Fix RuntimeError on Python 3 while listing objects

The Object class has two properties which confuse attribute setting when
receiving body values which directly correspond to the *name* of the
attribute on the class, but not to the expected *prop*. Receiving
"last_modified" in the body causes both "last_modified" and it's
expected prop name, "last-modified", to be set, thus changing the size
of the attrs dictionary inside of Resource.__init__.

This change also slightly modifies test_head, which was operating in a
slightly odd way in the first place, but turned into a failing test
because it wasn't passing through the proper channels to set its
attributes because we were side-stepping it..

Change-Id: I987c85fce8d8f6a97ca92e0482c8ff997d848752
Closes-bug: 1414089
This commit is contained in:
Brian Curtin
2015-01-23 01:46:13 -06:00
parent 5dd1bd94fd
commit b7719486d6
2 changed files with 16 additions and 13 deletions

View File

@@ -84,12 +84,12 @@ class Object(resource.Resource):
#: the object, in bytes.
content_length = resource.prop("content-length")
#: The MIME type of the object.
content_type = resource.prop("content-type")
content_type = resource.prop("content_type", alias="content-type")
#: The type of ranges that the object accepts.
accept_ranges = resource.prop("accept-ranges")
#: The date and time that the object was created or the last
#: time that the metadata was changed.
last_modified = resource.prop("last-modified")
last_modified = resource.prop("last_modified", alias="last-modified")
#: For objects smaller than 5 GB, this value is the MD5 checksum
#: of the object content. The value is not quoted.
#: For manifest objects, this value is the MD5 checksum of the

View File

@@ -20,12 +20,23 @@ from openstack.object_store.v1 import obj
CONTAINER_NAME = "mycontainer"
OBJECT_NAME = "myobject"
# Object can receive both last-modified in headers and last_modified in
# the body. However, originally, only last-modified was handled as an
# expected prop but it was named last_modified. Under Python 3, creating
# an Object with the body value last_modified causes the _attrs dictionary
# size to change while iterating over its values as we have an attribute
# called `last_modified` and we attempt to grow an additional attribute
# called `last-modified`, which is the "name" of `last_modified`.
# The same is true of content_type and content-type, or any prop
# attribute which would follow the same pattern.
# This example should represent the body values returned by a GET, so the keys
# must be underscores.
OBJ_EXAMPLE = {
"hash": "243f87b91224d85722564a80fd3cb1f1",
"last-modified": "2014-07-13T18:41:03.319240",
"last_modified": "2014-07-13T18:41:03.319240",
"bytes": 252466,
"name": OBJECT_NAME,
"content-type": "application/octet-stream"
"content_type": "application/octet-stream"
}
HEAD_EXAMPLE = {
@@ -72,15 +83,7 @@ class TestObject(testtools.TestCase):
self.assertEqual(CONTAINER_NAME, sot.container)
def test_head(self):
sot = obj.Object.existing(**OBJ_EXAMPLE)
# Update object with HEAD data
sot._attrs.update(HEAD_EXAMPLE)
# Attributes from creation
self.assertEqual(OBJ_EXAMPLE['name'], sot.name)
self.assertEqual(OBJ_EXAMPLE['hash'], sot.hash)
self.assertEqual(OBJ_EXAMPLE['bytes'], sot.bytes)
sot = obj.Object.existing(**HEAD_EXAMPLE)
# Attributes from header
self.assertEqual(HEAD_EXAMPLE['container'], sot.container)