pip/tools/automation/vendoring/patches/appdirs.patch

116 lines
5.1 KiB
Diff

diff --git a/src/pip/_vendor/appdirs.py b/src/pip/_vendor/appdirs.py
index ae67001a..3a52b758 100644
--- a/src/pip/_vendor/appdirs.py
+++ b/src/pip/_vendor/appdirs.py
@@ -37,6 +37,10 @@ if sys.platform.startswith('java'):
# are actually checked for and the rest of the module expects
# *sys.platform* style strings.
system = 'linux2'
+elif sys.platform == 'cli' and os.name == 'nt':
+ # Detect Windows in IronPython to match pip._internal.utils.compat.WINDOWS
+ # Discussion: <https://github.com/pypa/pip/pull/7501>
+ system = 'win32'
else:
system = sys.platform
@@ -64,7 +68,7 @@ def user_data_dir(appname=None, appauthor=None, version=None, roaming=False):
for a discussion of issues.
Typical user data directories are:
- Mac OS X: ~/Library/Application Support/<AppName>
+ Mac OS X: ~/Library/Application Support/<AppName> # or ~/.config/<AppName>, if the other does not exist
Unix: ~/.local/share/<AppName> # or in $XDG_DATA_HOME, if defined
Win XP (not roaming): C:\Documents and Settings\<username>\Application Data\<AppAuthor>\<AppName>
Win XP (roaming): C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>
@@ -150,7 +154,7 @@ def site_data_dir(appname=None, appauthor=None, version=None, multipath=False):
if appname:
if version:
appname = os.path.join(appname, version)
- pathlist = [os.sep.join([x, appname]) for x in pathlist]
+ pathlist = [os.path.join(x, appname) for x in pathlist]
if multipath:
path = os.pathsep.join(pathlist)
@@ -203,6 +203,8 @@ def user_config_dir(appname=None, appauthor=None, version=None, roaming=False):
return path
+# for the discussion regarding site_config_dir locations
+# see <https://github.com/pypa/pip/issues/1733>
def site_config_dir(appname=None, appauthor=None, version=None, multipath=False):
r"""Return full path to the user-shared data dir for this application.
@@ -238,14 +244,15 @@ def site_config_dir(appname=None, appauthor=None, version=None, multipath=False)
if appname and version:
path = os.path.join(path, version)
else:
- # XDG default for $XDG_CONFIG_DIRS
+ # XDG default for $XDG_CONFIG_DIRS (missing or empty)
+ # see <https://github.com/pypa/pip/pull/7501#discussion_r360624829>
# only first, if multipath is False
- path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg')
- pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)]
+ path = os.getenv('XDG_CONFIG_DIRS') or '/etc/xdg'
+ pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep) if x]
if appname:
if version:
appname = os.path.join(appname, version)
- pathlist = [os.sep.join([x, appname]) for x in pathlist]
+ pathlist = [os.path.join(x, appname) for x in pathlist]
if multipath:
path = os.pathsep.join(pathlist)
@@ -291,6 +300,10 @@ def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True):
if appauthor is None:
appauthor = appname
path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA"))
+ # When using Python 2, return paths as bytes on Windows like we do on
+ # other operating systems. See helper function docs for more details.
+ if not PY3 and isinstance(path, unicode):
+ path = _win_path_to_bytes(path)
if appname:
if appauthor is not False:
path = os.path.join(path, appauthor, appname)
@@ -557,18 +570,32 @@ def _get_win_folder_with_jna(csidl_name):
if system == "win32":
try:
- import win32com.shell
- _get_win_folder = _get_win_folder_with_pywin32
+ from ctypes import windll
+ _get_win_folder = _get_win_folder_with_ctypes
except ImportError:
try:
- from ctypes import windll
- _get_win_folder = _get_win_folder_with_ctypes
+ import com.sun.jna
+ _get_win_folder = _get_win_folder_with_jna
except ImportError:
- try:
- import com.sun.jna
- _get_win_folder = _get_win_folder_with_jna
- except ImportError:
- _get_win_folder = _get_win_folder_from_registry
+ _get_win_folder = _get_win_folder_from_registry
+
+
+def _win_path_to_bytes(path):
+ """Encode Windows paths to bytes. Only used on Python 2.
+
+ Motivation is to be consistent with other operating systems where paths
+ are also returned as bytes. This avoids problems mixing bytes and Unicode
+ elsewhere in the codebase. For more details and discussion see
+ <https://github.com/pypa/pip/issues/3463>.
+
+ If encoding using ASCII and MBCS fails, return the original Unicode path.
+ """
+ for encoding in ('ASCII', 'MBCS'):
+ try:
+ return path.encode(encoding)
+ except (UnicodeEncodeError, LookupError):
+ pass
+ return path
#---- self test code