Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#!/usr/bin/env python
#
# Hi There!
#
# You may be wondering what this giant blob of binary data here is, you might
# even be worried that we're up to something nefarious (good for you for being
# paranoid!). This is a base85 encoding of a zip file, this zip file contains
# an entire copy of pip (version 23.0).
#
# Pip is a thing that installs packages, pip itself is a package that someone
# might want to install, especially if they're looking to run this get-pip.py
# script. Pip has a lot of code to deal with the security of installing
# packages, various edge cases on various platforms, and other such sort of
# "tribal knowledge" that has been encoded in its code base. Because of this
# we basically include an entire copy of pip inside this blob. We do this
# because the alternatives are attempt to implement a "minipip" that probably
# doesn't do things correctly and has weird edge cases, or compress pip itself
# down into a single file.
#
# If you're wondering how this is created, it is generated using
# `scripts/generate.py` in https://github.com/pypa/get-pip.
import sys
this_python = sys.version_info[:2]
min_version = (3, 7)
if this_python < min_version:
message_parts = [
"This script does not work on Python {}.{}".format(*this_python),
"The minimum supported Python version is {}.{}.".format(*min_version),
"Please use https://bootstrap.pypa.io/pip/{}.{}/get-pip.py instead.".format(*this_python),
]
print("ERROR: " + " ".join(message_parts))
sys.exit(1)
import os.path
import pkgutil
import shutil
import tempfile
import argparse
import importlib
from base64 import b85decode
def include_setuptools(args):
"""
Install setuptools only if absent and not excluded.
"""
cli = not args.no_setuptools
env = not os.environ.get("PIP_NO_SETUPTOOLS")
absent = not importlib.util.find_spec("setuptools")
return cli and env and absent
def include_wheel(args):
"""
Install wheel only if absent and not excluded.
"""
cli = not args.no_wheel
env = not os.environ.get("PIP_NO_WHEEL")
absent = not importlib.util.find_spec("wheel")
return cli and env and absent
def determine_pip_install_arguments():
pre_parser = argparse.ArgumentParser()
pre_parser.add_argument("--no-setuptools", action="store_true")
pre_parser.add_argument("--no-wheel", action="store_true")
pre, args = pre_parser.parse_known_args()
args.append("pip")
if include_setuptools(pre):
args.append("setuptools")
if include_wheel(pre):
args.append("wheel")
return ["install", "--upgrade", "--force-reinstall"] + args
def monkeypatch_for_cert(tmpdir):
"""Patches `pip install` to provide default certificate with the lowest priority.
This ensures that the bundled certificates are used unless the user specifies a
custom cert via any of pip's option passing mechanisms (config, env-var, CLI).
A monkeypatch is the easiest way to achieve this, without messing too much with
the rest of pip's internals.
"""
from pip._internal.commands.install import InstallCommand
# We want to be using the internal certificates.
cert_path = os.path.join(tmpdir, "cacert.pem")
with open(cert_path, "wb") as cert:
cert.write(pkgutil.get_data("pip._vendor.certifi", "cacert.pem"))
install_parse_args = InstallCommand.parse_args
def cert_parse_args(self, args):
if not self.parser.get_default_values().cert:
# There are no user provided cert -- force use of bundled cert
self.parser.defaults["cert"] = cert_path # calculated above
return install_parse_args(self, args)
InstallCommand.parse_args = cert_parse_args
def bootstrap(tmpdir):
monkeypatch_for_cert(tmpdir)
# Execute the included pip and use it to install the latest pip and
# setuptools from PyPI
from pip._internal.cli.main import main as pip_entry_point
args = determine_pip_install_arguments()
sys.exit(pip_entry_point(args))
def main():
tmpdir = None
try:
# Create a temporary working directory
tmpdir = tempfile.mkdtemp()
# Unpack the zipfile into the temporary directory
pip_zip = os.path.join(tmpdir, "pip.zip")
with open(pip_zip, "wb") as fp:
fp.write(b85decode(DATA.replace(b"\n", b"")))
# Add the zipfile to sys.path so that we can import it
sys.path.insert(0, pip_zip)
# Run the bootstrap
bootstrap(tmpdir=tmpdir)
finally:
# Clean up our temporary working directory
if tmpdir:
shutil.rmtree(tmpdir, ignore_errors=True)
DATA = b"""
P)h>@6aWAK2mngCK33$8H+}X1003hF000jF003}la4%n9X>MtBUtcb8c|B0UO2j}6z0X&KUUXrd5f#*
ef)_y$_26w;%50mqfp%s{QkVX{vt7C&5b}6=dAye62s$SU9nhE}D}0jZ7QT~G41O@Cs{W8AFI5FEP~6
?y+rk*rU<;$CaP7I1^1|Pp&Ud1`-)Ht$47h=tSD>J!fm}sV{PrY}+lLd3oUh>R=L2FGW*E^2g*Gxwf^
e82QMwX{#{hK<5(fmSnUab%i{N{v`lg}tduUKS4YCD6gkCjC>0C$JPX}Aa(WN<gmo*)UOepU0;rYp~&
X(DpBFPL}t?ulkS<+%qo>R=ItXWk@_9-EstuX4u;Q}tnY|KAUO9KQH0000807|(&RwEnZzik2l0Imc8
01p5F0B~t=FJE76VQFq(UoLQYT~onsoG=i*^A#g<SawB74(*{)w^F5Ea_J$eltWV?7ly@Ju#s(+Y`?y
54D2T1gzYzP-n^O7{a{@n>k~cy`Say>QqE{|@JVt*Pu$xR(`G};)Krbmu>r!mBM?+;$5pWIOpUWWg_f
z&&Iba>oe^#uAua|L+MIMlgJUlQ!IC;zUDN1=XXU-{AygY0^gxyEd!+VMwOk!@Bx3%@ATvIwuFI*@$S
2}_Yo{E6Q_BX=Cwt_Yl&9ewT5IUGk9=Pj!f%PbYWscvNAhK9n!}Rfz@eJzY`c9(2;Yh-20LW;Te0P_p
@~U3CN~-}Yc@bha)u~X*U^o5lxkNF#QtivCrG!GkC@S`1FtF}@pe~CZFeVPmm;sXBDyRGRUHvimbBkf
n$9Y3@X+W^Zo&VK=dLV!rA=8D!+F8ZZGzuM^-Pr{@xkfAOUpKI12#E%uB;fm0t5lt&BFD>e(ZvnAQeh
>DJv3#>}rD!p1WoV`W_up;jKC3t=L*A^lu(TWQq9rx|iO>Ml8CskLT5a?e=}+;3K<`-RF@A9gH?g$l~
Ez@5Re!OgQ>$M>98)owJS{iz<v2hUMnV=TAb&rk2tbX4?+z;OuL$ko>fPALucNCG2JJwd!U=<`o0D3y
8tH=Rmu^+*rrErFsAsqWOavxeT-r)QnZCRM422Rt->rnF_0ILHAe@V}p#R9A-u9Vi$AT^_V3~0!sD4K
mfJ?)O^4q?tfepJ<s@@dRvbj@6%#8Pa-Z~UWyYt4^$f2<_5&2fb62w1__PoimKCvc)d!E|0pUpAi1=S
Uv<dh9o8`U4^T@31QY-O00;m|xjt5Y2PKuz0ssJ{1pojQ0001RX>c!JUvOz~Epl~kZe?;`UoLQYeN@4
2+b|5h`ztv2FdJ~aq8%_GScU;biuKZDNqQK%LQrhF(Pm4oBxf;-{`*KfPTHWG4v8d_kB^Vf4#RM=#jN
oNxRseNTkvb;ATxCfrhr=23H(uXr$IuliUKWa52!cF8eP#o4T2@76skm^e=RG_K{`;LjtO`}(XO#b$k
O-lmB|~5&ZK_tVMS?GZLFuXjgo=XyE8a1J@z%iFbskd`0(y0bk#O!oidt;R<-nMrAp;n$kv$s28WsFX
I0}m^jYiIbUfb&mzXkA5Dax%$KaQyR>YyOrXmdA)M?!YvmeWE(;G3Le80V(PZltS=punnaS#MK76T9A
yp4AIcm!|)zO8Wt>OmWe0noC9Xf=dsnEo<KM_on?g|V;!l6S}^U{x@sbih`+Fn6Q#d-x1TY(_n@R1RU
$IudKLRX*x&d4;dE>gNf$L7I}Gwwt<ZzwY&UdWOj2W1}oR|1y4hj)^MKtK<trUN3uoi)Wm?3OV8&@3H
z_%+g=6=4<j67)^%jtO1SN&+Y;Wl%yY$p;isM2uULC<+h))#Y!qoKyS@@KWE!$vNa7yn@2f<$;Y$vpq
qC8yi}{Sk{Nj&Z98~yCjI(K=^X7_iN>W=WjzGv%Ch~BB7@oWOf06i^UKLX%%{^OnP?Xo4gW&$`y)im^
Uq4@9L!XG-NDY0qS({=p=Z*M{c9IiAvK(L7wpG^0)(qEiyW3k0!34nTp$7FIleKPwqDu?^xfefX5~dL
9J1lv7(((+IC^D-ouwHk*gxRn)Zjt4^uX!B=I&UN`+?TMAJiT4+ew)TM8^q--VPZ%LYzS|vNuT{DY*4
iX-13AlK%)BvHZKTLNK-vFs9yxV1Ee_CJ<gq&2JBxiDF2UQ`(VZgrLs_fA=KKUY~OO?mHI-o$*ro75z
=riJ34)S7rRNfGj<s5&7}bHq_i-P)h>@6aWAK2mngCK32`gz%{@C0015V000aC003}la4&FqE_8WtWn
?9eu};M>3`O^T#obt*`VR~YY;QnfHmzwbC3ciJh5S8E87&>(bBYv517WkANp~bsMyYmG$}2ukNeuDHN
G^#ptMd*~JcpmA56q`#0W5TpB>IYnZ>tlx>JJR-$h|q#9KFT3l$ThGovM`Z`h1@k{0zqrjTIlGh#re*
%w%#go%(3HWDhs}=jz2OtQ*5LjXNW#DIpx4DusYoy!{s5eCbN6)&t+MoumghxP_Ew!2Ru`@Lf_lF*R=
M@&`~$0|XQR000O8O1VB(mbGx9Q2_t|Jpup#82|tPaA|NaUukZ1WpZv|Y%gD5X>MtBUtcb8d3BL7PsA
_`h4=gl>sYQ5qze*o5{yhISlAFch1PA2(j?d}sQ(_fa3Cbe66?u%{_@;$9zo|qsRtTMW`#Y8p2B@m$|
*$WzT`s1A1EoZseV$5;wimgqX)reVpI-E)>b%ylwX7E7V|&e9VZ=P?wvaUN~BBO8^yMQaT0}RgeJs@t
yNuSgplS{0nPB$>wDC_mB`!5Y~BZI1{gvqm;{0z$K(#iY?fngr-<U+GRyxS>YQuQ`U0hG;9hpHJtpwD
1o9}#PfrzG!(C2T!P$*b>&}6l&1Um3ko`)aFbeXUQ5!Sl*g}(&<cJ^*Q&9mO3~UTDh$Ru1Z!&hsm>T0
)?MS^_i(9h@ZA+gR(4qzl?-T?P2Gt_Fy6#Db>Df1Vtjk<NZE4peGNIHL=U12h2)N$=?ZabIo=Z0MXE*
P>1j(N$w%v)-x41@BxeriF0|XQR000O8O1VB(|7DJuC=37q&?f)@8UO$QaA|NaUukZ1WpZv|Y%gMUX>
4R)Wo~vZaCy~Q-E-Tx5r5ZTfie$Awj?i?r;a9Sn>fnFQ`hz+&b2ol4UZ<Fm^DSR0BKw2@&Df41waBMr
Q|w&IX%P@uvqNJZ$ALU^SrlRQRZx2-4~*+cD!m?Cwb1cwP1y;%d{=(ishXssxM6Dg>2aku7IBl&+`_G
V%OB7Wo7;43y$fZwKU(Fw7o5h8}m~ZE$_eYd#aW{whtn07F$v8SXP%M&v0kSG{J?)x#0P`B5M^*yKi_
udnMA0-=x{y6^!=tD6%2=`Es3{d|03S{q+3Dke#+%q&FoG*%@dQvWo^cOUsab;_&mTYjBR3DQ->C#K}
Fc@>;|h7j3aE4C{wm5Nt}-fHWzZBo_QXT_HHywio#0Fm`O|Jr@$~uUGw~ehxC3i6q$;B~KETN*qqgIw
Qwfyo(BS1{LG1EMf_^seqYTUpKr;^x)hY!>?c9FBp8j@HSB(;d#Ob2qiZ~m7wFp<79vfB9jAM15_|<4
RnIjKrkoRj<;!^wyBW|SLA$~c4cet6w-t>FvqKFi&Dn2yJ<w7aoOvdrDd56!-to)eAgs-A$rik?|0zk
tgXd9WH=48$z4(95&~!IqH;+p&oBpa{-{C0!O`%u-{Mk@zNf*(0;3QnS0)@|Q2UI={3NN;9Y7>lEEZX
rf_llN;M?L+?F&W&6cts`CW$Y3xeY0DmrS-IV9{ULd0lZuiXWtikpT9>KkkI&ZP&oe`?QqYokC=wiB?
|+kB|QZ?s7y7ESJaD_o&hg77J7k$wgOH81@Mm*e9((JEaulvLAWNQig%V+8VS16T#n<UGCdkh(Z3yv#
wQH1IB?DYi~KrIw4@!avvdgOgZSi1u?z4EdWJQWmLT;rMMm76slBP$rfOS%iVNQ!7|*2k}ff|RE>@3^
jFrM$hdY07$LqSBU<SofLsI?yXSrY&O@=4oB+kDZZ(6rkZ58*7`**LY4T8aP%3WI2C@aNk@b!PDwKv=
a|K{fr^q?z`YVorMPqh~=1N<OXO>DZ<pY>7t<Xd?&vFWwav%4U0?;HXbd|3p43yM*yq57+<~*x&uIJh
J%uCS6<Pt8DByRSe0YZXEfYJlum|!*1fh83nApc*(P8$amikfN{GvrE!&$0uz?UmLzj}d2cRf+7TYuO
eEu|zSz(l1tK^MmiL#ODXUplQ1*y-$l0(MAk>U>t*4!KC2*7B&SKuuO17KfBpmqpx4R)CT%U29n@gu}
jP1SD=K*Wc3zp3I38Ueqh_%RHiN388ir)H`2wkAYmC0gK<uEU&Stm9AHDqlK(Y(^^(<4<Q@d^Aui3HJ
rode9c6Qyp~b{Dre#aplCeeJ>Oj1!>W2y=aaUk;-=Yyh@{YVka97{8Xk?0OK&QPUmHDwmfEh3uyWtQJ
5VD|3&io$ygQmeDyIng#2$_R~jScfBz&QqXjNU}yRCc56L5UdTwwXWod7e5vtHJA`eM0b&EUj|3ODj|
ezB7|l?M#C<(>Y3|A}AP*qy})ddd!rJzB;bl!suf?Tsg%te*5|K>|L@x{|PKo);AbpiIOm1U5U<QfW9
mw4V5x7snsd^Jr%_e7QoPyJ>S^#-*r*>MmQP@8Bzv8;4DW&<2V}H_f$-I5G07-GR6F2C@0eCq9>QsZc
Loading
Loading full blame...