mirror of
https://github.com/pypa/pip
synced 2023-12-13 21:30:23 +01:00
Merge branch 'main' into main
This commit is contained in:
commit
01b1388165
13
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
13
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
|
@ -60,15 +60,12 @@ body:
|
|||
label: Output
|
||||
description: >-
|
||||
Provide the output of the steps above, including the commands
|
||||
themselves and pip's output/traceback etc. If you're familiar with
|
||||
Markdown, this block will have triple backticks added automatically
|
||||
around it -- you don't have to add them.
|
||||
themselves and pip's output/traceback etc.
|
||||
|
||||
If you want to present output from multiple commands, please present
|
||||
that as a shell session (commands you run get prefixed with `$ `).
|
||||
Please also ensure that the "How to reproduce" section contains matching
|
||||
instructions for reproducing this.
|
||||
render: sh-session
|
||||
If you want to present output from multiple commands, please prefix
|
||||
the line containing the command with `$ `. Please also ensure that
|
||||
the "How to reproduce" section contains matching instructions for
|
||||
reproducing this.
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
|
|
38
.github/ISSUE_TEMPLATE/~good-first-issue.yml
vendored
38
.github/ISSUE_TEMPLATE/~good-first-issue.yml
vendored
|
@ -1,38 +0,0 @@
|
|||
name: Good first issue
|
||||
description: If you're a pip maintainer, use this to create a "good first issue" for new contributors.
|
||||
labels: "good first issue"
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description
|
||||
description: >-
|
||||
A clear and concise description of what the task is.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: What needs to be done
|
||||
description: >-
|
||||
Describe what the contributor would need to do, describing the change.
|
||||
See https://github.com/pypa/pip/issues/7661 for example.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Guidance for potential contributors
|
||||
description: >-
|
||||
Usually, you don't have to modify the content here.
|
||||
value: >-
|
||||
This issue is a good starting point for first time contributors -- the
|
||||
process of fixing this should be a good introduction to pip's
|
||||
development workflow. If there is not a corresponding pull request for
|
||||
this issue, it is up for grabs. For directions for getting set up, see our
|
||||
[Getting Started Guide](https://pip.pypa.io/en/latest/development/getting-started/).
|
||||
If you are working on this issue and have questions, feel free to ask
|
||||
them here. If you've contributed code to pip before, we encourage you to
|
||||
pick up an issue without this label.
|
||||
validations:
|
||||
required: true
|
30
.github/chronographer.yml
vendored
Normal file
30
.github/chronographer.yml
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
|
||||
action-hints:
|
||||
# check-title-prefix: chng # default: `{{ branch-protection-check-name }}: `
|
||||
external-docs-url: https://pip.pypa.io/how-to-changelog
|
||||
inline-markdown: >
|
||||
Check out https://pip.pypa.io/how-to-changelog
|
||||
|
||||
branch-protection-check-name: Timeline protection
|
||||
|
||||
enforce-name:
|
||||
# suffix: .md
|
||||
suffix: .rst
|
||||
|
||||
exclude:
|
||||
bots:
|
||||
- dependabot-preview
|
||||
- dependabot
|
||||
- patchback
|
||||
humans:
|
||||
- pyup-bot
|
||||
|
||||
labels:
|
||||
skip-changelog: skip news
|
||||
|
||||
paths: # relative modified file paths that do or don't need changelog mention
|
||||
exclude: []
|
||||
include: []
|
||||
|
||||
...
|
11
.github/no-response.yml
vendored
11
.github/no-response.yml
vendored
|
@ -1,11 +0,0 @@
|
|||
# Number of days of inactivity before issue is closed for lack of response
|
||||
daysUntilClose: 15
|
||||
# Label requiring a response
|
||||
responseRequiredLabel: "S: awaiting response"
|
||||
# Comment to post when closing an Issue for lack of response. Set to `false` to disable
|
||||
closeComment: >
|
||||
This issue has been automatically closed because there has been no response
|
||||
to our request for more information from the original author. With only the
|
||||
information that is currently in the issue, we don't have enough information
|
||||
to take action. Please reach out if you have or find the answers we need so
|
||||
that we can investigate further.
|
162
.github/workflows/ci.yml
vendored
162
.github/workflows/ci.yml
vendored
|
@ -11,14 +11,20 @@ on:
|
|||
schedule:
|
||||
- cron: 0 0 * * MON # Run every Monday at 00:00 UTC
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
docs:
|
||||
name: docs
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- run: pip install nox
|
||||
- run: nox -s docs
|
||||
|
||||
|
@ -37,31 +43,24 @@ jobs:
|
|||
# Anything that's touching "vendored code"
|
||||
- "src/pip/_vendor/**"
|
||||
- "pyproject.toml"
|
||||
- "noxfile.py"
|
||||
tests:
|
||||
# Anything that's touching testable stuff
|
||||
# Anything that's touching code-related stuff
|
||||
- ".github/workflows/ci.yml"
|
||||
- "src/**"
|
||||
- "tests/**"
|
||||
- "noxfile.py"
|
||||
if: github.event_name == 'pull_request'
|
||||
|
||||
pre-commit:
|
||||
name: pre-commit
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: pre-commit/action@v2.0.0
|
||||
with:
|
||||
extra_args: --all-files --hook-stage=manual
|
||||
|
||||
packaging:
|
||||
name: packaging
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Set up git credentials
|
||||
run: |
|
||||
git config --global user.email "pypa-dev@googlegroups.com"
|
||||
|
@ -70,6 +69,7 @@ jobs:
|
|||
- run: pip install nox
|
||||
- run: nox -s prepare-release -- 99.9
|
||||
- run: nox -s build-release -- 99.9
|
||||
- run: pipx run check-manifest
|
||||
|
||||
vendoring:
|
||||
name: vendoring
|
||||
|
@ -81,18 +81,20 @@ jobs:
|
|||
github.event_name != 'pull_request'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.x"
|
||||
|
||||
- run: pip install vendoring
|
||||
- run: vendoring sync . --verbose
|
||||
- run: pip install nox
|
||||
- run: nox -s vendoring
|
||||
- run: git diff --exit-code
|
||||
|
||||
tests-unix:
|
||||
name: tests / ${{ matrix.python }} / ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
|
||||
needs: [pre-commit, packaging, determine-changes]
|
||||
needs: [packaging, determine-changes]
|
||||
if: >-
|
||||
needs.determine-changes.outputs.tests == 'true' ||
|
||||
github.event_name != 'pull_request'
|
||||
|
@ -102,15 +104,15 @@ jobs:
|
|||
matrix:
|
||||
os: [Ubuntu, MacOS]
|
||||
python:
|
||||
- 3.6
|
||||
- 3.7
|
||||
- 3.8
|
||||
- 3.9
|
||||
- "3.10.0-alpha - 3.10"
|
||||
- "3.7"
|
||||
- "3.8"
|
||||
- "3.9"
|
||||
- "3.10"
|
||||
- "3.11"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
|
||||
|
@ -120,19 +122,19 @@ jobs:
|
|||
|
||||
- name: Install MacOS dependencies
|
||||
if: matrix.os == 'MacOS'
|
||||
run: brew install bzr
|
||||
run: brew install breezy
|
||||
|
||||
- run: pip install tox 'virtualenv<20'
|
||||
- run: pip install nox
|
||||
|
||||
# Main check
|
||||
- name: Run unit tests
|
||||
run: >-
|
||||
tox -e py --
|
||||
nox -s test-${{ matrix.python }} --
|
||||
-m unit
|
||||
--verbose --numprocesses auto --showlocals
|
||||
- name: Run integration tests
|
||||
run: >-
|
||||
tox -e py --
|
||||
nox -s test-${{ matrix.python }} --
|
||||
-m integration
|
||||
--verbose --numprocesses auto --showlocals
|
||||
--durations=5
|
||||
|
@ -141,7 +143,7 @@ jobs:
|
|||
name: tests / ${{ matrix.python }} / ${{ matrix.os }} / ${{ matrix.group }}
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
|
||||
needs: [pre-commit, packaging, determine-changes]
|
||||
needs: [packaging, determine-changes]
|
||||
if: >-
|
||||
needs.determine-changes.outputs.tests == 'true' ||
|
||||
github.event_name != 'pull_request'
|
||||
|
@ -151,17 +153,17 @@ jobs:
|
|||
matrix:
|
||||
os: [Windows]
|
||||
python:
|
||||
- 3.6
|
||||
- "3.7"
|
||||
# Commented out, since Windows tests are expensively slow.
|
||||
# - 3.7
|
||||
# - 3.8
|
||||
- 3.9
|
||||
- "3.10.0-alpha - 3.10"
|
||||
# - "3.8"
|
||||
# - "3.9"
|
||||
# - "3.10"
|
||||
- "3.11"
|
||||
group: [1, 2]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python }}
|
||||
|
||||
|
@ -180,7 +182,7 @@ jobs:
|
|||
$acl.AddAccessRule($rule)
|
||||
Set-Acl "R:\Temp" $acl
|
||||
|
||||
- run: pip install tox 'virtualenv<20'
|
||||
- run: pip install nox
|
||||
env:
|
||||
TEMP: "R:\\Temp"
|
||||
|
||||
|
@ -188,7 +190,7 @@ jobs:
|
|||
- name: Run unit tests
|
||||
if: matrix.group == 1
|
||||
run: >-
|
||||
tox -e py --
|
||||
nox -s test-${{ matrix.python }} --
|
||||
-m unit
|
||||
--verbose --numprocesses auto --showlocals
|
||||
env:
|
||||
|
@ -197,7 +199,7 @@ jobs:
|
|||
- name: Run integration tests (group 1)
|
||||
if: matrix.group == 1
|
||||
run: >-
|
||||
tox -e py --
|
||||
nox -s test-${{ matrix.python }} --
|
||||
-m integration -k "not test_install"
|
||||
--verbose --numprocesses auto --showlocals
|
||||
env:
|
||||
|
@ -206,8 +208,80 @@ jobs:
|
|||
- name: Run integration tests (group 2)
|
||||
if: matrix.group == 2
|
||||
run: >-
|
||||
tox -e py --
|
||||
nox -s test-${{ matrix.python }} --
|
||||
-m integration -k "test_install"
|
||||
--verbose --numprocesses auto --showlocals
|
||||
env:
|
||||
TEMP: "R:\\Temp"
|
||||
|
||||
tests-zipapp:
|
||||
name: tests / zipapp
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs: [packaging, determine-changes]
|
||||
if: >-
|
||||
needs.determine-changes.outputs.tests == 'true' ||
|
||||
github.event_name != 'pull_request'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Install Ubuntu dependencies
|
||||
run: sudo apt-get install bzr
|
||||
|
||||
- run: pip install nox 'virtualenv<20' 'setuptools != 60.6.0'
|
||||
|
||||
# Main check
|
||||
- name: Run integration tests
|
||||
run: >-
|
||||
nox -s test-3.10 --
|
||||
-m integration
|
||||
--verbose --numprocesses auto --showlocals
|
||||
--durations=5
|
||||
--use-zipapp
|
||||
|
||||
check: # This job does nothing and is only used for the branch protection
|
||||
if: always()
|
||||
|
||||
needs:
|
||||
- determine-changes
|
||||
- docs
|
||||
- packaging
|
||||
- tests-unix
|
||||
- tests-windows
|
||||
- tests-zipapp
|
||||
- vendoring
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Decide whether the needed jobs succeeded or failed
|
||||
uses: re-actors/alls-green@release/v1
|
||||
with:
|
||||
allowed-skips: >-
|
||||
${{
|
||||
(
|
||||
needs.determine-changes.outputs.vendoring != 'true'
|
||||
&& github.event_name == 'pull_request'
|
||||
)
|
||||
&& 'vendoring'
|
||||
|| ''
|
||||
}}
|
||||
,
|
||||
${{
|
||||
(
|
||||
needs.determine-changes.outputs.tests != 'true'
|
||||
&& github.event_name == 'pull_request'
|
||||
)
|
||||
&& '
|
||||
tests-unix,
|
||||
tests-windows,
|
||||
tests-zipapp,
|
||||
tests-importlib-metadata,
|
||||
'
|
||||
|| ''
|
||||
}}
|
||||
jobs: ${{ toJSON(needs) }}
|
||||
|
|
1
.github/workflows/lock-threads.yml
vendored
1
.github/workflows/lock-threads.yml
vendored
|
@ -14,6 +14,7 @@ concurrency:
|
|||
|
||||
jobs:
|
||||
action:
|
||||
if: github.repository_owner == 'pypa'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v3
|
||||
|
|
4
.github/workflows/news-file.yml
vendored
4
.github/workflows/news-file.yml
vendored
|
@ -10,14 +10,14 @@ jobs:
|
|||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# `towncrier check` runs `git diff --name-only origin/main...`, which
|
||||
# needs a non-shallow clone.
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Check news entry
|
||||
if: "!contains(github.event.pull_request.labels.*.name, 'trivial')"
|
||||
if: "!contains(github.event.pull_request.labels.*.name, 'skip news')"
|
||||
run: |
|
||||
if ! pipx run towncrier check --compare-with origin/${{ github.base_ref }}; then
|
||||
echo "Please see https://pip.pypa.io/dev/news-entry-failure for guidance."
|
||||
|
|
19
.github/workflows/no-response.yml
vendored
Normal file
19
.github/workflows/no-response.yml
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
name: No Response
|
||||
|
||||
# Both `issue_comment` and `scheduled` event types are required for this Action
|
||||
# to work properly.
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
schedule:
|
||||
# Schedule for five minutes after the hour, every hour
|
||||
- cron: '5 * * * *'
|
||||
|
||||
jobs:
|
||||
noResponse:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: lee-dohm/no-response@v0.5.0
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
responseRequiredLabel: "S: awaiting response"
|
28
.github/workflows/update-rtd-redirects.yml
vendored
Normal file
28
.github/workflows/update-rtd-redirects.yml
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
name: Update documentation redirects
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
schedule:
|
||||
- cron: 0 0 * * MON # Run every Monday at 00:00 UTC
|
||||
|
||||
env:
|
||||
FORCE_COLOR: "1"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
update-rtd-redirects:
|
||||
runs-on: ubuntu-latest
|
||||
environment: RTD Deploys
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- run: pip install httpx pyyaml rich
|
||||
- run: python tools/update-rtd-redirects.py
|
||||
env:
|
||||
RTD_API_TOKEN: ${{ secrets.RTD_API_TOKEN }}
|
1
.mailmap
1
.mailmap
|
@ -34,6 +34,7 @@ Ludovic Gasc <gmludo@gmail.com> <git@gmludo.eu>
|
|||
Markus Hametner <fin+github@xbhd.org>
|
||||
Masklinn <bitbucket.org@masklinn.net>
|
||||
Matthew Iversen <teh.ivo@gmail.com> <teh.ivo@gmail.com>
|
||||
Ofek Lev <ofekmeister@gmail.com>
|
||||
Pi Delport <pjdelport@gmail.com>
|
||||
<pnasrat@gmail.com> <pnasrat@googlemail.com>
|
||||
Pradyun Gedam <pradyunsg@gmail.com> <pradyunsg@users.noreply.github.com>
|
||||
|
|
|
@ -2,7 +2,7 @@ exclude: 'src/pip/_vendor/'
|
|||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.4.0
|
||||
rev: v4.3.0
|
||||
hooks:
|
||||
- id: check-builtin-literals
|
||||
- id: check-added-large-files
|
||||
|
@ -17,29 +17,29 @@ repos:
|
|||
exclude: .patch
|
||||
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 21.7b0
|
||||
rev: 22.6.0
|
||||
hooks:
|
||||
- id: black
|
||||
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.8.4
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 4.0.1
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies: [
|
||||
'flake8-bugbear==20.1.4',
|
||||
'flake8-logging-format==0.6.0',
|
||||
'flake8-implicit-str-concat==0.2.0',
|
||||
'flake8-bugbear==22.10.27',
|
||||
'flake8-logging-format==0.9.0',
|
||||
'flake8-implicit-str-concat==0.3.0',
|
||||
]
|
||||
exclude: tests/data
|
||||
|
||||
- repo: https://github.com/PyCQA/isort
|
||||
rev: 5.7.0
|
||||
rev: 5.12.0
|
||||
hooks:
|
||||
- id: isort
|
||||
files: \.py$
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v0.910
|
||||
rev: v0.961
|
||||
hooks:
|
||||
- id: mypy
|
||||
exclude: tests/data
|
||||
|
@ -47,14 +47,16 @@ repos:
|
|||
additional_dependencies: [
|
||||
'keyring==23.0.1',
|
||||
'nox==2021.6.12',
|
||||
'pytest==6.2.5',
|
||||
'types-docutils==0.1.8',
|
||||
'types-setuptools==57.0.2',
|
||||
'types-six==0.1.9',
|
||||
'pytest',
|
||||
'types-docutils==0.18.3',
|
||||
'types-setuptools==57.4.14',
|
||||
'types-freezegun==1.1.9',
|
||||
'types-six==1.16.15',
|
||||
'types-pyyaml==6.0.12.2',
|
||||
]
|
||||
|
||||
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||
rev: v1.7.0
|
||||
rev: v1.9.0
|
||||
hooks:
|
||||
- id: python-no-log-warn
|
||||
- id: python-no-eval
|
||||
|
@ -72,8 +74,7 @@ repos:
|
|||
exclude: ^news/(.gitignore|.*\.(process|removal|feature|bugfix|vendor|doc|trivial).rst)
|
||||
files: ^news/
|
||||
|
||||
- repo: https://github.com/mgedmin/check-manifest
|
||||
rev: '0.46'
|
||||
hooks:
|
||||
- id: check-manifest
|
||||
stages: [manual]
|
||||
ci:
|
||||
autofix_prs: false
|
||||
autoupdate_commit_msg: 'pre-commit autoupdate'
|
||||
autoupdate_schedule: monthly
|
||||
|
|
15
.readthedocs-custom-redirects.yml
Normal file
15
.readthedocs-custom-redirects.yml
Normal file
|
@ -0,0 +1,15 @@
|
|||
# This file is read by tools/update-rtd-redirects.py.
|
||||
# It is related to Read the Docs, but is not a file processed by the platform.
|
||||
|
||||
/dev/news-entry-failure: >-
|
||||
https://pip.pypa.io/en/latest/development/contributing/#news-entries
|
||||
/errors/resolution-impossible: >-
|
||||
https://pip.pypa.io/en/stable/topics/dependency-resolution/#dealing-with-dependency-conflicts
|
||||
/surveys/backtracking: >-
|
||||
https://forms.gle/LkZP95S4CfqBAU1N6
|
||||
/warnings/backtracking: >-
|
||||
https://pip.pypa.io/en/stable/topics/dependency-resolution/#possible-ways-to-reduce-backtracking
|
||||
/warnings/enable-long-paths: >-
|
||||
https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd#enable-long-paths-in-windows-10-version-1607-and-later
|
||||
/warnings/venv: >-
|
||||
https://docs.python.org/3/tutorial/venv.html
|
75
AUTHORS.txt
75
AUTHORS.txt
|
@ -18,6 +18,7 @@ Alan Yee
|
|||
Albert Tugushev
|
||||
Albert-Guan
|
||||
albertg
|
||||
Alberto Sottile
|
||||
Aleks Bunin
|
||||
Alethea Flowers
|
||||
Alex Gaynor
|
||||
|
@ -38,6 +39,7 @@ Andre Aguiar
|
|||
Andreas Lutro
|
||||
Andrei Geacar
|
||||
Andrew Gaul
|
||||
Andrew Shymanel
|
||||
Andrey Bienkowski
|
||||
Andrey Bulgakov
|
||||
Andrés Delfino
|
||||
|
@ -98,6 +100,7 @@ Bradley Ayers
|
|||
Brandon L. Reiss
|
||||
Brandt Bucher
|
||||
Brett Randall
|
||||
Brett Rosen
|
||||
Brian Cristante
|
||||
Brian Rosner
|
||||
briantracy
|
||||
|
@ -124,6 +127,8 @@ Chris Brinker
|
|||
Chris Hunt
|
||||
Chris Jerdonek
|
||||
Chris McDonough
|
||||
Chris Pawley
|
||||
Chris Pryer
|
||||
Chris Wolfe
|
||||
Christian Clauss
|
||||
Christian Heimes
|
||||
|
@ -133,6 +138,7 @@ Christopher Hunt
|
|||
Christopher Snyder
|
||||
cjc7373
|
||||
Clark Boylan
|
||||
Claudio Jolowicz
|
||||
Clay McClure
|
||||
Cody
|
||||
Cody Soyland
|
||||
|
@ -155,6 +161,7 @@ Damian Shaw
|
|||
Dan Black
|
||||
Dan Savilonis
|
||||
Dan Sully
|
||||
Dane Hillard
|
||||
daniel
|
||||
Daniel Collins
|
||||
Daniel Hahler
|
||||
|
@ -163,7 +170,9 @@ Daniel Jost
|
|||
Daniel Katz
|
||||
Daniel Shaulov
|
||||
Daniele Esposti
|
||||
Daniele Nicolodi
|
||||
Daniele Procida
|
||||
Daniil Konovalenko
|
||||
Danny Hermes
|
||||
Danny McClanahan
|
||||
Darren Kavanagh
|
||||
|
@ -180,6 +189,7 @@ David Hewitt
|
|||
David Linke
|
||||
David Poggi
|
||||
David Pursehouse
|
||||
David Runge
|
||||
David Tucker
|
||||
David Wales
|
||||
Davidovich
|
||||
|
@ -193,17 +203,22 @@ Diego Caraballo
|
|||
Diego Ramirez
|
||||
DiegoCaraballo
|
||||
Dimitri Merejkowsky
|
||||
Dimitri Papadopoulos
|
||||
Dirk Stolle
|
||||
Dmitry Gladkov
|
||||
Dmitry Volodin
|
||||
Domen Kožar
|
||||
Dominic Davis-Foster
|
||||
Donald Stufft
|
||||
Dongweiming
|
||||
doron zarhi
|
||||
Douglas Thor
|
||||
DrFeathers
|
||||
Dustin Ingram
|
||||
Dwayne Bailey
|
||||
Ed Morley
|
||||
Edgar Ramírez
|
||||
Ee Durbin
|
||||
Eitan Adler
|
||||
ekristina
|
||||
elainechan
|
||||
|
@ -222,15 +237,17 @@ Eric Hanchrow
|
|||
Eric Hopper
|
||||
Erik M. Bray
|
||||
Erik Rose
|
||||
Ernest W Durbin III
|
||||
Ernest W. Durbin III
|
||||
Erwin Janssen
|
||||
Eugene Vereshchagin
|
||||
everdimension
|
||||
Federico
|
||||
Felipe Peter
|
||||
Felix Yan
|
||||
fiber-space
|
||||
Filip Kokosiński
|
||||
Filipe Laíns
|
||||
Finn Womack
|
||||
finnagin
|
||||
Florian Briand
|
||||
Florian Rathgeber
|
||||
Francesco
|
||||
|
@ -239,16 +256,20 @@ Frost Ming
|
|||
Gabriel Curio
|
||||
Gabriel de Perthuis
|
||||
Garry Polley
|
||||
gavin
|
||||
gdanielson
|
||||
Geoffrey Sneddon
|
||||
George Song
|
||||
Georgi Valkov
|
||||
Georgy Pchelkin
|
||||
ghost
|
||||
Giftlin Rajaiah
|
||||
gizmoguy1
|
||||
gkdoc
|
||||
Godefroid Chapelle
|
||||
Gopinath M
|
||||
GOTO Hayato
|
||||
gousaiyang
|
||||
gpiks
|
||||
Greg Roodt
|
||||
Greg Ward
|
||||
|
@ -262,11 +283,15 @@ Hari Charan
|
|||
Harsh Vardhan
|
||||
harupy
|
||||
Harutaka Kawamura
|
||||
hauntsaninja
|
||||
Henrich Hartzer
|
||||
Henry Schreiner
|
||||
Herbert Pfennig
|
||||
Holly Stotelmyer
|
||||
Hsiaoming Yang
|
||||
Hugo Lopes Tavares
|
||||
Hugo van Kemenade
|
||||
Hugues Bruant
|
||||
Hynek Schlawack
|
||||
Ian Bicking
|
||||
Ian Cordasco
|
||||
|
@ -284,17 +309,22 @@ Ionel Maries Cristian
|
|||
Ivan Pozdeev
|
||||
Jacob Kim
|
||||
Jacob Walls
|
||||
Jaime Sanz
|
||||
jakirkham
|
||||
Jakub Kuczys
|
||||
Jakub Stasiak
|
||||
Jakub Vysoky
|
||||
Jakub Wilk
|
||||
James Cleveland
|
||||
James Curtin
|
||||
James Firth
|
||||
James Gerity
|
||||
James Polley
|
||||
Jan Pokorný
|
||||
Jannis Leidel
|
||||
Jarek Potiuk
|
||||
jarondl
|
||||
Jason Curtis
|
||||
Jason R. Coombs
|
||||
Jay Graves
|
||||
Jean-Christophe Fillion-Robin
|
||||
|
@ -308,6 +338,7 @@ Jesse Rittner
|
|||
Jiashuo Li
|
||||
Jim Fisher
|
||||
Jim Garrison
|
||||
Jiun Bae
|
||||
Jivan Amara
|
||||
Joe Michelini
|
||||
John Paton
|
||||
|
@ -319,6 +350,7 @@ Jon Dufresne
|
|||
Jon Parise
|
||||
Jonas Nockert
|
||||
Jonathan Herbert
|
||||
Joonatan Partanen
|
||||
Joost Molenaar
|
||||
Jorge Niedbalski
|
||||
Joseph Bylund
|
||||
|
@ -327,6 +359,7 @@ Josh Bronson
|
|||
Josh Hansen
|
||||
Josh Schneier
|
||||
Juanjo Bazán
|
||||
Judah Rand
|
||||
Julian Berman
|
||||
Julian Gethmann
|
||||
Julien Demoor
|
||||
|
@ -334,7 +367,9 @@ Jussi Kukkonen
|
|||
jwg4
|
||||
Jyrki Pulliainen
|
||||
Kai Chen
|
||||
Kai Mueller
|
||||
Kamal Bin Mustafa
|
||||
kasium
|
||||
kaustav haldar
|
||||
keanemind
|
||||
Keith Maxwell
|
||||
|
@ -359,6 +394,7 @@ Laurent Bristiel
|
|||
Laurent LAPORTE
|
||||
Laurie O
|
||||
Laurie Opperman
|
||||
layday
|
||||
Leon Sasson
|
||||
Lev Givon
|
||||
Lincoln de Sousa
|
||||
|
@ -366,11 +402,13 @@ Lipis
|
|||
Loren Carvalho
|
||||
Lucas Cimon
|
||||
Ludovic Gasc
|
||||
Lukas Juhrich
|
||||
Luke Macken
|
||||
Luo Jiebin
|
||||
luojiebin
|
||||
luz.paz
|
||||
László Kiss Kollár
|
||||
M00nL1ght
|
||||
Marc Abramowitz
|
||||
Marc Tamlyn
|
||||
Marcus Smith
|
||||
|
@ -378,6 +416,8 @@ Mariatta
|
|||
Mark Kohler
|
||||
Mark Williams
|
||||
Markus Hametner
|
||||
Martey Dodoo
|
||||
Martin Fischer
|
||||
Martin Häcker
|
||||
Martin Pavlasek
|
||||
Masaki
|
||||
|
@ -385,6 +425,8 @@ Masklinn
|
|||
Matej Stuchlik
|
||||
Mathew Jennings
|
||||
Mathieu Bridon
|
||||
Mathieu Kniewallner
|
||||
Matt Bacchi
|
||||
Matt Good
|
||||
Matt Maker
|
||||
Matt Robenolt
|
||||
|
@ -396,6 +438,7 @@ Matthew Trumbell
|
|||
Matthew Willson
|
||||
Matthias Bussonnier
|
||||
mattip
|
||||
Maurits van Rees
|
||||
Max W Chase
|
||||
Maxim Kurnikov
|
||||
Maxime Rouyrre
|
||||
|
@ -410,6 +453,7 @@ Michael E. Karpeles
|
|||
Michael Klich
|
||||
Michael Williamson
|
||||
michaelpacer
|
||||
Michał Górny
|
||||
Mickaël Schoentgen
|
||||
Miguel Araujo Perez
|
||||
Mihir Singh
|
||||
|
@ -421,7 +465,12 @@ Miro Hrončok
|
|||
Monica Baluna
|
||||
montefra
|
||||
Monty Taylor
|
||||
Muha Ajjan
|
||||
Nadav Wexler
|
||||
Nahuel Ambrosini
|
||||
Nate Coraor
|
||||
Nate Prewitt
|
||||
Nathan Houghton
|
||||
Nathaniel J. Smith
|
||||
Nehal J Wani
|
||||
Neil Botelho
|
||||
|
@ -444,8 +493,9 @@ Nowell Strite
|
|||
NtaleGrey
|
||||
nvdv
|
||||
OBITORASU
|
||||
Ofekmeister
|
||||
Ofek Lev
|
||||
ofrinevo
|
||||
Oliver Freund
|
||||
Oliver Jeeves
|
||||
Oliver Mannion
|
||||
Oliver Tonnhofer
|
||||
|
@ -473,6 +523,7 @@ Paulus Schoutsen
|
|||
Pavel Safronov
|
||||
Pavithra Eswaramoorthy
|
||||
Pawel Jasinski
|
||||
Paweł Szramowski
|
||||
Pekka Klärck
|
||||
Peter Gessler
|
||||
Peter Lisák
|
||||
|
@ -499,6 +550,7 @@ Preet Thakkar
|
|||
Preston Holmes
|
||||
Przemek Wrzos
|
||||
Pulkit Goyal
|
||||
q0w
|
||||
Qiangning Hong
|
||||
Quentin Lee
|
||||
Quentin Pradet
|
||||
|
@ -511,9 +563,11 @@ Reece Dunham
|
|||
Remi Rampin
|
||||
Rene Dudfield
|
||||
Riccardo Magliocchetti
|
||||
Riccardo Schirone
|
||||
Richard Jones
|
||||
Richard Si
|
||||
Ricky Ng-Adam
|
||||
Rishi
|
||||
RobberPhex
|
||||
Robert Collins
|
||||
Robert McGibbon
|
||||
|
@ -523,15 +577,18 @@ Roey Berman
|
|||
Rohan Jain
|
||||
Roman Bogorodskiy
|
||||
Romuald Brunet
|
||||
ronaudinho
|
||||
Ronny Pfannschmidt
|
||||
Rory McCann
|
||||
Ross Brattain
|
||||
Roy Wellington Ⅳ
|
||||
Ruairidh MacLeod
|
||||
Russell Keith-Magee
|
||||
Ryan Wooden
|
||||
ryneeverett
|
||||
Sachi King
|
||||
Salvatore Rinchiera
|
||||
sandeepkiran-js
|
||||
Savio Jomton
|
||||
schlamar
|
||||
Scott Kitterman
|
||||
|
@ -542,8 +599,10 @@ Sebastian Schaetz
|
|||
Segev Finer
|
||||
SeongSoo Cho
|
||||
Sergey Vasilyev
|
||||
Seth Michael Larson
|
||||
Seth Woodworth
|
||||
shireenrao
|
||||
Shivansh-007
|
||||
Shlomi Fish
|
||||
Shovan Maity
|
||||
Simeon Visser
|
||||
|
@ -559,6 +618,7 @@ Stavros Korokithakis
|
|||
Stefan Scherfke
|
||||
Stefano Rivera
|
||||
Stephan Erb
|
||||
Stephen Rosen
|
||||
stepshal
|
||||
Steve (Gadget) Barnes
|
||||
Steve Barnes
|
||||
|
@ -577,6 +637,7 @@ Sylvain
|
|||
Takayuki SHIMIZUKAWA
|
||||
Taneli Hukkinen
|
||||
tbeswick
|
||||
Thiago
|
||||
Thijs Triemstra
|
||||
Thomas Fenzl
|
||||
Thomas Grainger
|
||||
|
@ -584,6 +645,7 @@ Thomas Guettler
|
|||
Thomas Johansson
|
||||
Thomas Kluyver
|
||||
Thomas Smith
|
||||
Thomas VINCENT
|
||||
Tim D. Smith
|
||||
Tim Gates
|
||||
Tim Harder
|
||||
|
@ -596,13 +658,17 @@ Tom V
|
|||
Tomas Hrnciar
|
||||
Tomas Orsava
|
||||
Tomer Chachamu
|
||||
Tommi Enenkel | AnB
|
||||
Tomáš Hrnčiar
|
||||
Tony Beswick
|
||||
Tony Narlock
|
||||
Tony Zhaocheng Tan
|
||||
TonyBeswick
|
||||
toonarmycaptain
|
||||
Toshio Kuratomi
|
||||
toxinu
|
||||
Travis Swicegood
|
||||
Tushar Sadhwani
|
||||
Tzu-ping Chung
|
||||
Valentin Haenel
|
||||
Victor Stinner
|
||||
|
@ -621,6 +687,7 @@ Wil Tan
|
|||
Wilfred Hughes
|
||||
William ML Leslie
|
||||
William T Olson
|
||||
William Woodruff
|
||||
Wilson Mo
|
||||
wim glenn
|
||||
Winson Luk
|
||||
|
@ -635,10 +702,12 @@ Yeray Diaz Diaz
|
|||
Yoval P
|
||||
Yu Jian
|
||||
Yuan Jing Vincent Yan
|
||||
Yusuke Hayashi
|
||||
Zearin
|
||||
Zhiping Deng
|
||||
ziebam
|
||||
Zvezdan Petkovic
|
||||
Łukasz Langa
|
||||
Роман Донченко
|
||||
Семён Марьясин
|
||||
rekcäH nitraM
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2008-2021 The pip developers (see AUTHORS.txt file)
|
||||
Copyright (c) 2008-present The pip developers (see AUTHORS.txt file)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
|
|
@ -2,10 +2,12 @@ include AUTHORS.txt
|
|||
include LICENSE.txt
|
||||
include NEWS.rst
|
||||
include README.rst
|
||||
include SECURITY.md
|
||||
include pyproject.toml
|
||||
|
||||
include src/pip/_vendor/README.rst
|
||||
include src/pip/_vendor/vendor.txt
|
||||
include src/pip/_vendor/pyparsing/diagram/template.jinja2
|
||||
recursive-include src/pip/_vendor *LICENSE*
|
||||
recursive-include src/pip/_vendor *COPYING*
|
||||
|
||||
|
@ -17,12 +19,14 @@ exclude .mailmap
|
|||
exclude .appveyor.yml
|
||||
exclude .readthedocs.yml
|
||||
exclude .pre-commit-config.yaml
|
||||
exclude .readthedocs-custom-redirects.yml
|
||||
exclude tox.ini
|
||||
exclude noxfile.py
|
||||
|
||||
recursive-include src/pip/_vendor *.pem
|
||||
recursive-include src/pip/_vendor py.typed
|
||||
recursive-include docs *.css *.py *.rst *.md
|
||||
recursive-include docs *.dot *.png
|
||||
|
||||
exclude src/pip/_vendor/six
|
||||
exclude src/pip/_vendor/six/moves
|
||||
|
|
498
NEWS.rst
498
NEWS.rst
|
@ -9,6 +9,504 @@
|
|||
|
||||
.. towncrier release notes start
|
||||
|
||||
23.0.1 (2023-02-17)
|
||||
===================
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Ignore PIP_REQUIRE_VIRTUALENV for ``pip index`` (`#11671 <https://github.com/pypa/pip/issues/11671>`_)
|
||||
- Implement ``--break-system-packages`` to permit installing packages into
|
||||
``EXTERNALLY-MANAGED`` Python installations. (`#11780 <https://github.com/pypa/pip/issues/11780>`_)
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Improve handling of isolated build environments on platforms that
|
||||
customize the Python's installation schemes, such as Debian and
|
||||
Homebrew. (`#11740 <https://github.com/pypa/pip/issues/11740>`_)
|
||||
- Do not crash in presence of misformatted hash field in ``direct_url.json``. (`#11773 <https://github.com/pypa/pip/issues/11773>`_)
|
||||
|
||||
|
||||
23.0 (2023-01-30)
|
||||
=================
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Change the hashes in the installation report to be a mapping. Emit the
|
||||
``archive_info.hashes`` dictionary in ``direct_url.json``. (`#11312 <https://github.com/pypa/pip/issues/11312>`_)
|
||||
- Implement logic to read the ``EXTERNALLY-MANAGED`` file as specified in PEP 668.
|
||||
This allows a downstream Python distributor to prevent users from using pip to
|
||||
modify the externally managed environment. (`#11381 <https://github.com/pypa/pip/issues/11381>`_)
|
||||
- Enable the use of ``keyring`` found on ``PATH``. This allows ``keyring``
|
||||
installed using ``pipx`` to be used by ``pip``. (`#11589 <https://github.com/pypa/pip/issues/11589>`_)
|
||||
- The inspect and installation report formats are now declared stable, and their version
|
||||
has been bumped from ``0`` to ``1``. (`#11757 <https://github.com/pypa/pip/issues/11757>`_)
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Wheel cache behavior is restored to match previous versions, allowing the
|
||||
cache to find existing entries. (`#11527 <https://github.com/pypa/pip/issues/11527>`_)
|
||||
- Use the "venv" scheme if available to obtain prefixed lib paths. (`#11598 <https://github.com/pypa/pip/issues/11598>`_)
|
||||
- Deprecated a historical ambiguity in how ``egg`` fragments in URL-style
|
||||
requirements are formatted and handled. ``egg`` fragments that do not look
|
||||
like PEP 508 names now produce a deprecation warning. (`#11617 <https://github.com/pypa/pip/issues/11617>`_)
|
||||
- Fix scripts path in isolated build environment on Debian. (`#11623 <https://github.com/pypa/pip/issues/11623>`_)
|
||||
- Make ``pip show`` show the editable location if package is editable (`#11638 <https://github.com/pypa/pip/issues/11638>`_)
|
||||
- Stop checking that ``wheel`` is present when ``build-system.requires``
|
||||
is provided without ``build-system.build-backend`` as ``setuptools``
|
||||
(which we still check for) will inject it anyway. (`#11673 <https://github.com/pypa/pip/issues/11673>`_)
|
||||
- Fix an issue when an already existing in-memory distribution would cause
|
||||
exceptions in ``pip install`` (`#11704 <https://github.com/pypa/pip/issues/11704>`_)
|
||||
|
||||
Vendored Libraries
|
||||
------------------
|
||||
|
||||
- Upgrade certifi to 2022.12.7
|
||||
- Upgrade chardet to 5.1.0
|
||||
- Upgrade colorama to 0.4.6
|
||||
- Upgrade distro to 1.8.0
|
||||
- Remove pep517 from vendored packages
|
||||
- Upgrade platformdirs to 2.6.2
|
||||
- Add pyproject-hooks 1.0.0
|
||||
- Upgrade requests to 2.28.2
|
||||
- Upgrade rich to 12.6.0
|
||||
- Upgrade urllib3 to 1.26.14
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Fixed the description of the option "--install-options" in the documentation (`#10265 <https://github.com/pypa/pip/issues/10265>`_)
|
||||
- Remove mention that editable installs are necessary for pip freeze to report the VCS
|
||||
URL. (`#11675 <https://github.com/pypa/pip/issues/11675>`_)
|
||||
- Clarify that the egg URL fragment is only necessary for editable VCS installs, and
|
||||
otherwise not necessary anymore. (`#11676 <https://github.com/pypa/pip/issues/11676>`_)
|
||||
|
||||
|
||||
22.3.1 (2022-11-05)
|
||||
===================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Fix entry point generation of ``pip.X``, ``pipX.Y``, and ``easy_install-X.Y``
|
||||
to correctly account for multi-digit Python version segments (e.g. the "11"
|
||||
part of 3.11). (`#11547 <https://github.com/pypa/pip/issues/11547>`_)
|
||||
|
||||
|
||||
22.3 (2022-10-15)
|
||||
=================
|
||||
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- Deprecate ``--install-options`` which forces pip to use the deprecated ``install``
|
||||
command of ``setuptools``. (`#11358 <https://github.com/pypa/pip/issues/11358>`_)
|
||||
- Deprecate installation with 'setup.py install' when no-binary is enabled for
|
||||
source distributions without 'pyproject.toml'. (`#11452 <https://github.com/pypa/pip/issues/11452>`_)
|
||||
- Deprecate ```--no-binary`` disabling the wheel cache. (`#11454 <https://github.com/pypa/pip/issues/11454>`_)
|
||||
- Remove ``--use-feature=2020-resolver`` opt-in flag. This was supposed to be removed in 21.0, but missed during that release cycle. (`#11493 <https://github.com/pypa/pip/issues/11493>`_)
|
||||
- Deprecate installation with 'setup.py install' when the 'wheel' package is absent for
|
||||
source distributions without 'pyproject.toml'. (`#8559 <https://github.com/pypa/pip/issues/8559>`_)
|
||||
- Remove the ability to use ``pip list --outdated`` in combination with ``--format=freeze``. (`#9789 <https://github.com/pypa/pip/issues/9789>`_)
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Use ``shell=True`` for opening the editor with ``pip config edit``. (`#10716 <https://github.com/pypa/pip/issues/10716>`_)
|
||||
- Use the ``data-dist-info-metadata`` attribute from :pep:`658` to resolve distribution metadata without downloading the dist yet. (`#11111 <https://github.com/pypa/pip/issues/11111>`_)
|
||||
- Add an option to run the test suite with pip built as a zipapp. (`#11250 <https://github.com/pypa/pip/issues/11250>`_)
|
||||
- Add a ``--python`` option to allow pip to manage Python environments other
|
||||
than the one pip is installed in. (`#11320 <https://github.com/pypa/pip/issues/11320>`_)
|
||||
- Document the new (experimental) zipapp distribution of pip. (`#11459 <https://github.com/pypa/pip/issues/11459>`_)
|
||||
- Use the much faster 'bzr co --lightweight' to obtain a copy of a Bazaar tree. (`#5444 <https://github.com/pypa/pip/issues/5444>`_)
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Fix ``--no-index`` when ``--index-url`` or ``--extra-index-url`` is specified
|
||||
inside a requirements file. (`#11276 <https://github.com/pypa/pip/issues/11276>`_)
|
||||
- Ensure that the candidate ``pip`` executable exists, when checking for a new version of pip. (`#11309 <https://github.com/pypa/pip/issues/11309>`_)
|
||||
- Ignore distributions with invalid ``Name`` in metadata instead of crashing, when
|
||||
using the ``importlib.metadata`` backend. (`#11352 <https://github.com/pypa/pip/issues/11352>`_)
|
||||
- Raise RequirementsFileParseError when parsing malformed requirements options that can't be successfully parsed by shlex. (`#11491 <https://github.com/pypa/pip/issues/11491>`_)
|
||||
- Fix build environment isolation on some system Pythons. (`#6264 <https://github.com/pypa/pip/issues/6264>`_)
|
||||
|
||||
Vendored Libraries
|
||||
------------------
|
||||
|
||||
- Upgrade certifi to 2022.9.24
|
||||
- Upgrade distlib to 0.3.6
|
||||
- Upgrade idna to 3.4
|
||||
- Upgrade pep517 to 0.13.0
|
||||
- Upgrade pygments to 2.13.0
|
||||
- Upgrade tenacity to 8.1.0
|
||||
- Upgrade typing_extensions to 4.4.0
|
||||
- Upgrade urllib3 to 1.26.12
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Mention that --quiet must be used when writing the installation report to stdout. (`#11357 <https://github.com/pypa/pip/issues/11357>`_)
|
||||
|
||||
|
||||
22.2.2 (2022-08-03)
|
||||
===================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Avoid ``AttributeError`` when removing the setuptools-provided ``_distutils_hack`` and it is missing its implementation. (`#11314 <https://github.com/pypa/pip/issues/11314>`_)
|
||||
- Fix import error when reinstalling pip in user site. (`#11319 <https://github.com/pypa/pip/issues/11319>`_)
|
||||
- Show pip deprecation warnings by default. (`#11330 <https://github.com/pypa/pip/issues/11330>`_)
|
||||
|
||||
|
||||
22.2.1 (2022-07-27)
|
||||
===================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Send the pip upgrade prompt to stderr. (`#11282 <https://github.com/pypa/pip/issues/11282>`_)
|
||||
- Ensure that things work correctly in environments where setuptools-injected
|
||||
``distutils`` is available by default. This is done by cooperating with
|
||||
setuptools' injection logic to ensure that pip uses the ``distutils`` from the
|
||||
Python standard library instead. (`#11298 <https://github.com/pypa/pip/issues/11298>`_)
|
||||
- Clarify that ``pip cache``'s wheels-related output is about locally built wheels only. (`#11300 <https://github.com/pypa/pip/issues/11300>`_)
|
||||
|
||||
|
||||
22.2 (2022-07-21)
|
||||
=================
|
||||
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- Remove the ``html5lib`` deprecated feature flag. (`#10825 <https://github.com/pypa/pip/issues/10825>`_)
|
||||
- Remove ``--use-deprecated=backtrack-on-build-failures``. (`#11241 <https://github.com/pypa/pip/issues/11241>`_)
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Add support to use `truststore <https://pypi.org/project/truststore/>`_ as an
|
||||
alternative SSL certificate verification backend. The backend can be enabled on Python
|
||||
3.10 and later by installing ``truststore`` into the environment, and adding the
|
||||
``--use-feature=truststore`` flag to various pip commands.
|
||||
|
||||
``truststore`` differs from the current default verification backend (provided by
|
||||
``certifi``) in it uses the operating system’s trust store, which can be better
|
||||
controlled and augmented to better support non-standard certificates. Depending on
|
||||
feedback, pip may switch to this as the default certificate verification backend in
|
||||
the future. (`#11082 <https://github.com/pypa/pip/issues/11082>`_)
|
||||
- Add ``--dry-run`` option to ``pip install``, to let it print what it would install but
|
||||
not actually change anything in the target environment. (`#11096 <https://github.com/pypa/pip/issues/11096>`_)
|
||||
- Record in wheel cache entries the URL of the original artifact that was downloaded
|
||||
to build the cached wheels. The record is named ``origin.json`` and uses the PEP 610
|
||||
Direct URL format. (`#11137 <https://github.com/pypa/pip/issues/11137>`_)
|
||||
- Support `PEP 691 <https://peps.python.org/pep-0691/>`_. (`#11158 <https://github.com/pypa/pip/issues/11158>`_)
|
||||
- pip's deprecation warnings now subclass the built-in ``DeprecationWarning``, and
|
||||
can be suppressed by running the Python interpreter with
|
||||
``-W ignore::DeprecationWarning``. (`#11225 <https://github.com/pypa/pip/issues/11225>`_)
|
||||
- Add ``pip inspect`` command to obtain the list of installed distributions and other
|
||||
information about the Python environment, in JSON format. (`#11245 <https://github.com/pypa/pip/issues/11245>`_)
|
||||
- Significantly speed up isolated environment creation, by using the same
|
||||
sources for pip instead of creating a standalone installation for each
|
||||
environment. (`#11257 <https://github.com/pypa/pip/issues/11257>`_)
|
||||
- Add an experimental ``--report`` option to the install command to generate a JSON report
|
||||
of what was installed. In combination with ``--dry-run`` and ``--ignore-installed`` it
|
||||
can be used to resolve the requirements. (`#53 <https://github.com/pypa/pip/issues/53>`_)
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Fix ``pip install --pre`` for packages with pre-release build dependencies defined
|
||||
both in ``pyproject.toml``'s ``build-system.requires`` and ``setup.py``'s
|
||||
``setup_requires``. (`#10222 <https://github.com/pypa/pip/issues/10222>`_)
|
||||
- When pip rewrites the shebang line in a script during wheel installation,
|
||||
update the hash and size in the corresponding ``RECORD`` file entry. (`#10744 <https://github.com/pypa/pip/issues/10744>`_)
|
||||
- Do not consider a ``.dist-info`` directory found inside a wheel-like zip file
|
||||
as metadata for an installed distribution. A package in a wheel is (by
|
||||
definition) not installed, and is not guaranteed to work due to how a wheel is
|
||||
structured. (`#11217 <https://github.com/pypa/pip/issues/11217>`_)
|
||||
- Use ``importlib.resources`` to read the ``vendor.txt`` file in ``pip debug``.
|
||||
This makes the command safe for use from a zipapp. (`#11248 <https://github.com/pypa/pip/issues/11248>`_)
|
||||
- Make the ``--use-pep517`` option of the ``download`` command apply not just
|
||||
to the requirements specified on the command line, but to their dependencies,
|
||||
as well. (`#9523 <https://github.com/pypa/pip/issues/9523>`_)
|
||||
|
||||
Process
|
||||
-------
|
||||
|
||||
- Remove reliance on the stdlib cgi module, which is deprecated in Python 3.11.
|
||||
|
||||
Vendored Libraries
|
||||
------------------
|
||||
|
||||
- Remove html5lib.
|
||||
- Upgrade certifi to 2022.6.15
|
||||
- Upgrade chardet to 5.0.0
|
||||
- Upgrade colorama to 0.4.5
|
||||
- Upgrade distlib to 0.3.5
|
||||
- Upgrade msgpack to 1.0.4
|
||||
- Upgrade pygments to 2.12.0
|
||||
- Upgrade pyparsing to 3.0.9
|
||||
- Upgrade requests to 2.28.1
|
||||
- Upgrade rich to 12.5.1
|
||||
- Upgrade typing_extensions to 4.3.0
|
||||
- Upgrade urllib3 to 1.26.10
|
||||
|
||||
|
||||
22.1.2 (2022-05-31)
|
||||
===================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Revert `#10979 <https://github.com/pypa/pip/issues/10979>`_ since it introduced a regression in certain edge cases. (`#10979 <https://github.com/pypa/pip/issues/10979>`_)
|
||||
- Fix an incorrect assertion in the logging logic, that prevented the upgrade prompt from being presented. (`#11136 <https://github.com/pypa/pip/issues/11136>`_)
|
||||
|
||||
|
||||
22.1.1 (2022-05-20)
|
||||
===================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Properly filter out optional dependencies (i.e. extras) when checking build environment distributions. (`#11112 <https://github.com/pypa/pip/issues/11112>`_)
|
||||
- Change the build environment dependency checking to be opt-in. (`#11116 <https://github.com/pypa/pip/issues/11116>`_)
|
||||
- Allow using a pre-release version to satisfy a build requirement. This helps
|
||||
manually populated build environments to more accurately detect build-time
|
||||
requirement conflicts. (`#11123 <https://github.com/pypa/pip/issues/11123>`_)
|
||||
|
||||
|
||||
22.1 (2022-05-11)
|
||||
=================
|
||||
|
||||
Process
|
||||
-------
|
||||
|
||||
- Enable the ``importlib.metadata`` metadata implementation by default on
|
||||
Python 3.11 (or later). The environment variable ``_PIP_USE_IMPORTLIB_METADATA``
|
||||
can still be used to enable the implementation on 3.10 and earlier, or disable
|
||||
it on 3.11 (by setting it to ``0`` or ``false``).
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Revert `#9243 <https://github.com/pypa/pip/issues/9243>`_ since it introduced a regression in certain edge cases. (`#10962 <https://github.com/pypa/pip/issues/10962>`_)
|
||||
- Fix missing ``REQUESTED`` metadata when using URL constraints. (`#11079 <https://github.com/pypa/pip/issues/11079>`_)
|
||||
- ``pip config`` now normalizes names by converting underscores into dashes. (`#9330 <https://github.com/pypa/pip/issues/9330>`_)
|
||||
|
||||
|
||||
22.1b1 (2022-04-30)
|
||||
===================
|
||||
|
||||
Process
|
||||
-------
|
||||
|
||||
- Start migration of distribution metadata implementation from ``pkg_resources``
|
||||
to ``importlib.metadata``. The new implementation is currently not exposed in
|
||||
any user-facing way, but included in the code base for easier development.
|
||||
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- Drop ``--use-deprecated=out-of-tree-build``, according to deprecation message. (`#11001 <https://github.com/pypa/pip/issues/11001>`_)
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Add option to install and uninstall commands to opt-out from running-as-root warning. (`#10556 <https://github.com/pypa/pip/issues/10556>`_)
|
||||
- Include Project-URLs in ``pip show`` output. (`#10799 <https://github.com/pypa/pip/issues/10799>`_)
|
||||
- Improve error message when ``pip config edit`` is provided an editor that
|
||||
doesn't exist. (`#10812 <https://github.com/pypa/pip/issues/10812>`_)
|
||||
- Add a user interface for supplying config settings to build backends. (`#11059 <https://github.com/pypa/pip/issues/11059>`_)
|
||||
- Add support for Powershell autocompletion. (`#9024 <https://github.com/pypa/pip/issues/9024>`_)
|
||||
- Explains why specified version cannot be retrieved when *Requires-Python* is not satisfied. (`#9615 <https://github.com/pypa/pip/issues/9615>`_)
|
||||
- Validate build dependencies when using ``--no-build-isolation``. (`#9794 <https://github.com/pypa/pip/issues/9794>`_)
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Fix conditional checks to prevent ``pip.exe`` from trying to modify itself, on Windows. (`#10560 <https://github.com/pypa/pip/issues/10560>`_)
|
||||
- Fix uninstall editable from Windows junction link. (`#10696 <https://github.com/pypa/pip/issues/10696>`_)
|
||||
- Fallback to pyproject.toml-based builds if ``setup.py`` is present in a project, but ``setuptools`` cannot be imported. (`#10717 <https://github.com/pypa/pip/issues/10717>`_)
|
||||
- When checking for conflicts in the build environment, correctly skip requirements
|
||||
containing markers that do not match the current environment. (`#10883 <https://github.com/pypa/pip/issues/10883>`_)
|
||||
- Disable brotli import in vendored urllib3 so brotli could be uninstalled/upgraded by pip. (`#10950 <https://github.com/pypa/pip/issues/10950>`_)
|
||||
- Prioritize URL credentials over netrc. (`#10979 <https://github.com/pypa/pip/issues/10979>`_)
|
||||
- Filter available distributions using hash declarations from constraints files. (`#9243 <https://github.com/pypa/pip/issues/9243>`_)
|
||||
- Fix an error when trying to uninstall packages installed as editable from a network drive. (`#9452 <https://github.com/pypa/pip/issues/9452>`_)
|
||||
- Fix pip install issues using a proxy due to an inconsistency in how Requests is currently handling variable precedence in session. (`#9691 <https://github.com/pypa/pip/issues/9691>`_)
|
||||
|
||||
Vendored Libraries
|
||||
------------------
|
||||
|
||||
- Upgrade CacheControl to 0.12.11
|
||||
- Upgrade distro to 1.7.0
|
||||
- Upgrade platformdirs to 2.5.2
|
||||
- Remove ``progress`` from vendored dependencies.
|
||||
- Upgrade ``pyparsing`` to 3.0.8 for startup performance improvements.
|
||||
- Upgrade rich to 12.2.0
|
||||
- Upgrade tomli to 2.0.1
|
||||
- Upgrade typing_extensions to 4.2.0
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Add more dedicated topic and reference pages to the documentation. (`#10899 <https://github.com/pypa/pip/issues/10899>`_)
|
||||
- Capitalise Y as the default for "Proceed (y/n)?" when uninstalling. (`#10936 <https://github.com/pypa/pip/issues/10936>`_)
|
||||
- Add ``scheme://`` requirement to ``--proxy`` option's description (`#10951 <https://github.com/pypa/pip/issues/10951>`_)
|
||||
- The wheel command now references the build interface section instead of stating the legacy
|
||||
setuptools behavior as the default. (`#10972 <https://github.com/pypa/pip/issues/10972>`_)
|
||||
- Improved usefulness of ``pip config --help`` output. (`#11074 <https://github.com/pypa/pip/issues/11074>`_)
|
||||
|
||||
|
||||
22.0.4 (2022-03-06)
|
||||
===================
|
||||
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- Drop the doctype check, that presented a warning for index pages that use non-compliant HTML 5. (`#10903 <https://github.com/pypa/pip/issues/10903>`_)
|
||||
|
||||
Vendored Libraries
|
||||
------------------
|
||||
|
||||
- Downgrade distlib to 0.3.3.
|
||||
|
||||
|
||||
22.0.3 (2022-02-03)
|
||||
===================
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Print the exception via ``rich.traceback``, when running with ``--debug``. (`#10791 <https://github.com/pypa/pip/issues/10791>`_)
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Only calculate topological installation order, for packages that are going to be installed/upgraded.
|
||||
|
||||
This fixes an `AssertionError` that occurred when determining installation order, for a very specific combination of upgrading-already-installed-package + change of dependencies + fetching some packages from a package index. This combination was especially common in Read the Docs' builds. (`#10851 <https://github.com/pypa/pip/issues/10851>`_)
|
||||
- Use ``html.parser`` by default, instead of falling back to ``html5lib`` when ``--use-deprecated=html5lib`` is not passed. (`#10869 <https://github.com/pypa/pip/issues/10869>`_)
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Clarify that using per-requirement overrides disables the usage of wheels. (`#9674 <https://github.com/pypa/pip/issues/9674>`_)
|
||||
|
||||
|
||||
22.0.2 (2022-01-30)
|
||||
===================
|
||||
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- Instead of failing on index pages that use non-compliant HTML 5, print a deprecation warning and fall back to ``html5lib``-based parsing for now. This simplifies the migration for non-compliant index pages, by letting such indexes function with a warning. (`#10847 <https://github.com/pypa/pip/issues/10847>`_)
|
||||
|
||||
|
||||
22.0.1 (2022-01-30)
|
||||
===================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Accept lowercase ``<!doctype html>`` on index pages. (`#10844 <https://github.com/pypa/pip/issues/10844>`_)
|
||||
- Properly handle links parsed by html5lib, when using ``--use-deprecated=html5lib``. (`#10846 <https://github.com/pypa/pip/issues/10846>`_)
|
||||
|
||||
|
||||
22.0 (2022-01-29)
|
||||
=================
|
||||
|
||||
Process
|
||||
-------
|
||||
|
||||
- Completely replace :pypi:`tox` in our development workflow, with :pypi:`nox`.
|
||||
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- Deprecate alternative progress bar styles, leaving only ``on`` and ``off`` as available choices. (`#10462 <https://github.com/pypa/pip/issues/10462>`_)
|
||||
- Drop support for Python 3.6. (`#10641 <https://github.com/pypa/pip/issues/10641>`_)
|
||||
- Disable location mismatch warnings on Python versions prior to 3.10.
|
||||
|
||||
These warnings were helping identify potential issues as part of the sysconfig -> distutils transition, and we no longer need to rely on reports from older Python versions for information on the transition. (`#10840 <https://github.com/pypa/pip/issues/10840>`_)
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Changed ``PackageFinder`` to parse HTML documents using the stdlib :class:`html.parser.HTMLParser` class instead of the ``html5lib`` package.
|
||||
|
||||
For now, the deprecated ``html5lib`` code remains and can be used with the ``--use-deprecated=html5lib`` command line option. However, it will be removed in a future pip release. (`#10291 <https://github.com/pypa/pip/issues/10291>`_)
|
||||
- Utilise ``rich`` for presenting pip's default download progress bar. (`#10462 <https://github.com/pypa/pip/issues/10462>`_)
|
||||
- Present a better error message when an invalid wheel file is encountered, providing more context where the invalid wheel file is. (`#10535 <https://github.com/pypa/pip/issues/10535>`_)
|
||||
- Documents the ``--require-virtualenv`` flag for ``pip install``. (`#10588 <https://github.com/pypa/pip/issues/10588>`_)
|
||||
- ``pip install <tab>`` autocompletes paths. (`#10646 <https://github.com/pypa/pip/issues/10646>`_)
|
||||
- Allow Python distributors to opt-out from or opt-in to the ``sysconfig`` installation scheme backend by setting ``sysconfig._PIP_USE_SYSCONFIG`` to ``True`` or ``False``. (`#10647 <https://github.com/pypa/pip/issues/10647>`_)
|
||||
- Make it possible to deselect tests requiring cryptography package on systems where it cannot be installed. (`#10686 <https://github.com/pypa/pip/issues/10686>`_)
|
||||
- Start using Rich for presenting error messages in a consistent format. (`#10703 <https://github.com/pypa/pip/issues/10703>`_)
|
||||
- Improve presentation of errors from subprocesses. (`#10705 <https://github.com/pypa/pip/issues/10705>`_)
|
||||
- Forward pip's verbosity configuration to VCS tools to control their output accordingly. (`#8819 <https://github.com/pypa/pip/issues/8819>`_)
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Optimize installation order calculation to improve performance when installing requirements that form a complex dependency graph with a large amount of edges. (`#10557 <https://github.com/pypa/pip/issues/10557>`_)
|
||||
- When a package is requested by the user for upgrade, correctly identify that the extra-ed variant of that same package depended by another user-requested package is requesting the same package, and upgrade it accordingly. (`#10613 <https://github.com/pypa/pip/issues/10613>`_)
|
||||
- Prevent pip from installing yanked releases unless explicitly pinned via the ``==`` or ``===`` operators. (`#10617 <https://github.com/pypa/pip/issues/10617>`_)
|
||||
- Stop backtracking on build failures, by instead surfacing them to the user and aborting immediately. This behaviour provides more immediate feedback when a package cannot be built due to missing build dependencies or platform incompatibility. (`#10655 <https://github.com/pypa/pip/issues/10655>`_)
|
||||
- Silence ``Value for <location> does not match`` warning caused by an erroneous patch in Slackware-distributed Python 3.9. (`#10668 <https://github.com/pypa/pip/issues/10668>`_)
|
||||
- Fix an issue where pip did not consider dependencies with and without extras to be equal (`#9644 <https://github.com/pypa/pip/issues/9644>`_)
|
||||
|
||||
Vendored Libraries
|
||||
------------------
|
||||
|
||||
- Upgrade CacheControl to 0.12.10
|
||||
- Upgrade certifi to 2021.10.8
|
||||
- Upgrade distlib to 0.3.4
|
||||
- Upgrade idna to 3.3
|
||||
- Upgrade msgpack to 1.0.3
|
||||
- Upgrade packaging to 21.3
|
||||
- Upgrade platformdirs to 2.4.1
|
||||
- Add pygments 2.11.2 as a vendored dependency.
|
||||
- Tree-trim unused portions of vendored pygments, to reduce the distribution size.
|
||||
- Upgrade pyparsing to 3.0.7
|
||||
- Upgrade Requests to 2.27.1
|
||||
- Upgrade resolvelib to 0.8.1
|
||||
- Add rich 11.0.0 as a vendored dependency.
|
||||
- Tree-trim unused portions of vendored rich, to reduce the distribution size.
|
||||
- Add typing_extensions 4.0.1 as a vendored dependency.
|
||||
- Upgrade urllib3 to 1.26.8
|
||||
|
||||
|
||||
21.3.1 (2021-10-22)
|
||||
===================
|
||||
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
|
||||
- Always refuse installing or building projects that have no ``pyproject.toml`` nor
|
||||
``setup.py``. (`#10531 <https://github.com/pypa/pip/issues/10531>`_)
|
||||
- Tweak running-as-root detection, to check ``os.getuid`` if it exists, on Unix-y and non-Linux/non-MacOS machines. (`#10565 <https://github.com/pypa/pip/issues/10565>`_)
|
||||
- When installing projects with a ``pyproject.toml`` in editable mode, and the build
|
||||
backend does not support :pep:`660`, prepare metadata using
|
||||
``prepare_metadata_for_build_wheel`` instead of ``setup.py egg_info``. Also, refuse
|
||||
installing projects that only have a ``setup.cfg`` and no ``setup.py`` nor
|
||||
``pyproject.toml``. These restore the pre-21.3 behaviour. (`#10573 <https://github.com/pypa/pip/issues/10573>`_)
|
||||
- Restore compatibility of where configuration files are loaded from on MacOS (back to ``Library/Application Support/pip``, instead of ``Preferences/pip``). (`#10585 <https://github.com/pypa/pip/issues/10585>`_)
|
||||
|
||||
Vendored Libraries
|
||||
------------------
|
||||
|
||||
|
||||
- Upgrade pep517 to 0.12.0
|
||||
|
||||
|
||||
21.3 (2021-10-11)
|
||||
=================
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ If you want to get involved head over to GitHub to get the source code, look at
|
|||
|
||||
* `GitHub page`_
|
||||
* `Development documentation`_
|
||||
* `Development mailing list`_
|
||||
* `Development IRC`_
|
||||
|
||||
Code of Conduct
|
||||
|
@ -56,7 +55,6 @@ rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.
|
|||
.. _Python 2 support policy: https://pip.pypa.io/en/latest/development/release-process/#python-2-support
|
||||
.. _Issue tracking: https://github.com/pypa/pip/issues
|
||||
.. _Discourse channel: https://discuss.python.org/c/packaging
|
||||
.. _Development mailing list: https://mail.python.org/mailman3/lists/distutils-sig.python.org/
|
||||
.. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa
|
||||
.. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev
|
||||
.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md
|
||||
|
|
3
SECURITY.md
Normal file
3
SECURITY.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Security and Vulnerability Reporting
|
||||
|
||||
If you find any security issues, please report to [security@python.org](mailto:security@python.org)
|
|
@ -16,6 +16,7 @@ pip
|
|||
|
||||
pip_install
|
||||
pip_uninstall
|
||||
pip_inspect
|
||||
pip_list
|
||||
pip_show
|
||||
pip_freeze
|
||||
|
|
|
@ -71,12 +71,11 @@ when decision is needed.
|
|||
Rename the file or checkout to ``{name}{'.bak' * n}``, where n is some number
|
||||
of ``.bak`` extensions, such that the file didn't exist at some point.
|
||||
So the most recent backup will be the one with the largest number after ``.bak``.
|
||||
*(a)abort*
|
||||
*(a)bort*
|
||||
Abort pip and return non-zero exit status.
|
||||
|
||||
|
||||
Build System Interface
|
||||
======================
|
||||
.. _`2-build-system-interface`:
|
||||
.. rubric:: Build System Interface
|
||||
|
||||
This is now covered in :doc:`../reference/build-system/index`.
|
||||
|
||||
|
|
|
@ -43,7 +43,9 @@ match the constraint of the current interpreter (but not your target one), it
|
|||
is recommended to specify all of these options if you are specifying one of
|
||||
them. Generic dependencies (e.g. universal wheels, or dependencies with no
|
||||
platform, abi, or implementation constraints) will still match an over-
|
||||
constrained download requirement.
|
||||
constrained download requirement. If some of your dependencies are not
|
||||
available as binaries, you can build them manually for your target platform
|
||||
and let pip download know where to find them using ``--find-links``.
|
||||
|
||||
|
||||
|
||||
|
@ -79,7 +81,7 @@ Examples
|
|||
|
||||
#. Download a package and all of its dependencies with OSX specific interpreter constraints.
|
||||
This forces OSX 10.10 or lower compatibility. Since OSX deps are forward compatible,
|
||||
this will also match ``macosx-10_9_x86_64``, ``macosx-10_8_x86_64``, ``macosx-10_8_intel``,
|
||||
this will also match ``macosx_10_9_x86_64``, ``macosx_10_8_x86_64``, ``macosx_10_8_intel``,
|
||||
etc.
|
||||
It will also match deps with platform ``any``. Also force the interpreter version to ``27``
|
||||
(or more generic, i.e. ``2``) and implementation to ``cp`` (or more generic, i.e. ``py``).
|
||||
|
@ -90,7 +92,7 @@ Examples
|
|||
|
||||
python -m pip download \
|
||||
--only-binary=:all: \
|
||||
--platform macosx-10_10_x86_64 \
|
||||
--platform macosx_10_10_x86_64 \
|
||||
--python-version 27 \
|
||||
--implementation cp \
|
||||
SomePackage
|
||||
|
@ -101,7 +103,7 @@ Examples
|
|||
|
||||
py -m pip download ^
|
||||
--only-binary=:all: ^
|
||||
--platform macosx-10_10_x86_64 ^
|
||||
--platform macosx_10_10_x86_64 ^
|
||||
--python-version 27 ^
|
||||
--implementation cp ^
|
||||
SomePackage
|
||||
|
|
|
@ -84,7 +84,7 @@ This error occurs, for instance, when the command is installed only for another
|
|||
user, and the current user doesn't have the permission to execute the other
|
||||
user's command.
|
||||
|
||||
To solve that issue, you can try one of the followings:
|
||||
To solve that issue, you can try one of the following:
|
||||
|
||||
- Install the command for yourself (e.g. in your home directory).
|
||||
- Ask the system admin to allow this command for all users.
|
||||
|
|
33
docs/html/cli/pip_inspect.rst
Normal file
33
docs/html/cli/pip_inspect.rst
Normal file
|
@ -0,0 +1,33 @@
|
|||
.. _`pip inspect`:
|
||||
|
||||
===========
|
||||
pip inspect
|
||||
===========
|
||||
|
||||
.. versionadded:: 22.2
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
.. tab:: Unix/macOS
|
||||
|
||||
.. pip-command-usage:: inspect "python -m pip"
|
||||
|
||||
.. tab:: Windows
|
||||
|
||||
.. pip-command-usage:: inspect "py -m pip"
|
||||
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
.. pip-command-description:: inspect
|
||||
|
||||
The format of the JSON output is described in :doc:`../reference/inspect-report`.
|
||||
|
||||
|
||||
Options
|
||||
=======
|
||||
|
||||
.. pip-command-options:: inspect
|
|
@ -11,7 +11,7 @@ Usage
|
|||
|
||||
.. tab:: Unix/macOS
|
||||
|
||||
.. pip-command-usage:: install "python -m pip"
|
||||
.. pip-command-usage:: install 'python -m pip'
|
||||
|
||||
.. tab:: Windows
|
||||
|
||||
|
@ -79,6 +79,18 @@ for an exception regarding pre-release versions). Where more than one source of
|
|||
the chosen version is available, it is assumed that any source is acceptable
|
||||
(as otherwise the versions would differ).
|
||||
|
||||
Obtaining information about what was installed
|
||||
----------------------------------------------
|
||||
|
||||
The install command has a ``--report`` option that will generate a JSON report of what
|
||||
pip has installed. In combination with the ``--dry-run`` and ``--ignore-installed`` it
|
||||
can be used to *resolve* a set of requirements without actually installing them.
|
||||
|
||||
The report can be written to a file, or to standard output (using ``--report -`` in
|
||||
combination with ``--quiet``).
|
||||
|
||||
The format of the JSON report is described in :doc:`../reference/installation-report`.
|
||||
|
||||
Installation Order
|
||||
------------------
|
||||
|
||||
|
@ -148,94 +160,20 @@ profile:
|
|||
3. For whatever reason, they don't or won't declare their build dependencies using
|
||||
``setup_requires``.
|
||||
|
||||
|
||||
Requirements File Format
|
||||
------------------------
|
||||
.. _`0-requirements-file-format`:
|
||||
.. rubric:: Requirements File Format
|
||||
|
||||
This section has been moved to :doc:`../reference/requirements-file-format`.
|
||||
|
||||
.. _`Requirement Specifiers`:
|
||||
.. _`0-requirement-specifiers`:
|
||||
.. rubric:: Requirement Specifiers
|
||||
|
||||
Requirement Specifiers
|
||||
----------------------
|
||||
This section has been moved to :doc:`../reference/requirement-specifiers`.
|
||||
|
||||
pip supports installing from a package index using a :term:`requirement
|
||||
specifier <pypug:Requirement Specifier>`. Generally speaking, a requirement
|
||||
specifier is composed of a project name followed by optional :term:`version
|
||||
specifiers <pypug:Version Specifier>`. :pep:`508` contains a full specification
|
||||
of the format of a requirement. Since version 18.1 pip supports the
|
||||
``url_req``-form specification.
|
||||
|
||||
Some examples:
|
||||
|
||||
::
|
||||
|
||||
SomeProject
|
||||
SomeProject == 1.3
|
||||
SomeProject >=1.2,<2.0
|
||||
SomeProject[foo, bar]
|
||||
SomeProject~=1.4.2
|
||||
|
||||
Since version 6.0, pip also supports specifiers containing `environment markers
|
||||
<https://www.python.org/dev/peps/pep-0508/#environment-markers>`__ like so:
|
||||
|
||||
::
|
||||
|
||||
SomeProject ==5.4 ; python_version < '3.8'
|
||||
SomeProject; sys_platform == 'win32'
|
||||
|
||||
Since version 19.1, pip also supports `direct references
|
||||
<https://www.python.org/dev/peps/pep-0440/#direct-references>`__ like so:
|
||||
|
||||
::
|
||||
|
||||
SomeProject @ file:///somewhere/...
|
||||
|
||||
Environment markers are supported in the command line and in requirements files.
|
||||
|
||||
.. note::
|
||||
|
||||
Use quotes around specifiers in the shell when using ``>``, ``<``, or when
|
||||
using environment markers. Don't use quotes in requirement files. [1]_
|
||||
|
||||
|
||||
.. _`Per-requirement Overrides`:
|
||||
|
||||
Per-requirement Overrides
|
||||
-------------------------
|
||||
|
||||
Since version 7.0 pip supports controlling the command line options given to
|
||||
``setup.py`` via requirements files. This disables the use of wheels (cached or
|
||||
otherwise) for that package, as ``setup.py`` does not exist for wheels.
|
||||
|
||||
The ``--global-option`` and ``--install-option`` options are used to pass
|
||||
options to ``setup.py``. For example:
|
||||
|
||||
::
|
||||
|
||||
FooProject >= 1.2 --global-option="--no-user-cfg" \
|
||||
--install-option="--prefix='/usr/local'" \
|
||||
--install-option="--no-compile"
|
||||
|
||||
The above translates roughly into running FooProject's ``setup.py``
|
||||
script as:
|
||||
|
||||
::
|
||||
|
||||
python setup.py --no-user-cfg install --prefix='/usr/local' --no-compile
|
||||
|
||||
Note that the only way of giving more than one option to ``setup.py``
|
||||
is through multiple ``--global-option`` and ``--install-option``
|
||||
options, as shown in the example above. The value of each option is
|
||||
passed as a single argument to the ``setup.py`` script. Therefore, a
|
||||
line such as the following is invalid and would result in an
|
||||
installation error.
|
||||
|
||||
::
|
||||
|
||||
# Invalid. Please use '--install-option' twice as shown above.
|
||||
FooProject >= 1.2 --install-option="--prefix=/usr/local --no-compile"
|
||||
.. _`0-per-requirement-overrides`:
|
||||
.. rubric:: Per-requirement Overrides
|
||||
|
||||
This is now covered in :doc:`../reference/requirements-file-format`.
|
||||
|
||||
.. _`Pre Release Versions`:
|
||||
|
||||
|
@ -256,11 +194,8 @@ that enables installation of pre-releases and development releases.
|
|||
|
||||
.. _pre-releases: https://www.python.org/dev/peps/pep-0440/#handling-of-pre-releases
|
||||
|
||||
|
||||
.. _`VCS Support`:
|
||||
|
||||
VCS Support
|
||||
-----------
|
||||
.. _`0-vcs-support`:
|
||||
.. rubric:: VCS Support
|
||||
|
||||
This is now covered in :doc:`../topics/vcs-support`.
|
||||
|
||||
|
@ -284,270 +219,43 @@ details) is selected.
|
|||
|
||||
See the :ref:`pip install Examples<pip install Examples>`.
|
||||
|
||||
.. _`0-ssl certificate verification`:
|
||||
.. rubric:: SSL Certificate Verification
|
||||
|
||||
.. _`SSL Certificate Verification`:
|
||||
This is now covered in :doc:`../topics/https-certificates`.
|
||||
|
||||
SSL Certificate Verification
|
||||
----------------------------
|
||||
|
||||
Starting with v1.3, pip provides SSL certificate verification over HTTP, to
|
||||
prevent man-in-the-middle attacks against PyPI downloads. This does not use
|
||||
the system certificate store but instead uses a bundled CA certificate
|
||||
store. The default bundled CA certificate store certificate store may be
|
||||
overridden by using ``--cert`` option or by using ``PIP_CERT``,
|
||||
``REQUESTS_CA_BUNDLE``, or ``CURL_CA_BUNDLE`` environment variables.
|
||||
|
||||
|
||||
.. _`Caching`:
|
||||
|
||||
Caching
|
||||
-------
|
||||
.. _`0-caching`:
|
||||
.. rubric:: Caching
|
||||
|
||||
This is now covered in :doc:`../topics/caching`.
|
||||
|
||||
.. _`Wheel cache`:
|
||||
|
||||
Wheel Cache
|
||||
^^^^^^^^^^^
|
||||
.. _`0-wheel-cache`:
|
||||
.. rubric:: Wheel Cache
|
||||
|
||||
This is now covered in :doc:`../topics/caching`.
|
||||
|
||||
.. _`hash-checking mode`:
|
||||
.. _`0-hash-checking-mode`:
|
||||
.. rubric:: Hash checking mode
|
||||
|
||||
Hash-Checking Mode
|
||||
------------------
|
||||
This is now covered in :doc:`../topics/secure-installs`.
|
||||
|
||||
Since version 8.0, pip can check downloaded package archives against local
|
||||
hashes to protect against remote tampering. To verify a package against one or
|
||||
more hashes, add them to the end of the line::
|
||||
.. _`0-local-project-installs`:
|
||||
.. rubric:: Local Project Installs
|
||||
|
||||
FooProject == 1.2 --hash=sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 \
|
||||
--hash=sha256:486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7
|
||||
This is now covered in :doc:`../topics/local-project-installs`.
|
||||
|
||||
(The ability to use multiple hashes is important when a package has both
|
||||
binary and source distributions or when it offers binary distributions for a
|
||||
variety of platforms.)
|
||||
.. _`0-editable-installs`:
|
||||
.. rubric:: Editable installs
|
||||
|
||||
The recommended hash algorithm at the moment is sha256, but stronger ones are
|
||||
allowed, including all those supported by ``hashlib``. However, weaker ones
|
||||
such as md5, sha1, and sha224 are excluded to avoid giving a false sense of
|
||||
security.
|
||||
This is now covered in :doc:`../topics/local-project-installs`.
|
||||
|
||||
Hash verification is an all-or-nothing proposition. Specifying a ``--hash``
|
||||
against any requirement not only checks that hash but also activates a global
|
||||
*hash-checking mode*, which imposes several other security restrictions:
|
||||
|
||||
* Hashes are required for all requirements. This is because a partially-hashed
|
||||
requirements file is of little use and thus likely an error: a malicious
|
||||
actor could slip bad code into the installation via one of the unhashed
|
||||
requirements. Note that hashes embedded in URL-style requirements via the
|
||||
``#md5=...`` syntax suffice to satisfy this rule (regardless of hash
|
||||
strength, for legacy reasons), though you should use a stronger
|
||||
hash like sha256 whenever possible.
|
||||
* Hashes are required for all dependencies. An error results if there is a
|
||||
dependency that is not spelled out and hashed in the requirements file.
|
||||
* Requirements that take the form of project names (rather than URLs or local
|
||||
filesystem paths) must be pinned to a specific version using ``==``. This
|
||||
prevents a surprising hash mismatch upon the release of a new version
|
||||
that matches the requirement specifier.
|
||||
* ``--egg`` is disallowed, because it delegates installation of dependencies
|
||||
to setuptools, giving up pip's ability to enforce any of the above.
|
||||
|
||||
.. _`--require-hashes`:
|
||||
|
||||
Hash-checking mode can be forced on with the ``--require-hashes`` command-line
|
||||
option:
|
||||
|
||||
.. tab:: Unix/macOS
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ python -m pip install --require-hashes -r requirements.txt
|
||||
...
|
||||
Hashes are required in --require-hashes mode (implicitly on when a hash is
|
||||
specified for any package). These requirements were missing hashes,
|
||||
leaving them open to tampering. These are the hashes the downloaded
|
||||
archives actually had. You can add lines like these to your requirements
|
||||
files to prevent tampering.
|
||||
pyelasticsearch==1.0 --hash=sha256:44ddfb1225054d7d6b1d02e9338e7d4809be94edbe9929a2ec0807d38df993fa
|
||||
more-itertools==2.2 --hash=sha256:93e62e05c7ad3da1a233def6731e8285156701e3419a5fe279017c429ec67ce0
|
||||
|
||||
.. tab:: Windows
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
C:\> py -m pip install --require-hashes -r requirements.txt
|
||||
...
|
||||
Hashes are required in --require-hashes mode (implicitly on when a hash is
|
||||
specified for any package). These requirements were missing hashes,
|
||||
leaving them open to tampering. These are the hashes the downloaded
|
||||
archives actually had. You can add lines like these to your requirements
|
||||
files to prevent tampering.
|
||||
pyelasticsearch==1.0 --hash=sha256:44ddfb1225054d7d6b1d02e9338e7d4809be94edbe9929a2ec0807d38df993fa
|
||||
more-itertools==2.2 --hash=sha256:93e62e05c7ad3da1a233def6731e8285156701e3419a5fe279017c429ec67ce0
|
||||
|
||||
|
||||
This can be useful in deploy scripts, to ensure that the author of the
|
||||
requirements file provided hashes. It is also a convenient way to bootstrap
|
||||
your list of hashes, since it shows the hashes of the packages it fetched. It
|
||||
fetches only the preferred archive for each package, so you may still need to
|
||||
add hashes for alternatives archives using :ref:`pip hash`: for instance if
|
||||
there is both a binary and a source distribution.
|
||||
|
||||
The :ref:`wheel cache <Wheel cache>` is disabled in hash-checking mode to
|
||||
prevent spurious hash mismatch errors. These would otherwise occur while
|
||||
installing sdists that had already been automatically built into cached wheels:
|
||||
those wheels would be selected for installation, but their hashes would not
|
||||
match the sdist ones from the requirements file. A further complication is that
|
||||
locally built wheels are nondeterministic: contemporary modification times make
|
||||
their way into the archive, making hashes unpredictable across machines and
|
||||
cache flushes. Compilation of C code adds further nondeterminism, as many
|
||||
compilers include random-seeded values in their output. However, wheels fetched
|
||||
from index servers are the same every time. They land in pip's HTTP cache, not
|
||||
its wheel cache, and are used normally in hash-checking mode. The only downside
|
||||
of having the wheel cache disabled is thus extra build time for sdists, and
|
||||
this can be solved by making sure pre-built wheels are available from the index
|
||||
server.
|
||||
|
||||
Hash-checking mode also works with :ref:`pip download` and :ref:`pip wheel`.
|
||||
See :doc:`../topics/repeatable-installs` for a comparison of hash-checking mode
|
||||
with other repeatability strategies.
|
||||
|
||||
.. warning::
|
||||
|
||||
Beware of the ``setup_requires`` keyword arg in :file:`setup.py`. The
|
||||
(rare) packages that use it will cause those dependencies to be downloaded
|
||||
by setuptools directly, skipping pip's hash-checking. If you need to use
|
||||
such a package, see :ref:`Controlling
|
||||
setup_requires <controlling-setup_requires>`.
|
||||
|
||||
.. warning::
|
||||
|
||||
Be careful not to nullify all your security work when you install your
|
||||
actual project by using setuptools directly: for example, by calling
|
||||
``python setup.py install``, ``python setup.py develop``, or
|
||||
``easy_install``. Setuptools will happily go out and download, unchecked,
|
||||
anything you missed in your requirements file—and it’s easy to miss things
|
||||
as your project evolves. To be safe, install your project using pip and
|
||||
:ref:`--no-deps <install_--no-deps>`.
|
||||
|
||||
Instead of ``python setup.py develop``, use...
|
||||
|
||||
.. tab:: Unix/macOS
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
python -m pip install --no-deps -e .
|
||||
|
||||
.. tab:: Windows
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
py -m pip install --no-deps -e .
|
||||
|
||||
|
||||
Instead of ``python setup.py install``, use...
|
||||
|
||||
.. tab:: Unix/macOS
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
python -m pip install --no-deps .
|
||||
|
||||
.. tab:: Windows
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
py -m pip install --no-deps .
|
||||
|
||||
Hashes from PyPI
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
PyPI provides an MD5 hash in the fragment portion of each package download URL,
|
||||
like ``#md5=123...``, which pip checks as a protection against download
|
||||
corruption. Other hash algorithms that have guaranteed support from ``hashlib``
|
||||
are also supported here: sha1, sha224, sha384, sha256, and sha512. Since this
|
||||
hash originates remotely, it is not a useful guard against tampering and thus
|
||||
does not satisfy the ``--require-hashes`` demand that every package have a
|
||||
local hash.
|
||||
|
||||
|
||||
Local project installs
|
||||
----------------------
|
||||
|
||||
pip supports installing local project in both regular mode and editable mode.
|
||||
You can install local projects by specifying the project path to pip:
|
||||
|
||||
.. tab:: Unix/macOS
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
python -m pip install path/to/SomeProject
|
||||
|
||||
.. tab:: Windows
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
py -m pip install path/to/SomeProject
|
||||
|
||||
.. note::
|
||||
|
||||
Depending on the build backend used by the project, this may generate
|
||||
secondary build artifacts in the project directory, such as the
|
||||
``.egg-info`` and ``build`` directories in the case of the setuptools
|
||||
backend.
|
||||
|
||||
Pip has a legacy behaviour that copies the entire project directory to a
|
||||
temporary location and installs from there. This approach was the cause of
|
||||
several performance and correctness issues, so it is now disabled by
|
||||
default, and it is planned that pip 22.1 will remove it.
|
||||
|
||||
To opt in to the legacy behavior, specify the
|
||||
``--use-deprecated=out-of-tree-build`` option in pip's command line.
|
||||
|
||||
|
||||
.. _`editable-installs`:
|
||||
|
||||
"Editable" Installs
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
"Editable" installs are fundamentally `"setuptools develop mode"
|
||||
<https://setuptools.readthedocs.io/en/latest/userguide/development_mode.html>`_
|
||||
installs.
|
||||
|
||||
You can install local projects or VCS projects in "editable" mode:
|
||||
|
||||
.. tab:: Unix/macOS
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
python -m pip install -e path/to/SomeProject
|
||||
python -m pip install -e git+http://repo/my_project.git#egg=SomeProject
|
||||
|
||||
.. tab:: Windows
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
py -m pip install -e path/to/SomeProject
|
||||
py -m pip install -e git+http://repo/my_project.git#egg=SomeProject
|
||||
|
||||
|
||||
(See the :doc:`../topics/vcs-support` section above for more information on VCS-related syntax.)
|
||||
|
||||
For local projects, the "SomeProject.egg-info" directory is created relative to
|
||||
the project path. This is one advantage over just using ``setup.py develop``,
|
||||
which creates the "egg-info" directly relative the current working directory.
|
||||
|
||||
|
||||
Build System Interface
|
||||
----------------------
|
||||
.. _`0-build-system-interface`:
|
||||
.. rubric:: Build System Interface
|
||||
|
||||
This is now covered in :doc:`../reference/build-system/index`.
|
||||
|
||||
|
||||
.. _`pip install Options`:
|
||||
|
||||
|
||||
Options
|
||||
=======
|
||||
|
||||
|
@ -569,7 +277,7 @@ Examples
|
|||
.. code-block:: shell
|
||||
|
||||
python -m pip install SomePackage # latest version
|
||||
python -m pip install SomePackage==1.0.4 # specific version
|
||||
python -m pip install 'SomePackage==1.0.4' # specific version
|
||||
python -m pip install 'SomePackage>=1.0.4' # minimum version
|
||||
|
||||
.. tab:: Windows
|
||||
|
@ -577,8 +285,8 @@ Examples
|
|||
.. code-block:: shell
|
||||
|
||||
py -m pip install SomePackage # latest version
|
||||
py -m pip install SomePackage==1.0.4 # specific version
|
||||
py -m pip install 'SomePackage>=1.0.4' # minimum version
|
||||
py -m pip install "SomePackage==1.0.4" # specific version
|
||||
py -m pip install "SomePackage>=1.0.4" # minimum version
|
||||
|
||||
|
||||
#. Install a list of requirements specified in a file. See the :ref:`Requirements files <Requirements Files>`.
|
||||
|
@ -641,13 +349,13 @@ Examples
|
|||
|
||||
.. code-block:: shell
|
||||
|
||||
python -m pip install SomeProject@git+https://git.repo/some_pkg.git@1.3.1
|
||||
python -m pip install 'SomeProject@git+https://git.repo/some_pkg.git@1.3.1'
|
||||
|
||||
.. tab:: Windows
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
py -m pip install SomeProject@git+https://git.repo/some_pkg.git@1.3.1
|
||||
py -m pip install "SomeProject@git+https://git.repo/some_pkg.git@1.3.1"
|
||||
|
||||
|
||||
#. Install a project from VCS in "editable" mode. See the sections on :doc:`../topics/vcs-support` and :ref:`Editable Installs <editable-installs>`.
|
||||
|
@ -656,43 +364,43 @@ Examples
|
|||
|
||||
.. code-block:: shell
|
||||
|
||||
python -m pip install -e git+https://git.repo/some_pkg.git#egg=SomePackage # from git
|
||||
python -m pip install -e hg+https://hg.repo/some_pkg.git#egg=SomePackage # from mercurial
|
||||
python -m pip install -e svn+svn://svn.repo/some_pkg/trunk/#egg=SomePackage # from svn
|
||||
python -m pip install -e git+https://git.repo/some_pkg.git@feature#egg=SomePackage # from 'feature' branch
|
||||
python -m pip install -e "git+https://git.repo/some_repo.git#egg=subdir&subdirectory=subdir_path" # install a python package from a repo subdirectory
|
||||
python -m pip install -e 'git+https://git.repo/some_pkg.git#egg=SomePackage' # from git
|
||||
python -m pip install -e 'hg+https://hg.repo/some_pkg.git#egg=SomePackage' # from mercurial
|
||||
python -m pip install -e 'svn+svn://svn.repo/some_pkg/trunk/#egg=SomePackage' # from svn
|
||||
python -m pip install -e 'git+https://git.repo/some_pkg.git@feature#egg=SomePackage' # from 'feature' branch
|
||||
python -m pip install -e 'git+https://git.repo/some_repo.git#egg=subdir&subdirectory=subdir_path' # install a python package from a repo subdirectory
|
||||
|
||||
.. tab:: Windows
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
py -m pip install -e git+https://git.repo/some_pkg.git#egg=SomePackage # from git
|
||||
py -m pip install -e hg+https://hg.repo/some_pkg.git#egg=SomePackage # from mercurial
|
||||
py -m pip install -e svn+svn://svn.repo/some_pkg/trunk/#egg=SomePackage # from svn
|
||||
py -m pip install -e git+https://git.repo/some_pkg.git@feature#egg=SomePackage # from 'feature' branch
|
||||
py -m pip install -e "git+https://git.repo/some_pkg.git#egg=SomePackage" # from git
|
||||
py -m pip install -e "hg+https://hg.repo/some_pkg.git#egg=SomePackage" # from mercurial
|
||||
py -m pip install -e "svn+svn://svn.repo/some_pkg/trunk/#egg=SomePackage" # from svn
|
||||
py -m pip install -e "git+https://git.repo/some_pkg.git@feature#egg=SomePackage" # from 'feature' branch
|
||||
py -m pip install -e "git+https://git.repo/some_repo.git#egg=subdir&subdirectory=subdir_path" # install a python package from a repo subdirectory
|
||||
|
||||
#. Install a package with `setuptools extras`_.
|
||||
#. Install a package with `extras`_.
|
||||
|
||||
.. tab:: Unix/macOS
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
python -m pip install SomePackage[PDF]
|
||||
python -m pip install "SomePackage[PDF] @ git+https://git.repo/SomePackage@main#subdirectory=subdir_path"
|
||||
python -m pip install .[PDF] # project in current directory
|
||||
python -m pip install SomePackage[PDF]==3.0
|
||||
python -m pip install SomePackage[PDF,EPUB] # multiple extras
|
||||
python -m pip install 'SomePackage[PDF]'
|
||||
python -m pip install 'SomePackage[PDF] @ git+https://git.repo/SomePackage@main#subdirectory=subdir_path'
|
||||
python -m pip install '.[PDF]' # project in current directory
|
||||
python -m pip install 'SomePackage[PDF]==3.0'
|
||||
python -m pip install 'SomePackage[PDF,EPUB]' # multiple extras
|
||||
|
||||
.. tab:: Windows
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
py -m pip install SomePackage[PDF]
|
||||
py -m pip install "SomePackage[PDF]"
|
||||
py -m pip install "SomePackage[PDF] @ git+https://git.repo/SomePackage@main#subdirectory=subdir_path"
|
||||
py -m pip install .[PDF] # project in current directory
|
||||
py -m pip install SomePackage[PDF]==3.0
|
||||
py -m pip install SomePackage[PDF,EPUB] # multiple extras
|
||||
py -m pip install ".[PDF]" # project in current directory
|
||||
py -m pip install "SomePackage[PDF]==3.0"
|
||||
py -m pip install "SomePackage[PDF,EPUB]" # multiple extras
|
||||
|
||||
#. Install a particular source archive file.
|
||||
|
||||
|
@ -700,15 +408,15 @@ Examples
|
|||
|
||||
.. code-block:: shell
|
||||
|
||||
python -m pip install ./downloads/SomePackage-1.0.4.tar.gz
|
||||
python -m pip install http://my.package.repo/SomePackage-1.0.4.zip
|
||||
python -m pip install './downloads/SomePackage-1.0.4.tar.gz'
|
||||
python -m pip install 'http://my.package.repo/SomePackage-1.0.4.zip'
|
||||
|
||||
.. tab:: Windows
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
py -m pip install ./downloads/SomePackage-1.0.4.tar.gz
|
||||
py -m pip install http://my.package.repo/SomePackage-1.0.4.zip
|
||||
py -m pip install "./downloads/SomePackage-1.0.4.tar.gz"
|
||||
py -m pip install "http://my.package.repo/SomePackage-1.0.4.zip"
|
||||
|
||||
#. Install a particular source archive file following :pep:`440` direct references.
|
||||
|
||||
|
@ -716,17 +424,17 @@ Examples
|
|||
|
||||
.. code-block:: shell
|
||||
|
||||
python -m pip install SomeProject@http://my.package.repo/SomeProject-1.2.3-py33-none-any.whl
|
||||
python -m pip install "SomeProject @ http://my.package.repo/SomeProject-1.2.3-py33-none-any.whl"
|
||||
python -m pip install SomeProject@http://my.package.repo/1.2.3.tar.gz
|
||||
python -m pip install 'SomeProject@http://my.package.repo/SomeProject-1.2.3-py33-none-any.whl'
|
||||
python -m pip install 'SomeProject @ http://my.package.repo/SomeProject-1.2.3-py33-none-any.whl'
|
||||
python -m pip install 'SomeProject@http://my.package.repo/1.2.3.tar.gz'
|
||||
|
||||
.. tab:: Windows
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
py -m pip install SomeProject@http://my.package.repo/SomeProject-1.2.3-py33-none-any.whl
|
||||
py -m pip install "SomeProject@http://my.package.repo/SomeProject-1.2.3-py33-none-any.whl"
|
||||
py -m pip install "SomeProject @ http://my.package.repo/SomeProject-1.2.3-py33-none-any.whl"
|
||||
py -m pip install SomeProject@http://my.package.repo/1.2.3.tar.gz
|
||||
py -m pip install "SomeProject@http://my.package.repo/1.2.3.tar.gz"
|
||||
|
||||
#. Install from alternative package repositories.
|
||||
|
||||
|
@ -831,10 +539,5 @@ Examples
|
|||
|
||||
py -m pip install SomePackage1 SomePackage2 --no-binary SomePackage1
|
||||
|
||||
----
|
||||
|
||||
.. [1] This is true with the exception that pip v7.0 and v7.0.1 required quotes
|
||||
around specifiers containing environment markers in requirement files.
|
||||
|
||||
.. _setuptools extras: https://setuptools.readthedocs.io/en/latest/userguide/dependency_management.html#optional-dependencies
|
||||
.. _extras: https://www.python.org/dev/peps/pep-0508/#extras
|
||||
.. _PyPI: https://pypi.org/
|
||||
|
|
|
@ -226,6 +226,6 @@ The json format outputs an additional ``editable_project_location`` field.
|
|||
|
||||
.. note::
|
||||
|
||||
Contrary to the ``freeze`` comand, ``pip list --format=freeze`` will not
|
||||
Contrary to the ``freeze`` command, ``pip list --format=freeze`` will not
|
||||
report editable install information, but the version of the package at the
|
||||
time it was installed.
|
||||
|
|
|
@ -43,7 +43,7 @@ Examples
|
|||
Uninstalling simplejson:
|
||||
/home/me/env/lib/python3.9/site-packages/simplejson
|
||||
/home/me/env/lib/python3.9/site-packages/simplejson-2.2.1-py3.9.egg-info
|
||||
Proceed (y/n)? y
|
||||
Proceed (Y/n)? y
|
||||
Successfully uninstalled simplejson
|
||||
|
||||
.. tab:: Windows
|
||||
|
@ -54,5 +54,5 @@ Examples
|
|||
Uninstalling simplejson:
|
||||
/home/me/env/lib/python3.9/site-packages/simplejson
|
||||
/home/me/env/lib/python3.9/site-packages/simplejson-2.2.1-py3.9.egg-info
|
||||
Proceed (y/n)? y
|
||||
Proceed (Y/n)? y
|
||||
Successfully uninstalled simplejson
|
||||
|
|
|
@ -25,11 +25,19 @@ Description
|
|||
.. pip-command-description:: wheel
|
||||
|
||||
|
||||
Build System Interface
|
||||
----------------------
|
||||
.. _`1-build-system-interface`:
|
||||
.. rubric:: Build System Interface
|
||||
|
||||
This is now covered in :doc:`../reference/build-system/index`.
|
||||
|
||||
Differences to ``build``
|
||||
------------------------
|
||||
|
||||
`build <https://pypi.org/project/build/>`_ is a simple tool which can among other things build
|
||||
wheels for projects using PEP 517. It is comparable to the execution of ``pip wheel --no-deps .``.
|
||||
It can also build source distributions which is not possible with ``pip``.
|
||||
``pip wheel`` covers the wheel scope of ``build`` but offers many additional features.
|
||||
|
||||
Options
|
||||
=======
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ print("pip release:", release)
|
|||
# -- Options for myst-parser ----------------------------------------------------------
|
||||
|
||||
myst_enable_extensions = ["deflist"]
|
||||
myst_heading_anchors = 3
|
||||
|
||||
# -- Options for smartquotes ----------------------------------------------------------
|
||||
|
||||
|
|
|
@ -24,24 +24,23 @@ The ``README``, license, ``pyproject.toml``, ``setup.py``, and so on are in the
|
|||
* ``README.rst``
|
||||
* ``setup.cfg``
|
||||
* ``setup.py``
|
||||
* ``tox.ini`` -- ``pip`` uses Tox, an automation tool, configured by this `tox.ini`_ file. ``tox.ini`` describes a few environments ``pip`` uses during development for simplifying how tests are run (complicated situation there). Example: ``tox -e -py36``. We can run tests for different versions of Python by changing “36” to “27” or similar.
|
||||
* ``.coveragerc``
|
||||
* ``noxfile.py`` -- ``pip`` uses Nox, an automation tool, configured by this file. ``noxfile.py`` describes a few environments ``pip`` uses during development for simplifying how tests are run (complicated situation there). Example: ``nox -s lint``, ``nox -s test-3.10``. We can run tests for different versions of Python by changing “3.10” to “3.7” or similar.
|
||||
* ``.gitattributes``
|
||||
* ``.gitignore``
|
||||
* ``.mailmap``
|
||||
* ``.readthedocs.yml``
|
||||
* ``docs/`` *[documentation, built with Sphinx]*
|
||||
|
||||
* ``html/`` *[sources to HTML documentation avail. online]*
|
||||
* ``man/`` has man pages the distros can use by running ``man pip``
|
||||
* ``pip_sphinxext.py`` *[an extension -- pip-specific plugins to Sphinx that do not apply to other packages]*
|
||||
* ``requirements.txt``
|
||||
|
||||
* ``news/`` *[pip stores news fragments… Every time pip makes a user-facing change, a file is added to this directory (usually a short note referring to a GitHub issue) with the right extension & name so it gets included in changelog…. So every release the maintainers will be deleting old files in this directory? Yes - we use the towncrier automation to generate a NEWS file, and auto-delete old stuff. There’s more about this in the contributor documentation!]*
|
||||
|
||||
* ``template.rst`` *[template for changelog -- this is a file towncrier uses…. Is this jinja? I don’t know, check towncrier docs]*
|
||||
|
||||
* ``src/`` *[source; see below]*
|
||||
* ``tasks/`` *[invoke is a PyPI library which uses files in this directory to define automation commands that are used in pip’s development processes -- not discussing further right now. For instance, automating the release.]*
|
||||
* ``tools/`` *[misc development workflow tools, like requirements files & CI files & helpers. For instance, automating the release.]*
|
||||
* ``tests/`` -- contains tests you can run. There are instructions in :doc:`../getting-started`.
|
||||
|
||||
* ``__init__.py``
|
||||
|
@ -51,10 +50,7 @@ The ``README``, license, ``pyproject.toml``, ``setup.py``, and so on are in the
|
|||
* ``lib/`` *[helpers for tests]*
|
||||
* ``unit/`` *[unit tests -- fast and small and nice!]*
|
||||
|
||||
* ``tools`` *[misc development workflow tools, like requirements files & CI files & helpers for tox]*
|
||||
* ``.github``
|
||||
* ``.tox``
|
||||
|
||||
|
||||
|
||||
src directory
|
||||
|
@ -67,24 +63,23 @@ dependencies (code from other packages).
|
|||
|
||||
Within ``src/``:
|
||||
|
||||
* ``pip.egg-info/`` *[ignore the contents for now]*
|
||||
* ``pip/``
|
||||
|
||||
* ``__init__.py``
|
||||
* ``__main__.py``
|
||||
* ``__pycache__/`` *[not discussing contents right now]*
|
||||
* ``_internal/`` *[where all the pip code lives that’s written by pip maintainers -- underscore means private. pip is not a library -- it’s a command line tool! A very important distinction! People who want to install stuff with pip should not use the internals -- they should use the CLI. There’s a note on this in the docs.]*
|
||||
|
||||
* ``__init__.py``
|
||||
* ``build_env.py`` [not discussing now]
|
||||
* ``build_env.py``
|
||||
* ``cache.py`` *[has all the info for how to handle caching within pip -- cache-handling stuff. Uses cachecontrol from PyPI, vendored into pip]*
|
||||
* ``cli/`` *[subpackage containing helpers & additional code for managing the command line interface. Uses argparse from stdlib]*
|
||||
* ``commands/`` *[literally - each file is the name of the command on the pip CLI. Each has a class that defines what’s needed to set it up, what happens]*
|
||||
* ``configuration.py``
|
||||
* ``download.py``
|
||||
* ``exceptions.py``
|
||||
* ``index.py``
|
||||
* ``locations.py``
|
||||
* ``index/``
|
||||
* ``locations/``
|
||||
* ``main.py`` *[legacy entry point]*
|
||||
* ``models/`` *[in-process refactoring! Goal: improve how pip internally models representations it has for data -- data representation. General overall cleanup. Data reps are spread throughout codebase….link is defined in a class in 1 file, and then another file imports Link from that file. Sometimes cyclic dependency?!?! To prevent future situations like this, etc., Pradyun started moving these into a models directory.]*
|
||||
* ``operations/`` -- a bit of a weird directory….. ``Freeze.py`` used to be in there. Freeze is an operation -- there was an operations.freeze. Then “prepare” got added (the operation of preparing a pkg). Then “check” got added for checking the state of an env.] [what’s a command vs an operation? Command is on CLI; an operation would be an internal bit of code that actually does some subset of the operation the command says. ``install`` command uses bits of ``check`` and ``prepare``, for instance. In the long run, Pradyun’s goal: ``prepare.py`` goes away (gets refactored into other files) such that ``operations`` is just ``check`` and ``freeze``..... … Pradyun plans to refactor this. [how does this compare to ``utils``?]
|
||||
|
||||
|
@ -102,5 +97,4 @@ Within ``src/``:
|
|||
|
||||
.. _`tracking issue`: https://github.com/pypa/pip/issues/6831
|
||||
.. _GitHub repository: https://github.com/pypa/pip/
|
||||
.. _tox.ini: https://github.com/pypa/pip/blob/main/tox.ini
|
||||
.. _improving the pip dependency resolver: https://github.com/pypa/pip/issues/988
|
||||
|
|
|
@ -24,9 +24,9 @@ Things pip does:
|
|||
backwards compatibility reasons. But thing with setuptools:
|
||||
has a ``setup.py`` file that it invokes to …… get info?
|
||||
|
||||
2. Decides where to install stuff. Once the package is built, resulting
|
||||
artifact is then installed into system in appropriate place. :pep:`517`
|
||||
defines interface between build backend & installer.
|
||||
2. Decides where to install stuff. Once the package is built, the resulting
|
||||
artifact is then installed to the system in its appropriate place. :pep:`517`
|
||||
defines the interface between the build backend & installer.
|
||||
|
||||
Broad overview of flow
|
||||
======================
|
||||
|
@ -111,24 +111,24 @@ The package index gives pip a list of files for that package (via the existing P
|
|||
|
||||
pip chooses from the list a single file to download.
|
||||
|
||||
It may go back and choose another file to download
|
||||
It may go back and choose another file to download.
|
||||
|
||||
When pip looks at the package index, the place where it looks has
|
||||
basically a link. The link’s text is the name of the file
|
||||
basically a link. The link’s text is the name of the file.
|
||||
|
||||
This is the `PyPI Simple API`_ (PyPI has several APIs, some are being
|
||||
deprecated). pip looks at Simple API, documented initially at :pep:`503` --
|
||||
packaging.python.org has PyPA specifications with more details for
|
||||
Simple Repository API
|
||||
Simple Repository API.
|
||||
|
||||
For this package name -- this is the list of files available
|
||||
For this package name -- this is the list of files available.
|
||||
|
||||
Looks there for:
|
||||
|
||||
* The list of filenames
|
||||
* Other info
|
||||
|
||||
Once it has those, selects one file, downloads it
|
||||
Once it has those, it selects one file and downloads it.
|
||||
|
||||
(Question: If I want to ``pip install flask``, I think the whole list of filenames
|
||||
cannot….should not be …. ? I want only the Flask …. Why am I getting the
|
||||
|
|
|
@ -18,17 +18,17 @@ Supported interpreters
|
|||
|
||||
pip support a variety of Python interpreters:
|
||||
|
||||
- CPython 3.6
|
||||
- CPython 3.7
|
||||
- CPython 3.8
|
||||
- CPython 3.9
|
||||
- CPython 3.10
|
||||
- Latest PyPy3
|
||||
|
||||
on different operating systems:
|
||||
|
||||
- Linux
|
||||
- Windows
|
||||
- MacOS
|
||||
- macOS
|
||||
|
||||
and on different architectures:
|
||||
|
||||
|
@ -77,9 +77,9 @@ Developer tasks
|
|||
======== =============== ================ ================== =============
|
||||
OS docs lint vendoring packaging
|
||||
======== =============== ================ ================== =============
|
||||
Linux Github Github Github Github
|
||||
Windows Github Github Github Github
|
||||
MacOS Github Github Github Github
|
||||
Linux GitHub GitHub GitHub GitHub
|
||||
Windows GitHub GitHub GitHub GitHub
|
||||
macOS GitHub GitHub GitHub GitHub
|
||||
======== =============== ================ ================== =============
|
||||
|
||||
Actual testing
|
||||
|
@ -88,28 +88,26 @@ Actual testing
|
|||
+------------------------------+---------------+-----------------+
|
||||
| **interpreter** | **unit** | **integration** |
|
||||
+-----------+----------+-------+---------------+-----------------+
|
||||
| | | CP3.6 | | |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | x86 | CP3.7 | | |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | CP3.8 | | |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | CP3.9 | | |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | CP3.10| | |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | PyPy3 | | |
|
||||
| Windows +----------+-------+---------------+-----------------+
|
||||
| | | CP3.6 | Github | Github |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | x64 | CP3.7 | | |
|
||||
| | x64 | CP3.7 | GitHub | GitHub |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | CP3.8 | | |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | CP3.9 | Github | Github |
|
||||
| | | CP3.9 | | |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | CP3.10| GitHub | GitHub |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | PyPy3 | | |
|
||||
+-----------+----------+-------+---------------+-----------------+
|
||||
| | | CP3.6 | | |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | x86 | CP3.7 | | |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | CP3.8 | | |
|
||||
|
@ -118,33 +116,33 @@ Actual testing
|
|||
| | +-------+---------------+-----------------+
|
||||
| | | PyPy3 | | |
|
||||
| Linux +----------+-------+---------------+-----------------+
|
||||
| | | CP3.6 | Github | Github |
|
||||
| | x64 | CP3.7 | GitHub | GitHub |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | x64 | CP3.7 | Github | Github |
|
||||
| | | CP3.8 | GitHub | GitHub |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | CP3.8 | Github | Github |
|
||||
| | | CP3.9 | GitHub | GitHub |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | CP3.9 | Github | Github |
|
||||
| | | CP3.10| GitHub | GitHub |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | PyPy3 | | |
|
||||
+-----------+----------+-------+---------------+-----------------+
|
||||
| | | CP3.6 | | |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | x86 | CP3.7 | | |
|
||||
| | arm64 | CP3.7 | | |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | CP3.8 | | |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | CP3.9 | | |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | CP3.10| | |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | PyPy3 | | |
|
||||
| MacOS +----------+-------+---------------+-----------------+
|
||||
| | | CP3.6 | Github | Github |
|
||||
| macOS +----------+-------+---------------+-----------------+
|
||||
| | x64 | CP3.7 | GitHub | GitHub |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | x64 | CP3.7 | Github | Github |
|
||||
| | | CP3.8 | GitHub | GitHub |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | CP3.8 | Github | Github |
|
||||
| | | CP3.9 | GitHub | GitHub |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | CP3.9 | Github | Github |
|
||||
| | | CP3.10| GitHub | GitHub |
|
||||
| | +-------+---------------+-----------------+
|
||||
| | | PyPy3 | | |
|
||||
+-----------+----------+-------+---------------+-----------------+
|
||||
|
|
|
@ -88,7 +88,7 @@ The contents of this file are reStructuredText formatted text that
|
|||
will be used as the content of the news file entry. You do not need to
|
||||
reference the issue or PR numbers in the entry, since ``towncrier``
|
||||
will automatically add a reference to all of the affected issues when
|
||||
rendering the NEWS file.
|
||||
rendering the NEWS file. There must be a newline at the end of the file.
|
||||
|
||||
In order to maintain a consistent style in the ``NEWS.rst`` file, it is
|
||||
preferred to keep the news entry to the point, in sentence case, shorter than
|
||||
|
|
|
@ -27,8 +27,8 @@ Development Environment
|
|||
pip is a command line application written in Python. For developing pip,
|
||||
you should `install Python`_ on your computer.
|
||||
|
||||
For developing pip, you need to install :pypi:`tox`. Often, you can run
|
||||
``python -m pip install tox`` to install and use it.
|
||||
For developing pip, you need to install :pypi:`nox`. Often, you can run
|
||||
``python -m pip install nox`` to install and use it.
|
||||
|
||||
|
||||
Running pip From Source Tree
|
||||
|
@ -42,7 +42,7 @@ You can then invoke your local source tree pip normally.
|
|||
|
||||
.. code-block:: shell
|
||||
|
||||
virtualenv .venv # You can also use "python -m venv .venv"
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
python -m pip install -e .
|
||||
python -m pip --version
|
||||
|
@ -51,7 +51,7 @@ You can then invoke your local source tree pip normally.
|
|||
|
||||
.. code-block:: shell
|
||||
|
||||
virtualenv .venv # You can also use "py -m venv .venv"
|
||||
py -m venv .venv
|
||||
.venv\Scripts\activate
|
||||
py -m pip install -e .
|
||||
py -m pip --version
|
||||
|
@ -60,7 +60,7 @@ Running Tests
|
|||
=============
|
||||
|
||||
pip's tests are written using the :pypi:`pytest` test framework and
|
||||
:mod:`unittest.mock`. :pypi:`tox` is used to automate the setup and execution
|
||||
:mod:`unittest.mock`. :pypi:`nox` is used to automate the setup and execution
|
||||
of pip's tests.
|
||||
|
||||
It is preferable to run the tests in parallel for better experience during development,
|
||||
|
@ -70,38 +70,39 @@ To run tests:
|
|||
|
||||
.. code-block:: console
|
||||
|
||||
$ tox -e py36 -- -n auto
|
||||
$ nox -s test-3.10 -- -n auto
|
||||
|
||||
To run tests without parallelization, run:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ tox -e py36
|
||||
$ nox -s test-3.10
|
||||
|
||||
The example above runs tests against Python 3.6. You can also use other
|
||||
versions like ``py39`` and ``pypy3``.
|
||||
The example above runs tests against Python 3.10. You can also use other
|
||||
versions like ``3.9`` and ``pypy3``.
|
||||
|
||||
``tox`` has been configured to forward any additional arguments it is given to
|
||||
``nox`` has been configured to forward any additional arguments it is given to
|
||||
``pytest``. This enables the use of pytest's `rich CLI`_. As an example, you
|
||||
can select tests using the various ways that pytest provides:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ # Using file name
|
||||
$ tox -e py36 -- tests/functional/test_install.py
|
||||
$ nox -s test-3.10 -- tests/functional/test_install.py
|
||||
$ # Using markers
|
||||
$ tox -e py36 -- -m unit
|
||||
$ nox -s test-3.10 -- -m unit
|
||||
$ # Using keywords
|
||||
$ tox -e py36 -- -k "install and not wheel"
|
||||
$ nox -s test-3.10 -- -k "install and not wheel"
|
||||
|
||||
Running pip's test suite requires supported version control tools (subversion,
|
||||
bazaar, git, and mercurial) to be installed. If you are missing one of the VCS
|
||||
tools, you can tell pip to skip those tests:
|
||||
Running pip's entire test suite requires supported version control tools
|
||||
(subversion, bazaar, git, and mercurial) to be installed. If you are missing
|
||||
any of these VCS, those tests should be skipped automatically. You can also
|
||||
explicitly tell pytest to skip those tests:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ tox -e py36 -- -k "not svn"
|
||||
$ tox -e py36 -- -k "not (svn or git)"
|
||||
$ nox -s test-3.10 -- -k "not svn"
|
||||
$ nox -s test-3.10 -- -k "not (svn or git)"
|
||||
|
||||
|
||||
Running Linters
|
||||
|
@ -115,7 +116,7 @@ To use linters locally, run:
|
|||
|
||||
.. code-block:: console
|
||||
|
||||
$ tox -e lint
|
||||
$ nox -s lint
|
||||
|
||||
.. note::
|
||||
|
||||
|
@ -154,7 +155,7 @@ To build it locally, run:
|
|||
|
||||
.. code-block:: console
|
||||
|
||||
$ tox -e docs
|
||||
$ nox -s docs
|
||||
|
||||
The built documentation can be found in the ``docs/build`` folder.
|
||||
|
||||
|
|
346
docs/html/development/issue-triage.md
Normal file
346
docs/html/development/issue-triage.md
Normal file
|
@ -0,0 +1,346 @@
|
|||
```{note}
|
||||
This section of the documentation is currently being written. pip
|
||||
developers welcome your help to complete this documentation. If
|
||||
you're interested in helping out, please let us know in the
|
||||
[tracking issue](https://github.com/pypa/pip/issues/6583), or
|
||||
just submit a pull request and mention it in that tracking issue.
|
||||
```
|
||||
|
||||
# Issue Triage
|
||||
|
||||
This serves as an introduction to issue tracking in pip as well as
|
||||
how to help triage reported issues.
|
||||
|
||||
## Issue Tracker
|
||||
|
||||
The [pip issue tracker](https://github.com/pypa/pip/issues) is hosted on
|
||||
GitHub alongside the project.
|
||||
|
||||
Currently, the issue tracker is used for bugs, feature requests, and general
|
||||
user support.
|
||||
|
||||
In the pip issue tracker, we make use of labels and milestones to organize and
|
||||
track work.
|
||||
|
||||
### Labels
|
||||
|
||||
Issue labels are used to:
|
||||
|
||||
1. Categorize issues
|
||||
2. Provide status information for contributors and reporters
|
||||
3. Help contributors find tasks to work on
|
||||
|
||||
The current set of labels are divided into several categories identified by
|
||||
prefix:
|
||||
|
||||
**C - Category**
|
||||
: which area of `pip` functionality a feature request or issue is related to
|
||||
|
||||
**K - Kind**
|
||||
**O - Operating System**
|
||||
: for issues that are OS-specific
|
||||
|
||||
**P - Project/Platform**
|
||||
: related to something external to `pip`
|
||||
|
||||
**R - Resolution**
|
||||
: no more discussion is really needed, an action has been identified and the
|
||||
issue is waiting or closed
|
||||
|
||||
**S - State**
|
||||
: for some automatic labels and other indicators that work is needed
|
||||
|
||||
**type**
|
||||
: the role or flavor of an issue
|
||||
|
||||
The specific labels falling into each category have a description that can be
|
||||
seen on the [Labels](https://github.com/pypa/pip/labels) page.
|
||||
|
||||
In addition, there are several standalone labels:
|
||||
|
||||
**good first issue**
|
||||
: this label marks an issue as beginner-friendly and shows up in banners that
|
||||
GitHub displays for first-time visitors to the repository
|
||||
|
||||
**triage**
|
||||
: default label given to issues when they are created
|
||||
|
||||
**trivial**
|
||||
: special label for pull requests that removes the
|
||||
{ref}`news file requirement <choosing-news-entry-type>`
|
||||
|
||||
**needs rebase or merge**
|
||||
|
||||
: this is a special label used by BrownTruck to mark PRs that have merge
|
||||
conflicts
|
||||
|
||||
### Automation
|
||||
|
||||
There are several helpers to manage issues and pull requests.
|
||||
|
||||
Issues created on the issue tracker are automatically given the
|
||||
`triage` label by the
|
||||
[triage-new-issues](https://github.com/apps/triage-new-issues)
|
||||
bot. The label is automatically removed when another label is added.
|
||||
|
||||
When an issue needs feedback from the author we can label it with
|
||||
`S: awaiting response`. When the author responds, the
|
||||
[no-response](https://github.com/apps/no-response) bot removes the label.
|
||||
|
||||
After an issue has been closed for 30 days, the
|
||||
[lock](https://github.com/apps/lock) bot locks the issue and adds the
|
||||
`S: auto-locked` label. This allows us to avoid monitoring existing closed
|
||||
issues, but unfortunately prevents and references to issues from showing up as
|
||||
links on the closed issue.
|
||||
|
||||
## Triage Issues
|
||||
|
||||
Users can make issues for a number of reasons:
|
||||
|
||||
1. Suggestions about pip features that could be added or improved
|
||||
2. Problems using pip
|
||||
3. Concerns about pip usability
|
||||
4. General packaging problems to be solved with pip
|
||||
5. Problems installing or using Python packages
|
||||
6. Problems managing virtual environments
|
||||
7. Problems managing Python installations
|
||||
|
||||
To triage issues means to identify what kind of issue is happening and
|
||||
|
||||
- confirm bugs
|
||||
- provide support
|
||||
- discuss and design around the uses of the tool
|
||||
|
||||
Specifically, to address an issue:
|
||||
|
||||
1. Read issue title
|
||||
2. Scan issue description
|
||||
3. Ask questions
|
||||
4. If time is available, try to reproduce
|
||||
5. Search for or remember related issues and link to them
|
||||
6. Identify an appropriate area of concern (if applicable)
|
||||
|
||||
Keep in mind that all communication is happening with other people and
|
||||
should be done with respect per the
|
||||
[Code of Conduct](https://www.pypa.io/en/latest/code-of-conduct/).
|
||||
|
||||
The lifecycle of an issue (bug or support) generally looks like:
|
||||
|
||||
1. waiting for triage (marked with label `triage`)
|
||||
|
||||
2. confirming issue - some discussion with the user, gathering
|
||||
details, trying to reproduce the issue (may be marked with a specific
|
||||
category, `S: awaiting-response`, `S: discussion-needed`, or
|
||||
`S: need-repro`)
|
||||
|
||||
3. confirmed - the issue is pretty consistently reproducible in a
|
||||
straightforward way, or a mechanism that could be causing the issue has been
|
||||
identified
|
||||
|
||||
4. awaiting fix - the fix is identified and no real discussion on the issue
|
||||
is needed, should be marked `R: awaiting PR`
|
||||
|
||||
5. closed - can be for several reasons
|
||||
|
||||
- fixed
|
||||
- could not be reproduced, no more details could be obtained, and no
|
||||
progress can be made
|
||||
- actual issue was with another project or related to system
|
||||
configuration and pip cannot (or will not) be adapted for it
|
||||
|
||||
### Requesting information
|
||||
|
||||
Requesting more information to better understand the context and environment
|
||||
that led to the issue. Examples of specific information that may be useful
|
||||
depending on the situation:
|
||||
|
||||
- pip debug: `pip debug`
|
||||
- pip version: `pip -V`
|
||||
- Python version: `python -VV`
|
||||
- Python path: `python -c 'import sys; print(sys.executable)'`
|
||||
- `python` on `PATH`: Unix: `which python`; Windows: `where python`
|
||||
- Python as resolved by the shell: `type python`
|
||||
- Origin of pip (get-pip.py, OS-level package manager, ensurepip, manual
|
||||
installation)
|
||||
- Using a virtual environment (with `--system-site-packages`?)
|
||||
- Using a conda environment
|
||||
- `PATH` environment variable
|
||||
- Network situation (e.g. airgapped environment, firewalls)
|
||||
- `--verbose` output of a failing command
|
||||
- (Unix) `strace` output from a failing command (be careful not to output
|
||||
into the same directory as a package that's being installed, otherwise pip
|
||||
will loop forever copying the log file...)
|
||||
- (Windows)
|
||||
[procmon](https://docs.microsoft.com/en-us/sysinternals/downloads/procmon)
|
||||
output during a failing command
|
||||
([example request](https://github.com/pypa/pip/issues/6814#issuecomment-516611389))
|
||||
- Listing of files relevant to the issue (e.g. `ls -l venv/lib/pythonX.Y/problem-package.dist-info/`)
|
||||
- whether the unexpected behavior ever worked as expected - if so then what
|
||||
were the details of the setup (same information as above)
|
||||
|
||||
Generally, information is good to request if it can help confirm or rule out
|
||||
possible sources of error. We shouldn't request information that does not
|
||||
improve our understanding of the situation.
|
||||
|
||||
### Reproducing issues
|
||||
|
||||
Whenever an issue happens and the cause isn't obvious, it is important
|
||||
that we be able to reproduce it independently. This serves several purposes:
|
||||
|
||||
1. If it is a pip bug, then any fix will need tests - a good reproducer
|
||||
is most of the way towards that.
|
||||
2. If it is not reproducible using the provided instructions, that helps
|
||||
rule out a lot of possible causes.
|
||||
3. A clear set of instructions is an easy way to get on the same page as
|
||||
someone reporting an issue.
|
||||
|
||||
The best way to reproduce an issue is with a script.
|
||||
|
||||
A script can be copied into a file and executed, whereas shell output
|
||||
has to be manually copied a line at a time.
|
||||
|
||||
Scripts to reproduce issues should be:
|
||||
|
||||
- portable (few/no assumptions about the system, other that it being Unix or Windows as applicable)
|
||||
- non-destructive
|
||||
- convenient
|
||||
- require little/no setup on the part of the runner
|
||||
|
||||
Examples:
|
||||
|
||||
- creating and installing multiple wheels with different versions
|
||||
([link](https://github.com/pypa/pip/issues/4331#issuecomment-520156471))
|
||||
- using a small web server for authentication errors
|
||||
([link](https://github.com/pypa/pip/issues/2920#issuecomment-508953118))
|
||||
- using docker to test system or global configuration-related issues
|
||||
([link](https://github.com/pypa/pip/issues/5533#issuecomment-520159896))
|
||||
- using docker to test special filesystem permission/configurations
|
||||
([link](https://github.com/pypa/pip/issues/6364#issuecomment-507074729))
|
||||
- using docker for global installation with get-pip
|
||||
([link](https://github.com/pypa/pip/issues/6498#issuecomment-513501112))
|
||||
- get-pip on system with no `/usr/lib64`
|
||||
([link](https://github.com/pypa/pip/issues/5379#issuecomment-515270576))
|
||||
- reproducing with `pip` from current development branch
|
||||
([link](https://github.com/pypa/pip/issues/6707#issue-467770959))
|
||||
|
||||
### Reaching resolution
|
||||
|
||||
Some user support questions are more related to system configuration than pip.
|
||||
It's important to treat these issues with the same care and attention as
|
||||
others, specifically:
|
||||
|
||||
1. Unless the issue is very old and the user doesn't seem active, wait for
|
||||
confirmation before closing the issue
|
||||
|
||||
2. Direct the user to the most appropriate forum for their questions:
|
||||
|
||||
- For Ubuntu, [askubuntu](https://askubuntu.com/)
|
||||
- For Other linuxes/unixes, [serverfault](https://serverfault.com/)
|
||||
- For network connectivity issues,
|
||||
[serverfault](https://serverfault.com/)
|
||||
|
||||
3. Just because a user support question is best solved using some other forum
|
||||
doesn't mean that we can't make things easier. Try to extract and
|
||||
understand from the user query how things could have been made easier for
|
||||
them or you, for example with better warning or error messages. If an issue
|
||||
does not exist covering that case then create one. If an issue does exist then
|
||||
make sure to reference that issue before closing this one.
|
||||
|
||||
4. A user may be having trouble installing a package, where the package
|
||||
`setup.py` or build-backend configuration is non-trivial. In these cases we
|
||||
can help to troubleshoot but the best advice is going to be to direct them
|
||||
to the support channels for the related projects.
|
||||
|
||||
5. Do not be hasty to assume it is one cause or another. What looks like
|
||||
someone else's problem may still be an issue in pip or at least something
|
||||
that could be improved.
|
||||
|
||||
6. For general discussion on Python packaging:
|
||||
|
||||
- [pypa/packaging](https://github.com/pypa/packaging-problems)
|
||||
- [discuss.python.org/packaging](https://discuss.python.org/c/packaging)
|
||||
|
||||
### Closing issues
|
||||
|
||||
An issue may be considered resolved and closed when:
|
||||
|
||||
- for each possible improvement or problem represented in the issue
|
||||
discussion:
|
||||
|
||||
- Consensus has been reached on a specific action and the actions
|
||||
appear to be external to the project, with no follow up needed
|
||||
in the project afterwards.
|
||||
|
||||
- PEP updates (with a corresponding issue in
|
||||
[python/peps](https://github.com/python/peps))
|
||||
- already tracked by another issue
|
||||
|
||||
- A project-specific issue has been identified and the issue no
|
||||
longer occurs as of the latest commit on the main branch.
|
||||
|
||||
- An enhancement or feature request no longer has a proponent and the maintainers
|
||||
don't think it's worth keeping open.
|
||||
|
||||
- An issue has been identified as a duplicate, and it is clearly a duplicate (i.e. the
|
||||
original report was very good and points directly to the issue)
|
||||
|
||||
- The issue has been fixed, and can be independently validated as no longer being an
|
||||
issue. If this is with code then the specific change/PR that led to it should be
|
||||
identified and posted for tracking.
|
||||
|
||||
## Common issues
|
||||
|
||||
1. network-related issues - any issue involving retries, address lookup, or
|
||||
anything like that are typically network issues.
|
||||
|
||||
2. issues related to having multiple Python versions, or an OS package
|
||||
manager-managed pip/python installation (specifically with Debian/Ubuntu).
|
||||
These typically present themselves as:
|
||||
|
||||
1. Not being able to find installed packages
|
||||
2. basic libraries not able to be found, fundamental OS components missing
|
||||
3. In these situations you will want to make sure that we know how they got
|
||||
their Python and pip. Knowing the relevant package manager commands can
|
||||
help, e.g. `dpkg -S`.
|
||||
|
||||
## For issues caused by changes by redistributors
|
||||
|
||||
Certain issues are caused by patches that redistributors of Python/pip
|
||||
make to Python/pip.
|
||||
|
||||
Certain redistributors have shared preferred wording to redirect users
|
||||
to their issue trackers.
|
||||
|
||||
Fedora, RHEL, CentOS (and probably other derivatives – Rocky, Scientific, CloudLinux):
|
||||
|
||||
```
|
||||
This issue looks like it's caused by changes that Fedora or Red Hat
|
||||
made in their pip packaging. Please file a Fedora bug at
|
||||
https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&component=python-pip
|
||||
|
||||
cc @encukou @hroncok
|
||||
```
|
||||
|
||||
Debian:
|
||||
|
||||
```
|
||||
This issue looks like it's caused by changes that Debian made in
|
||||
their pip packaging. Please file a bug with Debian, with
|
||||
`reportbug python3-pip` [Docs](https://www.debian.org/Bugs/Reporting).
|
||||
You can link to this issue in your bug report.
|
||||
|
||||
In the meantime, you may be able to work-around your issue by upgrading
|
||||
pip inside your virtualenv: `python -m pip install -U pip`
|
||||
```
|
||||
|
||||
Ubuntu:
|
||||
|
||||
```
|
||||
This issue looks like it's caused by changes that Ubuntu made in
|
||||
their pip packaging. Please file a bug with Ubuntu, with
|
||||
`ubuntu-bug python3-pip` [Docs](https://help.ubuntu.com/community/ReportingBugs).
|
||||
You can link to this issue in your bug report.
|
||||
|
||||
In the meantime, you may be able to work-around your issue by upgrading
|
||||
pip inside your virtualenv: `python -m pip install -U pip`
|
||||
```
|
|
@ -1,312 +0,0 @@
|
|||
.. note::
|
||||
|
||||
This section of the documentation is currently being written. pip
|
||||
developers welcome your help to complete this documentation. If
|
||||
you're interested in helping out, please let us know in the
|
||||
`tracking issue <https://github.com/pypa/pip/issues/6583>`__, or
|
||||
just submit a pull request and mention it in that tracking issue.
|
||||
|
||||
============
|
||||
Issue Triage
|
||||
============
|
||||
|
||||
This serves as an introduction to issue tracking in pip as well as
|
||||
how to help triage reported issues.
|
||||
|
||||
|
||||
Issue Tracker
|
||||
=============
|
||||
|
||||
The `pip issue tracker <https://github.com/pypa/pip/issues>`__ is hosted on
|
||||
GitHub alongside the project.
|
||||
|
||||
Currently, the issue tracker is used for bugs, feature requests, and general
|
||||
user support.
|
||||
|
||||
In the pip issue tracker, we make use of labels and milestones to organize and
|
||||
track work.
|
||||
|
||||
Labels
|
||||
------
|
||||
|
||||
Issue labels are used to:
|
||||
|
||||
#. Categorize issues
|
||||
#. Provide status information for contributors and reporters
|
||||
#. Help contributors find tasks to work on
|
||||
|
||||
The current set of labels are divided into several categories identified by
|
||||
prefix:
|
||||
|
||||
**C - Category**
|
||||
which area of ``pip`` functionality a feature request or issue is related to
|
||||
|
||||
**K - Kind**
|
||||
|
||||
**O - Operating System**
|
||||
for issues that are OS-specific
|
||||
|
||||
**P - Project/Platform**
|
||||
related to something external to ``pip``
|
||||
|
||||
**R - Resolution**
|
||||
no more discussion is really needed, an action has been identified and the
|
||||
issue is waiting or closed
|
||||
|
||||
**S - State**
|
||||
for some automatic labels and other indicators that work is needed
|
||||
|
||||
**type**
|
||||
the role or flavor of an issue
|
||||
|
||||
The specific labels falling into each category have a description that can be
|
||||
seen on the `Labels <https://github.com/pypa/pip/labels>`__ page.
|
||||
|
||||
In addition, there are several standalone labels:
|
||||
|
||||
**good first issue**
|
||||
this label marks an issue as beginner-friendly and shows up in banners that
|
||||
GitHub displays for first-time visitors to the repository
|
||||
|
||||
**triage**
|
||||
default label given to issues when they are created
|
||||
|
||||
**trivial**
|
||||
special label for pull requests that removes the
|
||||
:ref:`news file requirement <choosing-news-entry-type>`
|
||||
|
||||
**needs rebase or merge**
|
||||
this is a special label used by BrownTruck to mark PRs that have merge
|
||||
conflicts
|
||||
|
||||
Automation
|
||||
----------
|
||||
|
||||
There are several helpers to manage issues and pull requests.
|
||||
|
||||
Issues created on the issue tracker are automatically given the
|
||||
``triage`` label by the
|
||||
`triage-new-issues <https://github.com/apps/triage-new-issues>`__
|
||||
bot. The label is automatically removed when another label is added.
|
||||
|
||||
When an issue needs feedback from the author we can label it with
|
||||
``S: awaiting response``. When the author responds, the
|
||||
`no-response <https://github.com/apps/no-response>`__ bot removes the label.
|
||||
|
||||
After an issue has been closed for 30 days, the
|
||||
`lock <https://github.com/apps/lock>`__ bot locks the issue and adds the
|
||||
``S: auto-locked`` label. This allows us to avoid monitoring existing closed
|
||||
issues, but unfortunately prevents and references to issues from showing up as
|
||||
links on the closed issue.
|
||||
|
||||
|
||||
Triage Issues
|
||||
=============
|
||||
|
||||
Users can make issues for a number of reasons:
|
||||
|
||||
#. Suggestions about pip features that could be added or improved
|
||||
#. Problems using pip
|
||||
#. Concerns about pip usability
|
||||
#. General packaging problems to be solved with pip
|
||||
#. Problems installing or using Python packages
|
||||
#. Problems managing virtual environments
|
||||
#. Problems managing Python installations
|
||||
|
||||
To triage issues means to identify what kind of issue is happening and
|
||||
|
||||
* confirm bugs
|
||||
* provide support
|
||||
* discuss and design around the uses of the tool
|
||||
|
||||
Specifically, to address an issue:
|
||||
|
||||
#. Read issue title
|
||||
#. Scan issue description
|
||||
#. Ask questions
|
||||
#. If time is available, try to reproduce
|
||||
#. Search for or remember related issues and link to them
|
||||
#. Identify an appropriate area of concern (if applicable)
|
||||
|
||||
Keep in mind that all communication is happening with other people and
|
||||
should be done with respect per the
|
||||
`Code of Conduct <https://www.pypa.io/en/latest/code-of-conduct/>`__.
|
||||
|
||||
The lifecycle of an issue (bug or support) generally looks like:
|
||||
|
||||
#. waiting for triage (marked with label ``triage``)
|
||||
#. confirming issue - some discussion with the user, gathering
|
||||
details, trying to reproduce the issue (may be marked with a specific
|
||||
category, ``S: awaiting-response``, ``S: discussion-needed``, or
|
||||
``S: need-repro``)
|
||||
#. confirmed - the issue is pretty consistently reproducible in a
|
||||
straightforward way, or a mechanism that could be causing the issue has been
|
||||
identified
|
||||
#. awaiting fix - the fix is identified and no real discussion on the issue
|
||||
is needed, should be marked ``R: awaiting PR``
|
||||
#. closed - can be for several reasons
|
||||
|
||||
* fixed
|
||||
* could not be reproduced, no more details could be obtained, and no
|
||||
progress can be made
|
||||
* actual issue was with another project or related to system
|
||||
configuration and pip cannot (or will not) be adapted for it
|
||||
|
||||
|
||||
Requesting information
|
||||
----------------------
|
||||
|
||||
Requesting more information to better understand the context and environment
|
||||
that led to the issue. Examples of specific information that may be useful
|
||||
depending on the situation:
|
||||
|
||||
* pip debug: ``pip debug``
|
||||
* pip version: ``pip -V``
|
||||
* Python version: ``python -VV``
|
||||
* Python path: ``python -c 'import sys; print(sys.executable)'``
|
||||
* ``python`` on ``PATH``: Unix: ``which python``; Windows: ``where python``
|
||||
* Python as resolved by the shell: ``type python``
|
||||
* Origin of pip (get-pip.py, OS-level package manager, ensurepip, manual
|
||||
installation)
|
||||
* Using a virtual environment (with ``--system-site-packages``?)
|
||||
* Using a conda environment
|
||||
* ``PATH`` environment variable
|
||||
* Network situation (e.g. airgapped environment, firewalls)
|
||||
* ``--verbose`` output of a failing command
|
||||
* (Unix) ``strace`` output from a failing command (be careful not to output
|
||||
into the same directory as a package that's being installed, otherwise pip
|
||||
will loop forever copying the log file...)
|
||||
* (Windows)
|
||||
`procmon <https://docs.microsoft.com/en-us/sysinternals/downloads/procmon>`__
|
||||
output during a failing command
|
||||
(`example request <https://github.com/pypa/pip/issues/6814#issuecomment-516611389>`__)
|
||||
* Listing of files relevant to the issue (e.g. ``ls -l venv/lib/pythonX.Y/problem-package.dist-info/``)
|
||||
* whether the unexpected behavior ever worked as expected - if so then what
|
||||
were the details of the setup (same information as above)
|
||||
|
||||
|
||||
Generally, information is good to request if it can help confirm or rule out
|
||||
possible sources of error. We shouldn't request information that does not
|
||||
improve our understanding of the situation.
|
||||
|
||||
|
||||
Reproducing issues
|
||||
------------------
|
||||
|
||||
Whenever an issue happens and the cause isn't obvious, it is important
|
||||
that we be able to reproduce it independently. This serves several purposes:
|
||||
|
||||
#. If it is a pip bug, then any fix will need tests - a good reproducer
|
||||
is most of the way towards that.
|
||||
#. If it is not reproducible using the provided instructions, that helps
|
||||
rule out a lot of possible causes.
|
||||
#. A clear set of instructions is an easy way to get on the same page as
|
||||
someone reporting an issue.
|
||||
|
||||
The best way to reproduce an issue is with a script.
|
||||
|
||||
A script can be copied into a file and executed, whereas shell output
|
||||
has to be manually copied a line at a time.
|
||||
|
||||
Scripts to reproduce issues should be:
|
||||
|
||||
- portable (few/no assumptions about the system, other that it being Unix or Windows as applicable)
|
||||
- non-destructive
|
||||
- convenient
|
||||
- require little/no setup on the part of the runner
|
||||
|
||||
Examples:
|
||||
|
||||
- creating and installing multiple wheels with different versions
|
||||
(`link <https://github.com/pypa/pip/issues/4331#issuecomment-520156471>`__)
|
||||
- using a small web server for authentication errors
|
||||
(`link <https://github.com/pypa/pip/issues/2920#issuecomment-508953118>`__)
|
||||
- using docker to test system or global configuration-related issues
|
||||
(`link <https://github.com/pypa/pip/issues/5533#issuecomment-520159896>`__)
|
||||
- using docker to test special filesystem permission/configurations
|
||||
(`link <https://github.com/pypa/pip/issues/6364#issuecomment-507074729>`__)
|
||||
- using docker for global installation with get-pip
|
||||
(`link <https://github.com/pypa/pip/issues/6498#issuecomment-513501112>`__)
|
||||
- get-pip on system with no ``/usr/lib64``
|
||||
(`link <https://github.com/pypa/pip/issues/5379#issuecomment-515270576>`__)
|
||||
- reproducing with ``pip`` from current development branch
|
||||
(`link <https://github.com/pypa/pip/issues/6707#issue-467770959>`__)
|
||||
|
||||
|
||||
Reaching resolution
|
||||
-------------------
|
||||
|
||||
Some user support questions are more related to system configuration than pip.
|
||||
It's important to treat these issues with the same care and attention as
|
||||
others, specifically:
|
||||
|
||||
#. Unless the issue is very old and the user doesn't seem active, wait for
|
||||
confirmation before closing the issue
|
||||
#. Direct the user to the most appropriate forum for their questions:
|
||||
|
||||
* For Ubuntu, `askubuntu <https://askubuntu.com/>`__
|
||||
* For Other linuxes/unixes, `serverfault <https://serverfault.com/>`__
|
||||
* For network connectivity issues,
|
||||
`serverfault <https://serverfault.com/>`__
|
||||
|
||||
#. Just because a user support question is best solved using some other forum
|
||||
doesn't mean that we can't make things easier. Try to extract and
|
||||
understand from the user query how things could have been made easier for
|
||||
them or you, for example with better warning or error messages. If an issue
|
||||
does not exist covering that case then create one. If an issue does exist then
|
||||
make sure to reference that issue before closing this one.
|
||||
#. A user may be having trouble installing a package, where the package
|
||||
``setup.py`` or build-backend configuration is non-trivial. In these cases we
|
||||
can help to troubleshoot but the best advice is going to be to direct them
|
||||
to the support channels for the related projects.
|
||||
#. Do not be hasty to assume it is one cause or another. What looks like
|
||||
someone else's problem may still be an issue in pip or at least something
|
||||
that could be improved.
|
||||
#. For general discussion on Python packaging:
|
||||
|
||||
* `pypa/packaging <https://github.com/pypa/packaging-problems>`__
|
||||
* `discuss.python.org/packaging <https://discuss.python.org/c/packaging>`__
|
||||
|
||||
|
||||
Closing issues
|
||||
--------------
|
||||
|
||||
An issue may be considered resolved and closed when:
|
||||
|
||||
- for each possible improvement or problem represented in the issue
|
||||
discussion:
|
||||
|
||||
- Consensus has been reached on a specific action and the actions
|
||||
appear to be external to the project, with no follow up needed
|
||||
in the project afterwards.
|
||||
|
||||
- PEP updates (with a corresponding issue in
|
||||
`python/peps <https://github.com/python/peps>`__)
|
||||
- already tracked by another issue
|
||||
|
||||
- A project-specific issue has been identified and the issue no
|
||||
longer occurs as of the latest commit on the main branch.
|
||||
|
||||
- An enhancement or feature request no longer has a proponent and the maintainers
|
||||
don't think it's worth keeping open.
|
||||
- An issue has been identified as a duplicate, and it is clearly a duplicate (i.e. the
|
||||
original report was very good and points directly to the issue)
|
||||
- The issue has been fixed, and can be independently validated as no longer being an
|
||||
issue. If this is with code then the specific change/PR that led to it should be
|
||||
identified and posted for tracking.
|
||||
|
||||
|
||||
Common issues
|
||||
=============
|
||||
|
||||
#. network-related issues - any issue involving retries, address lookup, or
|
||||
anything like that are typically network issues.
|
||||
#. issues related to having multiple Python versions, or an OS package
|
||||
manager-managed pip/python installation (specifically with Debian/Ubuntu).
|
||||
These typically present themselves as:
|
||||
|
||||
#. Not being able to find installed packages
|
||||
#. basic libraries not able to be found, fundamental OS components missing
|
||||
#. In these situations you will want to make sure that we know how they got
|
||||
their Python and pip. Knowing the relevant package manager commands can
|
||||
help, e.g. ``dpkg -S``.
|
|
@ -31,6 +31,15 @@ to need extra work before being released, the release manager always has the
|
|||
option to back out the partial change prior to a release. The PR can then be
|
||||
reworked and resubmitted for the next release.
|
||||
|
||||
Vendoring updates will be picked up from the ``main`` branch, as for any other
|
||||
update. Ideally, vendoring updates should be merged between releases, just like
|
||||
any other change. If there are outstanding updates to vendored packages, the
|
||||
release manager *may* at their discretion choose to do a vendoring update
|
||||
before the release. However this is *not* a requirement and in particular,
|
||||
updates to vendored packages that fix issues in pip should be merged
|
||||
proactively, to ensure that they will be present in the next release.
|
||||
|
||||
|
||||
.. _`Deprecation Policy`:
|
||||
|
||||
Deprecation Policy
|
||||
|
@ -65,6 +74,13 @@ their merits.
|
|||
``pip._internal.utils.deprecation.deprecated``. The function is not a part of
|
||||
pip's public API.
|
||||
|
||||
Supported Versions
|
||||
==================
|
||||
|
||||
The latest version of the pip is the only supported version, previous
|
||||
versions should be considered unsupported. Users are encouraged to make
|
||||
regular updates to their version of pip in order to remain supported.
|
||||
|
||||
.. _`Python 2 Support`:
|
||||
|
||||
Python 2 Support
|
||||
|
@ -159,6 +175,11 @@ Sometimes we need to release a bugfix release of the form ``YY.N.Z+1``. In
|
|||
order to create one of these the changes should already be merged into the
|
||||
``main`` branch.
|
||||
|
||||
Note that this process is only needed when there are changes on the main branch
|
||||
that you do *not* want to include in the bugfix release. For a bugfix release
|
||||
that will include everything that is on the ``main`` branch, the above process
|
||||
for creating a new release can be used, simply changing the version number.
|
||||
|
||||
#. Create a new ``release/YY.N.Z+1`` branch off of the ``YY.N`` tag using the
|
||||
command ``git checkout -b release/YY.N.Z+1 YY.N``.
|
||||
#. Cherry pick the fixed commits off of the ``main`` branch, fixing any
|
||||
|
|
|
@ -81,10 +81,8 @@ Successfully installed sampleproject
|
|||
|
||||
```{pip-cli}
|
||||
$ pip install --upgrade sampleproject
|
||||
Uninstalling sampleproject:
|
||||
[...]
|
||||
Proceed (y/n)? y
|
||||
Successfully uninstalled sampleproject
|
||||
Successfully installed sampleproject
|
||||
```
|
||||
|
||||
### Uninstall a package
|
||||
|
@ -93,7 +91,7 @@ Successfully uninstalled sampleproject
|
|||
$ pip uninstall sampleproject
|
||||
Uninstalling sampleproject:
|
||||
[...]
|
||||
Proceed (y/n)? y
|
||||
Proceed (Y/n)? y
|
||||
Successfully uninstalled sampleproject
|
||||
```
|
||||
|
||||
|
|
|
@ -48,3 +48,5 @@ lists or chat rooms:
|
|||
[packaging-discourse]: https://discuss.python.org/c/packaging/14
|
||||
[irc-pypa]: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa
|
||||
[irc-pypa-dev]: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev
|
||||
|
||||
If you find any security issues, please report to [security@python.org](mailto:security@python.org)
|
||||
|
|
|
@ -14,7 +14,7 @@ If your Python environment does not have pip installed, there are 2 mechanisms
|
|||
to install pip supported directly by pip's maintainers:
|
||||
|
||||
- [`ensurepip`](#ensurepip)
|
||||
- [`get-pip.py`](#get-pip-py)
|
||||
- [`get-pip.py`](#get-pippy)
|
||||
|
||||
### `ensurepip`
|
||||
|
||||
|
@ -45,6 +45,34 @@ More details about this script can be found in [pypa/get-pip]'s README.
|
|||
|
||||
[pypa/get-pip]: https://github.com/pypa/get-pip
|
||||
|
||||
### Standalone zip application
|
||||
|
||||
```{note}
|
||||
The zip application is currently experimental. We test that pip runs correctly
|
||||
in this form, but it is possible that there could be issues in some situations.
|
||||
We will accept bug reports in such cases, but for now the zip application should
|
||||
not be used in production environments.
|
||||
```
|
||||
|
||||
In addition to installing pip in your environment, pip is available as a
|
||||
standalone [zip application](https://docs.python.org/3.11/library/zipapp.html).
|
||||
This can be downloaded from <https://bootstrap.pypa.io/pip/pip.pyz>. There are
|
||||
also zip applications for specific pip versions, named `pip-X.Y.Z.pyz`.
|
||||
|
||||
The zip application can be run using any supported version of Python:
|
||||
|
||||
```{pip-cli}
|
||||
$ python pip.pyz --help
|
||||
```
|
||||
|
||||
If run directly:
|
||||
|
||||
```{pip-cli}
|
||||
$ pip.pyz --help
|
||||
```
|
||||
|
||||
then the currently active Python interpreter will be used.
|
||||
|
||||
## Alternative Methods
|
||||
|
||||
Depending on how you installed Python, there might be other mechanisms
|
||||
|
@ -62,7 +90,7 @@ distro community, cloud provider support channels, etc).
|
|||
|
||||
## Upgrading `pip`
|
||||
|
||||
Upgrading your `pip` by running:
|
||||
Upgrade your `pip` by running:
|
||||
|
||||
```{pip-cli}
|
||||
$ pip install --upgrade pip
|
||||
|
@ -75,14 +103,15 @@ $ pip install --upgrade pip
|
|||
The current version of pip works on:
|
||||
|
||||
- Windows, Linux and MacOS.
|
||||
- CPython 3.6, 3.7, 3.8, 3.9, 3.10 and latest PyPy3.
|
||||
- CPython 3.7, 3.8, 3.9, 3.10 and latest PyPy3.
|
||||
|
||||
pip is tested to work on the latest patch version of the Python interpreter,
|
||||
for each of the minor versions listed above. Previous patch versions are
|
||||
supported on a best effort approach.
|
||||
|
||||
pip's maintainers do not provide support for users on older versions of Python,
|
||||
and these users should request for support from the relevant provider
|
||||
(eg: Linux distro community, cloud provider support channels, etc).
|
||||
Other operating systems and Python versions are not supported by pip's
|
||||
maintainers.
|
||||
|
||||
Users who are on unsupported platforms should be aware that if they hit issues, they may have to resolve them for themselves. If they received pip from a source which provides support for their platform, they should request pip support from that source.
|
||||
|
||||
[^python]: The `ensurepip` module was added to the Python standard library in Python 3.4.
|
||||
|
|
|
@ -49,6 +49,14 @@ hook will be called by pip, and dependencies it describes will also be installed
|
|||
in the build environment. For example, newer versions of setuptools expose the
|
||||
contents of `setup_requires` to pip via this hook.
|
||||
|
||||
Build-time requirement specifiers follow {pep}`508`, so it's possible to
|
||||
reference packages with URLs. For example:
|
||||
|
||||
```toml
|
||||
[build-system]
|
||||
requires = ["setuptools @ git+https://github.com/pypa/setuptools.git@main"]
|
||||
```
|
||||
|
||||
### Metadata Generation
|
||||
|
||||
```{versionadded} 19.0
|
||||
|
@ -98,6 +106,16 @@ This is considered a stopgap solution until setuptools adds support for
|
|||
regular {ref}`deprecation policy <Deprecation Policy>`.
|
||||
```
|
||||
|
||||
### Backend Configuration
|
||||
|
||||
Build backends have the ability to accept configuration settings, which can
|
||||
change the way the build is handled. These settings take the form of a
|
||||
series of `key=value` pairs. The user can supply configuration settings
|
||||
using the `--config-settings` command line option (which can be supplied
|
||||
multiple times, in order to specify multiple settings).
|
||||
|
||||
The supplied configuration settings are passed to every backend hook call.
|
||||
|
||||
## Build output
|
||||
|
||||
It is the responsibility of the build backend to ensure that the output is
|
||||
|
|
|
@ -7,5 +7,8 @@ interoperability standards that pip utilises/implements.
|
|||
:titlesonly:
|
||||
|
||||
build-system/index
|
||||
requirement-specifiers
|
||||
requirements-file-format
|
||||
installation-report
|
||||
inspect-report
|
||||
```
|
||||
|
|
219
docs/html/reference/inspect-report.md
Normal file
219
docs/html/reference/inspect-report.md
Normal file
|
@ -0,0 +1,219 @@
|
|||
# `pip inspect` JSON output specification
|
||||
|
||||
```{versionadded} 22.2
|
||||
```
|
||||
|
||||
```{versionchanged} 23.0
|
||||
``version`` has been bumped to ``1`` and the format declared stable.
|
||||
```
|
||||
|
||||
The `pip inspect` command produces a detailed JSON report of the Python
|
||||
environment, including installed distributions.
|
||||
|
||||
## Specification
|
||||
|
||||
The report is a JSON object with the following properties:
|
||||
|
||||
- `version`: the string `1`. It will change only if
|
||||
and when backward incompatible changes are introduced, such as removing mandatory
|
||||
fields or changing the semantics or data type of existing fields. The introduction of
|
||||
backward incompatible changes will follow the usual pip processes such as the
|
||||
deprecation cycle or feature flags. Tools must check this field to ensure they support
|
||||
the corresponding version.
|
||||
|
||||
- `pip_version`: a string with the version of pip used to produce the report.
|
||||
|
||||
- `installed`: an array of [`InspectReportItem`](InspectReportItem) representing the
|
||||
distribution packages that are installed.
|
||||
|
||||
- `environment`: an object describing the environment where the installation report was
|
||||
generated. See [PEP 508 environment
|
||||
markers](https://peps.python.org/pep-0508/#environment-markers) for more information.
|
||||
Values have a string type.
|
||||
|
||||
(InspectReportItem)=
|
||||
|
||||
An `InspectReportItem` is an object describing an installed distribution package with
|
||||
the following properties:
|
||||
|
||||
- `metadata`: the metadata of the distribution, converted to a JSON object according to
|
||||
the [PEP 566
|
||||
transformation](https://www.python.org/dev/peps/pep-0566/#json-compatible-metadata).
|
||||
|
||||
- `metadata_location`: the location of the metadata of the installed distribution. Most
|
||||
of the time this is the `.dist-info` directory. For legacy installs it is the
|
||||
`.egg-info` directory.
|
||||
|
||||
```{warning}
|
||||
This field may not necessarily point to a directory, for instance, in the case of older
|
||||
`.egg` installs.
|
||||
```
|
||||
|
||||
- `direct_url`: Information about the direct URL that was used for installation, if any,
|
||||
using the [direct URL data
|
||||
structure](https://packaging.python.org/en/latest/specifications/direct-url-data-structure/).
|
||||
In most case, this field corresponds to the
|
||||
[`direct_url.json`](https://packaging.python.org/en/latest/specifications/direct-url)
|
||||
metadata, except for legacy editable installs, where it is emulated.
|
||||
|
||||
- `requested`: `true` if the `REQUESTED` metadata is present, `false` otherwise. This
|
||||
field is only present for modern `.dist-info` installations.
|
||||
|
||||
```{note}
|
||||
The `REQUESTED` metadata may not be generated by all installers.
|
||||
It is generated by pip since version 20.2.
|
||||
```
|
||||
|
||||
- `installer`: the content of the `INSTALLER` metadata, if present and not empty.
|
||||
|
||||
## Example
|
||||
|
||||
Running the ``pip inspect`` command, in an environment where `pip` is installed in
|
||||
editable mode and `packaging` is installed as well, will produce an output similar to
|
||||
this (metadata abriged for brevity):
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1",
|
||||
"pip_version": "22.2.dev0",
|
||||
"installed": [
|
||||
{
|
||||
"metadata": {
|
||||
"metadata_version": "2.1",
|
||||
"name": "pyparsing",
|
||||
"version": "3.0.9",
|
||||
"summary": "pyparsing module - Classes and methods to define and execute parsing grammars",
|
||||
"description_content_type": "text/x-rst",
|
||||
"author_email": "Paul McGuire <ptmcg.gm+pyparsing@gmail.com>",
|
||||
"classifier": [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"Intended Audience :: Information Technology",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Operating System :: OS Independent",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3 :: Only",
|
||||
"Programming Language :: Python :: Implementation :: CPython",
|
||||
"Programming Language :: Python :: Implementation :: PyPy",
|
||||
"Typing :: Typed"
|
||||
],
|
||||
"requires_dist": [
|
||||
"railroad-diagrams ; extra == \"diagrams\"",
|
||||
"jinja2 ; extra == \"diagrams\""
|
||||
],
|
||||
"requires_python": ">=3.6.8",
|
||||
"project_url": [
|
||||
"Homepage, https://github.com/pyparsing/pyparsing/"
|
||||
],
|
||||
"provides_extra": [
|
||||
"diagrams"
|
||||
],
|
||||
"description": "..."
|
||||
},
|
||||
"metadata_location": "/home/me/.virtualenvs/demoenv/lib/python3.8/site-packages/pyparsing-3.0.9.dist-info",
|
||||
"installer": "pip",
|
||||
"requested": false
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"metadata_version": "2.1",
|
||||
"name": "packaging",
|
||||
"version": "21.3",
|
||||
"platform": [
|
||||
"UNKNOWN"
|
||||
],
|
||||
"summary": "Core utilities for Python packages",
|
||||
"description_content_type": "text/x-rst",
|
||||
"home_page": "https://github.com/pypa/packaging",
|
||||
"author": "Donald Stufft and individual contributors",
|
||||
"author_email": "donald@stufft.io",
|
||||
"license": "BSD-2-Clause or Apache-2.0",
|
||||
"classifier": [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: Apache Software License",
|
||||
"License :: OSI Approved :: BSD License",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3 :: Only",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: Implementation :: CPython",
|
||||
"Programming Language :: Python :: Implementation :: PyPy"
|
||||
],
|
||||
"requires_dist": [
|
||||
"pyparsing (!=3.0.5,>=2.0.2)"
|
||||
],
|
||||
"requires_python": ">=3.6",
|
||||
"description": "..."
|
||||
},
|
||||
"metadata_location": "/home/me/.virtualenvs/demoenv/lib/python3.8/site-packages/packaging-21.3.dist-info",
|
||||
"installer": "pip",
|
||||
"requested": true
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"metadata_version": "2.1",
|
||||
"name": "pip",
|
||||
"version": "22.2.dev0",
|
||||
"summary": "The PyPA recommended tool for installing Python packages.",
|
||||
"home_page": "https://pip.pypa.io/",
|
||||
"author": "The pip developers",
|
||||
"author_email": "distutils-sig@python.org",
|
||||
"license": "MIT",
|
||||
"classifier": [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Topic :: Software Development :: Build Tools",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3 :: Only",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: Implementation :: CPython",
|
||||
"Programming Language :: Python :: Implementation :: PyPy"
|
||||
],
|
||||
"requires_python": ">=3.7",
|
||||
"project_url": [
|
||||
"Documentation, https://pip.pypa.io",
|
||||
"Source, https://github.com/pypa/pip",
|
||||
"Changelog, https://pip.pypa.io/en/stable/news/"
|
||||
],
|
||||
"description": "..."
|
||||
},
|
||||
"metadata_location": "/home/me/pip/src/pip.egg-info",
|
||||
"direct_url": {
|
||||
"url": "file:///home/me/pip/src",
|
||||
"dir_info": {
|
||||
"editable": true
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"environment": {
|
||||
"implementation_name": "cpython",
|
||||
"implementation_version": "3.8.10",
|
||||
"os_name": "posix",
|
||||
"platform_machine": "x86_64",
|
||||
"platform_release": "5.13-generic",
|
||||
"platform_system": "Linux",
|
||||
"platform_version": "...",
|
||||
"python_full_version": "3.8.10",
|
||||
"platform_python_implementation": "CPython",
|
||||
"python_version": "3.8",
|
||||
"sys_platform": "linux"
|
||||
}
|
||||
}
|
||||
```
|
200
docs/html/reference/installation-report.md
Normal file
200
docs/html/reference/installation-report.md
Normal file
|
@ -0,0 +1,200 @@
|
|||
# Installation Report
|
||||
|
||||
```{versionadded} 22.2
|
||||
```
|
||||
|
||||
```{versionchanged} 23.0
|
||||
``version`` has been bumped to ``1`` and the format declared stable.
|
||||
```
|
||||
|
||||
The `--report` option of the pip install command produces a detailed JSON report of what
|
||||
it did install (or what it would have installed, if used with the `--dry-run` option).
|
||||
|
||||
```{note}
|
||||
When considering use cases, please bear in mind that
|
||||
|
||||
- while the `--report` option may be used to implement requirement locking tools (among
|
||||
other use cases), this format is *not* meant to be a lock file format as such;
|
||||
- there is no plan for pip to accept an installation report as input for the `install`,
|
||||
`download` or `wheel` commands;
|
||||
- the `--report` option and this format is intended to become a supported pip feature
|
||||
(when the format is stabilized to version 1);
|
||||
- it is however *not* a PyPA interoperability standard and as such its evolution will be
|
||||
governed by the pip processes and not the PyPA standardization processes.
|
||||
```
|
||||
|
||||
## Specification
|
||||
|
||||
The report is a JSON object with the following properties:
|
||||
|
||||
- `version`: the string `1`. It will change only if
|
||||
and when backward incompatible changes are introduced, such as removing mandatory
|
||||
fields or changing the semantics or data type of existing fields. The introduction of
|
||||
backward incompatible changes will follow the usual pip processes such as the
|
||||
deprecation cycle or feature flags. Tools must check this field to ensure they support
|
||||
the corresponding version.
|
||||
|
||||
- `pip_version`: a string with the version of pip used to produce the report.
|
||||
|
||||
- `install`: an array of [`InstallationReportItem`](InstallationReportItem) representing
|
||||
the distribution packages (to be) installed.
|
||||
|
||||
- `environment`: an object describing the environment where the installation report was
|
||||
generated. See [PEP 508 environment
|
||||
markers](https://peps.python.org/pep-0508/#environment-markers) for more information.
|
||||
Values have a string type.
|
||||
|
||||
(InstallationReportItem)=
|
||||
|
||||
An `InstallationReportItem` is an object describing a (to be) installed distribution
|
||||
package with the following properties:
|
||||
|
||||
- `metadata`: the metadata of the distribution, converted to a JSON object according to
|
||||
the [PEP 566
|
||||
transformation](https://www.python.org/dev/peps/pep-0566/#json-compatible-metadata).
|
||||
|
||||
- `is_direct`: `true` if the requirement was provided as, or constrained to, a direct
|
||||
URL reference. `false` if the requirements was provided as a name and version
|
||||
specifier.
|
||||
|
||||
- `download_info`: Information about the artifact (to be) downloaded for installation,
|
||||
using the [direct URL data
|
||||
structure](https://packaging.python.org/en/latest/specifications/direct-url-data-structure/).
|
||||
When `is_direct` is `true`, this field is the same as the
|
||||
[`direct_url.json`](https://packaging.python.org/en/latest/specifications/direct-url)
|
||||
metadata, otherwise it represents the URL of the artifact obtained from the index or
|
||||
`--find-links`.
|
||||
|
||||
```{note}
|
||||
For source archives, `download_info.archive_info.hashes` may
|
||||
be absent when the requirement was installed from the wheel cache
|
||||
and the cache entry was populated by an older pip version that did not
|
||||
record the origin URL of the downloaded artifact.
|
||||
```
|
||||
|
||||
- `requested`: `true` if the requirement was explicitly provided by the user, either
|
||||
directly via a command line argument or indirectly via a requirements file. `false`
|
||||
if the requirement was installed as a dependency of another requirement.
|
||||
|
||||
- `requested_extras`: extras requested by the user. This field is only present when the
|
||||
`requested` field is true.
|
||||
|
||||
## Example
|
||||
|
||||
The following command:
|
||||
|
||||
```console
|
||||
pip install \
|
||||
--ignore-installed --dry-run --quiet \
|
||||
--report - \
|
||||
"pydantic>=1.9" git+https://github.com/pypa/packaging@main
|
||||
```
|
||||
|
||||
will produce an output similar to this (metadata abriged for brevity):
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1",
|
||||
"pip_version": "22.2",
|
||||
"install": [
|
||||
{
|
||||
"download_info": {
|
||||
"url": "https://files.pythonhosted.org/packages/a4/0c/fbaa7319dcb5eecd3484686eb5a5c5702a6445adb566f01aee6de3369bc4/pydantic-1.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
|
||||
"archive_info": {
|
||||
"hashes": {
|
||||
"sha256": "18f3e912f9ad1bdec27fb06b8198a2ccc32f201e24174cec1b3424dda605a310"
|
||||
}
|
||||
}
|
||||
},
|
||||
"is_direct": false,
|
||||
"requested": true,
|
||||
"metadata": {
|
||||
"name": "pydantic",
|
||||
"version": "1.9.1",
|
||||
"requires_dist": [
|
||||
"typing-extensions (>=3.7.4.3)",
|
||||
"dataclasses (>=0.6) ; python_version < \"3.7\"",
|
||||
"python-dotenv (>=0.10.4) ; extra == 'dotenv'",
|
||||
"email-validator (>=1.0.3) ; extra == 'email'"
|
||||
],
|
||||
"requires_python": ">=3.6.1",
|
||||
"provides_extra": [
|
||||
"dotenv",
|
||||
"email"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"download_info": {
|
||||
"url": "https://github.com/pypa/packaging",
|
||||
"vcs_info": {
|
||||
"vcs": "git",
|
||||
"requested_revision": "main",
|
||||
"commit_id": "4f42225e91a0be634625c09e84dd29ea82b85e27"
|
||||
}
|
||||
},
|
||||
"is_direct": true,
|
||||
"requested": true,
|
||||
"metadata": {
|
||||
"name": "packaging",
|
||||
"version": "21.4.dev0",
|
||||
"requires_dist": [
|
||||
"pyparsing (!=3.0.5,>=2.0.2)"
|
||||
],
|
||||
"requires_python": ">=3.7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"download_info": {
|
||||
"url": "https://files.pythonhosted.org/packages/6c/10/a7d0fa5baea8fe7b50f448ab742f26f52b80bfca85ac2be9d35cdd9a3246/pyparsing-3.0.9-py3-none-any.whl",
|
||||
"archive_info": {
|
||||
"hashes": {
|
||||
"sha256": "5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"is_direct": false,
|
||||
"requested": false,
|
||||
"metadata": {
|
||||
"name": "pyparsing",
|
||||
"version": "3.0.9",
|
||||
"requires_dist": [
|
||||
"railroad-diagrams ; extra == \"diagrams\"",
|
||||
"jinja2 ; extra == \"diagrams\""
|
||||
],
|
||||
"requires_python": ">=3.6.8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"download_info": {
|
||||
"url": "https://files.pythonhosted.org/packages/75/e1/932e06004039dd670c9d5e1df0cd606bf46e29a28e65d5bb28e894ea29c9/typing_extensions-4.2.0-py3-none-any.whl",
|
||||
"archive_info": {
|
||||
"hashes": {
|
||||
"sha256": "6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708"
|
||||
}
|
||||
}
|
||||
},
|
||||
"is_direct": false,
|
||||
"requested": false,
|
||||
"metadata": {
|
||||
"name": "typing_extensions",
|
||||
"version": "4.2.0",
|
||||
"requires_python": ">=3.7"
|
||||
}
|
||||
}
|
||||
],
|
||||
"environment": {
|
||||
"implementation_name": "cpython",
|
||||
"implementation_version": "3.10.5",
|
||||
"os_name": "posix",
|
||||
"platform_machine": "x86_64",
|
||||
"platform_release": "5.13-generic",
|
||||
"platform_system": "Linux",
|
||||
"platform_version": "...",
|
||||
"python_full_version": "3.10.5",
|
||||
"platform_python_implementation": "CPython",
|
||||
"python_version": "3.10",
|
||||
"sys_platform": "linux"
|
||||
}
|
||||
}
|
||||
```
|
61
docs/html/reference/requirement-specifiers.md
Normal file
61
docs/html/reference/requirement-specifiers.md
Normal file
|
@ -0,0 +1,61 @@
|
|||
(Requirement Specifiers)=
|
||||
|
||||
# Requirement Specifiers
|
||||
|
||||
pip supports installing from a package index using a {term}`requirement specifier <pypug:Requirement Specifier>`. Generally speaking, a requirement specifier is composed of a project name followed by optional {term}`version specifiers <pypug:Version Specifier>`.
|
||||
|
||||
{pep}`508` contains a full specification of the format of a requirement.
|
||||
|
||||
```{versionadded} 6.0
|
||||
Support for environment markers.
|
||||
```
|
||||
|
||||
```{versionadded} 19.1
|
||||
Support for the direct URL reference form.
|
||||
```
|
||||
|
||||
## Overview
|
||||
|
||||
A requirement specifier comes in two forms:
|
||||
|
||||
- name-based, which is composed of:
|
||||
|
||||
- a package name (eg: `requests`)
|
||||
- optionally, a set of "extras" that serve to install optional dependencies (eg: `security`)
|
||||
- optionally, constraints to apply on the version of the package
|
||||
- optionally, environment markers
|
||||
|
||||
- URL-based, which is composed of:
|
||||
|
||||
- a package name (eg: `requests`)
|
||||
- optionally, a set of "extras" that serve to install optional dependencies (eg: `security`)
|
||||
- a URL for the package
|
||||
- optionally, environment markers
|
||||
|
||||
## Examples
|
||||
|
||||
A few example name-based requirement specifiers:
|
||||
|
||||
```
|
||||
SomeProject
|
||||
SomeProject == 1.3
|
||||
SomeProject >= 1.2, < 2.0
|
||||
SomeProject[foo, bar]
|
||||
SomeProject ~= 1.4.2
|
||||
SomeProject == 5.4 ; python_version < '3.8'
|
||||
SomeProject ; sys_platform == 'win32'
|
||||
requests [security] >= 2.8.1, == 2.8.* ; python_version < "2.7"
|
||||
```
|
||||
|
||||
```{note}
|
||||
Use quotes around specifiers in the shell when using `>`, `<`, or when using environment markers.
|
||||
|
||||
Do _not_ use quotes in requirement files. There is only one exception: pip v7.0 and v7.0.1 (from May 2015) required quotes around specifiers containing environment markers in requirement files.
|
||||
```
|
||||
|
||||
A few example URL-based requirement specifiers:
|
||||
|
||||
```none
|
||||
pip @ https://github.com/pypa/pip/archive/22.0.2.zip
|
||||
requests [security] @ https://github.com/psf/requests/archive/refs/heads/main.zip ; python_version >= "3.11"
|
||||
```
|
|
@ -15,13 +15,38 @@ consumption by pip, and other tools should take that into account before using
|
|||
it for their own purposes.
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```
|
||||
# This is a comment, to show how #-prefixed lines are ignored.
|
||||
# It is possible to specify requirements as plain names.
|
||||
pytest
|
||||
pytest-cov
|
||||
beautifulsoup4
|
||||
|
||||
# The syntax supported here is the same as that of requirement specifiers.
|
||||
docopt == 0.6.1
|
||||
requests [security] >= 2.8.1, == 2.8.* ; python_version < "2.7"
|
||||
urllib3 @ https://github.com/urllib3/urllib3/archive/refs/tags/1.26.8.zip
|
||||
|
||||
# It is possible to refer to other requirement files or constraints files.
|
||||
-r other-requirements.txt
|
||||
-c constraints.txt
|
||||
|
||||
# It is possible to refer to specific local distribution paths.
|
||||
./downloads/numpy-1.9.2-cp34-none-win32.whl
|
||||
|
||||
# It is possible to refer to URLs.
|
||||
http://wxpython.org/Phoenix/snapshot-builds/wxPython_Phoenix-3.0.3.dev1820+49a8884-cp34-none-win_amd64.whl
|
||||
```
|
||||
|
||||
## Structure
|
||||
|
||||
Each line of the requirements file indicates something to be installed,
|
||||
or arguments to {ref}`pip install`. The following forms are supported:
|
||||
|
||||
- `[[--option]...]`
|
||||
- `<requirement specifier> [; markers] [[--option]...]`
|
||||
- `<requirement specifier>`
|
||||
- `<archive url/path>`
|
||||
- `[-e] <local project path>`
|
||||
- `[-e] <vcs project url>`
|
||||
|
@ -74,13 +99,21 @@ and two {ref}`--find-links <install_--find-links>` locations:
|
|||
```
|
||||
````
|
||||
|
||||
(per-requirement-options)=
|
||||
|
||||
### Per-requirement options
|
||||
|
||||
```{versionadded} 7.0
|
||||
|
||||
```
|
||||
|
||||
The options which can be applied to individual requirements are:
|
||||
|
||||
- {ref}`--install-option <install_--install-option>`
|
||||
- {ref}`--global-option <install_--global-option>`
|
||||
- `--hash` (for {ref}`Hash-Checking mode`)
|
||||
- {ref}`--config-settings <install_--config-settings>`
|
||||
- `--hash` (for {ref}`Hash-checking mode`)
|
||||
|
||||
## Referring to other requirements files
|
||||
|
||||
If you wish, you can refer to other requirements files, like this:
|
||||
|
||||
|
@ -118,30 +151,29 @@ and only specify the variable name for your requirements, letting pip lookup
|
|||
the value at runtime. This approach aligns with the commonly used
|
||||
[12-factor configuration pattern](https://12factor.net/config).
|
||||
|
||||
## Example
|
||||
|
||||
## Influencing the build system
|
||||
|
||||
```{danger}
|
||||
This disables the use of wheels (cached or otherwise). This could mean that builds will be slower, less deterministic, less reliable and may not behave correctly upon installation.
|
||||
|
||||
This mechanism is only preserved for backwards compatibility and should be considered deprecated. A future release of pip may drop these options.
|
||||
```
|
||||
###### Requirements without Version Specifiers ######
|
||||
pytest
|
||||
pytest-cov
|
||||
beautifulsoup4
|
||||
|
||||
###### Requirements with Version Specifiers ######
|
||||
# See https://www.python.org/dev/peps/pep-0440/#version-specifiers
|
||||
docopt == 0.6.1 # Version Matching. Must be version 0.6.1
|
||||
keyring >= 4.1.1 # Minimum version 4.1.1
|
||||
coverage != 3.5 # Version Exclusion. Anything except version 3.5
|
||||
Mopidy-Dirble ~= 1.1 # Compatible release. Same as >= 1.1, == 1.*
|
||||
The `--global-option` option is used to pass options to `setup.py`.
|
||||
|
||||
###### Refer to other requirements files ######
|
||||
-r other-requirements.txt
|
||||
```{attention}
|
||||
These options are highly coupled with how pip invokes setuptools using the {doc}`../reference/build-system/setup-py` build system interface. It is not compatible with newer {doc}`../reference/build-system/pyproject-toml` build system interface.
|
||||
|
||||
###### A particular file ######
|
||||
./downloads/numpy-1.9.2-cp34-none-win32.whl
|
||||
http://wxpython.org/Phoenix/snapshot-builds/wxPython_Phoenix-3.0.3.dev1820+49a8884-cp34-none-win_amd64.whl
|
||||
|
||||
###### Additional Requirements without Version Specifiers ######
|
||||
# Same as 1st section, just here to show that you can put things in any order.
|
||||
rejected
|
||||
green
|
||||
This is will not work with other build-backends or newer setup.cfg-only projects.
|
||||
```
|
||||
|
||||
If you have a declaration like:
|
||||
|
||||
FooProject >= 1.2 --global-option="--no-user-cfg"
|
||||
|
||||
The above translates roughly into running FooProject's `setup.py` script as:
|
||||
|
||||
python setup.py --no-user-cfg install
|
||||
|
||||
Note that the only way of giving more than one option to `setup.py` is through multiple `--global-option` options.
|
||||
|
|
|
@ -66,12 +66,120 @@ man pages][netrc-docs].
|
|||
## Keyring Support
|
||||
|
||||
pip supports loading credentials stored in your keyring using the
|
||||
{pypi}`keyring` library.
|
||||
{pypi}`keyring` library, which can be enabled py passing `--keyring-provider`
|
||||
with a value of `auto`, `disabled`, `import`, or `subprocess`. The default
|
||||
value `auto` respects `--no-input` and not query keyring at all if the option
|
||||
is used; otherwise it tries the `import`, `subprocess`, and `disabled`
|
||||
providers (in this order) and uses the first one that works.
|
||||
|
||||
### Configuring pip's keyring usage
|
||||
|
||||
Since the keyring configuration is likely system-wide, a more common way to
|
||||
configure its usage would be to use a configuration instead:
|
||||
|
||||
```{seealso}
|
||||
{doc}`./configuration` describes how pip configuration works.
|
||||
```
|
||||
|
||||
```bash
|
||||
$ pip install keyring # install keyring from PyPI
|
||||
$ pip config set --global global.keyring-provider subprocess
|
||||
|
||||
# A different user on the same system which has PYTHONPATH configured and and
|
||||
# wanting to use keyring installed that way could then run
|
||||
$ pip config set --user global.keyring-provider import
|
||||
|
||||
# For a specific virtual environment you might want to use disable it again
|
||||
# because you will only be using PyPI and the private repo (and mirror)
|
||||
# requires 2FA with a keycard and a pincode
|
||||
$ pip config set --site global.index https://pypi.org/simple
|
||||
$ pip config set --site global.keyring-provider disabled
|
||||
|
||||
# configuring it via environment variable is also possible
|
||||
$ export PIP_KEYRING_PROVIDER=disabled
|
||||
```
|
||||
|
||||
### Using keyring's Python module
|
||||
|
||||
Setting `keyring-provider` to `import` makes pip communicate with `keyring` via
|
||||
its Python interface.
|
||||
|
||||
```bash
|
||||
# install keyring from PyPI
|
||||
$ pip install keyring --index-url https://pypi.org/simple
|
||||
$ echo "your-password" | keyring set pypi.company.com your-username
|
||||
$ pip install your-package --index-url https://pypi.company.com/
|
||||
$ pip install your-package --keyring-provider import --index-url https://pypi.company.com/
|
||||
```
|
||||
|
||||
### Using keyring as a command line application
|
||||
|
||||
Setting `keyring-provider` to `subprocess` makes pip look for and use the
|
||||
`keyring` command found on `PATH`.
|
||||
|
||||
For this use case, a username *must* be included in the URL, since it is
|
||||
required by `keyring`'s command line interface. See the example below or the
|
||||
basic HTTP authentication section at the top of this page.
|
||||
|
||||
```bash
|
||||
# Install keyring from PyPI using pipx, which we assume is installed properly
|
||||
# you can also create a venv somewhere and add it to the PATH yourself instead
|
||||
$ pipx install keyring --index-url https://pypi.org/simple
|
||||
|
||||
# For Azure DevOps, also install its keyring backend.
|
||||
$ pipx inject keyring artifacts-keyring --index-url https://pypi.org/simple
|
||||
|
||||
# For Google Artifact Registry, also install and initialize its keyring backend.
|
||||
$ pipx inject keyring keyrings.google-artifactregistry-auth --index-url https://pypi.org/simple
|
||||
$ gcloud auth login
|
||||
|
||||
# Note that a username is required in the index URL.
|
||||
$ pip install your-package --keyring-provider subprocess --index-url https://username@pypi.example.com/
|
||||
```
|
||||
|
||||
### Here be dragons
|
||||
|
||||
The `auto` provider is conservative and does not query keyring at all when
|
||||
`--no-input` is used because the keyring might require user interaction such as
|
||||
prompting the user on the console. Third party tools frequently call Pip for
|
||||
you and do indeed pass `--no-input` as they are well-behaved and don't have
|
||||
much information to work with. (Keyring does have an api to request a backend
|
||||
that does not require user input.) You have more information about your system,
|
||||
however!
|
||||
|
||||
You can force keyring usage by requesting a keyring provider other than `auto`
|
||||
(or `disabled`). Leaving `import` and `subprocess`. You do this by passing
|
||||
`--keyring-provider import` or one of the following methods:
|
||||
|
||||
```bash
|
||||
# via config file, possibly with --user, --global or --site
|
||||
$ pip config set global.keyring-provider subprocess
|
||||
# or via environment variable
|
||||
$ export PIP_KEYRING_PROVIDER=import
|
||||
```
|
||||
|
||||
```{warning}
|
||||
Be careful when doing this since it could cause tools such as pipx and Pipenv
|
||||
to appear to hang. They show their own progress indicator while hiding output
|
||||
from the subprocess in which they run Pip. You won't know whether the keyring
|
||||
backend is waiting the user input or not in such situations.
|
||||
```
|
||||
|
||||
pip is conservative and does not query keyring at all when `--no-input` is used
|
||||
because the keyring might require user interaction such as prompting the user
|
||||
on the console. You can force keyring usage by passing `--force-keyring` or one
|
||||
of the following:
|
||||
|
||||
```bash
|
||||
# possibly with --user, --global or --site
|
||||
$ pip config set global.force-keyring true
|
||||
# or
|
||||
$ export PIP_FORCE_KEYRING=1
|
||||
```
|
||||
|
||||
```{warning}
|
||||
Be careful when doing this since it could cause tools such as pipx and Pipenv
|
||||
to appear to hang. They show their own progress indicator while hiding output
|
||||
from the subprocess in which they run Pip. You won't know whether the keyring
|
||||
backend is waiting the user input or not in such situations.
|
||||
```
|
||||
|
||||
Note that `keyring` (the Python package) needs to be installed separately from
|
||||
|
@ -79,5 +187,4 @@ pip. This can create a bootstrapping issue if you need the credentials stored in
|
|||
the keyring to download and install keyring.
|
||||
|
||||
It is, thus, expected that users that wish to use pip's keyring support have
|
||||
some mechanism for downloading and installing {pypi}`keyring` in their Python
|
||||
environment.
|
||||
some mechanism for downloading and installing {pypi}`keyring`.
|
||||
|
|
|
@ -50,6 +50,43 @@ pip now caches wheels when building from an immutable Git reference
|
|||
(i.e. a commit hash).
|
||||
```
|
||||
|
||||
## Where is the cache stored
|
||||
|
||||
```{caution}
|
||||
The exact filesystem structure of pip's cache's contents is considered to be
|
||||
an implementation detail and may change between any two versions of pip.
|
||||
```
|
||||
|
||||
### `pip cache dir`
|
||||
|
||||
```{versionadded} 20.1
|
||||
|
||||
```
|
||||
|
||||
You can use `pip cache dir` to get the cache directory that pip is currently configured to use.
|
||||
|
||||
### Default paths
|
||||
|
||||
````{tab} Linux
|
||||
```
|
||||
~/.cache/pip
|
||||
```
|
||||
|
||||
pip will also respect `XDG_CACHE_HOME`.
|
||||
````
|
||||
|
||||
````{tab} MacOS
|
||||
```
|
||||
~/Library/Caches/pip
|
||||
```
|
||||
````
|
||||
|
||||
````{tab} Windows
|
||||
```
|
||||
%LocalAppData%\pip\Cache
|
||||
```
|
||||
````
|
||||
|
||||
## Avoiding caching
|
||||
|
||||
pip tries to use its cache whenever possible, and it is designed do the right
|
||||
|
@ -59,7 +96,7 @@ In some cases, pip's caching behaviour can be undesirable. As an example, if you
|
|||
have package with optional C extensions, that generates a pure Python wheel
|
||||
when the C extension can’t be built, pip will use that cached wheel even when
|
||||
you later invoke it from an environment that could have built those optional C
|
||||
extensions. This is because pip is seeing a cached wheel for that matches the
|
||||
extensions. This is because pip is seeing a cached wheel that matches the
|
||||
package being built, and pip assumes that the result of building a package from
|
||||
a package index is deterministic.
|
||||
|
||||
|
@ -81,13 +118,28 @@ It is also a good idea to remove the offending cached wheel using the
|
|||
|
||||
The {ref}`pip cache` command can be used to manage pip's cache.
|
||||
|
||||
The exact filesystem structure of pip's cache is considered to be an
|
||||
implementation detail and may change between any two versions of pip.
|
||||
### General overview
|
||||
|
||||
`pip cache info` provides an overview of the contents of pip's cache, such as the total size and location of various parts of it.
|
||||
|
||||
### Removing a single package
|
||||
|
||||
`pip cache remove setuptools` removes all wheel files related to setuptools from pip's cache.
|
||||
|
||||
### Removing the cache
|
||||
|
||||
`pip cache purge` will clear all wheel files from pip's cache.
|
||||
|
||||
### Listing cached files
|
||||
|
||||
`pip cache list` will list all wheel files from pip's cache.
|
||||
|
||||
`pip cache list setuptools` will list all setuptools-related wheel files from pip's cache.
|
||||
|
||||
## Disabling caching
|
||||
|
||||
pip's caching behaviour is disabled by passing the `--no-cache-dir` option.
|
||||
|
||||
It is, however, recommended to **NOT** disable pip's caching. Doing so can
|
||||
It is, however, recommended to **NOT** disable pip's caching unless you have caching at a higher level (eg: layered caches in container builds). Doing so can
|
||||
significantly slow down pip (due to repeated operations and package builds)
|
||||
and result in significantly more network usage.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
(configuration)=
|
||||
|
||||
# Configuration
|
||||
|
||||
pip allows a user to change its behaviour via 3 mechanisms:
|
||||
|
@ -9,15 +11,22 @@ pip allows a user to change its behaviour via 3 mechanisms:
|
|||
This page explains how the configuration files and environment variables work,
|
||||
and how they are related to pip's various command line options.
|
||||
|
||||
```{seealso}
|
||||
{doc}`../cli/pip_config` command, which helps manage pip's configuration.
|
||||
```
|
||||
|
||||
(config-file)=
|
||||
|
||||
## Configuration Files
|
||||
|
||||
Configuration files can change the default values for command line option.
|
||||
They are written using a standard INI style configuration files.
|
||||
Configuration files can change the default values for command line options.
|
||||
They are written using standard INI style configuration files.
|
||||
|
||||
pip has 3 "levels" of configuration files:
|
||||
pip has 4 "levels" of configuration files:
|
||||
|
||||
- `global`: system-wide configuration file, shared across users.
|
||||
- `user`: per-user configuration file.
|
||||
- `global`: system-wide configuration file, shared across all users.
|
||||
- `user`: per-user configuration file, shared across all environments.
|
||||
- `base` : per-base environment configuration file, shared across all virtualenvs with the same base. (available since pip 23.0)
|
||||
- `site`: per-environment configuration file; i.e. per-virtualenv.
|
||||
|
||||
### Location
|
||||
|
@ -39,6 +48,9 @@ User
|
|||
|
||||
The legacy "per-user" configuration file is also loaded, if it exists: {file}`$HOME/.pip/pip.conf`.
|
||||
|
||||
Base
|
||||
: {file}`\{sys.base_prefix\}/pip.conf`
|
||||
|
||||
Site
|
||||
: {file}`$VIRTUAL_ENV/pip.conf`
|
||||
```
|
||||
|
@ -55,6 +67,9 @@ User
|
|||
|
||||
The legacy "per-user" configuration file is also loaded, if it exists: {file}`$HOME/.pip/pip.conf`.
|
||||
|
||||
Base
|
||||
: {file}`\{sys.base_prefix\}/pip.conf`
|
||||
|
||||
Site
|
||||
: {file}`$VIRTUAL_ENV/pip.conf`
|
||||
```
|
||||
|
@ -73,6 +88,9 @@ User
|
|||
|
||||
The legacy "per-user" configuration file is also loaded, if it exists: {file}`%HOME%\\pip\\pip.ini`
|
||||
|
||||
Base
|
||||
: {file}`\{sys.base_prefix\}\\pip.ini`
|
||||
|
||||
Site
|
||||
: {file}`%VIRTUAL_ENV%\\pip.ini`
|
||||
```
|
||||
|
@ -84,6 +102,8 @@ a configuration file that's loaded first, and whose values are overridden by
|
|||
the values set in the aforementioned files. Setting this to {any}`os.devnull`
|
||||
disables the loading of _all_ configuration files.
|
||||
|
||||
(config-precedence)=
|
||||
|
||||
### Loading order
|
||||
|
||||
When multiple configuration files are found, pip combines them in the following
|
||||
|
@ -92,6 +112,7 @@ order:
|
|||
- `PIP_CONFIG_FILE`, if given.
|
||||
- Global
|
||||
- User
|
||||
- Base
|
||||
- Site
|
||||
|
||||
Each file read overrides any values read from previous files, so if the
|
||||
|
@ -213,9 +234,9 @@ Use `no`, `false` or `0` instead.
|
|||
|
||||
## Precedence / Override order
|
||||
|
||||
Command line options have override environment variables, which override the
|
||||
Command line options override environment variables, which override the
|
||||
values in a configuration file. Within the configuration file, values in
|
||||
command-specific sections over values in the global section.
|
||||
command-specific sections override values in the global section.
|
||||
|
||||
Examples:
|
||||
|
||||
|
|
|
@ -155,12 +155,14 @@ how to inspect:
|
|||
- their release notes and changelogs from past versions
|
||||
|
||||
During deployment, you can create a lockfile stating the exact package and
|
||||
version number for for each dependency of that package. You can create this
|
||||
with `pip-tools <https://github.com/jazzband/pip-tools/>`\_\_.
|
||||
version number for each dependency of that package. You can create this
|
||||
with [pip-tools](https://github.com/jazzband/pip-tools/).
|
||||
|
||||
This means the "work" is done once during development process, and thus
|
||||
will avoid performing dependency resolution during deployment.
|
||||
|
||||
(Fixing conflicting dependencies)=
|
||||
|
||||
## Dealing with dependency conflicts
|
||||
|
||||
This section provides practical suggestions to pip users who encounter
|
||||
|
@ -277,10 +279,10 @@ your _dependency_ by:
|
|||
- Requesting that the package maintainers loosen _their_ dependencies
|
||||
- Forking the package and loosening the dependencies yourself
|
||||
|
||||
:::{warning}
|
||||
```{warning}
|
||||
If you choose to fork the package yourself, you are _opting out_ of
|
||||
any support provided by the package maintainers. Proceed at your own risk!
|
||||
:::
|
||||
```
|
||||
|
||||
#### All requirements are appropriate, but a solution does not exist
|
||||
|
||||
|
|
19
docs/html/topics/deps.dot
Normal file
19
docs/html/topics/deps.dot
Normal file
|
@ -0,0 +1,19 @@
|
|||
digraph G {
|
||||
graph [fontname = "Handlee"];
|
||||
node [fontname = "Handlee"];
|
||||
edge [fontname = "Handlee"];
|
||||
|
||||
bgcolor=transparent;
|
||||
|
||||
A [color=blue fontcolor=blue];
|
||||
A -> B [color=red];
|
||||
A -> C [color=red];
|
||||
node [color=lightgrey fontcolor=lightgrey];
|
||||
edge [color=lightgrey];
|
||||
node [color=lightgrey];
|
||||
B -> B1;
|
||||
B -> B2;
|
||||
C -> C1;
|
||||
C -> C2;
|
||||
|
||||
}
|
BIN
docs/html/topics/deps.png
Normal file
BIN
docs/html/topics/deps.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
71
docs/html/topics/https-certificates.md
Normal file
71
docs/html/topics/https-certificates.md
Normal file
|
@ -0,0 +1,71 @@
|
|||
(SSL Certificate Verification)=
|
||||
|
||||
# HTTPS Certificates
|
||||
|
||||
```{versionadded} 1.3
|
||||
|
||||
```
|
||||
|
||||
By default, pip will perform SSL certificate verification for network
|
||||
connections it makes over HTTPS. These serve to prevent man-in-the-middle
|
||||
attacks against package downloads. This does not use the system certificate
|
||||
store but, instead, uses a bundled CA certificate store from {pypi}`certifi`.
|
||||
|
||||
## Using a specific certificate store
|
||||
|
||||
The `--cert` option (and the corresponding `PIP_CERT` environment variable)
|
||||
allow users to specify a different certificate store/bundle for pip to use. It
|
||||
is also possible to use `REQUESTS_CA_BUNDLE` or `CURL_CA_BUNDLE` environment
|
||||
variables.
|
||||
|
||||
## Using system certificate stores
|
||||
|
||||
```{versionadded} 22.2
|
||||
Experimental support, behind `--use-feature=truststore`.
|
||||
```
|
||||
|
||||
It is possible to use the system trust store, instead of the bundled certifi
|
||||
certificates for verifying HTTPS certificates. This approach will typically
|
||||
support corporate proxy certificates without additional configuration.
|
||||
|
||||
In order to use system trust stores, you need to:
|
||||
|
||||
- Use Python 3.10 or newer.
|
||||
- Install the {pypi}`truststore` package, in the Python environment you're
|
||||
running pip in.
|
||||
|
||||
This is typically done by installing this package using a system package
|
||||
manager or by using pip in {ref}`Hash-checking mode` for this package and
|
||||
trusting the network using the `--trusted-host` flag.
|
||||
|
||||
```{pip-cli}
|
||||
$ python -m pip install truststore
|
||||
[...]
|
||||
$ python -m pip install SomePackage --use-feature=truststore
|
||||
[...]
|
||||
Successfully installed SomePackage
|
||||
```
|
||||
|
||||
### When to use
|
||||
|
||||
You should try using system trust stores when there is a custom certificate
|
||||
chain configured for your system that pip isn't aware of. Typically, this
|
||||
situation will manifest with an `SSLCertVerificationError` with the message
|
||||
"certificate verify failed: unable to get local issuer certificate":
|
||||
|
||||
```{pip-cli}
|
||||
$ pip install -U SomePackage
|
||||
[...]
|
||||
SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (\_ssl.c:997)'))) - skipping
|
||||
```
|
||||
|
||||
This error means that OpenSSL wasn't able to find a trust anchor to verify the
|
||||
chain against. Using system trust stores instead of certifi will likely solve
|
||||
this issue.
|
||||
|
||||
If you encounter a TLS/SSL error when using the `truststore` feature you should
|
||||
open an issue on the [truststore GitHub issue tracker] instead of pip's issue
|
||||
tracker. The maintainers of truststore will help diagnose and fix the issue.
|
||||
|
||||
[truststore github issue tracker]:
|
||||
https://github.com/sethmlarson/truststore/issues
|
|
@ -14,6 +14,11 @@ authentication
|
|||
caching
|
||||
configuration
|
||||
dependency-resolution
|
||||
more-dependency-resolution
|
||||
https-certificates
|
||||
local-project-installs
|
||||
repeatable-installs
|
||||
secure-installs
|
||||
vcs-support
|
||||
python-option
|
||||
```
|
||||
|
|
67
docs/html/topics/local-project-installs.md
Normal file
67
docs/html/topics/local-project-installs.md
Normal file
|
@ -0,0 +1,67 @@
|
|||
# Local project installs
|
||||
|
||||
It is extremely common to have a project, available in a folder/directory on your computer [^1] that you wish to install.
|
||||
|
||||
With pip, depending on your usecase, there are two ways to do this:
|
||||
|
||||
- A regular install
|
||||
- An editable install
|
||||
|
||||
## Regular installs
|
||||
|
||||
You can install local projects by specifying the project path to pip:
|
||||
|
||||
```{pip-cli}
|
||||
$ pip install path/to/SomeProject
|
||||
```
|
||||
|
||||
This will install the project into the Python that pip is associated with, in a manner similar to how it would actually be installed.
|
||||
|
||||
This is what should be used in CI system and for deployments, since it most closely mirrors how a package would get installed if you build a distribution and installed from it (because that's _exactly_ what it does).
|
||||
|
||||
(editable-installs)=
|
||||
|
||||
## Editable installs
|
||||
|
||||
You can install local projects in "editable" mode:
|
||||
|
||||
```{pip-cli}
|
||||
$ pip install -e path/to/SomeProject
|
||||
```
|
||||
|
||||
Editable installs allow you to install your project without copying any files. Instead, the files in the development directory are added to Python's import path. This approach is well suited for development and is also known as a "development installation".
|
||||
|
||||
With an editable install, you only need to perform a re-installation if you change the project metadata (eg: version, what scripts need to be generated etc). You will still need to run build commands when you need to perform a compilation for non-Python code in the project (eg: C extensions).
|
||||
|
||||
```{caution}
|
||||
It is possible to see behaviour differences between regular installs vs editable installs. These differences depend on the build-backend, and you should check the build-backend documentation for the details. In case you distribute the project as a "distribution package", users will see the behaviour of regular installs -- thus, it is important to ensure that regular installs work correctly.
|
||||
```
|
||||
|
||||
```{note}
|
||||
This is functionally the same as [setuptools' develop mode], and that's precisely the mechanism used for setuptools-based projects.
|
||||
|
||||
There are two advantages over using `setup.py develop` directly:
|
||||
|
||||
- This works with non-setuptools build-backends as well.
|
||||
- The ".egg-info" directory is created relative to the project path, when using pip. This is generally a better location than setuptools, which dumps it in the current working directory.
|
||||
```
|
||||
|
||||
[setuptools' develop mode]: https://setuptools.readthedocs.io/en/latest/userguide/development_mode.html
|
||||
|
||||
## Build artifacts
|
||||
|
||||
```{versionchanged} 21.3
|
||||
The project being installed is no longer copied to a temporary directory before invoking the build system, by default. A `--use-deprecated=out-of-tree-build` option is provided as a temporary fallback to aid user migrations.
|
||||
```
|
||||
|
||||
```{versionchanged} 22.1
|
||||
The `--use-deprecated=out-of-tree-build` option has been removed.
|
||||
```
|
||||
|
||||
When provided with a project that's in a local directory, pip will invoke the build system "in place". This behaviour has several consequences:
|
||||
|
||||
- Local project builds will now be significantly faster, for certain kinds of projects and on systems with slow I/O (eg: via network attached storage or overly aggressive antivirus software).
|
||||
- Certain build backends (eg: `setuptools`) will litter the project directory with secondary build artifacts (eg: `.egg-info` directories).
|
||||
- Certain build backends (eg: `setuptools`) may not be able to perform with parallel builds anymore, since they previously relied on the fact that pip invoked them in a separate directory for each build.
|
||||
|
||||
[^1]: Specifically, the current machine's filesystem.
|
168
docs/html/topics/more-dependency-resolution.md
Normal file
168
docs/html/topics/more-dependency-resolution.md
Normal file
|
@ -0,0 +1,168 @@
|
|||
# More on Dependency Resolution
|
||||
|
||||
This article goes into more detail about pip's dependency resolution algorithm.
|
||||
In certain situations, pip can take a long time to determine what to install,
|
||||
and this article is intended to help readers understand what is happening
|
||||
"behind the scenes" during that process.
|
||||
|
||||
```{note}
|
||||
This document is a work in progress. The details included are accurate (at the
|
||||
time of writing), but there is additional information, in particular around
|
||||
pip's interface with resolvelib, which have not yet been included.
|
||||
|
||||
Contributions to improve this document are welcome.
|
||||
```
|
||||
|
||||
## The dependency resolution problem
|
||||
|
||||
The process of finding a set of packages to install, given a set of dependencies
|
||||
between them, is known to be an [NP-hard](https://en.wikipedia.org/wiki/NP-hardness)
|
||||
problem. What this means in practice is roughly that the process scales
|
||||
*extremely* badly as the size of the problem increases. So when you have a lot
|
||||
of dependencies, working out what to install will, in the worst case, take a
|
||||
very long time.
|
||||
|
||||
The practical implication of that is that there will always be some situations
|
||||
where pip cannot determine what to install in a reasonable length of time. We
|
||||
make every effort to ensure that such situations happen rarely, but eliminating
|
||||
them altogether isn't even theoretically possible. We'll discuss what options
|
||||
yopu have if you hit a problem situation like this a little later.
|
||||
|
||||
## Python specific issues
|
||||
|
||||
Many algorithms for handling dependency resolution assume that you know the
|
||||
full details of the problem at the start - that is, you know all of the
|
||||
dependencies up front. Unfortunately, that is not the case for Python packages.
|
||||
With the current package index structure, dependency metadata is only available
|
||||
by downloading the package file, and extracting the data from it. And in the
|
||||
case of source distributions, the situation is even worse as the project must
|
||||
be built after being downloaded in order to determine the dependencies.
|
||||
|
||||
Work is ongoing to try to make metadata more readily available at lower cost,
|
||||
but at the time of writing, this has not been completed.
|
||||
|
||||
As downloading projects is a costly operation, pip cannot pre-compute the full
|
||||
dependency tree. This means that we are unable to use a number of techniques
|
||||
for solving the dependency resolution problem. In practice, we have to use a
|
||||
*backtracking algorithm*.
|
||||
|
||||
## Dependency metadata
|
||||
|
||||
It is worth discussing precisely what metadata is needed in order to drive the
|
||||
package resolution process. There are essentially three key pieces of
|
||||
information:
|
||||
|
||||
* The project name
|
||||
* The release version
|
||||
* The dependencies themselves
|
||||
|
||||
There are other pieces of data (e.g., extras, python version restrictions, wheel
|
||||
compatibility tags) which are used as well, but they do not fundamentally
|
||||
alter the process, so we will ignore them here.
|
||||
|
||||
The most important information is the project name and version. Those two pieces
|
||||
of information identify an individual "candidate" for installation, and must
|
||||
uniquely identify such a candidate. Name and version must be available from the
|
||||
moment the candidate object is created. This is not an issue for distribution
|
||||
files (sdists and wheels) as that data is available from the filename, but for
|
||||
unpackaged source trees, pip needs to call the build backend to ask for that
|
||||
data. This is done before resolution proper starts.
|
||||
|
||||
The dependency data is *not* requested in advance (as noted above, doing so
|
||||
would be prohibitively costly, and for a backtracking algorithm it isn't
|
||||
needed). Instead, pip requests dependency data "on demand", as the algorithm
|
||||
starts to check that particular candidate.
|
||||
|
||||
One particular implication of the lazy fetching of dependency data is that
|
||||
often, pip *does not know* things that might be obvious to a human looking at
|
||||
the dependency tree as a whole. For example, if package A depends on version
|
||||
1.0 of package B, it's obvious to a human that there's no point in looking at
|
||||
other versions of package B. But if pip starts looking at B before it has
|
||||
considered A, it doesn't have access to A's dependency data, and so has no way
|
||||
of knowing that looking at other versions of B is wasted work. And worse still,
|
||||
pip cannot even know that there's vital information in A's dependencies.
|
||||
|
||||
This latter point is a common theme with many cases where pip takes a long time
|
||||
to complete a resolution - there's information pip doesn't know at the point
|
||||
where it makes a "wrong" choice. Most of the heuristics added to the resolver
|
||||
to guide the algorithm are designed to guess correctly in the face of that
|
||||
lack of knowledge.
|
||||
|
||||
## The resolver and the finder
|
||||
|
||||
So far, we have been talking about the "resolver" as a single entity. While that
|
||||
is mostly true, the process of getting package data from an index is handled
|
||||
by another component of pip, the "finder". The finder is responsible for
|
||||
feeding candidates to the resolver, and has a key role to play in selecting
|
||||
suitable candidates.
|
||||
|
||||
Note that the resolver is *only* relevant for packages fetched from an index.
|
||||
Candidates coming from other sources (local source directories, PEP 508
|
||||
direct URL references) do *not* go through the finder, and are merged with the
|
||||
candidates provided by the finder as part of the resolver's "provider"
|
||||
implementation.
|
||||
|
||||
As well as determining what versions exist in the index for a given project,
|
||||
the finder selects the best distribution file to use for that candidate. This
|
||||
may be a wheel or a source distribution, and precisely what is selected is
|
||||
controlled by wheel compatibility tags, pip's options (whether to prefer binary
|
||||
or source) and metadata supplied by the index. In particular, if a file is
|
||||
marked as only being for specific Python versions, the file will be ignored by
|
||||
the finder (and the resolver may never even see that version).
|
||||
|
||||
The finder also provides candidates for a project to the resolver in order of
|
||||
preference - the provider implements the rule that later versions are preferred
|
||||
over older versions, for example.
|
||||
|
||||
## The resolver algorithm
|
||||
|
||||
The resolver itself is based on a separate package, [resolvelib](https://pypi.org/project/resolvelib/).
|
||||
This implements an abstract backtracking resolution algorithm, in a way that is
|
||||
independent of the specifics of Python packages - those specifics are abstracted
|
||||
away by pip before calling the resolver.
|
||||
|
||||
Pip's interface to resolvelib is in the form of a "provider", which is the
|
||||
interface between pip's model of packages and the resolution algorithm. The
|
||||
provider deals in "candidates" and "requirements" and implements the following
|
||||
operations:
|
||||
|
||||
* `identify` - implements identity for candidates and requirements. It is this
|
||||
operation that implements the rule that candidates are identified by their
|
||||
name and version, for example.
|
||||
* `get_preference` - this provides information to the resolver to help it choose
|
||||
which requirement to look at "next" when working through the resolution
|
||||
process.
|
||||
* `find_matches` - given a set of constraints, determine what candidates exist
|
||||
that satisfy them. This is essentially where the finder interacts with the
|
||||
resolver.
|
||||
* `is_satisfied_by` - checks if a candidate satisfies a requirement. This is
|
||||
basically the implementation of what a requirement meams.
|
||||
* `get_dependencies` - get the dependency metadata for a candidate. This is
|
||||
the implementation of the process of getting and reading package metadata.
|
||||
|
||||
Of these methods, the only non-trivial one is the `get_preference` method. This
|
||||
implements the heuristics used to guide the resolution, telling it which
|
||||
requirement to try to satisfy next. It's this method that is responsible for
|
||||
trying to guess which route through the dependency tree will be most productive.
|
||||
As noted above, it's doing this with limited information. See the following
|
||||
diagram
|
||||
|
||||
![](deps.png)
|
||||
|
||||
When the provider is asked to choose between the red requirements (A->B and
|
||||
A->C) it doesn't know anything about the dependencies of B or C (i.e., the
|
||||
grey parts of the graph).
|
||||
|
||||
Pip's current implementation of the provider implements `get_preference` as
|
||||
follows:
|
||||
|
||||
* Prefer if any of the known requirements is "direct", e.g. points to an
|
||||
explicit URL.
|
||||
* If equal, prefer if any requirement is "pinned", i.e. contains
|
||||
operator ``===`` or ``==``.
|
||||
* If equal, calculate an approximate "depth" and resolve requirements
|
||||
closer to the user-specified requirements first.
|
||||
* Order user-specified requirements by the order they are specified.
|
||||
* If equal, prefers "non-free" requirements, i.e. contains at least one
|
||||
operator, such as ``>=`` or ``<``.
|
||||
* If equal, order alphabetically for consistency (helps debuggability).
|
29
docs/html/topics/python-option.md
Normal file
29
docs/html/topics/python-option.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Managing a different Python interpreter
|
||||
|
||||
```{versionadded} 22.3
|
||||
```
|
||||
|
||||
Occasionally, you may want to use pip to manage a Python installation other than
|
||||
the one pip is installed into. In this case, you can use the `--python` option
|
||||
to specify the interpreter you want to manage. This option can take one of two
|
||||
values:
|
||||
|
||||
1. The path to a Python executable.
|
||||
2. The path to a virtual environment.
|
||||
|
||||
In both cases, pip will run exactly as if it had been invoked from that Python
|
||||
environment.
|
||||
|
||||
One example of where this might be useful is to manage a virtual environment
|
||||
that does not have pip installed.
|
||||
|
||||
```{pip-cli}
|
||||
$ python -m venv .venv --without-pip
|
||||
$ pip --python .venv install SomePackage
|
||||
[...]
|
||||
Successfully installed SomePackage
|
||||
```
|
||||
|
||||
You could also use `--python .venv/bin/python` (or on Windows,
|
||||
`--python .venv\Scripts\python.exe`) if you wanted to be explicit, but the
|
||||
virtual environment name is shorter and works exactly the same.
|
|
@ -1,3 +1,4 @@
|
|||
(repeatability)=
|
||||
# Repeatable Installs
|
||||
|
||||
pip can be used to achieve various levels of repeatable environments. This page
|
||||
|
@ -19,7 +20,7 @@ specific version.
|
|||
```
|
||||
|
||||
A requirements file, containing pinned package versions can be generated using
|
||||
{ref}`pip freeze`. This would not only the top-level packages, but also all of
|
||||
{ref}`pip freeze`. This would pin not only the top-level packages, but also all of
|
||||
their transitive dependencies. Performing the installation using
|
||||
{ref}`--no-deps <install_--no-deps>` would provide an extra dose of insurance
|
||||
against installing anything not explicitly listed.
|
||||
|
|
100
docs/html/topics/secure-installs.md
Normal file
100
docs/html/topics/secure-installs.md
Normal file
|
@ -0,0 +1,100 @@
|
|||
# Secure installs
|
||||
|
||||
By default, pip does not perform any checks to protect against remote tampering and involves running arbitrary code from distributions. It is, however, possible to use pip in a manner that changes these behaviours, to provide a more secure installation mechanism.
|
||||
|
||||
This can be achieved by doing the following:
|
||||
|
||||
- Enable {ref}`Hash-checking mode`, by passing {any}`--require-hashes`
|
||||
- Disallow source distributions, by passing {any}`--only-binary :all: <--only-binary>`
|
||||
|
||||
(Hash-checking mode)=
|
||||
|
||||
## Hash-checking Mode
|
||||
|
||||
```{versionadded} 8.0
|
||||
|
||||
```
|
||||
|
||||
This mode uses local hashes, embedded in a requirements.txt file, to protect against remote tampering and network issues. These hashes are specified using a `--hash` [per requirement option](per-requirement-options).
|
||||
|
||||
Note that hash-checking is an all-or-nothing proposition. Specifying `--hash` against _any_ requirement will activate this mode globally.
|
||||
|
||||
To add hashes for a package, add them to line as follows:
|
||||
|
||||
```
|
||||
FooProject == 1.2 \
|
||||
--hash=sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 \
|
||||
--hash=sha256:486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7
|
||||
```
|
||||
|
||||
### Additional restrictions
|
||||
|
||||
- Hashes are required for _all_ requirements.
|
||||
|
||||
This is because a partially-hashed requirements file is of little use and thus likely an error: a malicious actor could slip bad code into the installation via one of the unhashed requirements.
|
||||
|
||||
Note that hashes embedded in URL-style requirements via the `#md5=...` syntax suffice to satisfy this rule (regardless of hash strength, for legacy reasons), though you should use a stronger hash like sha256 whenever possible.
|
||||
|
||||
- Hashes are required for _all_ dependencies.
|
||||
|
||||
If there is a dependency that is not spelled out and hashed in the requirements file, it will result in an error.
|
||||
|
||||
- Requirements must be pinned (either to a URL, filesystem path or using `==`).
|
||||
|
||||
This prevents a surprising hash mismatch upon the release of a new version that matches the requirement specifier.
|
||||
|
||||
### Forcing Hash-checking mode
|
||||
|
||||
It is possible to force the hash checking mode to be enabled, by passing `--require-hashes` command-line option.
|
||||
|
||||
This can be useful in deploy scripts, to ensure that the author of the requirements file provided hashes. It is also a convenient way to bootstrap your list of hashes, since it shows the hashes of the packages it fetched. It fetches only the preferred archive for each package, so you may still need to add hashes for alternatives archives using {ref}`pip hash`: for instance if there is both a binary and a source distribution.
|
||||
|
||||
### Hash algorithms
|
||||
|
||||
The recommended hash algorithm at the moment is sha256, but stronger ones are allowed, including all those supported by `hashlib`. However, weaker ones such as md5, sha1, and sha224 are excluded to avoid giving a false sense of security.
|
||||
|
||||
### Multiple hashes per package
|
||||
|
||||
It is possible to use multiple hashes for each package. This is important when a package offers binary distributions for a variety of platforms or when it is important to allow both binary and source distributions.
|
||||
|
||||
### Interaction with caching
|
||||
|
||||
The {ref}`locally-built wheel cache <wheel-caching>` is disabled in hash-checking mode to prevent spurious hash mismatch errors.
|
||||
|
||||
These would otherwise occur while installing sdists that had already been automatically built into cached wheels: those wheels would be selected for installation, but their hashes would not match the sdist ones from the requirements file.
|
||||
|
||||
A further complication is that locally built wheels are nondeterministic: contemporary modification times make their way into the archive, making hashes unpredictable across machines and cache flushes. Compilation of C code adds further nondeterminism, as many compilers include random-seeded values in their output.
|
||||
|
||||
However, wheels fetched from index servers are required to be the same every time. They land in pip's HTTP cache, not its wheel cache, and are used normally in hash-checking mode. The only downside of having the wheel cache disabled is thus extra build time for sdists, and this can be solved by making sure pre-built wheels are available from the index server.
|
||||
|
||||
### Using hashes from PyPI (or other index servers)
|
||||
|
||||
PyPI (and certain other index servers) provides a hash for the distribution, in the fragment portion of each download URL, like `#sha256=123...`, which pip checks as a protection against download corruption.
|
||||
|
||||
Other hash algorithms that have guaranteed support from `hashlib` are also supported here: sha1, sha224, sha384, sha256, and sha512. Since this hash originates remotely, it is not a useful guard against tampering and thus does not satisfy the `--require-hashes` demand that every package have a local hash.
|
||||
|
||||
## Repeatable installs
|
||||
|
||||
Hash-checking mode also works with {ref}`pip download` and {ref}`pip wheel`. See {doc}`../topics/repeatable-installs` for a comparison of hash-checking mode with other repeatability strategies.
|
||||
|
||||
```{warning}
|
||||
Beware of the `setup_requires` keyword arg in {file}`setup.py`. The (rare) packages that use it will cause those dependencies to be downloaded by setuptools directly, skipping pip's hash-checking. If you need to use such a package, see {ref}`controlling setup_requires <controlling-setup_requires>`.
|
||||
```
|
||||
|
||||
## Do not use setuptools directly
|
||||
|
||||
Be careful not to nullify all your security work by installing your actual project by using setuptools' deprecated interfaces directly: for example, by calling `python setup.py install`, `python setup.py develop`, or `easy_install`.
|
||||
|
||||
These will happily go out and download, unchecked, anything you missed in your requirements file and it’s easy to miss things as your project evolves. To be safe, install your project using pip and {any}`--no-deps`.
|
||||
|
||||
Instead of `python setup.py install`, use:
|
||||
|
||||
```{pip-cli}
|
||||
$ pip install --no-deps .
|
||||
```
|
||||
|
||||
Instead of `python setup.py develop`, use:
|
||||
|
||||
```{pip-cli}
|
||||
$ pip install --no-deps -e .
|
||||
```
|
|
@ -1,3 +1,4 @@
|
|||
(vcs support)=
|
||||
# VCS Support
|
||||
|
||||
pip supports installing from various version control systems (VCS).
|
||||
|
@ -17,9 +18,9 @@ The supported schemes are `git+file`, `git+https`, `git+ssh`, `git+http`,
|
|||
`git+git` and `git`. Here are some of the supported forms:
|
||||
|
||||
```none
|
||||
git+ssh://git.example.com/MyProject#egg=MyProject
|
||||
git+file:///home/user/projects/MyProject#egg=MyProject
|
||||
git+https://git.example.com/MyProject#egg=MyProject
|
||||
MyProject @ git+ssh://git@git.example.com/MyProject
|
||||
MyProject @ git+file:///home/user/projects/MyProject
|
||||
MyProject @ git+https://git.example.com/MyProject
|
||||
```
|
||||
|
||||
```{warning}
|
||||
|
@ -34,10 +35,10 @@ It is also possible to specify a "git ref" such as branch name, a commit hash or
|
|||
a tag name:
|
||||
|
||||
```none
|
||||
git+https://git.example.com/MyProject.git@master#egg=MyProject
|
||||
git+https://git.example.com/MyProject.git@v1.0#egg=MyProject
|
||||
git+https://git.example.com/MyProject.git@da39a3ee5e6b4b0d3255bfef95601890afd80709#egg=MyProject
|
||||
git+https://git.example.com/MyProject.git@refs/pull/123/head#egg=MyProject
|
||||
MyProject @ git+https://git.example.com/MyProject.git@master
|
||||
MyProject @ git+https://git.example.com/MyProject.git@v1.0
|
||||
MyProject @ git+https://git.example.com/MyProject.git@da39a3ee5e6b4b0d3255bfef95601890afd80709
|
||||
MyProject @ git+https://git.example.com/MyProject.git@refs/pull/123/head
|
||||
```
|
||||
|
||||
When passing a commit hash, specifying a full hash is preferable to a partial
|
||||
|
@ -50,20 +51,20 @@ The supported schemes are `hg+file`, `hg+http`, `hg+https`, `hg+ssh`
|
|||
and `hg+static-http`. Here are some of the supported forms:
|
||||
|
||||
```
|
||||
hg+http://hg.myproject.org/MyProject#egg=MyProject
|
||||
hg+https://hg.myproject.org/MyProject#egg=MyProject
|
||||
hg+ssh://hg.myproject.org/MyProject#egg=MyProject
|
||||
hg+file:///home/user/projects/MyProject#egg=MyProject
|
||||
MyProject @ hg+http://hg.myproject.org/MyProject
|
||||
MyProject @ hg+https://hg.myproject.org/MyProject
|
||||
MyProject @ hg+ssh://hg.myproject.org/MyProject
|
||||
MyProject @ hg+file:///home/user/projects/MyProject
|
||||
```
|
||||
|
||||
It is also possible to specify a revision number, a revision hash, a tag name
|
||||
or a local branch name:
|
||||
|
||||
```none
|
||||
hg+http://hg.example.com/MyProject@da39a3ee5e6b#egg=MyProject
|
||||
hg+http://hg.example.com/MyProject@2019#egg=MyProject
|
||||
hg+http://hg.example.com/MyProject@v1.0#egg=MyProject
|
||||
hg+http://hg.example.com/MyProject@special_feature#egg=MyProject
|
||||
MyProject @ hg+http://hg.example.com/MyProject@da39a3ee5e6b
|
||||
MyProject @ hg+http://hg.example.com/MyProject@2019
|
||||
MyProject @ hg+http://hg.example.com/MyProject@v1.0
|
||||
MyProject @ hg+http://hg.example.com/MyProject@special_feature
|
||||
```
|
||||
|
||||
### Subversion
|
||||
|
@ -72,9 +73,9 @@ The supported schemes are `svn`, `svn+svn`, `svn+http`, `svn+https` and
|
|||
`svn+ssh`. Here are some of the supported forms:
|
||||
|
||||
```none
|
||||
svn+https://svn.example.com/MyProject#egg=MyProject
|
||||
svn+ssh://svn.example.com/MyProject#egg=MyProject
|
||||
svn+ssh://user@svn.example.com/MyProject#egg=MyProject
|
||||
MyProject @ svn+https://svn.example.com/MyProject
|
||||
MyProject @ svn+ssh://svn.example.com/MyProject
|
||||
MyProject @ svn+ssh://user@svn.example.com/MyProject
|
||||
```
|
||||
|
||||
You can also give specific revisions to an SVN URL, like so:
|
||||
|
@ -93,18 +94,18 @@ The supported schemes are `bzr+http`, `bzr+https`, `bzr+ssh`, `bzr+sftp`,
|
|||
`bzr+ftp` and `bzr+lp`. Here are the supported forms:
|
||||
|
||||
```none
|
||||
bzr+http://bzr.example.com/MyProject/trunk#egg=MyProject
|
||||
bzr+sftp://user@example.com/MyProject/trunk#egg=MyProject
|
||||
bzr+ssh://user@example.com/MyProject/trunk#egg=MyProject
|
||||
bzr+ftp://user@example.com/MyProject/trunk#egg=MyProject
|
||||
bzr+lp:MyProject#egg=MyProject
|
||||
MyProject @ bzr+http://bzr.example.com/MyProject/trunk
|
||||
MyProject @ bzr+sftp://user@example.com/MyProject/trunk
|
||||
MyProject @ bzr+ssh://user@example.com/MyProject/trunk
|
||||
MyProject @ bzr+ftp://user@example.com/MyProject/trunk
|
||||
MyProject @ bzr+lp:MyProject
|
||||
```
|
||||
|
||||
Tags or revisions can be installed like so:
|
||||
|
||||
```none
|
||||
bzr+https://bzr.example.com/MyProject/trunk@2019#egg=MyProject
|
||||
bzr+http://bzr.example.com/MyProject/trunk@v1.0#egg=MyProject
|
||||
MyProject @ bzr+https://bzr.example.com/MyProject/trunk@2019
|
||||
MyProject @ bzr+http://bzr.example.com/MyProject/trunk@v1.0
|
||||
```
|
||||
|
||||
(editable-vcs-installs)=
|
||||
|
@ -129,18 +130,19 @@ VCS source will not overwrite it without an `--upgrade` flag. Further, pip
|
|||
looks at the package version, at the target revision to determine what action to
|
||||
take on the VCS requirement (not the commit itself).
|
||||
|
||||
The {ref}`pip freeze` subcommand will record the VCS requirement specifier
|
||||
(referencing a specific commit) only if the install is done with the editable
|
||||
option.
|
||||
|
||||
## URL fragments
|
||||
|
||||
pip looks at 2 fragments for VCS URLs:
|
||||
pip looks at the `subdirectory` fragments of VCS URLs for specifying the path to the
|
||||
Python package, when it is not in the root of the VCS directory. eg: `pkg_dir`.
|
||||
|
||||
- `egg`: For specifying the "project name" for use in pip's dependency
|
||||
resolution logic. eg: `egg=project_name`
|
||||
- `subdirectory`: For specifying the path to the Python package, when it is not
|
||||
in the root of the VCS directory. eg: `pkg_dir`
|
||||
pip also looks at the `egg` fragment specifying the "project name". In practice the
|
||||
`egg` fragment is only required to help pip determine the VCS clone location in editable
|
||||
mode. In all other circumstances, the `egg` fragment is not necessary and its use is
|
||||
discouraged.
|
||||
|
||||
The `egg` fragment **should** be a bare
|
||||
[PEP 508](https://peps.python.org/pep-0508/) project name. Anything else
|
||||
is not guaranteed to work.
|
||||
|
||||
````{admonition} Example
|
||||
If your repository layout is:
|
||||
|
@ -156,6 +158,12 @@ some_other_file
|
|||
|
||||
Then, to install from this repository, the syntax would be:
|
||||
|
||||
```{pip-cli}
|
||||
$ pip install "pkg @ vcs+protocol://repo_url/#subdirectory=pkg_dir"
|
||||
```
|
||||
|
||||
or:
|
||||
|
||||
```{pip-cli}
|
||||
$ pip install -e "vcs+protocol://repo_url/#egg=pkg&subdirectory=pkg_dir"
|
||||
```
|
||||
|
|
|
@ -2,6 +2,15 @@
|
|||
User Guide
|
||||
==========
|
||||
|
||||
.. Hello there!
|
||||
|
||||
If you're thinking of adding content to this page... please take a moment
|
||||
to consider if this content can live on its own, within a topic guide or a
|
||||
reference page.
|
||||
|
||||
There is active effort being put toward *reducing* the amount of content on
|
||||
this specific page (https://github.com/pypa/pip/issues/9475) and moving it
|
||||
into more focused single-page documents that cover that specific topic.
|
||||
|
||||
Running pip
|
||||
===========
|
||||
|
@ -17,7 +26,7 @@ to your system, which can be run from the command prompt as follows:
|
|||
|
||||
``python -m pip`` executes pip using the Python interpreter you
|
||||
specified as python. So ``/usr/bin/python3.7 -m pip`` means
|
||||
you are executing pip for your interpreter located at /usr/bin/python3.7.
|
||||
you are executing pip for your interpreter located at ``/usr/bin/python3.7``.
|
||||
|
||||
.. tab:: Windows
|
||||
|
||||
|
@ -59,19 +68,18 @@ For more information and examples, see the :ref:`pip install` reference.
|
|||
|
||||
.. _PyPI: https://pypi.org/
|
||||
|
||||
|
||||
Basic Authentication Credentials
|
||||
================================
|
||||
.. _`0-basic-authentication-credentials`:
|
||||
.. rubric:: Basic Authentication Credentials
|
||||
|
||||
This is now covered in :doc:`topics/authentication`.
|
||||
|
||||
netrc Support
|
||||
-------------
|
||||
.. _`0-netrc-support`:
|
||||
.. rubric:: netrc Support
|
||||
|
||||
This is now covered in :doc:`topics/authentication`.
|
||||
|
||||
Keyring Support
|
||||
---------------
|
||||
.. _`0-keyring-support`:
|
||||
.. rubric:: Keyring Support
|
||||
|
||||
This is now covered in :doc:`topics/authentication`.
|
||||
|
||||
|
@ -84,7 +92,7 @@ in many corporate environments requires an outbound HTTP proxy server.
|
|||
pip can be configured to connect through a proxy server in various ways:
|
||||
|
||||
* using the ``--proxy`` command-line option to specify a proxy in the form
|
||||
``[user:passwd@]proxy.server:port``
|
||||
``scheme://[user:passwd@]proxy.server:port``
|
||||
* using ``proxy`` in a :ref:`config-file`
|
||||
* by setting the standard environment-variables ``http_proxy``, ``https_proxy``
|
||||
and ``no_proxy``.
|
||||
|
@ -451,34 +459,26 @@ packages.
|
|||
|
||||
For more information and examples, see the :ref:`pip search` reference.
|
||||
|
||||
.. _`Configuration`:
|
||||
|
||||
|
||||
Configuration
|
||||
=============
|
||||
.. _`0-configuration`:
|
||||
.. rubric:: Configuration
|
||||
|
||||
This is now covered in :doc:`topics/configuration`.
|
||||
|
||||
.. _config-file:
|
||||
|
||||
Config file
|
||||
-----------
|
||||
.. _`0-config-file`:
|
||||
.. rubric:: Config file
|
||||
|
||||
This is now covered in :doc:`topics/configuration`.
|
||||
|
||||
Environment Variables
|
||||
---------------------
|
||||
.. _`0-environment-variables`:
|
||||
.. rubric:: Environment Variables
|
||||
|
||||
This is now covered in :doc:`topics/configuration`.
|
||||
|
||||
.. _config-precedence:
|
||||
|
||||
Config Precedence
|
||||
-----------------
|
||||
.. _`0-config-precedence`:
|
||||
.. rubric:: Config Precedence
|
||||
|
||||
This is now covered in :doc:`topics/configuration`.
|
||||
|
||||
|
||||
Command Completion
|
||||
==================
|
||||
|
||||
|
@ -496,6 +496,10 @@ To setup for fish::
|
|||
|
||||
python -m pip completion --fish > ~/.config/fish/completions/pip.fish
|
||||
|
||||
To setup for powershell::
|
||||
|
||||
python -m pip completion --powershell | Out-File -Encoding default -Append $PROFILE
|
||||
|
||||
Alternatively, you can use the result of the ``completion`` command directly
|
||||
with the eval function of your shell, e.g. by adding the following to your
|
||||
startup file::
|
||||
|
@ -629,7 +633,7 @@ Moreover, the "user scheme" can be customized by setting the
|
|||
``PYTHONUSERBASE`` environment variable, which updates the value of
|
||||
``site.USER_BASE``.
|
||||
|
||||
To install "SomePackage" into an environment with site.USER_BASE customized to
|
||||
To install "SomePackage" into an environment with ``site.USER_BASE`` customized to
|
||||
'/myappenv', do the following:
|
||||
|
||||
.. tab:: Unix/macOS
|
||||
|
@ -776,18 +780,14 @@ is the latest version:
|
|||
[...]
|
||||
Successfully installed SomePackage
|
||||
|
||||
.. _`Repeatability`:
|
||||
|
||||
|
||||
Ensuring Repeatability
|
||||
======================
|
||||
.. _`0-repeatability`:
|
||||
.. _`0-ensuring-repeatability`:
|
||||
.. rubric:: Ensuring Repeatability
|
||||
|
||||
This is now covered in :doc:`../topics/repeatable-installs`.
|
||||
|
||||
.. _`Fixing conflicting dependencies`:
|
||||
|
||||
Fixing conflicting dependencies
|
||||
===============================
|
||||
.. _`0-fixing-conflicting-dependencies`:
|
||||
.. rubric:: Fixing conflicting dependencies
|
||||
|
||||
This is now covered in :doc:`../topics/dependency-resolution`.
|
||||
|
||||
|
@ -800,7 +800,7 @@ As noted previously, pip is a command line program. While it is implemented in
|
|||
Python, and so is available from your Python code via ``import pip``, you must
|
||||
not use pip's internal APIs in this way. There are a number of reasons for this:
|
||||
|
||||
#. The pip code assumes that is in sole control of the global state of the
|
||||
#. The pip code assumes that it is in sole control of the global state of the
|
||||
program.
|
||||
pip manages things like the logging system configuration, or the values of
|
||||
the standard IO streams, without considering the possibility that user code
|
||||
|
@ -1146,3 +1146,8 @@ announcements on the `low-traffic packaging announcements list`_ and
|
|||
.. _our survey on upgrades that create conflicts: https://docs.google.com/forms/d/e/1FAIpQLSeBkbhuIlSofXqCyhi3kGkLmtrpPOEBwr6iJA6SzHdxWKfqdA/viewform
|
||||
.. _the official Python blog: https://blog.python.org/
|
||||
.. _Python Windows launcher: https://docs.python.org/3/using/windows.html#launcher
|
||||
|
||||
.. _`0-using-system-trust-stores-for-verifying-https`:
|
||||
.. rubric:: Using system trust stores for verifying HTTPS
|
||||
|
||||
This is now covered in :doc:`topics/https-certificates`.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
sphinx ~= 4.1.0
|
||||
sphinx ~= 4.2, != 4.4.0
|
||||
towncrier
|
||||
furo
|
||||
myst_parser
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
Always refuse installing or building projects that have no ``pyproject.toml`` nor
|
||||
``setup.py``.
|
|
@ -1 +0,0 @@
|
|||
Tweak running-as-root detection, to check ``os.getuid`` if it exists, on Unix-y and non-Linux/non-MacOS machines.
|
|
@ -1,5 +0,0 @@
|
|||
When installing projects with a ``pyproject.toml`` in editable mode, and the build
|
||||
backend does not support :pep:`660`, prepare metadata using
|
||||
``prepare_metadata_for_build_wheel`` instead of ``setup.py egg_info``. Also, refuse
|
||||
installing projects that only have a ``setup.cfg`` and no ``setup.py`` nor
|
||||
``pyproject.toml``. These restore the pre-21.3 behaviour.
|
|
@ -1 +0,0 @@
|
|||
Restore compatibility of where configuration files are loaded from on MacOS (back to ``Library/Application Support/pip``, instead of ``Preferences/pip``).
|
|
@ -1 +0,0 @@
|
|||
Documents the ``--require-virtualenv`` flag for ``pip install``.
|
1
news/10937.feature.rst
Normal file
1
news/10937.feature.rst
Normal file
|
@ -0,0 +1 @@
|
|||
Present conflict information during installation after each choice that is rejected (pass ``-vv`` to ``pip install`` to show it)
|
1
news/11169.feature.rst
Normal file
1
news/11169.feature.rst
Normal file
|
@ -0,0 +1 @@
|
|||
Display dependency chain on each Collecting/Processing log line.
|
1
news/11358.removal.rst
Normal file
1
news/11358.removal.rst
Normal file
|
@ -0,0 +1 @@
|
|||
Remove support for the deprecated ``--install-options``.
|
2
news/11451.removal.rst
Normal file
2
news/11451.removal.rst
Normal file
|
@ -0,0 +1,2 @@
|
|||
``--no-binary`` does not imply ``setup.py install`` anymore. Instead a wheel will be
|
||||
built locally and installed.
|
1
news/11529.bugfix.rst
Normal file
1
news/11529.bugfix.rst
Normal file
|
@ -0,0 +1 @@
|
|||
Fix grammar by changing "A new release of pip available:" to "A new release of pip is available:" in the notice used for indicating that.
|
4
news/11681.feature.rst
Normal file
4
news/11681.feature.rst
Normal file
|
@ -0,0 +1,4 @@
|
|||
The ``--config-settings``/``-C`` option now supports using the same key multiple
|
||||
times. When the same key is specified multiple times, all values are passed to
|
||||
the build backend as a list, as opposed to the previous behavior, where pip would
|
||||
only pass the last value if the same key was used multiple times.
|
1
news/11774.bugfix.rst
Normal file
1
news/11774.bugfix.rst
Normal file
|
@ -0,0 +1 @@
|
|||
Correct the way to decide if keyring is available.
|
2
news/11775.doc.rst
Normal file
2
news/11775.doc.rst
Normal file
|
@ -0,0 +1,2 @@
|
|||
Cross-reference the ``--python`` flag from the ``--prefix`` flag,
|
||||
and mention limitations of ``--prefix`` regarding script installation.
|
1
news/11809.doc.rst
Normal file
1
news/11809.doc.rst
Normal file
|
@ -0,0 +1 @@
|
|||
Add SECURITY.md to make the policy offical.
|
1
news/11837.bugfix.rst
Normal file
1
news/11837.bugfix.rst
Normal file
|
@ -0,0 +1 @@
|
|||
More consistent resolution backtracking by removing legacy hack related to setuptools resolution
|
1
news/11838.doc.rst
Normal file
1
news/11838.doc.rst
Normal file
|
@ -0,0 +1 @@
|
|||
Add username to Git over SSH example.
|
2
news/11842.doc.rst
Normal file
2
news/11842.doc.rst
Normal file
|
@ -0,0 +1,2 @@
|
|||
Quote extras in the pip install docs to guard shells with default glob
|
||||
qualifiers, like zsh.
|
1
news/11882.bugfix.rst
Normal file
1
news/11882.bugfix.rst
Normal file
|
@ -0,0 +1 @@
|
|||
Include ``AUTHORS.txt`` in pip's wheels.
|
1
news/8719.feature.rst
Normal file
1
news/8719.feature.rst
Normal file
|
@ -0,0 +1 @@
|
|||
Add ``--keyring-provider`` flag. See the Authentication page in the documentation for more info.
|
1
news/9752.feature.rst
Normal file
1
news/9752.feature.rst
Normal file
|
@ -0,0 +1 @@
|
|||
In the case of virtual environments, configuration files are now also included from the base installation.
|
|
@ -1 +0,0 @@
|
|||
Upgrade pep517 to 0.12.0
|
1
news/pkg_resources.vendor.rst
Normal file
1
news/pkg_resources.vendor.rst
Normal file
|
@ -0,0 +1 @@
|
|||
Patch pkg_resources to remove dependency on ``jaraco.text``.
|
|
@ -1 +1 @@
|
|||
Upgrade resolvelib to 0.8.1
|
||||
Upgrade resolvelib to 0.9.0
|
||||
|
|
1
news/setuptools.vendor.rst
Normal file
1
news/setuptools.vendor.rst
Normal file
|
@ -0,0 +1 @@
|
|||
Update pkg_resources (via setuptools) to 65.6.3
|
1
news/short-config-settings-option.feature.rst
Normal file
1
news/short-config-settings-option.feature.rst
Normal file
|
@ -0,0 +1 @@
|
|||
Add ``-C`` as a short version of the ``--config-settings`` option.
|
57
noxfile.py
57
noxfile.py
|
@ -1,6 +1,7 @@
|
|||
"""Automation using nox.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import glob
|
||||
import os
|
||||
import shutil
|
||||
|
@ -21,7 +22,7 @@ nox.options.sessions = ["lint"]
|
|||
|
||||
LOCATIONS = {
|
||||
"common-wheels": "tests/data/common_wheels",
|
||||
"protected-pip": "tools/tox_pip.py",
|
||||
"protected-pip": "tools/protected_pip.py",
|
||||
}
|
||||
REQUIREMENTS = {
|
||||
"docs": "docs/requirements.txt",
|
||||
|
@ -65,11 +66,8 @@ def should_update_common_wheels() -> bool:
|
|||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Development Commands
|
||||
# These are currently prototypes to evaluate whether we want to switch over
|
||||
# completely to nox for all our automation. Contributors should prefer using
|
||||
# `tox -e ...` until this note is removed.
|
||||
# -----------------------------------------------------------------------------
|
||||
@nox.session(python=["3.6", "3.7", "3.8", "3.9", "3.10", "pypy3"])
|
||||
@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11", "pypy3"])
|
||||
def test(session: nox.Session) -> None:
|
||||
# Get the common wheels.
|
||||
if should_update_common_wheels():
|
||||
|
@ -113,7 +111,13 @@ def test(session: nox.Session) -> None:
|
|||
# Run the tests
|
||||
# LC_CTYPE is set to get UTF-8 output inside of the subprocesses that our
|
||||
# tests use.
|
||||
session.run("pytest", *arguments, env={"LC_CTYPE": "en_US.UTF-8"})
|
||||
session.run(
|
||||
"pytest",
|
||||
*arguments,
|
||||
env={
|
||||
"LC_CTYPE": "en_US.UTF-8",
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@nox.session
|
||||
|
@ -169,11 +173,24 @@ def lint(session: nox.Session) -> None:
|
|||
session.run("pre-commit", "run", *args)
|
||||
|
||||
|
||||
# NOTE: This session will COMMIT upgrades to vendored libraries.
|
||||
# You should therefore not run it directly against `main`. If you
|
||||
# do (assuming you started with a clean main), you can run:
|
||||
#
|
||||
# git checkout -b vendoring-updates
|
||||
# git checkout main
|
||||
# git reset --hard origin/main
|
||||
@nox.session
|
||||
def vendoring(session: nox.Session) -> None:
|
||||
session.install("vendoring~=1.2.0")
|
||||
|
||||
if "--upgrade" not in session.posargs:
|
||||
parser = argparse.ArgumentParser(prog="nox -s vendoring")
|
||||
parser.add_argument("--upgrade-all", action="store_true")
|
||||
parser.add_argument("--upgrade", action="append", default=[])
|
||||
parser.add_argument("--skip", action="append", default=[])
|
||||
args = parser.parse_args(session.posargs)
|
||||
|
||||
if not (args.upgrade or args.upgrade_all):
|
||||
session.run("vendoring", "sync", "-v")
|
||||
return
|
||||
|
||||
|
@ -189,7 +206,9 @@ def vendoring(session: nox.Session) -> None:
|
|||
|
||||
vendor_txt = Path("src/pip/_vendor/vendor.txt")
|
||||
for name, old_version in pinned_requirements(vendor_txt):
|
||||
if name == "setuptools":
|
||||
if name in args.skip:
|
||||
continue
|
||||
if args.upgrade and name not in args.upgrade:
|
||||
continue
|
||||
|
||||
# update requirements.txt
|
||||
|
@ -223,6 +242,28 @@ def vendoring(session: nox.Session) -> None:
|
|||
release.commit_file(session, ".", message=message)
|
||||
|
||||
|
||||
@nox.session
|
||||
def coverage(session: nox.Session) -> None:
|
||||
# Install source distribution
|
||||
run_with_protected_pip(session, "install", ".")
|
||||
|
||||
# Install test dependencies
|
||||
run_with_protected_pip(session, "install", "-r", REQUIREMENTS["tests"])
|
||||
|
||||
if not os.path.exists(".coverage-output"):
|
||||
os.mkdir(".coverage-output")
|
||||
session.run(
|
||||
"pytest",
|
||||
"--cov=pip",
|
||||
"--cov-config=./setup.cfg",
|
||||
*session.posargs,
|
||||
env={
|
||||
"COVERAGE_OUTPUT_DIR": "./.coverage-output",
|
||||
"COVERAGE_PROCESS_START": os.fsdecode(Path("setup.cfg").resolve()),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Release Commands
|
||||
# -----------------------------------------------------------------------------
|
||||
|
|
|
@ -39,6 +39,7 @@ substitute = [
|
|||
# pkg_resource's vendored packages are directly vendored in pip.
|
||||
{ match='pkg_resources\.extern', replace="pip._vendor" },
|
||||
{ match='from \.extern', replace="from pip._vendor" },
|
||||
{ match='''\('pygments\.lexers\.''', replace="('pip._vendor.pygments.lexers." },
|
||||
]
|
||||
drop = [
|
||||
# contains unnecessary scripts
|
||||
|
@ -49,7 +50,14 @@ drop = [
|
|||
"easy_install.py",
|
||||
"setuptools",
|
||||
"pkg_resources/_vendor/",
|
||||
"_distutils_hack",
|
||||
"distutils-precedence.pth",
|
||||
"pkg_resources/extern/",
|
||||
# trim vendored pygments styles and lexers
|
||||
"pygments/styles/[!_]*.py",
|
||||
'^pygments/lexers/(?!python|__init__|_mapping).*\.py$',
|
||||
# trim rich's markdown support
|
||||
"rich/markdown.py",
|
||||
]
|
||||
|
||||
[tool.vendoring.typing-stubs]
|
||||
|
|
19
setup.cfg
19
setup.cfg
|
@ -24,6 +24,10 @@ extend-ignore =
|
|||
G200, G202,
|
||||
# black adds spaces around ':'
|
||||
E203,
|
||||
# using a cache
|
||||
B019,
|
||||
# reassigning variables in a loop
|
||||
B020,
|
||||
per-file-ignores =
|
||||
# G: The plugin logging-format treats every .log and .error as logging.
|
||||
noxfile.py: G
|
||||
|
@ -31,10 +35,15 @@ per-file-ignores =
|
|||
tests/*: B011
|
||||
|
||||
[mypy]
|
||||
mypy_path = $MYPY_CONFIG_FILE_DIR/src
|
||||
ignore_missing_imports = True
|
||||
disallow_untyped_defs = True
|
||||
disallow_any_generics = True
|
||||
warn_unused_ignores = True
|
||||
no_implicit_optional = True
|
||||
|
||||
[mypy-pip._internal.utils._jaraco_text]
|
||||
ignore_errors = True
|
||||
|
||||
[mypy-pip._vendor.*]
|
||||
ignore_errors = True
|
||||
|
@ -51,17 +60,12 @@ follow_imports = skip
|
|||
[mypy-pip._vendor.requests.*]
|
||||
follow_imports = skip
|
||||
|
||||
# TODO: The following option should be removed at some point in the future.
|
||||
[mypy-tests.functional.*]
|
||||
allow_untyped_defs = True
|
||||
|
||||
[tool:pytest]
|
||||
addopts = --ignore src/pip/_vendor --ignore tests/tests_cache -r aR --color=yes
|
||||
xfail_strict = True
|
||||
markers =
|
||||
network: tests that need network
|
||||
incompatible_with_sysconfig
|
||||
incompatible_with_test_venv
|
||||
incompatible_with_venv
|
||||
no_auto_tempdir_manager
|
||||
unit: unit tests
|
||||
|
@ -107,8 +111,3 @@ exclude_lines =
|
|||
pragma: no cover
|
||||
# This excludes typing-specific code, which will be validated by mypy anyway.
|
||||
if TYPE_CHECKING
|
||||
# Can be set to exclude e.g. `if PY2:` on Python 3
|
||||
${PIP_CI_COVERAGE_EXCLUDES}
|
||||
|
||||
[metadata]
|
||||
license_file = LICENSE.txt
|
||||
|
|
6
setup.py
6
setup.py
|
@ -37,11 +37,11 @@ setup(
|
|||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3 :: Only",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: Implementation :: CPython",
|
||||
"Programming Language :: Python :: Implementation :: PyPy",
|
||||
],
|
||||
|
@ -81,5 +81,7 @@ setup(
|
|||
],
|
||||
},
|
||||
zip_safe=False,
|
||||
python_requires=">=3.6",
|
||||
# NOTE: python_requires is duplicated in __pip-runner__.py.
|
||||
# When changing this value, please change the other copy as well.
|
||||
python_requires=">=3.7",
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from typing import List, Optional
|
||||
|
||||
__version__ = "22.0.dev0"
|
||||
__version__ = "23.1.dev0"
|
||||
|
||||
|
||||
def main(args: Optional[List[str]] = None) -> int:
|
||||
|
|
50
src/pip/__pip-runner__.py
Normal file
50
src/pip/__pip-runner__.py
Normal file
|
@ -0,0 +1,50 @@
|
|||
"""Execute exactly this copy of pip, within a different environment.
|
||||
|
||||
This file is named as it is, to ensure that this module can't be imported via
|
||||
an import statement.
|
||||
"""
|
||||
|
||||
# /!\ This version compatibility check section must be Python 2 compatible. /!\
|
||||
|
||||
import sys
|
||||
|
||||
# Copied from setup.py
|
||||
PYTHON_REQUIRES = (3, 7)
|
||||
|
||||
|
||||
def version_str(version): # type: ignore
|
||||
return ".".join(str(v) for v in version)
|
||||
|
||||
|
||||
if sys.version_info[:2] < PYTHON_REQUIRES:
|
||||
raise SystemExit(
|
||||
"This version of pip does not support python {} (requires >={}).".format(
|
||||
version_str(sys.version_info[:2]), version_str(PYTHON_REQUIRES)
|
||||
)
|
||||
)
|
||||
|
||||
# From here on, we can use Python 3 features, but the syntax must remain
|
||||
# Python 2 compatible.
|
||||
|
||||
import runpy # noqa: E402
|
||||
from importlib.machinery import PathFinder # noqa: E402
|
||||
from os.path import dirname # noqa: E402
|
||||
|
||||
PIP_SOURCES_ROOT = dirname(dirname(__file__))
|
||||
|
||||
|
||||
class PipImportRedirectingFinder:
|
||||
@classmethod
|
||||
def find_spec(self, fullname, path=None, target=None): # type: ignore
|
||||
if fullname != "pip":
|
||||
return None
|
||||
|
||||
spec = PathFinder.find_spec(fullname, [PIP_SOURCES_ROOT], target)
|
||||
assert spec, (PIP_SOURCES_ROOT, fullname)
|
||||
return spec
|
||||
|
||||
|
||||
sys.meta_path.insert(0, PipImportRedirectingFinder())
|
||||
|
||||
assert __name__ == "__main__", "Cannot run __pip-runner__.py as a non-main module"
|
||||
runpy.run_module("pip", run_name="__main__", alter_sys=True)
|
|
@ -1,17 +1,15 @@
|
|||
"""Build Environment used for isolation during sdist building
|
||||
"""
|
||||
|
||||
import contextlib
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
import site
|
||||
import sys
|
||||
import textwrap
|
||||
import zipfile
|
||||
from collections import OrderedDict
|
||||
from sysconfig import get_paths
|
||||
from types import TracebackType
|
||||
from typing import TYPE_CHECKING, Iterable, Iterator, List, Optional, Set, Tuple, Type
|
||||
from typing import TYPE_CHECKING, Iterable, List, Optional, Set, Tuple, Type, Union
|
||||
|
||||
from pip._vendor.certifi import where
|
||||
from pip._vendor.packaging.requirements import Requirement
|
||||
|
@ -19,8 +17,8 @@ from pip._vendor.packaging.version import Version
|
|||
|
||||
from pip import __file__ as pip_location
|
||||
from pip._internal.cli.spinners import open_spinner
|
||||
from pip._internal.locations import get_platlib, get_prefixed_libs, get_purelib
|
||||
from pip._internal.metadata import get_environment
|
||||
from pip._internal.locations import get_platlib, get_purelib, get_scheme
|
||||
from pip._internal.metadata import get_default_environment, get_environment
|
||||
from pip._internal.utils.subprocess import call_subprocess
|
||||
from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds
|
||||
|
||||
|
@ -30,41 +28,53 @@ if TYPE_CHECKING:
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _dedup(a: str, b: str) -> Union[Tuple[str], Tuple[str, str]]:
|
||||
return (a, b) if a != b else (a,)
|
||||
|
||||
|
||||
class _Prefix:
|
||||
def __init__(self, path: str) -> None:
|
||||
self.path = path
|
||||
self.setup = False
|
||||
self.bin_dir = get_paths(
|
||||
"nt" if os.name == "nt" else "posix_prefix",
|
||||
vars={"base": path, "platbase": path},
|
||||
)["scripts"]
|
||||
self.lib_dirs = get_prefixed_libs(path)
|
||||
scheme = get_scheme("", prefix=path)
|
||||
self.bin_dir = scheme.scripts
|
||||
self.lib_dirs = _dedup(scheme.purelib, scheme.platlib)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def _create_standalone_pip() -> Iterator[str]:
|
||||
"""Create a "standalone pip" zip file.
|
||||
def get_runnable_pip() -> str:
|
||||
"""Get a file to pass to a Python executable, to run the currently-running pip.
|
||||
|
||||
The zip file's content is identical to the currently-running pip.
|
||||
It will be used to install requirements into the build environment.
|
||||
This is used to run a pip subprocess, for installing requirements into the build
|
||||
environment.
|
||||
"""
|
||||
source = pathlib.Path(pip_location).resolve().parent
|
||||
|
||||
# Return the current instance if `source` is not a directory. We can't build
|
||||
# a zip from this, and it likely means the instance is already standalone.
|
||||
if not source.is_dir():
|
||||
yield str(source)
|
||||
return
|
||||
# This would happen if someone is using pip from inside a zip file. In that
|
||||
# case, we can use that directly.
|
||||
return str(source)
|
||||
|
||||
with TempDirectory(kind="standalone-pip") as tmp_dir:
|
||||
pip_zip = os.path.join(tmp_dir.path, "__env_pip__.zip")
|
||||
kwargs = {}
|
||||
if sys.version_info >= (3, 8):
|
||||
kwargs["strict_timestamps"] = False
|
||||
with zipfile.ZipFile(pip_zip, "w", **kwargs) as zf:
|
||||
for child in source.rglob("*"):
|
||||
zf.write(child, child.relative_to(source.parent).as_posix())
|
||||
yield os.path.join(pip_zip, "pip")
|
||||
return os.fsdecode(source / "__pip-runner__.py")
|
||||
|
||||
|
||||
def _get_system_sitepackages() -> Set[str]:
|
||||
"""Get system site packages
|
||||
|
||||
Usually from site.getsitepackages,
|
||||
but fallback on `get_purelib()/get_platlib()` if unavailable
|
||||
(e.g. in a virtualenv created by virtualenv<20)
|
||||
|
||||
Returns normalized set of strings.
|
||||
"""
|
||||
if hasattr(site, "getsitepackages"):
|
||||
system_sites = site.getsitepackages()
|
||||
else:
|
||||
# virtualenv < 20 overwrites site.py without getsitepackages
|
||||
# fallback on get_purelib/get_platlib.
|
||||
# this is known to miss things, but shouldn't in the cases
|
||||
# where getsitepackages() has been removed (inside a virtualenv)
|
||||
system_sites = [get_purelib(), get_platlib()]
|
||||
return {os.path.normcase(path) for path in system_sites}
|
||||
|
||||
|
||||
class BuildEnvironment:
|
||||
|
@ -87,9 +97,8 @@ class BuildEnvironment:
|
|||
# Customize site to:
|
||||
# - ensure .pth files are honored
|
||||
# - prevent access to system site packages
|
||||
system_sites = {
|
||||
os.path.normcase(site) for site in (get_purelib(), get_platlib())
|
||||
}
|
||||
system_sites = _get_system_sitepackages()
|
||||
|
||||
self._site_dir = os.path.join(temp_dir.path, "site")
|
||||
if not os.path.exists(self._site_dir):
|
||||
os.mkdir(self._site_dir)
|
||||
|
@ -168,9 +177,17 @@ class BuildEnvironment:
|
|||
missing = set()
|
||||
conflicting = set()
|
||||
if reqs:
|
||||
env = get_environment(self._lib_dirs)
|
||||
env = (
|
||||
get_environment(self._lib_dirs)
|
||||
if hasattr(self, "_lib_dirs")
|
||||
else get_default_environment()
|
||||
)
|
||||
for req_str in reqs:
|
||||
req = Requirement(req_str)
|
||||
# We're explicitly evaluating with an empty extra value, since build
|
||||
# environments are not provided any mechanism to select specific extras.
|
||||
if req.marker is not None and not req.marker.evaluate({"extra": ""}):
|
||||
continue
|
||||
dist = env.get_distribution(req.name)
|
||||
if not dist:
|
||||
missing.add(req_str)
|
||||
|
@ -179,7 +196,7 @@ class BuildEnvironment:
|
|||
installed_req_str = f"{req.name}=={dist.version}"
|
||||
else:
|
||||
installed_req_str = f"{req.name}==={dist.version}"
|
||||
if dist.version not in req.specifier:
|
||||
if not req.specifier.contains(dist.version, prereleases=True):
|
||||
conflicting.add((installed_req_str, req_str))
|
||||
# FIXME: Consider direct URL?
|
||||
return conflicting, missing
|
||||
|
@ -189,29 +206,21 @@ class BuildEnvironment:
|
|||
finder: "PackageFinder",
|
||||
requirements: Iterable[str],
|
||||
prefix_as_string: str,
|
||||
message: str,
|
||||
*,
|
||||
kind: str,
|
||||
) -> None:
|
||||
prefix = self._prefixes[prefix_as_string]
|
||||
assert not prefix.setup
|
||||
prefix.setup = True
|
||||
if not requirements:
|
||||
return
|
||||
with contextlib.ExitStack() as ctx:
|
||||
# TODO: Remove this block when dropping 3.6 support. Python 3.6
|
||||
# lacks importlib.resources and pep517 has issues loading files in
|
||||
# a zip, so we fallback to the "old" method by adding the current
|
||||
# pip directory to the child process's sys.path.
|
||||
if sys.version_info < (3, 7):
|
||||
pip_runnable = os.path.dirname(pip_location)
|
||||
else:
|
||||
pip_runnable = ctx.enter_context(_create_standalone_pip())
|
||||
self._install_requirements(
|
||||
pip_runnable,
|
||||
finder,
|
||||
requirements,
|
||||
prefix,
|
||||
message,
|
||||
)
|
||||
self._install_requirements(
|
||||
get_runnable_pip(),
|
||||
finder,
|
||||
requirements,
|
||||
prefix,
|
||||
kind=kind,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _install_requirements(
|
||||
|
@ -219,7 +228,8 @@ class BuildEnvironment:
|
|||
finder: "PackageFinder",
|
||||
requirements: Iterable[str],
|
||||
prefix: _Prefix,
|
||||
message: str,
|
||||
*,
|
||||
kind: str,
|
||||
) -> None:
|
||||
args: List[str] = [
|
||||
sys.executable,
|
||||
|
@ -261,8 +271,13 @@ class BuildEnvironment:
|
|||
args.append("--")
|
||||
args.extend(requirements)
|
||||
extra_environ = {"_PIP_STANDALONE_CERT": where()}
|
||||
with open_spinner(message) as spinner:
|
||||
call_subprocess(args, spinner=spinner, extra_environ=extra_environ)
|
||||
with open_spinner(f"Installing {kind}") as spinner:
|
||||
call_subprocess(
|
||||
args,
|
||||
command_desc=f"pip subprocess to install {kind}",
|
||||
spinner=spinner,
|
||||
extra_environ=extra_environ,
|
||||
)
|
||||
|
||||
|
||||
class NoOpBuildEnvironment(BuildEnvironment):
|
||||
|
@ -290,6 +305,7 @@ class NoOpBuildEnvironment(BuildEnvironment):
|
|||
finder: "PackageFinder",
|
||||
requirements: Iterable[str],
|
||||
prefix_as_string: str,
|
||||
message: str,
|
||||
*,
|
||||
kind: str,
|
||||
) -> None:
|
||||
raise NotImplementedError()
|
||||
|
|
|
@ -5,12 +5,14 @@ import hashlib
|
|||
import json
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Set
|
||||
|
||||
from pip._vendor.packaging.tags import Tag, interpreter_name, interpreter_version
|
||||
from pip._vendor.packaging.utils import canonicalize_name
|
||||
|
||||
from pip._internal.exceptions import InvalidWheelFilename
|
||||
from pip._internal.models.direct_url import DirectUrl
|
||||
from pip._internal.models.format_control import FormatControl
|
||||
from pip._internal.models.link import Link
|
||||
from pip._internal.models.wheel import Wheel
|
||||
|
@ -19,6 +21,8 @@ from pip._internal.utils.urls import path_to_url
|
|||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
ORIGIN_JSON_NAME = "origin.json"
|
||||
|
||||
|
||||
def _hash_dict(d: Dict[str, str]) -> str:
|
||||
"""Return a stable sha224 of a dictionary."""
|
||||
|
@ -204,6 +208,10 @@ class CacheEntry:
|
|||
):
|
||||
self.link = link
|
||||
self.persistent = persistent
|
||||
self.origin: Optional[DirectUrl] = None
|
||||
origin_direct_url_path = Path(self.link.file_path).parent / ORIGIN_JSON_NAME
|
||||
if origin_direct_url_path.exists():
|
||||
self.origin = DirectUrl.from_json(origin_direct_url_path.read_text())
|
||||
|
||||
|
||||
class WheelCache(Cache):
|
||||
|
@ -213,7 +221,11 @@ class WheelCache(Cache):
|
|||
when a certain link is not found in the simple wheel cache first.
|
||||
"""
|
||||
|
||||
def __init__(self, cache_dir: str, format_control: FormatControl) -> None:
|
||||
def __init__(
|
||||
self, cache_dir: str, format_control: Optional[FormatControl] = None
|
||||
) -> None:
|
||||
if format_control is None:
|
||||
format_control = FormatControl()
|
||||
super().__init__(cache_dir, format_control, {"binary"})
|
||||
self._wheel_cache = SimpleWheelCache(cache_dir, format_control)
|
||||
self._ephem_cache = EphemWheelCache(format_control)
|
||||
|
@ -262,3 +274,20 @@ class WheelCache(Cache):
|
|||
return CacheEntry(retval, persistent=False)
|
||||
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def record_download_origin(cache_dir: str, download_info: DirectUrl) -> None:
|
||||
origin_path = Path(cache_dir) / ORIGIN_JSON_NAME
|
||||
if origin_path.is_file():
|
||||
origin = DirectUrl.from_json(origin_path.read_text())
|
||||
# TODO: use DirectUrl.equivalent when https://github.com/pypa/pip/pull/10564
|
||||
# is merged.
|
||||
if origin.url != download_info.url:
|
||||
logger.warning(
|
||||
"Origin URL %s in cache entry %s does not match download URL %s. "
|
||||
"This is likely a pip bug or a cache corruption issue.",
|
||||
origin.url,
|
||||
cache_dir,
|
||||
download_info.url,
|
||||
)
|
||||
origin_path.write_text(download_info.to_json(), encoding="utf-8")
|
||||
|
|
|
@ -59,6 +59,14 @@ def autocomplete() -> None:
|
|||
print(dist)
|
||||
sys.exit(1)
|
||||
|
||||
should_list_installables = (
|
||||
not current.startswith("-") and subcommand_name == "install"
|
||||
)
|
||||
if should_list_installables:
|
||||
for path in auto_complete_paths(current, "path"):
|
||||
print(path)
|
||||
sys.exit(1)
|
||||
|
||||
subcommand = create_command(subcommand_name)
|
||||
|
||||
for opt in subcommand.parser.option_list_all:
|
||||
|
@ -138,7 +146,7 @@ def auto_complete_paths(current: str, completion_type: str) -> Iterable[str]:
|
|||
starting with ``current``.
|
||||
|
||||
:param current: The word to be completed
|
||||
:param completion_type: path completion type(`file`, `path` or `dir`)i
|
||||
:param completion_type: path completion type(``file``, ``path`` or ``dir``)
|
||||
:return: A generator of regular files and/or directories
|
||||
"""
|
||||
directory, filename = os.path.split(current)
|
||||
|
|
|
@ -10,6 +10,8 @@ import traceback
|
|||
from optparse import Values
|
||||
from typing import Any, Callable, List, Optional, Tuple
|
||||
|
||||
from pip._vendor.rich import traceback as rich_traceback
|
||||
|
||||
from pip._internal.cli import cmdoptions
|
||||
from pip._internal.cli.command_context import CommandContextMixIn
|
||||
from pip._internal.cli.parser import ConfigOptionParser, UpdatingDefaultsHelpFormatter
|
||||
|
@ -22,6 +24,7 @@ from pip._internal.cli.status_codes import (
|
|||
from pip._internal.exceptions import (
|
||||
BadCommand,
|
||||
CommandError,
|
||||
DiagnosticPipError,
|
||||
InstallationError,
|
||||
NetworkConnectionError,
|
||||
PreviousBuildDirError,
|
||||
|
@ -148,13 +151,6 @@ class Command(CommandContextMixIn):
|
|||
)
|
||||
options.cache_dir = None
|
||||
|
||||
if "2020-resolver" in options.features_enabled:
|
||||
logger.warning(
|
||||
"--use-feature=2020-resolver no longer has any effect, "
|
||||
"since it is now the default dependency resolver in pip. "
|
||||
"This will become an error in pip 21.0."
|
||||
)
|
||||
|
||||
def intercepts_unhandled_exc(
|
||||
run_func: Callable[..., int]
|
||||
) -> Callable[..., int]:
|
||||
|
@ -164,6 +160,11 @@ class Command(CommandContextMixIn):
|
|||
status = run_func(*args)
|
||||
assert isinstance(status, int)
|
||||
return status
|
||||
except DiagnosticPipError as exc:
|
||||
logger.error("[present-rich] %s", exc)
|
||||
logger.debug("Exception information:", exc_info=True)
|
||||
|
||||
return ERROR
|
||||
except PreviousBuildDirError as exc:
|
||||
logger.critical(str(exc))
|
||||
logger.debug("Exception information:", exc_info=True)
|
||||
|
@ -209,6 +210,7 @@ class Command(CommandContextMixIn):
|
|||
run = intercepts_unhandled_exc(self.run)
|
||||
else:
|
||||
run = self.run
|
||||
rich_traceback.install(show_locals=True)
|
||||
return run(options, args)
|
||||
finally:
|
||||
self.handle_pip_version_check(options)
|
||||
|
|
|
@ -10,9 +10,10 @@ pass on state. To be consistent, all options will follow this design.
|
|||
# The following comment should be removed at some point in the future.
|
||||
# mypy: strict-optional=False
|
||||
|
||||
import importlib.util
|
||||
import logging
|
||||
import os
|
||||
import textwrap
|
||||
import warnings
|
||||
from functools import partial
|
||||
from optparse import SUPPRESS_HELP, Option, OptionGroup, OptionParser, Values
|
||||
from textwrap import dedent
|
||||
|
@ -21,7 +22,6 @@ from typing import Any, Callable, Dict, Optional, Tuple
|
|||
from pip._vendor.packaging.utils import canonicalize_name
|
||||
|
||||
from pip._internal.cli.parser import ConfigOptionParser
|
||||
from pip._internal.cli.progress_bars import BAR_TYPES
|
||||
from pip._internal.exceptions import CommandError
|
||||
from pip._internal.locations import USER_CACHE_DIR, get_src_prefix
|
||||
from pip._internal.models.format_control import FormatControl
|
||||
|
@ -30,6 +30,8 @@ from pip._internal.models.target_python import TargetPython
|
|||
from pip._internal.utils.hashes import STRONG_HASHES
|
||||
from pip._internal.utils.misc import strtobool
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def raise_option_error(parser: OptionParser, option: Option, msg: str) -> None:
|
||||
"""
|
||||
|
@ -57,32 +59,6 @@ def make_option_group(group: Dict[str, Any], parser: ConfigOptionParser) -> Opti
|
|||
return option_group
|
||||
|
||||
|
||||
def check_install_build_global(
|
||||
options: Values, check_options: Optional[Values] = None
|
||||
) -> None:
|
||||
"""Disable wheels if per-setup.py call options are set.
|
||||
|
||||
:param options: The OptionParser options to update.
|
||||
:param check_options: The options to check, if not supplied defaults to
|
||||
options.
|
||||
"""
|
||||
if check_options is None:
|
||||
check_options = options
|
||||
|
||||
def getname(n: str) -> Optional[Any]:
|
||||
return getattr(check_options, n, None)
|
||||
|
||||
names = ["build_options", "global_options", "install_options"]
|
||||
if any(map(getname, names)):
|
||||
control = options.format_control
|
||||
control.disallow_binaries()
|
||||
warnings.warn(
|
||||
"Disabling all use of wheels due to the use of --build-option "
|
||||
"/ --global-option / --install-option.",
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
|
||||
def check_dist_restriction(options: Values, check_target: bool = False) -> None:
|
||||
"""Function for determining if custom platform options are allowed.
|
||||
|
||||
|
@ -188,6 +164,21 @@ require_virtualenv: Callable[..., Option] = partial(
|
|||
),
|
||||
)
|
||||
|
||||
override_externally_managed: Callable[..., Option] = partial(
|
||||
Option,
|
||||
"--break-system-packages",
|
||||
dest="override_externally_managed",
|
||||
action="store_true",
|
||||
help="Allow pip to modify an EXTERNALLY-MANAGED Python installation",
|
||||
)
|
||||
|
||||
python: Callable[..., Option] = partial(
|
||||
Option,
|
||||
"--python",
|
||||
dest="python",
|
||||
help="Run pip with the specified Python interpreter.",
|
||||
)
|
||||
|
||||
verbose: Callable[..., Option] = partial(
|
||||
Option,
|
||||
"-v",
|
||||
|
@ -235,13 +226,9 @@ progress_bar: Callable[..., Option] = partial(
|
|||
"--progress-bar",
|
||||
dest="progress_bar",
|
||||
type="choice",
|
||||
choices=list(BAR_TYPES.keys()),
|
||||
choices=["on", "off"],
|
||||
default="on",
|
||||
help=(
|
||||
"Specify type of progress to be displayed ["
|
||||
+ "|".join(BAR_TYPES.keys())
|
||||
+ "] (default: %default)"
|
||||
),
|
||||
help="Specify whether the progress bar should be used [on, off] (default: on)",
|
||||
)
|
||||
|
||||
log: Callable[..., Option] = partial(
|
||||
|
@ -265,13 +252,26 @@ no_input: Callable[..., Option] = partial(
|
|||
help="Disable prompting for input.",
|
||||
)
|
||||
|
||||
keyring_provider: Callable[..., Option] = partial(
|
||||
Option,
|
||||
"--keyring-provider",
|
||||
dest="keyring_provider",
|
||||
choices=["auto", "disabled", "import", "subprocess"],
|
||||
default="disabled",
|
||||
help=(
|
||||
"Enable the credential lookup via the keyring library if user input is allowed."
|
||||
" Specify which mechanism to use [disabled, import, subprocess]."
|
||||
" (default: disabled)"
|
||||
),
|
||||
)
|
||||
|
||||
proxy: Callable[..., Option] = partial(
|
||||
Option,
|
||||
"--proxy",
|
||||
dest="proxy",
|
||||
type="str",
|
||||
default="",
|
||||
help="Specify a proxy in the form [user:passwd@]proxy.server:port.",
|
||||
help="Specify a proxy in the form scheme://[user:passwd@]proxy.server:port.",
|
||||
)
|
||||
|
||||
retries: Callable[..., Option] = partial(
|
||||
|
@ -752,6 +752,15 @@ no_build_isolation: Callable[..., Option] = partial(
|
|||
"if this option is used.",
|
||||
)
|
||||
|
||||
check_build_deps: Callable[..., Option] = partial(
|
||||
Option,
|
||||
"--check-build-dependencies",
|
||||
dest="check_build_deps",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Check the build dependencies when PEP517 is used.",
|
||||
)
|
||||
|
||||
|
||||
def _handle_no_use_pep517(
|
||||
option: Option, opt: str, value: str, parser: OptionParser
|
||||
|
@ -774,6 +783,12 @@ def _handle_no_use_pep517(
|
|||
"""
|
||||
raise_option_error(parser, option=option, msg=msg)
|
||||
|
||||
# If user doesn't wish to use pep517, we check if setuptools is installed
|
||||
# and raise error if it is not.
|
||||
if not importlib.util.find_spec("setuptools"):
|
||||
msg = "It is not possible to use --no-use-pep517 without setuptools installed."
|
||||
raise_option_error(parser, option=option, msg=msg)
|
||||
|
||||
# Otherwise, --no-use-pep517 was passed via the command-line.
|
||||
parser.values.use_pep517 = False
|
||||
|
||||
|
@ -798,17 +813,38 @@ no_use_pep517: Any = partial(
|
|||
help=SUPPRESS_HELP,
|
||||
)
|
||||
|
||||
install_options: Callable[..., Option] = partial(
|
||||
|
||||
def _handle_config_settings(
|
||||
option: Option, opt_str: str, value: str, parser: OptionParser
|
||||
) -> None:
|
||||
key, sep, val = value.partition("=")
|
||||
if sep != "=":
|
||||
parser.error(f"Arguments to {opt_str} must be of the form KEY=VAL") # noqa
|
||||
dest = getattr(parser.values, option.dest)
|
||||
if dest is None:
|
||||
dest = {}
|
||||
setattr(parser.values, option.dest, dest)
|
||||
if key in dest:
|
||||
if isinstance(dest[key], list):
|
||||
dest[key].append(val)
|
||||
else:
|
||||
dest[key] = [dest[key], val]
|
||||
else:
|
||||
dest[key] = val
|
||||
|
||||
|
||||
config_settings: Callable[..., Option] = partial(
|
||||
Option,
|
||||
"--install-option",
|
||||
dest="install_options",
|
||||
action="append",
|
||||
metavar="options",
|
||||
help="Extra arguments to be supplied to the setup.py install "
|
||||
'command (use like --install-option="--install-scripts=/usr/local/'
|
||||
'bin"). Use multiple --install-option options to pass multiple '
|
||||
"options to setup.py install. If you are using an option with a "
|
||||
"directory path, be sure to use absolute path.",
|
||||
"-C",
|
||||
"--config-settings",
|
||||
dest="config_settings",
|
||||
type=str,
|
||||
action="callback",
|
||||
callback=_handle_config_settings,
|
||||
metavar="settings",
|
||||
help="Configuration settings to be passed to the PEP 517 build backend. "
|
||||
"Settings take the form KEY=VALUE. Use multiple --config-settings options "
|
||||
"to pass multiple keys to the backend.",
|
||||
)
|
||||
|
||||
build_options: Callable[..., Option] = partial(
|
||||
|
@ -857,6 +893,15 @@ disable_pip_version_check: Callable[..., Option] = partial(
|
|||
"of pip is available for download. Implied with --no-index.",
|
||||
)
|
||||
|
||||
root_user_action: Callable[..., Option] = partial(
|
||||
Option,
|
||||
"--root-user-action",
|
||||
dest="root_user_action",
|
||||
default="warn",
|
||||
choices=["warn", "ignore"],
|
||||
help="Action if pip is run as a root user. By default, a warning message is shown.",
|
||||
)
|
||||
|
||||
|
||||
def _handle_merge_hash(
|
||||
option: Option, opt_str: str, value: str, parser: OptionParser
|
||||
|
@ -952,7 +997,11 @@ use_new_feature: Callable[..., Option] = partial(
|
|||
metavar="feature",
|
||||
action="append",
|
||||
default=[],
|
||||
choices=["2020-resolver", "fast-deps", "in-tree-build"],
|
||||
choices=[
|
||||
"fast-deps",
|
||||
"truststore",
|
||||
"no-binary-enable-wheel-cache",
|
||||
],
|
||||
help="Enable new functionality, that may be backward incompatible.",
|
||||
)
|
||||
|
||||
|
@ -963,7 +1012,9 @@ use_deprecated_feature: Callable[..., Option] = partial(
|
|||
metavar="feature",
|
||||
action="append",
|
||||
default=[],
|
||||
choices=["legacy-resolver", "out-of-tree-build"],
|
||||
choices=[
|
||||
"legacy-resolver",
|
||||
],
|
||||
help=("Enable deprecated functionality, that will be removed in the future."),
|
||||
)
|
||||
|
||||
|
@ -979,11 +1030,13 @@ general_group: Dict[str, Any] = {
|
|||
debug_mode,
|
||||
isolated_mode,
|
||||
require_virtualenv,
|
||||
python,
|
||||
verbose,
|
||||
version,
|
||||
quiet,
|
||||
log,
|
||||
no_input,
|
||||
keyring_provider,
|
||||
proxy,
|
||||
retries,
|
||||
timeout,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from contextlib import ExitStack, contextmanager
|
||||
from typing import ContextManager, Iterator, TypeVar
|
||||
from typing import ContextManager, Generator, TypeVar
|
||||
|
||||
_T = TypeVar("_T", covariant=True)
|
||||
|
||||
|
@ -11,7 +11,7 @@ class CommandContextMixIn:
|
|||
self._main_context = ExitStack()
|
||||
|
||||
@contextmanager
|
||||
def main_context(self) -> Iterator[None]:
|
||||
def main_context(self) -> Generator[None, None, None]:
|
||||
assert not self._in_main_context
|
||||
|
||||
self._in_main_context = True
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
"""
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import List, Tuple
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
from pip._internal.build_env import get_runnable_pip
|
||||
from pip._internal.cli import cmdoptions
|
||||
from pip._internal.cli.parser import ConfigOptionParser, UpdatingDefaultsHelpFormatter
|
||||
from pip._internal.commands import commands_dict, get_similar_commands
|
||||
|
@ -45,6 +47,25 @@ def create_main_parser() -> ConfigOptionParser:
|
|||
return parser
|
||||
|
||||
|
||||
def identify_python_interpreter(python: str) -> Optional[str]:
|
||||
# If the named file exists, use it.
|
||||
# If it's a directory, assume it's a virtual environment and
|
||||
# look for the environment's Python executable.
|
||||
if os.path.exists(python):
|
||||
if os.path.isdir(python):
|
||||
# bin/python for Unix, Scripts/python.exe for Windows
|
||||
# Try both in case of odd cases like cygwin.
|
||||
for exe in ("bin/python", "Scripts/python.exe"):
|
||||
py = os.path.join(python, exe)
|
||||
if os.path.exists(py):
|
||||
return py
|
||||
else:
|
||||
return python
|
||||
|
||||
# Could not find the interpreter specified
|
||||
return None
|
||||
|
||||
|
||||
def parse_command(args: List[str]) -> Tuple[str, List[str]]:
|
||||
parser = create_main_parser()
|
||||
|
||||
|
@ -57,6 +78,32 @@ def parse_command(args: List[str]) -> Tuple[str, List[str]]:
|
|||
# args_else: ['install', '--user', 'INITools']
|
||||
general_options, args_else = parser.parse_args(args)
|
||||
|
||||
# --python
|
||||
if general_options.python and "_PIP_RUNNING_IN_SUBPROCESS" not in os.environ:
|
||||
# Re-invoke pip using the specified Python interpreter
|
||||
interpreter = identify_python_interpreter(general_options.python)
|
||||
if interpreter is None:
|
||||
raise CommandError(
|
||||
f"Could not locate Python interpreter {general_options.python}"
|
||||
)
|
||||
|
||||
pip_cmd = [
|
||||
interpreter,
|
||||
get_runnable_pip(),
|
||||
]
|
||||
pip_cmd.extend(args)
|
||||
|
||||
# Set a flag so the child doesn't re-invoke itself, causing
|
||||
# an infinite loop.
|
||||
os.environ["_PIP_RUNNING_IN_SUBPROCESS"] = "1"
|
||||
returncode = 0
|
||||
try:
|
||||
proc = subprocess.run(pip_cmd)
|
||||
returncode = proc.returncode
|
||||
except (subprocess.SubprocessError, OSError) as exc:
|
||||
raise CommandError(f"Failed to run pip under {interpreter}: {exc}")
|
||||
sys.exit(returncode)
|
||||
|
||||
# --version
|
||||
if general_options.version:
|
||||
sys.stdout.write(parser.version)
|
||||
|
|
|
@ -6,7 +6,7 @@ import shutil
|
|||
import sys
|
||||
import textwrap
|
||||
from contextlib import suppress
|
||||
from typing import Any, Dict, Iterator, List, Tuple
|
||||
from typing import Any, Dict, Generator, List, Tuple
|
||||
|
||||
from pip._internal.cli.status_codes import UNKNOWN_ERROR
|
||||
from pip._internal.configuration import Configuration, ConfigurationError
|
||||
|
@ -175,7 +175,9 @@ class ConfigOptionParser(CustomOptionParser):
|
|||
print(f"An error occurred during configuration: {exc}")
|
||||
sys.exit(3)
|
||||
|
||||
def _get_ordered_configuration_items(self) -> Iterator[Tuple[str, Any]]:
|
||||
def _get_ordered_configuration_items(
|
||||
self,
|
||||
) -> Generator[Tuple[str, Any], None, None]:
|
||||
# Configuration gives keys in an unordered manner. Order them.
|
||||
override_order = ["global", self.name, ":env:"]
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue