PyInstaller hiding PIL module in another folder - python

I followed this post to hide the vast majority of the files in my PyInstaller compilation, going from 108 files/folders to just 6. But one of those 6 is the PIL folder, since you have to do a from-import on it to access Image, and I would love to hide that folder as well.
I've experimented with adding it to sys.path in my hook, changing my imports to from <foldernamehere>.PIL import Image, and setting os.chdir immediately before and after the import but nothing has worked. The error is always the same:
ImportError: cannot import name '_imaging' from 'PIL' (<pathtobasefolder>\PIL\__init__.pyc)
One important thing to note is that I do not import PIL immediately. It's only imported after launch when the user performs specific actions, since it serves no purpose otherwise. I'm not sure how much that affects things.
Is this possible? Maybe importlib can be used, or maybe editing PyInstaller's native hooks would work?

Use the following command : pip install -U Pillow

Related

How does reload handle library files as `so`

I've installed a user module with the command pip --ignore-installed --user requests[security] and realized that the python interpreter, which is embedded in a tool, is ignoring that and is loading first the System wide installed Module i:
/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/OpenSSL
So went ahead and inserted manually my user path and tried to reload every module in OpenSSL like this:
import sys
sys.path.insert(0, /Users/MYUSERNAME/Library/Python/2.7/lib/python/site-packages/)
reload(OpenSSL.SSL)
reload(OpenSSL.SSL)
reload(OpenSSL._util)
reload(OpenSSL.crypto)
reload(OpenSSL.rand)
reload(OpenSSL.version)
However, I've realized that that OpenSSL comes with so files. Is reload reloading so files as well?
Let me know if more info is needed.
https://docs.python.org/3/library/imp.html?highlight=reload#imp.reload
There are a number of other caveats:
It is legal though generally not very useful to reload built-in or dynamically loaded modules, except for sys, __main__ and builtins. In many cases, however, extension modules are not designed to be initialized more than once, and may fail in arbitrary ways when reloaded.
(Emphasize mine — phd.)

pycharm 2017.1 inconsistency on directory path for loading modules

I developed a python3 package in Pycharm but am running into some confusing behavior when I try to import modules in my test cases. The problem seems to be with the directory path to the internal package modules. It is a bit difficult to explain the issue, but here is the gist.
So the python package name is pyugend. Now when I try and import a module--inside the package--named Models into a test case, pycharm forces me to reference the path as pyugend.pyugend.Models. So I need to reference pyugend twice.
However, when I build, install, and import this package into a jupyter notebook or some script, then I run into errors about the pyugend package not finding the internal modules. The only way to fix these errors is to change the paths inside of the module to references like pyugend.Models.
So basically, to run tests inside of pycharm I have make sure all of the internal package imports use a directory path like from pyugend.pyugend.Models import ... But when I want to use the package outside of pycharm then I actually have to go into the package, convert all of the import pyugend.pyugend... references to just single import pyugend.Models ... references.
I have included a picture of the directory structure as well as a picture of the __init__.py.
You can add the linesys.path.append(os.path.dirname(os.path.abspath(__file__))) before the imports in __init.py__ and then change the imports to from pyugend.Models import Base_model and so on, to enable consistent behavior wherever you use the package.

Python PIL import Mac compatiblity

I wonder now for a long time, can I redirect python imports.
So on my Machine I did:
pip install pil
and then I can do:
from PIL import Image
That works great but the problem is many programs just want Image, they want:
import Image
Now my question is can I "redirect" the above statement so that I can use import Image?
If that does not work, how could I make it work?
Basically you can use any of the methods mentioned here.
On my linux installation, PIL already uses one of those - there's a directory called PILcompat which has files like Image.py, and a file called PILcompat.pth which is used to tell python to add this directory to its module search path.
This way when
import Image
is executed, python finds PILcompat/Image.py which executes its contents -
from PIL.Image import *
I'm guessing either the .pth file or the directory are missing on your machine.

How to make an external module local

My code depends on functions from a module external_module which is in my pythonpath path and which I include as
# global import
import external_module.sub_mod_one as smo
Now I want to share my code but I don't want to force my collaborators to checkout my other git repos and add them to their environment.
So, I thought I can copy the files to the local directory and rewrite the import as
# local import
import sub_mod_one as smo
However, since development goes on, I don't want to do this manually.
Question Is there a python module or vim plugin or something else that does this for me? Namely, copying the the included modules to the current folder and rewriting the import statements?
The "right" solution is to
properly package your "external_module" so it can be installed with pip,
add to your project(s) a pip requirements file referencing your package
then have everybody using virtualenvs
This way the package will be cleanly installed (and at the right version), you don't have to mess with your exports, and you dont have out of sync copies of your package everywhere.
You could use conditional imports:
try:
import external_module.sub_mod_one as smo
except ImportError:
import sub_mod_one as smo

Including xlrd/xlwt/xlutils with modules outside of python installation

I'm self-taught in the Python world, so some of the structural conventions are still a little hazy to me. However, I've been getting very close to what I want to accomplish, but just ran into a larger problem.
Basically, I have a directory structure like this, which will sit outside of the normal python installation (this is to be distributed to people who should not have to know what a python installation is, but will have the one that comes standard with ArcGIS):
top_directory/
ArcToolbox.tbx
scripts/
ArcGIStool.py (script for the tool in the .tbx)
pythonmod/
__init__.py
general.py
xlrd/ (copied from my own python installation)
xlwt/ (copied from my own python installation)
xlutils/ (copied from my own python installation)
So, I like this directory structure, because all of the ArcGIStool.py scripts call functions within the pythonmod package (like those within general.py), and all of the general.py functions can call xlrd and xlwt functions with simple "import xlrd" statements. This means that if the user desired, he/she could just move the pythonmod folder to the python site-packages folder, and everything would run fine, even if xlrd/xlwt/xlutils are already installed.
THE PROBLEM:
Everything is great, until I try to use xlutils in general.py. Specifically, I need to "from xlutils.copy import copy". However, this sets off a cascade of import errors. One is that xlutils/copy.py uses "from xlutils.filter import process,XLRDReader,XLWTWriter". I solved this by modifying xlutils/copy.py like this:
try:
from xlutils.filter import process,XLRDReader,XLWTWriter
except ImportError:
from filter import process,XLRDReader,XLWTWriter
I thought this would work fine for other situations, but there are modules in the xlutils package that need to import xlrd. I tried following this advice, but when I use
try:
import xlrd
except ImportError:
import os, sys, imp
path = os.path.dirname(os.path.dirname(sys.argv[0]))
xlrd = imp.load_source("pythonmod.xlrd",os.path.join(path,"xlrd","__init__.py"))
I get a new import error: In xlrd/init.py, the info module is called (from xlrd/info.py), BUT when I use the above code, I get an error saying that the name "info" is not defined.
This leads me to believe that I don't really know what is going on, because I thought that when the init.py file was imported it would run just like normal and look within its containing folder for info.py. This does not seem to be the case, unfortunately.
Thanks for your interest, and any help would be greatly appreciated.
p.s. I don't want to have to modify the path variables, as I have no idea who will be using this toolset, and permissions are likely to be an issue, etc.
I realized I was using imp.load_source incorrectly. The correct syntax for what I wanted to do should have been:
imp.load_source("xlrd",os.path.join(path,"xlrd","__init__.py"))
In the end though, I ended up rewriting my code to not need xlutils at all, because I continued to have import errors that were causing many more problems than were worth dealing with.

Categories