Skip to content

Feature request: prevent decorators from making functions effectively untyped #1990

@rchen152

Description

@rchen152

Describe the Bug

Decorating a fully typed function with an untyped decorator can make the function effectively untyped. Example:

from typing import reveal_type

def decorate(f):
    def wrapper(x):
        return f(x)
    return wrapper

@decorate
def f(x: int) -> str:
    return str(x)

reveal_type(f)  # revealed type: (x: Unknown) -> Unknown  # :(

Mypy and pyright deal with this problem in different ways:

  • mypy has a disallow-untyped-decorators setting that emits an error when a typed function is decorated with an untyped decorator playground
  • pyright preserves the original signature when the decorator is untyped playground

I'm leaning toward the mypy approach: it's a smaller change to how we handle decorators, a new unannotated-decorator error kind would fit in nicely with our existing unannotated-{attribute,parameter,return} error kinds, and what pyright does is technically unsafe (although it's a reasonable assumption to make in practice). On the other hand, pyright's behavior seems better for IDE/codenav.

Sandbox Link

https://pyrefly.org/sandbox/?project=N4IgZglgNgpgziAXKOBDAdgEwEYHsAeAdAA4CeS4ATrgLYAEALqcROgOZ0Q3G6UN2UYANxiooAfSbEYAHXRzMMMHUUBjXqgYwAFGACUiOXWMqldAO6VUxaZW34DRk88EMArpXR0w9vU%2BOuHl6W1rZycgACahpaCmY%2B%2BIic6Ax6dAC0AHx0cAyUhl4mgZ45eb7h6IIiYpLMOvogADQgbgzQcCTkiCAAxHQAqm1QEEzebuiqbbjocBWKymC8NJri6G402DB2icmpGdm5%2Bf4CMO4lYDIgAHLrm-l0wPgAvpdyTSBkgmBQpIQMtFAKH0AAqkL4-HIYHAEOjqdCQNgeTQQaaEOR9ADKMBgdAAFgwGMQ4IgAPQkz5KH6EXhsEkwdAkzC4VRwElwhFIqYM7y8OioISoaCobCwWHTDlWLl0XDELkdORkBi46bpESUOAorwAXjolwAzIQAIwAJle6BAT2aqEmEBEADFoDAKGgsHgiGQLUA

(Only applicable for extension issues) IDE Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-discussionAn issue where it's not clear whether there is a bug or we are behaving as expected.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions