getting python module complete version with pkg_resources - python

I made a python package using distutils that in its setup.py file, has:
setup(name = "foo",
version = "0.2.1",
...)
when I do:
import pkg_resources
pkg_resources.get_distribution("foo").version
I get 0.2 and not 0.2.1. Why is that? how can i get the full version? thank you.

pkg_resources looks for installed distributions in your Python installation. Have you re-ran python setup.py install or python setup.py develop after you’ve changed the version?
Try inspected the object returned by get_distribution for an attribute showing where the location is located on the file system; maybe foo is not installed where you think it is, and an older version is found instead.

It looks like a bug to me. If the package was installed with distutils instead of setuptools, then pkg_resources.get_distribution() returns the oldest version installed.
The best way to fix it is to replace:
from distutils.core import setup
with:
from setuptools import setup

Related

How to get the path where pip installs `data_files`?

Running pip install seems to create the directory structure + files specified in data_files in /usr/local
However, if I run:
import sys
sys.prefix
I get the string /usr.
Is there any way to figure out where pip installed the data_files for a specific package in a distribution/OS agnostic way ?
Note: I am installing a package from a github repostiroy instead of pypi so maybe this results in the different behavior ?
I believe you should work with sysconfig.
First try:
path/to/pythonX.Y -m sysconfig
And then try its get_path function:
import sysconfig
data_path_str = sysconfig.get_path('data')
print("data_path_str", data_path_str)

Checking if a package is installed specifically via pip

Checking if a particular package is available from within Python can be done via
try:
import requests
except ImportError:
available = False
else:
available = True
Additionally, I would like to know if the respective package has been installed with pip (and can hence been updated with pip install -U package_name).
Any hints?
I believe one way to figure out if a project has been installed by pip is by looking at the content of the INSTALLER text file in the distribution's dist-info directory for this project. With pkg_resources from setuptools this can be done programmatically like the following (error checking omitted):
import pkg_resources
pkg_resources.get_distribution('requests').get_metadata('INSTALLER')
This would return pip\n, in case requests was indeed installed by pip.
You said subprocess.call() is allowed, so
available = not(subprocess.call(["pip", "show", "requests"]))

How should I handle importing third-party libraries within my setup.py script?

I'm developing a Python application and in the process of branching off a release. I've got a PyPI server set up on a company server and I've copied a source distribution of my package onto it.
I checked that the package was being hosted on the server and then tried installing it on my local development machine. I ended up with this output:
$ pip3 install --trusted-host 172.16.1.92 -i http://172.16.1.92:5001/simple/ <my-package>
Collecting <my-package>
Downloading http://172.16.1.92:5001/packages/<my-package>-0.2.0.zip
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\<me>\AppData\Local\Temp\pip-build-ubb3jkpr\<my-package>\setup.py", line 9, in <module>
import appdirs
ModuleNotFoundError: No module named 'appdirs'
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in C:\Users\<me>\AppData\Local\Temp\pip-build-ubb3jkpr\<my-package>\
The reason is that I'm trying to import a third-party library appdirs in my setup.py, which is necessary for me to compute the data_files argument to setup():
try:
from setuptools import setup
except ImportError:
from distutils.core import setup
import os
from collections import defaultdict
import appdirs
from <my-package>.version import __version__ as <my-package>_version
APP_NAME = '<my-app>'
APP_AUTHOR = '<company>'
SYSTEM_COMPONENT_PLUGIN_DIR = os.path.join(appdirs.user_data_dir(APP_NAME, APP_AUTHOR), 'components')
# ...
setup(
# ...
data_files=component_files,
)
However, I don't have appdirs installed on my local dev machine and I don't expect the end users to have it either.
Is it acceptable to rely on third-party libraries like this in setup.py, and if so what is the recommended approach to using them? Is there a way I can ensure appdirs gets installed before it's imported in setup.py, or should I just document that appdirs is a required package to install my package?
I'm ignoring licensing issues in this answer. You definetly need to take these into account before you really do a release.
Is it acceptable to rely on third-party libraries like this in setup.py
Yes, it is acceptable but generally these should be minimized, especially if these are modules which have no obvious use for the end-user. Noone likes to have packages they don't need or use.
what is the recommended approach to using them?
There are basically 3 options:
Bootstrap them (for example use pip to programmatically install packages). For example setuptools provides an ez_setup.py file that can be used to bootstrap setuptools. Maybe that can be customized to download and install appdirs.
Include them (especially if it's a small package) in your project. For example appdirs is basically just a single file module. Pretty easy to copy and maintain in your project. Be very careful with licensing issues when you do that!
Fail gracefully when it's not possible to import them and let the user install them. For example:
try:
import appdirs
except ImportError:
raise ImportError('this package requires "appdirs" to be installed. '
'Install it first: "pip install appdirs".')
You could use pip to install the package programmatically if the import fails:
try:
import appdirs
except ImportError:
import pip
pip.main(['install', 'appdirs'])
import appdirs
In some circumstances you may need to use importlib or __import__ to import the package after pip.main or referesh the PATH variable. It could also be worthwhile to include a verification if the user really wants to install that package before installing it.
I used a lot of the examples from "Installing python module within code" and I haven't personally tried used this in setup.py files but it looks like it could be a solution for your question.
You can mention install_requires with the dependencies list. Please check the python packaging guide here. Also you can provide a requirements.txt file so that it can be run at once using "pip install -r"

ImportError: matplotlib requires dateutil; import matplotlib.pyplot as plt

Am new to progamming and Python, i keep getting the error below when i run my program. Someone advised i should use pip to solve it. But cant pip get installed using the cmd. Though i suceeded using Powershell but still cant make it work. How do i solve this, any tips will go along way. Thanks
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
from satmc import satmc
File "C:\Python27\starb_models_grid1\satmc.py", line 3, in <module>
import matplotlib.pyplot as plt
File "C:\Python27\lib\site-packages\matplotlib\__init__.py", line 110, in <module>
raise ImportError("matplotlib requires dateutil")
ImportError: matplotlib requires dateutil
Am using version 2.7.3
You need to install various packages to get numpy working correctly.
libsvm-3.17.win32-py2.7
pyparsing-2.0.1.win32-py2.7
python-dateutil-2.2.win32-py2.7
pytz-2013.9.win32-py2.7
six-1.5.2.win32-py2.7
scipy-0.13.3.win32-py2.7
numpy-MKL-1.8.0.win32-py2.7
Matplotlib
Download all the binaries from this link and install and then you will have a working numpy installation.
You're probably looking for:
pip install python-dateutil
The error states that you are missing Dateutil.
This could mean that you did not install Dateutil with pip install python-dateutil or your way to install Python modules. But if you did your pip install and still get the same error it could also mean that DateUtil is installed in a folder where your Python distribution does not expect it.
In my case (Mac OSX) I installed pip with Brew http://brew.sh/. That pip will install the modules in: /usr/local/lib/python2.7/site-packages/
However the standard Mac OSX Python distribution will look for modules in /Library/Python/2.7/site-packages/
Your folders could be different of course, but you can check where Python looks for modules with:
import sys
print sys.path
Check this and see if one of the directories in the list contains the directory where dateutil is installed.
If not add a PYTHONPATH environment variable: Like: PYTHONPATH=/usr/local/lib/python2.7/site-packages/ or the folder where your dateutil is installed
I did pip install python-dateutil, but kept getting the same error. I got past that error by installing from http://www.lfd.uci.edu/~gohlke/pythonlibs/#python-dateutil
Look for the Matplotlib section and install the dependencies you don't have.
Matplotlib is a 2D plotting library.
Requires numpy, dateutil, pytz, pyparsing, six, setuptools, and optionally pillow, pycairo, tornado, wxpython, pyside, pyqt4, ghostscript, miktex, ffmpeg, mencoder, avconv, or imagemagick.

setuptools easyinstall mysql-python-1.2.3

I have read a bunch of threads on setuptools here.
A lot of people seem not to like it very much.
But I need to install MySQL-python-1.2.3. and when I do that I get this error:
MySQL-python-1.2.3 X$ python setup.py cleanTraceback (most recent call last):
File "setup.py", line 5, in <module>
from setuptools import setup, Extension
ImportError: No module named setuptools
So it seems I need setuptools and that it is assumed that it is installed.
On the setuptools python homepage it says:
Setuptools will install itself using the matching version of Python (e.g. python2.4), and will place the easy_install executable in the default location for installing Python scripts (as determined by the standard distutils configuration files, or by the Python installation).
Does this mean it will replace any default easy install from python?
If so I dont want to use it.
If so can I install MySQL-python-1.2.3 without setupttools?
Thanks
You should use virtualenv and pip.
Virtualenv automatically creates a setuptools version within the new environment, so the default one is intact.
You may want to read how the packaging and installing works: 1, 2

Categories

Resources