We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Conda(py2) Installation to a path (ascii characters only) with non-ascii characters in username
Create a user with non-ascii characters in name. And try to install Miniconda2 to a path with only ascii characters
```
C:\Users\AndrésGarcía\Downloads>start /wait "" Miniconda2-4.3.30.2-Windows-x86_64.exe 
/InstallationType=JustMe /AddToPath=0 /RegisterPython=0 /NoRegistry=1 /S /D=C:\AG\mc2
```
This will throw a menuinst traceback, ignore for now. See https://github.com/ContinuumIO/menuinst/issues/54

Then try to activate the base environment:
```
C:\Users\AndrésGarcía\Downloads>cd /d C:\AG\mc2

C:\AG\mc2>Scripts\activate
Traceback (most recent call last):
  File "C:\AG\mc2\Scripts\conda-script.py", line 10, in <module>
    sys.exit(main())
  File "C:\AG\mc2\lib\site-packages\conda\cli\main.py", line 178, in main
    init_loggers()
  File "C:\AG\mc2\lib\site-packages\conda\cli\main.py", line 84, in init_loggers
    from ..console import setup_verbose_handlers
  File "C:\AG\mc2\lib\site-packages\conda\console.py", line 9, in <module>
    from .base.context import context
  File "C:\AG\mc2\lib\site-packages\conda\base\context.py", line 771, in <module>
    context = Context(SEARCH_PATH, APP_NAME, None)
  File "C:\AG\mc2\lib\site-packages\conda\common\configuration.py", line 727, in __init__
    self._set_search_path(search_path)
  File "C:\AG\mc2\lib\site-packages\conda\common\configuration.py", line 745, in _set_search_path
    self._set_raw_data(load_file_configs(search_path))
  File "C:\AG\mc2\lib\site-packages\conda\common\configuration.py", line 364, in load_file_configs
    expanded_paths = tuple(expand(path) for path in search_path)
  File "C:\AG\mc2\lib\site-packages\conda\common\configuration.py", line 364, in <genexpr>
    expanded_paths = tuple(expand(path) for path in search_path)
  File "C:\AG\mc2\lib\site-packages\conda\common\path.py", line 247, in expand
    return abspath(expanduser(expandvars(path)))
  File "C:\AG\mc2\lib\ntpath.py", line 311, in expanduser
    return userhome + path[i:]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 13: ordinal not in range(128)

C:\AG\mc2>
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `conda/common/path.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 from __future__ import absolute_import, division, print_function, unicode_literals
3 
4 from functools import reduce
5 from logging import getLogger
6 import os
7 from os.path import abspath, basename, expanduser, expandvars, join, normpath, split, splitext
8 import re
9 import subprocess
10 
11 from .compat import on_win, string_types
12 from .. import CondaError
13 from .._vendor.auxlib.decorators import memoize
14 
15 try:
16     # Python 3
17     from urllib.parse import unquote, urlsplit
18     from urllib.request import url2pathname
19 except ImportError:  # pragma: no cover
20     # Python 2
21     from urllib import unquote, url2pathname  # NOQA
22     from urlparse import urlsplit  # NOQA
23 
24 try:
25     from cytoolz.itertoolz import accumulate, concat, take
26 except ImportError:  # pragma: no cover
27     from .._vendor.toolz.itertoolz import accumulate, concat, take
28 
29 log = getLogger(__name__)
30 
31 PATH_MATCH_REGEX = (
32     r"\./"              # ./
33     r"|\.\."            # ..
34     r"|~"               # ~
35     r"|/"               # /
36     r"|[a-zA-Z]:[/\\]"  # drive letter, colon, forward or backslash
37     r"|\\\\"            # windows UNC path
38     r"|//"              # windows UNC path
39 )
40 
41 
42 def is_path(value):
43     if '://' in value:
44         return False
45     return re.match(PATH_MATCH_REGEX, value)
46 
47 
48 def expand(path):
49     return abspath(expanduser(expandvars(path)))
50 
51 
52 def paths_equal(path1, path2):
53     """
54     Examples:
55         >>> paths_equal('/a/b/c', '/a/b/c/d/..')
56         True
57 
58     """
59     return normpath(abspath(path1)) == normpath(abspath(path2))
60 
61 
62 @memoize
63 def url_to_path(url):
64     """Convert a file:// URL to a path.
65 
66     Relative file URLs (i.e. `file:relative/path`) are not supported.
67     """
68     if is_path(url):
69         return url
70     if not url.startswith("file://"):  # pragma: no cover
71         raise CondaError("You can only turn absolute file: urls into paths (not %s)" % url)
72     _, netloc, path, _, _ = urlsplit(url)
73     path = unquote(path)
74     if netloc not in ('', 'localhost', '127.0.0.1', '::1'):
75         if not netloc.startswith('\\\\'):
76             # The only net location potentially accessible is a Windows UNC path
77             netloc = '//' + netloc
78     else:
79         netloc = ''
80         # Handle Windows drive letters if present
81         if re.match('^/([a-z])[:|]', path, re.I):
82             path = path[1] + ':' + path[3:]
83     return netloc + path
84 
85 
86 def tokenized_startswith(test_iterable, startswith_iterable):
87     return all(t == sw for t, sw in zip(test_iterable, startswith_iterable))
88 
89 
90 def get_all_directories(files):
91     directories = sorted(set(tuple(f.split('/')[:-1]) for f in files))
92     return directories or ()
93 
94 
95 def get_leaf_directories(files):
96     # type: (List[str]) -> List[str]
97     # give this function a list of files, and it will hand back a list of leaf directories to
98     #   pass to os.makedirs()
99     directories = get_all_directories(files)
100     if not directories:
101         return ()
102 
103     leaves = []
104 
105     def _process(x, y):
106         if not tokenized_startswith(y, x):
107             leaves.append(x)
108         return y
109     last = reduce(_process, directories)
110 
111     if not leaves:
112         leaves.append(directories[-1])
113     elif not tokenized_startswith(last, leaves[-1]):
114         leaves.append(last)
115 
116     return tuple('/'.join(leaf) for leaf in leaves)
117 
118 
119 def explode_directories(child_directories, already_split=False):
120     # get all directories including parents
121     # use already_split=True for the result of get_all_directories()
122     maybe_split = lambda x: x if already_split else x.split('/')
123     return set(concat(accumulate(join, maybe_split(directory)) for directory in child_directories))
124 
125 
126 def pyc_path(py_path, python_major_minor_version):
127     pyver_string = python_major_minor_version.replace('.', '')
128     if pyver_string.startswith('2'):
129         return py_path + 'c'
130     else:
131         directory, py_file = split(py_path)
132         basename_root, extension = splitext(py_file)
133         pyc_file = "__pycache__/%s.cpython-%s%sc" % (basename_root, pyver_string, extension)
134         return "%s/%s" % (directory, pyc_file) if directory else pyc_file
135 
136 
137 def missing_pyc_files(python_major_minor_version, files):
138     # returns a tuple of tuples, with the inner tuple being the .py file and the missing .pyc file
139     py_files = (f for f in files if f.endswith('.py'))
140     pyc_matches = ((py_file, pyc_path(py_file, python_major_minor_version))
141                    for py_file in py_files)
142     result = tuple(match for match in pyc_matches if match[1] not in files)
143     return result
144 
145 
146 def parse_entry_point_def(ep_definition):
147     cmd_mod, func = ep_definition.rsplit(':', 1)
148     command, module = cmd_mod.rsplit("=", 1)
149     command, module, func = command.strip(), module.strip(), func.strip()
150     return command, module, func
151 
152 
153 def get_python_short_path(python_version=None):
154     if on_win:
155         return "python.exe"
156     if python_version and '.' not in python_version:
157         python_version = '.'.join(python_version)
158     return join("bin", "python%s" % (python_version or ''))
159 
160 
161 def get_python_site_packages_short_path(python_version):
162     if python_version is None:
163         return None
164     elif on_win:
165         return 'Lib/site-packages'
166     else:
167         py_ver = get_major_minor_version(python_version)
168         return 'lib/python%s/site-packages' % py_ver
169 
170 
171 def get_major_minor_version(string, with_dot=True):
172     # returns None if not found, otherwise two digits as a string
173     # should work for
174     #   - 3.5.2
175     #   - 27
176     #   - bin/python2.7
177     #   - lib/python34/site-packages/
178     # the last two are dangers because windows doesn't have version information there
179     assert isinstance(string, string_types)
180     digits = tuple(take(2, (c for c in string if c.isdigit())))
181     if len(digits) == 2:
182         return '.'.join(digits) if with_dot else ''.join(digits)
183     return None
184 
185 
186 def get_bin_directory_short_path():
187     return 'Scripts' if on_win else 'bin'
188 
189 
190 def win_path_ok(path):
191     return path.replace('/', '\\') if on_win else path
192 
193 
194 def win_path_double_escape(path):
195     return path.replace('\\', '\\\\') if on_win else path
196 
197 
198 def win_path_backout(path):
199     # replace all backslashes except those escaping spaces
200     # if we pass a file url, something like file://\\unc\path\on\win, make sure
201     #   we clean that up too
202     return re.sub(r"(\\(?! ))", r"/", path).replace(':////', '://')
203 
204 
205 def ensure_pad(name, pad="_"):
206     """
207 
208     Examples:
209         >>> ensure_pad('conda')
210         '_conda_'
211 
212     """
213     return name and "%s%s%s" % (pad, name.strip(pad), pad)
214 
215 
216 def is_private_env_name(env_name):
217     """
218 
219     Examples:
220         >>> is_private_env_name("_conda")
221         False
222         >>> is_private_env_name("_conda_")
223         True
224 
225     """
226     return env_name and env_name[0] == env_name[-1] == "_"
227 
228 
229 def is_private_env_path(env_path):
230     """
231 
232     Examples:
233         >>> is_private_env_path('/some/path/to/envs/_conda_')
234         True
235         >>> is_private_env_path('/not/an/envs_dir/_conda_')
236         False
237 
238     """
239     if env_path is not None:
240         envs_directory, env_name = split(env_path)
241         if basename(envs_directory) != "envs":
242             return False
243         return is_private_env_name(env_name)
244     return False
245 
246 
247 def right_pad_os_sep(path):
248     return path if path.endswith(os.sep) else path + os.sep
249 
250 
251 def split_filename(path_or_url):
252     dn, fn = split(path_or_url)
253     return (dn or None, fn) if '.' in fn else (path_or_url, None)
254 
255 
256 def get_python_noarch_target_path(source_short_path, target_site_packages_short_path):
257     if source_short_path.startswith('site-packages/'):
258         sp_dir = target_site_packages_short_path
259         return source_short_path.replace('site-packages', sp_dir, 1)
260     elif source_short_path.startswith('python-scripts/'):
261         bin_dir = get_bin_directory_short_path()
262         return source_short_path.replace('python-scripts', bin_dir, 1)
263     else:
264         return source_short_path
265 
266 
267 def win_path_to_unix(path, root_prefix=""):
268     # If the user wishes to drive conda from MSYS2 itself while also having
269     # msys2 packages in their environment this allows the path conversion to
270     # happen relative to the actual shell. The onus is on the user to set
271     # CYGPATH to e.g. /usr/bin/cygpath.exe (this will be translated to e.g.
272     # (C:\msys32\usr\bin\cygpath.exe by MSYS2) to ensure this one is used.
273     if not path:
274         return ''
275     cygpath = os.environ.get('CYGPATH', 'cygpath.exe')
276     try:
277         path = subprocess.check_output([cygpath, '-up', path]).decode('ascii').split('\n')[0]
278     except Exception as e:
279         log.debug('%r' % e, exc_info=True)
280         # Convert a path or ;-separated string of paths into a unix representation
281         # Does not add cygdrive.  If you need that, set root_prefix to "/cygdrive"
282         def _translation(found_path):  # NOQA
283             found = found_path.group(1).replace("\\", "/").replace(":", "").replace("//", "/")
284             return root_prefix + "/" + found
285         path_re = '(?<![:/^a-zA-Z])([a-zA-Z]:[\/\\\\]+(?:[^:*?"<>|]+[\/\\\\]+)*[^:*?"<>|;\/\\\\]+?(?![a-zA-Z]:))'  # noqa
286         path = re.sub(path_re, _translation, path).replace(";/", ":/")
287     return path
288
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/conda/common/path.py b/conda/common/path.py
--- a/conda/common/path.py
+++ b/conda/common/path.py
@@ -8,7 +8,7 @@
 import re
 import subprocess
 
-from .compat import on_win, string_types
+from .compat import PY2, ensure_fs_path_encoding, on_win, string_types
 from .. import CondaError
 from .._vendor.auxlib.decorators import memoize
 
@@ -46,6 +46,8 @@
 
 
 def expand(path):
+    if on_win and PY2:
+        path = ensure_fs_path_encoding(path)
     return abspath(expanduser(expandvars(path)))

{"golden_diff": "diff --git a/conda/common/path.py b/conda/common/path.py\n--- a/conda/common/path.py\n+++ b/conda/common/path.py\n@@ -8,7 +8,7 @@\n import re\n import subprocess\n \n-from .compat import on_win, string_types\n+from .compat import PY2, ensure_fs_path_encoding, on_win, string_types\n from .. import CondaError\n from .._vendor.auxlib.decorators import memoize\n \n@@ -46,6 +46,8 @@\n \n \n def expand(path):\n+    if on_win and PY2:\n+        path = ensure_fs_path_encoding(path)\n     return abspath(expanduser(expandvars(path)))\n", "issue": "Conda(py2) Installation to a path (ascii characters only) with non-ascii characters in username\nCreate a user with non-ascii characters in name. And try to install Miniconda2 to a path with only ascii characters\r\n```\r\nC:\\Users\\Andr\u00e9sGarc\u00eda\\Downloads>start /wait \"\" Miniconda2-4.3.30.2-Windows-x86_64.exe \r\n/InstallationType=JustMe /AddToPath=0 /RegisterPython=0 /NoRegistry=1 /S /D=C:\\AG\\mc2\r\n```\r\nThis will throw a menuinst traceback, ignore for now. See https://github.com/ContinuumIO/menuinst/issues/54\r\n\r\nThen try to activate the base environment:\r\n```\r\nC:\\Users\\Andr\u00e9sGarc\u00eda\\Downloads>cd /d C:\\AG\\mc2\r\n\r\nC:\\AG\\mc2>Scripts\\activate\r\nTraceback (most recent call last):\r\n  File \"C:\\AG\\mc2\\Scripts\\conda-script.py\", line 10, in <module>\r\n    sys.exit(main())\r\n  File \"C:\\AG\\mc2\\lib\\site-packages\\conda\\cli\\main.py\", line 178, in main\r\n    init_loggers()\r\n  File \"C:\\AG\\mc2\\lib\\site-packages\\conda\\cli\\main.py\", line 84, in init_loggers\r\n    from ..console import setup_verbose_handlers\r\n  File \"C:\\AG\\mc2\\lib\\site-packages\\conda\\console.py\", line 9, in <module>\r\n    from .base.context import context\r\n  File \"C:\\AG\\mc2\\lib\\site-packages\\conda\\base\\context.py\", line 771, in <module>\r\n    context = Context(SEARCH_PATH, APP_NAME, None)\r\n  File \"C:\\AG\\mc2\\lib\\site-packages\\conda\\common\\configuration.py\", line 727, in __init__\r\n    self._set_search_path(search_path)\r\n  File \"C:\\AG\\mc2\\lib\\site-packages\\conda\\common\\configuration.py\", line 745, in _set_search_path\r\n    self._set_raw_data(load_file_configs(search_path))\r\n  File \"C:\\AG\\mc2\\lib\\site-packages\\conda\\common\\configuration.py\", line 364, in load_file_configs\r\n    expanded_paths = tuple(expand(path) for path in search_path)\r\n  File \"C:\\AG\\mc2\\lib\\site-packages\\conda\\common\\configuration.py\", line 364, in <genexpr>\r\n    expanded_paths = tuple(expand(path) for path in search_path)\r\n  File \"C:\\AG\\mc2\\lib\\site-packages\\conda\\common\\path.py\", line 247, in expand\r\n    return abspath(expanduser(expandvars(path)))\r\n  File \"C:\\AG\\mc2\\lib\\ntpath.py\", line 311, in expanduser\r\n    return userhome + path[i:]\r\nUnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 13: ordinal not in range(128)\r\n\r\nC:\\AG\\mc2>\r\n```\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nfrom functools import reduce\nfrom logging import getLogger\nimport os\nfrom os.path import abspath, basename, expanduser, expandvars, join, normpath, split, splitext\nimport re\nimport subprocess\n\nfrom .compat import on_win, string_types\nfrom .. import CondaError\nfrom .._vendor.auxlib.decorators import memoize\n\ntry:\n    # Python 3\n    from urllib.parse import unquote, urlsplit\n    from urllib.request import url2pathname\nexcept ImportError:  # pragma: no cover\n    # Python 2\n    from urllib import unquote, url2pathname  # NOQA\n    from urlparse import urlsplit  # NOQA\n\ntry:\n    from cytoolz.itertoolz import accumulate, concat, take\nexcept ImportError:  # pragma: no cover\n    from .._vendor.toolz.itertoolz import accumulate, concat, take\n\nlog = getLogger(__name__)\n\nPATH_MATCH_REGEX = (\n    r\"\\./\"              # ./\n    r\"|\\.\\.\"            # ..\n    r\"|~\"               # ~\n    r\"|/\"               # /\n    r\"|[a-zA-Z]:[/\\\\]\"  # drive letter, colon, forward or backslash\n    r\"|\\\\\\\\\"            # windows UNC path\n    r\"|//\"              # windows UNC path\n)\n\n\ndef is_path(value):\n    if '://' in value:\n        return False\n    return re.match(PATH_MATCH_REGEX, value)\n\n\ndef expand(path):\n    return abspath(expanduser(expandvars(path)))\n\n\ndef paths_equal(path1, path2):\n    \"\"\"\n    Examples:\n        >>> paths_equal('/a/b/c', '/a/b/c/d/..')\n        True\n\n    \"\"\"\n    return normpath(abspath(path1)) == normpath(abspath(path2))\n\n\n@memoize\ndef url_to_path(url):\n    \"\"\"Convert a file:// URL to a path.\n\n    Relative file URLs (i.e. `file:relative/path`) are not supported.\n    \"\"\"\n    if is_path(url):\n        return url\n    if not url.startswith(\"file://\"):  # pragma: no cover\n        raise CondaError(\"You can only turn absolute file: urls into paths (not %s)\" % url)\n    _, netloc, path, _, _ = urlsplit(url)\n    path = unquote(path)\n    if netloc not in ('', 'localhost', '127.0.0.1', '::1'):\n        if not netloc.startswith('\\\\\\\\'):\n            # The only net location potentially accessible is a Windows UNC path\n            netloc = '//' + netloc\n    else:\n        netloc = ''\n        # Handle Windows drive letters if present\n        if re.match('^/([a-z])[:|]', path, re.I):\n            path = path[1] + ':' + path[3:]\n    return netloc + path\n\n\ndef tokenized_startswith(test_iterable, startswith_iterable):\n    return all(t == sw for t, sw in zip(test_iterable, startswith_iterable))\n\n\ndef get_all_directories(files):\n    directories = sorted(set(tuple(f.split('/')[:-1]) for f in files))\n    return directories or ()\n\n\ndef get_leaf_directories(files):\n    # type: (List[str]) -> List[str]\n    # give this function a list of files, and it will hand back a list of leaf directories to\n    #   pass to os.makedirs()\n    directories = get_all_directories(files)\n    if not directories:\n        return ()\n\n    leaves = []\n\n    def _process(x, y):\n        if not tokenized_startswith(y, x):\n            leaves.append(x)\n        return y\n    last = reduce(_process, directories)\n\n    if not leaves:\n        leaves.append(directories[-1])\n    elif not tokenized_startswith(last, leaves[-1]):\n        leaves.append(last)\n\n    return tuple('/'.join(leaf) for leaf in leaves)\n\n\ndef explode_directories(child_directories, already_split=False):\n    # get all directories including parents\n    # use already_split=True for the result of get_all_directories()\n    maybe_split = lambda x: x if already_split else x.split('/')\n    return set(concat(accumulate(join, maybe_split(directory)) for directory in child_directories))\n\n\ndef pyc_path(py_path, python_major_minor_version):\n    pyver_string = python_major_minor_version.replace('.', '')\n    if pyver_string.startswith('2'):\n        return py_path + 'c'\n    else:\n        directory, py_file = split(py_path)\n        basename_root, extension = splitext(py_file)\n        pyc_file = \"__pycache__/%s.cpython-%s%sc\" % (basename_root, pyver_string, extension)\n        return \"%s/%s\" % (directory, pyc_file) if directory else pyc_file\n\n\ndef missing_pyc_files(python_major_minor_version, files):\n    # returns a tuple of tuples, with the inner tuple being the .py file and the missing .pyc file\n    py_files = (f for f in files if f.endswith('.py'))\n    pyc_matches = ((py_file, pyc_path(py_file, python_major_minor_version))\n                   for py_file in py_files)\n    result = tuple(match for match in pyc_matches if match[1] not in files)\n    return result\n\n\ndef parse_entry_point_def(ep_definition):\n    cmd_mod, func = ep_definition.rsplit(':', 1)\n    command, module = cmd_mod.rsplit(\"=\", 1)\n    command, module, func = command.strip(), module.strip(), func.strip()\n    return command, module, func\n\n\ndef get_python_short_path(python_version=None):\n    if on_win:\n        return \"python.exe\"\n    if python_version and '.' not in python_version:\n        python_version = '.'.join(python_version)\n    return join(\"bin\", \"python%s\" % (python_version or ''))\n\n\ndef get_python_site_packages_short_path(python_version):\n    if python_version is None:\n        return None\n    elif on_win:\n        return 'Lib/site-packages'\n    else:\n        py_ver = get_major_minor_version(python_version)\n        return 'lib/python%s/site-packages' % py_ver\n\n\ndef get_major_minor_version(string, with_dot=True):\n    # returns None if not found, otherwise two digits as a string\n    # should work for\n    #   - 3.5.2\n    #   - 27\n    #   - bin/python2.7\n    #   - lib/python34/site-packages/\n    # the last two are dangers because windows doesn't have version information there\n    assert isinstance(string, string_types)\n    digits = tuple(take(2, (c for c in string if c.isdigit())))\n    if len(digits) == 2:\n        return '.'.join(digits) if with_dot else ''.join(digits)\n    return None\n\n\ndef get_bin_directory_short_path():\n    return 'Scripts' if on_win else 'bin'\n\n\ndef win_path_ok(path):\n    return path.replace('/', '\\\\') if on_win else path\n\n\ndef win_path_double_escape(path):\n    return path.replace('\\\\', '\\\\\\\\') if on_win else path\n\n\ndef win_path_backout(path):\n    # replace all backslashes except those escaping spaces\n    # if we pass a file url, something like file://\\\\unc\\path\\on\\win, make sure\n    #   we clean that up too\n    return re.sub(r\"(\\\\(?! ))\", r\"/\", path).replace(':////', '://')\n\n\ndef ensure_pad(name, pad=\"_\"):\n    \"\"\"\n\n    Examples:\n        >>> ensure_pad('conda')\n        '_conda_'\n\n    \"\"\"\n    return name and \"%s%s%s\" % (pad, name.strip(pad), pad)\n\n\ndef is_private_env_name(env_name):\n    \"\"\"\n\n    Examples:\n        >>> is_private_env_name(\"_conda\")\n        False\n        >>> is_private_env_name(\"_conda_\")\n        True\n\n    \"\"\"\n    return env_name and env_name[0] == env_name[-1] == \"_\"\n\n\ndef is_private_env_path(env_path):\n    \"\"\"\n\n    Examples:\n        >>> is_private_env_path('/some/path/to/envs/_conda_')\n        True\n        >>> is_private_env_path('/not/an/envs_dir/_conda_')\n        False\n\n    \"\"\"\n    if env_path is not None:\n        envs_directory, env_name = split(env_path)\n        if basename(envs_directory) != \"envs\":\n            return False\n        return is_private_env_name(env_name)\n    return False\n\n\ndef right_pad_os_sep(path):\n    return path if path.endswith(os.sep) else path + os.sep\n\n\ndef split_filename(path_or_url):\n    dn, fn = split(path_or_url)\n    return (dn or None, fn) if '.' in fn else (path_or_url, None)\n\n\ndef get_python_noarch_target_path(source_short_path, target_site_packages_short_path):\n    if source_short_path.startswith('site-packages/'):\n        sp_dir = target_site_packages_short_path\n        return source_short_path.replace('site-packages', sp_dir, 1)\n    elif source_short_path.startswith('python-scripts/'):\n        bin_dir = get_bin_directory_short_path()\n        return source_short_path.replace('python-scripts', bin_dir, 1)\n    else:\n        return source_short_path\n\n\ndef win_path_to_unix(path, root_prefix=\"\"):\n    # If the user wishes to drive conda from MSYS2 itself while also having\n    # msys2 packages in their environment this allows the path conversion to\n    # happen relative to the actual shell. The onus is on the user to set\n    # CYGPATH to e.g. /usr/bin/cygpath.exe (this will be translated to e.g.\n    # (C:\\msys32\\usr\\bin\\cygpath.exe by MSYS2) to ensure this one is used.\n    if not path:\n        return ''\n    cygpath = os.environ.get('CYGPATH', 'cygpath.exe')\n    try:\n        path = subprocess.check_output([cygpath, '-up', path]).decode('ascii').split('\\n')[0]\n    except Exception as e:\n        log.debug('%r' % e, exc_info=True)\n        # Convert a path or ;-separated string of paths into a unix representation\n        # Does not add cygdrive.  If you need that, set root_prefix to \"/cygdrive\"\n        def _translation(found_path):  # NOQA\n            found = found_path.group(1).replace(\"\\\\\", \"/\").replace(\":\", \"\").replace(\"//\", \"/\")\n            return root_prefix + \"/\" + found\n        path_re = '(?<![:/^a-zA-Z])([a-zA-Z]:[\\/\\\\\\\\]+(?:[^:*?\"<>|]+[\\/\\\\\\\\]+)*[^:*?\"<>|;\\/\\\\\\\\]+?(?![a-zA-Z]:))'  # noqa\n        path = re.sub(path_re, _translation, path).replace(\";/\", \":/\")\n    return path\n", "path": "conda/common/path.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nfrom functools import reduce\nfrom logging import getLogger\nimport os\nfrom os.path import abspath, basename, expanduser, expandvars, join, normpath, split, splitext\nimport re\nimport subprocess\n\nfrom .compat import PY2, ensure_fs_path_encoding, on_win, string_types\nfrom .. import CondaError\nfrom .._vendor.auxlib.decorators import memoize\n\ntry:\n    # Python 3\n    from urllib.parse import unquote, urlsplit\n    from urllib.request import url2pathname\nexcept ImportError:  # pragma: no cover\n    # Python 2\n    from urllib import unquote, url2pathname  # NOQA\n    from urlparse import urlsplit  # NOQA\n\ntry:\n    from cytoolz.itertoolz import accumulate, concat, take\nexcept ImportError:  # pragma: no cover\n    from .._vendor.toolz.itertoolz import accumulate, concat, take\n\nlog = getLogger(__name__)\n\nPATH_MATCH_REGEX = (\n    r\"\\./\"              # ./\n    r\"|\\.\\.\"            # ..\n    r\"|~\"               # ~\n    r\"|/\"               # /\n    r\"|[a-zA-Z]:[/\\\\]\"  # drive letter, colon, forward or backslash\n    r\"|\\\\\\\\\"            # windows UNC path\n    r\"|//\"              # windows UNC path\n)\n\n\ndef is_path(value):\n    if '://' in value:\n        return False\n    return re.match(PATH_MATCH_REGEX, value)\n\n\ndef expand(path):\n    if on_win and PY2:\n        path = ensure_fs_path_encoding(path)\n    return abspath(expanduser(expandvars(path)))\n\n\ndef paths_equal(path1, path2):\n    \"\"\"\n    Examples:\n        >>> paths_equal('/a/b/c', '/a/b/c/d/..')\n        True\n\n    \"\"\"\n    return normpath(abspath(path1)) == normpath(abspath(path2))\n\n\n@memoize\ndef url_to_path(url):\n    \"\"\"Convert a file:// URL to a path.\n\n    Relative file URLs (i.e. `file:relative/path`) are not supported.\n    \"\"\"\n    if is_path(url):\n        return url\n    if not url.startswith(\"file://\"):  # pragma: no cover\n        raise CondaError(\"You can only turn absolute file: urls into paths (not %s)\" % url)\n    _, netloc, path, _, _ = urlsplit(url)\n    path = unquote(path)\n    if netloc not in ('', 'localhost', '127.0.0.1', '::1'):\n        if not netloc.startswith('\\\\\\\\'):\n            # The only net location potentially accessible is a Windows UNC path\n            netloc = '//' + netloc\n    else:\n        netloc = ''\n        # Handle Windows drive letters if present\n        if re.match('^/([a-z])[:|]', path, re.I):\n            path = path[1] + ':' + path[3:]\n    return netloc + path\n\n\ndef tokenized_startswith(test_iterable, startswith_iterable):\n    return all(t == sw for t, sw in zip(test_iterable, startswith_iterable))\n\n\ndef get_all_directories(files):\n    directories = sorted(set(tuple(f.split('/')[:-1]) for f in files))\n    return directories or ()\n\n\ndef get_leaf_directories(files):\n    # type: (List[str]) -> List[str]\n    # give this function a list of files, and it will hand back a list of leaf directories to\n    #   pass to os.makedirs()\n    directories = get_all_directories(files)\n    if not directories:\n        return ()\n\n    leaves = []\n\n    def _process(x, y):\n        if not tokenized_startswith(y, x):\n            leaves.append(x)\n        return y\n    last = reduce(_process, directories)\n\n    if not leaves:\n        leaves.append(directories[-1])\n    elif not tokenized_startswith(last, leaves[-1]):\n        leaves.append(last)\n\n    return tuple('/'.join(leaf) for leaf in leaves)\n\n\ndef explode_directories(child_directories, already_split=False):\n    # get all directories including parents\n    # use already_split=True for the result of get_all_directories()\n    maybe_split = lambda x: x if already_split else x.split('/')\n    return set(concat(accumulate(join, maybe_split(directory)) for directory in child_directories))\n\n\ndef pyc_path(py_path, python_major_minor_version):\n    pyver_string = python_major_minor_version.replace('.', '')\n    if pyver_string.startswith('2'):\n        return py_path + 'c'\n    else:\n        directory, py_file = split(py_path)\n        basename_root, extension = splitext(py_file)\n        pyc_file = \"__pycache__/%s.cpython-%s%sc\" % (basename_root, pyver_string, extension)\n        return \"%s/%s\" % (directory, pyc_file) if directory else pyc_file\n\n\ndef missing_pyc_files(python_major_minor_version, files):\n    # returns a tuple of tuples, with the inner tuple being the .py file and the missing .pyc file\n    py_files = (f for f in files if f.endswith('.py'))\n    pyc_matches = ((py_file, pyc_path(py_file, python_major_minor_version))\n                   for py_file in py_files)\n    result = tuple(match for match in pyc_matches if match[1] not in files)\n    return result\n\n\ndef parse_entry_point_def(ep_definition):\n    cmd_mod, func = ep_definition.rsplit(':', 1)\n    command, module = cmd_mod.rsplit(\"=\", 1)\n    command, module, func = command.strip(), module.strip(), func.strip()\n    return command, module, func\n\n\ndef get_python_short_path(python_version=None):\n    if on_win:\n        return \"python.exe\"\n    if python_version and '.' not in python_version:\n        python_version = '.'.join(python_version)\n    return join(\"bin\", \"python%s\" % (python_version or ''))\n\n\ndef get_python_site_packages_short_path(python_version):\n    if python_version is None:\n        return None\n    elif on_win:\n        return 'Lib/site-packages'\n    else:\n        py_ver = get_major_minor_version(python_version)\n        return 'lib/python%s/site-packages' % py_ver\n\n\ndef get_major_minor_version(string, with_dot=True):\n    # returns None if not found, otherwise two digits as a string\n    # should work for\n    #   - 3.5.2\n    #   - 27\n    #   - bin/python2.7\n    #   - lib/python34/site-packages/\n    # the last two are dangers because windows doesn't have version information there\n    assert isinstance(string, string_types)\n    digits = tuple(take(2, (c for c in string if c.isdigit())))\n    if len(digits) == 2:\n        return '.'.join(digits) if with_dot else ''.join(digits)\n    return None\n\n\ndef get_bin_directory_short_path():\n    return 'Scripts' if on_win else 'bin'\n\n\ndef win_path_ok(path):\n    return path.replace('/', '\\\\') if on_win else path\n\n\ndef win_path_double_escape(path):\n    return path.replace('\\\\', '\\\\\\\\') if on_win else path\n\n\ndef win_path_backout(path):\n    # replace all backslashes except those escaping spaces\n    # if we pass a file url, something like file://\\\\unc\\path\\on\\win, make sure\n    #   we clean that up too\n    return re.sub(r\"(\\\\(?! ))\", r\"/\", path).replace(':////', '://')\n\n\ndef ensure_pad(name, pad=\"_\"):\n    \"\"\"\n\n    Examples:\n        >>> ensure_pad('conda')\n        '_conda_'\n\n    \"\"\"\n    return name and \"%s%s%s\" % (pad, name.strip(pad), pad)\n\n\ndef is_private_env_name(env_name):\n    \"\"\"\n\n    Examples:\n        >>> is_private_env_name(\"_conda\")\n        False\n        >>> is_private_env_name(\"_conda_\")\n        True\n\n    \"\"\"\n    return env_name and env_name[0] == env_name[-1] == \"_\"\n\n\ndef is_private_env_path(env_path):\n    \"\"\"\n\n    Examples:\n        >>> is_private_env_path('/some/path/to/envs/_conda_')\n        True\n        >>> is_private_env_path('/not/an/envs_dir/_conda_')\n        False\n\n    \"\"\"\n    if env_path is not None:\n        envs_directory, env_name = split(env_path)\n        if basename(envs_directory) != \"envs\":\n            return False\n        return is_private_env_name(env_name)\n    return False\n\n\ndef right_pad_os_sep(path):\n    return path if path.endswith(os.sep) else path + os.sep\n\n\ndef split_filename(path_or_url):\n    dn, fn = split(path_or_url)\n    return (dn or None, fn) if '.' in fn else (path_or_url, None)\n\n\ndef get_python_noarch_target_path(source_short_path, target_site_packages_short_path):\n    if source_short_path.startswith('site-packages/'):\n        sp_dir = target_site_packages_short_path\n        return source_short_path.replace('site-packages', sp_dir, 1)\n    elif source_short_path.startswith('python-scripts/'):\n        bin_dir = get_bin_directory_short_path()\n        return source_short_path.replace('python-scripts', bin_dir, 1)\n    else:\n        return source_short_path\n\n\ndef win_path_to_unix(path, root_prefix=\"\"):\n    # If the user wishes to drive conda from MSYS2 itself while also having\n    # msys2 packages in their environment this allows the path conversion to\n    # happen relative to the actual shell. The onus is on the user to set\n    # CYGPATH to e.g. /usr/bin/cygpath.exe (this will be translated to e.g.\n    # (C:\\msys32\\usr\\bin\\cygpath.exe by MSYS2) to ensure this one is used.\n    if not path:\n        return ''\n    cygpath = os.environ.get('CYGPATH', 'cygpath.exe')\n    try:\n        path = subprocess.check_output([cygpath, '-up', path]).decode('ascii').split('\\n')[0]\n    except Exception as e:\n        log.debug('%r' % e, exc_info=True)\n        # Convert a path or ;-separated string of paths into a unix representation\n        # Does not add cygdrive.  If you need that, set root_prefix to \"/cygdrive\"\n        def _translation(found_path):  # NOQA\n            found = found_path.group(1).replace(\"\\\\\", \"/\").replace(\":\", \"\").replace(\"//\", \"/\")\n            return root_prefix + \"/\" + found\n        path_re = '(?<![:/^a-zA-Z])([a-zA-Z]:[\\/\\\\\\\\]+(?:[^:*?\"<>|]+[\\/\\\\\\\\]+)*[^:*?\"<>|;\\/\\\\\\\\]+?(?![a-zA-Z]:))'  # noqa\n        path = re.sub(path_re, _translation, path).replace(\";/\", \":/\")\n    return path\n", "path": "conda/common/path.py"}]}