Skip to content

Use try_call_dunder infrastructure consistently #190

@sharkdp

Description

@sharkdp

Summary

__enter__ and __exit__ should be treated like all other dunder methods. However, while working on astral-sh/ruff#16368, I noticed that we look them up manually (and potentially incorrectly) here …

https://github.com/astral-sh/ruff/blob/1be0dc6885317340acdd3427aa43acc05e7a43d3/crates/red_knot_python_semantic/src/types/infer.rs#L1621-L1622

… and call them manually (and potentially incorrectly) here:

https://github.com/astral-sh/ruff/blob/1be0dc6885317340acdd3427aa43acc05e7a43d3/crates/red_knot_python_semantic/src/types/infer.rs#L1660-L1661

This only leads to incorrect behavior in very exotic situations like the following, where we incorrectly raise a "Object of type Manager cannot be used with with because it does not correctly implement __enter__" diagnostic:

from __future__ import annotations

class Target: ...

class SomeCallable:
    def __call__(self) -> Target:
        return Target()

class Descriptor:
    def __get__(self, instance, owner) -> SomeCallable:
        return SomeCallable()

class Manager:
    __enter__: Descriptor = Descriptor()

    def __exit__(self, exc_type, exc_value, traceback): ...

with Manager() as f:
    reveal_type(f)  # revealed: Target

Fixing this would involve using try_call_dunder after astral-sh/ruff#16368 is merged, or using static_member + a manual descriptor call, if that is not possible.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions