Skip to content

Commit 8b5ecdb

Browse files
authored
Merge branch '5.0' into feature/remove-null-tests-for-ids
2 parents 97be40c + 6fe4ea7 commit 8b5ecdb

File tree

26 files changed

+444
-143
lines changed

26 files changed

+444
-143
lines changed

CHANGELOG.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
- Python 3.6 support has been dropped.
77
- `Result`, `Session`, and `Transaction` can no longer be imported from
88
`neo4j.work`. They should've been imported from `neo4j` all along.
9-
Remark: It's recommended to import everything needed directly from `noe4j`,
10-
not its submodules or subpackages.
9+
Remark: It's recommended to import everything needed directly from `noe4j` if
10+
available, not its submodules or subpackages.
1111
- Experimental pipelines feature has been removed.
1212
- Experimental async driver has been added.
1313
- `ResultSummary.server.version_info` has been removed.
@@ -51,9 +51,9 @@
5151
Use `hour_minute_second_nanosecond` instead.
5252
- The property `second` returns an `int` instead of a `float`.
5353
Use `nanosecond` to get the sub-second information.
54-
- Creation of a driver with `bolt[+s[sc]]://` scheme has been deprecated and
55-
will raise an error in the Future. The routing context was and will be
56-
silently ignored until then.
54+
- Creation of a driver with `bolt[+s[sc]]://` scheme and a routing context has
55+
been deprecated and will raise an error in the Future. The routing context was
56+
and will be silently ignored until then.
5757
- Bookmarks
5858
- `Session.last_bookmark` was deprecated. Its behaviour is partially incorrect
5959
and cannot be fixed without breaking its signature.
@@ -94,6 +94,10 @@
9494
- `ServerInfo.connection_id` has been deprecated and will be removed in a
9595
future release. There is no replacement as this is considered internal
9696
information.
97+
- Output of logging helper `neo4j.debug.watch` changes
98+
- ANSI colour codes for log output are now opt-in
99+
- Prepend log format with log-level (if colours are disabled)
100+
- Prepend log format with thread name and id
97101

98102

99103
## Version 4.4

docs/source/api.rst

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,8 @@ For example:
275275
raise gaierror("Unexpected socket address %r" % socket_address)
276276
277277
driver = GraphDatabase.driver("neo4j://example.com:9999",
278-
auth=("neo4j", "password"),
279-
resolver=custom_resolver)
278+
auth=("neo4j", "password"),
279+
resolver=custom_resolver)
280280
281281
282282
:Default: :const:`None`
@@ -541,9 +541,9 @@ Name of the database to query.
541541

542542

543543
.. py:attribute:: neo4j.DEFAULT_DATABASE
544-
:noindex:
544+
:noindex:
545545

546-
This will use the default database on the Neo4j instance.
546+
This will use the default database on the Neo4j instance.
547547

548548

549549
.. Note::
@@ -558,9 +558,10 @@ Name of the database to query.
558558

559559
.. code-block:: python
560560
561-
from neo4j import GraphDatabase
562-
driver = GraphDatabase.driver(uri, auth=(user, password))
563-
session = driver.session(database="system")
561+
from neo4j import GraphDatabase
562+
563+
driver = GraphDatabase.driver(uri, auth=(user, password))
564+
session = driver.session(database="system")
564565
565566
566567
:Default: ``neo4j.DEFAULT_DATABASE``
@@ -593,9 +594,10 @@ context of the impersonated user. For this, the user for which the
593594

594595
.. code-block:: python
595596
596-
from neo4j import GraphDatabase
597-
driver = GraphDatabase.driver(uri, auth=(user, password))
598-
session = driver.session(impersonated_user="alice")
597+
from neo4j import GraphDatabase
598+
599+
driver = GraphDatabase.driver(uri, auth=(user, password))
600+
session = driver.session(impersonated_user="alice")
599601
600602
601603
:Default: :const:`None`
@@ -740,8 +742,8 @@ Example:
740742
def set_person_name(tx, node_id, name):
741743
query = "MATCH (a:Person) WHERE id(a) = $id SET a.name = $name"
742744
result = tx.run(query, id=node_id, name=name)
743-
info = result.consume()
744-
# use the info for logging etc.
745+
summary = result.consume()
746+
# use the summary for logging etc.
745747
746748
.. _managed-transactions-ref:
747749

@@ -1350,6 +1352,49 @@ following code:
13501352
...
13511353
13521354
1355+
*******
1356+
Logging
1357+
*******
1358+
1359+
The driver offers logging for debugging purposes. It is not recommended to
1360+
enable logging for anything other than debugging. For instance, if the driver is
1361+
not able to connect to the database server or if undesired behavior is observed.
1362+
1363+
There are different ways of enabling logging as listed below.
1364+
1365+
Simple Approach
1366+
===============
1367+
1368+
.. autofunction:: neo4j.debug.watch(*logger_names, level=logging.DEBUG, out=sys.stderr, colour=False)
1369+
1370+
Context Manager
1371+
===============
1372+
1373+
.. autoclass:: neo4j.debug.Watcher(*logger_names, default_level=logging.DEBUG, default_out=sys.stderr, colour=False)
1374+
:members:
1375+
:special-members: __enter__, __exit__
1376+
1377+
Full Controll
1378+
=============
1379+
1380+
.. code-block:: python
1381+
1382+
import logging
1383+
import sys
1384+
1385+
# create a handler, e.g. to log to stdout
1386+
handler = logging.StreamHandler(sys.stdout)
1387+
# configure the handler to your liking
1388+
handler.setFormatter(logging.Formatter(
1389+
"%(threadName)s(%(thread)d) %(asctime)s %(message)s"
1390+
))
1391+
# add the handler to the driver's logger
1392+
logging.getLogger("neo4j").addHandler(handler)
1393+
# make sure the logger logs on the desired log level
1394+
logging.getLogger("neo4j").setLevel(logging.DEBUG)
1395+
# from now on, DEBUG logging to stderr is enabled in the driver
1396+
1397+
13531398
*********
13541399
Bookmarks
13551400
*********

docs/source/async_api.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,8 +446,8 @@ Example:
446446
async def set_person_name(tx, node_id, name):
447447
query = "MATCH (a:Person) WHERE id(a) = $id SET a.name = $name"
448448
result = await tx.run(query, id=node_id, name=name)
449-
info = await result.consume()
450-
# use the info for logging etc.
449+
summary = await result.consume()
450+
# use the summary for logging etc.
451451
452452
.. _async-managed-transactions-ref:
453453

docs/source/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757

5858
# General information about the project.
5959
project = 'Neo4j Python Driver'
60-
copyright = '2002-2020 Neo4j, Inc.'
60+
copyright = 'Neo4j, Inc.'
6161
author = 'Neo4j, Inc.'
6262

6363
# The version info for the project you're documenting, acts as replacement for

docs/source/types/spatial.rst

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Point
1212

1313
.. autoclass:: neo4j.spatial.Point
1414
:show-inheritance:
15-
:members: srid
15+
:members:
1616

1717

1818
CartesianPoint
@@ -21,9 +21,6 @@ CartesianPoint
2121
.. autoclass:: neo4j.spatial.CartesianPoint
2222
:show-inheritance:
2323

24-
.. property:: srid
25-
:type: int
26-
2724
.. property:: x
2825
:type: float
2926

@@ -39,24 +36,28 @@ CartesianPoint
3936

4037
Same value as ``point[2]``.
4138

42-
Only available if the point is in space.
39+
Only available if the point is in 3D space.
4340

4441

4542
Examples
4643
--------
4744

4845
.. code-block:: python
4946
50-
point=CartesianPoint((1.23, 4.56)
47+
from neo4j.spatial import CartesianPoint
5148
52-
print(point.x, point.y)
49+
point = CartesianPoint((1.23, 4.56))
50+
print(point.x, point.y, point.srid)
51+
# 1.23 4.56 7203
5352
5453
5554
.. code-block:: python
5655
57-
point=CartesianPoint((1.23, 4.56, 7.89)
56+
from neo4j.spatial import CartesianPoint
5857
59-
print(point.x, point.y, point.z)
58+
point = CartesianPoint((1.23, 4.56, 7.89))
59+
print(point.x, point.y, point.z, point.srid)
60+
# 1.23 4.56 7.8 9157
6061
6162
6263
WGS84Point
@@ -65,9 +66,6 @@ WGS84Point
6566
.. autoclass:: neo4j.spatial.WGS84Point
6667
:show-inheritance:
6768

68-
.. property:: srid
69-
:type: int
70-
7169
.. property:: x
7270
:type: float
7371

@@ -83,7 +81,7 @@ WGS84Point
8381

8482
Same value as ``point[2]``.
8583

86-
Only available if the point is in space.
84+
Only available if the point is in 3D space.
8785

8886
.. property:: longitude
8987
:type: float
@@ -100,19 +98,25 @@ WGS84Point
10098

10199
Alias for :attr:`.z`.
102100

103-
Only available if the point is in space.
101+
Only available if the point is in 3D space.
104102

105103

106104
Examples
107105
--------
108106

109107
.. code-block:: python
110108
111-
point=WGS84Point((1.23, 4.56))
112-
print(point.longitude, point.latitude)
109+
from neo4j.spatial import WGS84Point
110+
111+
point = WGS84Point((1.23, 4.56))
112+
print(point.longitude, point.latitude, point.srid)
113+
# 1.23 4.56 4326
113114
114115
115116
.. code-block:: python
116117
117-
point=WGS84Point((1.23, 4.56, 7.89))
118-
print(point.longitude, point.latitude, point.height)
118+
from neo4j.spatial import WGS84Point
119+
120+
point = WGS84Point((1.23, 4.56, 7.89))
121+
print(point.longitude, point.latitude, point.height, point.srid)
122+
# 1.23 4.56 7.89 4979

neo4j/_async/io/_bolt.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ def __init__(self, unresolved_address, sock, max_connection_lifetime, *,
100100
auth=None, user_agent=None, routing_context=None):
101101
self.unresolved_address = unresolved_address
102102
self.socket = sock
103+
self.local_port = self.socket.getsockname()[1]
103104
self.server_info = ServerInfo(Address(sock.getpeername()),
104105
self.PROTOCOL_VERSION)
105106
# so far `connection.recv_timeout_seconds` is the only available
@@ -379,11 +380,6 @@ def encrypted(self):
379380
def der_encoded_server_certificate(self):
380381
pass
381382

382-
@property
383-
@abc.abstractmethod
384-
def local_port(self):
385-
pass
386-
387383
@abc.abstractmethod
388384
async def hello(self):
389385
""" Appends a HELLO message to the outgoing queue, sends it and consumes

neo4j/_async/io/_bolt3.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,6 @@ def encrypted(self):
137137
def der_encoded_server_certificate(self):
138138
return self.socket.getpeercert(binary_form=True)
139139

140-
@property
141-
def local_port(self):
142-
try:
143-
return self.socket.getsockname()[1]
144-
except OSError:
145-
return 0
146-
147140
def get_base_headers(self):
148141
return {
149142
"user_agent": self.user_agent,

neo4j/_async/io/_bolt4.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,6 @@ def encrypted(self):
9090
def der_encoded_server_certificate(self):
9191
return self.socket.getpeercert(binary_form=True)
9292

93-
@property
94-
def local_port(self):
95-
try:
96-
return self.socket.getsockname()[1]
97-
except OSError:
98-
return 0
99-
10093
def get_base_headers(self):
10194
return {
10295
"user_agent": self.user_agent,

neo4j/_async/io/_bolt5.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,6 @@ def encrypted(self):
8989
def der_encoded_server_certificate(self):
9090
return self.socket.getpeercert(binary_form=True)
9191

92-
@property
93-
def local_port(self):
94-
try:
95-
return self.socket.getsockname()[1]
96-
except OSError:
97-
return 0
98-
9992
def get_base_headers(self):
10093
headers = {"user_agent": self.user_agent}
10194
if self.routing_context is not None:

neo4j/_async/io/_common.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class AsyncMessageInbox:
4242

4343
def __init__(self, s, on_error):
4444
self.on_error = on_error
45+
self._local_port = s.getsockname()[1]
4546
self._messages = self._yield_messages(s)
4647

4748
async def _yield_messages(self, sock):
@@ -56,7 +57,7 @@ async def _yield_messages(self, sock):
5657
await receive_into_buffer(sock, buffer, 2)
5758
chunk_size = buffer.pop_u16()
5859
if chunk_size == 0:
59-
log.debug("[#%04X] S: <NOOP>", sock.getsockname()[1])
60+
log.debug("[#%04X] S: <NOOP>", self._local_port)
6061

6162
await receive_into_buffer(sock, buffer, chunk_size + 2)
6263
chunk_size = buffer.pop_u16()

0 commit comments

Comments
 (0)