I have a file package.py that i am trying to package into package.pyd. I have the following statement in package.py
CURR = os.path.dirname(os.path.realpath(__file__))
which works fine when I run package.py but when I import package.pyd into another file wrapper.py I get the following error message
Traceback (most recent call last):
File "C:\Projects\Wrapper.py", line 1, in <module>
import package
File "package.py", line 40, in init package (package.c:4411)
NameError: name '__file__' is not defined
How can I get the location of the .pyd file. Also is there a way to check if it is being run as a .pyd or .py.
Thank you!
It seems that __file__ variable not available in module init.
But you can get __file__ after module was loaded:
def get_file():
return __file__
You can check the __file__ variable to know what file was loaded.
Also keep in mind python's search order: pyd (so), py, pyw(for windows), pyc.
More information about it is in this this question
Found two working methods.
Involving inspect module:
import inspect
import sys
import os
if hasattr(sys.modules[__name__], '__file__'):
_file_name = __file__
else:
_file_name = inspect.getfile(inspect.currentframe())
CURR = os.path.dirname(os.path.realpath(_file_name))
import some file from the same level and using its __file__ attribute:
import os
from . import __file__ as _initpy_file
CURR = os.path.dirname(os.path.realpath(_initpy_file))
Actually, it doesn't have to be __init__.py module, you can add and import any [empty] file to make it work.
__file__ now works in recent more versions of Cython (0.27 ish) when on run on a version of Python that supports multi-phase module initialization (Python >=3.5). See https://github.com/cython/cython/issues/1715 for the point at which it was added.
Related
I'm using libusb1 and noticed an import error when there is a platform module in my main module:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/duranda/.local/lib/python3.6/site-packages/usb1/__init__.py", line 61, in <module>
from . import libusb1
File "/home/duranda/.local/lib/python3.6/site-packages/usb1/libusb1.py", line 199, in <module>
libusb = _loadLibrary()
File "/home/duranda/.local/lib/python3.6/site-packages/usb1/libusb1.py", line 161, in _loadLibrary
system = platform.system()
AttributeError: module 'platform' has no attribute 'system'
This can be easily reproduced by launching a Python interpreter from a directory containing a platform.py or platform/__init__.py and then importing usb1 using import usb1.
How is it possible that a local module shadows another module (in this case the platform module from the standard lib) from a third party module? To the best of my knowledge, libusb1 imports platform directly and doesn't do anything crazy with globals.
add as first lines in your module:
import sys
print("\n".join(sys.path))
import platform
print("platform file is", platform.__file__)
This will probably show, that the python path tries to first import your local modules and only then the system modules.
In other words. don't use local modules with names, that conflict with system or thrd party module names.
More explanations:
if multiple modules import a module with the same name, then python imports the module only once.
Only the first import imports the module
The second import will just point to the already imported module, which it will find in sys.modules
Thus a module name can be considered a unique pointer to python code.
(Try printing out sys.modules this is a dict and will show you which modules are imported so far.)
So it doesn't matter whether an import statement is located in your file or in a third party file.
import platform will only point to one module. The one that is being selected / found is the one, that occurs first in the python path.
So self written modules should not have conflicting names with existing modules.
Since the module platform in your working directory, and Python interpreter would insert current working directory into sys.path at the beginning. You could print sys.path out to check.
Thus, Python interpreter use the first one found when looking for module based on sys.path, which is your own module instead of the one in standard library.
A workaround (trick) is to move the current working directory to the end position; Note to put it at the top of file, and then import the module
import sys
# move the current working directory to the end position
sys.path = sys.path[1:] + sys.path[:1]
More Comments:
To reply #gelonida: suppose that we really want to use both modules,
we could import one first and give it an alias, and then modify
sys.path to import another one
import sys
# <------- newly added
_platform = patch_module('platform', '_platform') # our own module
# move the current working directory to the end position
sys.path = sys.path[1:] + sys.path[:1]
And the above code use a patch_module() method
def patch_module(source_module_name, target_module_name):
""" All imported modules are cached in *sys.modules*
"""
__import__(source_module_name)
m = sys.modules.pop(source_module_name)
sys.modules[target_module_name] = m
target_module = __import__(target_module_name)
return target_module
I am pretty new to python, so I might be missing (and probably am) some critical part of the import system, but I can't for the life of me figure it out at this point. I have a directory structure as follows:
/
/always_run.py
/lib/__init__.py
/lib/data.py
/lib/config.py
File Internals (imports):
/always_run.py
from lib import data
/lib/data.py
from lib import config
yields
Traceback (most recent call last):
File ".\data.py", line 9, in <module>
from lib import config as configs
ModuleNotFoundError: No module named 'lib'
Note: I've also tried:
from . import config
yields:
Traceback (most recent call last):
File ".\data.py", line 9, in <module>
from . import config as configs
ImportError: cannot import name 'config'
Within data.py I also have:
if __name__ == "__main__":
print("loading myself")
Just to test, but it makes no difference, it never gets to that point
Normally I run my program as python always_run.py and the world is my oyster, but if I try to run data.py directly I always get import failures. (after first cding into the lib directory and running python .\data.py
Is what I am trying to do not possible without adding the local directory to the sys.path, like this(test, works):
import sys
local_path = os.path.dirname(os.path.realpath(__file__))
if local_path not in sys.path:
sys.path.append(local_path)
import config
In the process of writing this, I tested one further thing, cding to the parent directory and running python -m lib.data which works flawlessly. Now my question is one of curiosity, because I still can not find the answer otherwise. Is it not possible to run a local file that is part of a module from the local directory? Or must it be done from another directory?
I have the following code with few modules:
import Persistence.Image as img
import sys
def main():
print(sys.path)
original_image = img.Image.open_image()
if __name__ == "__main__":
main()
(I've created my own Image module)
And so I'm getting the following error claiming that the Persistence module does not exist:
Traceback (most recent call last):
File "/home/ulises/PycharmProjects/IntelligentPuzzle/Puzzle.py", line 1, in <module>
import Persistence.Image as img
ImportError: No module named Persistence.Image
I've been searching for this problem here but can't find anything that worked to solve this as the directory tree seems to be correct as you can see on this image:
I'm using ubuntu if it's any use.
Thanks and regards!
Persistence package does not exist in that source tree. There is a "Persistence" directory there, but it is not a package, because it does not contain a __init__.py file.
From the Python documentation:
The __init__.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path. In the simplest case, __init__.py can just be an empty file, but it can also execute initialization code for the package or set the __all__ variable, described later.
I don't believe that you are importing with proper syntax. You need to use from Persistance import Image as img. For example:
>>> import cmath.sqrt as c_sqrt
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
import cmath.sqrt
ImportError: No module named 'cmath.sqrt'; 'cmath' is not a package
>>> from cmath import sqrt as c_sqrt
>>> c_sqrt(-1)
1j
I am trying to import a module from a different directory dynamically. I am following an answer from this question. I have a module named bar in a directory named foo. The main script will be running in the parent directory to foo.
Here is the code i have thus far in my test script (which is running in the parent directory to foo)
#test.py
import imp
mod = imp.load_source("bar","./foo")
and code for bar.py
#bar.py
class bar:
def __init__(self):
print "HELLO WORLD"
But when i run test.py I get this error:
Traceback (most recent call last):
File "C:\Documents and Settings\user\Desktop\RBR\test.py", line 3, in <module>
mod = imp.load_source("bar","./foo")
IOError: [Errno 13] Permission denied
imp.load_source requires the pathname + file name of the module to import, you should change your source for the one below:
mod = imp.load_source("bar","./foo/bar.py")
Appears to be a simple pathing problem - check __file__ or cwd... Maybe try an absolute file path first? - This imp example may help.
This may be my own misunderstanding of how Python imports and search paths work, or it may be a problem in the packaging of the caldav package.
I have set up a virtualenv environment named myproject
In the top level of myproject, I have a script test.py which contains two imports:
import lxml
import caldav
In this directory, I type:
python test.py
and it works fine without any problem
Now I move the script to the subdirectory test and run the command:
python test/test.py
The import lxml seems to still work. The import caldav fails with the following exception:
Traceback (most recent call last):
File "test/test.py", line 34, in <module>
main()
File "test/test.py", line 29, in main
exec ( "import " + modulename )
File "<string>", line 1, in <module>
File "/home/ec2-user/caldav2sql/myproject/test/caldav/__init__.py", line 3, in <module>
from davclient import DAVClient
File "/home/ec2-user/caldav2sql/myproject/test/caldav/davclient.py", line 8, in <module>
from caldav.lib import error
ImportError: No module named lib
Am I doing something wrong here? Should I be setting up some kind of path?
Most likely, caldav was in the same directory as test.py, so when you import it it worked fine. Now that you moved test.py to a subdirectory, your imports can't find it. You can either move caldav or set your PYTHONPATH.
You could also modify your sys.path
Information from Python's module tutorial: http://docs.python.org/tutorial/modules.html
The variable sys.path is a list of strings that determines the interpreter’s search path for modules. It is initialized to a default path taken from the environment variable PYTHONPATH, or from a built-in default if PYTHONPATH is not set. You can modify it using standard list operations:
>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')