diff --git a/docs/source/index.rst b/docs/source/index.rst index abffa3af..ac13f381 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 b875838a..18552451 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 3c2d9e73..62d4d206 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 bcd02c33..dbffb9f9 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 e59ceda1..c7225032 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 134c0924..076216d3 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 cdf49af0..245cc850 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 4bebeb6a..7affca02 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 9727c1be..d38ccc4f 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 b56aefaa..16bf1ecb 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 f31fae52..606bec65 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_*