Skip to content

Commit 2b9b741

Browse files
authored
Merge pull request #71 from DavidCEllis/multi-updates
Typing fixes and dependency updates, Python 3.12 new minimum
2 parents 20d707e + 66272e5 commit 2b9b741

9 files changed

Lines changed: 164 additions & 279 deletions

File tree

.github/workflows/auto_test.yml

Lines changed: 1 addition & 1 deletion
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]
17-
python-version: ["3.14", "3.13", "3.12", "3.11", "3.10"]
17+
python-version: ["3.15-dev", "3.14", "3.13", "3.12"]
1818

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

.github/workflows/build_zipapp.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
- name: Set up Python
1818
uses: actions/setup-python@v6
1919
with:
20-
python-version: "3.10" # build with oldest supported python
20+
python-version: "3.12" # build with oldest supported python
2121
- name: Install the module
2222
run: |
2323
python -m pip install --upgrade pip

.github/workflows/publish_to_pypi.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
- name: Set up Python
1717
uses: actions/setup-python@v6
1818
with:
19-
python-version: "3.10"
19+
python-version: "3.12"
2020
- name: Install pypa/build
2121
run: >-
2222
python3 -m

.github/workflows/publish_to_testpypi.yml

Lines changed: 0 additions & 57 deletions
This file was deleted.

pyproject.toml

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@ authors = [
1212
{ name = "David C Ellis" },
1313
]
1414
readme = "README.md"
15-
requires-python = ">=3.10"
15+
requires-python = ">=3.12"
1616
dependencies = [
17-
"ducktools-classbuilder>=0.12.3",
18-
"ducktools-lazyimporter>=0.7.0",
19-
"ducktools-scriptmetadata>=0.2.0",
20-
"ducktools-pythonfinder>=0.8.1",
21-
"tomli>=2.2; python_version < '3.11'",
22-
"packaging>=24.2",
17+
"ducktools-classbuilder>=0.12.6",
18+
"ducktools-lazyimporter>=0.8.4",
19+
"ducktools-scriptmetadata>=0.2.1",
20+
"ducktools-pythonfinder>=0.10.5",
21+
"packaging>=26.0",
2322
]
2423
classifiers = [
2524
"Development Status :: 2 - Pre-Alpha",
@@ -41,8 +40,8 @@ dynamic = ["version"]
4140
[dependency-groups]
4241
dev = [
4342
"coverage-conditional-plugin>=0.9.0",
44-
"pytest>=8.4.0",
45-
"pytest-cov>=6.2.1",
43+
"pytest>=9.0",
44+
"pytest-cov>=7.1",
4645
]
4746

4847
[tool.setuptools.packages.find]

src/ducktools/env/_sqlclasses.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,11 @@
2929
import itertools
3030

3131
from ducktools.lazyimporter import LazyImporter, ModuleImport
32-
3332
from ducktools.classbuilder import (
3433
SlotMakerMeta,
3534
builder,
3635
make_unified_gatherer,
3736
)
38-
3937
from ducktools.classbuilder.prefab import (
4038
PREFAB_FIELDS,
4139
Attribute,
@@ -47,11 +45,37 @@
4745
)
4846

4947

48+
TYPE_CHECKING = False
49+
if TYPE_CHECKING:
50+
from typing import dataclass_transform
51+
else:
52+
def dataclass_transform(
53+
*,
54+
eq_default=True,
55+
order_default=False,
56+
kw_only_default=False,
57+
frozen_default=False,
58+
field_specifiers=(),
59+
**kwargs
60+
):
61+
def decorator(cls_or_fn):
62+
cls_or_fn.__dataclass_transform__ = {
63+
"eq_default": eq_default,
64+
"order_default": order_default,
65+
"kw_only_default": kw_only_default,
66+
"frozen_default": frozen_default,
67+
"field_specifiers": field_specifiers,
68+
"kwargs": kwargs,
69+
}
70+
return cls_or_fn
71+
return decorator
72+
73+
5074
# Unlike the other modules this has its own lazy importer
5175
# As it might be spun off as a separate package
5276
_laz = LazyImporter(
5377
[
54-
ModuleImport("sqlite3", asname="sql")
78+
ModuleImport("sqlite3", asname="sql"),
5579
]
5680
)
5781

@@ -113,7 +137,7 @@ def get_sql_fields(cls: "SQLMeta", local=False) -> dict[str, SQLAttribute]:
113137
k: SQLAttribute.from_field(v) if type(v) in parents else v
114138
for k, v in attribs.items()
115139
}
116-
return attributes
140+
return attributes # type: ignore # Bug in classbuilder stub file
117141

118142

119143
unified_gatherer = make_unified_gatherer(SQLAttribute)
@@ -148,6 +172,7 @@ class SQLMeta(SlotMakerMeta):
148172
default_methods = frozenset({init_maker, repr_maker, eq_maker})
149173

150174

175+
@dataclass_transform(kw_only_default=True, field_specifiers=(SQLAttribute,))
151176
class SQLClass(metaclass=SQLMeta):
152177
_meta_gatherer = unified_gatherer
153178
__slots__ = {}
@@ -167,7 +192,7 @@ def __init_subclass__(
167192
methods=methods,
168193
flags={"slotted": slots, "kw_only": True},
169194
field_getter=get_sql_fields,
170-
)
195+
) # type: ignore # Another complex typing issue with classbuilder
171196

172197
fields = get_sql_fields(cls)
173198
valid_fields = {}
@@ -201,11 +226,11 @@ def __init_subclass__(
201226
for name, field in fields.items():
202227
if field.primary_key:
203228
if primary_key is not None:
204-
raise AttributeError("sqlclass *must* have **only** one primary key")
229+
raise AttributeError("SQLClass *must* have **only** one primary key")
205230
primary_key = name
206231

207232
if primary_key is None:
208-
raise AttributeError("sqlclass *must* have one primary key")
233+
raise AttributeError("SQLClass *must* have one primary key")
209234

210235
cls.PK_NAME = primary_key
211236
cls.TABLE_NAME = caps_to_snake(cls.__name__)
@@ -398,7 +423,7 @@ def update_row(self, con, columns: list[str]):
398423
search_condition = f"{self.PK_NAME} = :{self.PK_NAME}"
399424

400425
with con:
401-
result = con.execute(
426+
con.execute(
402427
f"UPDATE {self.TABLE_NAME} SET {set_columns} WHERE {search_condition}",
403428
processed_values,
404429
)

src/ducktools/env/scripts/get_pip.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,18 @@ def as_version(self):
6262

6363
# This is mostly kept for testing.
6464
PREVIOUS_PIP = PipZipapp(
65-
version_str="25.1.1",
66-
sha3_256="19cea26421fcda28baa6a54f3e9be60a9ea06e85bf9b91f627de18bed0d0dc7b",
67-
source_url="zipapp/pip-25.1.1.pyz",
68-
)
69-
70-
LATEST_PIP = PipZipapp(
7165
version_str="25.3",
7266
sha3_256="a619d1451f2c42c072e0005d98c8a0fdd60ec1f033597a91f8b46c416c338fb6",
7367
source_url="zipapp/pip-25.3.pyz",
7468
)
7569

70+
LATEST_PIP = PipZipapp(
71+
version_str="26.0.1",
72+
sha3_256="fe1f58ec30e3b09a0fa54619f55750682549364670fc206995e1b72c24157011",
73+
source_url="zipapp/pip-26.0.1.pyz",
74+
)
75+
76+
7677
def is_pip_outdated(
7778
paths: ManagedPaths,
7879
latest_version: PipZipapp = LATEST_PIP

src/ducktools/env/scripts/get_uv.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,13 @@
2020
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2121
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2222
# SOFTWARE.
23-
import sys
24-
25-
2623
from .._logger import log
2724
from .. import _lazy_imports as _laz
2825

2926

3027
uv_versionspec = ">=0.7.0"
3128
uv_versionre = r"^uv (?P<uv_ver>\d+\.\d+\.\d+)"
3229

33-
uv_download = "bin/uv.exe" if sys.platform == "win32" else "bin/uv"
34-
3530

3631
def get_local_uv():
3732
"""

0 commit comments

Comments
 (0)