Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Address third part of 451: Storing Key.parent on instance for future calls #459

Merged
merged 1 commit into from
Dec 31, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 22 additions & 7 deletions gcloud/datastore/key.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def __init__(self, path=None, namespace=None, dataset_id=None):
**must** treat any value set by the back-end as opaque.
"""
self._path = path or [{'kind': ''}]
self._parent = None
self._namespace = namespace
self._dataset_id = dataset_id

Expand Down Expand Up @@ -166,21 +167,35 @@ def dataset_id(self):
"""
return self._dataset_id

def _make_parent(self):
"""Creates a parent key for the current path.

Extracts all but the last element in the key path and creates a new
key, while still matching the namespace and the dataset ID.

:rtype: :class:`gcloud.datastore.key.Key` or `NoneType`
:returns: a new `Key` instance, whose path consists of all but the last
element of self's path. If self has only one path element,
returns None.
"""
parent_path = self.path[:-1]
if parent_path:
return Key(path=parent_path, dataset_id=self.dataset_id,
namespace=self.namespace)

@property
def parent(self):
"""Getter: return a new key for the next highest element in path.

:rtype: :class:`gcloud.datastore.key.Key`
:rtype: :class:`gcloud.datastore.key.Key` or `NoneType`
:returns: a new `Key` instance, whose path consists of all but the last
element of self's path. If self has only one path element,
returns None.
"""
if len(self._path) <= 1:
return None
# This is temporary. Will be addressed throughout #451.
clone = self._clone()
clone._path = self.path[:-1]
return clone
if self._parent is None:
self._parent = self._make_parent()

return self._parent

def __repr__(self):
return '<Key%s>' % self.path
11 changes: 11 additions & 0 deletions gcloud/datastore/test_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,14 @@ def test_parent_explicit_nested(self):
{'kind': 'ghi', 'id': 123},
])
self.assertEqual(key.parent.path, [parent_part])

def test_parent_multiple_calls(self):
_PARENT_KIND = 'KIND1'
_PARENT_ID = 1234
_PARENT_PATH = {'kind': _PARENT_KIND, 'id': _PARENT_ID}
_PATH = [_PARENT_PATH, {'kind': 'KIND2'}]
key = self._makeOne(path=_PATH)
parent = key.parent
self.assertEqual(parent.path, [_PARENT_PATH])
new_parent = key.parent
self.assertTrue(parent is new_parent)