Skip to content

Commit 9b10f67

Browse files
authored
Python 3.11 support (#435)
* WIP: Python 3.11 support * put in temp warning in test_frame.py * fix pyright up to 1.1.279 * fix bounds test in test_frame.py:test_generic * change bound on test to 3.10.99 * change strings to comments related to unavailability * test with pandas 1.5.2, pyright 1.1.281 * remove pyarrow checks for python 3.11 * update github action to get rid of github set-output warning
1 parent b7163c2 commit 9b10f67

File tree

6 files changed

+61
-12
lines changed

6 files changed

+61
-12
lines changed

.github/setup/action.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ runs:
2121

2222
- name: Determine poetry version
2323
shell: bash
24-
run: echo "::set-output name=VERSION::$(poetry --version)"
24+
run: echo "{VERSION}=$(poetry --version)"
2525
id: poetry_version
2626

2727
- name: Cache poetry.lock

.github/workflows/test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
fail-fast: false
1515
matrix:
1616
os: [ubuntu-latest, windows-latest, macos-latest]
17-
python-version: ['3.8', '3.9', '3.10.6']
17+
python-version: ['3.8', '3.9', '3.10.6', '3.11']
1818

1919
steps:
2020
- uses: actions/checkout@v3

pyproject.toml

+8-7
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ classifiers = [
1919
"Programming Language :: Python :: 3.8",
2020
"Programming Language :: Python :: 3.9",
2121
"Programming Language :: Python :: 3.10",
22+
"Programming Language :: Python :: 3.11",
2223
"Topic :: Scientific/Engineering"
2324
]
2425
packages = [
@@ -30,26 +31,26 @@ packages = [
3031
"Documentation" = "https://pandas.pydata.org/pandas-docs/stable"
3132

3233
[tool.poetry.dependencies]
33-
python = ">=3.8,<3.11"
34+
python = ">=3.8,<3.12"
3435
types-pytz = ">= 2022.1.1"
3536

3637
[tool.poetry.dev-dependencies]
3738
mypy = "0.990"
38-
pyarrow = ">=9.0.0"
39+
pyarrow = ">=10.0.1"
3940
pytest = ">=7.1.2"
40-
pyright = ">=1.1.278"
41+
pyright = ">=1.1.281"
4142
poethepoet = "0.16.0"
4243
loguru = ">=0.6.0"
43-
pandas = "1.5.1"
44+
pandas = "1.5.2"
4445
typing-extensions = ">=4.2.0"
4546
matplotlib = ">=3.5.1"
4647
pre-commit = ">=2.19.0"
4748
black = ">=22.8.0"
4849
isort = ">=5.10.1"
4950
openpyxl = ">=3.0.10"
50-
tables = ">=3.7.0"
51-
lxml = ">=4.7.1,<4.9.0"
52-
pyreadstat = ">=1.1.9"
51+
tables = { version = ">=3.7.0", python = "<3.11" }
52+
lxml = { version = ">=4.7.1,<4.9.0", python = "<3.11" }
53+
pyreadstat = ">=1.2.0"
5354
xlrd = ">=2.0.1"
5455
pyxlsb = ">=1.0.9"
5556
odfpy = ">=1.4.1"

tests/__init__.py

+28-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
)
77
import os
88
import platform
9+
import sys
910
from typing import (
1011
TYPE_CHECKING,
1112
Final,
@@ -21,6 +22,16 @@
2122
WINDOWS = os.name == "nt" or "cygwin" in platform.system().lower()
2223
PD_LTE_15 = Version(pd.__version__) < Version("1.5.999")
2324

25+
lxml_skip = pytest.mark.skipif(
26+
sys.version_info >= (3, 11), reason="lxml is not available for 3.11 yet"
27+
)
28+
# This is only needed temporarily due to no wheels being available for lxml on 3.11
29+
30+
pytables_skip = pytest.mark.skipif(
31+
sys.version_info >= (3, 11), reason="pytables is not available for 3.11 yet"
32+
)
33+
# This is only needed temporarily due to no wheels being available for pytables on 3.11
34+
2435

2536
def check(actual: T, klass: type, dtype: type | None = None, attr: str = "left") -> T:
2637
if not isinstance(actual, klass):
@@ -44,6 +55,7 @@ def pytest_warns_bounded(
4455
match: str,
4556
lower: str | None = None,
4657
upper: str | None = None,
58+
version_str: str | None = None,
4759
) -> AbstractContextManager:
4860
"""
4961
Version conditional pytest.warns context manager
@@ -62,11 +74,14 @@ def pytest_warns_bounded(
6274
The lower bound of the version to check for the warning.
6375
upper : str, optional
6476
The upper bound of the version to check for the warning.
77+
version_str: str, optional
78+
The version string to use. If None, then uses the pandas version.
79+
Can be used to check a python version as well
6580
6681
Notes
6782
-----
6883
The lower and upper bounds are exclusive so that a pytest.warns context
69-
manager is returned if lower < pd.__version__ < upper.
84+
manager is returned if lower < version_str < upper.
7085
7186
Examples
7287
--------
@@ -85,10 +100,21 @@ def pytest_warns_bounded(
85100
):
86101
# Versions between 1.3.x and 1.5.x will raise an error
87102
pass
103+
104+
with pytest_warns_bounded(
105+
UserWarning, match="foo", lower="3.10",
106+
version_str = platform.python_version()
107+
):
108+
# Python version 3.11 and above will raise an error
109+
# if the warning is not issued
110+
pass
88111
"""
89112
lb = Version("0.0.0") if lower is None else Version(lower)
90113
ub = Version("9999.0.0") if upper is None else Version(upper)
91-
current = Version(pd.__version__)
114+
if version_str is None:
115+
current = Version(pd.__version__)
116+
else:
117+
current = Version(version_str)
92118
if lb < current < ub:
93119
return pytest.warns(warning, match=match)
94120
else:

tests/test_frame.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import io
77
import itertools
88
from pathlib import Path
9+
import platform
910
from typing import (
1011
TYPE_CHECKING,
1112
Any,
@@ -1757,7 +1758,15 @@ class MyDataFrame(pd.DataFrame, Generic[T]):
17571758
def func() -> MyDataFrame[int]:
17581759
return MyDataFrame[int]({"foo": [1, 2, 3]})
17591760

1760-
func()
1761+
# This should be fixed in pandas 1.5.2, if
1762+
# https://github.com/pandas-dev/pandas/pull/49736 is included
1763+
with pytest_warns_bounded(
1764+
UserWarning,
1765+
"Pandas doesn't allow columns to be created",
1766+
lower="3.10.99",
1767+
version_str=platform.python_version(),
1768+
):
1769+
func()
17611770

17621771

17631772
def test_to_xarray():

tests/test_io.py

+13
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@
6565
from pandas.io.sas.sas_xport import XportReader
6666
from pandas.io.stata import StataReader
6767

68+
from . import (
69+
lxml_skip,
70+
pytables_skip,
71+
)
72+
6873
DF = DataFrame({"a": [1, 2, 3], "b": [0.0, 0.0, 0.0]})
6974
CWD = os.path.split(os.path.abspath(__file__))[0]
7075

@@ -108,6 +113,7 @@ def test_orc_bytes():
108113
check(assert_type(DF.to_orc(index=False), bytes), bytes)
109114

110115

116+
@lxml_skip
111117
def test_xml():
112118
with ensure_clean() as path:
113119
check(assert_type(DF.to_xml(path), None), type(None))
@@ -116,6 +122,7 @@ def test_xml():
116122
check(assert_type(read_xml(f), DataFrame), DataFrame)
117123

118124

125+
@lxml_skip
119126
def test_xml_str():
120127
with ensure_clean() as path:
121128
check(assert_type(DF.to_xml(), str), str)
@@ -282,12 +289,14 @@ def test_sas_xport() -> None:
282289
pass
283290

284291

292+
@pytables_skip
285293
def test_hdf():
286294
with ensure_clean() as path:
287295
check(assert_type(DF.to_hdf(path, "df"), None), type(None))
288296
check(assert_type(read_hdf(path), Union[DataFrame, Series]), DataFrame)
289297

290298

299+
@pytables_skip
291300
def test_hdfstore():
292301
with ensure_clean() as path:
293302
store = HDFStore(path, model="w")
@@ -329,6 +338,7 @@ def test_hdfstore():
329338
store.close()
330339

331340

341+
@pytables_skip
332342
def test_read_hdf_iterator():
333343
with ensure_clean() as path:
334344
check(assert_type(DF.to_hdf(path, "df", format="table"), None), type(None))
@@ -343,6 +353,7 @@ def test_read_hdf_iterator():
343353
ti.close()
344354

345355

356+
@pytables_skip
346357
def test_hdf_context_manager():
347358
with ensure_clean() as path:
348359
check(assert_type(DF.to_hdf(path, "df", format="table"), None), type(None))
@@ -351,6 +362,7 @@ def test_hdf_context_manager():
351362
check(assert_type(store.get("df"), Union[DataFrame, Series]), DataFrame)
352363

353364

365+
@pytables_skip
354366
def test_hdf_series():
355367
s = DF["a"]
356368
with ensure_clean() as path:
@@ -795,6 +807,7 @@ def test_read_sql_query_generator():
795807
con.close()
796808

797809

810+
@lxml_skip
798811
def test_read_html():
799812
check(assert_type(DF.to_html(), str), str)
800813
with ensure_clean() as path:

0 commit comments

Comments
 (0)