We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Regression: cannot install from explicit conda package filenames
This command used to work, but now it gives the following error/traceback:

Example: `conda install bzip2-1.0.6-vc14_3.tar.bz2 --dry-run`

```
An unexpected error has occurred.
Please consider posting the following information to the
conda GitHub issue tracker at:

    https://github.com/conda/conda/issues



Current conda install:

               platform : win-64
          conda version : 4.2.12
       conda is private : False
      conda-env version : 4.2.12
    conda-build version : 2.0.7
         python version : 3.5.2.final.0
       requests version : 2.10.0
       root environment : C:\Miniconda3  (writable)
    default environment : C:\Miniconda3\envs\test_conda
       envs directories : C:\Miniconda3\envs
          package cache : C:\Miniconda3\pkgs
           channel URLs : https://repo.continuum.io/pkgs/free/win-64
                          https://repo.continuum.io/pkgs/free/noarch
                          https://repo.continuum.io/pkgs/pro/win-64
                          https://repo.continuum.io/pkgs/pro/noarch
                          https://repo.continuum.io/pkgs/msys2/win-64
                          https://repo.continuum.io/pkgs/msys2/noarch
            config file : None
           offline mode : False



`$ C:\Miniconda3\Scripts\conda-script.py install bzip2-1.0.6-vc14_3.tar.bz2 --dry-run`




    Traceback (most recent call last):
      File "C:\Miniconda3\lib\site-packages\conda\exceptions.py", line 479, in conda_exception_handler
        return_value = func(*args, **kwargs)
      File "C:\Miniconda3\lib\site-packages\conda\cli\main.py", line 145, in _main
        exit_code = args.func(args, p)
      File "C:\Miniconda3\lib\site-packages\conda\cli\main_install.py", line 80, in execute
        install(args, parser, 'install')
      File "C:\Miniconda3\lib\site-packages\conda\cli\install.py", line 209, in install
        explicit(args.packages, prefix, verbose=not context.quiet)
      File "C:\Miniconda3\lib\site-packages\conda\misc.py", line 66, in explicit
        if not is_url(url_p):
      File "C:\Miniconda3\lib\site-packages\conda\common\url.py", line 72, in is_url
        p = urlparse(url)
      File "C:\Miniconda3\lib\site-packages\conda\_vendor\auxlib\decorators.py", line 56, in _memoized_func
        result = func(*args, **kwargs)
      File "C:\Miniconda3\lib\site-packages\conda\common\url.py", line 55, in urlparse
        if on_win and url.startswith('file:'):
    AttributeError: 'NoneType' object has no attribute 'startswith'
```

--- 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/url.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 from __future__ import absolute_import, division, print_function, unicode_literals
3 
4 import re
5 import socket
6 import sys
7 from getpass import getpass
8 from logging import getLogger
9 from os.path import abspath, expanduser
10 
11 try:
12     # Python 3
13     from urllib.parse import (quote, quote_plus, unquote, unquote_plus,  # NOQA
14                               urlunparse as stdlib_urlparse, urljoin)  # NOQA
15     from urllib.request import pathname2url  # NOQA
16 except ImportError:
17     # Python 2
18     from urllib import quote, quote_plus, unquote, unquote_plus, pathname2url  # NOQA
19     from urlparse import urlunparse as stdlib_urlparse, urljoin  # NOQA
20 
21 from requests.packages.urllib3.exceptions import LocationParseError
22 from requests.packages.urllib3.util.url import Url, parse_url
23 
24 from .._vendor.auxlib.decorators import memoize
25 
26 log = getLogger(__name__)
27 
28 
29 on_win = bool(sys.platform == "win32")
30 
31 
32 @memoize
33 def path_to_url(path):
34     path = abspath(expanduser(path))
35     url = urljoin('file:', pathname2url(path))
36     log.debug("%s converted to %s", path, url)
37     return url
38 
39 
40 def url_to_path(url):  # NOQA
41     """Convert a file:// URL to a path."""
42     assert url.startswith('file:'), "You can only turn file: urls into filenames (not %r)" % url
43     path = url[len('file:'):].lstrip('/')
44     path = unquote(path)
45     if re.match('^([a-z])[:|]', path, re.I):
46         path = path[0] + ':' + path[2:]
47     elif not path.startswith(r'\\'):
48         # if not a Windows UNC path
49         path = '/' + path
50     return path
51 
52 
53 @memoize
54 def urlparse(url):
55     if on_win and url.startswith('file:'):
56         url.replace('\\', '/')
57     return parse_url(url)
58 
59 
60 def url_to_s3_info(url):
61     """
62     Convert a S3 url to a tuple of bucket and key
63     """
64     parsed_url = parse_url(url)
65     assert parsed_url.scheme == 's3', "You can only use s3: urls (not %r)" % url
66     bucket, key = parsed_url.host, parsed_url.path
67     return bucket, key
68 
69 
70 def is_url(url):
71     try:
72         p = urlparse(url)
73         return p.netloc is not None or p.scheme == "file"
74     except LocationParseError:
75         log.debug("Could not parse url ({0}).".format(url))
76         return False
77 
78 
79 def is_ipv4_address(string_ip):
80     """
81     Examples:
82         >>> [is_ipv4_address(ip) for ip in ('8.8.8.8', '192.168.10.10', '255.255.255.255')]
83         [True, True, True]
84         >>> [is_ipv4_address(ip) for ip in ('8.8.8', '192.168.10.10.20', '256.255.255.255', '::1')]
85         [False, False, False, False]
86     """
87     try:
88         socket.inet_aton(string_ip)
89     except socket.error:
90         return False
91     return string_ip.count('.') == 3
92 
93 
94 def is_ipv6_address(string_ip):
95     """
96     Examples:
97         >>> [is_ipv6_address(ip) for ip in ('::1', '2001:db8:85a3::370:7334', '1234:'*7+'1234')]
98         [True, True, True]
99         >>> [is_ipv6_address(ip) for ip in ('192.168.10.10', '1234:'*8+'1234')]
100         [False, False]
101     """
102     try:
103         socket.inet_pton(socket.AF_INET6, string_ip)
104     except socket.error:
105         return False
106     return True
107 
108 
109 def is_ip_address(string_ip):
110     """
111     Examples:
112         >>> is_ip_address('192.168.10.10')
113         True
114         >>> is_ip_address('::1')
115         True
116         >>> is_ip_address('www.google.com')
117         False
118     """
119     return is_ipv4_address(string_ip) or is_ipv6_address(string_ip)
120 
121 
122 def join(*args):
123     start = '/' if not args[0] or args[0].startswith('/') else ''
124     return start + '/'.join(y for y in (x.strip('/') for x in args if x) if y)
125 
126 
127 join_url = join
128 
129 
130 def has_scheme(value):
131     return re.match(r'[a-z][a-z0-9]{0,11}://', value)
132 
133 
134 def strip_scheme(url):
135     return url.split('://', 1)[-1]
136 
137 
138 def mask_anaconda_token(url):
139     _, token = split_anaconda_token(url)
140     return url.replace(token, "<TOKEN>", 1) if token else url
141 
142 
143 def split_anaconda_token(url):
144     """
145     Examples:
146         >>> split_anaconda_token("https://1.2.3.4/t/tk-123-456/path")
147         (u'https://1.2.3.4/path', u'tk-123-456')
148         >>> split_anaconda_token("https://1.2.3.4/t//path")
149         (u'https://1.2.3.4/path', u'')
150         >>> split_anaconda_token("https://some.domain/api/t/tk-123-456/path")
151         (u'https://some.domain/api/path', u'tk-123-456')
152         >>> split_anaconda_token("https://1.2.3.4/conda/t/tk-123-456/path")
153         (u'https://1.2.3.4/conda/path', u'tk-123-456')
154         >>> split_anaconda_token("https://1.2.3.4/path")
155         (u'https://1.2.3.4/path', None)
156         >>> split_anaconda_token("https://10.2.3.4:8080/conda/t/tk-123-45")
157         (u'https://10.2.3.4:8080/conda', u'tk-123-45')
158     """
159     _token_match = re.search(r'/t/([a-zA-Z0-9-]*)', url)
160     token = _token_match.groups()[0] if _token_match else None
161     cleaned_url = url.replace('/t/' + token, '', 1) if token is not None else url
162     return cleaned_url.rstrip('/'), token
163 
164 
165 def split_platform(url):
166     """
167 
168     Examples:
169         >>> split_platform("https://1.2.3.4/t/tk-123/osx-64/path")
170         (u'https://1.2.3.4/t/tk-123/path', u'osx-64')
171 
172     """
173     from conda.base.constants import PLATFORM_DIRECTORIES
174     _platform_match_regex = r'/(%s)/?' % r'|'.join(r'%s' % d for d in PLATFORM_DIRECTORIES)
175     _platform_match = re.search(_platform_match_regex, url, re.IGNORECASE)
176     platform = _platform_match.groups()[0] if _platform_match else None
177     cleaned_url = url.replace('/' + platform, '', 1) if platform is not None else url
178     return cleaned_url.rstrip('/'), platform
179 
180 
181 def split_package_filename(url):
182     cleaned_url, package_filename = (url.rsplit('/', 1) if url.endswith(('.tar.bz2', '.json'))
183                                      else (url, None))
184     return cleaned_url, package_filename
185 
186 
187 def split_scheme_auth_token(url):
188     if not url:
189         return None, None, None, None
190     cleaned_url, token = split_anaconda_token(url)
191     url_parts = urlparse(cleaned_url)
192     remainder_url = Url(host=url_parts.host, port=url_parts.port, path=url_parts.path,
193                         query=url_parts.query).url
194     return remainder_url, url_parts.scheme, url_parts.auth, token
195 
196 
197 def split_conda_url_easy_parts(url):
198     # scheme, auth, token, platform, package_filename, host, port, path, query
199     cleaned_url, token = split_anaconda_token(url)
200     cleaned_url, platform = split_platform(cleaned_url)
201     cleaned_url, package_filename = split_package_filename(cleaned_url)
202 
203     # TODO: split out namespace using regex
204 
205     url_parts = urlparse(cleaned_url)
206 
207     return (url_parts.scheme, url_parts.auth, token, platform, package_filename, url_parts.host,
208             url_parts.port, url_parts.path, url_parts.query)
209 
210 
211 def is_windows_path(value):
212     return re.match(r'[a-z]:[/\\]', value, re.IGNORECASE)
213 
214 
215 @memoize
216 def get_proxy_username_and_pass(scheme):
217     username = input("\n%s proxy username: " % scheme)
218     passwd = getpass("Password:")
219     return username, passwd
220 
221 
222 def add_username_and_password(url, username, password):
223     url_parts = parse_url(url)._asdict()
224     url_parts['auth'] = username + ':' + quote(password, '')
225     return Url(**url_parts).url
226 
227 
228 def maybe_add_auth(url, auth, force=False):
229     """add auth if the url doesn't currently have it"""
230     if not auth:
231         return url
232     url_parts = urlparse(url)._asdict()
233     if url_parts['auth'] and not force:
234         return url
235     url_parts['auth'] = auth
236     return Url(**url_parts).url
237 
238 
239 if __name__ == "__main__":
240     import doctest
241     doctest.testmod()
242
```
--- 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/url.py b/conda/common/url.py
--- a/conda/common/url.py
+++ b/conda/common/url.py
@@ -68,6 +68,8 @@
 
 
 def is_url(url):
+    if not url:
+        return False
     try:
         p = urlparse(url)
         return p.netloc is not None or p.scheme == "file"

{"golden_diff": "diff --git a/conda/common/url.py b/conda/common/url.py\n--- a/conda/common/url.py\n+++ b/conda/common/url.py\n@@ -68,6 +68,8 @@\n \n \n def is_url(url):\n+    if not url:\n+        return False\n     try:\n         p = urlparse(url)\n         return p.netloc is not None or p.scheme == \"file\"\n", "issue": "Regression: cannot install from explicit conda package filenames\nThis command used to work, but now it gives the following error/traceback:\r\n\r\nExample: `conda install bzip2-1.0.6-vc14_3.tar.bz2 --dry-run`\r\n\r\n```\r\nAn unexpected error has occurred.\r\nPlease consider posting the following information to the\r\nconda GitHub issue tracker at:\r\n\r\n    https://github.com/conda/conda/issues\r\n\r\n\r\n\r\nCurrent conda install:\r\n\r\n               platform : win-64\r\n          conda version : 4.2.12\r\n       conda is private : False\r\n      conda-env version : 4.2.12\r\n    conda-build version : 2.0.7\r\n         python version : 3.5.2.final.0\r\n       requests version : 2.10.0\r\n       root environment : C:\\Miniconda3  (writable)\r\n    default environment : C:\\Miniconda3\\envs\\test_conda\r\n       envs directories : C:\\Miniconda3\\envs\r\n          package cache : C:\\Miniconda3\\pkgs\r\n           channel URLs : https://repo.continuum.io/pkgs/free/win-64\r\n                          https://repo.continuum.io/pkgs/free/noarch\r\n                          https://repo.continuum.io/pkgs/pro/win-64\r\n                          https://repo.continuum.io/pkgs/pro/noarch\r\n                          https://repo.continuum.io/pkgs/msys2/win-64\r\n                          https://repo.continuum.io/pkgs/msys2/noarch\r\n            config file : None\r\n           offline mode : False\r\n\r\n\r\n\r\n`$ C:\\Miniconda3\\Scripts\\conda-script.py install bzip2-1.0.6-vc14_3.tar.bz2 --dry-run`\r\n\r\n\r\n\r\n\r\n    Traceback (most recent call last):\r\n      File \"C:\\Miniconda3\\lib\\site-packages\\conda\\exceptions.py\", line 479, in conda_exception_handler\r\n        return_value = func(*args, **kwargs)\r\n      File \"C:\\Miniconda3\\lib\\site-packages\\conda\\cli\\main.py\", line 145, in _main\r\n        exit_code = args.func(args, p)\r\n      File \"C:\\Miniconda3\\lib\\site-packages\\conda\\cli\\main_install.py\", line 80, in execute\r\n        install(args, parser, 'install')\r\n      File \"C:\\Miniconda3\\lib\\site-packages\\conda\\cli\\install.py\", line 209, in install\r\n        explicit(args.packages, prefix, verbose=not context.quiet)\r\n      File \"C:\\Miniconda3\\lib\\site-packages\\conda\\misc.py\", line 66, in explicit\r\n        if not is_url(url_p):\r\n      File \"C:\\Miniconda3\\lib\\site-packages\\conda\\common\\url.py\", line 72, in is_url\r\n        p = urlparse(url)\r\n      File \"C:\\Miniconda3\\lib\\site-packages\\conda\\_vendor\\auxlib\\decorators.py\", line 56, in _memoized_func\r\n        result = func(*args, **kwargs)\r\n      File \"C:\\Miniconda3\\lib\\site-packages\\conda\\common\\url.py\", line 55, in urlparse\r\n        if on_win and url.startswith('file:'):\r\n    AttributeError: 'NoneType' object has no attribute 'startswith'\r\n```\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nimport re\nimport socket\nimport sys\nfrom getpass import getpass\nfrom logging import getLogger\nfrom os.path import abspath, expanduser\n\ntry:\n    # Python 3\n    from urllib.parse import (quote, quote_plus, unquote, unquote_plus,  # NOQA\n                              urlunparse as stdlib_urlparse, urljoin)  # NOQA\n    from urllib.request import pathname2url  # NOQA\nexcept ImportError:\n    # Python 2\n    from urllib import quote, quote_plus, unquote, unquote_plus, pathname2url  # NOQA\n    from urlparse import urlunparse as stdlib_urlparse, urljoin  # NOQA\n\nfrom requests.packages.urllib3.exceptions import LocationParseError\nfrom requests.packages.urllib3.util.url import Url, parse_url\n\nfrom .._vendor.auxlib.decorators import memoize\n\nlog = getLogger(__name__)\n\n\non_win = bool(sys.platform == \"win32\")\n\n\n@memoize\ndef path_to_url(path):\n    path = abspath(expanduser(path))\n    url = urljoin('file:', pathname2url(path))\n    log.debug(\"%s converted to %s\", path, url)\n    return url\n\n\ndef url_to_path(url):  # NOQA\n    \"\"\"Convert a file:// URL to a path.\"\"\"\n    assert url.startswith('file:'), \"You can only turn file: urls into filenames (not %r)\" % url\n    path = url[len('file:'):].lstrip('/')\n    path = unquote(path)\n    if re.match('^([a-z])[:|]', path, re.I):\n        path = path[0] + ':' + path[2:]\n    elif not path.startswith(r'\\\\'):\n        # if not a Windows UNC path\n        path = '/' + path\n    return path\n\n\n@memoize\ndef urlparse(url):\n    if on_win and url.startswith('file:'):\n        url.replace('\\\\', '/')\n    return parse_url(url)\n\n\ndef url_to_s3_info(url):\n    \"\"\"\n    Convert a S3 url to a tuple of bucket and key\n    \"\"\"\n    parsed_url = parse_url(url)\n    assert parsed_url.scheme == 's3', \"You can only use s3: urls (not %r)\" % url\n    bucket, key = parsed_url.host, parsed_url.path\n    return bucket, key\n\n\ndef is_url(url):\n    try:\n        p = urlparse(url)\n        return p.netloc is not None or p.scheme == \"file\"\n    except LocationParseError:\n        log.debug(\"Could not parse url ({0}).\".format(url))\n        return False\n\n\ndef is_ipv4_address(string_ip):\n    \"\"\"\n    Examples:\n        >>> [is_ipv4_address(ip) for ip in ('8.8.8.8', '192.168.10.10', '255.255.255.255')]\n        [True, True, True]\n        >>> [is_ipv4_address(ip) for ip in ('8.8.8', '192.168.10.10.20', '256.255.255.255', '::1')]\n        [False, False, False, False]\n    \"\"\"\n    try:\n        socket.inet_aton(string_ip)\n    except socket.error:\n        return False\n    return string_ip.count('.') == 3\n\n\ndef is_ipv6_address(string_ip):\n    \"\"\"\n    Examples:\n        >>> [is_ipv6_address(ip) for ip in ('::1', '2001:db8:85a3::370:7334', '1234:'*7+'1234')]\n        [True, True, True]\n        >>> [is_ipv6_address(ip) for ip in ('192.168.10.10', '1234:'*8+'1234')]\n        [False, False]\n    \"\"\"\n    try:\n        socket.inet_pton(socket.AF_INET6, string_ip)\n    except socket.error:\n        return False\n    return True\n\n\ndef is_ip_address(string_ip):\n    \"\"\"\n    Examples:\n        >>> is_ip_address('192.168.10.10')\n        True\n        >>> is_ip_address('::1')\n        True\n        >>> is_ip_address('www.google.com')\n        False\n    \"\"\"\n    return is_ipv4_address(string_ip) or is_ipv6_address(string_ip)\n\n\ndef join(*args):\n    start = '/' if not args[0] or args[0].startswith('/') else ''\n    return start + '/'.join(y for y in (x.strip('/') for x in args if x) if y)\n\n\njoin_url = join\n\n\ndef has_scheme(value):\n    return re.match(r'[a-z][a-z0-9]{0,11}://', value)\n\n\ndef strip_scheme(url):\n    return url.split('://', 1)[-1]\n\n\ndef mask_anaconda_token(url):\n    _, token = split_anaconda_token(url)\n    return url.replace(token, \"<TOKEN>\", 1) if token else url\n\n\ndef split_anaconda_token(url):\n    \"\"\"\n    Examples:\n        >>> split_anaconda_token(\"https://1.2.3.4/t/tk-123-456/path\")\n        (u'https://1.2.3.4/path', u'tk-123-456')\n        >>> split_anaconda_token(\"https://1.2.3.4/t//path\")\n        (u'https://1.2.3.4/path', u'')\n        >>> split_anaconda_token(\"https://some.domain/api/t/tk-123-456/path\")\n        (u'https://some.domain/api/path', u'tk-123-456')\n        >>> split_anaconda_token(\"https://1.2.3.4/conda/t/tk-123-456/path\")\n        (u'https://1.2.3.4/conda/path', u'tk-123-456')\n        >>> split_anaconda_token(\"https://1.2.3.4/path\")\n        (u'https://1.2.3.4/path', None)\n        >>> split_anaconda_token(\"https://10.2.3.4:8080/conda/t/tk-123-45\")\n        (u'https://10.2.3.4:8080/conda', u'tk-123-45')\n    \"\"\"\n    _token_match = re.search(r'/t/([a-zA-Z0-9-]*)', url)\n    token = _token_match.groups()[0] if _token_match else None\n    cleaned_url = url.replace('/t/' + token, '', 1) if token is not None else url\n    return cleaned_url.rstrip('/'), token\n\n\ndef split_platform(url):\n    \"\"\"\n\n    Examples:\n        >>> split_platform(\"https://1.2.3.4/t/tk-123/osx-64/path\")\n        (u'https://1.2.3.4/t/tk-123/path', u'osx-64')\n\n    \"\"\"\n    from conda.base.constants import PLATFORM_DIRECTORIES\n    _platform_match_regex = r'/(%s)/?' % r'|'.join(r'%s' % d for d in PLATFORM_DIRECTORIES)\n    _platform_match = re.search(_platform_match_regex, url, re.IGNORECASE)\n    platform = _platform_match.groups()[0] if _platform_match else None\n    cleaned_url = url.replace('/' + platform, '', 1) if platform is not None else url\n    return cleaned_url.rstrip('/'), platform\n\n\ndef split_package_filename(url):\n    cleaned_url, package_filename = (url.rsplit('/', 1) if url.endswith(('.tar.bz2', '.json'))\n                                     else (url, None))\n    return cleaned_url, package_filename\n\n\ndef split_scheme_auth_token(url):\n    if not url:\n        return None, None, None, None\n    cleaned_url, token = split_anaconda_token(url)\n    url_parts = urlparse(cleaned_url)\n    remainder_url = Url(host=url_parts.host, port=url_parts.port, path=url_parts.path,\n                        query=url_parts.query).url\n    return remainder_url, url_parts.scheme, url_parts.auth, token\n\n\ndef split_conda_url_easy_parts(url):\n    # scheme, auth, token, platform, package_filename, host, port, path, query\n    cleaned_url, token = split_anaconda_token(url)\n    cleaned_url, platform = split_platform(cleaned_url)\n    cleaned_url, package_filename = split_package_filename(cleaned_url)\n\n    # TODO: split out namespace using regex\n\n    url_parts = urlparse(cleaned_url)\n\n    return (url_parts.scheme, url_parts.auth, token, platform, package_filename, url_parts.host,\n            url_parts.port, url_parts.path, url_parts.query)\n\n\ndef is_windows_path(value):\n    return re.match(r'[a-z]:[/\\\\]', value, re.IGNORECASE)\n\n\n@memoize\ndef get_proxy_username_and_pass(scheme):\n    username = input(\"\\n%s proxy username: \" % scheme)\n    passwd = getpass(\"Password:\")\n    return username, passwd\n\n\ndef add_username_and_password(url, username, password):\n    url_parts = parse_url(url)._asdict()\n    url_parts['auth'] = username + ':' + quote(password, '')\n    return Url(**url_parts).url\n\n\ndef maybe_add_auth(url, auth, force=False):\n    \"\"\"add auth if the url doesn't currently have it\"\"\"\n    if not auth:\n        return url\n    url_parts = urlparse(url)._asdict()\n    if url_parts['auth'] and not force:\n        return url\n    url_parts['auth'] = auth\n    return Url(**url_parts).url\n\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n", "path": "conda/common/url.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nimport re\nimport socket\nimport sys\nfrom getpass import getpass\nfrom logging import getLogger\nfrom os.path import abspath, expanduser\n\ntry:\n    # Python 3\n    from urllib.parse import (quote, quote_plus, unquote, unquote_plus,  # NOQA\n                              urlunparse as stdlib_urlparse, urljoin)  # NOQA\n    from urllib.request import pathname2url  # NOQA\nexcept ImportError:\n    # Python 2\n    from urllib import quote, quote_plus, unquote, unquote_plus, pathname2url  # NOQA\n    from urlparse import urlunparse as stdlib_urlparse, urljoin  # NOQA\n\nfrom requests.packages.urllib3.exceptions import LocationParseError\nfrom requests.packages.urllib3.util.url import Url, parse_url\n\nfrom .._vendor.auxlib.decorators import memoize\n\nlog = getLogger(__name__)\n\n\non_win = bool(sys.platform == \"win32\")\n\n\n@memoize\ndef path_to_url(path):\n    path = abspath(expanduser(path))\n    url = urljoin('file:', pathname2url(path))\n    log.debug(\"%s converted to %s\", path, url)\n    return url\n\n\ndef url_to_path(url):  # NOQA\n    \"\"\"Convert a file:// URL to a path.\"\"\"\n    assert url.startswith('file:'), \"You can only turn file: urls into filenames (not %r)\" % url\n    path = url[len('file:'):].lstrip('/')\n    path = unquote(path)\n    if re.match('^([a-z])[:|]', path, re.I):\n        path = path[0] + ':' + path[2:]\n    elif not path.startswith(r'\\\\'):\n        # if not a Windows UNC path\n        path = '/' + path\n    return path\n\n\n@memoize\ndef urlparse(url):\n    if on_win and url.startswith('file:'):\n        url.replace('\\\\', '/')\n    return parse_url(url)\n\n\ndef url_to_s3_info(url):\n    \"\"\"\n    Convert a S3 url to a tuple of bucket and key\n    \"\"\"\n    parsed_url = parse_url(url)\n    assert parsed_url.scheme == 's3', \"You can only use s3: urls (not %r)\" % url\n    bucket, key = parsed_url.host, parsed_url.path\n    return bucket, key\n\n\ndef is_url(url):\n    if not url:\n        return False\n    try:\n        p = urlparse(url)\n        return p.netloc is not None or p.scheme == \"file\"\n    except LocationParseError:\n        log.debug(\"Could not parse url ({0}).\".format(url))\n        return False\n\n\ndef is_ipv4_address(string_ip):\n    \"\"\"\n    Examples:\n        >>> [is_ipv4_address(ip) for ip in ('8.8.8.8', '192.168.10.10', '255.255.255.255')]\n        [True, True, True]\n        >>> [is_ipv4_address(ip) for ip in ('8.8.8', '192.168.10.10.20', '256.255.255.255', '::1')]\n        [False, False, False, False]\n    \"\"\"\n    try:\n        socket.inet_aton(string_ip)\n    except socket.error:\n        return False\n    return string_ip.count('.') == 3\n\n\ndef is_ipv6_address(string_ip):\n    \"\"\"\n    Examples:\n        >>> [is_ipv6_address(ip) for ip in ('::1', '2001:db8:85a3::370:7334', '1234:'*7+'1234')]\n        [True, True, True]\n        >>> [is_ipv6_address(ip) for ip in ('192.168.10.10', '1234:'*8+'1234')]\n        [False, False]\n    \"\"\"\n    try:\n        socket.inet_pton(socket.AF_INET6, string_ip)\n    except socket.error:\n        return False\n    return True\n\n\ndef is_ip_address(string_ip):\n    \"\"\"\n    Examples:\n        >>> is_ip_address('192.168.10.10')\n        True\n        >>> is_ip_address('::1')\n        True\n        >>> is_ip_address('www.google.com')\n        False\n    \"\"\"\n    return is_ipv4_address(string_ip) or is_ipv6_address(string_ip)\n\n\ndef join(*args):\n    start = '/' if not args[0] or args[0].startswith('/') else ''\n    return start + '/'.join(y for y in (x.strip('/') for x in args if x) if y)\n\n\njoin_url = join\n\n\ndef has_scheme(value):\n    return re.match(r'[a-z][a-z0-9]{0,11}://', value)\n\n\ndef strip_scheme(url):\n    return url.split('://', 1)[-1]\n\n\ndef mask_anaconda_token(url):\n    _, token = split_anaconda_token(url)\n    return url.replace(token, \"<TOKEN>\", 1) if token else url\n\n\ndef split_anaconda_token(url):\n    \"\"\"\n    Examples:\n        >>> split_anaconda_token(\"https://1.2.3.4/t/tk-123-456/path\")\n        (u'https://1.2.3.4/path', u'tk-123-456')\n        >>> split_anaconda_token(\"https://1.2.3.4/t//path\")\n        (u'https://1.2.3.4/path', u'')\n        >>> split_anaconda_token(\"https://some.domain/api/t/tk-123-456/path\")\n        (u'https://some.domain/api/path', u'tk-123-456')\n        >>> split_anaconda_token(\"https://1.2.3.4/conda/t/tk-123-456/path\")\n        (u'https://1.2.3.4/conda/path', u'tk-123-456')\n        >>> split_anaconda_token(\"https://1.2.3.4/path\")\n        (u'https://1.2.3.4/path', None)\n        >>> split_anaconda_token(\"https://10.2.3.4:8080/conda/t/tk-123-45\")\n        (u'https://10.2.3.4:8080/conda', u'tk-123-45')\n    \"\"\"\n    _token_match = re.search(r'/t/([a-zA-Z0-9-]*)', url)\n    token = _token_match.groups()[0] if _token_match else None\n    cleaned_url = url.replace('/t/' + token, '', 1) if token is not None else url\n    return cleaned_url.rstrip('/'), token\n\n\ndef split_platform(url):\n    \"\"\"\n\n    Examples:\n        >>> split_platform(\"https://1.2.3.4/t/tk-123/osx-64/path\")\n        (u'https://1.2.3.4/t/tk-123/path', u'osx-64')\n\n    \"\"\"\n    from conda.base.constants import PLATFORM_DIRECTORIES\n    _platform_match_regex = r'/(%s)/?' % r'|'.join(r'%s' % d for d in PLATFORM_DIRECTORIES)\n    _platform_match = re.search(_platform_match_regex, url, re.IGNORECASE)\n    platform = _platform_match.groups()[0] if _platform_match else None\n    cleaned_url = url.replace('/' + platform, '', 1) if platform is not None else url\n    return cleaned_url.rstrip('/'), platform\n\n\ndef split_package_filename(url):\n    cleaned_url, package_filename = (url.rsplit('/', 1) if url.endswith(('.tar.bz2', '.json'))\n                                     else (url, None))\n    return cleaned_url, package_filename\n\n\ndef split_scheme_auth_token(url):\n    if not url:\n        return None, None, None, None\n    cleaned_url, token = split_anaconda_token(url)\n    url_parts = urlparse(cleaned_url)\n    remainder_url = Url(host=url_parts.host, port=url_parts.port, path=url_parts.path,\n                        query=url_parts.query).url\n    return remainder_url, url_parts.scheme, url_parts.auth, token\n\n\ndef split_conda_url_easy_parts(url):\n    # scheme, auth, token, platform, package_filename, host, port, path, query\n    cleaned_url, token = split_anaconda_token(url)\n    cleaned_url, platform = split_platform(cleaned_url)\n    cleaned_url, package_filename = split_package_filename(cleaned_url)\n\n    # TODO: split out namespace using regex\n\n    url_parts = urlparse(cleaned_url)\n\n    return (url_parts.scheme, url_parts.auth, token, platform, package_filename, url_parts.host,\n            url_parts.port, url_parts.path, url_parts.query)\n\n\ndef is_windows_path(value):\n    return re.match(r'[a-z]:[/\\\\]', value, re.IGNORECASE)\n\n\n@memoize\ndef get_proxy_username_and_pass(scheme):\n    username = input(\"\\n%s proxy username: \" % scheme)\n    passwd = getpass(\"Password:\")\n    return username, passwd\n\n\ndef add_username_and_password(url, username, password):\n    url_parts = parse_url(url)._asdict()\n    url_parts['auth'] = username + ':' + quote(password, '')\n    return Url(**url_parts).url\n\n\ndef maybe_add_auth(url, auth, force=False):\n    \"\"\"add auth if the url doesn't currently have it\"\"\"\n    if not auth:\n        return url\n    url_parts = urlparse(url)._asdict()\n    if url_parts['auth'] and not force:\n        return url\n    url_parts['auth'] = auth\n    return Url(**url_parts).url\n\n\nif __name__ == \"__main__\":\n    import doctest\n    doctest.testmod()\n", "path": "conda/common/url.py"}]}