Skip to content

Incorporate typing_extensions into type checkers #19

Closed

Description

@jakub-toptal

What's needed?

Type annotations in some cases are limited and thus it would be good to enhance them with what the typing-extensions package has to offer.

One example of this would be @classmethod, which always uses cls argument as the first argument. Ideally, we would annotate it with the Self type from the typing-extensions package.

Proposed solution

Use typing-extensions package to enhance type annotations.

Use cases

This can be applied to @classmethods and perhaps other functions used as decorators. One apparent case where we could use better type checking is the @actor decorator, which decorates classes at runtime making it impossible for pylint to verify if attributes / methods are defined on the decorated class.

Alternatives and workarounds

In case of @classmethod, we an omit the type annotation for the cls argument and it still passes type checking.

Otherwise, we have to explicitly tell type checkers pylint and/or mypy that a particular line should be ignored, because there is no correct type annotation available.

Additional context

No response

Activity

  1. added
    part:❓We need to figure out which part is affected
    priority:❓We need to figure out how soon this should be addressed
    type:enhancementNew feature or enhancement visitble to users
    on Oct 6, 2022
  2. leandro-lucarella-frequenz commented on Oct 6, 2022

    @leandro-lucarella-frequenz
    Contributor

    One important clarification:

    Using Self is particularly useful for @classmethods acting as alternative constructors, because the cls argument should a special case in type checkers, as it is known that it always have to be the type of the class defining the @classmethod.

    But for @classmethods acting as alternative constructors, you also need to return the type of the class defining the @classmethod, and this has to work too for subclasses not re-defining the alternative constructor.

    As a workaround we can use the class name explicitly.

    For example:

    class S:
        @classmethod
        def make(cls) -> S:
            return cls()
    
    class T(S):
        pass
    
    def print_t(t: T) -> None:
        print(t)
    
    print_t(T.make())

    This should fail a type checking, because T.make() is marked to return a S, not a T. But this should work:

    from typing_extensions import Self
    
    class S:
        @classmethod
        def make(cls) -> Self:  # <------
            return cls()
    
    class T(S):
        pass
    
    def print_t(t: T) -> None:
        print(t)
    
    print_t(T.make())

    Note: this is untested because mypy doesn't support Self yet, but is what I assume it should happen :)

  3. leandro-lucarella-frequenz commented on Oct 7, 2022

    @leandro-lucarella-frequenz
    Contributor

    Some other important clarifications:

    • Self is introduced in Python 3.11.
    • typing-extensions is not a random package, is an official Python package maintained by the Python organization and only includes features backported from newer Python versions so they are available for older versions. Thus the use of this package is by definition temporary (until we can depend on a new enough Python minimal version)
    • mypy doesn't support Self yet, this is why we didn't go for it. There is a PR, so support should come fairly soon. Implementation of PEP 673 (typing.Self) python/mypy#11666
    • This comes from another PR's discussion: Change component data wrappers to be data classes #4 (comment)
  4. removed
    part:❓We need to figure out which part is affected
    priority:❓We need to figure out how soon this should be addressed
    on Oct 7, 2022
  5. leandro-lucarella-frequenz commented on Apr 21, 2023

    @leandro-lucarella-frequenz
    Contributor

    We already have typing_extensions as a dependency and mypy already supports Self, we just need to start using it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

type:enhancementNew feature or enhancement visitble to users

Type

No type

Fields

Priority

None yet

Projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions