BitFieldFlags: raise AttributeError if no '_flags'
BitFieldFlags: raise AttributeError if no '_flags'

From [3. Data model — Python 3.8.2 documentation](https://docs.python.org/3.8/reference/datamodel.html#object.__getattr__):

    .. method:: object.__getattr__(self, name)

       Called when the default attribute access fails with an :exc:`AttributeError`
       (either :meth:`__getattribute__` raises an :exc:`AttributeError` because
       *name* is not an instance attribute or an attribute in the class tree
       for ``self``; or :meth:`__get__` of a *name* property raises
       :exc:`AttributeError`).  This method should either return the (computed)
       attribute value or raise an :exc:`AttributeError` exception.

       Note that if the attribute is found through the normal mechanism,
       :meth:`__getattr__` is not called.  (This is an intentional asymmetry between
       :meth:`__getattr__` and :meth:`__setattr__`.) This is done both for efficiency
       reasons and because otherwise :meth:`__getattr__` would have no way to access
       other attributes of the instance.  Note that at least for instance variables,
       you can fake total control by not inserting any values in the instance attribute
       dictionary (but instead inserting them in another object).  See the
       :meth:`__getattribute__` method below for a way to actually get total control
       over attribute access.

As stated in the above comment, `__getattr__` is used by the interpreter
if and only if `__getattribute__` (which is tried first by the interpreter)
has already raised `AttributeError`.  If `__getattr__` also did not exist,
Python would pass through the exception as-is, but in this case we would
like to override it in which case it simply clears it.  We therefore
reconstruct the `AttributeError` exception so tests like `hasattr` will
correctly return `False`, etc.

For CPython 3, the function responsible is ([`slot_tp_getattr_hook`](https://github.com/python/cpython/blob/05e4a296ecc127641160a04f39cc02c0f66a8c27/Objects/typeobject.c#L6617)), and the clearing line is ([here](https://github.com/python/cpython/blob/05e4a296ecc127641160a04f39cc02c0f66a8c27/Objects/typeobject.c#L6652)).

This behavior is also on par with the code below which does
`raise AttributeError("flag {} is not registered".format(key))`
if the `key` is not found in `self._flags`.

We may as well have called `__getattribute__` directly, but using the
intrinsic construct (which calls the `__getattribute__` slot anyway) is
faster, and the case in which `_flags` is absent is unlikely except in
special circumstances like #80.  The CPython `copy` module tests for
existence of `__setstate__`, which triggered the exception when creating
a new object (BitFieldFlags without its `__init__` called) to clone into.

Fixes #80

    def _reconstruct(x, memo, func, args,
                     state=None, listiter=None, dictiter=None,
                     deepcopy=deepcopy):
    ...
    y = func(*args)
    ...
            if hasattr(y, '__setstate__'):
                y.__setstate__(state)

disqus/django-bitfield