Python script import fails if script is moved to subdirectory - python

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')

Related

How to import my python file in another file in visual studio code

I am using python/selenium in visual studio code. I am trying to import my another python class driverScript which resides in executionEngine module and in the file DriverScript. I have imported as below:
import driverScript from executionEngine.DriverScript
It is producing error:
Traceback (most recent call last):
File "c:/Selenium/Selenium-Python Framework/RK_Practice/Tests/mainTest.py", line 5, in <module>
from executionEngine.DriverScript import driverScript
ModuleNotFoundError: No module named 'executionEngine'
How can I import correctly? Your help is very much appreciated.
If the script you are wishing to import is not in the current directory, you may want to take this approach:
import sys
sys.path.insert(1, '/path/to/script/folder')
import driverScript from executionEngine.DriverScript
If your python file is on the same level in dir, then you can import just by calling:
import filename
If your python file is inside another folder, then you need to create a blank __init__.py file that will help python to understand it's a package. Then you can import that as follows:
from folderName import filename
Depends on where executionEngine is supposed to come from. If it's from a package installable via a package manager such as pip or Anaconda, looks like it's not properly installed. If you installed it yourself, you probably need to add the directory containing executionEngine to your PYTHONPATH, so the Python interpreter can find it. This can be done in the VSCode environment files. See the PYTHONPATH section in https://code.visualstudio.com/docs/python/environments

I can't import a module in Python/Windows

I'm having problem when I trying to import a custom module I have which is very simple but I'm always getting:
Traceback (most recent call last):
File "demo_module1.py", line 12, in <module>
import mymodule
ModuleNotFoundError: No module named 'mymodule'
I have tried to set environment variables:
set PYTHONHOME=C:\Software\python-3.7.4
set PYTHONPATH=%PYTHONPATH%;C:\pyproys\test
Everything is located here: 'C:\pyproys\test'
The only way it works is if I add it directly in the code "But I don't want to do it in every single script I have so don't want to maintain it in that way".
import sys
sys.path.append('C:\pyproys\\test')
print(sys.path)
Here is the script I'm trying to run:
demo_module1.py
import mymodule
mymodule.greeting("Jonathan")
'mymodule.py' is in the same folder as 'demo_module1.py'
I'm expecting the code to run fine by just executing:
python demo_module1.py
Can someone please point me out what I'm doing wrong?
Try to find the directory /lib/site-packages in your Python folder in C drive and paste your module in that folder and then restart the system. Hope it'll solve your issue.

Run module (both as a module and) locally as script with local import

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?

How to get path of the pyd file aka equivalent of __file__

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.

How to import a function from a module in the same folder? [duplicate]

This question already has answers here:
import function from a file in the same folder
(4 answers)
Closed last month.
I am trying to separate my script into several files with functions, so I moved some functions into separate files and want to import them into one main file. The structure is:
core/
main.py
posts_run.py
posts_run.py has two functions, get_all_posts and retrieve_posts, so I try import get_all_posts with:
from posts_run import get_all_posts
Python 3.5 gives the error:
ImportError: cannot import name 'get_all_posts'
Main.py contains following rows of code:
import vk
from configs import client_id, login, password
session = vk.AuthSession(scope='wall,friends,photos,status,groups,offline,messages', app_id=client_id, user_login=login,
user_password=password)
api = vk.API(session)
Then i need to import api to functions, so I have ability to get API calls to vk.
Full stack trace
Traceback (most recent call last):
File "E:/gited/vkscrap/core/main.py", line 26, in <module>
from posts_run import get_all_posts
File "E:\gited\vkscrap\core\posts_run.py", line 7, in <module>
from main import api, absolute_url, fullname
File "E:\gited\vkscrap\core\main.py", line 26, in <module>
from posts_run import get_all_posts
ImportError: cannot import name 'get_all_posts'
api - is a api = vk.API(session) in main.py.
absolute_url and fullname are also stored in main.py.
I am using PyCharm 2016.1 on Windows 7, Python 3.5 x64 in virtualenv.
How can I import this function?
You need to add __init__.py in your core folder. You getting this error because python does not recognise your folder as python package
After that do
from .posts_run import get_all_posts
# ^ here do relative import
# or
from core.posts_run import get_all_posts
# because your package named 'core' and importing looks in root folder
MyFile.py:
def myfunc():
return 12
start python interpreter:
>>> from MyFile import myFunc
>>> myFunc()
12
Alternatively:
>>> import MyFile
>>> MyFile.myFunc()
12
Does this not work on your machine?
Python doesn't find the module to import because it is executed from another directory.
Open a terminal and cd into the script's folder, then execute python from there.
Run this code in your script to print from where python is being executed from:
import os
print(os.getcwd())
EDIT:
This is a demonstration of what I mean
Put the code above in a test.py file located at C:\folder\test.py
open a terminal and type
python3 C:\folder\test.py
This will output the base directory of python executable
now type
cd C:\folder
python3 test.py
This will output C:\folder\. So if you have other modules in folder importing them should not be a problem
I usually write a bash/batch script to cd into the directory and start my programs. This allows to have zero-impact on host machines
A cheat solution can be found from this question (question is Why use sys.path.append(path) instead of sys.path.insert(1, path)? ). Essentially you do the following
import sys
sys.path.insert(1, directory_path_your_code_is_in)
import file_name_without_dot_py_at_end
This will get round that as you are running it in PyCharm 2016.1, it might be in a different current directory to what you are expecting...

Categories

Resources