Skip to content

Commit 2b4f1c7

Browse files
Merge pull request #737 from neo4j/feature/remove-null-tests-for-ids
Remove null handling for Node/Relationship Ids
2 parents 1becfc5 + d6f35fa commit 2b4f1c7

File tree

6 files changed

+142
-76
lines changed

6 files changed

+142
-76
lines changed

neo4j/graph/__init__.py

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,13 @@ class Graph:
4444

4545
def __init__(self):
4646
self._nodes = {}
47+
self._legacy_nodes = {} # TODO: 6.0 - remove
4748
self._relationships = {}
49+
self._legacy_relationships = {} # TODO: 6.0 - remove
4850
self._relationship_types = {}
49-
self._node_set_view = EntitySetView(self._nodes)
50-
self._relationship_set_view = EntitySetView(self._relationships)
51+
self._node_set_view = EntitySetView(self._nodes, self._legacy_nodes)
52+
self._relationship_set_view = EntitySetView(self._relationships,
53+
self._legacy_relationships)
5154

5255
@property
5356
def nodes(self):
@@ -86,9 +89,9 @@ def hydrate_node(self, id_, labels=None,
8689
try:
8790
inst = self.graph._nodes[element_id]
8891
except KeyError:
89-
inst = self.graph._nodes[element_id] = Node(
90-
self.graph, element_id, id_, labels, properties
91-
)
92+
inst = Node(self.graph, element_id, id_, labels, properties)
93+
self.graph._nodes[element_id] = inst
94+
self.graph._legacy_nodes[id_] = inst
9295
else:
9396
# If we have already hydrated this node as the endpoint of
9497
# a relationship, it won't have any labels or properties.
@@ -128,9 +131,11 @@ def hydrate_unbound_relationship(self, id_, type_, properties=None,
128131
inst = self.graph._relationships[element_id]
129132
except KeyError:
130133
r = self.graph.relationship_type(type_)
131-
inst = self.graph._relationships[element_id] = r(
134+
inst = r(
132135
self.graph, element_id, id_, properties
133136
)
137+
self.graph._relationships[element_id] = inst
138+
self.graph._legacy_relationships[id_] = inst
134139
return inst
135140

136141
def hydrate_path(self, nodes, relationships, sequence):
@@ -260,8 +265,9 @@ class EntitySetView(Mapping):
260265
""" View of a set of :class:`.Entity` instances within a :class:`.Graph`.
261266
"""
262267

263-
def __init__(self, entity_dict):
268+
def __init__(self, entity_dict, legacy_entity_dict):
264269
self._entity_dict = entity_dict
270+
self._legacy_entity_dict = legacy_entity_dict # TODO: 6.0 - remove
265271

266272
def __getitem__(self, e_id):
267273
# TODO: 6.0 - remove this compatibility shim
@@ -270,14 +276,7 @@ def __getitem__(self, e_id):
270276
"Accessing entities by an integer id is deprecated, "
271277
"use the new style element_id (str) instead"
272278
)
273-
if isinstance(e_id, float) and int(e_id) == e_id:
274-
# Non-int floats would always fail for legacy IDs
275-
e_id = int(e_id)
276-
elif isinstance(e_id, complex) and int(e_id.real) == e_id:
277-
# complex numbers with imaginary parts or non-integer real
278-
# parts would always fail for legacy IDs
279-
e_id = int(e_id.real)
280-
e_id = str(e_id)
279+
return self._legacy_entity_dict[e_id]
281280
return self._entity_dict[e_id]
282281

283282
def __len__(self):

testkitbackend/test_config.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@
5353
"Optimization:PullPipelining": true,
5454
"Optimization:ResultListFetchAll": "The idiomatic way to cast to list is indistinguishable from iterating over the result.",
5555

56-
"Detail:NullOnMissingId": true,
57-
5856
"ConfHint:connection.recv_timeout_seconds": true,
5957

6058
"Backend:RTFetch": true,

tests/unit/common/test_api.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,8 @@ def test_serverinfo_initialization():
377377
assert server_info.address is address
378378
assert server_info.protocol_version is version
379379
assert server_info.agent is None
380-
assert server_info.connection_id is None
380+
with pytest.warns(DeprecationWarning):
381+
assert server_info.connection_id is None
381382

382383

383384
@pytest.mark.parametrize(

tests/unit/common/test_data.py

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,21 @@ def test_can_hydrate_v1_node_structure():
3333

3434
with pytest.warns(DeprecationWarning, match="element_id"):
3535
assert alice.id == 123
36-
# for backwards compatibility, the driver should compy the element_id
36+
# for backwards compatibility, the driver should compute the element_id
3737
assert alice.element_id == "123"
3838
assert alice.labels == {"Person"}
3939
assert set(alice.keys()) == {"name"}
4040
assert alice.get("name") == "Alice"
4141

4242

43-
@pytest.mark.parametrize("with_id", (True, False))
44-
def test_can_hydrate_v2_node_structure(with_id):
43+
def test_can_hydrate_v2_node_structure():
4544
hydrant = DataHydrator()
4645

47-
id_ = 123 if with_id else None
48-
49-
struct = Structure(b'N', id_, ["Person"], {"name": "Alice"}, "abc")
46+
struct = Structure(b'N', 123, ["Person"], {"name": "Alice"}, "abc")
5047
alice, = hydrant.hydrate([struct])
5148

5249
with pytest.warns(DeprecationWarning, match="element_id"):
53-
assert alice.id == id_
50+
assert alice.id == 123
5451
assert alice.element_id == "abc"
5552
assert alice.labels == {"Person"}
5653
assert set(alice.keys()) == {"name"}
@@ -78,25 +75,20 @@ def test_can_hydrate_v1_relationship_structure():
7875
assert rel.get("since") == 1999
7976

8077

81-
@pytest.mark.parametrize("with_ids", (True, False))
82-
def test_can_hydrate_v2_relationship_structure(with_ids):
78+
def test_can_hydrate_v2_relationship_structure():
8379
hydrant = DataHydrator()
8480

85-
id_ = 123 if with_ids else None
86-
start_id = 456 if with_ids else None
87-
end_id = 789 if with_ids else None
88-
89-
struct = Structure(b'R', id_, start_id, end_id, "KNOWS", {"since": 1999},
81+
struct = Structure(b'R', 123, 456, 789, "KNOWS", {"since": 1999},
9082
"abc", "def", "ghi")
9183

9284
rel, = hydrant.hydrate([struct])
9385

9486
with pytest.warns(DeprecationWarning, match="element_id"):
95-
assert rel.id == id_
87+
assert rel.id == 123
9688
with pytest.warns(DeprecationWarning, match="element_id"):
97-
assert rel.start_node.id == start_id
89+
assert rel.start_node.id == 456
9890
with pytest.warns(DeprecationWarning, match="element_id"):
99-
assert rel.end_node.id == end_id
91+
assert rel.end_node.id == 789
10092
# for backwards compatibility, the driver should compy the element_id
10193
assert rel.element_id == "abc"
10294
assert rel.start_node.element_id == "def"
@@ -125,7 +117,8 @@ def test_can_hydrate_in_list():
125117

126118
alice, = alice_in_list
127119

128-
assert alice.id == 123
120+
with pytest.warns(DeprecationWarning, match="element_id"):
121+
assert alice.id == 123
129122
assert alice.labels == {"Person"}
130123
assert set(alice.keys()) == {"name"}
131124
assert alice.get("name") == "Alice"
@@ -141,7 +134,8 @@ def test_can_hydrate_in_dict():
141134

142135
alice = alice_in_dict["foo"]
143136

144-
assert alice.id == 123
137+
with pytest.warns(DeprecationWarning, match="element_id"):
138+
assert alice.id == 123
145139
assert alice.labels == {"Person"}
146140
assert set(alice.keys()) == {"name"}
147141
assert alice.get("name") == "Alice"

tests/unit/common/test_record.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ def test_data_relationship():
287287
gh = Graph.Hydrator(g)
288288
alice = gh.hydrate_node(1, {"Person"}, {"name": "Alice", "age": 33})
289289
bob = gh.hydrate_node(2, {"Person"}, {"name": "Bob", "age": 44})
290-
alice_knows_bob = gh.hydrate_relationship(1, alice.id, bob.id, "KNOWS",
290+
alice_knows_bob = gh.hydrate_relationship(1, 1, 2, "KNOWS",
291291
{"since": 1999})
292292
record = Record(zip(["a", "b", "r"], [alice, bob, alice_knows_bob]))
293293
assert record.data() == {

0 commit comments

Comments
 (0)