Skip to content

Commit 4d3330e

Browse files
committed
Merge branch 'release-0.0.10'
2 parents f45e9cb + b270599 commit 4d3330e

File tree

10 files changed

+505
-127
lines changed

10 files changed

+505
-127
lines changed

CHANGELOG.rst

+25-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
11
Changelog
22
=========
33

4-
Unreleased
5-
----------
4+
0.0.10 - 2015-03-05
5+
-------------------
6+
7+
* bugfix:Documentation: Name collisions are now handled at the resource
8+
model layer instead of the factory, meaning that the documentation
9+
now uses the correct names.
10+
(`issue 67 <https://github.com/boto/boto3/pull/67>`__)
11+
* feature:Session: Add a ``region_name`` option when creating a session.
12+
(`issue 69 <https://github.com/boto/boto3/pull/69>`__,
13+
`issue 21 <https://github.com/boto/boto3/issues/21>`__)
14+
* feature:Botocore: Update to Botocore 0.94.0
15+
16+
* Update to the latest Amazon CloudeSearch API.
17+
* Add support for near-realtime data updates and exporting historical
18+
data from Amazon Cognito Sync.
19+
* **Removed** the ability to clone a low-level client. Instead, create
20+
a new client with the same parameters.
21+
* Add support for URL paths in an endpoint URL.
22+
* Multithreading signature fixes.
23+
* Add support for listing hosted zones by name and getting hosted zone
24+
counts from Amazon Route53.
25+
* Add support for tagging to AWS Data Pipeline.
26+
27+
0.0.9 - 2015-02-19
28+
------------------
629

730
* feature:Botocore: Update to Botocore 0.92.0
831

boto3/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818

1919
__author__ = 'Amazon Web Services'
20-
__version__ = '0.0.9'
20+
__version__ = '0.0.10'
2121

2222

2323
# The default Boto3 session; autoloaded when needed.

boto3/docs.py

+11-4
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,12 @@ def docs_for(service_name):
177177
for name, model in sorted(data['resources'].items(),
178178
key=lambda i:i[0]):
179179
resource_model = ResourceModel(name, model, data['resources'])
180+
181+
shape = None
182+
if resource_model.shape:
183+
shape = service_model.shape_for(resource_model.shape)
184+
resource_model.load_rename_map(shape)
185+
180186
if name not in models:
181187
models[name] = {'type': 'resource', 'model': resource_model}
182188

@@ -333,7 +339,8 @@ def document_resource(service_name, official_name, resource_model,
333339
docs += ' Attributes:\n\n'
334340
shape = service_model.shape_for(resource_model.shape)
335341

336-
for name, member in sorted(shape.members.items()):
342+
attributes = resource_model.get_attributes(shape)
343+
for name, (orig_name, member) in sorted(attributes.items()):
337344
docs += (' .. py:attribute:: {0}\n\n (``{1}``)'
338345
' {2}\n\n').format(
339346
xform_name(name), py_type_name(member.type_name),
@@ -403,7 +410,7 @@ def document_resource(service_name, official_name, resource_model,
403410
' to reach a specific state.\n\n')
404411
service_waiter_model = session.get_waiter_model(service_name)
405412
for waiter in sorted(resource_model.waiters,
406-
key=lambda i: i.resource_waiter_name):
413+
key=lambda i: i.name):
407414
docs += document_waiter(waiter, service_name, resource_model,
408415
service_model, service_waiter_model)
409416

@@ -467,7 +474,7 @@ def document_waiter(waiter, service_name, resource_model, service_model,
467474
' This method calls ``wait()`` on'
468475
' :py:meth:`{2}.Client.get_waiter` using `{3}`_ .').format(
469476
resource_model.name,
470-
xform_name(waiter.name).replace('_', ' '),
477+
' '.join(waiter.name.split('_')[2:]),
471478
service_name,
472479
xform_name(waiter.waiter_name))
473480

@@ -476,7 +483,7 @@ def document_waiter(waiter, service_name, resource_model, service_model,
476483

477484
return document_operation(
478485
operation_model=operation_model, service_name=service_name,
479-
operation_name=xform_name(waiter.resource_waiter_name),
486+
operation_name=xform_name(waiter.name),
480487
description=description,
481488
example_instance = xform_name(resource_model.name),
482489
ignore_params=ignore_params, rtype=None)

boto3/resources/factory.py

+29-85
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
import logging
1515
from functools import partial
1616

17-
from botocore import xform_name
18-
1917
from .action import ServiceAction
2018
from .action import WaiterAction
2119
from .base import ResourceMeta, ServiceResource
@@ -74,6 +72,11 @@ def load_from_definition(self, service_name, resource_name, model,
7472

7573
resource_model = ResourceModel(resource_name, model, resource_defs)
7674

75+
shape = None
76+
if resource_model.shape:
77+
shape = service_model.shape_for(resource_model.shape)
78+
resource_model.load_rename_map(shape)
79+
7780
self._load_identifiers(attrs, meta, resource_model)
7881
self._load_actions(attrs, resource_model, resource_defs,
7982
service_model)
@@ -98,11 +101,8 @@ def _load_identifiers(self, attrs, meta, model):
98101
operations on the resource.
99102
"""
100103
for identifier in model.identifiers:
101-
snake_cased = xform_name(identifier.name)
102-
snake_cased = self._check_allowed_name(
103-
attrs, snake_cased, 'identifier', model.name)
104-
meta.identifiers.append(snake_cased)
105-
attrs[snake_cased] = None
104+
meta.identifiers.append(identifier.name)
105+
attrs[identifier.name] = None
106106

107107
def _load_actions(self, attrs, model, resource_defs, service_model):
108108
"""
@@ -112,16 +112,12 @@ def _load_actions(self, attrs, model, resource_defs, service_model):
112112
"""
113113
if model.load:
114114
attrs['load'] = self._create_action(
115-
'load', model.load, resource_defs, service_model,
116-
is_load=True)
115+
model.load, resource_defs, service_model, is_load=True)
117116
attrs['reload'] = attrs['load']
118117

119118
for action in model.actions:
120-
snake_cased = xform_name(action.name)
121-
snake_cased = self._check_allowed_name(
122-
attrs, snake_cased, 'action', model.name)
123-
attrs[snake_cased] = self._create_action(snake_cased,
124-
action, resource_defs, service_model)
119+
attrs[action.name] = self._create_action(action, resource_defs,
120+
service_model)
125121

126122
def _load_attributes(self, attrs, meta, model, service_model):
127123
"""
@@ -133,16 +129,9 @@ def _load_attributes(self, attrs, meta, model, service_model):
133129
if model.shape:
134130
shape = service_model.shape_for(model.shape)
135131

136-
for name, member in shape.members.items():
137-
snake_cased = xform_name(name)
138-
if snake_cased in meta.identifiers:
139-
# Skip identifiers, these are set through other means
140-
continue
141-
142-
snake_cased = self._check_allowed_name(
143-
attrs, snake_cased, 'attribute', model.name)
144-
attrs[snake_cased] = self._create_autoload_property(name,
145-
snake_cased)
132+
attributes = model.get_attributes(shape)
133+
for name, (orig_name, member) in attributes.items():
134+
attrs[name] = self._create_autoload_property(orig_name, name)
146135

147136
def _load_collections(self, attrs, model, resource_defs, service_model):
148137
"""
@@ -152,12 +141,8 @@ def _load_collections(self, attrs, model, resource_defs, service_model):
152141
through the collection's items.
153142
"""
154143
for collection_model in model.collections:
155-
snake_cased = xform_name(collection_model.name)
156-
snake_cased = self._check_allowed_name(
157-
attrs, snake_cased, 'collection', model.name)
158-
159-
attrs[snake_cased] = self._create_collection(
160-
attrs['meta'].service_name, model.name, snake_cased,
144+
attrs[collection_model.name] = self._create_collection(
145+
attrs['meta'].service_name, model.name,
161146
collection_model, resource_defs, service_model)
162147

163148
def _load_has_relations(self, attrs, service_name, resource_name,
@@ -176,11 +161,8 @@ def _load_has_relations(self, attrs, service_name, resource_name,
176161
# This is a dangling reference, i.e. we have all
177162
# the data we need to create the resource, so
178163
# this instance becomes an attribute on the class.
179-
snake_cased = xform_name(reference.name)
180-
snake_cased = self._check_allowed_name(
181-
attrs, snake_cased, 'reference', model.name)
182-
attrs[snake_cased] = self._create_reference(
183-
reference.resource.type, snake_cased, reference,
164+
attrs[reference.name] = self._create_reference(
165+
reference.resource.type, reference,
184166
service_name, resource_name, model, resource_defs,
185167
service_model)
186168

@@ -200,44 +182,7 @@ def _load_waiters(self, attrs, model):
200182
of the resource.
201183
"""
202184
for waiter in model.waiters:
203-
snake_cased = xform_name(waiter.resource_waiter_name)
204-
snake_cased = self._check_allowed_name(
205-
attrs, snake_cased, 'waiter', model.name)
206-
attrs[snake_cased] = self._create_waiter(waiter, snake_cased)
207-
208-
def _check_allowed_name(self, attrs, name, category, resource_name):
209-
"""
210-
Determine if a given name is allowed on the instance, and if not,
211-
then raise an exception. This prevents public attributes of the
212-
class from being clobbered, e.g. since we define ``Resource.meta``,
213-
no identifier may be named ``meta``. Another example: no action
214-
named ``queue_items`` may be added after an identifier of the same
215-
name has been added.
216-
217-
One attempt is made in the event of a collision to remedy the
218-
situation. The ``category`` is appended to the name and the
219-
check is performed again. For example, if an action named
220-
``get_frobs`` fails the test, then we try ``get_frobs_action``
221-
after logging a warning.
222-
223-
:raises: ValueError
224-
"""
225-
if name in attrs:
226-
logger.warning('%s `%s` would clobber existing %s'
227-
' resource attribute, going to try'
228-
' %s instead...', category, name,
229-
resource_name, name + '_' + category)
230-
# TODO: Move this logic into the model and strictly
231-
# define the loading order of categories. This
232-
# will make documentation much simpler.
233-
name = name + '_' + category
234-
235-
if name in attrs:
236-
raise ValueError('{0} `{1}` would clobber existing '
237-
'{2} resource attribute'.format(
238-
category, name, resource_name))
239-
240-
return name
185+
attrs[waiter.name] = self._create_waiter(waiter)
241186

242187
def _create_autoload_property(factory_self, name, snake_cased):
243188
"""
@@ -262,22 +207,22 @@ def property_loader(self):
262207
property_loader.__doc__ = 'TODO'
263208
return property(property_loader)
264209

265-
def _create_waiter(factory_self, waiter_model, snake_cased):
210+
def _create_waiter(factory_self, waiter_model):
266211
"""
267212
Creates a new wait method for each resource where both a waiter and
268213
resource model is defined.
269214
"""
270-
waiter = WaiterAction(waiter_model, waiter_resource_name=snake_cased)
215+
waiter = WaiterAction(waiter_model,
216+
waiter_resource_name=waiter_model.name)
271217
def do_waiter(self, *args, **kwargs):
272218
waiter(self, *args, **kwargs)
273219

274-
do_waiter.__name__ = str(snake_cased)
220+
do_waiter.__name__ = str(waiter_model.name)
275221
do_waiter.__doc__ = 'TODO'
276222
return do_waiter
277223

278224
def _create_collection(factory_self, service_name, resource_name,
279-
snake_cased, collection_model,
280-
resource_defs, service_model):
225+
collection_model, resource_defs, service_model):
281226
"""
282227
Creates a new property on the resource to lazy-load a collection.
283228
"""
@@ -289,13 +234,12 @@ def get_collection(self):
289234
return cls(collection_model, self, factory_self,
290235
resource_defs, service_model)
291236

292-
get_collection.__name__ = str(snake_cased)
237+
get_collection.__name__ = str(collection_model.name)
293238
get_collection.__doc__ = 'TODO'
294239
return property(get_collection)
295240

296-
def _create_reference(factory_self, name, snake_cased, reference,
297-
service_name, resource_name, model, resource_defs,
298-
service_model):
241+
def _create_reference(factory_self, name, reference, service_name,
242+
resource_name, model, resource_defs, service_model):
299243
"""
300244
Creates a new property on the resource to lazy-load a reference.
301245
"""
@@ -313,7 +257,7 @@ def get_reference(self):
313257
# identifiers to instantiate the resource reference.
314258
return handler(self, {}, {})
315259

316-
get_reference.__name__ = str(snake_cased)
260+
get_reference.__name__ = str(reference.name)
317261
get_reference.__doc__ = 'TODO'
318262
return property(get_reference)
319263

@@ -352,7 +296,7 @@ def create_resource(self, *args, **kwargs):
352296
create_resource.__doc__ = 'TODO'
353297
return create_resource
354298

355-
def _create_action(factory_self, snake_cased, action_model, resource_defs,
299+
def _create_action(factory_self, action_model, resource_defs,
356300
service_model, is_load=False):
357301
"""
358302
Creates a new method which makes a request to the underlying
@@ -386,6 +330,6 @@ def do_action(self, *args, **kwargs):
386330

387331
return response
388332

389-
do_action.__name__ = str(snake_cased)
333+
do_action.__name__ = str(action_model.name)
390334
do_action.__doc__ = 'TODO'
391335
return do_action

0 commit comments

Comments
 (0)