From 077e5ec9852f926b08521dd75412b14018f6dbdb Mon Sep 17 00:00:00 2001 From: Robsdedude Date: Thu, 6 Nov 2025 14:55:25 +0100 Subject: [PATCH] Python 3.14 --- docs/source/index.rst | 1 + pyproject.toml | 5 +++-- src/neo4j/_async/io/_bolt.py | 3 ++- src/neo4j/_async/io/_common.py | 5 +++-- src/neo4j/_async_compat/util.py | 2 +- src/neo4j/_sync/io/_bolt.py | 3 ++- src/neo4j/_sync/io/_common.py | 5 +++-- src/neo4j/_warnings.py | 9 +++++---- testkit/Dockerfile | 2 +- tests/conftest.py | 3 ++- tox.ini | 2 +- 11 files changed, 24 insertions(+), 16 deletions(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index abffa3afb..ac13f3815 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -19,6 +19,7 @@ See https://neo4j.com/developer/kb/neo4j-supported-versions/ for a driver-server Python versions supported: +* Python 3.14 * Python 3.13 * Python 3.12 * Python 3.11 diff --git a/pyproject.toml b/pyproject.toml index b875838ac..185524513 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Database", "Topic :: Software Development", "Typing :: Typed", @@ -59,7 +60,7 @@ pandas = [ "pandas >= 1.1.0, < 3.0.0", "numpy >= 1.21.2, < 3.0.0", ] -pyarrow = ["pyarrow >= 6.0.0, < 22.0.0"] +pyarrow = ["pyarrow >= 6.0.0, < 23.0.0"] [build-system] @@ -151,7 +152,7 @@ dep-project-dependencies = [ "pytz", "numpy >= 1.7.0, < 3.0.0", "pandas >= 1.1.0, < 3.0.0", - "pyarrow >= 6.0.0, < 22.0.0", + "pyarrow >= 6.0.0, < 23.0.0", ] [tool.setuptools.dynamic] diff --git a/src/neo4j/_async/io/_bolt.py b/src/neo4j/_async/io/_bolt.py index 3c2d9e73b..62d4d206b 100644 --- a/src/neo4j/_async/io/_bolt.py +++ b/src/neo4j/_async/io/_bolt.py @@ -18,6 +18,7 @@ import abc import asyncio +import inspect from collections import deque from logging import getLogger from time import monotonic @@ -198,7 +199,7 @@ def __init__( ) def __del__(self): - if not asyncio.iscoroutinefunction(self.close): + if not inspect.iscoroutinefunction(self.close): self.close() @abc.abstractmethod diff --git a/src/neo4j/_async/io/_common.py b/src/neo4j/_async/io/_common.py index bcd02c334..dbffb9f9f 100644 --- a/src/neo4j/_async/io/_common.py +++ b/src/neo4j/_async/io/_common.py @@ -15,6 +15,7 @@ import asyncio +import inspect import logging from contextlib import suppress from struct import pack as struct_pack @@ -191,7 +192,7 @@ def inner(*args, **kwargs): try: func(*args, **kwargs) except (Neo4jError, ServiceUnavailable, SessionExpired) as exc: - assert not asyncio.iscoroutinefunction(self.__on_error) + assert not inspect.iscoroutinefunction(self.__on_error) self.__on_error(exc) raise @@ -212,7 +213,7 @@ async def inner(*args, **kwargs): return inner - if asyncio.iscoroutinefunction(connection_attr): + if inspect.iscoroutinefunction(connection_attr): return outer_async(connection_attr) return outer(connection_attr) diff --git a/src/neo4j/_async_compat/util.py b/src/neo4j/_async_compat/util.py index e59ceda1f..c72250329 100644 --- a/src/neo4j/_async_compat/util.py +++ b/src/neo4j/_async_compat/util.py @@ -67,7 +67,7 @@ async def callback(cb, *args, **kwargs): @staticmethod def shielded(coro_function): - assert asyncio.iscoroutinefunction(coro_function) + assert inspect.iscoroutinefunction(coro_function) @wraps(coro_function) async def shielded_function(*args, **kwargs): diff --git a/src/neo4j/_sync/io/_bolt.py b/src/neo4j/_sync/io/_bolt.py index 134c09248..076216d3e 100644 --- a/src/neo4j/_sync/io/_bolt.py +++ b/src/neo4j/_sync/io/_bolt.py @@ -18,6 +18,7 @@ import abc import asyncio +import inspect from collections import deque from logging import getLogger from time import monotonic @@ -198,7 +199,7 @@ def __init__( ) def __del__(self): - if not asyncio.iscoroutinefunction(self.close): + if not inspect.iscoroutinefunction(self.close): self.close() @abc.abstractmethod diff --git a/src/neo4j/_sync/io/_common.py b/src/neo4j/_sync/io/_common.py index cdf49af02..245cc8509 100644 --- a/src/neo4j/_sync/io/_common.py +++ b/src/neo4j/_sync/io/_common.py @@ -15,6 +15,7 @@ import asyncio +import inspect import logging from contextlib import suppress from struct import pack as struct_pack @@ -191,7 +192,7 @@ def inner(*args, **kwargs): try: func(*args, **kwargs) except (Neo4jError, ServiceUnavailable, SessionExpired) as exc: - assert not asyncio.iscoroutinefunction(self.__on_error) + assert not inspect.iscoroutinefunction(self.__on_error) self.__on_error(exc) raise @@ -212,7 +213,7 @@ def inner(*args, **kwargs): return inner - if asyncio.iscoroutinefunction(connection_attr): + if inspect.iscoroutinefunction(connection_attr): return outer_async(connection_attr) return outer(connection_attr) diff --git a/src/neo4j/_warnings.py b/src/neo4j/_warnings.py index 4bebeb6ac..7affca020 100644 --- a/src/neo4j/_warnings.py +++ b/src/neo4j/_warnings.py @@ -16,9 +16,8 @@ from __future__ import annotations -import asyncio +import inspect from functools import wraps -from inspect import isclass from warnings import warn from . import _typing as t @@ -98,7 +97,7 @@ def _make_warning_decorator( warning_func: _WarningFunc, ) -> t.Callable[[_FuncT], _FuncT]: def decorator(f): - if asyncio.iscoroutinefunction(f): + if inspect.iscoroutinefunction(f): @wraps(f) async def inner(*args, **kwargs): @@ -107,7 +106,8 @@ async def inner(*args, **kwargs): inner._without_warning = f return inner - if isclass(f): + + if inspect.isclass(f): if hasattr(f, "__init__"): original_init = f.__init__ @@ -125,6 +125,7 @@ def _without_warning(cls, *args, **kwargs): f._without_warning = classmethod(_without_warning) return f raise TypeError("Cannot decorate class without __init__") + else: @wraps(f) diff --git a/testkit/Dockerfile b/testkit/Dockerfile index 9727c1beb..d38ccc4f6 100644 --- a/testkit/Dockerfile +++ b/testkit/Dockerfile @@ -56,7 +56,7 @@ ENV PIP_NO_CACHE_DIR=1 FROM base AS base-py-arg # Install all supported Python versions -ARG PYTHON_VERSIONS="3.13 3.12 3.11 3.10" +ARG PYTHON_VERSIONS="3.14 3.13 3.12 3.11 3.10" FROM base AS base-py-arg-single-python diff --git a/tests/conftest.py b/tests/conftest.py index b56aefaa4..16bf1ecb4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -17,6 +17,7 @@ from __future__ import annotations import asyncio +import inspect import sys from functools import wraps @@ -186,7 +187,7 @@ def neo4j_session(neo4j_driver): @pytest_asyncio.fixture def aio_benchmark(benchmark, event_loop): def _wrapper(func, *args, **kwargs): - if asyncio.iscoroutinefunction(func): + if inspect.iscoroutinefunction(func): @benchmark def _(): diff --git a/tox.ini b/tox.ini index f31fae524..606bec650 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{310,311,312,313}-{unit,integration,performance} +envlist = py{310,311,312,313,314}-{unit,integration,performance} [testenv] passenv = TEST_*