python / python/mypy

Non-inline `__init_subclass__` definition not recognized, despite giving type hints.

Abierto
#18,987 7 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

bug
Lenguaje dominante
Python
Estrellas
20.6k
Forks
3.3k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

Mypy does not recognize overwritten __init_subclass__ and complains that it's different from object's __init_subclass__.

So a simple code would be something like:

import dataclasses as dcls
from typing import Protocol, TypeVar, Callable

class InitSubclassWithKey(Protocol):
    """
    The ``__init_subclass__`` method of the classes making use of a factory.
    """

    def __call__(self, cls, *, key: str = "") -> None: ...

GLOBAL_REGISTRY = {}

def generate_init_subclass[T](lazy_base_class: Callable[[], T]) -> InitSubclassWithKey:
    def __init_subclass__(cls, *, key: str = "") -> None:
        base_class = lazy_base_class()
        GLOBAL_REGISTRY[base_class, key] = cls
        print("Registered:", base_class, key, cls)

    return __init_subclass__


class Base:
    # Have to use a lazy getter here because or else it would be ``NameError``.
    __init_subclass__ = generate_init_subclass(lambda: Base)

class Derived(Base, key="derived"):
    pass

Expected Derived to pass without issue (as is the case if I define __init_subclass__ directly).
Note: mypy has full type information here because of the protocol given (InitSubclassWithKey).

However, I get:

main.py:26: error: Unexpected keyword argument "key" for "__init_subclass__" of "object"  [call-arg]
Found 1 error in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: mypy 1.15.0 (compiled: yes)
  • Mypy command-line flags: main.py
  • Mypy configuration options from mypy.ini (and other config files): N/A
  • Python version used: 3.13

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con el reproductor en main.py y ejecuta mypy 1.15.0 bajo Python 3.13 para confirmar el error de argumento de palabra clave inesperado. Traza cómo mypy gestiona una asignación no inline a init_subclass y vuelve a object; se considera terminado cuando la asignación tipada de Protocol permite Derived(Base, key="derived") sin errores.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
devtools
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.