Visitar URL original
Comparing master@{1day}...master · python/mypy · GitHub
Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: python/mypy
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master@{1day}
Choose a base ref
...
head repository: python/mypy
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
  • 7 commits
  • 30 files changed
  • 2 contributors

Commits on Oct 12, 2026

  1. [mypyc] Fix compile error when a native __next__ returns an unboxed…

    … value (#22145)
    
    Fixes mypyc/mypyc#1235.
    
    `native_slot()` filled `tp_iternext` with the native `__next__` method
    itself, which only works if the method returns `PyObject *`. With `->
    int`, CPython got the tagged integer, or `CPY_INT_TAG` after
    `StopIteration`, as an object pointer, so `next()`, `for` loops,
    `list()` and `obj.__next__()` from Python all crashed. `float`, `i64`
    and tuples crashed too. With `bool`, `False` came back as NULL, so the
    iteration stopped early without an error. MSVC warns about the mismatch
    (C4047).
    
    `native_slot()` now uses `generate_dunder_wrapper()` when the method
    returns an unboxed value. That's the wrapper the unary number slots such
    as `__int__` and `__index__` already use. It calls the native method,
    returns NULL if the method raised (checking `PyErr_Occurred()` for types
    such as `float`, whose error value is also a valid value), and boxes the
    result. A `StopIteration` raised by `__next__` still ends the iteration,
    because the wrapper returns NULL with it set. Methods that return an
    object, including the `__next__` of every native generator, still fill
    the slot directly, so they don't get an extra call. The other slots that
    use `native_slot()` (`__iter__`, `__str__`, `__repr__`, `__await__`,
    `__aiter__` and `__anext__`) get the same check, although they normally
    return objects.
    rheard authored Oct 12, 2026
    Configuration menu
    Copy the full SHA
    b7a3905 View commit details
    Browse the repository at this point in the history
  2. [mypyc] Fix segfault when a native __get__ returns an unboxed value (#…

    …22146)
    
    Fixes mypyc/mypyc#1236.
    
    `generate_get_wrapper()` returned the result of the native `__get__`
    from the `tp_descr_get` slot without boxing it. With `-> int`, CPython
    got the tagged integer as an object pointer and crashed. With `-> bool`,
    a `False` came back as NULL and raised `SystemError: error return
    without exception set`. With `-> float` or a tuple, the generated C
    didn't compile (`error C2440` on MSVC). The wrapper now checks for an
    error and boxes unboxed return values, like the other dunder wrappers.
    Methods that return an object, including the `__get__` that mypyc
    generates for nested functions and lambdas, still return the result
    directly.
    
    CPython calls `tp_descr_get` with a NULL `owner` for `d.__get__(obj,
    None)`, and the wrapper passed the NULL on to the method, so a `__get__`
    that used `owner` crashed. The wrapper already replaced a NULL
    `instance` with `None`, and it now does the same for `owner`, which is
    also what CPython does for a `__get__` defined in Python.
    
    The arguments are still passed on without type checks. Building the
    wrapper with `WrapperGenerator`, which checks them, would make a
    `__get__` whose `instance` is annotated with a non-native host class
    raise `TypeError` for instances of Python subclasses of that class,
    because type checks for non-native classes are exact (see
    mypyc/mypyc#1148).
    rheard authored Oct 12, 2026
    Configuration menu
    Copy the full SHA
    09f3e00 View commit details
    Browse the repository at this point in the history
  3. [mypyc] Reject calling a property through class object (#22155)

    Follow-up to #22139, from [this review
    comment](#22139 (comment)).
    
    mypy types `C.prop` as the property's getter, so it accepts
    `C.prop(obj)`. At runtime, `C.prop` is the property object (a getset
    descriptor for a native class), and calling it raises `TypeError:
    'property' object is not callable`. For a native class, mypyc compiled
    `C.prop(obj)` as a direct call to the getter, so it returned `obj.prop`
    instead of raising. The same happened with inherited, read-write and
    trait properties, and with `cls.prop(obj)` in a classmethod of a class
    with no subclasses. If the getter was an abstract trait property with an
    empty body, the process aborted (`Fatal Python error: Aborted`).
    
    mypyc now reports an error for these calls, like the existing error for
    accessing an instance attribute through a class object:
    
    ```
    error: Cannot call property "prop" through class object
    ```
    
    #18969 would make mypy report these calls (`"property" not
    callable`) in code that it type checks, but mypyc still needs its own
    check.
    rheard authored Oct 12, 2026
    Configuration menu
    Copy the full SHA
    a5be5d8 View commit details
    Browse the repository at this point in the history
  4. Do not use types as error contexts during type checking (#22156)

    Fixes #16175
    Fixes #8592
    
    Situations where an error has a wrong line number are very annoying
    (maybe even more than a crash). Using types as error context during type
    checking is really risky. So, I removed all such cases in `checker.py`
    in `checkexpr.py` (by locally removing `Context` as a base class for
    `Type`). Most remaining uses are in `semanal.py` and `typeanal.py`.
    Those are less risky, and trickier to remove.
    
    Notes:
    * This will cause less precise error locations, but IMO it is much
    better than some random bizarre locations.
    * I only add tests for situations with known repros.
    * While I am at it, I do not emit variance errors for lambdas, unless I
    a missing something, those are bogus.
    ilevkivskyi authored Oct 12, 2026
    Configuration menu
    Copy the full SHA
    69dcb38 View commit details
    Browse the repository at this point in the history
  5. Fix new style union aliases with not ready items (#22172)

    Fixes #21263
    Fixes #11887
    
    Old style aliases with new style unions are quite tricky, since this
    requires some heuristics to figure out whether this is a type alias or a
    regular variable. Things get even trickier when some items are not
    ready, because our heuristics must be robust w.r.t. to this.
    
    I spent few hours today playing with this, and I don't think there is a
    fully-principled fix that doesn't involve rewriting a bunch of logic.
    But I think I have something that is still fairly principled. Namely, in
    this PR:
    * Handle `becomes_typeinfo` status for imported placeholders
    consistently.
    * Put `should_wait_rhs()` back in sync with `can_be_type_alias()` w.r.t.
    `OpExpr`.
    * Add "backtracking" logic (maybe type alias -> actually a regular
    variable) for one rare case that is tricky to handle otherwise.
    
    Note, the root cause of the crash is that we normally never change a
    type alias back to a regular variable. Normal flow for a symbol table
    entry is always like this `None -> PlaceholderNode ->
    PlaceholderNode(becomes_typeinfo=True) -> SymbolNode` (where some steps
    may be skipped). A lot of logic depends on this, but in the relevant
    scenarios it is tricky to follow this principle.
    ilevkivskyi authored Oct 12, 2026
    Configuration menu
    Copy the full SHA
    fe98edc View commit details
    Browse the repository at this point in the history
  6. [mypyc] Specialize .real and .imag on float and complex (#22143)

    Fixes mypyc/mypyc#1228
    
    This is a duplicate of #22099. I'm opening this due to Github issues
    yesterday. This includes patches due to @p-sawicki's review
    
    Reading `.real` or `.imag` from a value typed as `int`, `float`,
    `complex`, or a union of them was compiled to a generic attribute
    lookup, whose result was then unboxed or type-checked again. Native
    `int`, `bool` and `float` values were even boxed first, only to read
    back the same value or zero. I ran into this in the same code as #22097.
    
    This specializes these reads when the static type of the receiver is
    `int`, `float`, `complex` or a union of them, which includes values
    narrowed by `isinstance()`:
    
    - On native `int`, `bool` and `float` values, `x.real` is the value
    itself (converted to an `int` for a `bool`), and `x.imag` is `0` or
    `0.0`.
    - When the result is a `float` (receivers typed `float`, `complex` or
    `float | complex`), new `CPyComplex_Real` and `CPyComplex_Imag`
    primitives read exact `complex`, `float` and `int` objects directly as a
    C double.
    - When the result can be an `int` (receivers such as `int | float |
    complex`), new `CPyNumber_Real` and `CPyNumber_Imag` primitives return
    exact `int` and `float` objects themselves, as `int.real` and
    `float.real` do, and read exact `complex` objects directly.
    
    Anything else (a subclass that overrides `real` or `imag`, a `bool` in a
    union, or an object of the wrong type at runtime) uses the same lookup
    as before, followed by the same unboxing or type check, so results and
    error messages don't change.
    
    The run tests cover NaN, infinities, `-0.0`, a value equal to mypyc's
    float error value (`-113.0`), small and large ints, bools, subclasses
    that override the properties, and the error cases.
    
    Microbenchmark results (Python 3.12, ns per value):
    - `z.real + z.imag` with `z: complex`: 59.3 -> 6.0
    - the same with ints passed as `z: complex`: 55.8 -> 7.1
    - `x.real + x.imag` with `x: float`: 49.9 -> 6.0
    - `x.real + x.imag` with `x: int`: 41.8 -> 9.9
    - `x.real` and `x.imag` with `x: int | float | complex`: 29.6 -> 8.1
    with ints, 36.9 -> 13.0 with floats, 46.3 -> 18.8 with complex values
    (35.0 -> 25.7 when the three alternate)
    - `if isinstance(x, (float, complex)): real, imag = x.real, x.imag` with
    `x: Any`: 93.9 -> 52.7, or 6.6 together with #22097
    rheard authored Oct 12, 2026
    Configuration menu
    Copy the full SHA
    9536af3 View commit details
    Browse the repository at this point in the history
  7. Bump ast-serialize to 0.13.0 (#22186)

    One test needs update because duplicate type comments are not blockers
    anymore.
    ilevkivskyi authored Oct 12, 2026
    Configuration menu
    Copy the full SHA
    0ff0c12 View commit details
    Browse the repository at this point in the history
Loading