pip 24.2__py3-none-any.whl → 24.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. pip/__init__.py +1 -1
  2. pip/_internal/build_env.py +4 -0
  3. pip/_internal/cli/index_command.py +1 -1
  4. pip/_internal/cli/parser.py +2 -2
  5. pip/_internal/cli/progress_bars.py +1 -1
  6. pip/_internal/commands/list.py +1 -1
  7. pip/_internal/commands/search.py +1 -1
  8. pip/_internal/exceptions.py +33 -1
  9. pip/_internal/index/sources.py +2 -3
  10. pip/_internal/locations/_distutils.py +3 -3
  11. pip/_internal/metadata/importlib/_envs.py +1 -1
  12. pip/_internal/models/wheel.py +28 -3
  13. pip/_internal/network/lazy_wheel.py +1 -1
  14. pip/_internal/req/constructors.py +1 -1
  15. pip/_internal/req/req_file.py +30 -7
  16. pip/_internal/resolution/resolvelib/candidates.py +7 -2
  17. pip/_internal/resolution/resolvelib/factory.py +11 -5
  18. pip/_internal/utils/compatibility_tags.py +25 -2
  19. pip/_internal/utils/misc.py +2 -7
  20. pip/_vendor/certifi/__init__.py +1 -1
  21. pip/_vendor/certifi/cacert.pem +131 -0
  22. pip/_vendor/distlib/__init__.py +1 -1
  23. pip/_vendor/distlib/compat.py +1 -2
  24. pip/_vendor/distlib/database.py +30 -60
  25. pip/_vendor/distlib/locators.py +57 -65
  26. pip/_vendor/distlib/markers.py +7 -12
  27. pip/_vendor/distlib/metadata.py +72 -109
  28. pip/_vendor/distlib/scripts.py +36 -55
  29. pip/_vendor/distlib/util.py +41 -82
  30. pip/_vendor/distlib/version.py +1 -2
  31. pip/_vendor/distlib/wheel.py +65 -64
  32. pip/_vendor/packaging/tags.py +64 -5
  33. pip/_vendor/truststore/__init__.py +24 -1
  34. pip/_vendor/truststore/_api.py +3 -0
  35. pip/_vendor/truststore/_macos.py +136 -64
  36. pip/_vendor/truststore/_windows.py +5 -2
  37. pip/_vendor/urllib3/_version.py +1 -1
  38. pip/_vendor/urllib3/connection.py +2 -2
  39. pip/_vendor/urllib3/connectionpool.py +5 -2
  40. pip/_vendor/urllib3/util/retry.py +3 -1
  41. pip/_vendor/urllib3/util/ssl_.py +13 -4
  42. pip/_vendor/vendor.txt +4 -4
  43. {pip-24.2.dist-info → pip-24.3.1.dist-info}/AUTHORS.txt +3 -0
  44. {pip-24.2.dist-info → pip-24.3.1.dist-info}/METADATA +2 -1
  45. {pip-24.2.dist-info → pip-24.3.1.dist-info}/RECORD +49 -49
  46. {pip-24.2.dist-info → pip-24.3.1.dist-info}/WHEEL +1 -1
  47. {pip-24.2.dist-info → pip-24.3.1.dist-info}/LICENSE.txt +0 -0
  48. {pip-24.2.dist-info → pip-24.3.1.dist-info}/entry_points.txt +0 -0
  49. {pip-24.2.dist-info → pip-24.3.1.dist-info}/top_level.txt +0 -0
pip/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from typing import List, Optional
2
2
 
3
- __version__ = "24.2"
3
+ __version__ = "24.3.1"
4
4
 
5
5
 
6
6
  def main(args: Optional[List[str]] = None) -> int:
@@ -242,6 +242,10 @@ class BuildEnvironment:
242
242
  prefix.path,
243
243
  "--no-warn-script-location",
244
244
  "--disable-pip-version-check",
245
+ # The prefix specified two lines above, thus
246
+ # target from config file or env var should be ignored
247
+ "--target",
248
+ "",
245
249
  ]
246
250
  if logger.getEffectiveLevel() <= logging.DEBUG:
247
251
  args.append("-vv")
@@ -54,7 +54,7 @@ class SessionCommandMixin(CommandContextMixIn):
54
54
 
55
55
  def __init__(self) -> None:
56
56
  super().__init__()
57
- self._session: Optional["PipSession"] = None
57
+ self._session: Optional[PipSession] = None
58
58
 
59
59
  @classmethod
60
60
  def _get_index_urls(cls, options: Values) -> Optional[List[str]]:
@@ -6,7 +6,7 @@ import shutil
6
6
  import sys
7
7
  import textwrap
8
8
  from contextlib import suppress
9
- from typing import Any, Dict, Generator, List, Optional, Tuple
9
+ from typing import Any, Dict, Generator, List, NoReturn, Optional, Tuple
10
10
 
11
11
  from pip._internal.cli.status_codes import UNKNOWN_ERROR
12
12
  from pip._internal.configuration import Configuration, ConfigurationError
@@ -289,6 +289,6 @@ class ConfigOptionParser(CustomOptionParser):
289
289
  defaults[option.dest] = option.check_value(opt_str, default)
290
290
  return optparse.Values(defaults)
291
291
 
292
- def error(self, msg: str) -> None:
292
+ def error(self, msg: str) -> NoReturn:
293
293
  self.print_usage(sys.stderr)
294
294
  self.exit(UNKNOWN_ERROR, f"{msg}\n")
@@ -25,7 +25,7 @@ def _rich_progress_bar(
25
25
  iterable: Iterable[bytes],
26
26
  *,
27
27
  bar_type: str,
28
- size: int,
28
+ size: Optional[int],
29
29
  ) -> Generator[bytes, None, None]:
30
30
  assert bar_type == "on", "This should only be used in the default mode."
31
31
 
@@ -176,7 +176,7 @@ class ListCommand(IndexGroupCommand):
176
176
  if options.excludes:
177
177
  skip.update(canonicalize_name(n) for n in options.excludes)
178
178
 
179
- packages: "_ProcessedDists" = [
179
+ packages: _ProcessedDists = [
180
180
  cast("_DistWithLatestInfo", d)
181
181
  for d in get_environment(options.path).iter_installed_distributions(
182
182
  local_only=options.local,
@@ -89,7 +89,7 @@ def transform_hits(hits: List[Dict[str, str]]) -> List["TransformedHit"]:
89
89
  packages with the list of versions stored inline. This converts the
90
90
  list from pypi into one we can use.
91
91
  """
92
- packages: Dict[str, "TransformedHit"] = OrderedDict()
92
+ packages: Dict[str, TransformedHit] = OrderedDict()
93
93
  for hit in hits:
94
94
  name = hit["name"]
95
95
  summary = hit["summary"]
@@ -15,6 +15,8 @@ import sys
15
15
  from itertools import chain, groupby, repeat
16
16
  from typing import TYPE_CHECKING, Dict, Iterator, List, Literal, Optional, Union
17
17
 
18
+ from pip._vendor.packaging.requirements import InvalidRequirement
19
+ from pip._vendor.packaging.version import InvalidVersion
18
20
  from pip._vendor.rich.console import Console, ConsoleOptions, RenderResult
19
21
  from pip._vendor.rich.markup import escape
20
22
  from pip._vendor.rich.text import Text
@@ -429,7 +431,7 @@ class HashErrors(InstallationError):
429
431
  """Multiple HashError instances rolled into one for reporting"""
430
432
 
431
433
  def __init__(self) -> None:
432
- self.errors: List["HashError"] = []
434
+ self.errors: List[HashError] = []
433
435
 
434
436
  def append(self, error: "HashError") -> None:
435
437
  self.errors.append(error)
@@ -775,3 +777,33 @@ class LegacyDistutilsInstall(DiagnosticPipError):
775
777
  ),
776
778
  hint_stmt=None,
777
779
  )
780
+
781
+
782
+ class InvalidInstalledPackage(DiagnosticPipError):
783
+ reference = "invalid-installed-package"
784
+
785
+ def __init__(
786
+ self,
787
+ *,
788
+ dist: "BaseDistribution",
789
+ invalid_exc: Union[InvalidRequirement, InvalidVersion],
790
+ ) -> None:
791
+ installed_location = dist.installed_location
792
+
793
+ if isinstance(invalid_exc, InvalidRequirement):
794
+ invalid_type = "requirement"
795
+ else:
796
+ invalid_type = "version"
797
+
798
+ super().__init__(
799
+ message=Text(
800
+ f"Cannot process installed package {dist} "
801
+ + (f"in {installed_location!r} " if installed_location else "")
802
+ + f"because it has an invalid {invalid_type}:\n{invalid_exc.args[0]}"
803
+ ),
804
+ context=(
805
+ "Starting with pip 24.1, packages with invalid "
806
+ f"{invalid_type}s can not be processed."
807
+ ),
808
+ hint_stmt="To proceed this package must be uninstalled.",
809
+ )
@@ -6,7 +6,6 @@ from typing import Callable, Dict, Iterable, List, Optional, Tuple
6
6
 
7
7
  from pip._vendor.packaging.utils import (
8
8
  InvalidSdistFilename,
9
- InvalidVersion,
10
9
  InvalidWheelFilename,
11
10
  canonicalize_name,
12
11
  parse_sdist_filename,
@@ -68,10 +67,10 @@ class _FlatDirectoryToUrls:
68
67
  # otherwise not worth considering as a package
69
68
  try:
70
69
  project_filename = parse_wheel_filename(entry.name)[0]
71
- except (InvalidWheelFilename, InvalidVersion):
70
+ except InvalidWheelFilename:
72
71
  try:
73
72
  project_filename = parse_sdist_filename(entry.name)[0]
74
- except (InvalidSdistFilename, InvalidVersion):
73
+ except InvalidSdistFilename:
75
74
  continue
76
75
 
77
76
  self._project_name_to_urls[project_filename].append(url)
@@ -21,7 +21,7 @@ from distutils.cmd import Command as DistutilsCommand
21
21
  from distutils.command.install import SCHEME_KEYS
22
22
  from distutils.command.install import install as distutils_install_command
23
23
  from distutils.sysconfig import get_python_lib
24
- from typing import Dict, List, Optional, Union, cast
24
+ from typing import Dict, List, Optional, Union
25
25
 
26
26
  from pip._internal.models.scheme import Scheme
27
27
  from pip._internal.utils.compat import WINDOWS
@@ -64,7 +64,7 @@ def distutils_scheme(
64
64
  obj: Optional[DistutilsCommand] = None
65
65
  obj = d.get_command_obj("install", create=True)
66
66
  assert obj is not None
67
- i = cast(distutils_install_command, obj)
67
+ i: distutils_install_command = obj
68
68
  # NOTE: setting user or home has the side-effect of creating the home dir
69
69
  # or user base for installations during finalize_options()
70
70
  # ideally, we'd prefer a scheme class that has no side-effects.
@@ -78,7 +78,7 @@ def distutils_scheme(
78
78
  i.root = root or i.root
79
79
  i.finalize_options()
80
80
 
81
- scheme = {}
81
+ scheme: Dict[str, str] = {}
82
82
  for key in SCHEME_KEYS:
83
83
  scheme[key] = getattr(i, "install_" + key)
84
84
 
@@ -150,7 +150,7 @@ def _emit_egg_deprecation(location: Optional[str]) -> None:
150
150
  deprecated(
151
151
  reason=f"Loading egg at {location} is deprecated.",
152
152
  replacement="to use pip for package installation",
153
- gone_in="24.3",
153
+ gone_in="25.1",
154
154
  issue=12330,
155
155
  )
156
156
 
@@ -6,8 +6,13 @@ import re
6
6
  from typing import Dict, Iterable, List
7
7
 
8
8
  from pip._vendor.packaging.tags import Tag
9
+ from pip._vendor.packaging.utils import (
10
+ InvalidWheelFilename as PackagingInvalidWheelName,
11
+ )
12
+ from pip._vendor.packaging.utils import parse_wheel_filename
9
13
 
10
14
  from pip._internal.exceptions import InvalidWheelFilename
15
+ from pip._internal.utils.deprecation import deprecated
11
16
 
12
17
 
13
18
  class Wheel:
@@ -29,9 +34,29 @@ class Wheel:
29
34
  raise InvalidWheelFilename(f"{filename} is not a valid wheel filename.")
30
35
  self.filename = filename
31
36
  self.name = wheel_info.group("name").replace("_", "-")
32
- # we'll assume "_" means "-" due to wheel naming scheme
33
- # (https://github.com/pypa/pip/issues/1150)
34
- self.version = wheel_info.group("ver").replace("_", "-")
37
+ _version = wheel_info.group("ver")
38
+ if "_" in _version:
39
+ try:
40
+ parse_wheel_filename(filename)
41
+ except PackagingInvalidWheelName as e:
42
+ deprecated(
43
+ reason=(
44
+ f"Wheel filename {filename!r} is not correctly normalised. "
45
+ "Future versions of pip will raise the following error:\n"
46
+ f"{e.args[0]}\n\n"
47
+ ),
48
+ replacement=(
49
+ "to rename the wheel to use a correctly normalised "
50
+ "name (this may require updating the version in "
51
+ "the project metadata)"
52
+ ),
53
+ gone_in="25.1",
54
+ issue=12938,
55
+ )
56
+
57
+ _version = _version.replace("_", "-")
58
+
59
+ self.version = _version
35
60
  self.build_tag = wheel_info.group("build")
36
61
  self.pyversions = wheel_info.group("pyver").split(".")
37
62
  self.abis = wheel_info.group("abi").split(".")
@@ -159,7 +159,7 @@ class LazyZipOverHTTP:
159
159
  try:
160
160
  # For read-only ZIP files, ZipFile only needs
161
161
  # methods read, seek, seekable and tell.
162
- ZipFile(self) # type: ignore
162
+ ZipFile(self)
163
163
  except BadZipFile:
164
164
  pass
165
165
  else:
@@ -80,7 +80,7 @@ def _set_requirement_extras(req: Requirement, new_extras: Set[str]) -> Requireme
80
80
  assert (
81
81
  pre is not None and post is not None
82
82
  ), f"regex group selection for requirement {req} failed, this should never happen"
83
- extras: str = "[%s]" % ",".join(sorted(new_extras)) if new_extras else ""
83
+ extras: str = "[{}]".format(",".join(sorted(new_extras)) if new_extras else "")
84
84
  return get_requirement(f"{pre}{extras}{post}")
85
85
 
86
86
 
@@ -329,10 +329,15 @@ class RequirementsFileParser:
329
329
  self, filename: str, constraint: bool
330
330
  ) -> Generator[ParsedLine, None, None]:
331
331
  """Parse a given file, yielding parsed lines."""
332
- yield from self._parse_and_recurse(filename, constraint)
332
+ yield from self._parse_and_recurse(
333
+ filename, constraint, [{os.path.abspath(filename): None}]
334
+ )
333
335
 
334
336
  def _parse_and_recurse(
335
- self, filename: str, constraint: bool
337
+ self,
338
+ filename: str,
339
+ constraint: bool,
340
+ parsed_files_stack: List[Dict[str, Optional[str]]],
336
341
  ) -> Generator[ParsedLine, None, None]:
337
342
  for line in self._parse_file(filename, constraint):
338
343
  if not line.is_requirement and (
@@ -353,12 +358,30 @@ class RequirementsFileParser:
353
358
  # original file and nested file are paths
354
359
  elif not SCHEME_RE.search(req_path):
355
360
  # do a join so relative paths work
356
- req_path = os.path.join(
357
- os.path.dirname(filename),
358
- req_path,
361
+ # and then abspath so that we can identify recursive references
362
+ req_path = os.path.abspath(
363
+ os.path.join(
364
+ os.path.dirname(filename),
365
+ req_path,
366
+ )
359
367
  )
360
-
361
- yield from self._parse_and_recurse(req_path, nested_constraint)
368
+ parsed_files = parsed_files_stack[0]
369
+ if req_path in parsed_files:
370
+ initial_file = parsed_files[req_path]
371
+ tail = (
372
+ f" and again in {initial_file}"
373
+ if initial_file is not None
374
+ else ""
375
+ )
376
+ raise RequirementsFileParseError(
377
+ f"{req_path} recursively references itself in {filename}{tail}"
378
+ )
379
+ # Keeping a track where was each file first included in
380
+ new_parsed_files = parsed_files.copy()
381
+ new_parsed_files[req_path] = filename
382
+ yield from self._parse_and_recurse(
383
+ req_path, nested_constraint, [new_parsed_files, *parsed_files_stack]
384
+ )
362
385
  else:
363
386
  yield line
364
387
 
@@ -9,6 +9,7 @@ from pip._vendor.packaging.version import Version
9
9
  from pip._internal.exceptions import (
10
10
  HashError,
11
11
  InstallationSubprocessError,
12
+ InvalidInstalledPackage,
12
13
  MetadataInconsistent,
13
14
  MetadataInvalid,
14
15
  )
@@ -398,8 +399,12 @@ class AlreadyInstalledCandidate(Candidate):
398
399
  def iter_dependencies(self, with_requires: bool) -> Iterable[Optional[Requirement]]:
399
400
  if not with_requires:
400
401
  return
401
- for r in self.dist.iter_dependencies():
402
- yield from self._factory.make_requirements_from_spec(str(r), self._ireq)
402
+
403
+ try:
404
+ for r in self.dist.iter_dependencies():
405
+ yield from self._factory.make_requirements_from_spec(str(r), self._ireq)
406
+ except InvalidRequirement as exc:
407
+ raise InvalidInstalledPackage(dist=self.dist, invalid_exc=exc) from None
403
408
 
404
409
  def get_install_requirement(self) -> Optional[InstallRequirement]:
405
410
  return None
@@ -23,13 +23,14 @@ from typing import (
23
23
  from pip._vendor.packaging.requirements import InvalidRequirement
24
24
  from pip._vendor.packaging.specifiers import SpecifierSet
25
25
  from pip._vendor.packaging.utils import NormalizedName, canonicalize_name
26
- from pip._vendor.packaging.version import Version
26
+ from pip._vendor.packaging.version import InvalidVersion, Version
27
27
  from pip._vendor.resolvelib import ResolutionImpossible
28
28
 
29
29
  from pip._internal.cache import CacheEntry, WheelCache
30
30
  from pip._internal.exceptions import (
31
31
  DistributionNotFound,
32
32
  InstallationError,
33
+ InvalidInstalledPackage,
33
34
  MetadataInconsistent,
34
35
  MetadataInvalid,
35
36
  UnsupportedPythonVersion,
@@ -283,10 +284,15 @@ class Factory:
283
284
  installed_dist = self._installed_dists[name]
284
285
  except KeyError:
285
286
  return None
286
- # Don't use the installed distribution if its version does not fit
287
- # the current dependency graph.
288
- if not specifier.contains(installed_dist.version, prereleases=True):
289
- return None
287
+
288
+ try:
289
+ # Don't use the installed distribution if its version
290
+ # does not fit the current dependency graph.
291
+ if not specifier.contains(installed_dist.version, prereleases=True):
292
+ return None
293
+ except InvalidVersion as e:
294
+ raise InvalidInstalledPackage(dist=installed_dist, invalid_exc=e)
295
+
290
296
  candidate = self._make_candidate_from_dist(
291
297
  dist=installed_dist,
292
298
  extras=extras,
@@ -12,10 +12,11 @@ from pip._vendor.packaging.tags import (
12
12
  generic_tags,
13
13
  interpreter_name,
14
14
  interpreter_version,
15
+ ios_platforms,
15
16
  mac_platforms,
16
17
  )
17
18
 
18
- _osx_arch_pat = re.compile(r"(.+)_(\d+)_(\d+)_(.+)")
19
+ _apple_arch_pat = re.compile(r"(.+)_(\d+)_(\d+)_(.+)")
19
20
 
20
21
 
21
22
  def version_info_to_nodot(version_info: Tuple[int, ...]) -> str:
@@ -24,7 +25,7 @@ def version_info_to_nodot(version_info: Tuple[int, ...]) -> str:
24
25
 
25
26
 
26
27
  def _mac_platforms(arch: str) -> List[str]:
27
- match = _osx_arch_pat.match(arch)
28
+ match = _apple_arch_pat.match(arch)
28
29
  if match:
29
30
  name, major, minor, actual_arch = match.groups()
30
31
  mac_version = (int(major), int(minor))
@@ -43,6 +44,26 @@ def _mac_platforms(arch: str) -> List[str]:
43
44
  return arches
44
45
 
45
46
 
47
+ def _ios_platforms(arch: str) -> List[str]:
48
+ match = _apple_arch_pat.match(arch)
49
+ if match:
50
+ name, major, minor, actual_multiarch = match.groups()
51
+ ios_version = (int(major), int(minor))
52
+ arches = [
53
+ # Since we have always only checked that the platform starts
54
+ # with "ios", for backwards-compatibility we extract the
55
+ # actual prefix provided by the user in case they provided
56
+ # something like "ioscustom_". It may be good to remove
57
+ # this as undocumented or deprecate it in the future.
58
+ "{}_{}".format(name, arch[len("ios_") :])
59
+ for arch in ios_platforms(ios_version, actual_multiarch)
60
+ ]
61
+ else:
62
+ # arch pattern didn't match (?!)
63
+ arches = [arch]
64
+ return arches
65
+
66
+
46
67
  def _custom_manylinux_platforms(arch: str) -> List[str]:
47
68
  arches = [arch]
48
69
  arch_prefix, arch_sep, arch_suffix = arch.partition("_")
@@ -68,6 +89,8 @@ def _get_custom_platforms(arch: str) -> List[str]:
68
89
  arch_prefix, arch_sep, arch_suffix = arch.partition("_")
69
90
  if arch.startswith("macosx"):
70
91
  arches = _mac_platforms(arch)
92
+ elif arch.startswith("ios"):
93
+ arches = _ios_platforms(arch)
71
94
  elif arch_prefix in ["manylinux2014", "manylinux2010"]:
72
95
  arches = _custom_manylinux_platforms(arch)
73
96
  else:
@@ -129,12 +129,7 @@ def rmtree(
129
129
  onexc = _onerror_ignore
130
130
  if onexc is None:
131
131
  onexc = _onerror_reraise
132
- handler: OnErr = partial(
133
- # `[func, path, Union[ExcInfo, BaseException]] -> Any` is equivalent to
134
- # `Union[([func, path, ExcInfo] -> Any), ([func, path, BaseException] -> Any)]`.
135
- cast(Union[OnExc, OnErr], rmtree_errorhandler),
136
- onexc=onexc,
137
- )
132
+ handler: OnErr = partial(rmtree_errorhandler, onexc=onexc)
138
133
  if sys.version_info >= (3, 12):
139
134
  # See https://docs.python.org/3.12/whatsnew/3.12.html#shutil.
140
135
  shutil.rmtree(dir, onexc=handler) # type: ignore
@@ -555,7 +550,7 @@ class HiddenText:
555
550
 
556
551
  # This is useful for testing.
557
552
  def __eq__(self, other: Any) -> bool:
558
- if type(self) != type(other):
553
+ if type(self) is not type(other):
559
554
  return False
560
555
 
561
556
  # The string being used for redaction doesn't also have to match,
@@ -1,4 +1,4 @@
1
1
  from .core import contents, where
2
2
 
3
3
  __all__ = ["contents", "where"]
4
- __version__ = "2024.07.04"
4
+ __version__ = "2024.08.30"
@@ -4796,3 +4796,134 @@ PQQDAwNoADBlAjAdfKR7w4l1M+E7qUW/Runpod3JIha3RxEL2Jq68cgLcFBTApFw
4796
4796
  hVmpHqTm6iMxoAACMQD94vizrxa5HnPEluPBMBnYfubDl94cT7iJLzPrSA8Z94dG
4797
4797
  XSaQpYXFuXqUPoeovQA=
4798
4798
  -----END CERTIFICATE-----
4799
+
4800
+ # Issuer: CN=TWCA CYBER Root CA O=TAIWAN-CA OU=Root CA
4801
+ # Subject: CN=TWCA CYBER Root CA O=TAIWAN-CA OU=Root CA
4802
+ # Label: "TWCA CYBER Root CA"
4803
+ # Serial: 85076849864375384482682434040119489222
4804
+ # MD5 Fingerprint: 0b:33:a0:97:52:95:d4:a9:fd:bb:db:6e:a3:55:5b:51
4805
+ # SHA1 Fingerprint: f6:b1:1c:1a:83:38:e9:7b:db:b3:a8:c8:33:24:e0:2d:9c:7f:26:66
4806
+ # SHA256 Fingerprint: 3f:63:bb:28:14:be:17:4e:c8:b6:43:9c:f0:8d:6d:56:f0:b7:c4:05:88:3a:56:48:a3:34:42:4d:6b:3e:c5:58
4807
+ -----BEGIN CERTIFICATE-----
4808
+ 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
4838
+ -----END CERTIFICATE-----
4839
+
4840
+ # Issuer: CN=SecureSign Root CA12 O=Cybertrust Japan Co., Ltd.
4841
+ # Subject: CN=SecureSign Root CA12 O=Cybertrust Japan Co., Ltd.
4842
+ # Label: "SecureSign Root CA12"
4843
+ # Serial: 587887345431707215246142177076162061960426065942
4844
+ # MD5 Fingerprint: c6:89:ca:64:42:9b:62:08:49:0b:1e:7f:e9:07:3d:e8
4845
+ # SHA1 Fingerprint: 7a:22:1e:3d:de:1b:06:ac:9e:c8:47:70:16:8e:3c:e5:f7:6b:06:f4
4846
+ # SHA256 Fingerprint: 3f:03:4b:b5:70:4d:44:b2:d0:85:45:a0:20:57:de:93:eb:f3:90:5f:ce:72:1a:cb:c7:30:c0:6d:da:ee:90:4e
4847
+ -----BEGIN CERTIFICATE-----
4848
+ MIIDcjCCAlqgAwIBAgIUZvnHwa/swlG07VOX5uaCwysckBYwDQYJKoZIhvcNAQEL
4849
+ BQAwUTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28u
4850
+ LCBMdGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExMjAeFw0yMDA0MDgw
4851
+ NTM2NDZaFw00MDA0MDgwNTM2NDZaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpD
4852
+ eWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBS
4853
+ b290IENBMTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6OcE3emhF
4854
+ KxS06+QT61d1I02PJC0W6K6OyX2kVzsqdiUzg2zqMoqUm048luT9Ub+ZyZN+v/mt
4855
+ p7JIKwccJ/VMvHASd6SFVLX9kHrko+RRWAPNEHl57muTH2SOa2SroxPjcf59q5zd
4856
+ J1M3s6oYwlkm7Fsf0uZlfO+TvdhYXAvA42VvPMfKWeP+bl+sg779XSVOKik71gur
4857
+ FzJ4pOE+lEa+Ym6b3kaosRbnhW70CEBFEaCeVESE99g2zvVQR9wsMJvuwPWW0v4J
4858
+ hscGWa5Pro4RmHvzC1KqYiaqId+OJTN5lxZJjfU+1UefNzFJM3IFTQy2VYzxV4+K
4859
+ h9GtxRESOaCtAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
4860
+ AgEGMB0GA1UdDgQWBBRXNPN0zwRL1SXm8UC2LEzZLemgrTANBgkqhkiG9w0BAQsF
4861
+ AAOCAQEAPrvbFxbS8hQBICw4g0utvsqFepq2m2um4fylOqyttCg6r9cBg0krY6Ld
4862
+ mmQOmFxv3Y67ilQiLUoT865AQ9tPkbeGGuwAtEGBpE/6aouIs3YIcipJQMPTw4WJ
4863
+ mBClnW8Zt7vPemVV2zfrPIpyMpcemik+rY3moxtt9XUa5rBouVui7mlHJzWhhpmA
4864
+ 8zNL4WukJsPvdFlseqJkth5Ew1DgDzk9qTPxpfPSvWKErI4cqc1avTc7bgoitPQV
4865
+ 55FYxTpE05Uo2cBl6XLK0A+9H7MV2anjpEcJnuDLN/v9vZfVvhgaaaI5gdka9at/
4866
+ yOPiZwud9AzqVN/Ssq+xIvEg37xEHA==
4867
+ -----END CERTIFICATE-----
4868
+
4869
+ # Issuer: CN=SecureSign Root CA14 O=Cybertrust Japan Co., Ltd.
4870
+ # Subject: CN=SecureSign Root CA14 O=Cybertrust Japan Co., Ltd.
4871
+ # Label: "SecureSign Root CA14"
4872
+ # Serial: 575790784512929437950770173562378038616896959179
4873
+ # MD5 Fingerprint: 71:0d:72:fa:92:19:65:5e:89:04:ac:16:33:f0:bc:d5
4874
+ # SHA1 Fingerprint: dd:50:c0:f7:79:b3:64:2e:74:a2:b8:9d:9f:d3:40:dd:bb:f0:f2:4f
4875
+ # SHA256 Fingerprint: 4b:00:9c:10:34:49:4f:9a:b5:6b:ba:3b:a1:d6:27:31:fc:4d:20:d8:95:5a:dc:ec:10:a9:25:60:72:61:e3:38
4876
+ -----BEGIN CERTIFICATE-----
4877
+ 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
4906
+ JRNItX+S
4907
+ -----END CERTIFICATE-----
4908
+
4909
+ # Issuer: CN=SecureSign Root CA15 O=Cybertrust Japan Co., Ltd.
4910
+ # Subject: CN=SecureSign Root CA15 O=Cybertrust Japan Co., Ltd.
4911
+ # Label: "SecureSign Root CA15"
4912
+ # Serial: 126083514594751269499665114766174399806381178503
4913
+ # MD5 Fingerprint: 13:30:fc:c4:62:a6:a9:de:b5:c1:68:af:b5:d2:31:47
4914
+ # SHA1 Fingerprint: cb:ba:83:c8:c1:5a:5d:f1:f9:73:6f:ca:d7:ef:28:13:06:4a:07:7d
4915
+ # SHA256 Fingerprint: e7:78:f0:f0:95:fe:84:37:29:cd:1a:00:82:17:9e:53:14:a9:c2:91:44:28:05:e1:fb:1d:8f:b6:b8:88:6c:3a
4916
+ -----BEGIN CERTIFICATE-----
4917
+ MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMw
4918
+ UTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBM
4919
+ dGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMy
4920
+ NTZaFw00NTA0MDgwODMyNTZaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpDeWJl
4921
+ cnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBSb290
4922
+ IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQLUHSNZDKZmbPSYAi4Io5GdCx4
4923
+ wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq8bOLbe1PL0vJSpSR
4924
+ ZHX+AezB2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB/wQFMAMB
4925
+ Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT
4926
+ 9DAKBggqhkjOPQQDAwNoADBlAjEA2S6Jfl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp
4927
+ 4P9mLQlO4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJSwdLZrWeqrqgHkHZAXQ6
4928
+ bkU6iYAZezKYVWOr62Nuk22rGwlgMU4=
4929
+ -----END CERTIFICATE-----
@@ -6,7 +6,7 @@
6
6
  #
7
7
  import logging
8
8
 
9
- __version__ = '0.3.8'
9
+ __version__ = '0.3.9'
10
10
 
11
11
 
12
12
  class DistlibException(Exception):
@@ -217,8 +217,7 @@ except ImportError: # pragma: no cover
217
217
  # Additionally check that `file` is not a directory, as on Windows
218
218
  # directories pass the os.access check.
219
219
  def _access_check(fn, mode):
220
- return (os.path.exists(fn) and os.access(fn, mode)
221
- and not os.path.isdir(fn))
220
+ return (os.path.exists(fn) and os.access(fn, mode) and not os.path.isdir(fn))
222
221
 
223
222
  # If we're given a path with a directory part, look it up directly rather
224
223
  # than referring to PATH directories. This includes checking relative to the