Skip to content

sysmon crashes on 3.14.0b4 #2005

@hynek

Description

@hynek

Describe the bug

I had to add 3.14 to run under coverage and it crashes in sysmon:

File "/home/runner/work/attrs/attrs/.tox/py314-tests/lib/python3.14/site-packages/coverage/sysmon.py", line 322, in sysmon_py_start
[256](https://github.com/python-attrs/attrs/actions/runs/16437709695/job/46451014636?pr=1446#step:9:257)
    frame = inspect.currentframe().f_back  # type: ignore[union-attr]
[257](https://github.com/python-attrs/attrs/actions/runs/16437709695/job/46451014636?pr=1446#step:9:258)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[258](https://github.com/python-attrs/attrs/actions/runs/16437709695/job/46451014636?pr=1446#step:9:259)
AttributeError: 'NoneType' object has no attribute 'f_back'

Switching core = "ctrace" in pyproject.toml fixes the problem: python-attrs/attrs@fd5d37816016

Here's the full error:

https://github.com/python-attrs/attrs/actions/runs/16437709695/job/46451014636?pr=1446

For posterity:

py314-tests: remove tox env folder /Users/hynek/FOSS/attrs/.tox/py314-tests
py314-tests: venv> /Users/hynek/.local/share/uv/tools/tox/bin/uv venv -p cpython3.14 --allow-existing --python-preference system /Users/hynek/FOSS/attrs/.tox/py314-tests
py314-tests: uv-sync> uv sync --locked --python-preference system --no-default-groups --no-editable --reinstall-package attrs --group cov -p cpython3.14
py314-tests: venv-query> .tox/py314-tests/bin/python /Users/hynek/.local/share/uv/tools/tox/lib/python3.13/site-packages/tox_uv/_venv_query.py
py314-tests: commands_pre[0]> python -c 'import pathlib; pathlib.Path("/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/cov.pth").write_text("import coverage; coverage.process_startup()")'
py314-tests: commands[0]> coverage run -m pytest
================================================================ test session starts ================================================================
platform darwin -- Python 3.14.0b4, pytest-8.4.1, pluggy-1.6.0
cachedir: .tox/py314-tests/.pytest_cache
rootdir: /Users/hynek/FOSS/attrs
configfile: pyproject.toml
testpaths: tests
plugins: mypy-plugins-3.2.0, hypothesis-6.136.0
collected 1433 items

tests/test_3rd_party.py .                                                                                                                     [  0%]
tests/test_abc.py ....                                                                                                                        [  0%]
tests/test_annotations.py ...............................................                                                                     [  3%]
tests/test_cmp.py ..............................................................................                                              [  9%]
tests/test_compat.py ...                                                                                                                      [  9%]
tests/test_config.py ....                                                                                                                     [  9%]
tests/test_converters.py ......................................                                                                               [ 12%]
tests/test_dunders.py ...................................................................................................                     [ 19%]
tests/test_filters.py .................................                                                                                       [ 21%]
tests/test_funcs.py ...................................................                                                                       [ 24%]
tests/test_functional.py .................................................................................................................... [ 33%]
............................................................................................................................................. [ 42%]
............................................................................................................................................. [ 52%]
............                                                                                                                                  [ 53%]
tests/test_hooks.py ..............                                                                                                            [ 54%]
tests/test_import.py .                                                                                                                        [ 54%]
tests/test_init_subclass.py ....                                                                                                              [ 54%]
tests/test_make.py .................................................................................

========================================================== 868 passed, 1 warning in 11.91s ==========================================================
Traceback (most recent call last):
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/main.py", line 289, in wrap_session
    session.exitstatus = doit(config, session) or 0
                         ~~~~^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/main.py", line 343, in _main
    config.hook.pytest_runtestloop(session=session)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_hooks.py", line 512, in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_manager.py", line 120, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 167, in _multicall
    raise exception
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/logging.py", line 801, in pytest_runtestloop
    return (yield)  # Run all the tests.
            ^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/terminal.py", line 688, in pytest_runtestloop
    result = yield
             ^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 121, in _multicall
    res = hook_impl.function(*args)
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/main.py", line 367, in pytest_runtestloop
    item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_hooks.py", line 512, in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_manager.py", line 120, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 167, in _multicall
    raise exception
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/warnings.py", line 90, in pytest_runtest_protocol
    return (yield)
            ^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/assertion/__init__.py", line 192, in pytest_runtest_protocol
    return (yield)
            ^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/unittest.py", line 475, in pytest_runtest_protocol
    return (yield)
            ^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/faulthandler.py", line 88, in pytest_runtest_protocol
    return (yield)
            ^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 121, in _multicall
    res = hook_impl.function(*args)
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/runner.py", line 117, in pytest_runtest_protocol
    runtestprotocol(item, nextitem=nextitem)
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/runner.py", line 136, in runtestprotocol
    reports.append(call_and_report(item, "call", log))
                   ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/runner.py", line 248, in call_and_report
    report: TestReport = ihook.pytest_runtest_makereport(item=item, call=call)
                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_hooks.py", line 512, in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_manager.py", line 120, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 167, in _multicall
    raise exception
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/tmpdir.py", line 308, in pytest_runtest_makereport
    rep = yield
          ^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 43, in run_old_style_hookwrapper
    teardown.send(result)
    ~~~~~~~~~~~~~^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_hypothesis_pytestplugin.py", line 329, in pytest_runtest_makereport
    report = (yield).get_result()
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_result.py", line 103, in get_result
    raise exc.with_traceback(tb)
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 38, in run_old_style_hookwrapper
    res = yield
          ^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 139, in _multicall
    teardown.throw(exception)
    ~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/skipping.py", line 275, in pytest_runtest_makereport
    rep = yield
          ^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 121, in _multicall
    res = hook_impl.function(*args)
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/runner.py", line 368, in pytest_runtest_makereport
    return TestReport.from_item_and_call(item, call)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/reports.py", line 377, in from_item_and_call
    longrepr = item.repr_failure(excinfo)
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/python.py", line 1713, in repr_failure
    return self._repr_failure_py(excinfo, style=style)
           ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/nodes.py", line 456, in _repr_failure_py
    return excinfo.getrepr(
           ~~~~~~~~~~~~~~~^
        funcargs=True,
        ^^^^^^^^^^^^^^
    ...<5 lines>...
        truncate_args=truncate_args,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/_code/code.py", line 766, in getrepr
    return fmt.repr_excinfo(self)
           ~~~~~~~~~~~~~~~~^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/_code/code.py", line 1202, in repr_excinfo
    reprtraceback = self.repr_traceback(excinfo_)
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/_code/code.py", line 1135, in repr_traceback
    self.repr_traceback_entry(entry, excinfo if last == entry else None)
    ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/_code/code.py", line 1072, in repr_traceback_entry
    end_line_index = entry.end_lineno_relative
                     ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/_code/code.py", line 238, in end_lineno_relative
    frame_summary = self.get_python_framesummary()
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/_code/code.py", line 217, in get_python_framesummary
    stack_summary = extract_tb(self._rawentry, limit=1)
  File "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/traceback.py", line 69, in extract_tb
    def extract_tb(tb, limit=None):

  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/coverage/sysmon.py", line 322, in sysmon_py_start
    frame = inspect.currentframe().f_back  # type: ignore[union-attr]
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'f_back'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pytest/__main__.py", line 9, in <module>
    raise SystemExit(pytest.console_main())
                     ~~~~~~~~~~~~~~~~~~~^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/config/__init__.py", line 201, in console_main
    code = main()
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/config/__init__.py", line 175, in main
    ret: ExitCode | int = config.hook.pytest_cmdline_main(config=config)
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_hooks.py", line 512, in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
           ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_manager.py", line 120, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 167, in _multicall
    raise exception
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/pluggy/_callers.py", line 121, in _multicall
    res = hook_impl.function(*args)
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/main.py", line 336, in pytest_cmdline_main
    return wrap_session(config, _main)
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/main.py", line 309, in wrap_session
    config.notify_exception(excinfo, config.option)
    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/config/__init__.py", line 1176, in notify_exception
    excrepr = excinfo.getrepr(
        funcargs=True, showlocals=getattr(option, "showlocals", False), style=style
    )
  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/_pytest/_code/code.py", line 747, in getrepr
    format_exception(
    ~~~~~~~~~~~~~~~~^
        self.type,
        ^^^^^^^^^^
        self.value,
        ^^^^^^^^^^^
        self.traceback[0]._rawentry if self.traceback else None,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/traceback.py", line 146, in format_exception
    def format_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \

  File "/Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/coverage/sysmon.py", line 322, in sysmon_py_start
    frame = inspect.currentframe().f_back  # type: ignore[union-attr]
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'f_back'
py314-tests: exit 1 (14.20 seconds) /Users/hynek/FOSS/attrs> coverage run -m pytest pid=69738
  py314-tests: FAIL code 1 (15.18=setup[0.95]+cmd[0.03,14.20] seconds)
  evaluation failed :( (15.24 seconds)

To Reproduce

  1. What version of Python are you using?

3.14.0b4

  1. What version of coverage.py shows the problem? The output of coverage debug sys is helpful.

7.9.2

❯ .tox/py314-tests/bin/coverage debug sys
-- sys -------------------------------------------------------
               coverage_version: 7.9.2
                coverage_module: /Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages/coverage/__init__.py
                           core: -none-
                        CTracer: unavailable
           plugins.file_tracers: -none-
            plugins.configurers: -none-
      plugins.context_switchers: -none-
              configs_attempted: /Users/hynek/FOSS/attrs/.coveragerc
                                 /Users/hynek/FOSS/attrs/setup.cfg
                                 /Users/hynek/FOSS/attrs/tox.ini
                                 /Users/hynek/FOSS/attrs/pyproject.toml
                   configs_read: /Users/hynek/FOSS/attrs/tox.ini
                                 /Users/hynek/FOSS/attrs/pyproject.toml
                    config_file: /Users/hynek/FOSS/attrs/pyproject.toml
                config_contents: b'# SPDX-License-Identifier: MIT\n\n[build-system]\nrequires = ["hatchling", "hatch-vcs", "hatch-fancy-pypi-readme>=23.2.0"]\nbuild-backend = "hatchling.build"\n\n\n[project]\nname = "attrs"\nauthors = [{ name = "Hynek Schlawack", email = "[email protected]" }]\nlicense = "MIT"\nlicense-files = ["LICENSE"]\nrequires-python = ">=3.9"\ndescription = "Classes Without Boilerplate"\nkeywords = ["class", "attribute", "boilerplate"]\nclassifiers = [\n  "Development Status :: 5 - Production/Stable",\n  "Programming Language :: Python :: 3.9",\n  "Programming Language :: Python :: 3.10",\n  "Programming Language :: Python :: 3.11",\n  "Programming Language :: Python :: 3.12",\n  "Programming Language :: Python :: 3.13",\n  "Programming Language :: Python :: 3.14",\n  "Programming Language :: Python :: Implementation :: CPython",\n  "Programming Language :: Python :: Implementation :: PyPy",\n  "Typing :: Typed",\n]\ndependencies = []\ndynamic = ["version", "readme"]\n\n[project.urls]\nDocumentation = "https://www.attrs.org/"\nChangelog = "https://www.attrs.org/en/stable/changelog.html"\nGitHub = "https://github.com/python-attrs/attrs"\nFunding = "https://github.com/sponsors/hynek"\nTidelift = "https://tidelift.com/subscription/pkg/pypi-attrs?utm_source=pypi-attrs&utm_medium=pypi"\n\n\n[dependency-groups]\ntests-mypy = [\'pytest-mypy-plugins; platform_python_implementation == "CPython" and python_version >= "3.10"\']\ntests = [\n  { include-group = "tests-mypy" },\n  # For regression test to ensure cloudpickle compat doesn\'t break.\n  \'cloudpickle; platform_python_implementation == "CPython"\',\n  "hypothesis",\n  "pympler",\n  "pytest",\n]\ncov = [\n  { include-group = "tests" },\n  "coverage[toml]",\n]\npyright = ["pyright", { include-group = "tests" }]\nbenchmark = [\n  { include-group = "tests" },\n  "pytest-codspeed",\n  "pytest-xdist[psutil]",\n]\ndocs = [\n  "cogapp",\n  "furo",\n  "myst-parser",\n  "sphinx",\n  "sphinx-notfound-page",\n  "sphinxcontrib-towncrier",\n  "towncrier",\n]\ndocs-watch = [{ include-group = "docs" }, "watchfiles"]\ndev = [{ include-group = "tests" }]\n\n\n[tool.hatch.version]\nsource = "vcs"\nraw-options = { local_scheme = "no-local-version" }\n\n[tool.hatch.build.targets.wheel]\npackages = ["src/attr", "src/attrs"]\n\n[tool.hatch.metadata.hooks.fancy-pypi-readme]\ncontent-type = "text/markdown"\n\n# PyPI doesn\'t support the <picture> tag.\n[[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]]\ntext = """<p align="center">\n  <a href="https://www.attrs.org/">\n    <img src="https://raw.githubusercontent.com/python-attrs/attrs/main/docs/_static/attrs_logo.svg" width="35%" alt="attrs" />\n  </a>\n</p>\n"""\n\n[[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]]\npath = "README.md"\nstart-after = "<!-- teaser-begin -->"\n\n[[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]]\ntext = """\n\n## Release Information\n\n"""\n\n[[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]]\npath = "CHANGELOG.md"\npattern = "\\n(###.+?\\n)## "\n\n[[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]]\ntext = """\n\n---\n\n[Full changelog \xe2\x86\x92](https://www.attrs.org/en/stable/changelog.html)\n"""\n\n# Point sponsor image URLs to versions.\n[[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]]\npattern = \'docs\\/_static\\/sponsors\'\nreplacement = \'https://www.attrs.org/en/$HFPR_VERSION/_static/sponsors\'\n\n[[tool.sponcon.sponsors]]\ntitle = "Variomedia AG"\nurl = "https://www.variomedia.de/"\nimg = "Variomedia.svg"\n\n[[tool.sponcon.sponsors]]\ntitle = "Tidelift"\nurl = "https://tidelift.com/?utm_source=lifter&utm_medium=referral&utm_campaign=hynek"\nimg = "Tidelift.svg"\n\n[[tool.sponcon.sponsors]]\ntitle = "Klaviyo"\nurl = "https://klaviyo.com/"\nimg = "Klaviyo.svg"\n\n[[tool.sponcon.sponsors]]\ntitle = "Privacy Solutions"\nurl = "https://privacy-solutions.org/"\nimg = "Privacy-Solutions.svg"\n\n[[tool.sponcon.sponsors]]\ntitle = "emsys renewables"\nurl = "https://www.emsys-renewables.com/"\nimg = "emsys-renewables.svg"\n\n[[tool.sponcon.sponsors]]\ntitle = "FilePreviews"\nurl = "https://filepreviews.io/"\nimg = "FilePreviews.svg"\n\n[[tool.sponcon.sponsors]]\ntitle = "Polar"\nurl = "https://polar.sh/"\nimg = "Polar.svg"\n\n\n[tool.pytest.ini_options]\naddopts = ["-ra", "--strict-markers", "--strict-config"]\nxfail_strict = true\ntestpaths = "tests"\nfilterwarnings = ["once::Warning", "ignore:::pympler[.*]"]\n\n\n[tool.coverage.run]\nparallel = true\nbranch = true\nsource_pkgs = ["attr", "attrs"]\ncore = "ctrace"  # currently necessary for 3.14\n\n[tool.coverage.paths]\nsource = ["src", ".tox/py*/**/site-packages"]\n\n[tool.coverage.report]\nshow_missing = true\nskip_covered = true\nexclude_lines = [\n  "pragma: no cover",\n  # PyPy is unacceptably slow under coverage.\n  "if PYPY:",\n  # not meant to be executed\n  \': \\.\\.\\.$\',\n  \'^ +\\.\\.\\.$\',\n]\n\n\n[tool.interrogate]\nomit-covered-files = true\nverbose = 2\nfail-under = 100\nwhitelist-regex = ["test_.*"]\n\n\n[tool.check-wheel-contents]\ntoplevel = ["attr", "attrs"]\n\n\n[tool.ruff]\nsrc = ["src", "tests", "conftest.py", "docs"]\nline-length = 79\n\n[tool.ruff.per-file-target-version]\n"tests/test_pattern_matching.py" = "py310"\n\n[tool.ruff.lint]\nselect = ["ALL"]\nignore = [\n  "A001",    # shadowing is fine\n  "A002",    # shadowing is fine\n  "A003",    # shadowing is fine\n  "ANN",     # Mypy is better at this\n  "ARG",     # unused arguments are normal when implementing interfaces\n  "C901",    # we\'re complex software\n  "COM",     # ruff format takes care of our commas\n  "D",       # We prefer our own docstring style.\n  "E501",    # leave line-length enforcement to ruff format\n  "ERA001",  # we need to keep around some notes\n  "FBT",     # we don\'t hate bool args around here\n  "FIX",     # Yes, we want XXX as a marker.\n  "ISC001",  # conflicts with ruff format\n  "N",       # we need more naming freedom\n  "PD",      # we\'re not pandas\n  "PLC0415", # sometimes, imports have to live elsewhere\n  "PLR0912", # we\'re complex software\n  "PLR0913", # yes, many arguments, but most have defaults\n  "PLR0915", # we\'re complex software\n  "PLR2004", # numbers are sometimes fine\n  "PLW0603", #sometimes we need globals\n  "S307",    # eval FTW\n  "SLF001",  # private members are accessed by friendly functions\n  "TC",      # TYPE_CHECKING blocks break autodocs\n  "TD",      # we don\'t follow other people\'s todo style\n  "TRY301",  # I\'m sorry, but this makes not sense for us.\n  "UP031",   # format() is slow as molasses; % and f\'\' FTW.\n  "UP006",   # replace Dict etc by dict etc later.\n  "UP035",   # replace Dict etc by dict etc later.\n]\n\n[tool.ruff.lint.per-file-ignores]\n"bench/**" = [\n  "INP001", # Benchmarks don\'t have to be importable.\n]\n"**/test_*" = [\n  "B015",    # pointless comparison in tests aren\'t pointless\n  "B017",    # pytest.raises(Exception) is fine\n  "B018",    # pointless expressions in tests aren\'t pointless\n  "DTZ",     # datetime best practices don\'t matter in tests\n  "EM",      # no need for exception msg hygiene in tests\n  "PLE0309", # hash doesn\'t have to return anything in tests\n  "PLW1641", # it\'s OK to rely object\'s __hash__\n  "PLR0124", # pointless comparison in tests aren\'t pointless\n  "PT011",   # broad is fine\n  "PT012",   # sometimes we need more than a single stmt\n  "RUF012",  # we don\'t do ClassVar annotations in tests\n  "S",       # security concerns don\'t matter in tests\n  "SIM201",  # sometimes we need to check `not ==`\n  "SIM202",  # sometimes we need to check `not ==`\n  "SIM300",  # Yoda rocks in asserts\n  "TRY",     # exception best practices don\'t matter in tests\n]\n\n"src/*/*.pyi" = ["ALL"] # TODO\n"tests/test_annotations.py" = ["FA100"]\n"tests/typing_example.py" = [\n  "E741",  # ambiguous variable names don\'t matter in type checks\n  "B018",  # useless expressions aren\'t useless in type checks\n  "B015",  # pointless comparison in type checks aren\'t pointless\n  "UP037", # we test some older syntaxes on purpose\n]\n\n[tool.ruff.lint.isort]\nlines-between-types = 1\nlines-after-imports = 2\n\n\n[tool.towncrier]\nname = "attrs"\ndirectory = "changelog.d"\nfilename = "CHANGELOG.md"\nstart_string = "<!-- towncrier release notes start -->\\n"\ntemplate = "changelog.d/towncrier_template.md.jinja"\ntitle_format = ""\nissue_format = "[#{issue}](https://github.com/python-attrs/attrs/issues/{issue})"\nunderlines = ["", "", ""]\n\n[[tool.towncrier.section]]\npath = ""\n\n[[tool.towncrier.type]]\ndirectory = "breaking"\nname = "Backwards-incompatible Changes"\nshowcontent = true\n\n[[tool.towncrier.type]]\ndirectory = "deprecation"\nname = "Deprecations"\nshowcontent = true\n\n[[tool.towncrier.type]]\ndirectory = "change"\nname = "Changes"\nshowcontent = true\n\n\n[tool.mypy]\npretty = true\ndisallow_untyped_defs = true\ncheck_untyped_defs = true\n'
                      data_file: -none-
                         python: 3.14.0b4 (v3.14.0b4:7ec1faba0c8, Jul  8 2025, 05:34:15) [Clang 16.0.0 (clang-1600.0.26.6)]
                       platform: macOS-15.5-arm64-arm-64bit-Mach-O
                 implementation: CPython
                          build: v3.14.0b4:7ec1faba0c8
                                 Jul  8 2025 05:34:15
                    gil_enabled: True
                     executable: /Users/hynek/FOSS/attrs/.tox/py314-tests/bin/python3
                   def_encoding: utf-8
                    fs_encoding: utf-8
                            pid: 78428
                            cwd: /Users/hynek/FOSS/attrs
                           path: /Users/hynek/FOSS/attrs/.tox/py314-tests/bin
                                 /Library/Frameworks/Python.framework/Versions/3.14/lib/python314.zip
                                 /Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14
                                 /Library/Frameworks/Python.framework/Versions/3.14/lib/python3.14/lib-dynload
                                 /Users/hynek/FOSS/attrs/.tox/py314-tests/lib/python3.14/site-packages
                    environment: HOME = /Users/hynek
                                 PIPX_DEFAULT_PYTHON = /Library/Frameworks/Python.framework/Versions/3.13/bin/python3.13
                                 PYTHONSTARTUP = /Users/hynek/.pythonstartup
                                 PYTHON_CONFIGURE_OPTS = --enable-framework
                                 PYTHON_HISTORY = .python-history
                                 PY_PYTHON = 3.13
                                 UV_PYTHON_PREFERENCE = system
                                 VIRTUALFISH_DEFAULT_PYTHON = python3.13
                   command_line: .tox/py314-tests/bin/coverage debug sys
         sqlite3_sqlite_version: 3.49.1
             sqlite3_temp_store: 0
        sqlite3_compile_options: ATOMIC_INTRINSICS=1, COMPILER=clang-16.0.0, DEFAULT_AUTOVACUUM,
                                 DEFAULT_CACHE_SIZE=-2000, DEFAULT_FILE_FORMAT=4,
                                 DEFAULT_JOURNAL_SIZE_LIMIT=-1, DEFAULT_MMAP_SIZE=0, DEFAULT_PAGE_SIZE=4096,
                                 DEFAULT_PCACHE_INITSZ=20, DEFAULT_RECURSIVE_TRIGGERS,
                                 DEFAULT_SECTOR_SIZE=4096, DEFAULT_SYNCHRONOUS=2,
                                 DEFAULT_WAL_AUTOCHECKPOINT=1000, DEFAULT_WAL_SYNCHRONOUS=2,
                                 DEFAULT_WORKER_THREADS=0, DIRECT_OVERFLOW_READ, ENABLE_FTS3,
                                 ENABLE_FTS3_PARENTHESIS, ENABLE_FTS4, ENABLE_FTS5, ENABLE_MATH_FUNCTIONS,
                                 ENABLE_RTREE, MALLOC_SOFT_LIMIT=1024, MAX_ATTACHED=10, MAX_COLUMN=2000,
                                 MAX_COMPOUND_SELECT=500, MAX_DEFAULT_PAGE_SIZE=8192, MAX_EXPR_DEPTH=1000,
                                 MAX_FUNCTION_ARG=1000, MAX_LENGTH=1000000000,
                                 MAX_LIKE_PATTERN_LENGTH=50000, MAX_MMAP_SIZE=0x7fff0000,
                                 MAX_PAGE_COUNT=0xfffffffe, MAX_PAGE_SIZE=65536, MAX_SQL_LENGTH=1000000000,
                                 MAX_TRIGGER_DEPTH=1000, MAX_VARIABLE_NUMBER=32766, MAX_VDBE_OP=250000000,
                                 MAX_WORKER_THREADS=8, MUTEX_PTHREADS, OMIT_AUTOINIT, SYSTEM_MALLOC, TCL,
                                 TEMP_STORE=1, THREADSAFE=1
  1. What versions of what packages do you have installed? The output of pip freeze is helpful.
❯ uv pip freeze -p .tox/py314-tests/bin/python
Using Python 3.14.0b4 environment at: .tox/py314-tests
attrs @ file:///Users/hynek/FOSS/attrs
cloudpickle==3.1.1
coverage==7.9.2
decorator==5.2.1
hypothesis==6.136.0
iniconfig==2.1.0
jinja2==3.1.6
jsonschema==4.25.0
jsonschema-specifications==2025.4.1
markupsafe==3.0.2
mypy==1.17.0
mypy-extensions==1.1.0
packaging==25.0
pathspec==0.12.1
pluggy==1.6.0
pygments==2.19.2
pympler==1.1
pytest==8.4.1
pytest-mypy-plugins==3.2.0
pyyaml==6.0.2
referencing==0.36.2
regex==2024.11.6
rpds-py==0.26.0
sortedcontainers==2.4.0
tomlkit==0.13.3
typing-extensions==4.14.1
  1. What code shows the problem? Give us a specific commit of a specific repo that we can check out. If you've already worked around the problem, please provide a commit before that fix.

python-attrs/attrs#1446 – I might merge it soon, so it will be in main.

  1. What commands should we run to reproduce the problem? Be specific. Include everything, even git clone, pip install, and so on. Explain like we're five!
  • gh pr checkout 1446
    • if merged: gh repo clone python-attrs/attrs
  • remove core = "ctrace" from pyproject.toml
  • run tox -re py314-tests

Expected behavior

Not a crash 😇

Additional context
You're awesome!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions