Skip to content

Commit

Permalink
ci: fix wheel building (#352)
Browse files Browse the repository at this point in the history
* ci: test out wheel build

* upload artifact

* fix name

* try skipping

* hard limit on recursion

* move around dev extra

* style(pre-commit.ci): auto fixes [...]

* 2-step

* fix workflow

* run last step

* remove unused

* remove testing

* final

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
tlambert03 and pre-commit-ci[bot] authored Feb 3, 2025
1 parent 0f6e607 commit e951f3f
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 69 deletions.
87 changes: 36 additions & 51 deletions .github/workflows/pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,76 +12,61 @@ jobs:
hatch-build-hooks-enable: true
coverage-upload: none

deploy-sdist:
needs: test
if: success() && startsWith(github.ref, 'refs/tags/v')
build-sdist:
name: 🐍 sdist
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-python@v5
- uses: hynek/build-and-inspect-python-package@v2
with:
python-version: "3.x"

- name: 👷 Build
run: |
python -m pip install build
python -m build
- name: 🚢 Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
skip-wheel: true

- uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
files: "./dist/*"

deploy-wheel:
if: startsWith(github.event.ref, 'refs/tags/v')
needs: deploy-sdist
name: mypyc wheels (${{ matrix.name }})
build-wheels:
name: mypyc wheels (${{ matrix.os }})
runs-on: ${{ matrix.os }}
permissions:
id-token: write
contents: write
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
name: linux-x86_64
- os: windows-latest
name: windows-amd64
- os: macos-13
name: macos-x86_64
macos_arch: "x86_64"
- os: macos-14
name: macos-arm64
macos_arch: "arm64"

os: [ubuntu-latest, windows-latest, macos-13, macos-latest]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Build wheels via cibuildwheel
uses: pypa/[email protected]
uses: pypa/[email protected]
- name: Upload wheels artifacts
uses: actions/upload-artifact@v4
with:
output-dir: dist
env:
CIBW_ARCHS_MACOS: "${{ matrix.macos_arch }}"
name: cibw-wheels-${{ runner.os }}-${{ runner.arch }}
path: ./wheelhouse/*.whl

- name: Upload wheels as workflow artifacts
uses: actions/upload-artifact@v4
publish:
name: Publish to PyPI
needs: [test, build-sdist, build-wheels]
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Get sdist
uses: actions/download-artifact@v4
with:
name: ${{ matrix.name }}-mypyc-wheels
path: ./dist/*.whl
name: Packages
path: dist
- name: Get wheels
uses: actions/download-artifact@v4
with:
pattern: cibw-wheels-*
path: dist
merge-multiple: true

- name: 🚢 Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

- uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
files: "./dist/*"
33 changes: 17 additions & 16 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,6 @@ dependencies = [
# extras
# https://peps.python.org/pep-0621/#dependencies-optional-dependencies
[project.optional-dependencies]
dev = [
"ipython",
"mypy",
"mypy_extensions",
"pre-commit",
"PyQt5",
"pytest-mypy-plugins",
"rich",
"ruff",
"typing-extensions",
]
docs = [
"griffe==0.25.5",
"mkdocs-material==8.5.10",
Expand All @@ -55,19 +44,32 @@ docs = [
proxy = ["wrapt"]
pydantic = ["pydantic"]
test = [
"dask",
"dask[array]>=2024.0.0",
"attrs",
"numpy",
"numpy >1.21.6",
"pydantic",
"pyinstaller>=4.0",
"pytest>=6.0",
"pytest-cov",
"wrapt",
"msgspec; python_version < '3.13'",
"msgspec",
"toolz",
]
testqt = ["pytest-qt", "qtpy"]

dev = [
"psygnal[test, testqt]",
"PyQt6",
"ipython",
"mypy",
"mypy_extensions",
"pre-commit",
"pytest-mypy-plugins",
"rich",
"ruff",
"typing-extensions",
]

[project.urls]
homepage = "https://github.com/pyapp-kit/psygnal"
repository = "https://github.com/pyapp-kit/psygnal"
Expand Down Expand Up @@ -125,7 +127,6 @@ before-all = "yum install -y python3-devel"
[tool.cibuildwheel.environment]
HATCH_BUILD_HOOKS_ENABLE = "1"


# https://docs.astral.sh/ruff/
[tool.ruff]
line-length = 88
Expand All @@ -146,7 +147,7 @@ select = [
"C4", # flake8-comprehensions
"B", # flake8-bugbear
"A001", # flake8-builtins
"TCH", # flake8-typecheck
"TC", # flake8-typecheck
"TID", # flake8-tidy-imports
"RUF", # ruff-specific rules
]
Expand Down
23 changes: 21 additions & 2 deletions src/psygnal/_signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ def ensure_at_least_20(val: int):
from __future__ import annotations

import inspect
import sys
import threading
import warnings
import weakref
Expand Down Expand Up @@ -182,7 +181,14 @@ def ensure_at_least_20(val: int):

_NULL = object()
F = TypeVar("F", bound=Callable)
RECURSION_LIMIT = sys.getrecursionlimit()

# using 300 instead of sys.getrecursionlimit()
# in a mypyc-compiled program, hitting an actual RecursionError can cause
# a segfault (rather than raise a python exception), so we really MUST
# avoid it. Windows has a lower stack limit than other platforms, so we
# use 300 as a cross-platform "safe" limit, determined via testing. It's
# probably plenty large for most reasonable use-cases.
RECURSION_LIMIT = 300

ReemissionVal = Literal["immediate", "queued", "latest-only"]
VALID_REEMISSION = set(ReemissionVal.__args__) # type: ignore
Expand Down Expand Up @@ -1223,6 +1229,13 @@ def emit_fast(self, *args: Any) -> None:
self._args_queue.append(args)
return

if self._recursion_depth >= RECURSION_LIMIT:
raise RecursionError(
f"Psygnal recursion limit ({RECURSION_LIMIT}) reached when emitting "
f"signal {self.name!r} with args {args}"
)

self._recursion_depth += 1
try:
for caller in self._slots:
caller.cb(args)
Expand All @@ -1238,6 +1251,9 @@ def emit_fast(self, *args: Any) -> None:
)
# this comment will show up in the traceback
raise loop_err from cb_err # emit() call ABOVE || callback error BELOW
finally:
if self._recursion_depth > 0:
self._recursion_depth -= 1

def __call__(
self, *args: Any, check_nargs: bool = False, check_types: bool = False
Expand All @@ -1246,6 +1262,9 @@ def __call__(
return self.emit(*args, check_nargs=check_nargs, check_types=check_types)

def _run_emit_loop(self, args: tuple[Any, ...]) -> None:
if self._recursion_depth >= RECURSION_LIMIT:
raise RecursionError("Recursion limit reached!")

with self._lock:
self._emit_queue.append(args)
if len(self._emit_queue) > 1:
Expand Down

0 comments on commit e951f3f

Please sign in to comment.