99import ensurepip
1010import ensurepip ._uninstall
1111
12+ # pip currently requires ssl support, so we ensure we handle
13+ # it being missing (http://bugs.python.org/issue19744)
14+ ensurepip_no_ssl = test .support .import_fresh_module ("ensurepip" ,
15+ blocked = ["ssl" ])
16+ try :
17+ import ssl
18+ except ImportError :
19+ def requires_usable_pip (f ):
20+ deco = unittest .skip (ensurepip ._MISSING_SSL_MESSAGE )
21+ return deco (f )
22+ else :
23+ def requires_usable_pip (f ):
24+ return f
25+
1226class TestEnsurePipVersion (unittest .TestCase ):
1327
1428 def test_returns_version (self ):
@@ -28,8 +42,10 @@ def setUp(self):
2842 patched_os .path = os .path
2943 self .os_environ = patched_os .environ = os .environ .copy ()
3044
45+
3146class TestBootstrap (EnsurepipMixin , unittest .TestCase ):
3247
48+ @requires_usable_pip
3349 def test_basic_bootstrapping (self ):
3450 ensurepip .bootstrap ()
3551
@@ -44,6 +60,7 @@ def test_basic_bootstrapping(self):
4460 additional_paths = self .run_pip .call_args [0 ][1 ]
4561 self .assertEqual (len (additional_paths ), 2 )
4662
63+ @requires_usable_pip
4764 def test_bootstrapping_with_root (self ):
4865 ensurepip .bootstrap (root = "/foo/bar/" )
4966
@@ -56,6 +73,7 @@ def test_bootstrapping_with_root(self):
5673 unittest .mock .ANY ,
5774 )
5875
76+ @requires_usable_pip
5977 def test_bootstrapping_with_user (self ):
6078 ensurepip .bootstrap (user = True )
6179
@@ -67,6 +85,7 @@ def test_bootstrapping_with_user(self):
6785 unittest .mock .ANY ,
6886 )
6987
88+ @requires_usable_pip
7089 def test_bootstrapping_with_upgrade (self ):
7190 ensurepip .bootstrap (upgrade = True )
7291
@@ -78,6 +97,7 @@ def test_bootstrapping_with_upgrade(self):
7897 unittest .mock .ANY ,
7998 )
8099
100+ @requires_usable_pip
81101 def test_bootstrapping_with_verbosity_1 (self ):
82102 ensurepip .bootstrap (verbosity = 1 )
83103
@@ -89,6 +109,7 @@ def test_bootstrapping_with_verbosity_1(self):
89109 unittest .mock .ANY ,
90110 )
91111
112+ @requires_usable_pip
92113 def test_bootstrapping_with_verbosity_2 (self ):
93114 ensurepip .bootstrap (verbosity = 2 )
94115
@@ -100,6 +121,7 @@ def test_bootstrapping_with_verbosity_2(self):
100121 unittest .mock .ANY ,
101122 )
102123
124+ @requires_usable_pip
103125 def test_bootstrapping_with_verbosity_3 (self ):
104126 ensurepip .bootstrap (verbosity = 3 )
105127
@@ -111,14 +133,17 @@ def test_bootstrapping_with_verbosity_3(self):
111133 unittest .mock .ANY ,
112134 )
113135
136+ @requires_usable_pip
114137 def test_bootstrapping_with_regular_install (self ):
115138 ensurepip .bootstrap ()
116139 self .assertEqual (self .os_environ ["ENSUREPIP_OPTIONS" ], "install" )
117140
141+ @requires_usable_pip
118142 def test_bootstrapping_with_alt_install (self ):
119143 ensurepip .bootstrap (altinstall = True )
120144 self .assertEqual (self .os_environ ["ENSUREPIP_OPTIONS" ], "altinstall" )
121145
146+ @requires_usable_pip
122147 def test_bootstrapping_with_default_pip (self ):
123148 ensurepip .bootstrap (default_pip = True )
124149 self .assertNotIn ("ENSUREPIP_OPTIONS" , self .os_environ )
@@ -128,6 +153,7 @@ def test_altinstall_default_pip_conflict(self):
128153 ensurepip .bootstrap (altinstall = True , default_pip = True )
129154 self .run_pip .assert_not_called ()
130155
156+ @requires_usable_pip
131157 def test_pip_environment_variables_removed (self ):
132158 # ensurepip deliberately ignores all pip environment variables
133159 # See http://bugs.python.org/issue19734 for details
@@ -169,6 +195,7 @@ def test_uninstall_fails_with_wrong_version(self):
169195 self .run_pip .assert_not_called ()
170196
171197
198+ @requires_usable_pip
172199 def test_uninstall (self ):
173200 with fake_pip ():
174201 ensurepip ._uninstall_helper ()
@@ -177,6 +204,7 @@ def test_uninstall(self):
177204 ["uninstall" , "-y" , "pip" , "setuptools" ]
178205 )
179206
207+ @requires_usable_pip
180208 def test_uninstall_with_verbosity_1 (self ):
181209 with fake_pip ():
182210 ensurepip ._uninstall_helper (verbosity = 1 )
@@ -185,6 +213,7 @@ def test_uninstall_with_verbosity_1(self):
185213 ["uninstall" , "-y" , "-v" , "pip" , "setuptools" ]
186214 )
187215
216+ @requires_usable_pip
188217 def test_uninstall_with_verbosity_2 (self ):
189218 with fake_pip ():
190219 ensurepip ._uninstall_helper (verbosity = 2 )
@@ -193,6 +222,7 @@ def test_uninstall_with_verbosity_2(self):
193222 ["uninstall" , "-y" , "-vv" , "pip" , "setuptools" ]
194223 )
195224
225+ @requires_usable_pip
196226 def test_uninstall_with_verbosity_3 (self ):
197227 with fake_pip ():
198228 ensurepip ._uninstall_helper (verbosity = 3 )
@@ -201,6 +231,7 @@ def test_uninstall_with_verbosity_3(self):
201231 ["uninstall" , "-y" , "-vvv" , "pip" , "setuptools" ]
202232 )
203233
234+ @requires_usable_pip
204235 def test_pip_environment_variables_removed (self ):
205236 # ensurepip deliberately ignores all pip environment variables
206237 # See http://bugs.python.org/issue19734 for details
@@ -210,6 +241,30 @@ def test_pip_environment_variables_removed(self):
210241 self .assertNotIn ("PIP_THIS_SHOULD_GO_AWAY" , self .os_environ )
211242
212243
244+ class TestMissingSSL (EnsurepipMixin , unittest .TestCase ):
245+
246+ def setUp (self ):
247+ sys .modules ["ensurepip" ] = ensurepip_no_ssl
248+ @self .addCleanup
249+ def restore_module ():
250+ sys .modules ["ensurepip" ] = ensurepip
251+ super ().setUp ()
252+
253+ def test_bootstrap_requires_ssl (self ):
254+ self .os_environ ["PIP_THIS_SHOULD_STAY" ] = "test fodder"
255+ with self .assertRaisesRegex (RuntimeError , "requires SSL/TLS" ):
256+ ensurepip_no_ssl .bootstrap ()
257+ self .run_pip .assert_not_called ()
258+ self .assertIn ("PIP_THIS_SHOULD_STAY" , self .os_environ )
259+
260+ def test_uninstall_requires_ssl (self ):
261+ self .os_environ ["PIP_THIS_SHOULD_STAY" ] = "test fodder"
262+ with self .assertRaisesRegex (RuntimeError , "requires SSL/TLS" ):
263+ with fake_pip ():
264+ ensurepip_no_ssl ._uninstall_helper ()
265+ self .run_pip .assert_not_called ()
266+ self .assertIn ("PIP_THIS_SHOULD_STAY" , self .os_environ )
267+
213268# Basic testing of the main functions and their argument parsing
214269
215270EXPECTED_VERSION_OUTPUT = "pip " + ensurepip ._PIP_VERSION
@@ -224,6 +279,7 @@ def test_bootstrap_version(self):
224279 self .assertEqual (result , EXPECTED_VERSION_OUTPUT )
225280 self .run_pip .assert_not_called ()
226281
282+ @requires_usable_pip
227283 def test_basic_bootstrapping (self ):
228284 ensurepip ._main ([])
229285
@@ -248,6 +304,7 @@ def test_uninstall_version(self):
248304 self .assertEqual (result , EXPECTED_VERSION_OUTPUT )
249305 self .run_pip .assert_not_called ()
250306
307+ @requires_usable_pip
251308 def test_basic_uninstall (self ):
252309 with fake_pip ():
253310 ensurepip ._uninstall ._main ([])
0 commit comments