0

I have a class which has an instance variable of type enum.Flag. It implements __getattr__ so that i can return the boolean state of a flag given by name.

The code works fine when running without debugging, producing the expected output.

Code sample run without debugging. Console output.

However, when i run it using the Visual Studio Debugger (VS 2019, 16.7.4, Python 3.6, 64-bit), it always stops in the __getattr__ method and i need to continue 100 times until i can continue normally. I have no breakpoint set!

VS 2019 Debugger stopping in the __getattr__

I tested the very same code in IDLE. IDLE does NOT stop in getattr during debugging!

How can i get rid of those annoying false positives disturbing my debug session?

from enum import Flag, auto
from copy import deepcopy

class MyFlags(Flag):
    FOO = auto()
    BAR = auto()
    BAZ = auto()

class Features:
    __slots__ = ('_features', )
    
    def __init__(self, bitmask):
        self._features = bitmask

    @property
    def bitmask(self):
        return self._features

    def __getattr__(self, attr):
        try:
            return bool(MyFlags[attr].value & self._features)

        except:
            raise AttributeError(attr)

f = Features(5)

print(f.bitmask)
print(f.FOO)
print(f.BAR)
print(f.BAZ)

f = Features(3)

print(f.bitmask)
print(f.FOO)
print(f.BAR)
print(f.BAZ)

g = deepcopy(f)

print(f.bitmask)
print(f.FOO)
print(f.BAR)
print(f.BAZ)
  • The VSD screenshot shows something about a "triggered exception", and offers you to "copy details". Please [edit] your post to provide them, unless they seem completely unrelated (in which case, please state so). – MisterMiyagi Sep 25 '20 at 09:32
  • Sorry, the details did not give more insights: `Nachricht = __deepcopy__ Quelle = path\deepcopy_test.py Stapelüberwachung: File "path\deepcopy_test.py", line 34, in __getattr__ raise AttributeError(attr) File "path\deepcopy_test.py", line 50, in g = deepcopy(f)` – Wör Du Schnaffzig Sep 25 '20 at 09:44
  • It looks as if VSD just stops on any exception during debug mode. In my tests, your code triggers this only 3 times though – what is the message on the other 97 times? – MisterMiyagi Sep 25 '20 at 09:48
  • That the DebugBreak is triggered 3 times, results from the simplified example. In my real code it is triggered more times. It is triggered on '__deepcopy__', '__getstate__', '__setstate__', obviously executed from several deepcopy operations. So, i can say that those 3 cases are the only relevant ones as the many other breaks result from the same origin. – Wör Du Schnaffzig Sep 25 '20 at 09:54
  • According to the docs (only found a German one unsuitable for pasting here), stopping on exceptions is one of the points of the VS Debugger. What *other* behaviour did you expect, and why? – MisterMiyagi Sep 25 '20 at 09:57
  • The point of the `AttributeError` in `__getattr__` is to tell the deepcopy about the existance of certain attributes not to raise an exception per se. This seems to be the very pythonic stdlib workaround for `hasattr(...)`. Normally no one would care about that exception, but in this case it makes the VS to unconvieniently break into the debugger. On one hand this is correct VS behaviour, on the other hand it interferes with the pythonic way of doing things. – Wör Du Schnaffzig Sep 25 '20 at 10:10

0 Answers0