Repository: plotly/dash
File: dash/_utils.py (Python)

Code before:
        )
    return "/".join([requests_pathname.rstrip("/"), path.lstrip("/")])


def strip_relative_path(requests_pathname, path):
    if path is None:
        return None
    if (
        requests_pathname != "/" and not path.startswith(requests_pathname.rstrip("/"))
    ) or (requests_pathname == "/" and not path.startswith("/")):
        raise exceptions.UnsupportedRelativePath(
            """
            Paths that aren't prefixed with requests_pathname_prefix are not supported.
            You supplied: {} and requests_pathname_prefix was {}
            """.format(
                path, requests_pathname
            )
        )
    if requests_pathname != "/" and path.startswith(requests_pathname.rstrip("/")):
        path = path.replace(
            # handle the case where the path might be `/my-dash-app`
            # but the requests_pathname_prefix is `/my-dash-app/`
            requests_pathname.rstrip("/"),
            "",
            1,
        )
    return path.strip("/")


# pylint: disable=no-member
def patch_collections_abc(member):
    return getattr(collections if utils.PY2 else collections.abc, member)


class AttributeDict(dict):
    """Dictionary subclass enabling attribute lookup/assignment of keys/values.

    For example::
        >>> m = AttributeDict({'foo': 'bar'})
        >>> m.foo
        'bar'
        >>> m.foo = 'not bar'
        >>> m['foo']
        'not bar'
    ``AttributeDict`` objects also provide ``.first()`` which acts like
    ``.get()`` but accepts multiple keys as arguments, and returns the value of
    the first hit, e.g.::
        >>> m = AttributeDict({'foo': 'bar', 'biz': 'baz'})
        >>> m.first('wrong', 'incorrect', 'foo', 'biz')
        'bar'
    """

Review comment (suggestion):
In fact we should be able to 🔪 `patch_collections_abc` entirely

Code after:
        return None
    if (
        requests_pathname != "/" and not path.startswith(requests_pathname.rstrip("/"))
    ) or (requests_pathname == "/" and not path.startswith("/")):
        raise exceptions.UnsupportedRelativePath(
            """
            Paths that aren't prefixed with requests_pathname_prefix are not supported.
            You supplied: {} and requests_pathname_prefix was {}
            """.format(
                path, requests_pathname
            )
        )
    if requests_pathname != "/" and path.startswith(requests_pathname.rstrip("/")):
        path = path.replace(
            # handle the case where the path might be `/my-dash-app`
            # but the requests_pathname_prefix is `/my-dash-app/`
            requests_pathname.rstrip("/"),
            "",
            1,
        )
    return path.strip("/")


# pylint: disable=no-member
def patch_collections_abc(member):
    return getattr(collections.abc, member)


class AttributeDict(dict):
    """Dictionary subclass enabling attribute lookup/assignment of keys/values.

    For example::
        >>> m = AttributeDict({'foo': 'bar'})
        >>> m.foo
        'bar'
        >>> m.foo = 'not bar'
        >>> m['foo']
        'not bar'
    ``AttributeDict`` objects also provide ``.first()`` which acts like
    ``.get()`` but accepts multiple keys as arguments, and returns the value of
    the first hit, e.g.::
        >>> m = AttributeDict({'foo': 'bar', 'biz': 'baz'})
        >>> m.first('wrong', 'incorrect', 'foo', 'biz')
        'bar'
    """

    def __setattr__(self, key, value):
        self[key] = value

    def __getattr__(self, key):
        try: