From 1f8350ad76d73028f942d5ce257cb2bc5985659f Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Sun, 20 Oct 2024 18:30:44 +0100 Subject: [PATCH 1/3] Add a _Stringlike string subclass that adds an __or__ function that is used for defaults and converts everything to strings. --- src/ducktools/classbuilder/annotations.py | 41 +++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/ducktools/classbuilder/annotations.py b/src/ducktools/classbuilder/annotations.py index 25b1401..af3e15f 100644 --- a/src/ducktools/classbuilder/annotations.py +++ b/src/ducktools/classbuilder/annotations.py @@ -37,6 +37,36 @@ def f(): # End evil stuff from types.py +class _Stringlike(str): + # There are typing operators that are not supported by strings + # This adds the 'or' operator '|' + + def __or__(self, other): + if isinstance(other, str): + other_r = other + elif name := getattr(other, "__name__", None): + other_r = name + else: + other_r = str(other) + + return type(self)(f"{self} | {other_r}") + + def __ror__(self, other): + if isinstance(other, str): + other_r = other + elif name := getattr(other, "__name__", None): + other_r = name + else: + other_r = str(other) + + return type(self)(f"{other_r} | {self}") + + def __repr__(self): + base = super().__repr__() + clsname = type(self).__name__ + return f"{clsname}({base})" + + class _StringGlobs(dict): """ Based on the fake globals dictionary used for annotations @@ -47,7 +77,7 @@ class _StringGlobs(dict): is not found. """ def __missing__(self, key): - return key + return _Stringlike(key) def __repr__(self): cls_name = self.__class__.__name__ @@ -165,7 +195,14 @@ def call_annotate_func(annotate): closure = None new_annotate = _FunctionType(annotate.__code__, globs, closure=closure) - return new_annotate(1) + + # Convert _Stringlike back to str + annos = { + k: str(v) if isinstance(v, _Stringlike) else v + for k, v in new_annotate(1).items() + } + + return annos def get_ns_annotations(ns, eval_str=True): From 8c3f19938c9f605807cab45c6f846bd8852f4fba Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Mon, 21 Oct 2024 10:15:09 +0100 Subject: [PATCH 2/3] Move mypy out of testing env and into type_checking --- .github/workflows/auto_test.yml | 2 +- pyproject.toml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/auto_test.yml b/.github/workflows/auto_test.yml index f0cca20..9569cdd 100644 --- a/.github/workflows/auto_test.yml +++ b/.github/workflows/auto_test.yml @@ -42,7 +42,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install -e .[testing] + python -m pip install -e .[testing,type_checking] - name: Check type stub files run: | python -m mypy.stubtest ducktools.classbuilder diff --git a/pyproject.toml b/pyproject.toml index 011de4e..606160d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,6 +27,12 @@ classifiers = [ dynamic = ['version'] license = {file = "LICENSE.md"} +[project.optional-dependencies] +testing = ["pytest>=8.2", "pytest-cov", "typing_extensions"] +type_checking = ["mypy"] +performance_tests = ["attrs", "pydantic"] +docs = ["sphinx", "myst-parser", "sphinx_rtd_theme"] + [tool.setuptools.packages.find] where = ["src"] @@ -34,12 +40,6 @@ where = ["src"] version_file = "src/ducktools/classbuilder/_version.py" version_file_template = "__version__ = \"{version}\"\n__version_tuple__ = {version_tuple}\n" - -[project.optional-dependencies] -testing = ["pytest>=8.2", "pytest-cov", "mypy", "typing_extensions"] -performance_tests = ["attrs", "pydantic"] -docs = ["sphinx", "myst-parser", "sphinx_rtd_theme"] - [project.urls] "Homepage" = "https://github.com/davidcellis/ducktools-classbuilder" From 7c7fe3ebeb24dcc0a68566ae6551801e0336901a Mon Sep 17 00:00:00 2001 From: David C Ellis Date: Mon, 21 Oct 2024 10:15:36 +0100 Subject: [PATCH 3/3] 3.13 is final now --- .github/workflows/auto_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto_test.yml b/.github/workflows/auto_test.yml index 9569cdd..7731b64 100644 --- a/.github/workflows/auto_test.yml +++ b/.github/workflows/auto_test.yml @@ -14,7 +14,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - python-version: ["3.13-dev", "3.12", "3.11", "3.10", "pypy-3.10", "3.9", "3.8"] + python-version: ["3.13", "3.12", "3.11", "3.10", "pypy-3.10", "3.9", "3.8"] steps: - uses: actions/checkout@v4