Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/pip/_internal/utils/compat.py @ 0:4f3585e2f14b draft default tip
"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author | shellac |
---|---|
date | Mon, 22 Mar 2021 18:12:50 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4f3585e2f14b |
---|---|
1 """Stuff that differs in different Python versions and platform | |
2 distributions.""" | |
3 | |
4 # The following comment should be removed at some point in the future. | |
5 # mypy: disallow-untyped-defs=False | |
6 | |
7 import codecs | |
8 import locale | |
9 import logging | |
10 import os | |
11 import sys | |
12 | |
13 from pip._internal.utils.typing import MYPY_CHECK_RUNNING | |
14 | |
15 if MYPY_CHECK_RUNNING: | |
16 from typing import Optional, Union | |
17 | |
18 | |
19 __all__ = ["console_to_str", "get_path_uid", "stdlib_pkgs", "WINDOWS"] | |
20 | |
21 | |
22 logger = logging.getLogger(__name__) | |
23 | |
24 | |
25 def has_tls(): | |
26 # type: () -> bool | |
27 try: | |
28 import _ssl # noqa: F401 # ignore unused | |
29 return True | |
30 except ImportError: | |
31 pass | |
32 | |
33 from pip._vendor.urllib3.util import IS_PYOPENSSL | |
34 return IS_PYOPENSSL | |
35 | |
36 | |
37 def str_to_display(data, desc=None): | |
38 # type: (Union[bytes, str], Optional[str]) -> str | |
39 """ | |
40 For display or logging purposes, convert a bytes object (or text) to | |
41 text (e.g. unicode in Python 2) safe for output. | |
42 | |
43 :param desc: An optional phrase describing the input data, for use in | |
44 the log message if a warning is logged. Defaults to "Bytes object". | |
45 | |
46 This function should never error out and so can take a best effort | |
47 approach. It is okay to be lossy if needed since the return value is | |
48 just for display. | |
49 | |
50 We assume the data is in the locale preferred encoding. If it won't | |
51 decode properly, we warn the user but decode as best we can. | |
52 | |
53 We also ensure that the output can be safely written to standard output | |
54 without encoding errors. | |
55 """ | |
56 if isinstance(data, str): | |
57 return data | |
58 | |
59 # Otherwise, data is a bytes object (str in Python 2). | |
60 # First, get the encoding we assume. This is the preferred | |
61 # encoding for the locale, unless that is not found, or | |
62 # it is ASCII, in which case assume UTF-8 | |
63 encoding = locale.getpreferredencoding() | |
64 if (not encoding) or codecs.lookup(encoding).name == "ascii": | |
65 encoding = "utf-8" | |
66 | |
67 # Now try to decode the data - if we fail, warn the user and | |
68 # decode with replacement. | |
69 try: | |
70 decoded_data = data.decode(encoding) | |
71 except UnicodeDecodeError: | |
72 logger.warning( | |
73 '%s does not appear to be encoded as %s', | |
74 desc or 'Bytes object', | |
75 encoding, | |
76 ) | |
77 decoded_data = data.decode(encoding, errors="backslashreplace") | |
78 | |
79 # Make sure we can print the output, by encoding it to the output | |
80 # encoding with replacement of unencodable characters, and then | |
81 # decoding again. | |
82 # We use stderr's encoding because it's less likely to be | |
83 # redirected and if we don't find an encoding we skip this | |
84 # step (on the assumption that output is wrapped by something | |
85 # that won't fail). | |
86 # The double getattr is to deal with the possibility that we're | |
87 # being called in a situation where sys.__stderr__ doesn't exist, | |
88 # or doesn't have an encoding attribute. Neither of these cases | |
89 # should occur in normal pip use, but there's no harm in checking | |
90 # in case people use pip in (unsupported) unusual situations. | |
91 output_encoding = getattr(getattr(sys, "__stderr__", None), | |
92 "encoding", None) | |
93 | |
94 if output_encoding: | |
95 output_encoded = decoded_data.encode( | |
96 output_encoding, | |
97 errors="backslashreplace" | |
98 ) | |
99 decoded_data = output_encoded.decode(output_encoding) | |
100 | |
101 return decoded_data | |
102 | |
103 | |
104 def console_to_str(data): | |
105 # type: (bytes) -> str | |
106 """Return a string, safe for output, of subprocess output. | |
107 """ | |
108 return str_to_display(data, desc='Subprocess output') | |
109 | |
110 | |
111 def get_path_uid(path): | |
112 # type: (str) -> int | |
113 """ | |
114 Return path's uid. | |
115 | |
116 Does not follow symlinks: | |
117 https://github.com/pypa/pip/pull/935#discussion_r5307003 | |
118 | |
119 Placed this function in compat due to differences on AIX and | |
120 Jython, that should eventually go away. | |
121 | |
122 :raises OSError: When path is a symlink or can't be read. | |
123 """ | |
124 if hasattr(os, 'O_NOFOLLOW'): | |
125 fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW) | |
126 file_uid = os.fstat(fd).st_uid | |
127 os.close(fd) | |
128 else: # AIX and Jython | |
129 # WARNING: time of check vulnerability, but best we can do w/o NOFOLLOW | |
130 if not os.path.islink(path): | |
131 # older versions of Jython don't have `os.fstat` | |
132 file_uid = os.stat(path).st_uid | |
133 else: | |
134 # raise OSError for parity with os.O_NOFOLLOW above | |
135 raise OSError( | |
136 "{} is a symlink; Will not return uid for symlinks".format( | |
137 path) | |
138 ) | |
139 return file_uid | |
140 | |
141 | |
142 # packages in the stdlib that may have installation metadata, but should not be | |
143 # considered 'installed'. this theoretically could be determined based on | |
144 # dist.location (py27:`sysconfig.get_paths()['stdlib']`, | |
145 # py26:sysconfig.get_config_vars('LIBDEST')), but fear platform variation may | |
146 # make this ineffective, so hard-coding | |
147 stdlib_pkgs = {"python", "wsgiref", "argparse"} | |
148 | |
149 | |
150 # windows detection, covers cpython and ironpython | |
151 WINDOWS = (sys.platform.startswith("win") or | |
152 (sys.platform == 'cli' and os.name == 'nt')) |