1
1
Fork 0
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:
Pradyun Gedam 2023-03-27 11:52:58 +01:00 committed by GitHub
commit 01b1388165
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
735 changed files with 79370 additions and 42631 deletions

View file

@ -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:

View file

@ -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
View 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: []
...

View file

@ -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.

View file

@ -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) }}

View file

@ -14,6 +14,7 @@ concurrency:
jobs:
action:
if: github.repository_owner == 'pypa'
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v3

View file

@ -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
View 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"

View 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 }}

View file

@ -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>

View file

@ -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

View 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

View file

@ -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

View file

@ -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

View file

@ -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
View file

@ -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 systems 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)
=================

View file

@ -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
View 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)

View file

@ -16,6 +16,7 @@ pip
pip_install
pip_uninstall
pip_inspect
pip_list
pip_show
pip_freeze

View file

@ -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`.

View file

@ -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

View file

@ -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.

View 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

View file

@ -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 its 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/

View file

@ -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.

View file

@ -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

View file

@ -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
=======

View file

@ -55,6 +55,7 @@ print("pip release:", release)
# -- Options for myst-parser ----------------------------------------------------------
myst_enable_extensions = ["deflist"]
myst_heading_anchors = 3
# -- Options for smartquotes ----------------------------------------------------------

View file

@ -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. Theres more about this in the contributor documentation!]*
* ``template.rst`` *[template for changelog -- this is a file towncrier uses…. Is this jinja? I dont 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 pips 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 thats written by pip maintainers -- underscore means private. pip is not a library -- its 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. Theres 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 whats 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.] [whats 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, Pradyuns 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

View file

@ -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 links text is the name of the file
basically a link. The links 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

View file

@ -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 | | |
+-----------+----------+-------+---------------+-----------------+

View file

@ -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

View file

@ -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.

View 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`
```

View file

@ -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``.

View file

@ -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

View file

@ -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
```

View file

@ -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)

View file

@ -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.

View file

@ -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

View file

@ -7,5 +7,8 @@ interoperability standards that pip utilises/implements.
:titlesonly:
build-system/index
requirement-specifiers
requirements-file-format
installation-report
inspect-report
```

View 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"
}
}
```

View 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"
}
}
```

View 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"
```

View file

@ -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.

View file

@ -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`.

View file

@ -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 cant 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.

View file

@ -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:

View file

@ -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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View 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

View file

@ -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
```

View 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.

View 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).

View 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.

View file

@ -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.

View 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 its 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 .
```

View file

@ -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"
```

View file

@ -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`.

View file

@ -1,4 +1,4 @@
sphinx ~= 4.1.0
sphinx ~= 4.2, != 4.4.0
towncrier
furo
myst_parser

View file

@ -1,2 +0,0 @@
Always refuse installing or building projects that have no ``pyproject.toml`` nor
``setup.py``.

View file

@ -1 +0,0 @@
Tweak running-as-root detection, to check ``os.getuid`` if it exists, on Unix-y and non-Linux/non-MacOS machines.

View file

@ -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.

View file

@ -1 +0,0 @@
Restore compatibility of where configuration files are loaded from on MacOS (back to ``Library/Application Support/pip``, instead of ``Preferences/pip``).

View file

@ -1 +0,0 @@
Documents the ``--require-virtualenv`` flag for ``pip install``.

1
news/10937.feature.rst Normal file
View 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
View file

@ -0,0 +1 @@
Display dependency chain on each Collecting/Processing log line.

1
news/11358.removal.rst Normal file
View file

@ -0,0 +1 @@
Remove support for the deprecated ``--install-options``.

2
news/11451.removal.rst Normal file
View 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
View 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
View 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
View file

@ -0,0 +1 @@
Correct the way to decide if keyring is available.

2
news/11775.doc.rst Normal file
View 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
View file

@ -0,0 +1 @@
Add SECURITY.md to make the policy offical.

1
news/11837.bugfix.rst Normal file
View file

@ -0,0 +1 @@
More consistent resolution backtracking by removing legacy hack related to setuptools resolution

1
news/11838.doc.rst Normal file
View file

@ -0,0 +1 @@
Add username to Git over SSH example.

2
news/11842.doc.rst Normal file
View 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
View file

@ -0,0 +1 @@
Include ``AUTHORS.txt`` in pip's wheels.

1
news/8719.feature.rst Normal file
View 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
View file

@ -0,0 +1 @@
In the case of virtual environments, configuration files are now also included from the base installation.

View file

@ -1 +0,0 @@
Upgrade pep517 to 0.12.0

View file

@ -0,0 +1 @@
Patch pkg_resources to remove dependency on ``jaraco.text``.

View file

@ -1 +1 @@
Upgrade resolvelib to 0.8.1
Upgrade resolvelib to 0.9.0

View file

@ -0,0 +1 @@
Update pkg_resources (via setuptools) to 65.6.3

View file

@ -0,0 +1 @@
Add ``-C`` as a short version of the ``--config-settings`` option.

View file

@ -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
# -----------------------------------------------------------------------------

View file

@ -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]

View file

@ -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

View file

@ -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",
)

View file

@ -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
View 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)

View file

@ -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()

View file

@ -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")

View file

@ -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)

View file

@ -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)

View file

@ -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,

View file

@ -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

View file

@ -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)

View file

@ -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