Doctor Coder
Doctor Coder

Reputation: 1061

Python: how to print detailed error messages about errors?

I'd like to get detailed info about each variable treatment error.

Example 1:

user = User()
print(user.name)
...
AttributeError: variable 'user' (class User) doesn't have field 'name', there are only: full_name, address, telephone, email

Example 2:

some_nums = [1, 2, 3]
print(some_nums[3])
...
IndexError: attempt to get #4 'some_nums' list's elem; it has only 3 elems

I known i can wrap each method in my program in individual try-expect block and print such message in the except clause in each of them.

But it there any way to collect local variables data, automatically pass it to top single try-except block and print such messages there?

I saw something like in py.test library. It overrides builtin python assert's and prints detailed message in stack trace when assert falls https://pytest.org/latest/assert.html

Upvotes: 2

Views: 1368

Answers (1)

sberry
sberry

Reputation: 132018

You can override the magic method __getattribute__ if you want to

class HelpfulErrors(object):

    def __getattribute__(self, name):
        try:
            return object.__getattribute__(self, name)
        except:
            raise AttributeError("class {} doesn't have field '{}', there are only: {}".format(self.__class__.__name__, name, ", ".join(self.__dict__.keys())))

class User(HelpfulErrors):

    def __init__(self, age=21):
        self.age = age
        self.can_drink = self.age >= 21


u = User()
print(u.age)
print(u.can_drink)
print(u.name)

OUTPUT

21
True
Traceback (most recent call last):
  File "mes.py", line 18, in <module>
    print(u.name)
  File "mes.py", line 6, in __getattribute__
    raise AttributeError("class {} doesn't have field '{}', there are only: {}".format(self.__class__.__name__, name, ", ".join(self.__dict__.keys())))
AttributeError: class User doesn't have field 'name', there are only: can_drink, age

This really only tells you what is currently in the classes __dict__ though, so this could change over time unless all instance members that will ever be available are defined by the time __init__ is finished.

Upvotes: 1

Related Questions