python / python/mypy

Order of declarations matters, but it shouldn't

Ouverte
#14,519 2 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

bug
Langage dominant
Python
Étoiles
20.6k
Forks
3.3k
Merge moyen
1 j 18 h
PR mergées (30 j)
54

Description

This replaces #14509.

Bug Report

The order of declarations shouldn't matter to mypy w.r.t.[^wrt] type annotations when from __future__ import annotations is in effect, but in the example that follows, they do.

To Reproduce

Analyze the following code with --strict (or run on mypy-play.net):

from __future__ import annotations

import functools
from typing import (
        Any,
        Callable,
        cast,
        Counter,
        Optional,
        TypeVar,
        )


Tc = TypeVar('Tc', bound=Callable[..., Any])


def func_wraps(wraps: Tc) -> Callable[[Callable[..., Any]], Tc]:
    '''declare that one function wraps another

    Args:
        wraps: the function being wrapped

    Returns:
        a function 'decorator()', where...
        Args:
            the function which wraps 'wraps'
        Returns:
            the input argument, unchanged

    The type annotations of the return value of the 'decorator()' will
    be those of 'wraps'.
    '''
    def inner(wrapper: Callable[..., Any], /) -> Tc:
        '''decorator

        Args:
            wrapper: the function which wraps 'wraps'
        Returns:
            the same function, unchanged
        '''
        wrapper_ = cast(Tc, wrapper)
        return functools.wraps(wraps)(wrapper_)
    return inner


def function1() -> ChildClass:
    return ChildClass()


class ParentClass:
    def __init__(self, *, param: Optional[int] = None) -> None:
        _ = param

class ChildClass(ParentClass):
    some_counter: Counter[int]

    @func_wraps(ParentClass.__init__)
    def __init__(self, *args: Any, **kwargs: Any):
        super().__init__(*args, **kwargs)
        self.some_counter = Counter()


def function2() -> ChildClass:
    return ChildClass()

Expected Behavior

There should be no errors.

Actual Behavior

The following error is issued w.r.t.[^wrt] function1:

bug.py:47: error: Returning Any from function declared to return "ChildClass"  [no-any-return]
Found 1 error in 1 file (checked 1 source file)

Your Environment

  • Mypy version used: 0.991, master (2023-01-24)
  • Mypy command-line flags: --show-error-codes --strict --warn-unreachable
  • Mypy configuration options from mypy.ini (and other config files): N/A
  • Python version used: 3.8, 3.11

[^wrt]: with respect to

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par exécuter le reproducteur bug.py fourni avec les flags stricts de mypy, ou utilisez l’exemple mypy-play lié, et comparez les diagnostics pour function1 et function2. Suivez le traitement de l’ordre des déclarations pour les annotations différées et les initialiseurs décorés ; le travail est terminé lorsque le reproducteur ne signale aucune erreur, y compris no-any-return pour function1.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
devtools
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Clairement spécifiée
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.