Zipimport with packages - python

I'm trying to package the pychess package into a zip file and import it with zipimport, but running into some issues.
I've packaged it into a zipfile with the following script, which works:
#!/usr/bin/env python
import zipfile
zf = zipfile.PyZipFile('../pychess.zip.mod', mode='w')
try:
zf.writepy('.')
finally:
zf.close()
for name in zf.namelist():
print name
However, I'm unable to do complicated imports in my code:
z = zipimport.zipimporter('./pychess.zip.mod')
#z.load_module('pychess') # zipimport.ZipImportError: can't find module 'pychess'
#z.load_module('Utils.lutils') # zipimport.ZipImportError: can't find module 'Utils.lutils'
Utils = z.load_module('Utils') # seems to work, but...
from Utils import lutils
#from Utils.lutils import LBoard # ImportError: No module named pychess.Utils.const
How can I import, e.g. pychess.Utils.lutils.LBoard from the zip file?
Here is the full list of modules I need to import:
import pychess
from pychess.Utils.lutils import LBoard
from pychess.Utils.const import *
from pychess.Utils.lutils import lmovegen
from pychess.Utils.lutils import lmove
Thanks!

Assuming you have an unpacked pychess, resulting in a pychess-0.10.1 directory in your current directory and that pychess-0.10.1/lib/pychess exists ( I got that directory from untarring pychess-0.10.1.tar.gz).
First run:
#!/usr/bin/env python
import os
import zipfile
os.chdir('pychess-0.10.1/lib')
zf = zipfile.PyZipFile('../../pychess.zip', mode='w')
try:
zf.writepy('pychess')
finally:
zf.close()
for name in zf.namelist():
print name
after that, this works:
#!/usr/bin/env python
import sys
sys.path.insert(0, 'pychess.zip')
from pychess.Utils.lutils import LBoard

Related

How do I import helper files (.py) from another python script?

I am brand new to working with python so this question might be basic. I am attempting to import five helper files into a primary script, the directory setup is as follows and both the script I'm calling from and the helper scripts are located within src here in this path-
/Users/myusername/Desktop/abd-datatable/src
I am currently importing as-
import helper1 as fdh
import helper2 as hdh
..
import helper5 as constants
The error I see is
File "/Users/myusername/Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/22.77756/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 21, in do_import
module = self._system_import(name, *args, **kwargs)
ModuleNotFoundError: No module named 'src'
I have also attempted the following for which the import was still unsuccessful:
import src.helper1 as fdh
..
import src.helper5 as constants
and
from src import src.helper1 as fdh
...
from src import helper5 as constants
and tried adding the following to the head of the script-
import sys
import os
module_path = os.path.abspath(os.getcwd())
if module_path not in sys.path:
sys.path.append(module_path)
Would be very grateful for any pointers on how to debug this!
Seems likely that it's a path issue.
In your case, if you want to import from src, you would need to add Users/myusername/Desktop/abd-datatable to the path.
os.getcwd() is getting the path you invoke the script from, so it would only work if you are invoking the script from Users/myusername/Desktop/abd-datatable.

Executing external python script function

I have two scripts in the same folder:
5057_Basic_Flow_Acquire.xyzpy
5006_Basic_Flow_Execute.xyzpy
I need to call function run() from 5057_Basic_Flow_Acquire file in the 5006_Basic_Flow_Execute file.
I tried two approaches:
1.
import time
import os
import sys
import types
dir_path = os.path.dirname(os.path.realpath(__file__))
#os.chdir(str(dir_path))
sys.path.append(str(dir_path))
sensor = __import__('5057_Basic_Flow_Acquire')
import time
import os
import sys
import types
import importlib
import importlib.util
dir_path = os.path.dirname(os.path.realpath(__file__))
spec = importlib.util.spec_from_file_location('run', dir_path+'\\5057_Basic_Flow_Acquire')
module = importlib.util.module_from_spec(spec)
Pycharm is reporting this type of errors:
case:
ModuleNotFoundError: No module named '5057_Basic_Flow_Acquire'
case
AttributeError: 'NoneType' object has no attribute 'loader'
So in both cases module was not found.
Does someone have any suggestion?
You should rename your files to something like :
5057_Basic_Flow_Acquire_xyz.py
5006_Basic_Flow_Execute_xyz.py
so that they are recognized as modules and can be imported.
Then, in your 5057_Basic_Flow_Acquire_xyz module, you can import the run function with the following line :
from 5006_Basic_Flow_Execute_xyz import run
Both files are in the same directory, so you should be able to import without changing your PATH environment variable as the current directory is automatically added at the top of the list.

importing the right module but getting an error in python

import sys
from subprocess import run, PIPE
import shlex
from src.detector_main import detect_main
def main():
# print command line arguments
for arg in sys.argv[1:]:
print(arg)
if __name__ == "__main__":
# main()
print(sys.argv)
This is my main module. If you see the from src.detector_main import detect_main, it is supposed to import detect_main from src/detector_main.py.
In my detector_main.py, I have a bunch of imports,
import ast
import os
import fpdf
import sys
from Detector.class_coupling_detector import detect_class_cohesion
from Detector.cyclomatic_complexity_detector import detect_cyclomatic_complexity
from Detector.long_lambda_detector import detect_long_lambda
from Detector.long_list_comp_detector import detect_long_list_comp
from Detector.pylint_output_detector import detect_pylint_output
from Detector.shotgun_surgery_detector import detect_shotgun_surgery
from Detector.useless_exception_detector import detect_useless_exception
# from tools.viz_generator import add_viz
def detect_main(directory):
# Get stats for files in directory
stats_dict = get_stats(directory)
....
Running my main module gives me this error:
File "pyscent.py", line 5, in <module>
from src.detector_main import detect_main
File "C:\Users\user\Desktop\proj\src\detector_main.py", line 5, in <module>
from Detector.class_coupling_detector import detect_class_cohesion
ModuleNotFoundError: No module named 'Detector'
I don't get this because I am following the exact path.
I don't get this because I am following the right path.
In your example you import the Detector.class_coupling_detector module in file that is in the same directory as Detector but your cwd is not the src directory.
Due to this you should either use absolute import from src.Detector... or relative import from .Detector...
Here is some information about difference between this two ways to import

Python: Change the script's working directory to a different directory to read constants

My script is trying to read my utils from a different folder. I keep getting Import Error. PFB my script :
import sys
import os
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname+"/../../dags/golden/")
dname = os.path.dirname(abspath)
sys.path.append(dname)
import utils
semantics_config = utils.get_config()
And my folder structure is as follows :
/home/scripts/golden/script.py
/home/dags/golden/utils.py
Output is :
Traceback (most recent call last):
File "check.py", line 22, in
import utils
ImportError: No module named utils
Any pointers will be greatly helpful!
Try this
import sys
import os
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname+"/../../dags/golden/")
dname = os.getcwd()
sys.path.append(dname)
import utils
semantics_config = utils.get_config()
You are again assigning "dname" as old path.
So use os.getcwd()
or
import sys
import os
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
sys.path.append(dname+"/../../dags/golden/")
import utils
semantics_config = utils.get_config()
You made a mistake in your script.
os.chdir(dname+"/../../dags/golden/"), only changes your current working directory, but not change the value of variable "abspath"
So the value of "dname" keep the same before and after your "os.chdir"
just do sys.path.append(dname+"/../../dags/golden/"), you will get what you want.
BTW, python is very easy to locating the problem and learn. Maybe, You just need to add a print before you using a variable. And, don't forge to remove those print before you release your scripts.

How to change built_in module in python

I want to change os.path in os.py, but it failed. path is different in different platform.
os.py
import ntpath as path
sys.modules['os.path'] = path
from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep, devnull)
It turns out that
from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
devnull)
ImportError: No module named path
Your approach should work. Rename the subdirectory os in your current directory to my_os. Python finds your os directory first and tries to import from there.
Adding this line:
__future__ import absolute_import
to the beginning of the os.py avoids this problem by using absolute imports.
did you try with "__import__" function ?
import mtpath as path
os_path = __import__(path, globals(), locals(), ['curdir', 'pardir', 'sep', 'pathsep', 'defpath', 'extsep', 'altsep', 'devnull']
Then, you can use 'curdir' as :
os_path.curdir
Well, you can also asign it to 'curdir' name as in the documentation :
curdir = os_path.curdir
pardir = os_path.curdir
…

Categories