# Buggy code
def _read_channel_configuration(scheme, host, port, path):
    # return location, name, scheme, auth, token

    test_url = Url(host=host, port=port, path=path).url.rstrip("/")

    # Step 1. migrated_custom_channels matches
    for name, location in sorted(
        context.migrated_custom_channels.items(), reverse=True, key=lambda x: len(x[0])
    ):
        location, _scheme, _auth, _token = split_scheme_auth_token(location)
        if tokenized_conda_url_startswith(test_url, join_url(location, name)):
            # translate location to new location, with new credentials
            subname = test_url.replace(join_url(location, name), "", 1).strip("/")
            channel_name = join_url(name, subname)
            channel = _get_channel_for_name(channel_name)
            return (
                channel.location,
                channel_name,
                channel.scheme,
                channel.auth,
                channel.token,
            )

    # Step 2. migrated_channel_aliases matches
    for migrated_alias in context.migrated_channel_aliases:
        if test_url.startswith(migrated_alias.location):
            name = test_url.replace(migrated_alias.location, "", 1).strip("/")
            ca = context.channel_alias
            return ca.location, name, ca.scheme, ca.auth, ca.token

    # Step 3. custom_channels matches
    for name, channel in sorted(
        context.custom_channels.items(), reverse=True, key=lambda x: len(x[0])
    ):
        that_test_url = join_url(channel.location, channel.name)
        if test_url.startswith(that_test_url):
            subname = test_url.replace(that_test_url, "", 1).strip("/")
            return (
                channel.location,
                join_url(channel.name, subname),
                scheme,
                channel.auth,
                channel.token,
            )

    # Step 4. channel_alias match
    ca = context.channel_alias
    if ca.location and test_url.startswith(ca.location):
        name = test_url.replace(ca.location, "", 1).strip("/") or None
        return ca.location, name, scheme, ca.auth, ca.token

    # Step 5. not-otherwise-specified file://-type urls
    if host is None:
        # this should probably only happen with a file:// type url
        assert port is None
        location, name = test_url.rsplit("/", 1)
        if not location:
            location = "/"
        _scheme, _auth, _token = "file", None, None
        return location, name, _scheme, _auth, _token

    # Step 6. fall through to host:port as channel_location and path as channel_name
    return (
        Url(host=host, port=port).url.rstrip("/"),
        path.strip("/") or None,
        scheme or None,
        None,
        None,
    )


# Traceback (AttributeError)
Traceback (most recent call last):
File "C:\Miniconda3\lib\site-packages\conda\exceptions.py", line 479, in c
onda_exception_handler
return_value = func(*args, **kwargs)
File "C:\Miniconda3\lib\site-packages\conda\cli\main.py", line 145, in _ma
in
exit_code = args.func(args, p)
File "C:\Miniconda3\lib\site-packages\conda\cli\main_update.py", line 65,
in execute
install(args, parser, 'update')
File "C:\Miniconda3\lib\site-packages\conda\cli\install.py", line 308, in
install
update_deps=context.update_dependencies)
File "C:\Miniconda3\lib\site-packages\conda\plan.py", line 526, in install
_actions
force=force, always_copy=always_copy)
File "C:\Miniconda3\lib\site-packages\conda\plan.py", line 308, in ensure_
linked_actions
fetched_in = is_fetched(dist)
File "C:\Miniconda3\lib\site-packages\conda\install.py", line 727, in is_f
etched
for fn in package_cache().get(dist, {}).get('files', ()):
File "C:\Miniconda3\lib\site-packages\conda\install.py", line 675, in pack
age_cache
add_cached_package(pdir, url)
File "C:\Miniconda3\lib\site-packages\conda\install.py", line 633, in add_
cached_package
schannel = Channel(url).canonical_name
File "C:\Miniconda3\lib\site-packages\conda\models\channel.py", line 161,
in __call__
c = Channel.from_value(value)
File "C:\Miniconda3\lib\site-packages\conda\models\channel.py", line 211,
in from_value
return Channel.from_url(value)
File "C:\Miniconda3\lib\site-packages\conda\models\channel.py", line 196,
in from_url
return parse_conda_channel_url(url)
File "C:\Miniconda3\lib\site-packages\conda\models\channel.py", line 132,
in parse_conda_channel_url
configured_token) = _read_channel_configuration(scheme, host, port, path
)
File "C:\Miniconda3\lib\site-packages\conda\models\channel.py", line 122,
in _read_channel_configuration
return (Url(host=host, port=port).url.rstrip('/'), path.strip('/') or No
ne,
AttributeError: 'NoneType' object has no attribute 'strip'

# Fixed code
def _read_channel_configuration(scheme, host, port, path):
    # return location, name, scheme, auth, token

    path = path and path.rstrip("/")
    test_url = Url(host=host, port=port, path=path).url

    # Step 1. No path given; channel name is None
    if not path:
        return (
            Url(host=host, port=port).url.rstrip("/"),
            None,
            scheme or None,
            None,
            None,
        )

    # Step 2. migrated_custom_channels matches
    for name, location in sorted(
        context.migrated_custom_channels.items(), reverse=True, key=lambda x: len(x[0])
    ):
        location, _scheme, _auth, _token = split_scheme_auth_token(location)
        if tokenized_conda_url_startswith(test_url, join_url(location, name)):
            # translate location to new location, with new credentials
            subname = test_url.replace(join_url(location, name), "", 1).strip("/")
            channel_name = join_url(name, subname)
            channel = _get_channel_for_name(channel_name)
            return (
                channel.location,
                channel_name,
                channel.scheme,
                channel.auth,
                channel.token,
            )

    # Step 3. migrated_channel_aliases matches
    for migrated_alias in context.migrated_channel_aliases:
        if test_url.startswith(migrated_alias.location):
            name = test_url.replace(migrated_alias.location, "", 1).strip("/")
            ca = context.channel_alias
            return ca.location, name, ca.scheme, ca.auth, ca.token

    # Step 4. custom_channels matches
    for name, channel in sorted(
        context.custom_channels.items(), reverse=True, key=lambda x: len(x[0])
    ):
        that_test_url = join_url(channel.location, channel.name)
        if test_url.startswith(that_test_url):
            subname = test_url.replace(that_test_url, "", 1).strip("/")
            return (
                channel.location,
                join_url(channel.name, subname),
                scheme,
                channel.auth,
                channel.token,
            )

    # Step 5. channel_alias match
    ca = context.channel_alias
    if ca.location and test_url.startswith(ca.location):
        name = test_url.replace(ca.location, "", 1).strip("/") or None
        return ca.location, name, scheme, ca.auth, ca.token

    # Step 6. not-otherwise-specified file://-type urls
    if host is None:
        # this should probably only happen with a file:// type url
        assert port is None
        location, name = test_url.rsplit("/", 1)
        if not location:
            location = "/"
        _scheme, _auth, _token = "file", None, None
        return location, name, _scheme, _auth, _token

    # Step 7. fall through to host:port as channel_location and path as channel_name
    return (
        Url(host=host, port=port).url.rstrip("/"),
        path.strip("/") or None,
        scheme or None,
        None,
        None,
    )