Question: Class attributes apparently do not access the descriptors' __set__ method. Is this expected or is there some issue?
Below code demonstrates the problem. The code is pulled straight from the Python documentation.
class RevealAccess:
    """A data descriptor that sets and returns values
       normally and prints a message logging their access.
    """
    def __init__(self, initval=None, name='var'):
        self.val = initval
        self.name = name
    def __get__(self, obj, objtype):
        print('Retrieving', self.name)
        print(f'obj = {obj}')
        print(f'objtype = {objtype}')
        return self.val
    def __set__(self, obj, val):
        print('Updating', self.name)
        self.val = val
class MyReveal:
    x = RevealAccess(10, 'var "x"')
Creating an instance behaves as expected:
>>> mr = MyReveal()
>>> mr.x
Retrieving var "x"
obj = <__main__.MyReveal object at 0x139246eb8>
objtype = <class '__main__.MyReveal'>
>>> mr.x = 'set mr.x'
Updating var "x"
Retrieving var "x"
obj = <__main__.MyReveal object at 0x139246eb8>
objtype = <class '__main__.MyReveal'>
When using directly on the class attribute, the __get__ behaves as expected:
>>> MyReveal.x
Retrieving var "x"
obj = None
objtype = <class '__main__.MyReveal'>
MyReveal.x=set mr.x
However, when trying to set, the __set__ seems to be ignored and the attribute is just written over, losing the descriptor:
>>> MyReveal.x = 'set MyReveal.x'
<no output>
>>> MyReveal.x
'set MyReveal.x'
>>> mr.x
'set MyReveal.x'
As seen, the diagnostics from the descriptor are gone, leaving the value of the x attribute just the bare str.
Is this expected behavior? Or, more likely, what am I doing wrong? Or, a bug?