2
2
import fnmatch
3
3
import io
4
4
import os
5
+ import pathlib
5
6
import re
6
7
import shutil
7
8
import subprocess
8
9
import sys
9
10
import time
10
11
from contextlib import ExitStack , contextmanager
11
- from typing import TYPE_CHECKING , Callable , Dict , Iterable , Iterator , List , Optional
12
+ from typing import (
13
+ TYPE_CHECKING ,
14
+ Callable ,
15
+ Dict ,
16
+ Iterable ,
17
+ Iterator ,
18
+ List ,
19
+ Optional ,
20
+ Union ,
21
+ )
12
22
from unittest .mock import patch
13
23
14
- import py .path
15
24
import pytest
16
25
17
26
# Config will be available from the public API in pytest >= 7.0.0:
27
36
from pip ._internal .locations import _USE_SYSCONFIG
28
37
from pip ._internal .utils .temp_dir import global_tempdir_manager
29
38
from tests .lib import DATA_DIR , SRC_DIR , PipTestEnvironment , TestData
30
- from tests .lib .path import Path
31
39
from tests .lib .server import MockServer as _MockServer
32
40
from tests .lib .server import make_mock_server , server_running
33
41
from tests .lib .venv import VirtualEnvironment , VirtualEnvironmentType
37
45
if TYPE_CHECKING :
38
46
from typing import Protocol
39
47
40
- from wsgi import WSGIApplication
48
+ from _typeshed . wsgi import WSGIApplication
41
49
else :
42
50
# TODO: Protocol was introduced in Python 3.8. Remove this branch when
43
51
# dropping support for Python 3.7.
@@ -146,42 +154,44 @@ def resolver_variant(request: pytest.FixtureRequest) -> Iterator[str]:
146
154
147
155
148
156
@pytest .fixture (scope = "session" )
149
- def tmpdir_factory (
150
- request : pytest .FixtureRequest , tmpdir_factory : pytest .TempdirFactory
151
- ) -> Iterator [pytest .TempdirFactory ]:
157
+ def tmp_path_factory (
158
+ request : pytest .FixtureRequest , tmp_path_factory : pytest .TempPathFactory
159
+ ) -> Iterator [pytest .TempPathFactory ]:
152
160
"""Modified `tmpdir_factory` session fixture
153
161
that will automatically cleanup after itself.
154
162
"""
155
- yield tmpdir_factory
163
+ yield tmp_path_factory
156
164
if not request .config .getoption ("--keep-tmpdir" ):
157
165
shutil .rmtree (
158
- tmpdir_factory .getbasetemp (),
166
+ tmp_path_factory .getbasetemp (),
159
167
ignore_errors = True ,
160
168
)
161
169
162
170
163
171
@pytest .fixture
164
- def tmpdir (request : pytest .FixtureRequest , tmpdir : py .path .local ) -> Iterator [Path ]:
172
+ def tmp_path (
173
+ request : pytest .FixtureRequest ,
174
+ tmp_path : pathlib .Path ,
175
+ ) -> Iterator [pathlib .Path ]:
165
176
"""
166
177
Return a temporary directory path object which is unique to each test
167
178
function invocation, created as a sub directory of the base temporary
168
- directory. The returned object is a ``tests.lib.path .Path`` object.
179
+ directory. The returned object is a ``pathlib .Path`` object.
169
180
170
- This uses the built-in tmpdir fixture from pytest itself but modified
171
- to return our typical path object instead of py.path.local as well as
172
- deleting the temporary directories at the end of each test case.
181
+ This uses the built-in tmp_path fixture from pytest itself, but deletes the
182
+ temporary directories at the end of each test case.
173
183
"""
174
- assert tmpdir . isdir ()
175
- yield Path ( str ( tmpdir ))
184
+ assert tmp_path . is_dir ()
185
+ yield tmp_path
176
186
# Clear out the temporary directory after the test has finished using it.
177
187
# This should prevent us from needing a multiple gigabyte temporary
178
188
# directory while running the tests.
179
189
if not request .config .getoption ("--keep-tmpdir" ):
180
- tmpdir . remove ( ignore_errors = True )
190
+ shutil . rmtree ( tmp_path , ignore_errors = True )
181
191
182
192
183
193
@pytest .fixture (autouse = True )
184
- def isolate (tmpdir : Path , monkeypatch : pytest .MonkeyPatch ) -> None :
194
+ def isolate (tmp_path : pathlib . Path , monkeypatch : pytest .MonkeyPatch ) -> None :
185
195
"""
186
196
Isolate our tests so that things like global configuration files and the
187
197
like do not affect our test results.
@@ -194,11 +204,11 @@ def isolate(tmpdir: Path, monkeypatch: pytest.MonkeyPatch) -> None:
194
204
# as well as user level configuration files.
195
205
196
206
# Create a directory to use as our home location.
197
- home_dir = os .path .join (str ( tmpdir ) , "home" )
207
+ home_dir = os .path .join (tmp_path , "home" )
198
208
os .makedirs (home_dir )
199
209
200
210
# Create a directory to use as a fake root
201
- fake_root = os .path .join (str ( tmpdir ) , "fake-root" )
211
+ fake_root = os .path .join (tmp_path , "fake-root" )
202
212
os .makedirs (fake_root )
203
213
204
214
if sys .platform == "win32" :
@@ -296,7 +306,7 @@ def scoped_global_tempdir_manager(request: pytest.FixtureRequest) -> Iterator[No
296
306
297
307
298
308
@pytest .fixture (scope = "session" )
299
- def pip_src (tmpdir_factory : pytest .TempdirFactory ) -> Path :
309
+ def pip_src (tmp_path_factory : pytest .TempPathFactory ) -> pathlib . Path :
300
310
def not_code_files_and_folders (path : str , names : List [str ]) -> Iterable [str ]:
301
311
# In the root directory...
302
312
if path == SRC_DIR :
@@ -317,7 +327,7 @@ def not_code_files_and_folders(path: str, names: List[str]) -> Iterable[str]:
317
327
ignored .update (fnmatch .filter (names , pattern ))
318
328
return ignored
319
329
320
- pip_src = Path ( str ( tmpdir_factory .mktemp ("pip_src" )) ).joinpath ("pip_src" )
330
+ pip_src = tmp_path_factory .mktemp ("pip_src" ).joinpath ("pip_src" )
321
331
# Copy over our source tree so that each use is self contained
322
332
shutil .copytree (
323
333
SRC_DIR ,
@@ -328,11 +338,11 @@ def not_code_files_and_folders(path: str, names: List[str]) -> Iterable[str]:
328
338
329
339
330
340
def _common_wheel_editable_install (
331
- tmpdir_factory : pytest .TempdirFactory , common_wheels : Path , package : str
332
- ) -> Path :
341
+ tmp_path_factory : pytest .TempPathFactory , common_wheels : pathlib . Path , package : str
342
+ ) -> pathlib . Path :
333
343
wheel_candidates = list (common_wheels .glob (f"{ package } -*.whl" ))
334
344
assert len (wheel_candidates ) == 1 , wheel_candidates
335
- install_dir = Path ( str ( tmpdir_factory .mktemp (package )) ) / "install"
345
+ install_dir = tmp_path_factory .mktemp (package ) / "install"
336
346
Wheel (wheel_candidates [0 ]).install_as_egg (install_dir )
337
347
(install_dir / "EGG-INFO" ).rename (install_dir / f"{ package } .egg-info" )
338
348
assert compileall .compile_dir (str (install_dir ), quiet = 1 )
@@ -341,25 +351,28 @@ def _common_wheel_editable_install(
341
351
342
352
@pytest .fixture (scope = "session" )
343
353
def setuptools_install (
344
- tmpdir_factory : pytest .TempdirFactory , common_wheels : Path
345
- ) -> Path :
346
- return _common_wheel_editable_install (tmpdir_factory , common_wheels , "setuptools" )
354
+ tmp_path_factory : pytest .TempPathFactory , common_wheels : pathlib . Path
355
+ ) -> pathlib . Path :
356
+ return _common_wheel_editable_install (tmp_path_factory , common_wheels , "setuptools" )
347
357
348
358
349
359
@pytest .fixture (scope = "session" )
350
- def wheel_install (tmpdir_factory : pytest .TempdirFactory , common_wheels : Path ) -> Path :
351
- return _common_wheel_editable_install (tmpdir_factory , common_wheels , "wheel" )
360
+ def wheel_install (
361
+ tmp_path_factory : pytest .TempPathFactory ,
362
+ common_wheels : pathlib .Path ,
363
+ ) -> pathlib .Path :
364
+ return _common_wheel_editable_install (tmp_path_factory , common_wheels , "wheel" )
352
365
353
366
354
367
@pytest .fixture (scope = "session" )
355
368
def coverage_install (
356
- tmpdir_factory : pytest .TempdirFactory , common_wheels : Path
357
- ) -> Path :
358
- return _common_wheel_editable_install (tmpdir_factory , common_wheels , "coverage" )
369
+ tmp_path_factory : pytest .TempPathFactory , common_wheels : pathlib . Path
370
+ ) -> pathlib . Path :
371
+ return _common_wheel_editable_install (tmp_path_factory , common_wheels , "coverage" )
359
372
360
373
361
374
def install_egg_link (
362
- venv : VirtualEnvironment , project_name : str , egg_info_dir : Path
375
+ venv : VirtualEnvironment , project_name : str , egg_info_dir : pathlib . Path
363
376
) -> None :
364
377
with open (venv .site / "easy-install.pth" , "a" ) as fp :
365
378
fp .write (str (egg_info_dir .resolve ()) + "\n " )
@@ -370,10 +383,10 @@ def install_egg_link(
370
383
@pytest .fixture (scope = "session" )
371
384
def virtualenv_template (
372
385
request : pytest .FixtureRequest ,
373
- tmpdir_factory : pytest .TempdirFactory ,
374
- pip_src : Path ,
375
- setuptools_install : Path ,
376
- coverage_install : Path ,
386
+ tmp_path_factory : pytest .TempPathFactory ,
387
+ pip_src : pathlib . Path ,
388
+ setuptools_install : pathlib . Path ,
389
+ coverage_install : pathlib . Path ,
377
390
) -> Iterator [VirtualEnvironment ]:
378
391
379
392
venv_type : VirtualEnvironmentType
@@ -383,12 +396,12 @@ def virtualenv_template(
383
396
venv_type = "virtualenv"
384
397
385
398
# Create the virtual environment
386
- tmpdir = Path ( str ( tmpdir_factory .mktemp ("virtualenv" )) )
387
- venv = VirtualEnvironment (tmpdir .joinpath ("venv_orig" ), venv_type = venv_type )
399
+ tmp_path = tmp_path_factory .mktemp ("virtualenv" )
400
+ venv = VirtualEnvironment (tmp_path .joinpath ("venv_orig" ), venv_type = venv_type )
388
401
389
402
# Install setuptools and pip.
390
403
install_egg_link (venv , "setuptools" , setuptools_install )
391
- pip_editable = Path ( str ( tmpdir_factory .mktemp ("pip" )) ) / "pip"
404
+ pip_editable = tmp_path_factory .mktemp ("pip" ) / "pip"
392
405
shutil .copytree (pip_src , pip_editable , symlinks = True )
393
406
# noxfile.py is Python 3 only
394
407
assert compileall .compile_dir (
@@ -420,58 +433,60 @@ def virtualenv_template(
420
433
421
434
# Rename original virtualenv directory to make sure
422
435
# it's not reused by mistake from one of the copies.
423
- venv_template = tmpdir / "venv_template"
436
+ venv_template = tmp_path / "venv_template"
424
437
venv .move (venv_template )
425
438
yield venv
426
439
427
440
428
441
@pytest .fixture (scope = "session" )
429
442
def virtualenv_factory (
430
443
virtualenv_template : VirtualEnvironment ,
431
- ) -> Callable [[Path ], VirtualEnvironment ]:
432
- def factory (tmpdir : Path ) -> VirtualEnvironment :
433
- return VirtualEnvironment (tmpdir , virtualenv_template )
444
+ ) -> Callable [[pathlib . Path ], VirtualEnvironment ]:
445
+ def factory (tmp_path : pathlib . Path ) -> VirtualEnvironment :
446
+ return VirtualEnvironment (tmp_path , virtualenv_template )
434
447
435
448
return factory
436
449
437
450
438
451
@pytest .fixture
439
452
def virtualenv (
440
- virtualenv_factory : Callable [[Path ], VirtualEnvironment ], tmpdir : Path
453
+ virtualenv_factory : Callable [[pathlib .Path ], VirtualEnvironment ],
454
+ tmp_path : pathlib .Path ,
441
455
) -> Iterator [VirtualEnvironment ]:
442
456
"""
443
457
Return a virtual environment which is unique to each test function
444
458
invocation created inside of a sub directory of the test function's
445
459
temporary directory. The returned object is a
446
460
``tests.lib.venv.VirtualEnvironment`` object.
447
461
"""
448
- yield virtualenv_factory (tmpdir .joinpath ("workspace" , "venv" ))
462
+ yield virtualenv_factory (tmp_path .joinpath ("workspace" , "venv" ))
449
463
450
464
451
465
@pytest .fixture
452
- def with_wheel (virtualenv : VirtualEnvironment , wheel_install : Path ) -> None :
466
+ def with_wheel (virtualenv : VirtualEnvironment , wheel_install : pathlib . Path ) -> None :
453
467
install_egg_link (virtualenv , "wheel" , wheel_install )
454
468
455
469
456
470
class ScriptFactory (Protocol ):
457
471
def __call__ (
458
- self , tmpdir : Path , virtualenv : Optional [VirtualEnvironment ] = None
472
+ self , tmp_path : pathlib . Path , virtualenv : Optional [VirtualEnvironment ] = None
459
473
) -> PipTestEnvironment :
460
474
...
461
475
462
476
463
477
@pytest .fixture (scope = "session" )
464
478
def script_factory (
465
- virtualenv_factory : Callable [[Path ], VirtualEnvironment ], deprecated_python : bool
479
+ virtualenv_factory : Callable [[pathlib .Path ], VirtualEnvironment ],
480
+ deprecated_python : bool ,
466
481
) -> ScriptFactory :
467
482
def factory (
468
- tmpdir : Path , virtualenv : Optional [VirtualEnvironment ] = None
483
+ tmp_path : pathlib . Path , virtualenv : Optional [VirtualEnvironment ] = None
469
484
) -> PipTestEnvironment :
470
485
if virtualenv is None :
471
- virtualenv = virtualenv_factory (tmpdir .joinpath ("venv" ))
486
+ virtualenv = virtualenv_factory (tmp_path .joinpath ("venv" ))
472
487
return PipTestEnvironment (
473
488
# The base location for our test environment
474
- tmpdir ,
489
+ tmp_path ,
475
490
# Tell the Test Environment where our virtualenv is located
476
491
virtualenv = virtualenv ,
477
492
# Do not ignore hidden files, they need to be checked as well
@@ -491,33 +506,33 @@ def factory(
491
506
492
507
@pytest .fixture
493
508
def script (
494
- tmpdir : Path ,
509
+ tmp_path : pathlib . Path ,
495
510
virtualenv : VirtualEnvironment ,
496
- script_factory : Callable [[ Path , Optional [ VirtualEnvironment ]], PipTestEnvironment ] ,
511
+ script_factory : ScriptFactory ,
497
512
) -> PipTestEnvironment :
498
513
"""
499
514
Return a PipTestEnvironment which is unique to each test function and
500
515
will execute all commands inside of the unique virtual environment for this
501
516
test function. The returned object is a
502
517
``tests.lib.PipTestEnvironment``.
503
518
"""
504
- return script_factory (tmpdir .joinpath ("workspace" ), virtualenv )
519
+ return script_factory (tmp_path .joinpath ("workspace" ), virtualenv )
505
520
506
521
507
522
@pytest .fixture (scope = "session" )
508
- def common_wheels () -> Path :
523
+ def common_wheels () -> pathlib . Path :
509
524
"""Provide a directory with latest setuptools and wheel wheels"""
510
525
return DATA_DIR .joinpath ("common_wheels" )
511
526
512
527
513
528
@pytest .fixture (scope = "session" )
514
- def shared_data (tmpdir_factory : pytest .TempdirFactory ) -> TestData :
515
- return TestData .copy (Path ( str ( tmpdir_factory .mktemp ("data" )) ))
529
+ def shared_data (tmp_path_factory : pytest .TempPathFactory ) -> TestData :
530
+ return TestData .copy (tmp_path_factory .mktemp ("data" ))
516
531
517
532
518
533
@pytest .fixture
519
- def data (tmpdir : Path ) -> TestData :
520
- return TestData .copy (tmpdir .joinpath ("data" ))
534
+ def data (tmp_path : pathlib . Path ) -> TestData :
535
+ return TestData .copy (tmp_path .joinpath ("data" ))
521
536
522
537
523
538
class InMemoryPipResult :
@@ -527,12 +542,12 @@ def __init__(self, returncode: int, stdout: str) -> None:
527
542
528
543
529
544
class InMemoryPip :
530
- def pip (self , * args : str ) -> InMemoryPipResult :
545
+ def pip (self , * args : Union [ str , pathlib . Path ] ) -> InMemoryPipResult :
531
546
orig_stdout = sys .stdout
532
547
stdout = io .StringIO ()
533
548
sys .stdout = stdout
534
549
try :
535
- returncode = pip_entry_point (list ( args ) )
550
+ returncode = pip_entry_point ([ os . fspath ( a ) for a in args ] )
536
551
except SystemExit as e :
537
552
returncode = e .code or 0
538
553
finally :
@@ -555,15 +570,15 @@ def deprecated_python() -> bool:
555
570
556
571
557
572
@pytest .fixture (scope = "session" )
558
- def cert_factory (tmpdir_factory : pytest .TempdirFactory ) -> CertFactory :
573
+ def cert_factory (tmp_path_factory : pytest .TempPathFactory ) -> CertFactory :
559
574
# Delay the import requiring cryptography in order to make it possible
560
575
# to deselect relevant tests on systems where cryptography cannot
561
576
# be installed.
562
577
from tests .lib .certs import make_tls_cert , serialize_cert , serialize_key
563
578
564
579
def factory () -> str :
565
580
"""Returns path to cert/key file."""
566
- output_path = Path ( str ( tmpdir_factory .mktemp ("certs" )) ) / "cert.pem"
581
+ output_path = tmp_path_factory .mktemp ("certs" ) / "cert.pem"
567
582
# Must be Text on PY2.
568
583
cert , key = make_tls_cert ("localhost" )
569
584
with open (str (output_path ), "wb" ) as f :
0 commit comments