Skip to content

Clarify aliases vs variables #3494

Closed

Description

@ilevkivskyi

We have both type aliases and variables with types like Type[...], also there are module aliases and variables of type ModuleType. I think we should document the difference in semantics and provide examples. (Also I think there are few minor things that should be fixed in mypy.) Here how I see things:

  1. Variables with type Type[...] should be created by assignments with an explicit type annotations:
    class A: ...
    tp: Type[A] = A
  2. Aliases are created by assignments without an explicit type:
    class A: ...
    Alias = A
  3. The difference is that aliases are completely known statically and can be used in type context (annotations):
    class A: ...
    class B: ...
    
    if random() > 0.5:
        Alias = A
    else:
        Alias = B  # I think this should be prohibited (there are two TODOs in semanal.py)
    
    tp: Type[object]
    if random() > 0.5:
        tp = A
    else:
        tp = B  # This is OK
    
    def fun1(x: Alias) -> None: ... # This is OK
    def fun2(x: tp) -> None: ... # Error
  4. There is similar distinction between module aliases and variables with type types.ModuleType:
    import math, cmath
    from types import ModuleType
    
    mod: ModuleType = math  # variable
    m = math # Alias
    
    mod.sin # Error. ModuleType has no attribute 'sin'
    m.sin # OK
    and also
    if random() > 0.5:
        m = math
    else:
        m = cmath  # Should be prohibited
    
    mod: ModuleType
    if random() > 0.5:
        mod = math
    else:
        mod = cmath # OK, note explicit annotation above
  5. For modules, we could add better support later (a particular module is a literal type as in Simple dependent types #3062 and binder can bind mod to Union[Literal[math], Literal[cmath]] after the above code).

@JukkaL Do we agree on semantics here? If yes, then I will make some minor changes in mypy and add this to documentation (maybe we also need to clarify this in PEP 484).

Activity

  1. carljm commented on Jun 3, 2017

    @carljm
    Member

    The current version of #3435 allows

    if random() > 0.5:
        m = math
    else:
        m = cmath
    

    and infers m as ModuleType var (not module alias), even without the explicit prior annotation. I did it this way because of the concern that we could break currently-working code otherwise.

    The behavior you propose here would actually be much simpler to implement, as it wouldn't require backtracking. It only requires that we never propagate a module alias to an already-typed variable, which is already implemented.

  2. ilevkivskyi commented on Jun 3, 2017

    @ilevkivskyi
    MemberAuthor

    @carljm

    The behavior you propose here would actually be much simpler to implement

    Probably you are right. Even though this may flag some existing code, this would be actually right. Plus this can be easily fixed by adding explicit annotation - EIBTI.

  3. JukkaL commented on Jun 5, 2017

    @JukkaL
    Collaborator

    @ilevkivskyi I mostly agree, though I'm not sure about using literal types for modules -- they feel different to me. Anyway, better types for modules should probably be discussed separately from the rest of the points. Feel free to open an issue for this -- I couldn't find an existing issue.

    @carljm I agree with Ivan -- requiring an explicit annotation would be the right thing in case of a conditional module alias. This would be consistent with how mypy behaves in other contexts.

  4. ilevkivskyi commented on Jun 5, 2017

    @ilevkivskyi
    MemberAuthor

    @JukkaL

    I'm not sure about using literal types for modules -- they feel different to me. Anyway, better types for modules should probably be discussed separately from the rest of the points. Feel free to open an issue for this -- I couldn't find an existing issue.

    Yes, I will open a separate issue. This was just a vague idea.

  5. ilevkivskyi commented on Jun 6, 2017

    @ilevkivskyi
    MemberAuthor

    OK, opened a separate issue #3500 for point 5 of the list in original post.

    EDIT: Corrected the issue number.

  6. carljm commented on Jun 6, 2017

    @carljm
    Member

    The "better types for modules" issue is #3500.

  7. self-assigned this
    on Jun 7, 2017
  8. added a commit that references this issue on Jul 7, 2017
  9. removed their assignment
    on May 14, 2018
  10. added a commit that references this issue on Jan 30, 2020
    ea3c65c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions