From e587064b0c0f02e9d980c4118d2df1d4983cfe78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Nov 2025 09:05:47 +0000 Subject: [PATCH 1/7] ci(dependabot): bump pypa/cibuildwheel from 3.2 to 3.3 Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 3.2 to 3.3. - [Release notes](https://github.com/pypa/cibuildwheel/releases) - [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md) - [Commits](https://github.com/pypa/cibuildwheel/compare/v3.2...v3.3) --- updated-dependencies: - dependency-name: pypa/cibuildwheel dependency-version: '3.3' dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/pypi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index 3e41d8e5..32e9943e 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -29,7 +29,7 @@ jobs: fetch-depth: 0 - uses: astral-sh/setup-uv@v7 - name: Build wheels via cibuildwheel - uses: pypa/cibuildwheel@v3.2 + uses: pypa/cibuildwheel@v3.3 - name: Upload wheels artifacts uses: actions/upload-artifact@v4 with: From 203b84d82a58abdca7e45f2d5ed2b93e4ce27eab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 09:07:07 +0000 Subject: [PATCH 2/7] ci(dependabot): bump actions/checkout from 5 to 6 Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/benchmark.yml | 2 +- .github/workflows/pypi.yml | 6 +++--- .github/workflows/test.yml | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index d87b07b0..8d0ea170 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -17,7 +17,7 @@ jobs: name: Benchmark runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: fetch-depth: 0 - uses: actions/setup-python@v6 diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index 3e41d8e5..5c2e0f60 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -11,7 +11,7 @@ jobs: name: 🐍 sdist and universal wheel runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: fetch-depth: 0 - uses: hynek/build-and-inspect-python-package@v2 @@ -24,7 +24,7 @@ jobs: matrix: os: [ubuntu-latest, windows-latest, macos-13, macos-latest] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: fetch-depth: 0 - uses: astral-sh/setup-uv@v7 @@ -61,7 +61,7 @@ jobs: - name: 🚢 Publish to PyPI uses: pypa/gh-action-pypi-publish@release/v1 - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: fetch-depth: 0 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8c31b3ed..17fbb5c0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,7 +16,7 @@ jobs: check-manifest: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - run: pipx run check-manifest test: @@ -55,7 +55,7 @@ jobs: compile: "1" steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: astral-sh/setup-uv@v7 with: enable-cache: true @@ -105,7 +105,7 @@ jobs: typing: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: astral-sh/setup-uv@v7 with: enable-cache: true @@ -116,7 +116,7 @@ jobs: benchmarks: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: "3.13" From 6f05b524d16238353f98bff3d4367aaa7474c988 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 22:15:59 +0000 Subject: [PATCH 3/7] ci(pre-commit.ci): autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/rhysd/actionlint: v1.7.8 → v1.7.9](https://github.com/rhysd/actionlint/compare/v1.7.8...v1.7.9) - [github.com/adhtruong/mirrors-typos: v1.38.1 → v1.40.0](https://github.com/adhtruong/mirrors-typos/compare/v1.38.1...v1.40.0) - [github.com/astral-sh/ruff-pre-commit: v0.14.0 → v0.14.7](https://github.com/astral-sh/ruff-pre-commit/compare/v0.14.0...v0.14.7) - [github.com/pre-commit/mirrors-mypy: v1.18.2 → v1.19.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.18.2...v1.19.0) --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 53792103..a4a1b20f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,26 +12,26 @@ repos: - id: validate-pyproject - repo: https://github.com/rhysd/actionlint - rev: v1.7.8 + rev: v1.7.9 hooks: - id: actionlint files: "^\\.github/workflows/.*\\.ya?ml$" - repo: https://github.com/adhtruong/mirrors-typos - rev: v1.38.1 + rev: v1.40.0 hooks: - id: typos args: [--force-exclude] # omitting --write-changes - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.0 + rev: v0.14.7 hooks: - id: ruff-check args: [--fix, --unsafe-fixes] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.18.2 + rev: v1.19.0 hooks: - id: mypy exclude: tests|_throttler.pyi From 567e7bef55e428b9b5fbea4f60cc098fbe8b4e47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 09:03:14 +0000 Subject: [PATCH 4/7] ci(dependabot): bump actions/upload-artifact from 4 to 6 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 6. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v4...v6) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/pypi.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index 3e41d8e5..49cd2ff8 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -31,7 +31,7 @@ jobs: - name: Build wheels via cibuildwheel uses: pypa/cibuildwheel@v3.2 - name: Upload wheels artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: cibw-wheels-${{ runner.os }}-${{ runner.arch }} path: ./wheelhouse/*.whl diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8c31b3ed..3d37a0bd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -82,7 +82,7 @@ jobs: run: uv run coverage run -p -m pytest -v - name: Upload coverage - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: covreport-${{ matrix.os }}-py${{ matrix.python-version }}-mypyc${{ matrix.compile }}-${{ matrix.qt }} path: ./.coverage* From b00e494166a354e909573c6a156c908c61e0cbda Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 09:03:17 +0000 Subject: [PATCH 5/7] ci(dependabot): bump actions/download-artifact from 5 to 7 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 5 to 7. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v5...v7) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/pypi.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index 3e41d8e5..58510652 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -47,12 +47,12 @@ jobs: steps: - name: Get sdist - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v7 with: name: Packages path: dist - name: Get wheels - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v7 with: pattern: cibw-wheels-* path: dist From 07724297967634f0328444070e25dbf0050eb9ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 09:03:24 +0000 Subject: [PATCH 6/7] ci(dependabot): bump actions/cache from 4 to 5 Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/cache dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/benchmark.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index d87b07b0..69952ebb 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -40,7 +40,7 @@ jobs: - name: Restore previous results if: github.event_name != 'pull_request' - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: .asv key: asv-${{ runner.os }} From 69f5b1a2d7a8f8018805f1b5bb46278ef849bcf5 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Tue, 23 Dec 2025 19:01:05 -0500 Subject: [PATCH 7/7] remove getattr, and add a stub --- .pre-commit-config.yaml | 2 +- src/psygnal/_group.py | 10 ---------- src/psygnal/_group.pyi | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 src/psygnal/_group.pyi diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a4a1b20f..8acbced1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -34,7 +34,7 @@ repos: rev: v1.19.0 hooks: - id: mypy - exclude: tests|_throttler.pyi + exclude: tests|_throttler.pyi|_group.pyi additional_dependencies: - types-attrs - pydantic diff --git a/src/psygnal/_group.py b/src/psygnal/_group.py index 54da3cf1..f8fa7932 100644 --- a/src/psygnal/_group.py +++ b/src/psygnal/_group.py @@ -539,16 +539,6 @@ def __getitem__(self, item: str) -> SignalInstance: """Get a signal instance by name.""" return self._psygnal_instances[item] - # this is just here for type checking, particularly on cases - # where the SignalGroup comes from the SignalGroupDescriptor - # (such as in evented dataclasses). In those cases, it's hard to indicate - # to mypy that all remaining attributes are SignalInstances. - def __getattr__(self, __name: str) -> SignalInstance: - """Get a signal instance by name.""" - raise AttributeError( # pragma: no cover - f"{type(self).__name__!r} object has no attribute {__name!r}" - ) - def __iter__(self) -> Iterator[str]: """Yield the names of all signals in the group.""" return iter(self._psygnal_instances) diff --git a/src/psygnal/_group.pyi b/src/psygnal/_group.pyi new file mode 100644 index 00000000..cefe578a --- /dev/null +++ b/src/psygnal/_group.pyi @@ -0,0 +1,39 @@ +# This stub provides __getattr__ for type checking, which cannot be in the +# main file because mypyc doesn't support __getattr__ in classes with +# allow_interpreted_subclasses=True. +from collections.abc import Iterator, Mapping +from typing import Any, ClassVar + +from psygnal._signal import Signal, SignalInstance + +class SignalRelay(SignalInstance): + instance: Any + def __init__( + self, signals: Mapping[str, SignalInstance], instance: Any = None + ) -> None: ... + +class SignalGroup: + _psygnal_signals: ClassVar[Mapping[str, Signal]] + _psygnal_uniform: ClassVar[bool] + _psygnal_name_conflicts: ClassVar[set[str]] + _psygnal_aliases: ClassVar[dict[str, str | None]] + _psygnal_instances: dict[str, SignalInstance] + + def __init__(self, instance: Any = None) -> None: ... + def __init_subclass__( + cls, + strict: bool = False, + signal_aliases: Mapping[str, str | None] = ..., + ) -> None: ... + @property + def instance(self) -> Any: ... + @property + def all(self) -> SignalRelay: ... + @property + def signals(self) -> Mapping[str, SignalInstance]: ... + def __len__(self) -> int: ... + def __getitem__(self, item: str) -> SignalInstance: ... + def __getattr__(self, name: str) -> SignalInstance: ... + def __iter__(self) -> Iterator[str]: ... + def __contains__(self, item: str) -> bool: ... + def __repr__(self) -> str: ...