Skip to content

Support relative imports #60

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ashleyh opened this issue Jan 27, 2013 · 14 comments
Closed

Support relative imports #60

ashleyh opened this issue Jan 27, 2013 · 14 comments
Labels

Comments

@ashleyh
Copy link
Contributor

ashleyh commented Jan 27, 2013

The following is currently a parse error:

from .a import b
@ghost ghost assigned JukkaL Dec 24, 2013
@JukkaL
Copy link
Collaborator

JukkaL commented Jul 15, 2014

Also from . import x does not work.

@JukkaL JukkaL removed their assignment Jul 25, 2014
@mason-bially
Copy link
Contributor

I ran into this error too, there appears a need to add the ability to deal with a dot here in the parse unfortunately, I'm not sure what that would mean for the rest of the import code which will need to support it.

@mason-bially
Copy link
Contributor

Would need to expand this node (and the one below) to deal with it, likely a relative file-name (or just a bool if it's available elsewhere in the tree).

mason-bially added a commit to mason-bially/mypy that referenced this issue Aug 14, 2014
* Changing the `all_imported_modules_in_file(self, file)` projection in build which gathers imports from file ASTs root nodes.
* Adding support for the relative import syntax in noderepr.py and output.py.
* Adding a relative counter int to the AST nodes and fixing up treetransform.py.
* Changing the `parse_import_from(self)` function to parse relative imports.
@JukkaL
Copy link
Collaborator

JukkaL commented Dec 3, 2014

I guess anybody can finish the implementation, as it seems that @mason-bially is no longer working on this. If nobody else picks this up, I might work on this in the next couple of weeks, since this is a pretty major missing feature.

mason-bially added a commit to mason-bially/mypy that referenced this issue Dec 5, 2014
* Changing the `all_imported_modules_in_file(self, file)` projection in build which gathers imports from file ASTs root nodes.
* Adding support for the relative import syntax in noderepr.py and output.py.
* Adding a relative counter int to the AST nodes and fixing up treetransform.py.
* Changing the `parse_import_from(self)` function to parse relative imports.
@mason-bially
Copy link
Contributor

I am working on this now. I burned out during the period I was working on this due to other projects. I've had almost passing code in my repo for ages. I'm cleaning this up ASAP, apologies.

mason-bially added a commit to mason-bially/mypy that referenced this issue Dec 5, 2014
mason-bially added a commit to mason-bially/mypy that referenced this issue Dec 5, 2014
@JukkaL
Copy link
Collaborator

JukkaL commented Dec 7, 2014

Relative imports work now!

@JukkaL JukkaL closed this as completed Dec 7, 2014
@reinhrst
Copy link

I'm running today's version from git (both globally and in the virtualenv) from mypy (just started, but so far love the project!), still get error with relative imports.

My __init__.py reads:

from . import mongo
from . import devicetracker
from . import website
from . import constants
from . import fileimporter

LOGFORMAT = '%(levelname)s %(asctime)s %(message)s'

__all__ = [mongo, devicetracker, website, constants, fileimporter]

result:

(.virtualenv)#reinoud@g ~/work/config 12:25:38 > ls -1
__init__.py
constants.py
devicetracker.py
fileimporter.py
mongo.py
website.py
(.virtualenv)#reinoud@g ~/work/config 12:25:44 > mypy --verbose __init__.py 
__init__.py, line 1: No module named '__main__'
__init__.py, line 1: Module has no attribute 'mongo'
__init__.py, line 2: No module named '__main__'
__init__.py, line 2: Module has no attribute 'devicetracker'
__init__.py, line 3: No module named '__main__'
__init__.py, line 3: Module has no attribute 'website'
__init__.py, line 4: No module named '__main__'
__init__.py, line 4: Module has no attribute 'constants'
__init__.py, line 5: No module named '__main__'
__init__.py, line 5: Module has no attribute 'fileimporter'
__init__.py, line 9: Name 'mongo' is not defined
__init__.py, line 9: Name 'devicetracker' is not defined
__init__.py, line 9: Name 'website' is not defined
__init__.py, line 9: Name 'constants' is not defined
__init__.py, line 9: Name 'fileimporter' is not defined

Anything obvious I'm missing?

@mason-bially
Copy link
Contributor

This seems to be an error related to relative imports in the main package. It might be conflicting with the fact that the main package is also an __init__ file.

For a temporary fix, try using a separate main file which imports the library?

@mason-bially
Copy link
Contributor

So I originally suspected this. The use case you are trying is not supported by python.

Consider:

$ python __init__.py
Traceback (most recent call last):
  File "__init__.py", line 1, in <module>
    from . import foo
SystemError: Parent module '' not loaded, cannot perform relative import

The temporary fix I proposed should work correctly. I'm assuming you already have a main script which imports and uses the module with the __init__.py file anyway, run mypy on that.

Although it might be worth fixing relative imports to support this behavior simply for usability, but that would be an additional feature (in my opinion).

@reinhrst
Copy link

Right, this makes sense. I guess that's why there is an -m option on the executable to check modules.

I am hoping to convince my editor to check each file each time I save it, guess I should accept that not working in this case. Would indeed be nice to have at some point, but I see how this is not top priority now.

@mason-bially
Copy link
Contributor

Unfortunately, I believe the correct way to do that at the moment is to check the whole project from the beginning every time (i.e. from the root main.py file). Theoretically you would need some sort of resume-able type checking structure to accomplish an IDE style type checker without doing that.

Since I'm not actually part of the team maintaining this project I don't know what the plans are for that.

@JukkaL
Copy link
Collaborator

JukkaL commented Feb 20, 2015

Mypy should probably support type checking any file within a package, instead of having to start from a top-level module or having to use -m modname. For example, assume I have files like this:

work/main.py
work/thing/__init__.py
work/thing/sub.py

Now all of these should work:

$ mypy main.py
$ mypy thing/__init__.py
$ mypy thing/sub.py
$ mypy -m main
$ mypy -m thing
$ mypy -m thing.sub

I need to think about this a bit more, though.

@o11c
Copy link
Contributor

o11c commented Jul 2, 2015

I just hit this while fixing the test script to actually test everything, not just a subset.

It is unrelated to which module is the "main" module. Rather, it seems that relative imports are supported in __init__.py at all, because it thinks that e.g. requests doesn't have a parent module at all.

@o11c
Copy link
Contributor

o11c commented Jul 2, 2015

Actually, it looks related to the .pyi changes, I've gotten past that error now.

Now to fix the actual bugs in the stubs that weren't being tested ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants