Skip to content

Commit dfc8b73

Browse files
authored
refactor: moving from deprecated pkg_resources API, bumping requirements, adding 3.12 and 3.13 support (#87)
* build: running edgetest on edgetest * ci: adding 3.12 and 3.13 to our build matrices * test: fixing warning from pytest about our core class * refactor: removing use of deprecated pkg_resources API and moving towards packaging * build: adding 3.12 and 3.13 classifiers to pyproject.toml * chore: bumping version * ci: removing 3.13 support since it doesn't seem well-adopted at the moment * test: moving up the pins for integration test packages since the older versions don't support Python 3.12
1 parent f8b186a commit dfc8b73

File tree

9 files changed

+64
-38
lines changed

9 files changed

+64
-38
lines changed

Diff for: .github/workflows/test-package.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ jobs:
1717
matrix:
1818
os: [ubuntu-latest, windows-latest]
1919
python-version:
20-
- 3.8
2120
- 3.9
2221
- "3.10"
2322
- "3.11"
23+
- "3.12"
2424
steps:
2525
- uses: actions/checkout@v4
2626
- name: Set up Python ${{ matrix.python-version }}

Diff for: docs/source/conf.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
author = "Akshay Gupta"
2525

2626
# The short X.Y version
27-
version = "2024.8.0"
27+
version = "2024.10.0"
2828
# The full version, including alpha/beta/rc tags
2929
release = ""
3030

Diff for: edgetest/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Package initialization."""
22

3-
__version__ = "2024.8.0"
3+
__version__ = "2024.10.0"
44

55
__title__ = "edgetest"
66
__description__ = "Bleeding edge dependency testing"

Diff for: edgetest/core.py

+3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ class TestPackage:
4040
after ``run_tests`` has been executed.
4141
"""
4242

43+
# Tell pytest this isn't for tests
44+
__test__ = False
45+
4346
def __init__(
4447
self,
4548
hook: _HookRelay,

Diff for: edgetest/utils.py

+46-24
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
from subprocess import PIPE, Popen
99
from typing import Any, Dict, List, Optional, Tuple, Union
1010

11-
from packaging.specifiers import SpecifierSet
12-
from pkg_resources import parse_requirements
11+
from packaging.requirements import Requirement
12+
from packaging.specifiers import Specifier, SpecifierSet
1313
from tomlkit import TOMLDocument, load
1414
from tomlkit.container import Container
1515
from tomlkit.items import Array, Item, String, Table
@@ -97,7 +97,11 @@ def convert_requirements(requirements: str, conf: Optional[Dict] = None) -> Dict
9797
A configuration dictionary.
9898
"""
9999
conf = {"envs": []} if conf is None else conf
100-
pkgs = [pkg.project_name for pkg in parse_requirements(requirements)]
100+
pkgs = [
101+
Requirement(val).name
102+
for val in requirements.splitlines()
103+
if not (val.strip().startswith("#") or val.strip() == "")
104+
]
101105
for pkg in pkgs:
102106
conf["envs"].append({})
103107
conf["envs"][-1]["name"] = pkg
@@ -119,7 +123,7 @@ def gen_requirements_config(fname_or_buf: str, **options) -> Dict:
119123
Parameters
120124
----------
121125
fname_or_buf : str
122-
Path to the requirements file to parse using ``pkg_resources.parse_requirements``
126+
Path to the requirements file to parse using ``packaging.requirements.Requirement``
123127
or the string representing the requirements file.
124128
**options
125129
Options to apply to each test environment.
@@ -387,7 +391,7 @@ def upgrade_requirements(
387391
Parameters
388392
----------
389393
fname_or_buf : str
390-
Path to the requirements file to parse using ``pkg_resources.parse_requirements``
394+
Path to the requirements file to parse using ``packaging.requirements.Requirement``
391395
or the string representing the requirements file.
392396
upgraded_packages : list
393397
A list of packages upgraded in the testing procedure.
@@ -407,23 +411,32 @@ def upgrade_requirements(
407411
except OSError:
408412
# Filename too long for the is_file() function
409413
cfg = fname_or_buf
410-
pkgs = list(parse_requirements(cfg))
414+
pkgs = [
415+
Requirement(val)
416+
for val in cfg.splitlines()
417+
if not (val.strip().startswith("#") or val.strip() == "")
418+
]
411419
upgrades = {pkg["name"]: pkg["version"] for pkg in upgraded_packages}
412420

413421
for pkg in pkgs:
414-
if pkg.project_name not in upgrades:
422+
if pkg.name not in upgrades:
415423
continue
416424
# Replace the spec
417-
specs = deepcopy(pkg.specs)
425+
specs = list(pkg.specifier)
426+
new_spec = list(pkg.specifier)
418427
for index, value in enumerate(specs):
419-
if value[0] == "<=":
420-
pkg.specs[index] = ("<=", upgrades[pkg.project_name])
421-
elif value[0] == "<":
422-
pkg.specs[index] = ("!=", value[1])
423-
pkg.specs.append(("<=", upgrades[pkg.project_name]))
424-
elif value[0] == "==":
425-
pkg.specs = [(">=", value[1]), ("<=", upgrades[pkg.project_name])]
426-
pkg.specifier = SpecifierSet(",".join("".join(spec) for spec in pkg.specs)) # type: ignore
428+
if value.operator == "<=":
429+
new_spec[index] = Specifier(f"<={upgrades[pkg.name]}")
430+
elif value.operator == "<":
431+
new_spec[index] = Specifier(f"!={value.version}")
432+
new_spec.append(Specifier(f"<={upgrades[pkg.name]}"))
433+
elif value.operator == "==":
434+
new_spec = Specifier(f">={value.version}") & Specifier(
435+
f"<={upgrades[pkg.name]}"
436+
) # type: ignore
437+
# End the loop
438+
break
439+
pkg.specifier = SpecifierSet(",".join(str(spec) for spec in new_spec))
427440

428441
return "\n".join(str(pkg) for pkg in pkgs)
429442

@@ -522,15 +535,15 @@ def _isin_case_dashhyphen_ins(a: str, vals: List[str]) -> bool:
522535
return any(a.replace("_", "-").lower() == b.replace("_", "-").lower() for b in vals)
523536

524537

525-
def get_lower_bounds(requirements: str, lower: str) -> str:
538+
def get_lower_bounds(requirements: Union[str, List[str]], lower: str) -> str:
526539
r"""Get lower bounds of requested packages from installation requirements.
527540
528541
Parses through the project ``requirements`` and the newline-delimited
529542
packages requested in ``lower`` to find the lower bounds.
530543
531544
Parameters
532545
----------
533-
requirements : str
546+
requirements : str or list
534547
Project setup requirements,
535548
e.g. ``"pandas>=1.5.1,<=1.4.2\nnumpy>=1.22.1,<=1.25.4"``
536549
lower : str
@@ -542,12 +555,21 @@ def get_lower_bounds(requirements: str, lower: str) -> str:
542555
str
543556
The packages along with the lower bound, e.g. ``"pandas==1.5.1\nnumpy==1.22.1"``.
544557
"""
545-
all_lower_bounds = {
546-
pkg.project_name + (f"[{','.join(pkg.extras)}]" if pkg.extras else ""): dict(
547-
pkg.specs
548-
).get(">=")
549-
for pkg in parse_requirements(requirements)
550-
}
558+
if isinstance(requirements, str):
559+
pkgs = [
560+
Requirement(val)
561+
for val in requirements.splitlines()
562+
if not (val.strip().startswith("#") or val.strip() == "")
563+
]
564+
elif isinstance(requirements, list):
565+
pkgs = [Requirement(val) for val in requirements]
566+
all_lower_bounds: Dict[str, str] = {}
567+
for pkg in pkgs:
568+
full_name = pkg.name + (f"[{','.join(pkg.extras)}]" if pkg.extras else "")
569+
for spec in pkg.specifier:
570+
if spec.operator == ">=":
571+
all_lower_bounds[full_name] = spec.version
572+
break
551573

552574
lower_with_bounds = ""
553575
for pkg_name, lower_bound in all_lower_bounds.items():

Diff for: pyproject.toml

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ classifiers = [
1919
"Programming Language :: Python :: 3.9",
2020
"Programming Language :: Python :: 3.10",
2121
"Programming Language :: Python :: 3.11",
22+
"Programming Language :: Python :: 3.12",
2223
]
23-
dependencies = ["Cerberus<=1.3.5,>=1.3.0", "click<=8.1.7,>=7.0", "pluggy<=1.4.0,>=1.3.0", "tabulate<=0.9.0,>=0.8.9", "packaging<=24.0,>20.6", "tomlkit<=0.11.4,>=0.11.4", "uv<=0.2.28,>=0.2.0"]
24+
dependencies = ["Cerberus<=1.3.5,>=1.3.0", "click<=8.1.7,>=7.0", "pluggy<=1.5.0,>=1.3.0", "tabulate<=0.9.0,>=0.8.9", "packaging<=24.1,>20.6", "tomlkit<=0.11.4,>=0.11.4", "uv<=0.4.26,>=0.2.0"]
2425

2526
dynamic = ["readme", "version"]
2627

@@ -93,7 +94,7 @@ lower = [
9394
# BUMPVER --------------------------------------------------------------------
9495

9596
[bumpver]
96-
current_version = "2024.8.0"
97+
current_version = "2024.10.0"
9798
version_pattern = "YYYY.MM.INC0"
9899

99100
[bumpver.file_patterns]

Diff for: requirements.txt

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
# This file was autogenerated by uv via the following command:
2-
# uv pip compile -o requirements.txt pyproject.toml
2+
# uv pip compile --output-file=requirements.txt pyproject.toml
33
cerberus==1.3.5
44
# via edgetest (pyproject.toml)
55
click==8.1.7
66
# via edgetest (pyproject.toml)
7-
packaging==24.0
7+
packaging==24.1
88
# via edgetest (pyproject.toml)
9-
pluggy==1.4.0
9+
pluggy==1.5.0
1010
# via edgetest (pyproject.toml)
1111
tabulate==0.9.0
1212
# via edgetest (pyproject.toml)
1313
tomlkit==0.11.4
1414
# via edgetest (pyproject.toml)
15-
uv==0.2.28
15+
uv==0.4.26
1616
# via edgetest (pyproject.toml)

Diff for: tests/test_integration_cfg.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
include_package_data = True
4747
packages = find:
4848
install_requires =
49-
polars<=1.0.0,>=0.20.31
49+
polars>=1.0.0,<=1.5.0
5050
5151
[options.extras_require]
5252
tests =
@@ -75,8 +75,8 @@
7575
include_package_data = True
7676
packages = find:
7777
install_requires =
78-
scikit-learn>=1.0,<=1.2.0
79-
polars[pyarrow]<=1.0.0,>=0.20.31
78+
scikit-learn>=1.3.2,<=1.4.0
79+
polars[pyarrow]>=1.0.0,<=1.5.0
8080
8181
[options.extras_require]
8282
tests =

Diff for: tests/test_integration_toml.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
version = "0.1.0"
3131
description = "Fake description"
3232
requires-python = ">=3.7.0"
33-
dependencies = ["polars<=1.0.0,>=0.20.31"]
33+
dependencies = ["polars>=1.0.0,<=1.5.0"]
3434
3535
[project.optional-dependencies]
3636
tests = ["pytest"]
@@ -48,7 +48,7 @@
4848
version = "0.1.0"
4949
description = "Fake description"
5050
requires-python = ">=3.7.0"
51-
dependencies = ["Scikit_Learn>=1.0,<=1.2.0", "Polars[pyarrow]<=1.0.0,>=0.20.31"]
51+
dependencies = ["Scikit_Learn>=1.3.2,<=1.4.0", "Polars[pyarrow]>=1.0.0,<=1.5.0"]
5252
5353
[project.optional-dependencies]
5454
tests = ["pytest"]

0 commit comments

Comments
 (0)