Skip to content

Accessing attributes in modules imported by import_module #5059

Closed

Description

@pawelswiecki

Are you reporting a bug, or opening a feature request?
I believe I found a bug in mypy (as far as I understand what's going on, this is not a typeshed issue).

The code

# my_file.py
from importlib import import_module
import os

settings_module_path = os.getenv('PRODUCTION_SETTINGS_MODULE')
settings = import_module(settings_module_path)

if settings and hasattr(settings, 'LOGGING'):
    log_config = settings.LOGGING

Behaviour

$ mypy 
my_file.py:8: error: Module has no attribute "LOGGING"

Expected behavior
No mypy error. Especially, when the attribute is explicitly asserted to be there (analogically as with narrowing types using isinstance()).

Versions
Python 3.6.5
mypy==0.600

Activity

  1. emmatyping commented on May 16, 2018

    @emmatyping
    Member

    This is a duplicate of #1424, we don't currently support hasattr checks.

  2. pawelswiecki commented on May 16, 2018

    @pawelswiecki
    Author

    Thank you for the reply.

    This issue is not about hasattr checks, though. (It was just a suggestion how it could be dealt with.) It's about modules imported using import_module. Shouldn't mypy approach differently to them? Adding # type: ignore seems the only option I have, which I'd love to avoid.

  3. emmatyping commented on May 16, 2018

    @emmatyping
    Member

    Importing something based on an environment variable is too dynamic, mypy cannot statically know what module you are reffering to.

    importlib.import_module returns type types.ModuleType. We don't know anything else about the attributes of that module, beyond the attributes of that type. Therefore, the error message boils down to #1424.

    Perhaps we should warn when someone calls __import__, importlib.import_module or the like, because it almost always requires a type ignore.

  4. pawelswiecki commented on May 16, 2018

    @pawelswiecki
    Author

    Right, I get it, thanks for the explanation. Sometimes it's unavoidable to use import_module (as in my example), warning won't help in my opinion, since the user is probably aware of the situation. I will wait for resolving #1424. Thanks again.

  5. JukkaL commented on May 16, 2018

    @JukkaL
    Collaborator

    I think that the return type of importlib.import_module should be Any, similar to how the type of getattr is Any.

  6. JelleZijlstra commented on May 16, 2018

    @JelleZijlstra
    Member

    Or perhaps types.ModuleType should grow a def __getattr__(self, attr) -> Any, because modules can have arbitrary attributes.

  7. patrick91 commented on Jul 20, 2020

    @patrick91
    Contributor

    I'm having problem with this too:

    @strawberry.type
    class TypeB:
        @strawberry.field(
            type=lambda: importlib.import_module(".type_a", __package__).TypeA
        )
        def type_a(self, info) -> "TypeA":
            from .type_a import TypeA
    
            return TypeA()

    I get this error:

    Module has no attribute "TypeA"mypy(error)
    

    Which can only be fixed by using # type: ignore

  8. added a commit that references this issue on May 30, 2022
  9. added a commit that references this issue on Sep 2, 2022
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