Skip to content

Commit 16e5273

Browse files
committed
Add support for Python 3.12
1 parent fd7206a commit 16e5273

File tree

14 files changed

+42
-23
lines changed

14 files changed

+42
-23
lines changed

docs/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Neo4j versions supported:
1212

1313
Python versions supported:
1414

15+
* Python 3.12 (added in driver version 5.14.0)
1516
* Python 3.11 (added in driver version 5.3.0)
1617
* Python 3.10
1718
* Python 3.9

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,11 @@ pandas = [
5050
"pandas >= 1.1.0, < 3.0.0",
5151
"numpy >= 1.7.0, < 2.0.0",
5252
]
53+
pyarrow = ["pyarrow >= 1.0.0"]
5354

5455
[build-system]
5556
requires = [
56-
"setuptools~=65.6",
57+
"setuptools>=66.1.0",
5758
"tomlkit~=0.11.6",
5859
]
5960
build-backend = "setuptools.build_meta"

requirements-dev.txt

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# the driver itself
2-
-e .[pandas,numpy]
2+
-e .[pandas,numpy,pyarrow]
33

44
# auto-generate sync driver from async code
55
unasync>=0.5.0
@@ -10,16 +10,10 @@ mypy>=0.971
1010
typing-extensions>=4.3.0
1111
types-pytz>=2022.1.2
1212

13-
# for packaging
14-
setuptools~=65.6
15-
# TODO: 6.0 - can be removed once `setup.py` is simplified
16-
tomlkit~=0.11.6
17-
1813
# needed for running tests
1914
coverage[toml]>=5.5
2015
freezegun >= 1.2.2
2116
mock>=4.0.3
22-
pyarrow>=1.0.0
2317
pytest>=6.2.5
2418
pytest-asyncio>=0.16.0
2519
pytest-benchmark>=3.4.1

src/neo4j/_async_compat/concurrency.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ async def acquire(self, blocking=True, timeout=-1):
136136
try:
137137
await wait_for(fut, timeout)
138138
except asyncio.CancelledError:
139+
if fut.cancelled():
140+
raise
139141
already_finished = not fut.cancel()
140142
if already_finished:
141143
# Too late to cancel the acquisition.

src/neo4j/_async_compat/shims/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
# we remove support for Python 3.9.
3131

3232

33-
if sys.version_info >= (3, 8):
33+
if (3, 12) > sys.version_info >= (3, 8):
3434
# copied from Python 3.10's asyncio package with applied patch
3535

3636
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,

testkit/Dockerfile

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,29 @@ ENV PYENV_ROOT /.pyenv
4242
ENV PATH $PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH
4343

4444
# Setup python version
45-
ENV PYTHON_VERSIONS 3.7 3.8 3.9 3.10 3.11
45+
ENV PYTHON_VERSIONS 3.12 3.11 3.10 3.9 3.8 3.7
4646

4747
RUN for version in $PYTHON_VERSIONS; do \
4848
pyenv install $version; \
4949
done
5050
RUN pyenv rehash
51-
RUN pyenv global $(pyenv versions --bare --skip-aliases)
51+
RUN pyenv global $(pyenv versions --bare --skip-aliases | sort --version-sort --reverse)
5252

5353
# Install Latest pip and setuptools for each environment
5454
# + tox and tools for starting the tests
5555
# https://pip.pypa.io/en/stable/news/
5656
RUN for version in $PYTHON_VERSIONS; do \
5757
python$version -m pip install -U pip && \
58-
python$version -m pip install -U setuptools && \
5958
python$version -m pip install -U coverage tox; \
6059
done
60+
61+
# Installing pyarrow lib until pre-built wheel for Python 3.12 exists
62+
# https://github.com/apache/arrow/issues/37880
63+
RUN apt update && \
64+
apt install -y -V lsb-release cmake gcc && \
65+
distro_name=$(lsb_release --id --short | tr 'A-Z' 'a-z') && \
66+
code_name=$(lsb_release --codename --short) && \
67+
wget https://apache.jfrog.io/artifactory/arrow/${distro_name}/apache-arrow-apt-source-latest-${code_name}.deb && \
68+
apt install -y -V ./apache-arrow-apt-source-latest-${code_name}.deb && \
69+
apt update && \
70+
apt install -y -V libarrow-dev # For C++ \

testkit/_common.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ def run(args, env=None):
1515

1616
def run_python(args, env=None, warning_as_error=True):
1717
cmd = [TEST_BACKEND_VERSION, "-u"]
18+
if sys.version_info >= (3, 12):
19+
# Ignore warnings for Python 3.12 for now
20+
# https://github.com/dateutil/dateutil/issues/1284 needs to be released
21+
# and propagate through our dependency graph
22+
warning_as_error = False
1823
if warning_as_error:
1924
cmd += ["-W", "error"]
2025
cmd += list(args)

tests/unit/async_/test_driver.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,7 @@ async def test_execute_query_keyword_parameters(
716716
@pytest.mark.parametrize("parameters", (
717717
{"_": "a"}, {"foo_": None}, {"foo_": 1, "bar_": 2}
718718
))
719+
@mark_async_test
719720
async def test_reserved_query_keyword_parameters(
720721
mocker, parameters: t.Dict[str, t.Any],
721722
) -> None:

tests/unit/async_/work/test_result.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ async def test_data(num_records):
607607
record.data.return_value = expected_data[-1]
608608
assert await result.data("hello", "world") == expected_data
609609
for record in records:
610-
assert record.data.called_once_with("hello", "world")
610+
record.data.assert_called_once_with("hello", "world")
611611

612612

613613
@pytest.mark.parametrize("records", (

tests/unit/mixed/async_compat/test_concurrency.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,6 @@ async def waiter_non_blocking():
225225
assert fut.exception() is exc
226226
awaits += 1
227227

228-
229228
assert not lock.locked()
230229
await asyncio.gather(blocker(), waiter_non_blocking())
231230
assert not lock.locked()

tests/unit/mixed/async_compat/test_shims.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ async def _check_wait_for(wait_for_, should_propagate_cancellation):
4242

4343

4444
@pytest.mark.skipif(
45-
sys.version_info < (3, 8),
46-
reason="wait_for is only broken in Python 3.8+"
45+
not (3, 12) > sys.version_info >= (3, 8),
46+
reason="wait_for is only broken in Python 3.8-3.11 (inclusive)"
4747
)
4848
@mark_async_test
4949
async def test_wait_for_shim_is_necessary_starting_from_3x8():
@@ -56,8 +56,8 @@ async def test_wait_for_shim_is_necessary_starting_from_3x8():
5656

5757

5858
@pytest.mark.skipif(
59-
sys.version_info >= (3, 8),
60-
reason="wait_for is only broken in Python 3.8+"
59+
(3, 12) > sys.version_info >= (3, 8),
60+
reason="wait_for is only broken in Python 3.8-3.11 (inclusive)"
6161
)
6262
@mark_async_test
6363
async def test_wait_for_shim_is_not_necessary_prior_to_3x8():

tests/unit/sync/test_driver.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,7 @@ def test_execute_query_keyword_parameters(
715715
@pytest.mark.parametrize("parameters", (
716716
{"_": "a"}, {"foo_": None}, {"foo_": 1, "bar_": 2}
717717
))
718+
@mark_sync_test
718719
def test_reserved_query_keyword_parameters(
719720
mocker, parameters: t.Dict[str, t.Any],
720721
) -> None:

tests/unit/sync/work/test_result.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ def test_data(num_records):
607607
record.data.return_value = expected_data[-1]
608608
assert result.data("hello", "world") == expected_data
609609
for record in records:
610-
assert record.data.called_once_with("hello", "world")
610+
record.data.assert_called_once_with("hello", "world")
611611

612612

613613
@pytest.mark.parametrize("records", (

tox.ini

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
[tox]
2-
envlist = py{37,38,39,310,311}-{unit,integration,performance}
2+
envlist = py{37,38,39,310,311,312}-{unit,integration,performance}
33

44
[testenv]
55
passenv = TEST_NEO4J_*
66
deps = -r requirements-dev.txt
77
setenv = COVERAGE_FILE={envdir}/.coverage
88
usedevelop = true
9+
# Ignore warnings for Python 3.12 for now
10+
# https://github.com/dateutil/dateutil/issues/1284 needs to be released
11+
# and propagate through our dependency graph
12+
warnargs =
13+
py{37,38,39,310,311}: -W error
14+
py312:
915
commands =
1016
coverage erase
11-
unit: coverage run -m pytest -W error -v {posargs} tests/unit
12-
unit: coverage run -m pytest -v --doctest-modules {posargs} src
13-
integration: coverage run -m pytest -W error -v {posargs} tests/integration
17+
unit: coverage run -m pytest {[testenv]warnargs} -v {posargs} tests/unit
18+
integration: coverage run -m pytest {[testenv]warnargs} -v {posargs} tests/integration
1419
performance: python -m pytest --benchmark-autosave -v {posargs} tests/performance
1520
unit,integration: coverage report

0 commit comments

Comments
 (0)