Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Broken hasattr/getattr #3

Open
caenrigen opened this issue Jan 11, 2023 · 0 comments
Open

Broken hasattr/getattr #3

caenrigen opened this issue Jan 11, 2023 · 0 comments

Comments

@caenrigen
Copy link

Hi there! Cool packages, but run into an issue with it right in the beginning...

from dotsi import DotsiDict

assert getattr({}, "a", None) is None  # all good
hasattr(DotsiDict({}), "a") # raises
assert getattr(DotsiDict({}), "a", None) is None  # raises

which raises e.g.

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/var/folders/s5/z9b__9915kq1tpx_kltkywn80000gn/T/ipykernel_40275/4202784131.py in <module>
----> 1 assert getattr(DotsiDict({}), "a", None) is None

KeyError: 'a'

The problem is this line:

    __getattr__ = dict.__getitem__

and the core issue is this:

{}["a"]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/var/folders/s5/z9b__9915kq1tpx_kltkywn80000gn/T/ipykernel_24098/539066286.py in <module>
----> 1 {}["a"]

KeyError: 'a'
{}.a
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/var/folders/s5/z9b__9915kq1tpx_kltkywn80000gn/T/ipykernel_24098/3365273685.py in <module>
----> 1 {}.a

AttributeError: 'dict' object has no attribute 'a'

python relies on catching specific exceptions to make hasattr and getattr(obj, key, default_value) work


Potential solution is something like:

def getattr_func(self, attr: str):
    try:
        return dict.__getitem__(self, attr)
    except KeyError as e:
       # maybe improve messages to mimic the default one
        raise AttributeError(repr(attr)) from e


class DotsiDict(dict):
    "Extends `dict` to support dot-access."

    def __setitem__(self, key, value):  # PRIMARY
        super(DotsiDict, self).__setitem__(key, dotsify(value))

    __setattr__ = __setitem__
    __getattr__ = getattr_func
    __delattr__ = dict.__delitem__

    # ...

PS for context i run into this because I use iPython/JupyterLab + rich.pretty package to visualise objects:

from rich.pretty import install
install()

DotsiDict({}) # raises error because `rich.pretty` checks for `getattr(object_to_be_displayed, "_repr_html_", None)`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant