Skip to content

Commit 6a98a8e

Browse files
robsdedudeMaxAake
andauthored
Improve string representations of SummaryCounters (#1233)
Instead of for example {'nodes_created': 42, 'labels_removed': 0, '_contains_system_updates': True} the `repr` string representation is now SummaryCounters({'nodes-created': 42, 'labels-removed': 0, 'contains-system-updates': True}) or similar. This is more in line with Python's recommendations: > If at all possible, this should look like a valid Python expression that > could be used to recreate an object with the same value (given an appropriate > environment). If this is not possible, a string of the form > <...some useful description...> should be returned. > > -- https://docs.python.org/3/reference/datamodel.html#object.__repr__ Further, the `str` representation has been adjusted from for instance {'nodes_created': 42, 'labels_removed': 0, '_contains_system_updates': True} to SummaryCounters{nodes_created: 42, contains_updates: True, contains_system_updates: True} representing all non-default attributes/properties of the object. Co-authored-by: Max Gustafsson <61233757+MaxAake@users.noreply.github.com>
1 parent 54dc5db commit 6a98a8e

File tree

3 files changed

+574
-19
lines changed

3 files changed

+574
-19
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,9 @@ See also https://github.com/neo4j/neo4j-python-driver/wiki for a full changelog.
193193
- The driver incorrectly applied a timeout hint received from the server to both read and write I/O operations.
194194
It is now only applied to read I/O operations.
195195
In turn, a new configuration option `connection_write_timeout` with a default value of `30 seconds` is introduced.
196-
- Adjust `repr` string representation of spatial types to conform with Python's recommendations.
196+
- Adjust string representation(s) of several types:
197+
- `SummaryCounters`: `repr` and `str` to conform with Python's recommendations.
198+
- `Point` and its subclasses: `repr` to conform with Python's recommendations.
197199

198200

199201
## Version 5.28

src/neo4j/_work/summary.py

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,28 @@ def status_precedence(status: GqlStatusObject) -> int:
330330
return self._gql_status_objects
331331

332332

333+
_COUNTER_KEY_TO_ATTR_NAME = {
334+
"nodes-created": "nodes_created",
335+
"nodes-deleted": "nodes_deleted",
336+
"relationships-created": "relationships_created",
337+
"relationships-deleted": "relationships_deleted",
338+
"properties-set": "properties_set",
339+
"labels-added": "labels_added",
340+
"labels-removed": "labels_removed",
341+
"indexes-added": "indexes_added",
342+
"indexes-removed": "indexes_removed",
343+
"constraints-added": "constraints_added",
344+
"constraints-removed": "constraints_removed",
345+
"system-updates": "system_updates",
346+
"contains-updates": "_contains_updates",
347+
"contains-system-updates": "_contains_system_updates",
348+
}
349+
350+
_COUNTER_ATTR_NAME_TO_KEY = {
351+
v: k for k, v in _COUNTER_KEY_TO_ATTR_NAME.items()
352+
}
353+
354+
333355
class SummaryCounters:
334356
"""Contains counters for various operations that a query triggered."""
335357

@@ -373,29 +395,33 @@ class SummaryCounters:
373395
_contains_system_updates = None
374396

375397
def __init__(self, statistics) -> None:
376-
key_to_attr_name = {
377-
"nodes-created": "nodes_created",
378-
"nodes-deleted": "nodes_deleted",
379-
"relationships-created": "relationships_created",
380-
"relationships-deleted": "relationships_deleted",
381-
"properties-set": "properties_set",
382-
"labels-added": "labels_added",
383-
"labels-removed": "labels_removed",
384-
"indexes-added": "indexes_added",
385-
"indexes-removed": "indexes_removed",
386-
"constraints-added": "constraints_added",
387-
"constraints-removed": "constraints_removed",
388-
"system-updates": "system_updates",
389-
"contains-updates": "_contains_updates",
390-
"contains-system-updates": "_contains_system_updates",
391-
}
392398
for key, value in dict(statistics).items():
393-
attr_name = key_to_attr_name.get(key)
399+
attr_name = _COUNTER_KEY_TO_ATTR_NAME.get(key)
394400
if attr_name:
395401
setattr(self, attr_name, value)
396402

397403
def __repr__(self) -> str:
398-
return repr(vars(self))
404+
statistics = {
405+
_COUNTER_ATTR_NAME_TO_KEY[k]: v
406+
for k, v in vars(self).items()
407+
if k in _COUNTER_ATTR_NAME_TO_KEY
408+
}
409+
return f"{self.__class__.__name__}({statistics!r})"
410+
411+
def __str__(self) -> str:
412+
attrs = []
413+
for k, v in vars(self).items():
414+
if k.startswith("_"): # hide private attributes
415+
continue
416+
if hasattr(self.__class__, k) and getattr(self.__class__, k) == v:
417+
# hide default values
418+
continue
419+
attrs.append(f"{k}: {v}")
420+
attrs.append(f"contains_updates: {self.contains_updates}")
421+
attrs.append(
422+
f"contains_system_updates: {self.contains_system_updates}"
423+
)
424+
return f"SummaryCounters{{{', '.join(attrs)}}}"
399425

400426
@property
401427
def contains_updates(self) -> bool:

0 commit comments

Comments
 (0)