diff --git a/CHANGELOG.md b/CHANGELOG.md index 92b011c7..6f5c849b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ See also https://github.com/neo4j/neo4j-python-driver/wiki for a full changelog. ## NEXT RELEASE +- Python 3.13 support added. - Deprecated setting attributes on `Neo4jError` like `message` and `code`. - Deprecated undocumented method `Neo4jError.hydrate`. It's internal and should not be used by client code. diff --git a/README.rst b/README.rst index ac95a3ef..71d58699 100644 --- a/README.rst +++ b/README.rst @@ -16,8 +16,9 @@ breaking API changes. See also: https://neo4j.com/developer/kb/neo4j-supported-versions/ -+ Python 3.12 supported. -+ Python 3.11 supported. ++ Python 3.13 supported (since driver version 5.26.0). ++ Python 3.12 supported (since driver version 5.14.0). ++ Python 3.11 supported (since driver version 5.3.0). + Python 3.10 supported. + Python 3.9 supported. + Python 3.8 supported. diff --git a/docs/source/index.rst b/docs/source/index.rst index d952e9bc..81613c26 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -12,6 +12,7 @@ Neo4j versions supported: Python versions supported: +* Python 3.13 (added in driver version 5.26.0) * Python 3.12 (added in driver version 5.14.0) * Python 3.11 (added in driver version 5.3.0) * Python 3.10 diff --git a/pyproject.toml b/pyproject.toml index d3b37929..dbace833 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,7 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Database", "Topic :: Software Development", "Typing :: Typed", diff --git a/requirements-dev.txt b/requirements-dev.txt index 49624fd1..ae3f9270 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -30,4 +30,4 @@ tox>=4.0.0 sphinx # needed for BenchKit -sanic>=23.12.1; python_version >= '3.8.0' +sanic>=23.12.1 ; python_version >= '3.8.0' diff --git a/src/neo4j/_async/work/session.py b/src/neo4j/_async/work/session.py index 72f79464..77c0a7bf 100644 --- a/src/neo4j/_async/work/session.py +++ b/src/neo4j/_async/work/session.py @@ -26,7 +26,13 @@ from ..._async_compat import async_sleep from ..._async_compat.util import AsyncUtil from ..._conf import SessionConfig -from ..._meta import deprecated + + +if t.TYPE_CHECKING: + from typing_extensions import deprecated +else: + from ..._meta import deprecated + from ..._util import ContextBool from ..._work import Query from ...api import ( diff --git a/src/neo4j/_data.py b/src/neo4j/_data.py index 2f6abe7f..474ce6a9 100644 --- a/src/neo4j/_data.py +++ b/src/neo4j/_data.py @@ -31,7 +31,13 @@ from ._codec.hydration import BrokenHydrationObject from ._conf import iter_items -from ._meta import deprecated + + +if t.TYPE_CHECKING: + from typing_extensions import deprecated +else: + from ._meta import deprecated + from ._spatial import Point from .exceptions import BrokenRecordError from .graph import ( diff --git a/src/neo4j/_meta.py b/src/neo4j/_meta.py index 657ec2ad..6e2bc787 100644 --- a/src/neo4j/_meta.py +++ b/src/neo4j/_meta.py @@ -111,15 +111,23 @@ def deprecated(message: str) -> t.Callable[[_FuncT], _FuncT]: @deprecated("'foo' has been deprecated in favour of 'bar'") def foo(x): pass - """ - return _make_warning_decorator(message, deprecation_warn) + @property + @deprecated("'bar' will be internal without a replacement") + def bar(self): + return "bar" -def deprecated_property(message: str): - def decorator(f): - return property(deprecated(message)(f)) + @property + def baz(self): + return self._baz - return t.cast(property, decorator) + @baz.setter + @deprecated("'baz' will be read-only in the future") + def baz(self, value): + self._baz = value + + """ + return _make_warning_decorator(message, deprecation_warn) # TODO: 6.0 - remove this class, replace usage with PreviewWarning diff --git a/src/neo4j/_sync/work/session.py b/src/neo4j/_sync/work/session.py index ee23b792..61bd23b8 100644 --- a/src/neo4j/_sync/work/session.py +++ b/src/neo4j/_sync/work/session.py @@ -26,7 +26,13 @@ from ..._async_compat import sleep from ..._async_compat.util import Util from ..._conf import SessionConfig -from ..._meta import deprecated + + +if t.TYPE_CHECKING: + from typing_extensions import deprecated +else: + from ..._meta import deprecated + from ..._util import ContextBool from ..._work import Query from ...api import ( diff --git a/src/neo4j/api.py b/src/neo4j/api.py index cbf0c418..8c93276c 100644 --- a/src/neo4j/api.py +++ b/src/neo4j/api.py @@ -25,7 +25,12 @@ urlparse, ) -from ._meta import deprecated + +if t.TYPE_CHECKING: + from typing_extensions import deprecated +else: + from ._meta import deprecated + from .exceptions import ConfigurationError diff --git a/src/neo4j/spatial/__init__.py b/src/neo4j/spatial/__init__.py index 45590105..022abfd5 100644 --- a/src/neo4j/spatial/__init__.py +++ b/src/neo4j/spatial/__init__.py @@ -16,6 +16,9 @@ """Spatial data types for interchange with the DBMS.""" +from __future__ import annotations + + __all__ = [ "CartesianPoint", "Point", @@ -25,10 +28,17 @@ "point_type", ] +import typing as t from functools import wraps from .._codec.hydration.v1 import spatial as _hydration -from .._meta import deprecated + + +if t.TYPE_CHECKING: + from typing_extensions import deprecated +else: + from .._meta import deprecated + from .._spatial import ( CartesianPoint, Point, diff --git a/testkit/Dockerfile b/testkit/Dockerfile index 0380be61..8b6b9d63 100644 --- a/testkit/Dockerfile +++ b/testkit/Dockerfile @@ -1,12 +1,12 @@ FROM ubuntu:20.04 -ENV DEBIAN_FRONTEND noninteractive +ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y locales && \ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && \ localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 \ && rm -rf /var/lib/apt/lists/* -ENV LANG en_US.UTF-8 +ENV LANG=en_US.UTF-8 # Using apt-get update alone in a RUN statement causes caching issues and subsequent apt-get install instructions fail. RUN apt-get --quiet update && apt-get --quiet install -y \ @@ -38,11 +38,11 @@ RUN update-ca-certificates # Install pyenv RUN git clone https://github.com/pyenv/pyenv.git .pyenv -ENV PYENV_ROOT /.pyenv -ENV PATH $PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH +ENV PYENV_ROOT=/.pyenv +ENV PATH="$PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH" # Setup python version -ENV PYTHON_VERSIONS 3.12 3.11 3.10 3.9 3.8 3.7 +ENV PYTHON_VERSIONS="3.13 3.12 3.11 3.10 3.9 3.8 3.7" RUN for version in $PYTHON_VERSIONS; do \ pyenv install $version; \ @@ -57,3 +57,18 @@ RUN for version in $PYTHON_VERSIONS; do \ python$version -m pip install -U pip && \ python$version -m pip install -U coverage tox; \ done + +# Installing pyarrow lib until pre-built wheel for Python 3.13 exists +# https://github.com/apache/arrow/issues/43519 +RUN apt update && \ + apt install -y -V lsb-release cmake gcc && \ + distro_name=$(lsb_release --id --short | tr 'A-Z' 'a-z') && \ + code_name=$(lsb_release --codename --short) && \ + wget https://apache.jfrog.io/artifactory/arrow/${distro_name}/apache-arrow-apt-source-latest-${code_name}.deb && \ + apt install -y -V ./apache-arrow-apt-source-latest-${code_name}.deb && \ + apt update && \ + apt install -y -V libarrow-dev libarrow-dataset-dev libarrow-flight-dev libparquet-dev && \ + apt clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +ENV PYARROW_WITH_CUDA=off +ENV PYARROW_WITH_GANDIVA=off +ENV PYARROW_PARALLEL=8 diff --git a/tox.ini b/tox.ini index d75274c2..8cc0e0aa 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{37,38,39,310,311,312}-{unit,integration,performance} +envlist = py{37,38,39,310,311,312,313}-{unit,integration,performance} [testenv] passenv = TEST_NEO4J_*