[issue21919] Changing cls.__bases__ must ensure proper metaclass inheritance

2018-09-28 Thread Guido van Rossum


Guido van Rossum  added the comment:

As long as you can't crash CPython with this, this is the responsibility of the 
code that assigns to __bases__. If they don't take care, the program's behavior 
is undefined.

--

___
Python tracker 

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



[issue21919] Changing cls.__bases__ must ensure proper metaclass inheritance

2018-09-28 Thread Raymond Hettinger


Raymond Hettinger  added the comment:

>  I am adding Raymond as part of triaging who might have a better explanation 
> about this. 

Guido, is this something we care about?  There is value in checking for 
metaclass conflicts when a class is created (to catch plausible mistakes and to 
assure that the right __new__() and __init__() methods run).  But 
post-creation, it's unclear whether there is value in rerunning checks and 
whether its even possible to know how other base classes might have affected 
the class creation.

Do this go in the "consenting adults" category (in the same way that we allow 
the __class__ attribute to be changed on instances without trying to verify 
whether it makes sense)?

--
assignee:  -> gvanrossum
nosy: +gvanrossum
versions: +Python 3.8 -Python 2.7, Python 3.4, Python 3.5

___
Python tracker 

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



[issue21919] Changing cls.__bases__ must ensure proper metaclass inheritance

2018-09-27 Thread Karthikeyan Singaravelan


Karthikeyan Singaravelan  added the comment:

Thanks for the report and patience. This behavior is still reproducible on 
master as of f55c64c632 . I am adding Raymond as part of triaging who might 
have a better explanation about this. Raymond, feel free to remove yourself if 
this is not relevant.

A slightly cleaned up version of the program with repl statements removed for 
reference : 

class O(object):
 pass

class M(type):
 pass

class N(type):
 pass

class A(O, metaclass=M):
 pass

class B(O, metaclass=N):
 pass

print(B.__bases__)
print(B.__mro__)

print(type(B))
print(type(A))
print(issubclass(type(B), type(A)))

class C(A, metaclass=N):
 pass

class D(B, A):
 pass

class E(B, metaclass=N):
 pass

--
nosy: +rhettinger

___
Python tracker 

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



[issue21919] Changing cls.__bases__ must ensure proper metaclass inheritance

2018-09-23 Thread Mark Lawrence


Change by Mark Lawrence :


--
nosy:  -BreamoreBoy

___
Python tracker 

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



[issue21919] Changing cls.__bases__ must ensure proper metaclass inheritance

2018-09-23 Thread Karthikeyan Singaravelan


Change by Karthikeyan Singaravelan :


--
nosy: +xtreak

___
Python tracker 

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



[issue21919] Changing cls.__bases__ must ensure proper metaclass inheritance

2015-03-02 Thread Eldar Abusalimov

Eldar Abusalimov added the comment:

@Mark, that OK, for the issue without a patch. :)

I could make a patch, but I'm not sure whether the proposed behavior is right. 
It could be considered arguable, I guess...

--

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



[issue21919] Changing cls.__bases__ must ensure proper metaclass inheritance

2015-02-27 Thread Mark Lawrence

Mark Lawrence added the comment:

@Eldar sorry that this issue slipped our net.

--
nosy: +BreamoreBoy
versions: +Python 3.5 -Python 3.2

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



[issue21919] Changing cls.__bases__ must ensure proper metaclass inheritance

2014-07-04 Thread Eldar Abusalimov

New submission from Eldar Abusalimov:

When a new class is constructed Python checks for possible metaclass conflicts 
within bases and an explicitly specified one, if any, choosing the best 
available (the most specialized) one. That is the following implication is 
expected:

issubclass(B, A) = issubclass(type(B), type(A))

However, changing __bases__ attribute can break this invariant silently without 
an error.

 class O(object):
... pass
... 
 class M(type):
... pass
... 
 class N(type):
... pass
... 
 class A(O, metaclass=M):
... pass
... 
 class B(O, metaclass=N):
... pass
... 
 B.__bases__ = (A,)
 B.__mro__
(class '__main__.B', class '__main__.A', class '__main__.O', class 
'object')
 type(B)
class '__main__.N'
 type(A)
class '__main__.M'
 issubclass(B, A)
True
 issubclass(type(B), type(A))
False

Trying to derive from B now makes things look pretty weird:

 class C(A, metaclass=N):
... pass
... 
Traceback (most recent call last):
  File stdin, line 1, in module
TypeError: metaclass conflict: the metaclass of a derived class must be a 
(non-strict) subclass of the metaclasses of all its bases
 class D(B, A): pass
... 
Traceback (most recent call last):
  File stdin, line 1, in module
TypeError: metaclass conflict: the metaclass of a derived class must be a 
(non-strict) subclass of the metaclasses of all its bases
 class E(B, metaclass=N):
... pass
... 
 type(E)
class '__main__.N'

That is one can extend a class but not its base (and not a class along its 
base). This effectively allows to bypass metaclass checks (by introducing a 
dummy class with the default metaclass, deriving it from a desired class with 
an inappropriate metaclass by changing __bases__ and using it instead of the 
desired class).

This behavior is observed in 2.7, 3.2 and 3.4.


I would expect the same check for metaclass conflicts when changing __bases__ 
as upon creating a new class:

 # EXPECTED:
... 
 B.__bases__ = (A,)
Traceback (most recent call last):
  File stdin, line 1, in module
TypeError: metaclass conflict: the metaclass of a derived class must be a 
(non-strict) subclass of the metaclasses of all its bases

--
components: Interpreter Core
messages: 222312
nosy: Eldar.Abusalimov
priority: normal
severity: normal
status: open
title: Changing cls.__bases__ must ensure proper metaclass inheritance
type: behavior
versions: Python 2.7, Python 3.2, Python 3.4

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