We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
datastore: default to empty dataset
When working with datasets, the Datastore backend will normalize any empty datasets to the dataset of the calling application. This should be preferred to prepending "s~" to dataset ids as that is not always a valid operation.

datastore: default to empty dataset
When working with datasets, the Datastore backend will normalize any empty datasets to the dataset of the calling application. This should be preferred to prepending "s~" to dataset ids as that is not always a valid operation.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `gcloud/datastore/key.py`
Content:
```
1 """Create / interact with gcloud datastore keys."""
2 
3 import copy
4 from itertools import izip
5 
6 from gcloud.datastore import datastore_v1_pb2 as datastore_pb
7 from gcloud.datastore.dataset import Dataset
8 
9 
10 class Key(object):
11     """An immutable representation of a datastore Key.
12 
13     .. automethod:: __init__
14     """
15 
16     def __init__(self, dataset=None, namespace=None, path=None):
17         """Constructor / initializer for a key.
18 
19         :type dataset: :class:`gcloud.datastore.dataset.Dataset`
20         :param dataset: A dataset instance for the key.
21 
22         :type namespace: :class:`str`
23         :param namespace: A namespace identifier for the key.
24 
25         :type path: sequence of dicts
26         :param path: Each dict must have keys 'kind' (a string) and optionally
27                      'name' (a string) or 'id' (an integer).
28         """
29         self._dataset = dataset
30         self._namespace = namespace
31         self._path = path or [{'kind': ''}]
32 
33     def _clone(self):
34         """Duplicates the Key.
35 
36         We make a shallow copy of the :class:`gcloud.datastore.dataset.Dataset`
37         because it holds a reference an authenticated connection,
38         which we don't want to lose.
39 
40         :rtype: :class:`gcloud.datastore.key.Key`
41         :returns: a new `Key` instance
42         """
43         clone = copy.deepcopy(self)
44         clone._dataset = self._dataset  # Make a shallow copy of the Dataset.
45         return clone
46 
47     @classmethod
48     def from_protobuf(cls, pb, dataset=None):
49         """Factory method for creating a key based on a protobuf.
50 
51         The protobuf should be one returned from the Cloud Datastore
52         Protobuf API.
53 
54         :type pb: :class:`gcloud.datastore.datastore_v1_pb2.Key`
55         :param pb: The Protobuf representing the key.
56 
57         :type dataset: :class:`gcloud.datastore.dataset.Dataset`
58         :param dataset: A dataset instance.  If not passed, defaults to an
59                         instance whose ID is derived from pb.
60 
61         :rtype: :class:`gcloud.datastore.key.Key`
62         :returns: a new `Key` instance
63         """
64         path = []
65         for element in pb.path_element:
66             element_dict = {'kind': element.kind}
67 
68             if element.HasField('id'):
69                 element_dict['id'] = element.id
70 
71             # This is safe: we expect proto objects returned will only have
72             # one of `name` or `id` set.
73             if element.HasField('name'):
74                 element_dict['name'] = element.name
75 
76             path.append(element_dict)
77 
78         if not dataset:
79             dataset = Dataset(id=pb.partition_id.dataset_id)
80             namespace = pb.partition_id.namespace
81         else:
82             namespace = None
83 
84         return cls(dataset, namespace, path)
85 
86     def to_protobuf(self):
87         """Return a protobuf corresponding to the key.
88 
89         :rtype: :class:`gcloud.datastore.datastore_v1_pb2.Key`
90         :returns: The Protobuf representing the key.
91         """
92         key = datastore_pb.Key()
93 
94         # Technically a dataset is required to do anything with the key,
95         # but we shouldn't throw a cryptic error if one isn't provided
96         # in the initializer.
97         if self.dataset():
98             # Apparently 's~' is a prefix for High-Replication and is necessary
99             # here. Another valid preflix is 'e~' indicating EU datacenters.
100             dataset_id = self.dataset().id()
101             if dataset_id:
102                 if dataset_id[:2] not in ['s~', 'e~']:
103                     dataset_id = 's~' + dataset_id
104 
105                 key.partition_id.dataset_id = dataset_id
106 
107         if self._namespace:
108             key.partition_id.namespace = self._namespace
109 
110         for item in self.path():
111             element = key.path_element.add()
112             if 'kind' in item:
113                 element.kind = item['kind']
114             if 'id' in item:
115                 element.id = item['id']
116             if 'name' in item:
117                 element.name = item['name']
118 
119         return key
120 
121     @classmethod
122     def from_path(cls, *args, **kwargs):
123         """Factory method for creating a key based on a path.
124 
125         :type args: :class:`tuple`
126         :param args: sequence of even length, where the first of each pair is a
127                      string representing the 'kind' of the path element, and
128                      the second of the pair is either a string (for the path
129                      element's name) or an integer (for its id).
130 
131         :type kwargs: :class:`dict`
132         :param kwargs: Other named parameters which can be passed to
133                        :func:`Key.__init__`.
134 
135         :rtype: :class:`gcloud.datastore.key.Key`
136         :returns: a new :class:`Key` instance
137         """
138         if len(args) % 2:
139             raise ValueError('Must pass an even number of args.')
140 
141         path = []
142         items = iter(args)
143 
144         for kind, id_or_name in izip(items, items):
145             entry = {'kind': kind}
146             if isinstance(id_or_name, basestring):
147                 entry['name'] = id_or_name
148             else:
149                 entry['id'] = id_or_name
150             path.append(entry)
151 
152         kwargs['path'] = path
153         return cls(**kwargs)
154 
155     def is_partial(self):
156         """Boolean test: is the key fully mapped onto a backend entity?
157 
158         :rtype: :class:`bool`
159         :returns: True if the last element of the key's path does not have
160                   an 'id' or a 'name'.
161         """
162         return self.id_or_name() is None
163 
164     def dataset(self, dataset=None):
165         """Dataset setter / getter.
166 
167         :type dataset: :class:`gcloud.datastore.dataset.Dataset`
168         :param dataset: A dataset instance for the key.
169 
170         :rtype: :class:`Key` (for setter); or
171                 :class:`gcloud.datastore.dataset.Dataset` (for getter)
172         :returns: a new key, cloned from self., with the given dataset
173                   (setter); or self's dataset (getter).
174         """
175         if dataset:
176             clone = self._clone()
177             clone._dataset = dataset
178             return clone
179         else:
180             return self._dataset
181 
182     def namespace(self, namespace=None):
183         """Namespace setter / getter.
184 
185         :type namespace: :class:`str`
186         :param namespace: A namespace identifier for the key.
187 
188         :rtype: :class:`Key` (for setter); or :class:`str` (for getter)
189         :returns: a new key, cloned from self., with the given namespace
190                   (setter); or self's namespace (getter).
191         """
192         if namespace:
193             clone = self._clone()
194             clone._namespace = namespace
195             return clone
196         else:
197             return self._namespace
198 
199     def path(self, path=None):
200         """Path setter / getter.
201 
202         :type path: sequence of dicts
203         :param path: Each dict must have keys 'kind' (a string) and optionally
204                      'name' (a string) or 'id' (an integer).
205 
206         :rtype: :class:`Key` (for setter); or :class:`str` (for getter)
207         :returns: a new key, cloned from self., with the given path (setter);
208                  or self's path (getter).
209         """
210         if path:
211             clone = self._clone()
212             clone._path = path
213             return clone
214         else:
215             return self._path
216 
217     def kind(self, kind=None):
218         """Kind setter / getter.  Based on the last element of path.
219 
220         :type kind: :class:`str`
221         :param kind: The new kind for the key.
222 
223         :rtype: :class:`Key` (for setter); or :class:`str` (for getter)
224         :returns: a new key, cloned from self., with the given kind (setter);
225                  or self's kind (getter).
226         """
227         if kind:
228             clone = self._clone()
229             clone._path[-1]['kind'] = kind
230             return clone
231         elif self.path():
232             return self._path[-1]['kind']
233 
234     def id(self, id_to_set=None):
235         """ID setter / getter.  Based on the last element of path.
236 
237         :type id_to_set: :class:`int`
238         :param id_to_set: The new ID for the key.
239 
240         :rtype: :class:`Key` (for setter); or :class:`int` (for getter)
241         :returns: a new key, cloned from self., with the given id (setter);
242                   or self's id (getter).
243         """
244         if id_to_set:
245             clone = self._clone()
246             clone._path[-1]['id'] = id_to_set
247             return clone
248         elif self.path():
249             return self._path[-1].get('id')
250 
251     def name(self, name=None):
252         """Name setter / getter.  Based on the last element of path.
253 
254         :type kind: :class:`str`
255         :param kind: The new name for the key.
256 
257         :rtype: :class:`Key` (for setter); or :class:`str` (for getter)
258         :returns: a new key, cloned from self., with the given name (setter);
259                  or self's name (getter).
260         """
261         if name:
262             clone = self._clone()
263             clone._path[-1]['name'] = name
264             return clone
265         elif self.path():
266             return self._path[-1].get('name')
267 
268     def id_or_name(self):
269         """Getter.  Based on the last element of path.
270 
271         :rtype: :class:`int` (if 'id' is set); or :class:`str` (the 'name')
272         :returns: True if the last element of the key's path has either an 'id'
273                   or a 'name'.
274         """
275         return self.id() or self.name()
276 
277     def parent(self):
278         """Getter:  return a new key for the next highest element in path.
279 
280         :rtype: :class:`gcloud.datastore.key.Key`
281         :returns: a new `Key` instance, whose path consists of all but the last
282                   element of self's path.  If self has only one path element,
283                   return None.
284         """
285         if len(self._path) <= 1:
286             return None
287         return self.path(self.path()[:-1])
288 
289     def __repr__(self):
290         return '<Key%s>' % self.path()
291
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/gcloud/datastore/key.py b/gcloud/datastore/key.py
--- a/gcloud/datastore/key.py
+++ b/gcloud/datastore/key.py
@@ -95,13 +95,8 @@
         # but we shouldn't throw a cryptic error if one isn't provided
         # in the initializer.
         if self.dataset():
-            # Apparently 's~' is a prefix for High-Replication and is necessary
-            # here. Another valid preflix is 'e~' indicating EU datacenters.
             dataset_id = self.dataset().id()
             if dataset_id:
-                if dataset_id[:2] not in ['s~', 'e~']:
-                    dataset_id = 's~' + dataset_id
-
                 key.partition_id.dataset_id = dataset_id
 
         if self._namespace:

{"golden_diff": "diff --git a/gcloud/datastore/key.py b/gcloud/datastore/key.py\n--- a/gcloud/datastore/key.py\n+++ b/gcloud/datastore/key.py\n@@ -95,13 +95,8 @@\n         # but we shouldn't throw a cryptic error if one isn't provided\n         # in the initializer.\n         if self.dataset():\n-            # Apparently 's~' is a prefix for High-Replication and is necessary\n-            # here. Another valid preflix is 'e~' indicating EU datacenters.\n             dataset_id = self.dataset().id()\n             if dataset_id:\n-                if dataset_id[:2] not in ['s~', 'e~']:\n-                    dataset_id = 's~' + dataset_id\n-\n                 key.partition_id.dataset_id = dataset_id\n \n         if self._namespace:\n", "issue": "datastore: default to empty dataset\nWhen working with datasets, the Datastore backend will normalize any empty datasets to the dataset of the calling application. This should be preferred to prepending \"s~\" to dataset ids as that is not always a valid operation.\n\ndatastore: default to empty dataset\nWhen working with datasets, the Datastore backend will normalize any empty datasets to the dataset of the calling application. This should be preferred to prepending \"s~\" to dataset ids as that is not always a valid operation.\n\n", "before_files": [{"content": "\"\"\"Create / interact with gcloud datastore keys.\"\"\"\n\nimport copy\nfrom itertools import izip\n\nfrom gcloud.datastore import datastore_v1_pb2 as datastore_pb\nfrom gcloud.datastore.dataset import Dataset\n\n\nclass Key(object):\n    \"\"\"An immutable representation of a datastore Key.\n\n    .. automethod:: __init__\n    \"\"\"\n\n    def __init__(self, dataset=None, namespace=None, path=None):\n        \"\"\"Constructor / initializer for a key.\n\n        :type dataset: :class:`gcloud.datastore.dataset.Dataset`\n        :param dataset: A dataset instance for the key.\n\n        :type namespace: :class:`str`\n        :param namespace: A namespace identifier for the key.\n\n        :type path: sequence of dicts\n        :param path: Each dict must have keys 'kind' (a string) and optionally\n                     'name' (a string) or 'id' (an integer).\n        \"\"\"\n        self._dataset = dataset\n        self._namespace = namespace\n        self._path = path or [{'kind': ''}]\n\n    def _clone(self):\n        \"\"\"Duplicates the Key.\n\n        We make a shallow copy of the :class:`gcloud.datastore.dataset.Dataset`\n        because it holds a reference an authenticated connection,\n        which we don't want to lose.\n\n        :rtype: :class:`gcloud.datastore.key.Key`\n        :returns: a new `Key` instance\n        \"\"\"\n        clone = copy.deepcopy(self)\n        clone._dataset = self._dataset  # Make a shallow copy of the Dataset.\n        return clone\n\n    @classmethod\n    def from_protobuf(cls, pb, dataset=None):\n        \"\"\"Factory method for creating a key based on a protobuf.\n\n        The protobuf should be one returned from the Cloud Datastore\n        Protobuf API.\n\n        :type pb: :class:`gcloud.datastore.datastore_v1_pb2.Key`\n        :param pb: The Protobuf representing the key.\n\n        :type dataset: :class:`gcloud.datastore.dataset.Dataset`\n        :param dataset: A dataset instance.  If not passed, defaults to an\n                        instance whose ID is derived from pb.\n\n        :rtype: :class:`gcloud.datastore.key.Key`\n        :returns: a new `Key` instance\n        \"\"\"\n        path = []\n        for element in pb.path_element:\n            element_dict = {'kind': element.kind}\n\n            if element.HasField('id'):\n                element_dict['id'] = element.id\n\n            # This is safe: we expect proto objects returned will only have\n            # one of `name` or `id` set.\n            if element.HasField('name'):\n                element_dict['name'] = element.name\n\n            path.append(element_dict)\n\n        if not dataset:\n            dataset = Dataset(id=pb.partition_id.dataset_id)\n            namespace = pb.partition_id.namespace\n        else:\n            namespace = None\n\n        return cls(dataset, namespace, path)\n\n    def to_protobuf(self):\n        \"\"\"Return a protobuf corresponding to the key.\n\n        :rtype: :class:`gcloud.datastore.datastore_v1_pb2.Key`\n        :returns: The Protobuf representing the key.\n        \"\"\"\n        key = datastore_pb.Key()\n\n        # Technically a dataset is required to do anything with the key,\n        # but we shouldn't throw a cryptic error if one isn't provided\n        # in the initializer.\n        if self.dataset():\n            # Apparently 's~' is a prefix for High-Replication and is necessary\n            # here. Another valid preflix is 'e~' indicating EU datacenters.\n            dataset_id = self.dataset().id()\n            if dataset_id:\n                if dataset_id[:2] not in ['s~', 'e~']:\n                    dataset_id = 's~' + dataset_id\n\n                key.partition_id.dataset_id = dataset_id\n\n        if self._namespace:\n            key.partition_id.namespace = self._namespace\n\n        for item in self.path():\n            element = key.path_element.add()\n            if 'kind' in item:\n                element.kind = item['kind']\n            if 'id' in item:\n                element.id = item['id']\n            if 'name' in item:\n                element.name = item['name']\n\n        return key\n\n    @classmethod\n    def from_path(cls, *args, **kwargs):\n        \"\"\"Factory method for creating a key based on a path.\n\n        :type args: :class:`tuple`\n        :param args: sequence of even length, where the first of each pair is a\n                     string representing the 'kind' of the path element, and\n                     the second of the pair is either a string (for the path\n                     element's name) or an integer (for its id).\n\n        :type kwargs: :class:`dict`\n        :param kwargs: Other named parameters which can be passed to\n                       :func:`Key.__init__`.\n\n        :rtype: :class:`gcloud.datastore.key.Key`\n        :returns: a new :class:`Key` instance\n        \"\"\"\n        if len(args) % 2:\n            raise ValueError('Must pass an even number of args.')\n\n        path = []\n        items = iter(args)\n\n        for kind, id_or_name in izip(items, items):\n            entry = {'kind': kind}\n            if isinstance(id_or_name, basestring):\n                entry['name'] = id_or_name\n            else:\n                entry['id'] = id_or_name\n            path.append(entry)\n\n        kwargs['path'] = path\n        return cls(**kwargs)\n\n    def is_partial(self):\n        \"\"\"Boolean test: is the key fully mapped onto a backend entity?\n\n        :rtype: :class:`bool`\n        :returns: True if the last element of the key's path does not have\n                  an 'id' or a 'name'.\n        \"\"\"\n        return self.id_or_name() is None\n\n    def dataset(self, dataset=None):\n        \"\"\"Dataset setter / getter.\n\n        :type dataset: :class:`gcloud.datastore.dataset.Dataset`\n        :param dataset: A dataset instance for the key.\n\n        :rtype: :class:`Key` (for setter); or\n                :class:`gcloud.datastore.dataset.Dataset` (for getter)\n        :returns: a new key, cloned from self., with the given dataset\n                  (setter); or self's dataset (getter).\n        \"\"\"\n        if dataset:\n            clone = self._clone()\n            clone._dataset = dataset\n            return clone\n        else:\n            return self._dataset\n\n    def namespace(self, namespace=None):\n        \"\"\"Namespace setter / getter.\n\n        :type namespace: :class:`str`\n        :param namespace: A namespace identifier for the key.\n\n        :rtype: :class:`Key` (for setter); or :class:`str` (for getter)\n        :returns: a new key, cloned from self., with the given namespace\n                  (setter); or self's namespace (getter).\n        \"\"\"\n        if namespace:\n            clone = self._clone()\n            clone._namespace = namespace\n            return clone\n        else:\n            return self._namespace\n\n    def path(self, path=None):\n        \"\"\"Path setter / getter.\n\n        :type path: sequence of dicts\n        :param path: Each dict must have keys 'kind' (a string) and optionally\n                     'name' (a string) or 'id' (an integer).\n\n        :rtype: :class:`Key` (for setter); or :class:`str` (for getter)\n        :returns: a new key, cloned from self., with the given path (setter);\n                 or self's path (getter).\n        \"\"\"\n        if path:\n            clone = self._clone()\n            clone._path = path\n            return clone\n        else:\n            return self._path\n\n    def kind(self, kind=None):\n        \"\"\"Kind setter / getter.  Based on the last element of path.\n\n        :type kind: :class:`str`\n        :param kind: The new kind for the key.\n\n        :rtype: :class:`Key` (for setter); or :class:`str` (for getter)\n        :returns: a new key, cloned from self., with the given kind (setter);\n                 or self's kind (getter).\n        \"\"\"\n        if kind:\n            clone = self._clone()\n            clone._path[-1]['kind'] = kind\n            return clone\n        elif self.path():\n            return self._path[-1]['kind']\n\n    def id(self, id_to_set=None):\n        \"\"\"ID setter / getter.  Based on the last element of path.\n\n        :type id_to_set: :class:`int`\n        :param id_to_set: The new ID for the key.\n\n        :rtype: :class:`Key` (for setter); or :class:`int` (for getter)\n        :returns: a new key, cloned from self., with the given id (setter);\n                  or self's id (getter).\n        \"\"\"\n        if id_to_set:\n            clone = self._clone()\n            clone._path[-1]['id'] = id_to_set\n            return clone\n        elif self.path():\n            return self._path[-1].get('id')\n\n    def name(self, name=None):\n        \"\"\"Name setter / getter.  Based on the last element of path.\n\n        :type kind: :class:`str`\n        :param kind: The new name for the key.\n\n        :rtype: :class:`Key` (for setter); or :class:`str` (for getter)\n        :returns: a new key, cloned from self., with the given name (setter);\n                 or self's name (getter).\n        \"\"\"\n        if name:\n            clone = self._clone()\n            clone._path[-1]['name'] = name\n            return clone\n        elif self.path():\n            return self._path[-1].get('name')\n\n    def id_or_name(self):\n        \"\"\"Getter.  Based on the last element of path.\n\n        :rtype: :class:`int` (if 'id' is set); or :class:`str` (the 'name')\n        :returns: True if the last element of the key's path has either an 'id'\n                  or a 'name'.\n        \"\"\"\n        return self.id() or self.name()\n\n    def parent(self):\n        \"\"\"Getter:  return a new key for the next highest element in path.\n\n        :rtype: :class:`gcloud.datastore.key.Key`\n        :returns: a new `Key` instance, whose path consists of all but the last\n                  element of self's path.  If self has only one path element,\n                  return None.\n        \"\"\"\n        if len(self._path) <= 1:\n            return None\n        return self.path(self.path()[:-1])\n\n    def __repr__(self):\n        return '<Key%s>' % self.path()\n", "path": "gcloud/datastore/key.py"}], "after_files": [{"content": "\"\"\"Create / interact with gcloud datastore keys.\"\"\"\n\nimport copy\nfrom itertools import izip\n\nfrom gcloud.datastore import datastore_v1_pb2 as datastore_pb\nfrom gcloud.datastore.dataset import Dataset\n\n\nclass Key(object):\n    \"\"\"An immutable representation of a datastore Key.\n\n    .. automethod:: __init__\n    \"\"\"\n\n    def __init__(self, dataset=None, namespace=None, path=None):\n        \"\"\"Constructor / initializer for a key.\n\n        :type dataset: :class:`gcloud.datastore.dataset.Dataset`\n        :param dataset: A dataset instance for the key.\n\n        :type namespace: :class:`str`\n        :param namespace: A namespace identifier for the key.\n\n        :type path: sequence of dicts\n        :param path: Each dict must have keys 'kind' (a string) and optionally\n                     'name' (a string) or 'id' (an integer).\n        \"\"\"\n        self._dataset = dataset\n        self._namespace = namespace\n        self._path = path or [{'kind': ''}]\n\n    def _clone(self):\n        \"\"\"Duplicates the Key.\n\n        We make a shallow copy of the :class:`gcloud.datastore.dataset.Dataset`\n        because it holds a reference an authenticated connection,\n        which we don't want to lose.\n\n        :rtype: :class:`gcloud.datastore.key.Key`\n        :returns: a new `Key` instance\n        \"\"\"\n        clone = copy.deepcopy(self)\n        clone._dataset = self._dataset  # Make a shallow copy of the Dataset.\n        return clone\n\n    @classmethod\n    def from_protobuf(cls, pb, dataset=None):\n        \"\"\"Factory method for creating a key based on a protobuf.\n\n        The protobuf should be one returned from the Cloud Datastore\n        Protobuf API.\n\n        :type pb: :class:`gcloud.datastore.datastore_v1_pb2.Key`\n        :param pb: The Protobuf representing the key.\n\n        :type dataset: :class:`gcloud.datastore.dataset.Dataset`\n        :param dataset: A dataset instance.  If not passed, defaults to an\n                        instance whose ID is derived from pb.\n\n        :rtype: :class:`gcloud.datastore.key.Key`\n        :returns: a new `Key` instance\n        \"\"\"\n        path = []\n        for element in pb.path_element:\n            element_dict = {'kind': element.kind}\n\n            if element.HasField('id'):\n                element_dict['id'] = element.id\n\n            # This is safe: we expect proto objects returned will only have\n            # one of `name` or `id` set.\n            if element.HasField('name'):\n                element_dict['name'] = element.name\n\n            path.append(element_dict)\n\n        if not dataset:\n            dataset = Dataset(id=pb.partition_id.dataset_id)\n            namespace = pb.partition_id.namespace\n        else:\n            namespace = None\n\n        return cls(dataset, namespace, path)\n\n    def to_protobuf(self):\n        \"\"\"Return a protobuf corresponding to the key.\n\n        :rtype: :class:`gcloud.datastore.datastore_v1_pb2.Key`\n        :returns: The Protobuf representing the key.\n        \"\"\"\n        key = datastore_pb.Key()\n\n        # Technically a dataset is required to do anything with the key,\n        # but we shouldn't throw a cryptic error if one isn't provided\n        # in the initializer.\n        if self.dataset():\n            dataset_id = self.dataset().id()\n            if dataset_id:\n                key.partition_id.dataset_id = dataset_id\n\n        if self._namespace:\n            key.partition_id.namespace = self._namespace\n\n        for item in self.path():\n            element = key.path_element.add()\n            if 'kind' in item:\n                element.kind = item['kind']\n            if 'id' in item:\n                element.id = item['id']\n            if 'name' in item:\n                element.name = item['name']\n\n        return key\n\n    @classmethod\n    def from_path(cls, *args, **kwargs):\n        \"\"\"Factory method for creating a key based on a path.\n\n        :type args: :class:`tuple`\n        :param args: sequence of even length, where the first of each pair is a\n                     string representing the 'kind' of the path element, and\n                     the second of the pair is either a string (for the path\n                     element's name) or an integer (for its id).\n\n        :type kwargs: :class:`dict`\n        :param kwargs: Other named parameters which can be passed to\n                       :func:`Key.__init__`.\n\n        :rtype: :class:`gcloud.datastore.key.Key`\n        :returns: a new :class:`Key` instance\n        \"\"\"\n        if len(args) % 2:\n            raise ValueError('Must pass an even number of args.')\n\n        path = []\n        items = iter(args)\n\n        for kind, id_or_name in izip(items, items):\n            entry = {'kind': kind}\n            if isinstance(id_or_name, basestring):\n                entry['name'] = id_or_name\n            else:\n                entry['id'] = id_or_name\n            path.append(entry)\n\n        kwargs['path'] = path\n        return cls(**kwargs)\n\n    def is_partial(self):\n        \"\"\"Boolean test: is the key fully mapped onto a backend entity?\n\n        :rtype: :class:`bool`\n        :returns: True if the last element of the key's path does not have\n                  an 'id' or a 'name'.\n        \"\"\"\n        return self.id_or_name() is None\n\n    def dataset(self, dataset=None):\n        \"\"\"Dataset setter / getter.\n\n        :type dataset: :class:`gcloud.datastore.dataset.Dataset`\n        :param dataset: A dataset instance for the key.\n\n        :rtype: :class:`Key` (for setter); or\n                :class:`gcloud.datastore.dataset.Dataset` (for getter)\n        :returns: a new key, cloned from self., with the given dataset\n                  (setter); or self's dataset (getter).\n        \"\"\"\n        if dataset:\n            clone = self._clone()\n            clone._dataset = dataset\n            return clone\n        else:\n            return self._dataset\n\n    def namespace(self, namespace=None):\n        \"\"\"Namespace setter / getter.\n\n        :type namespace: :class:`str`\n        :param namespace: A namespace identifier for the key.\n\n        :rtype: :class:`Key` (for setter); or :class:`str` (for getter)\n        :returns: a new key, cloned from self., with the given namespace\n                  (setter); or self's namespace (getter).\n        \"\"\"\n        if namespace:\n            clone = self._clone()\n            clone._namespace = namespace\n            return clone\n        else:\n            return self._namespace\n\n    def path(self, path=None):\n        \"\"\"Path setter / getter.\n\n        :type path: sequence of dicts\n        :param path: Each dict must have keys 'kind' (a string) and optionally\n                     'name' (a string) or 'id' (an integer).\n\n        :rtype: :class:`Key` (for setter); or :class:`str` (for getter)\n        :returns: a new key, cloned from self., with the given path (setter);\n                 or self's path (getter).\n        \"\"\"\n        if path:\n            clone = self._clone()\n            clone._path = path\n            return clone\n        else:\n            return self._path\n\n    def kind(self, kind=None):\n        \"\"\"Kind setter / getter.  Based on the last element of path.\n\n        :type kind: :class:`str`\n        :param kind: The new kind for the key.\n\n        :rtype: :class:`Key` (for setter); or :class:`str` (for getter)\n        :returns: a new key, cloned from self., with the given kind (setter);\n                 or self's kind (getter).\n        \"\"\"\n        if kind:\n            clone = self._clone()\n            clone._path[-1]['kind'] = kind\n            return clone\n        elif self.path():\n            return self._path[-1]['kind']\n\n    def id(self, id_to_set=None):\n        \"\"\"ID setter / getter.  Based on the last element of path.\n\n        :type id_to_set: :class:`int`\n        :param id_to_set: The new ID for the key.\n\n        :rtype: :class:`Key` (for setter); or :class:`int` (for getter)\n        :returns: a new key, cloned from self., with the given id (setter);\n                  or self's id (getter).\n        \"\"\"\n        if id_to_set:\n            clone = self._clone()\n            clone._path[-1]['id'] = id_to_set\n            return clone\n        elif self.path():\n            return self._path[-1].get('id')\n\n    def name(self, name=None):\n        \"\"\"Name setter / getter.  Based on the last element of path.\n\n        :type kind: :class:`str`\n        :param kind: The new name for the key.\n\n        :rtype: :class:`Key` (for setter); or :class:`str` (for getter)\n        :returns: a new key, cloned from self., with the given name (setter);\n                 or self's name (getter).\n        \"\"\"\n        if name:\n            clone = self._clone()\n            clone._path[-1]['name'] = name\n            return clone\n        elif self.path():\n            return self._path[-1].get('name')\n\n    def id_or_name(self):\n        \"\"\"Getter.  Based on the last element of path.\n\n        :rtype: :class:`int` (if 'id' is set); or :class:`str` (the 'name')\n        :returns: True if the last element of the key's path has either an 'id'\n                  or a 'name'.\n        \"\"\"\n        return self.id() or self.name()\n\n    def parent(self):\n        \"\"\"Getter:  return a new key for the next highest element in path.\n\n        :rtype: :class:`gcloud.datastore.key.Key`\n        :returns: a new `Key` instance, whose path consists of all but the last\n                  element of self's path.  If self has only one path element,\n                  return None.\n        \"\"\"\n        if len(self._path) <= 1:\n            return None\n        return self.path(self.path()[:-1])\n\n    def __repr__(self):\n        return '<Key%s>' % self.path()\n", "path": "gcloud/datastore/key.py"}]}