Issue #13575: there is only one class type.
This commit is contained in:
parent
9d57481f04
commit
aa6c1d240f
|
@ -36,9 +36,7 @@ continuing through the base classes of ``type(a)`` excluding metaclasses. If the
|
|||
looked-up value is an object defining one of the descriptor methods, then Python
|
||||
may override the default behavior and invoke the descriptor method instead.
|
||||
Where this occurs in the precedence chain depends on which descriptor methods
|
||||
were defined. Note that descriptors are only invoked for new style objects or
|
||||
classes (a class is new style if it inherits from :class:`object` or
|
||||
:class:`type`).
|
||||
were defined.
|
||||
|
||||
Descriptors are a powerful, general purpose protocol. They are the mechanism
|
||||
behind properties, methods, static methods, class methods, and :func:`super()`.
|
||||
|
@ -89,8 +87,6 @@ of ``obj``. If ``d`` defines the method :meth:`__get__`, then ``d.__get__(obj)`
|
|||
is invoked according to the precedence rules listed below.
|
||||
|
||||
The details of invocation depend on whether ``obj`` is an object or a class.
|
||||
Either way, descriptors only work for new style objects and classes. A class is
|
||||
new style if it is a subclass of :class:`object`.
|
||||
|
||||
For objects, the machinery is in :meth:`object.__getattribute__` which
|
||||
transforms ``b.x`` into ``type(b).__dict__['x'].__get__(b, type(b))``. The
|
||||
|
@ -115,7 +111,6 @@ The important points to remember are:
|
|||
|
||||
* descriptors are invoked by the :meth:`__getattribute__` method
|
||||
* overriding :meth:`__getattribute__` prevents automatic descriptor calls
|
||||
* :meth:`__getattribute__` is only available with new style classes and objects
|
||||
* :meth:`object.__getattribute__` and :meth:`type.__getattribute__` make
|
||||
different calls to :meth:`__get__`.
|
||||
* data descriptors always override instance dictionaries.
|
||||
|
@ -128,10 +123,7 @@ and then returns ``A.__dict__['m'].__get__(obj, A)``. If not a descriptor,
|
|||
``m`` is returned unchanged. If not in the dictionary, ``m`` reverts to a
|
||||
search using :meth:`object.__getattribute__`.
|
||||
|
||||
Note, in Python 2.2, ``super(B, obj).m()`` would only invoke :meth:`__get__` if
|
||||
``m`` was a data descriptor. In Python 2.3, non-data descriptors also get
|
||||
invoked unless an old-style class is involved. The implementation details are
|
||||
in :c:func:`super_getattro()` in
|
||||
The implementation details are in :c:func:`super_getattro()` in
|
||||
`Objects/typeobject.c <http://svn.python.org/view/python/trunk/Objects/typeobject.c?view=markup>`_
|
||||
and a pure Python equivalent can be found in `Guido's Tutorial`_.
|
||||
|
||||
|
|
|
@ -375,7 +375,7 @@ class _Pickler:
|
|||
# allowing protocol 0 and 1 to work normally. For this to
|
||||
# work, the function returned by __reduce__ should be
|
||||
# called __newobj__, and its first argument should be a
|
||||
# new-style class. The implementation for __newobj__
|
||||
# class. The implementation for __newobj__
|
||||
# should be as follows, although pickle has no way to
|
||||
# verify this:
|
||||
#
|
||||
|
|
|
@ -1639,6 +1639,8 @@ opcodes = [
|
|||
is pushed on the stack.
|
||||
|
||||
NOTE: checks for __safe_for_unpickling__ went away in Python 2.3.
|
||||
NOTE: the distinction between old-style and new-style classes does
|
||||
not make sense in Python 3.
|
||||
"""),
|
||||
|
||||
I(name='OBJ',
|
||||
|
|
|
@ -15,8 +15,8 @@ have been called before resurrection). At best (and this has been an
|
|||
historically common bug), tp_clear empties an instance's __dict__, and
|
||||
"impossible" AttributeErrors result. At worst, tp_clear leaves behind an
|
||||
insane object at the C level, and segfaults result (historically, most
|
||||
often by setting a new-style class's mro pointer to NULL, after which
|
||||
attribute lookups performed by the class can segfault).
|
||||
often by setting a class's mro pointer to NULL, after which attribute
|
||||
lookups performed by the class can segfault).
|
||||
|
||||
OTOH, it's OK to run Python-level code that can't access unreachable
|
||||
objects, and sometimes that's necessary. The chief example is the callback
|
||||
|
@ -119,7 +119,7 @@ isn't easy to stumble into by accident while Python is running, and, indeed,
|
|||
it took quite a while to dream up failing test cases. Zope3 saw segfaults
|
||||
during shutdown, during the second call of gc in Py_Finalize, after most
|
||||
modules had been torn down. That creates many trash cycles (esp. those
|
||||
involving new-style classes), making the problem much more likely. Once you
|
||||
involving classes), making the problem much more likely. Once you
|
||||
know what's required to provoke the problem, though, it's easy to create
|
||||
tests that segfault before shutdown.
|
||||
|
||||
|
|
|
@ -100,15 +100,13 @@ PyType_Modified(PyTypeObject *type)
|
|||
static void
|
||||
type_mro_modified(PyTypeObject *type, PyObject *bases) {
|
||||
/*
|
||||
Check that all base classes or elements of the mro of type are
|
||||
Check that all base classes or elements of the MRO of type are
|
||||
able to be cached. This function is called after the base
|
||||
classes or mro of the type are altered.
|
||||
|
||||
Unset HAVE_VERSION_TAG and VALID_VERSION_TAG if the type
|
||||
inherits from an old-style class, either directly or if it
|
||||
appears in the MRO of a new-style class. No support either for
|
||||
custom MROs that include types that are not officially super
|
||||
types.
|
||||
has a custom MRO that includes a type which is not officially
|
||||
super type.
|
||||
|
||||
Called from mro_internal, which will subsequently be called on
|
||||
each subclass when their mro is recursively updated.
|
||||
|
@ -124,11 +122,7 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {
|
|||
PyObject *b = PyTuple_GET_ITEM(bases, i);
|
||||
PyTypeObject *cls;
|
||||
|
||||
if (!PyType_Check(b) ) {
|
||||
clear = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(PyType_Check(b));
|
||||
cls = (PyTypeObject *)b;
|
||||
|
||||
if (!PyType_HasFeature(cls, Py_TPFLAGS_HAVE_VERSION_TAG) ||
|
||||
|
@ -488,7 +482,7 @@ type_set_bases(PyTypeObject *type, PyObject *value, void *context)
|
|||
if (!PyType_Check(ob)) {
|
||||
PyErr_Format(
|
||||
PyExc_TypeError,
|
||||
"%s.__bases__ must be tuple of old- or new-style classes, not '%s'",
|
||||
"%s.__bases__ must be tuple of classes, not '%s'",
|
||||
type->tp_name, Py_TYPE(ob)->tp_name);
|
||||
return -1;
|
||||
}
|
||||
|
@ -1619,7 +1613,7 @@ mro_internal(PyTypeObject *type)
|
|||
type->tp_mro = tuple;
|
||||
|
||||
type_mro_modified(type, type->tp_mro);
|
||||
/* corner case: the old-style super class might have been hidden
|
||||
/* corner case: the super class might have been hidden
|
||||
from the custom MRO */
|
||||
type_mro_modified(type, type->tp_bases);
|
||||
|
||||
|
@ -1676,9 +1670,8 @@ best_base(PyObject *bases)
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
if (base == NULL)
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"a new-style class can't have only classic bases");
|
||||
assert (base != NULL);
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
|
@ -3196,7 +3189,7 @@ object_set_class(PyObject *self, PyObject *value, void *closure)
|
|||
}
|
||||
if (!PyType_Check(value)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"__class__ must be set to new-style class, not '%s' object",
|
||||
"__class__ must be set to a class, not '%s' object",
|
||||
Py_TYPE(value)->tp_name);
|
||||
return -1;
|
||||
}
|
||||
|
@ -3811,8 +3804,8 @@ inherit_special(PyTypeObject *type, PyTypeObject *base)
|
|||
that the extension type's own factory function ensures).
|
||||
Heap types, of course, are under our control, so they do
|
||||
inherit tp_new; static extension types that specify some
|
||||
other built-in type as the default are considered
|
||||
new-style-aware so they also inherit object.__new__. */
|
||||
other built-in type as the default also
|
||||
inherit object.__new__. */
|
||||
if (base != &PyBaseObject_Type ||
|
||||
(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
|
||||
if (type->tp_new == NULL)
|
||||
|
@ -6352,7 +6345,7 @@ supercheck(PyTypeObject *type, PyObject *obj)
|
|||
{
|
||||
/* Check that a super() call makes sense. Return a type object.
|
||||
|
||||
obj can be a new-style class, or an instance of one:
|
||||
obj can be a class, or an instance of one:
|
||||
|
||||
- If it is a class, it must be a subclass of 'type'. This case is
|
||||
used for class methods; the return value is obj.
|
||||
|
|
|
@ -665,7 +665,7 @@ PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
|
|||
if (bases == NULL)
|
||||
goto failure;
|
||||
}
|
||||
/* Create a real new-style class. */
|
||||
/* Create a real class. */
|
||||
result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",
|
||||
dot+1, bases, dict);
|
||||
failure:
|
||||
|
|
|
@ -474,7 +474,7 @@ Py_Finalize(void)
|
|||
flush_std_files();
|
||||
|
||||
/* Collect final garbage. This disposes of cycles created by
|
||||
* new-style class definitions, for example.
|
||||
* class definitions, for example.
|
||||
* XXX This is disabled because it caused too many problems. If
|
||||
* XXX a __del__ or weakref callback triggers here, Python code has
|
||||
* XXX a hard time running, because even the sys module has been
|
||||
|
@ -1348,11 +1348,6 @@ parse_syntax_error(PyObject *err, PyObject **message, const char **filename,
|
|||
_Py_IDENTIFIER(offset);
|
||||
_Py_IDENTIFIER(text);
|
||||
|
||||
/* old style errors */
|
||||
if (PyTuple_Check(err))
|
||||
return PyArg_ParseTuple(err, "O(ziiz)", message, filename,
|
||||
lineno, offset, text);
|
||||
|
||||
/* new style errors. `err' is an instance */
|
||||
|
||||
if (! (v = _PyObject_GetAttrId(err, &PyId_msg)))
|
||||
|
|
|
@ -402,7 +402,7 @@ class ProxyAlreadyVisited(object):
|
|||
|
||||
|
||||
def _write_instance_repr(out, visited, name, pyop_attrdict, address):
|
||||
'''Shared code for use by old-style and new-style classes:
|
||||
'''Shared code for use by all classes:
|
||||
write a representation to file-like object "out"'''
|
||||
out.write('<')
|
||||
out.write(name)
|
||||
|
@ -481,7 +481,7 @@ class HeapTypeObjectPtr(PyObjectPtr):
|
|||
|
||||
def proxyval(self, visited):
|
||||
'''
|
||||
Support for new-style classes.
|
||||
Support for classes.
|
||||
|
||||
Currently we just locate the dictionary using a transliteration to
|
||||
python of _PyObject_GetDictPtr, ignoring descriptors
|
||||
|
@ -498,7 +498,7 @@ class HeapTypeObjectPtr(PyObjectPtr):
|
|||
attr_dict = {}
|
||||
tp_name = self.safe_tp_name()
|
||||
|
||||
# New-style class:
|
||||
# Class:
|
||||
return InstanceProxy(tp_name, attr_dict, long(self._gdbval))
|
||||
|
||||
def write_repr(self, out, visited):
|
||||
|
@ -670,44 +670,6 @@ class PyDictObjectPtr(PyObjectPtr):
|
|||
pyop_value.write_repr(out, visited)
|
||||
out.write('}')
|
||||
|
||||
class PyInstanceObjectPtr(PyObjectPtr):
|
||||
_typename = 'PyInstanceObject'
|
||||
|
||||
def proxyval(self, visited):
|
||||
# Guard against infinite loops:
|
||||
if self.as_address() in visited:
|
||||
return ProxyAlreadyVisited('<...>')
|
||||
visited.add(self.as_address())
|
||||
|
||||
# Get name of class:
|
||||
in_class = self.pyop_field('in_class')
|
||||
cl_name = in_class.pyop_field('cl_name').proxyval(visited)
|
||||
|
||||
# Get dictionary of instance attributes:
|
||||
in_dict = self.pyop_field('in_dict').proxyval(visited)
|
||||
|
||||
# Old-style class:
|
||||
return InstanceProxy(cl_name, in_dict, long(self._gdbval))
|
||||
|
||||
def write_repr(self, out, visited):
|
||||
# Guard against infinite loops:
|
||||
if self.as_address() in visited:
|
||||
out.write('<...>')
|
||||
return
|
||||
visited.add(self.as_address())
|
||||
|
||||
# Old-style class:
|
||||
|
||||
# Get name of class:
|
||||
in_class = self.pyop_field('in_class')
|
||||
cl_name = in_class.pyop_field('cl_name').proxyval(visited)
|
||||
|
||||
# Get dictionary of instance attributes:
|
||||
pyop_in_dict = self.pyop_field('in_dict')
|
||||
|
||||
_write_instance_repr(out, visited,
|
||||
cl_name, pyop_in_dict, self.as_address())
|
||||
|
||||
class PyListObjectPtr(PyObjectPtr):
|
||||
_typename = 'PyListObject'
|
||||
|
||||
|
|
Loading…
Reference in New Issue