Skip to content

Clean-ups and meta data bump for 6.0 #1200

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jul 16, 2025
Merged
14 changes: 7 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ See also https://github.com/neo4j/neo4j-python-driver/wiki for a full changelog.
- It is now the same error raised as when trying to start an explicit transaction while another explicit transaction
is already active.
- Slightly change `Neo4jError` and `ClientError`:
- Properties `message` and `code` are always a `str` (instead of `str | None`).
- Remove possibility to override/set `message` and `code` properties.
- Remove undocumented, internal methods `Neo4jError.hydrate`, `Neo4jError.invalidates_all_connections`,
and `Neo4jError.is_fatal_during_discovery`.
- Remove deprecated method `Neo4jError.is_retriable`.
Use `Neo4jError.is_retryable` instead.
- Change string representation of `Neo4jError` to include GQL error information.
- Properties `message` and `code` are always a `str` (instead of `str | None`).
- Remove possibility to override/set `message` and `code` properties.
- Remove undocumented, internal methods `Neo4jError.hydrate`, `Neo4jError.invalidates_all_connections`,
and `Neo4jError.is_fatal_during_discovery`.
- Remove deprecated method `Neo4jError.is_retriable`.
Use `Neo4jError.is_retryable` instead.
- Change string representation of `Neo4jError` to include GQL error information.
- Remove deprecated `Record.__getslice__`. This magic method has been removed in Python 3.0.
If you were calling it directly, please use `Record.__getitem__(slice(...))` or simply `record[...]` instead.
- Bookmarks
Expand Down
13 changes: 3 additions & 10 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,10 @@ Neo4j Bolt Driver for Python

This repository contains the official Neo4j driver for Python.

Starting with 5.0, the Neo4j Drivers will be moving to a monthly release
cadence. A minor version will be released on the last Friday of each month so
as to maintain versioning consistency with the core product (Neo4j DBMS) which
has also moved to a monthly cadence.
Driver upgrades within a major version will never contain breaking API changes.

As a policy, patch versions will not be released except on rare occasions. Bug
fixes and updates will go into the latest minor version and users should
upgrade to that. Driver upgrades within a major version will never contain
breaking API changes.

See also: https://neo4j.com/developer/kb/neo4j-supported-versions/
For version compatibility with Neo4j server, please refer to:
https://neo4j.com/developer/kb/neo4j-supported-versions/

+ Python 3.13 supported.
+ Python 3.12 supported.
Expand Down
16 changes: 8 additions & 8 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ Each supported scheme maps to a particular :class:`neo4j.Driver` subclass that i
+------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
| URI Scheme | Driver Object and Setting |
+========================+=======================================================================================================================================+
| bolt | :ref:`bolt-driver-ref` with no encryption. |
| bolt | :ref:`bolt-driver-ref` with no encryption or with custom encryption configuration, see :ref:`driver-configuration-ref`. |
+------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
| bolt+ssc | :ref:`bolt-driver-ref` with encryption (accepts self signed certificates). |
+------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
| bolt+s | :ref:`bolt-driver-ref` with encryption (accepts only certificates signed by a certificate authority), full certificate checks. |
+------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
| neo4j | :ref:`neo4j-driver-ref` with no encryption. |
| neo4j | :ref:`neo4j-driver-ref` with no encryption or with custom encryption configuration, see :ref:`driver-configuration-ref`. |
+------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
| neo4j+ssc | :ref:`neo4j-driver-ref` with encryption (accepts self signed certificates). |
+------------------------+---------------------------------------------------------------------------------------------------------------------------------------+
Expand Down Expand Up @@ -799,9 +799,8 @@ For example:
self.driver.close()

Connection details held by the :class:`neo4j.Driver` are immutable.
Therefore if, for example, a password is changed, a replacement :class:`neo4j.Driver` object must be created.
More than one :class:`.Driver` may be required if connections to multiple remotes, or connections as multiple users, are required,
unless when using impersonation (:ref:`impersonated-user-ref`).
Therefore if, for example, the server URI is changed, a replacement :class:`neo4j.Driver` object must be created.
More than one :class:`.Driver` may be required if connections to multiple remotes.

:class:`neo4j.Driver` objects are thread-safe but cannot be shared across processes.
Therefore, ``multithreading`` should generally be preferred over ``multiprocessing`` for parallel database access.
Expand Down Expand Up @@ -959,7 +958,8 @@ more information.
:class:`neo4j.Bookmarks` object instead.

.. versionchanged:: 6.0
Only accepts :class:`neo4j.Bookmarks` objects or :data:`None`.
No longer accepts an iterable of strings.
Pass a :class:`neo4j.Bookmarks` objects or :data:`None` instead.


.. _database-ref:
Expand All @@ -980,7 +980,7 @@ Name of the database to query.
straightforward way and potentially simplifies driver logic as well as
reduces network communication resulting in better performance.

Usage of Cypher clauses like `USE` is not a replacement for this option.
Usage of Cypher clauses like ``USE`` is not a replacement for this option.
The driver does not parse any Cypher.

When no explicit name is set, the driver behavior depends on the connection
Expand Down Expand Up @@ -1379,7 +1379,7 @@ Example:

.. _managed-transactions-ref:

Managed Transactions (`transaction functions`)
Managed Transactions (*transaction functions*)
==============================================
Transaction functions are the most powerful form of transaction, providing access mode override and retry capabilities.

Expand Down
10 changes: 4 additions & 6 deletions docs/source/async_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ Each supported scheme maps to a particular :class:`neo4j.AsyncDriver` subclass t
+------------------------+---------------------------------------------------------------------------------------------------------------------------------------------+
| URI Scheme | Driver Object and Setting |
+========================+=============================================================================================================================================+
| bolt | :ref:`async-bolt-driver-ref` with no encryption. |
| bolt | :ref:`async-bolt-driver-ref` with no encryption or with custom encryption configuration, see :ref:`async-driver-configuration-ref`. |
+------------------------+---------------------------------------------------------------------------------------------------------------------------------------------+
| bolt+ssc | :ref:`async-bolt-driver-ref` with encryption (accepts self signed certificates). |
+------------------------+---------------------------------------------------------------------------------------------------------------------------------------------+
| bolt+s | :ref:`async-bolt-driver-ref` with encryption (accepts only certificates signed by a certificate authority), full certificate checks. |
+------------------------+---------------------------------------------------------------------------------------------------------------------------------------------+
| neo4j | :ref:`async-neo4j-driver-ref` with no encryption. |
| neo4j | :ref:`async-neo4j-driver-ref` with no encryption or with custom encryption configuration, see :ref:`async-driver-configuration-ref`. |
+------------------------+---------------------------------------------------------------------------------------------------------------------------------------------+
| neo4j+ssc | :ref:`async-neo4j-driver-ref` with encryption (accepts self signed certificates). |
+------------------------+---------------------------------------------------------------------------------------------------------------------------------------------+
Expand Down Expand Up @@ -487,9 +487,7 @@ For example:
await self.driver.close()

Connection details held by the :class:`neo4j.AsyncDriver` are immutable.
Therefore if, for example, a password is changed, a replacement :class:`neo4j.AsyncDriver` object must be created.
More than one :class:`.AsyncDriver` may be required if connections to multiple remotes, or connections as multiple users, are required,
unless when using impersonation (:ref:`impersonated-user-ref`).
Therefore if, for example, the server URI is changed, a replacement :class:`neo4j.AsyncDriver` object must be created.

:class:`neo4j.AsyncDriver` objects are safe to be used in concurrent coroutines.
They are not thread-safe.
Expand Down Expand Up @@ -837,7 +835,7 @@ Example:
.. _async-managed-transactions-ref:


Managed Transactions (`transaction functions`)
Managed Transactions (*transaction functions*)
==============================================
Transaction functions are the most powerful form of transaction, providing access mode override and retry capabilities.

Expand Down
1 change: 0 additions & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ Specifically for this driver, this will:
* enable :class:`DeprecationWarning`, which the driver emits if deprecated APIs are used.
* enable the driver's debug mode (this can also be achieved by setting the environment variable ``PYTHONNEO4JDEBUG``):

It might be changed or removed any time even without prior notice.
* the driver will raise an exception if non-concurrency-safe methods are used concurrently.
* the driver will emit warnings if the server sends back notification
(see also :ref:`driver-warn-notification-severity-ref`).
Expand Down
3 changes: 0 additions & 3 deletions src/neo4j/_addressing.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,6 @@ def __str__(self) -> str:
return "[{}]:{}".format(*self)


# TODO: 6.0 - make this class private
class ResolvedAddress(Address):
_unresolved_host_name: str

Expand All @@ -360,11 +359,9 @@ def __new__(cls, iterable, *, host_name: str) -> ResolvedAddress:
return new


# TODO: 6.0 - make this class private
class ResolvedIPv4Address(IPv4Address, ResolvedAddress):
pass


# TODO: 6.0 - make this class private
class ResolvedIPv6Address(IPv6Address, ResolvedAddress):
pass
8 changes: 4 additions & 4 deletions src/neo4j/_async/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ class AsyncPoolConfig(Config):
trusted_certificates = TrustSystemCAs()
# Specify how to determine the authenticity of encryption certificates
# provided by the Neo4j instance on connection.
# * `neo4j.TrustSystemCAs()`: Use system trust store. (default)
# * `neo4j.TrustAll()`: Trust any certificate.
# * `neo4j.TrustCustomCAs("<path>", ...)`:
# * ``neo4j.TrustSystemCAs()``: Use system trust store. (default)
# * ``neo4j.TrustAll()``: Trust any certificate.
# * ``neo4j.TrustCustomCAs("<path>", ...)``:
# Trust the specified certificate(s).

#: Certificate to use for mTLS as 2nd authentication factor.
Expand All @@ -78,7 +78,7 @@ class AsyncPoolConfig(Config):
#: Custom SSL context to use for wrapping sockets
ssl_context = None
# Use any custom SSL context to wrap sockets.
# Overwrites `trusted_certificates` and `encrypted`.
# Overwrites ``trusted_certificates`` and ``encrypted``.
# The use of this option is strongly discouraged.

#: User Agent (Python Driver Specific)
Expand Down
22 changes: 11 additions & 11 deletions src/neo4j/_async/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,18 +301,18 @@ def bookmark_manager(
driver = neo4j.AsyncGraphDatabase.driver(...)
bookmark_manager = neo4j.AsyncGraphDatabase.bookmark_manager(...)

async with driver.session(
bookmark_manager=bookmark_manager
) as session1:
async with driver.session(
async with (
driver.session(bookmark_manager=bookmark_manager) as session1,
driver.session(
bookmark_manager=bookmark_manager,
access_mode=neo4j.READ_ACCESS
) as session2:
result1 = await session1.run("<WRITE_QUERY>")
await result1.consume()
# READ_QUERY is guaranteed to see what WRITE_QUERY wrote.
result2 = await session2.run("<READ_QUERY>")
await result2.consume()
default_access_mode=neo4j.READ_ACCESS,
) as session2,
):
result1 = await session1.run("<WRITE_QUERY>")
await result1.consume()
# READ_QUERY is guaranteed to see what WRITE_QUERY wrote.
result2 = await session2.run("<READ_QUERY>")
await result2.consume()

This is a very contrived example, and in this particular case, having
both queries in the same session has the exact same effect and might
Expand Down
4 changes: 2 additions & 2 deletions src/neo4j/_async/io/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"""
Low-level functionality required for speaking Bolt.

It is not intended to be used directly by driver users. Instead, the `session`
module provides the main user-facing abstractions.
It is not intended to be used directly by driver users. Instead, the
``session`` module provides the main user-facing abstractions.
"""

__all__ = [
Expand Down
5 changes: 3 additions & 2 deletions src/neo4j/_async/io/_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,7 @@ async def update_routing_table(
:param acquisition_timeout: connection acquisition timeout
:param database_callback: A callback function that will be called with
the database name as only argument when a new routing table has
been acquired. This database name might different from `database`
been acquired. This database name might different from ``database``
if that was None and the underlying protocol supports reporting
back the actual database.

Expand Down Expand Up @@ -1062,7 +1062,8 @@ async def ensure_routing_table_is_fresh(

This method is thread-safe.

:returns: `True` if an update was required, `False` otherwise.
:returns:
:data:`True` if an update was required, :data:`False` otherwise.
"""
async with self.refresh_lock:
for database_ in list(self.routing_tables.keys()):
Expand Down
13 changes: 7 additions & 6 deletions src/neo4j/_async/work/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ async def _attach(self):

async def _buffer(self, n=None):
"""
Try to fill `self._record_buffer` with n records.
Try to fill ``self._record_buffer`` with n records.

Might end up with more records in the buffer if the fetch size makes it
overshoot.
Expand Down Expand Up @@ -589,9 +589,10 @@ async def single(self, strict: bool = False) -> Record | None:
emit a warning and return the first record.

:param strict:
If :data:`True`, raise a :exc:`.ResultNotSingleError` instead of
returning :data:`None` if there is more than one record or warning
if there is more than 1 record.
If :data:`False`, return :data:`None` if there is no record and
emit a warning if there is more than 1 record.
If :data:`True`, raise a :exc:`.ResultNotSingleError` if there is
not exactly one record.
:data:`False` by default.
:type strict: bool

Expand Down Expand Up @@ -817,7 +818,7 @@ async def to_df(
r"""
Convert (the rest of) the result to a pandas DataFrame.

This method is only available if the `pandas` library is installed.
This method is only available if the ``pandas`` library is installed.

::

Expand Down Expand Up @@ -897,7 +898,7 @@ async def to_df(
If :data:`False`, columns of the above types will be left as driver
types (dtype ``object``).

:raises ImportError: if `pandas` library is not available.
:raises ImportError: if the ``pandas`` library is not available.
:raises ResultConsumedError: if the transaction from which this result
was obtained has been closed or the Result has been explicitly
consumed.
Expand Down
16 changes: 8 additions & 8 deletions src/neo4j/_async/work/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class AsyncSession(AsyncWorkspace):
Therefore, a session should generally be short-lived, and must not
span multiple threads/asynchronous Tasks.

In general, sessions will be created and destroyed within a `with`
In general, sessions will be created and destroyed within a ``with``
context. For example::

async with driver.session(database="neo4j") as session:
Expand Down Expand Up @@ -604,7 +604,7 @@ async def execute_read(
This transaction will automatically be committed when the function
returns, unless an exception is thrown during query execution or by
the user code. Note, that this function performs retries and that the
supplied `transaction_function` might get invoked more than once.
supplied ``transaction_function`` might get invoked more than once.
Therefore, it needs to be idempotent (i.e., have the same effect,
regardless if called once or many times).

Expand Down Expand Up @@ -644,12 +644,12 @@ async def get_two_tx(tx):
:class:`.AsyncManagedTransaction`.
:type transaction_function:
typing.Callable[[AsyncManagedTransaction, P], typing.Awaitable[R]]
:param args: additional arguments for the `transaction_function`
:param args: additional arguments for the ``transaction_function``
:type args: P
:param kwargs: key word arguments for the `transaction_function`
:param kwargs: key word arguments for the ``transaction_function``
:type kwargs: P

:returns: whatever the given `transaction_function` returns
:returns: whatever the given ``transaction_function`` returns
:rtype: R

:raises SessionError: if the session has been closed.
Expand Down Expand Up @@ -683,7 +683,7 @@ async def execute_write(
This transaction will automatically be committed when the function
returns unless, an exception is thrown during query execution or by
the user code. Note, that this function performs retries and that the
supplied `transaction_function` might get invoked more than once.
supplied ``transaction_function`` might get invoked more than once.
Therefore, it needs to be idempotent (i.e., have the same effect,
regardless if called once or many times).

Expand All @@ -705,9 +705,9 @@ async def create_node_tx(tx, name):
:class:`.AsyncManagedTransaction`.
:type transaction_function:
typing.Callable[[AsyncManagedTransaction, P], typing.Awaitable[R]]
:param args: additional arguments for the `transaction_function`
:param args: additional arguments for the ``transaction_function``
:type args: P
:param kwargs: key word arguments for the `transaction_function`
:param kwargs: key word arguments for the ``transaction_function``
:type kwargs: P

:returns: a result as returned by the given unit of work
Expand Down
Loading