New submission from Wombatz:

This behavior occurs at least in python-3.6.0b3 and python-3.6.0b4.

Modifying the class __dict__ inside the __set_name__ method of a descriptor 
that is used inside that class can lead to a bug that possibly prevents other 
descriptors from being initialized (the call to their __set_name__ is 
prevented).

That happens because internally the cpython interpreter iterates the class 
__dict__ when calling all the __set_name__ methods. Changing the class __dict__ 
while iterating it leads to undefined behavior. This is the line in the source 
code https://github.com/python/cpython/blob/master/Objects/typeobject.c#L7010

See the attached file for an example where the bug can be observed. It defines 
a "desc" class that implements the __set_name__ method where it prints the name 
and modifies the class __dict__ of the containing class. Later a class is 
defined that has multiple instances of the "desc" class as class attributes. 
Depending on the number of attributes not all of them are initialized.

When you see the underlying C-Code the reason for this behavior is obvious but 
in python itself the problem might not be apparent.

To fix this bug the class __dict__ could be cashed and then the __set_name__ 
methods could be called while iterating over that copy.

----------
components: Interpreter Core
files: reproduce.py
messages: 281674
nosy: Wombatz
priority: normal
severity: normal
status: open
title: Modifying class __dict__ inside __set_name__
type: behavior
versions: Python 3.6
Added file: http://bugs.python.org/file45632/reproduce.py

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue28797>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to