Install many versions of the same Python package with pip3 support.
Getting started
Technical stack
-
Python3 as an interpreter (programming language) to execute the code.
- The following list of versions has been tested:
3.4
,3.5
,3.6
,3.7
.
- The following list of versions has been tested:
Requirements
- Git as a version control system to work with current repository.
-
pip as a package manager for
Python
.
Installation
Install using pip3
:
$ pip3 install pip3-multiple-versions
Usage
Versions
To specify particular version, use the function named use
from multiple_versions
:
import multiple_versions
multiple_versions.use(name='requests', version='2.0.0')
import requests
print(requests)
<module 'requests' from '.../requests-2.0.0/requests/__init__.py'>
Distribution functionality (pkg_resources) also supported by default:
import pkg_resources
print(pkg_resources.get_distribution('requests').version)
2.0.0
Command line interface
Version
Get the version of the package — pip3-multiple-versions --version
:
$ pip3-multiple-versions --version
pip3-multiple-versions, version 0.0.1
Help
Get the detailed description of all supported commands by the package — pip3-multiple-versions --help
:
$ pip3-multiple-versions --help
Usage: pip3-multiple-versions [OPTIONS] COMMAND [ARGS]...
Provide command-line interface for pip3 package's multiple versions.
Options:
--version Show the version and exit.
--help Show this message and exit.
Install
Install a package — pip3-multiple-versions package install
.
You can install as many version as you wish.
Arguments | Type | Required | Restrictions | Description |
---|---|---|---|---|
name | String | Yes | - | Name of a package. |
version | String | Yes | - | Version of a package. |
extra-index-url | String | No | May contain authentication token. | URL to extra Python Package Index. May be private one. |
$ pip3-multiple-versions package install \
--name=avm-model \
--version=2.0.0 \
--extra-index-url=https://${AUTHENTICATION_TOKEN}:@${GEMFURY_PRIVATE_REPOSITORY}
How it works
Benchmark
Any cache system from Python
is not used and the library does not decrease speed of imports call.
Performance without multiple versions calling:
$ python3 -mtimeit -s "import requests"
50000000 loops, best of 5: 6.62 nsec per loop
Performance with multiple versions calling:
$ python3 -mtimeit -s "import multiple_versions; multiple_versions.use(name='requests', version='2.0.0'); import requests"
50000000 loops, best of 5: 6.56 nsec per loop
Troubleshootings
Unknown module folder
You may get the unknown module folder error illustrated below.
Traceback (most recent call last):
File "test.py", line 45, in <module>
multiple_versions.use(name='requests', version='2.0.0')
File "/Users/dmytro/projects/pip3-multiple-versions/multiple_versions/main.py", line 140, in use
imported_package_folder = _get_imported_package_folder(package_name=name, package_version=version)
File "/Users/dmytro/projects/pip3-multiple-versions/multiple_versions/main.py", line 112, in _get_imported_package_folder
raise ModuleNotFoundError('Unknown module folder, package name is different from package folder name.')
ModuleNotFoundError: Unknown module folder, package name is different from package folder name.
It means, that the project name is different from package folder name. After installation this kind of projects, you have:
-
Package folder you do imports from.
import rest_framework
-
Folder with meta data from setup.py such as version, description, etc.
$ ls /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages ... rest_framework djangorestframework-3.11.0-py3.7.egg-info ...
And the point is that multiple_versions.use
under the hood requires data for both of them and the problem is these
different names — djangorestframework
(package name while installing) and rest_framework
(package folder name).
The library easily parse package name, but not package folder name. The solution is to use import_name
variable to be
passed to multiple_versions.use
.
import multiple_versions
multiple_versions.use(name='djangorestframework', version='3.11.0', import_name='rest_framework')
import rest_framework
You don't need import_name
variable in case package name and package folder name is the same:
$ ls /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages
...
marshmallow
marshmallow-3.3.0.dist-info
typing_inspect
typing_inspect-0.4.0.dist-info
...
Development
Clone the project
To start working with the project, clone it with the following commands.
$ git clone git@github.com:dmytrostriletskyi/pip3-multiple-versions.git
$ cd dmytrostriletskyi/pip3-multiple-versions
Distribution
Build the project with the following command:
$ python3 setup.py sdist
Install it locally:
$ pip3 install dist/*.tar.gz
After the command above, you can execute the command line interface as if you installed it through pip3
:
$ pip3-multiple-versions --version
pip3-multiple-versions, version 0.0.1