[issue43639] Do not raise AttributeError on instance attribute update/deletion if data descriptor with missing __set__/__delete__ method found on its type

2021-12-29 Thread Raymond Hettinger


Change by Raymond Hettinger :


--
assignee:  -> rhettinger

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue43639] Do not raise AttributeError on instance attribute update/deletion if data descriptor with missing __set__/__delete__ method found on its type

2021-12-29 Thread Raymond Hettinger


Raymond Hettinger  added the comment:

I'm going to decline this one.  

* It is arguable whether or not this behavior should have been designed in 
originally.  However, changing it now is risky (as noted by Brett and Ethan).

* Personally, I disagree with the notion of allowing a partial pass through.  
That seems hazardous and error-prone to me.  It is easier to reason about data 
descriptors being all or nothing.  I like that AttributeError is raised while 
still allowing me to add the missing methods if I want to explicitly define 
some other behavior. 

* This has been open for 9 months and no one else stepped forward to champion 
it.

* For two decades, no one has complained that the current behavior got in the 
way of what they were trying to do.  That provides some evidence that there 
isn't a real world problem to be solved.

--
resolution:  -> rejected
stage: patch review -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue43639] Do not raise AttributeError on instance attribute update/deletion if data descriptor with missing __set__/__delete__ method found on its type

2021-03-27 Thread Raymond Hettinger


Change by Raymond Hettinger :


--
nosy: +rhettinger
versions:  -Python 3.6, Python 3.7, Python 3.8, Python 3.9

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue43639] Do not raise AttributeError on instance attribute update/deletion if data descriptor with missing __set__/__delete__ method found on its type

2021-03-27 Thread Géry

Change by Géry :


--
keywords: +patch
pull_requests: +23781
stage:  -> patch review
pull_request: https://github.com/python/cpython/pull/25033

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue43639] Do not raise AttributeError on instance attribute update/deletion if data descriptor with missing __set__/__delete__ method found on its type

2021-03-27 Thread Géry

New submission from Géry :

Currently, the `object.__setattr__` and `type.__setattr__` methods raise an 
`AttributeError` during attribute *update* on an instance if its type has an 
attribute which is a *data* descriptor without a `__set__` method. Likewise, 
the `object.__delattr__` and `type.__delattr__` methods raise an 
`AttributeError` during attribute *deletion* on an instance if its type has an 
attribute which is a *data* descriptor without a `__delete__` method.

This should not be the case. When update/deletion is impossible through a data 
descriptor found on the type, update/deletion should carry its process on the 
instance, like when there is no data descriptor found on the type. And this is 
what the `object.__getattribute__` and `type.__getattribute__` methods already 
do: they do *not* raise an `AttributeError` during attribute *lookup* on an 
instance if its type has an attribute which is a *data* descriptor without a 
`__get__` method. See [the discussion on Python 
Discuss](https://discuss.python.org/t/why-do-setattr-and-delattr-raise-an-attributeerror-in-this-case/7836?u=maggyero).

Here is a simple program illustrating the differences between attribute lookup 
by `object.__getattribute__` on the one hand (`AttributeError` is not raised), 
and attribute update by `object.__setattr__` and attribute deletion by 
`object.__delattr__` on the other hand (`AttributeError` is raised):

```python
class DataDescriptor1:  # missing __get__
def __set__(self, instance, value): pass
def __delete__(self, instance): pass

class DataDescriptor2:  # missing __set__
def __get__(self, instance, owner=None): pass
def __delete__(self, instance): pass

class DataDescriptor3:  # missing __delete__
def __get__(self, instance, owner=None): pass
def __set__(self, instance, value): pass

class A:
x = DataDescriptor1()
y = DataDescriptor2()
z = DataDescriptor3()

a = A()
vars(a).update({'x': 'foo', 'y': 'bar', 'z': 'baz'})

a.x
# actual: returns 'foo'
# expected: returns 'foo'

a.y = 'qux'
# actual: raises AttributeError: __set__
# expected: vars(a)['y'] == 'qux'

del a.z
# actual: raises AttributeError: __delete__
# expected: 'z' not in vars(a)
```

Here is another simple program illustrating the differences between attribute 
lookup by `type.__getattribute__` on the one hand (`AttributeError` is not 
raised), and attribute update by `type.__setattr__` and attribute deletion by 
`type.__delattr__` on the other hand (`AttributeError` is raised):

```python
class DataDescriptor1:  # missing __get__
def __set__(self, instance, value): pass
def __delete__(self, instance): pass

class DataDescriptor2:  # missing __set__
def __get__(self, instance, owner=None): pass
def __delete__(self, instance): pass

class DataDescriptor3:  # missing __delete__
def __get__(self, instance, owner=None): pass
def __set__(self, instance, value): pass

class M(type):
x = DataDescriptor1()
y = DataDescriptor2()
z = DataDescriptor3()

class A(metaclass=M):
x = 'foo'
y = 'bar'
z = 'baz'

A.x
# actual: returns 'foo'
# expected: returns 'foo'

A.y = 'qux'
# actual: raises AttributeError: __set__
# expected: vars(A)['y'] == 'qux'

del A.z
# actual: raises AttributeError: __delete__
# expected: 'z' not in vars(A)
```

--
components: Interpreter Core
messages: 389598
nosy: maggyero
priority: normal
severity: normal
status: open
title: Do not raise AttributeError on instance attribute update/deletion if 
data descriptor with missing __set__/__delete__ method found on its type
type: behavior
versions: Python 3.10, Python 3.6, Python 3.7, Python 3.8, Python 3.9

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com