I really hope this is a simple case of me miss-understanding the complex Python2 import mechanisms. I have the following setup:
$> ls -ltr pypackage1
total 3
-rw-r--r-- 1 pelson pelson 0 Aug 17 19:20 io.py
-rw-r--r-- 1 pelson pelson 0 Aug 17 19:20 __init__.py
-rw-r--r-- 1 pelson pelson 57 Aug 17 19:22 code.py
$> cat pypackage1/code.py
from __future__ import absolute_import
import zipfile
i.e. I have nothing but a stub package with an empty __init__.py and io.py, and a 2 lines code.py file.
I can import pypackage1:
$> python -c "import pypackage1.code"
But I cannot run the code.py file:
$> python pypackage1/code.py
Traceback (most recent call last):
File "pypackage1/code.py", line 3, in <module>
import zipfile
File "python2.7/zipfile.py", line 462, in <module>
class ZipExtFile(io.BufferedIOBase):
AttributeError: 'module' object has no attribute 'BufferedIOBase'
Clearly the problem has to do with the zipfile module picking up my relative io module over the builtin io module, but I thought my from __future__ import absolute_import would have fixed that.
Thanks in advance for any help,
That’s the correct behaviour. If you want to fix the error simply do not run from inside the package.
When you run a script which is inside the package, python wont interpret that directory as a package, thus adding the working directory to the
PYTHONPATH.That’s why the
iomodule imported by thezipfilemodule is youriomodule and not the one inside the standard library.I’d recommend to create a simple launcher script outside your package (or in a
bin/scriptsfolder), and launch that. This script can simply contain something like:An alternative to this is to tell the python interpreter that the file that you want to execute is part of a module. You can do this using the
-mcommand line option. In your case you would have to do:Note that the argument of
-mshould be the module name, not the file name.