Skip to content

Commit c17caaf

Browse files
committed
enable python 3.12
1 parent 0ecfa71 commit c17caaf

6 files changed

Lines changed: 78 additions & 72 deletions

File tree

.github/workflows/actions.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
strategy:
3939
matrix:
4040
os: ["ubuntu-latest"]
41-
version: ["3.9", "3.10", "3.11"]
41+
version: ["3.9", "3.10", "3.11", "3.12"]
4242
steps:
4343
- name: Checkout 🔖
4444
uses: actions/checkout@v3

.pre-commit-config.yaml

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ default_language_version:
22
python: python3
33
repos:
44
- repo: https://github.com/pre-commit/pre-commit-hooks
5-
rev: v4.4.0
5+
rev: v5.0.0
66
hooks:
77
- id: check-added-large-files
88
- id: check-ast
@@ -13,28 +13,18 @@ repos:
1313
- id: check-toml
1414
- id: check-yaml
1515
exclude: mkdocs.yml
16-
- repo: https://github.com/psf/black
17-
rev: 23.1.0
18-
hooks:
19-
- id: black
20-
exclude: test/data/schema/wrong_syntax.py
2116
- repo: https://github.com/pre-commit/mirrors-mypy
22-
rev: v1.0.0
17+
rev: v1.15.0
2318
hooks:
2419
- id: mypy
2520
exclude: test/data/schema/wrong_syntax.py
2621
- repo: https://github.com/dosisod/refurb
27-
rev: v1.11.1
22+
rev: v2.0.0
2823
hooks:
2924
- id: refurb
3025
exclude: test/data/schema/wrong_syntax.py
31-
- repo: https://github.com/charliermarsh/ruff-pre-commit
32-
rev: 'v0.0.247'
26+
- repo: https://github.com/astral-sh/ruff-pre-commit
27+
rev: v0.11.4
3328
hooks:
3429
- id: ruff
3530
args: [--fix, --exit-non-zero-on-fix]
36-
- repo: https://github.com/tcort/markdown-link-check
37-
rev: 'v3.11.2'
38-
hooks:
39-
- id: markdown-link-check
40-
args: [-q]

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "dac"
33
dynamic = ["version"]
44
description = "Tool to distribute data as code"
55
readme = "README.md"
6-
requires-python = ">=3.9,<3.12"
6+
requires-python = ">=3.9,<3.13"
77
license = { text = "MIT" }
88
authors = [
99
{ name = "Francesco Calcavecchia", email = "francesco.calcavecchia@gmail.com" },

src/dac/_version_management.py

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,60 @@
1+
import tempfile
12
import re
23
import subprocess
34
from typing import Optional
5+
from pathlib import Path
46

57

68
def find_latest_version(pkg_name: str, major: Optional[int] = None) -> str:
7-
output = subprocess.check_output(
8-
[
9-
"pip",
10-
"install",
11-
"--no-deps",
12-
"--ignore-installed",
13-
"--no-cache-dir",
14-
"--dry-run",
15-
f"{pkg_name}{f'=={major}.*' if major is not None else ''}",
16-
],
17-
stderr=subprocess.DEVNULL,
9+
pip_log = _pretend_pip_install(pkg_name=pkg_name, major=major)
10+
would_install_line = _extract_would_install_line(pip_log=pip_log)
11+
package_with_version = _extract_package_with_version(
12+
pip_log_would_install_line=would_install_line, pkg_name=pkg_name, major=major
1813
)
19-
output_lines = output.decode("utf-8").splitlines()
20-
would_install_line = [line for line in output_lines if "Would install" in line][0]
21-
regex_rule = f"{pkg_name.replace('_', '-')}-{major if major is not None else ''}.[^ ]+"
22-
match = re.search(regex_rule, would_install_line.replace("_", "-"))
23-
assert match is not None
24-
return match[0][len(f"{pkg_name}-") :]
14+
return package_with_version[len(f"{pkg_name}-") :]
2515

2616

2717
def increase_minor(version: str) -> str:
2818
major, minor, patch = version.split(".")
2919
assert major.isdigit() and minor.isdigit()
3020
return f"{major}.{int(minor) + 1}.0"
21+
22+
23+
def _pretend_pip_install(pkg_name: str, major: Optional[int]) -> str:
24+
with tempfile.NamedTemporaryFile() as log_file:
25+
result = subprocess.run(
26+
[
27+
"pip",
28+
"install",
29+
"--no-deps",
30+
"--ignore-installed",
31+
"--dry-run",
32+
f"--log={log_file.name}",
33+
f"{pkg_name}{f'=={major}.*' if major is not None else ''}",
34+
],
35+
stdout=subprocess.PIPE,
36+
stderr=subprocess.PIPE,
37+
text=True,
38+
)
39+
if result.returncode != 0:
40+
raise subprocess.SubprocessError(
41+
f"Something went wrong while using pip to find the version of {pkg_name}{f'(major version {major})' if major else ''}.\n\nSTDOUT: {result.stdout}\n\nSTDERR: {result.stderr}"
42+
)
43+
return Path(log_file.name).read_text()
44+
45+
46+
def _extract_would_install_line(pip_log: str) -> str:
47+
would_install_lines = [line for line in pip_log.splitlines() if "Would install" in line]
48+
assert (
49+
len(would_install_lines) == 1
50+
), f"Expected exactly one line containing 'Would install' in the pip log generated by pip installing the requested package, but found {len(would_install_lines)} lines."
51+
return would_install_lines[0]
52+
53+
54+
def _extract_package_with_version(pip_log_would_install_line: str, pkg_name: str, major: Optional[int]) -> str:
55+
regex_rule = f"{pkg_name.replace('_', '-')}-{major if major is not None else ''}.[^ ]+"
56+
match = re.search(regex_rule, pip_log_would_install_line.replace("_", "-"))
57+
assert (
58+
match is not None and match[0] != ""
59+
), f"It was not possible to determine the version, because we could not find a match to the regex {regex_rule} in {pip_log_would_install_line.replace('_', '-')}"
60+
return match[0]

test/integration_test/version_management_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def test_if_find_latest_version_is_called_then_return_latest_version():
99

1010

1111
def test_if_find_latest_version_is_called_with_major_constraint_then_return_latest_major_version():
12-
assert "0.25.3" == find_latest_version(pkg_name="pandas", major=0)
12+
assert "1.5.3" == find_latest_version(pkg_name="pandas", major=1)
1313

1414

1515
def test_if_pkg_does_not_exist_then_find_package_raises_exception():
@@ -23,5 +23,5 @@ def test_if_next_version_without_major_spec_then_return_latest_version_with_mino
2323

2424

2525
def test_if_next_version_with_major_spec_then_return_minor_upgrade_for_that_major():
26-
result = invoke_dac_next_version(pkg_name="pandas", major=0)
27-
assert result.stdout == "0.26.0\n"
26+
result = invoke_dac_next_version(pkg_name="pandas", major=1)
27+
assert result.stdout == "1.6.0\n"
Lines changed: 21 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,40 @@
1-
import subprocess
21
from test.data import get_pip_log_with_dash, get_pip_log_with_underscore
3-
from unittest.mock import MagicMock
2+
from unittest.mock import patch
43

54
from dac._version_management import find_latest_version
6-
from pytest import MonkeyPatch, fixture
75

86

9-
def test_if_pkg_name_uses_dash_separator_and_pip_log_dash_then_correct_latest_version(mock_pip_output_with_dash: None):
10-
latest_version = find_latest_version(pkg_name="investing-algorithm-framework")
11-
assert latest_version == "2.3.2"
7+
def test_if_pkg_name_uses_dash_separator_and_pip_log_dash_then_correct_latest_version():
8+
with patch("dac._version_management._pretend_pip_install") as mock_pretend_pip_install:
9+
mock_pretend_pip_install.return_value = get_pip_log_with_dash()
1210

11+
latest_version = find_latest_version(pkg_name="investing-algorithm-framework")
1312

14-
def test_if_pkg_name_uses_dash_separator_and_pip_log_underscore_then_correct_latest_version(
15-
mock_pip_output_with_underscore: None,
16-
):
17-
latest_version = find_latest_version(pkg_name="investing-algorithm-framework")
18-
assert latest_version == "2.3.2"
13+
assert latest_version == "2.3.2"
1914

2015

21-
def test_if_pkg_name_uses_underscore_separator_and_pip_log_dash_then_correct_latest_version(
22-
mock_pip_output_with_dash: None,
23-
):
24-
latest_version = find_latest_version(pkg_name="investing_algorithm_framework")
25-
assert latest_version == "2.3.2"
16+
def test_if_pkg_name_uses_dash_separator_and_pip_log_underscore_then_correct_latest_version():
17+
with patch("dac._version_management._pretend_pip_install") as mock_pretend_pip_install:
18+
mock_pretend_pip_install.return_value = get_pip_log_with_underscore()
2619

20+
latest_version = find_latest_version(pkg_name="investing-algorithm-framework")
2721

28-
def test_if_pkg_name_uses_underscore_separator_and_pip_log_underscore_then_correct_latest_version(
29-
mock_pip_output_with_underscore: None,
30-
):
31-
latest_version = find_latest_version(pkg_name="investing_algorithm_framework")
32-
assert latest_version == "2.3.2"
22+
assert latest_version == "2.3.2"
3323

3424

35-
@fixture
36-
def mock_pip_output_with_dash(monkeypatch: MonkeyPatch):
37-
output = MagicMock()
38-
output.decode.return_value = get_pip_log_with_dash()
25+
def test_if_pkg_name_uses_underscore_separator_and_pip_log_dash_then_correct_latest_version():
26+
with patch("dac._version_management._pretend_pip_install") as mock_pretend_pip_install:
27+
mock_pretend_pip_install.return_value = get_pip_log_with_dash()
3928

40-
def return_foo(*args, **kwargs) -> str:
41-
return output
29+
latest_version = find_latest_version(pkg_name="investing_algorithm_framework")
4230

43-
monkeypatch.setattr(subprocess, "check_output", return_foo)
31+
assert latest_version == "2.3.2"
4432

4533

46-
@fixture
47-
def mock_pip_output_with_underscore(monkeypatch: MonkeyPatch):
48-
output = MagicMock()
49-
output.decode.return_value = get_pip_log_with_underscore()
34+
def test_if_pkg_name_uses_underscore_separator_and_pip_log_underscore_then_correct_latest_version():
35+
with patch("dac._version_management._pretend_pip_install") as mock_pretend_pip_install:
36+
mock_pretend_pip_install.return_value = get_pip_log_with_underscore()
5037

51-
def return_foo(*args, **kwargs) -> str:
52-
return output
38+
latest_version = find_latest_version(pkg_name="investing_algorithm_framework")
5339

54-
monkeypatch.setattr(subprocess, "check_output", return_foo)
40+
assert latest_version == "2.3.2"

0 commit comments

Comments
 (0)