Skip to content

Commit 9aff877

Browse files
committed
Making Key.parent return the same instance on return calls.
This is in preparation for adding parent to the constructor. Addresses third part of #451.
1 parent 8cb41f6 commit 9aff877

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

gcloud/datastore/key.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ def __init__(self, path=None, namespace=None, dataset_id=None):
4747
**must** treat any value set by the back-end as opaque.
4848
"""
4949
self._path = path or [{'kind': ''}]
50+
self._parent = None
5051
self._namespace = namespace
5152
self._dataset_id = dataset_id
5253

@@ -166,21 +167,35 @@ def dataset_id(self):
166167
"""
167168
return self._dataset_id
168169

170+
def _make_parent(self):
171+
"""Creates a parent key for the current path.
172+
173+
Extracts all but the last element in the key path and creates a new
174+
key, while still matching the namespace and the dataset ID.
175+
176+
:rtype: :class:`gcloud.datastore.key.Key` or `NoneType`
177+
:returns: a new `Key` instance, whose path consists of all but the last
178+
element of self's path. If self has only one path element,
179+
returns None.
180+
"""
181+
parent_path = self.path[:-1]
182+
if parent_path:
183+
return Key(path=parent_path, dataset_id=self.dataset_id,
184+
namespace=self.namespace)
185+
169186
@property
170187
def parent(self):
171188
"""Getter: return a new key for the next highest element in path.
172189
173-
:rtype: :class:`gcloud.datastore.key.Key`
190+
:rtype: :class:`gcloud.datastore.key.Key` or `NoneType`
174191
:returns: a new `Key` instance, whose path consists of all but the last
175192
element of self's path. If self has only one path element,
176193
returns None.
177194
"""
178-
if len(self._path) <= 1:
179-
return None
180-
# This is temporary. Will be addressed throughout #451.
181-
clone = self._clone()
182-
clone._path = self.path[:-1]
183-
return clone
195+
if self._parent is None:
196+
self._parent = self._make_parent()
197+
198+
return self._parent
184199

185200
def __repr__(self):
186201
return '<Key%s>' % self.path

gcloud/datastore/test_key.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,14 @@ def test_parent_explicit_nested(self):
186186
{'kind': 'ghi', 'id': 123},
187187
])
188188
self.assertEqual(key.parent.path, [parent_part])
189+
190+
def test_parent_multiple_calls(self):
191+
_PARENT_KIND = 'KIND1'
192+
_PARENT_ID = 1234
193+
_PARENT_PATH = {'kind': _PARENT_KIND, 'id': _PARENT_ID}
194+
_PATH = [_PARENT_PATH, {'kind': 'KIND2'}]
195+
key = self._makeOne(path=_PATH)
196+
parent = key.parent
197+
self.assertEqual(parent.path, [_PARENT_PATH])
198+
new_parent = key.parent
199+
self.assertTrue(parent is new_parent)

0 commit comments

Comments
 (0)