Skip to content

Fix missing slot false positives for finalize.atexit & TarInfo.path - #16333

Merged
srittau merged 1 commit into
python:mainfrom
zyv:slots-properties
Sep 1, 2026
Merged

Fix missing slot false positives for finalize.atexit & TarInfo.path#16333
srittau merged 1 commit into
python:mainfrom
zyv:slots-properties

Conversation

@zyv

@zyv zyv commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Both are declared as bare instance attributes on classes whose stub also declares __slots__ without them, so type checkers reject every assignment to them even though the runtime allows it. CPython implements both as read-write properties.

weakref.finalize (Lib/weakref.py) has __slots__ = () and implements atexit as a property with a setter; the neighbouring alive is already modelled as a property in typeshed.

tarfile.TarInfo (Lib/tarfile.py) implements path as a read-write property aliasing name, exactly like linkpath aliases linkname; linkpath is already modelled as a property, path was not, and path is absent from the __slots__ tuple.

Reproducer, rejected before and accepted after this patch:

import tarfile
import weakref

class C: ...

def f(c: C, ti: tarfile.TarInfo) -> None:
    weakref.finalize(c, print).atexit = False
    ti.path = "x"

mypy 2.3.1 before:

error: Trying to assign name "atexit" that is not in "__slots__" of type "weakref.finalize"  [misc]
error: Trying to assign name "path" that is not in "__slots__" of type "tarfile.TarInfo"  [misc]

ty 0.0.77 reports the same two as missing-slot; pyrefly reports missing-attribute. stubtest output is unchanged for both modules.

The __slots__ entries came from the automated sweep in #14611 (part of #8832). The attribute declarations predate it, so the contradiction was introduced by adding __slots__ on top of them rather than by the annotations themselves.

Both are declared as bare instance attributes on classes whose stub also
declares `__slots__` without them, so type checkers reject every assignment
to them even though the runtime allows it. CPython implements both as
read-write properties.

`weakref.finalize` (Lib/weakref.py) has `__slots__ = ()` and implements
`atexit` as a property with a setter; the neighbouring `alive` is
already modelled as a property in typeshed.

`tarfile.TarInfo` (Lib/tarfile.py) implements `path` as a read-write
property aliasing `name`, exactly like `linkpath` aliases `linkname`;
`linkpath` is already modelled as a property, `path` was not, and
`path` is absent from the `__slots__` tuple.

Reproducer, rejected before and accepted after this patch:

    import tarfile
    import weakref

    class C: ...

    def f(c: C, ti: tarfile.TarInfo) -> None:
        weakref.finalize(c, print).atexit = False
        ti.path = "x"

mypy 2.3.1 before:

  error: Trying to assign name "atexit" that is not in "__slots__" of type "weakref.finalize"  [misc]
  error: Trying to assign name "path" that is not in "__slots__" of type "tarfile.TarInfo"  [misc]

ty 0.0.77 reports the same two as `missing-slot`; pyrefly reports
`missing-attribute`. stubtest output is unchanged for both modules.

The `__slots__` entries came from the automated sweep in python#14611.
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

dd-trace-py (https://github.com/DataDog/dd-trace-py)
- ddtrace/internal/wrapping/context.py:485: error: Trying to assign name "atexit" that is not in "__slots__" of type "weakref.finalize"  [misc]

@srittau srittau left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@srittau
srittau merged commit ff2ee1e into python:main Sep 1, 2026
88 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants