I know you are asking for a one-liner, but let me describe first the common workaround to targeting Git repositories (not just Github) that also avoids requiring git:
- Download a copy of the source code
- Using
wget
or curl
or whichever shell or script-able utility is available
- From Github, you can target either
- Unzip/Untar the .zip/.tar.gz to some temporary directory
- From that temporary directory, run
pip install ./<temp directory>[<extra dependency]
- The same considerations for where pip installs the package applies
- If using a virtual env, make sure to activate it first
- Or use the
python -m pip install ...
syntax to select a specific environment and interpreter
With regular pip install
targeting a Git repo like this,
pip install git+https://github.com/python/mypy.git#egg=mypy[reports]
pip install "mypy[reports] @ https://github.com/python/mypy/archive/master.zip"
...it automatically already does steps 1 and 2. If you add a -v
/--verbose
option, you'll see that it clones a copy of the codes first from a specific commit, and stores them in some temporary directory (which we don't normally care about), then does the regular installation from there.
Sample for mypy:
$ pip install -v git+https://github.com/python/mypy.git#egg=mypy[reports]
...
Collecting mypy[reports]
Cloning https://github.com/python/mypy.git to /private/var/folders/3h/pdjwtnlx4p13chnw21rvwbtw0000gp/T/pip-install-d6gv_iva/mypy_fe678fe853cb45b68755c0c57dfcb757
...
Cloning into '/private/var/folders/3h/pdjwtnlx4p13chnw21rvwbtw0000gp/T/pip-install-d6gv_iva/mypy_fe678fe853cb45b68755c0c57dfcb757'
...
Building wheels for collected packages: mypy
Running command Building wheel for mypy (pyproject.toml)
running bdist_wheel
running build
running build_py
pin_version()
creating build
creating build/lib
creating build/lib/mypy
creating build/lib/mypyc
...
Successfully built mypy
Installing collected packages: mypy
Running command git rev-parse HEAD
4f07c79aea0fef61ab649d6acedf01186f1054eb
changing mode of /path/to/venv/bin/dmypy to 755
changing mode of /path/to/venv/bin/mypy to 755
changing mode of /path/to/venv/bin/mypyc to 755
changing mode of /path/to/venv/bin/stubgen to 755
changing mode of /path/to/venvi/bin/stubtest to 755
Successfully installed mypy-0.960+dev.4f07c79aea0fef61ab649d6acedf01186f1054eb
$ python
...
>>> import importlib_metadata
>>> importlib_metadata.metadata('mypy').get_all('Requires-Dist')
[ ... extra == 'reports'"]
So, if you don't have Git, you can't do a git clone
, but instead have to download the codes manually. As with the direct pip install
, if you don't care about a specific version, you can just download the latest master
/main
commit:
Sample again for mypy:
$ wget -O mypy-master.zip https://github.com/python/mypy/archive/refs/heads/master.zip
...
2022-05-05 20:29:07 (2.85 MB/s) - ‘mypy-master.zip’ saved [3433301]
$ unzip -o mypy-master.zip
...
inflating: mypy-master/test-data/unit/typexport-basic.test
inflating: mypy-master/test-requirements.txt
inflating: mypy-master/tox.ini
Then the last step would simply be doing pip install
, which supports targetting a <local project path>
and specifying extras all in one command:
python -m pip install .[PDF] # project in current directory
So following the downloaded and unpacked mypy-master
above, the last step would simply be:
$ pip install -v ./mypy-master[reports]
Processing ./mypy-master
...
Building wheels for collected packages: mypy
Running command Building wheel for mypy (pyproject.toml)
running bdist_wheel
running build
running build_py
pin_version()
creating build
creating build/lib
creating build/lib/mypy
creating build/lib/mypyc
...
Successfully built mypy
Installing collected packages: mypy
Running command git rev-parse HEAD
4f07c79aea0fef61ab649d6acedf01186f1054eb
changing mode of /path/to/venv/bin/dmypy to 755
changing mode of /path/to/venv/bin/mypy to 755
changing mode of /path/to/venv/bin/mypyc to 755
changing mode of /path/to/venv/bin/stubgen to 755
changing mode of /path/to/venvi/bin/stubtest to 755
Successfully installed mypy-0.960+dev.4f07c79aea0fef61ab649d6acedf01186f1054eb
$ python
...
>>> import importlib_metadata
>>> importlib_metadata.metadata('mypy').get_all('Requires-Dist')
[ ... extra == 'reports'"]
...which shows the same output as the one that pip install
-ed directly from git+https
. The same considerations with using pip install
applies, for example, if you are using a virtual environment, make sure to activate that first so mypy is installed in the same location.
Now, to make it all a one-liner command, you can turn those steps into a script, a shell alias, or just straight-up run multiple commands with &&
operator:
$ wget -O mypy-master.zip https://github.com/python/mypy/archive/refs/heads/master.zip && unzip -o mypy-master.zip && pip install ./mypy-master[reports] && rm -R mypy-master*
Note that I added removal of the temporary files/folders at the end of the command. If one of the steps fails (ex. network connection error), then the rest of the commands will be aborted. You can add better/more error-handling as needed.
$ wget -O mypy-master.zip https://github.com/python/mypy/archive/refs/heads/master.zip && unzip -o mypy-master.zip && pip install ./mypy-master[reports] && rm -Rf mypy-master*
--2022-05-05 21:09:39-- https://github.com/python/mypy/archive/refs/heads/master.zip
Resolving github.com (github.com)... failed: nodename nor servname provided, or not known.
wget: unable to resolve host address ‘github.com’
I agree though that that isn't an elegant or an intuitive command.