I'm trying to get an in depth understanding of a bare minimum python package. As a setup.py this works perfectly:
from setuptools import setup
setup(
name='helloworld',
version='0.0.1',
description='Say hello!',
py_modules=['helloworld'],
package_dir={'': 'src'},
)
Again, I can import and run "helloworld" just fine. However, when I change "name" and "py_modules" to be something different from each other the system breaks. According to Mark Smith's EuroPython lecture "name" is what you pip install and "py_modules" is what you import.
from setuptools import setup
setup(
name='installMe',
version='0.0.1',
description='Say hello!',
py_modules=['importMe'],
package_dir={'': 'src'},
)
So I installed the software in a python virtual environment:
python3 -m venv bareMinEnv
source bareMinEnv/bin/activate
pip install -e .
and everything looked fine:
pip list
Package Version Location
---------- ------- ------------------------------------------------------------------
installMe 0.0.1 /mnt/d/PROJECTS/PACKAGE_CREATION/min2/bareMinimumPythonPackage/src
pip 20.2.3
setuptools 49.2.1
However, it breaks at the importation step. Here it show's I can't import "importMe":
>>> from importMe import say_hello
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'importMe'
and here is evidence I can't import "installMe":
>>> from installMe import say_hello
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'installMe'
All of this works if I keep the names the same. So how to I make them different while maintaining functionality? I've created a dozen packages and I don't understand why it's not behaving as I believe the documentation describes. Again, this is easy to fix by keeping the names the same. However, I'm trying to understand every detail about the pip packaging system. Thanks in advance.
Related
I took a few days to understand pip install workflow, and now that I'm aware of at list main problems, I'm facing this import issue that I just can't find a workaround.
I have this minimum executable example:
packagetest/
__init__.py
main.py
aux.py
setup.py
aux.py
class Aux:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
main.py
from packagetest.aux import Aux
def printAux():
print(Aux('aux1'))
if __name__ == "__main__":
printAux()
setup.py
from setuptools import find_packages, setup
setup(
name='packagetest',
version='0.1',
packages=find_packages(),
)
That's it. That's my python package.
Then I run pip install . and in another project, let's say project2.py, I can call:
from packagetest import main
main.printAux()
and that's my output:
aux1
Everything works perfectly, except not. If I run pip uninstall packagetest, go into my packagetest/ folder and then try to run python main.py I catch this error:
Traceback (most recent call last):
File "main.py", line 1, in <module>
from packagetest.aux import Aux
ModuleNotFoundError: No module named 'packagetest'
That's because my packagetest is not installed and python can't find packagetest when i'm importing it with from packagetest.aux import Aux. if I change it to from aux import Aux it works perfectly, but in this case I can't export this project using pip install because aux will not be recognized as a module. I tried and I catch this another error on project2.py:
Traceback (most recent call last):
File "project2.py", line 1, in <module>
from packagetest import main
File "/home/leonardo/.local/lib/python3.8/site-packages/packagetest/main.py", line 1, in <module>
from aux import Aux
ModuleNotFoundError: No module named 'aux'
My question is how to make my project executable without installing it? I want an import that works in both cases, and don't want my modules to be executable only it my package is installed inside pip packages. I wan't to clone my repo and execute my project in a new machine without being forced to install in via pip.
Is it possible? How big projects handle that?
I testing my PyPI package, before upload, with pip3 install -e ., in the package directory.
It depends on pillow (import PIL in code).
When I tested with already installed pillow it worked.
But, I uninstall the pillow then reinstall my package with pip3 install -e ., it didn't work:
Obtaining file:///Users/hongbook/dev/identicon
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/Users/hongbook/dev/identicon/setup.py", line 4, in <module>
import Identicon
File "/Users/hongbook/dev/identicon/Identicon/__init__.py", line 2, in <module>
from .Identicon import render
File "/Users/hongbook/dev/identicon/Identicon/Identicon.py", line 5, in <module>
from PIL import Image, ImageDraw
ModuleNotFoundError: No module named 'PIL'
I expected when I install that, pillow should be installed since I wrote it install_requires's value in setup.py(also that in requirements.txt):
# setup.py
from setuptools import setup, find_packages
...
setup(
name='Identicon',
version=Identicon.__version__,
...
install_requires=[
'pillow',
],
)
# requirements.txt
pillow
How can I make dependency my project to pillow right?
I think your problem is stemming from this:
version=Identicon.__version__,
In order to do that, you're importing Identicon, which is your package, which imports PIL. So, your setup.py is broken. It requires the dependencies to be already installed in order to execute, however it's the setup.py job to install those dependencies in the first place.
This is a common "chicken and egg" situation in packaging. The solution is to use a different way to parse the version number from your package, or store the version number somewhere that doesn't trigger imports of your dependencies.
You can import version without importing the entire package using imp. See how I do it in SQLObject:
from imp import load_source
from os.path import abspath, dirname, join
versionpath = join(abspath(dirname(__file__)), "sqlobject", "__version__.py")
sqlobject_version = load_source("sqlobject_version", versionpath)
setup(name="SQLObject",
version=sqlobject_version.version,
…
)
I forked the scikit-learn repository, added a file that I need and downloaded the repository. I am not sure how to use this custom library. I cd'ed to the scikit-learn-master folder and tried to use it but it throws errors. So after reading the errors I installed it using python3 setup.py install. There were two setup.py files. One in the scikit-learn-master folder and sklearn folder so I ran python3 setup.py install at both these locations. They threw some warnings but no errors. I opened the python terminal in the scikit-learn-master folder and used import sklearn which returns the following -
Traceback (most recent call last):
File "/Users/shubhamgandhi/Desktop/scikit-learn-master/sklearn/__check_build/__init__.py", line 44, in <module>
from ._check_build import check_build # noqa
ModuleNotFoundError: No module named 'sklearn.__check_build._check_build'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/shubhamgandhi/Desktop/scikit-learn-master/sklearn/__init__.py", line 128, in <module>
from . import __check_build
File "/Users/shubhamgandhi/Desktop/scikit-learn-master/sklearn/__check_build/__init__.py", line 46, in <module>
raise_build_error(e)
File "/Users/shubhamgandhi/Desktop/scikit-learn-master/sklearn/__check_build/__init__.py", line 41, in raise_build_error
%s""" % (e, local_dir, ''.join(dir_content).strip(), msg))
ImportError: No module named 'sklearn.__check_build._check_build'
___________________________________________________________________________
Contents of /Users/shubhamgandhi/Desktop/scikit-learn-master/sklearn/__check_build:
__init__.py __pycache__ _check_build.c
_check_build.pyx setup.py setup.pyc
___________________________________________________________________________
It seems that scikit-learn has not been built correctly.
If you have installed scikit-learn from source, please do not forget
to build the package before using it: run `python setup.py install` or
`make` in the source directory.
If you have used an installer, please check that it is suited for your
Python version, your operating system and your platform.
I am not sure how to proceed. Is there anything I am missing?
It appears the module has not been built correctly. And so it shows importError for check_build.
Before installing the module using pip, make sure you have installed all of the dependencies. On the README file, the mentioned packages are:
Python (>= 2.7 or >= 3.3)
NumPy (>= 1.8.2)
SciPy (>= 0.13.3)
For running the examples Matplotlib >= 1.1.1 is required.
If you are not planning on contributing to the project, but only using it, it is recommended that you download from https://pypi.python.org/pypi/scikit-learn instead of forking it.
View detailed instructions on how to install here.
After installing and building this way, if you still have issues, you can refer http://scikit-learn.org/stable/faq.html for FAQs.
I'm using Ubuntu 14.04. While I have to retain my "main" python install as 2.7.6, I need to install 2.7.9 to be able to use ssl.SSLContext, to get Flask to deal with HTTPS requests.
However, if I just do:
sudo make install
or
sudo make altinstall
in the Python-2.7.9 directory, I ultimately get:
make: *** [libinstall] Error 1
EDIT: this appears at the end of sudo make install:
...
Compiling /usr/local/lib/python2.7/xml/sax/saxutils.py ...
Compiling /usr/local/lib/python2.7/xml/sax/xmlreader.py ...
Compiling /usr/local/lib/python2.7/xmllib.py ...
Compiling /usr/local/lib/python2.7/xmlrpclib.py ...
Compiling /usr/local/lib/python2.7/zipfile.py ...
make: *** [libinstall] Error 1
So I installed it to a custom directory by modifying the call to ./config, which did not yield the libinstall error.
However, when I try to import Tkinter into Python 2.7.9 (running from the custom directory) I obtain:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/repos/Python279/lib/python2.7/lib-tk/Tkinter.py", line 39, in <module>
import _tkinter # If this fails your Python may not be configured for Tk
ImportError: No module named _tkinter
If I just go ahead and install the vanilla way (i.e., to a non-custom directory) and simply ignore the libinstall error I get, upon importing Tkinter:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/lib-tk/Tkinter.py", line 39, in <module>
import _tkinter # If this fails your Python may not be configured for Tk
ImportError: /usr/lib/python2.7/lib-dynload/_tkinter.so: undefined symbol: PyFPE_jbuf
Does anyone have any idea what is going on?
Following furas' suggestion, installing via the
Python 2.7 PPA maintained be Felix Krull worked spectacularly. Thanks Furas!
EDIT Some notes:
Because this PPA installs python2.7 (specifically v. 2.7.11, as of 1/29/2016), this obviated the need for a custom python install location
While the PPA website mentions that this doesn't include python-tk, provided you have installed it, python plays with it just fine (solving my problem)
First of all source code from a program must be configured, compiled, then installed. You can do this by:
./configure # Or ./config depending on the file name
make
make install
Second of all when you tried to import the module _tkinter you wanted to import the .py file which was called Tkinter.py
Try to use:
import Tkinter
I'm using cairo plot to draw charts with python. I followed the instruction as stated on the website to install Cairplot, http://linil.wordpress.com/2008/09/16/cairoplot-11/ :
sudo apt-get install bzr
bzr branch lp:cairoplot/1.1
The installation completes successfully.
I then try to import the modules in python:
>>> import CairoPlot Traceback (most recent call last): File "<stdin>",
line 1, in <module> ImportError: No
module named CairoPlot
>>> import cairo
>>>
Importing cairo is fine, but I can't figure out why I am not able to import CairoPlot.
bzr branch lp:cairoplot/1.1 creates a directory called 1.1 in your current working directory. Inside you'll find CairoPlot.py. Move CairoPlot.py into a directory which is listed in your PYTHONPATH, or edit your PYTHONPATH to include (the unfortunately named) 1.1.
Is the directory where CairoPlot is installed in your $PYTHONPATH? Do you need to run any setup scripts, like setuptools?
The repository appears to include a setup.py file, so you likely need to run setuptools to fully install the module.