Tried to use relative imports, and broke my import paths?

拥有回忆 提交于 2019-12-12 06:24:46

问题


I'm running a Flask server locally on my Mac.

My project:

project/my_lib/my_class.py  
project/testing/flask_server.py  
project/testing/something/test_class.py  

At one point, I tried to get fancy with some relative imports to test a class in a different directory:

In project/testing/something/test_class.py:

from ..my_lib.my_class import MyClass

That gave me an error:

ValueError: Attempted relative import beyond toplevel package

So I backed out of that, but now I can't get my Flask server to run, even though I eliminated the new import code.

$ python testing/flask_server.py

Spits out this:

Traceback (most recent call last):
  File "testing/flask_server.py", line 2, in <module>
    from flask import Flask
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask/__init__.py", line 17, in <module>
    from werkzeug.exceptions import abort
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/werkzeug/__init__.py", line 154, in <module>
    __import__('werkzeug.exceptions')
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/werkzeug/exceptions.py", line 71, in <module>
    from werkzeug.wrappers import Response
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/werkzeug/wrappers.py", line 26, in <module>
    from werkzeug.http import HTTP_STATUS_CODES, \
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/werkzeug/http.py", line 28, in <module>
    from urllib.request import parse_http_list as _parse_list_header
ImportError: No module named request

Huh?


UPDATE:

The flask import error only happens in the directory the bad code was originally called from. That is, if I do

from flask import Flask

from anywhere in the project/testing dir, I get the import error, but if I do it in project/ or anywhere else on my system, it's fine..?


SOLUTION (PARTLY):

I don't have an explanation as to why this happened, but I did the following to fix it:

  1. Created a new testing/ directory and copied the files from the old one into it. The old testing/ directory had to be deleted- it was basically corrupted.
  2. Did my cross-directory imports using absolute instead of relative paths.

(By the way, I tried to retrace my steps to reproduce the relative import error but was unable to, so I'm not sure of either the cause or solution to this whole thing.)


回答1:


You probably have your own urllib2 python file in your system path, perhaps in the local directory. Don't do that, as it breaks werkzeug (and other python code).

To be compatible with both python 2 and 3, werkzeug uses constructs like:

try:
    from urllib2 import parse_http_list as _parse_list_header
except ImportError: # pragma: no cover
    from urllib.request import parse_http_list as _parse_list_header

The from urllib2 import parse_http_list as _parse_list_header line could throw a ImportError exception if you have a local urllib2.py module or urllib2/__init__.py package that masks the standard library file.

Because the first import throws an ImportError, the second line is executed, which also fails because the urllib.request package is only available on Python 3.

From your project, run the following code to diagnose where you have that module:

import urllib2
print urllib2.__file__

If that still works, then run:

from urllib2 import parse_http_list as _parse_list_header

as it could be that urllib2 indirectly imports something that you masked. urllib2 uses from urlib import ... statements for example, so a local urllib module would also break the import.

It is important that you do this from your flask project, just before the from flask import Flask line.



来源:https://stackoverflow.com/questions/17391289/tried-to-use-relative-imports-and-broke-my-import-paths

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!