Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/setuptools/_path.py: 41%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from __future__ import annotations
3import contextlib
4import os
5import sys
6from typing import TYPE_CHECKING, Union
8if TYPE_CHECKING:
9 from typing_extensions import TypeAlias
12from more_itertools import unique_everseen
14if sys.version_info >= (3, 9):
15 StrPath: TypeAlias = Union[str, os.PathLike[str]] # Same as _typeshed.StrPath
16else:
17 StrPath: TypeAlias = Union[str, os.PathLike]
20def ensure_directory(path):
21 """Ensure that the parent directory of `path` exists"""
22 dirname = os.path.dirname(path)
23 os.makedirs(dirname, exist_ok=True)
26def same_path(p1: StrPath, p2: StrPath) -> bool:
27 """Differs from os.path.samefile because it does not require paths to exist.
28 Purely string based (no comparison between i-nodes).
29 >>> same_path("a/b", "./a/b")
30 True
31 >>> same_path("a/b", "a/./b")
32 True
33 >>> same_path("a/b", "././a/b")
34 True
35 >>> same_path("a/b", "./a/b/c/..")
36 True
37 >>> same_path("a/b", "../a/b/c")
38 False
39 >>> same_path("a", "a/b")
40 False
41 """
42 return normpath(p1) == normpath(p2)
45def normpath(filename: StrPath) -> str:
46 """Normalize a file/dir name for comparison purposes."""
47 # See pkg_resources.normalize_path for notes about cygwin
48 file = os.path.abspath(filename) if sys.platform == 'cygwin' else filename
49 return os.path.normcase(os.path.realpath(os.path.normpath(file)))
52@contextlib.contextmanager
53def paths_on_pythonpath(paths):
54 """
55 Add the indicated paths to the head of the PYTHONPATH environment
56 variable so that subprocesses will also see the packages at
57 these paths.
59 Do this in a context that restores the value on exit.
61 >>> getfixture('monkeypatch').setenv('PYTHONPATH', 'anything')
62 >>> with paths_on_pythonpath(['foo', 'bar']):
63 ... assert 'foo' in os.environ['PYTHONPATH']
64 ... assert 'anything' in os.environ['PYTHONPATH']
65 >>> os.environ['PYTHONPATH']
66 'anything'
68 >>> getfixture('monkeypatch').delenv('PYTHONPATH')
69 >>> with paths_on_pythonpath(['foo', 'bar']):
70 ... assert 'foo' in os.environ['PYTHONPATH']
71 >>> os.environ.get('PYTHONPATH')
72 """
73 nothing = object()
74 orig_pythonpath = os.environ.get('PYTHONPATH', nothing)
75 current_pythonpath = os.environ.get('PYTHONPATH', '')
76 try:
77 prefix = os.pathsep.join(unique_everseen(paths))
78 to_join = filter(None, [prefix, current_pythonpath])
79 new_path = os.pathsep.join(to_join)
80 if new_path:
81 os.environ['PYTHONPATH'] = new_path
82 yield
83 finally:
84 if orig_pythonpath is nothing:
85 os.environ.pop('PYTHONPATH', None)
86 else:
87 os.environ['PYTHONPATH'] = orig_pythonpath