Issue2551
Created on 2017-02-08.16:08:40 by stefan.richthofer, last changed 2017-02-27.04:48:45 by zyasoft.
msg11085 (view) |
Author: Stefan Richthofer (stefan.richthofer) |
Date: 2017-02-08.16:08:39 |
|
#2475 and #1777 both suffer the issue that Jython emits
TypeError: Error when calling the metaclass bases
multiple bases have instance lay-out conflict
under certain __slot__ usage. While in #1777 it was suggested to simply avoid using __slots__ in Jython, which is actually a suitable workaround as proposed in https://github.com/sympy/sympy/pull/12120, that hint stems from a time when Jython had no __slots__ support at all.
Given that this issue also occurs elsewhere and nowadays __slots__ is actually supported in Jython we might better get this fixed. In case this issue turns out to be fixable with some reasonable effort I would withdraw https://github.com/sympy/sympy/pull/12120 in favor of a Jython-side solution.
I undertook the effort to boil it down to following diamond-style configuration:
class test1(object):
__slots__ = ('a',)
class test2_1(test1):
__slots__ = ()
class test2_2(test1):
__slots__ = ()
class test3(test2_1, test2_2):
pass
which fails in Jython, but passes in CPython.
Same behavior if either test2_1 or test2_2 have some value in __slots__, e.g. ('b') or also ('a') (name seems not to matter).
On the other hand if test2_1 and test2_2 both have some value in __slots__, e.g. ('b'), ('c') (but same with ('a'), ('a') or so, name doesn't matter here either) this fails in CPython too with the same error.
This issue might or might not be related to #2101 / #1996, cannot tell yet.
|
msg11086 (view) |
Author: Stefan Richthofer (stefan.richthofer) |
Date: 2017-02-08.16:20:05 |
|
This issue looks like a variant of what is tested in
test_class_jy / test_slotted_diamond_problem_bug
So a similar but not totally equal issue was already discovered an fixed once upon a time.
|
msg11089 (view) |
Author: Aaron Meurer (asmeurer) |
Date: 2017-02-08.17:22:20 |
|
From what I can tell based on the documentation, this should work https://docs.python.org/3.6/reference/datamodel.html#slots.
|
msg11090 (view) |
Author: Stefan Richthofer (stefan.richthofer) |
Date: 2017-02-08.21:46:02 |
|
After some digging I'm convinced the problem lies in PyType and is about detection of what is called a solid base. I.e. a class defining __slots__ = () shall actually not be considered a solid base, but currently is. A proper solid base would have to actually add a slot, not set slots to an empty sequence. Solid bases are detected based on numSlots, which would normally be 0 if slots is an empty sequence. However in the example numSlots would be 1 because of the parent class.
I would modify
private static boolean isSolidBase(PyType type) {
return type.underlying_class != null || (type.numSlots != 0 && !type.needs_userdict);
}
such that it doesn't rely on absolute numSlots value but on the difference to base's numSlots. So to be a solid base it must actually *introduce* a slot, not just *have* a slot from base or so.
Proposed change:
private static boolean isSolidBase(PyType type) {
return type.underlying_class != null || (type.numSlots - (type.base != null ? type.base.numSlots : 0) != 0 && !type.needs_userdict);
}
|
msg11091 (view) |
Author: Stefan Richthofer (stefan.richthofer) |
Date: 2017-02-08.22:25:48 |
|
Fixed as of https://github.com/jythontools/jython/commit/d9908177c85218f26bcdad1f698127a7d5bfb3d9
|
|
Date |
User |
Action |
Args |
2017-02-27 04:48:45 | zyasoft | set | status: pending -> closed |
2017-02-08 22:25:48 | stefan.richthofer | set | status: open -> pending assignee: stefan.richthofer resolution: fixed messages:
+ msg11091 milestone: Jython 2.7.1 |
2017-02-08 21:46:02 | stefan.richthofer | set | messages:
+ msg11090 title: __slots__ in Diamond-style causes lay-out conflict (breaks pathlib and sympy) -> __slots__ in diamond-style causes lay-out conflict (breaks pathlib and sympy) |
2017-02-08 17:22:20 | asmeurer | set | messages:
+ msg11089 |
2017-02-08 16:20:05 | stefan.richthofer | set | messages:
+ msg11086 |
2017-02-08 16:08:40 | stefan.richthofer | create | |
|