Skip to content

Type of first argument of class methods should not be 'type' #123

Closed

Description

@JukkaL

This is an extract from the PEP draft:

An exception is that the first argument of instance and
class methods does not need to be annotated; it is assumed to have the
type of the containing class for instance methods, and type for
class methods.

If the type of first argument of a class method is type, it wouldn't be possible to access other class attributes or methods via the argument. Consider this code:

class A:
    n = 0

    @classmethod
    def f(cls) -> None:
        cls.n = 1   # Error?

This should probably be okay, but type does not have attribute n, so a type checker would have to reject the code if type of cls is type. A better type would be something like Type[A] mentioned in #107. Note that we don't necessarily need to support Type[A] for user code -- this type can be internal to the type checker, similar to callable types with *args etc. that can't be represented using the type syntax.

(Mypy currently uses Any for the first argument of class methods, but that's an implementation limitation that should be fixed.)

Activity

  1. ilevkivskyi commented on May 21, 2015

    @ilevkivskyi
    Member

    I agree, Type[A] would be much better. To implement this, one probably needs to also infer values of variables for which type type is inferred. Then one can compare the inferred value with annotation Type[A]. By the way, currently mypy complains about this

    temp = dict
    
    def f(x: dict):
        ...
    
    mydict = temp()
    
    f(mydict)

    Also, I think it would be useful to support Type[A] for user code for the reasons mentioned in #107

  2. ilevkivskyi commented on May 21, 2015

    @ilevkivskyi
    Member

    Actually, if I replace dict with int then everything works as expected. Problem with dict probably was that it wants Dict[A,B]. This means that it should be easy to implement Type[A], mypy already can infer values of variables, so you just need to add a check that the value of cls in

    def func(cls: Type[A]):
        ...

    is consistent with the annotation, i.e. issubclass(cls, A) == True.

  3. ilevkivskyi commented on May 21, 2015

    @ilevkivskyi
    Member

    Ok, maybe it is not so easy. I just understood how huge is mypy. As a quick workaround maybe one can say that the annotation assumed for first arg in classmethod is TypeVar('', bound=type)?

  4. gvanrossum commented on May 21, 2015

    @gvanrossum
    Member

    Jukka, can you update the PEP to say something vague about the cls argument to class methods? Without defining something like Type[...] -- we'll open that can of worms later.

  5. JukkaL commented on May 21, 2015

    @JukkaL
    ContributorAuthor

    Ok i'll do it later today. 

    —
    Sent from Mailbox

    On Thu, May 21, 2015 at 11:16 AM, Guido van Rossum
    notifications@github.com wrote:

    Jukka, can you update the PEP to say something vague about the cls argument to class methods? Without defining something like Type[...] -- we'll open that can of worms later.

    Reply to this email directly or view it on GitHub:
    #123 (comment)

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions