mirror of https://github.com/python/cpython
Issue #27366: Tweak PEP 487 documentation
* Added versionadded directives * Deleted duplicate sentence from __init_subclass__ docstring * Modernized tests
This commit is contained in:
parent
6074f217db
commit
01d1719062
|
@ -1497,6 +1497,8 @@ class' :attr:`~object.__dict__`.
|
||||||
Called at the time the owning class *owner* is created. The
|
Called at the time the owning class *owner* is created. The
|
||||||
descriptor has been assigned to *name*.
|
descriptor has been assigned to *name*.
|
||||||
|
|
||||||
|
.. versionadded:: 3.6
|
||||||
|
|
||||||
|
|
||||||
The attribute :attr:`__objclass__` is interpreted by the :mod:`inspect` module
|
The attribute :attr:`__objclass__` is interpreted by the :mod:`inspect` module
|
||||||
as specifying the class where this object was defined (setting this
|
as specifying the class where this object was defined (setting this
|
||||||
|
@ -1648,6 +1650,7 @@ applied to, ``__init_subclass__`` solely applies to future subclasses of the
|
||||||
class defining the method.
|
class defining the method.
|
||||||
|
|
||||||
.. classmethod:: object.__init_subclass__(cls)
|
.. classmethod:: object.__init_subclass__(cls)
|
||||||
|
|
||||||
This method is called whenever the containing class is subclassed.
|
This method is called whenever the containing class is subclassed.
|
||||||
*cls* is then the new subclass. If defined as a normal instance method,
|
*cls* is then the new subclass. If defined as a normal instance method,
|
||||||
this method is implicitly converted to a class method.
|
this method is implicitly converted to a class method.
|
||||||
|
@ -1669,6 +1672,8 @@ class defining the method.
|
||||||
The default implementation ``object.__init_subclass__`` does
|
The default implementation ``object.__init_subclass__`` does
|
||||||
nothing, but raises an error if it is called with any arguments.
|
nothing, but raises an error if it is called with any arguments.
|
||||||
|
|
||||||
|
.. versionadded:: 3.6
|
||||||
|
|
||||||
|
|
||||||
.. _metaclasses:
|
.. _metaclasses:
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
from unittest import TestCase, main
|
|
||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
class Test(TestCase):
|
class Test(unittest.TestCase):
|
||||||
def test_init_subclass(self):
|
def test_init_subclass(self):
|
||||||
class A(object):
|
class A:
|
||||||
initialized = False
|
initialized = False
|
||||||
|
|
||||||
def __init_subclass__(cls):
|
def __init_subclass__(cls):
|
||||||
|
@ -19,7 +19,7 @@ class Test(TestCase):
|
||||||
self.assertTrue(B.initialized)
|
self.assertTrue(B.initialized)
|
||||||
|
|
||||||
def test_init_subclass_dict(self):
|
def test_init_subclass_dict(self):
|
||||||
class A(dict, object):
|
class A(dict):
|
||||||
initialized = False
|
initialized = False
|
||||||
|
|
||||||
def __init_subclass__(cls):
|
def __init_subclass__(cls):
|
||||||
|
@ -33,7 +33,7 @@ class Test(TestCase):
|
||||||
self.assertTrue(B.initialized)
|
self.assertTrue(B.initialized)
|
||||||
|
|
||||||
def test_init_subclass_kwargs(self):
|
def test_init_subclass_kwargs(self):
|
||||||
class A(object):
|
class A:
|
||||||
def __init_subclass__(cls, **kwargs):
|
def __init_subclass__(cls, **kwargs):
|
||||||
cls.kwargs = kwargs
|
cls.kwargs = kwargs
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ class Test(TestCase):
|
||||||
self.assertEqual(B.kwargs, dict(x=3))
|
self.assertEqual(B.kwargs, dict(x=3))
|
||||||
|
|
||||||
def test_init_subclass_error(self):
|
def test_init_subclass_error(self):
|
||||||
class A(object):
|
class A:
|
||||||
def __init_subclass__(cls):
|
def __init_subclass__(cls):
|
||||||
raise RuntimeError
|
raise RuntimeError
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ class Test(TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_init_subclass_wrong(self):
|
def test_init_subclass_wrong(self):
|
||||||
class A(object):
|
class A:
|
||||||
def __init_subclass__(cls, whatever):
|
def __init_subclass__(cls, whatever):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ class Test(TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_init_subclass_skipped(self):
|
def test_init_subclass_skipped(self):
|
||||||
class BaseWithInit(object):
|
class BaseWithInit:
|
||||||
def __init_subclass__(cls, **kwargs):
|
def __init_subclass__(cls, **kwargs):
|
||||||
super().__init_subclass__(**kwargs)
|
super().__init_subclass__(**kwargs)
|
||||||
cls.initialized = cls
|
cls.initialized = cls
|
||||||
|
@ -76,7 +76,7 @@ class Test(TestCase):
|
||||||
self.assertIs(BaseWithoutInit.initialized, BaseWithoutInit)
|
self.assertIs(BaseWithoutInit.initialized, BaseWithoutInit)
|
||||||
|
|
||||||
def test_init_subclass_diamond(self):
|
def test_init_subclass_diamond(self):
|
||||||
class Base(object):
|
class Base:
|
||||||
def __init_subclass__(cls, **kwargs):
|
def __init_subclass__(cls, **kwargs):
|
||||||
super().__init_subclass__(**kwargs)
|
super().__init_subclass__(**kwargs)
|
||||||
cls.calls = []
|
cls.calls = []
|
||||||
|
@ -84,7 +84,7 @@ class Test(TestCase):
|
||||||
class Left(Base):
|
class Left(Base):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Middle(object):
|
class Middle:
|
||||||
def __init_subclass__(cls, middle, **kwargs):
|
def __init_subclass__(cls, middle, **kwargs):
|
||||||
super().__init_subclass__(**kwargs)
|
super().__init_subclass__(**kwargs)
|
||||||
cls.calls += [middle]
|
cls.calls += [middle]
|
||||||
|
@ -107,7 +107,7 @@ class Test(TestCase):
|
||||||
self.owner = owner
|
self.owner = owner
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
class A(object):
|
class A:
|
||||||
d = Descriptor()
|
d = Descriptor()
|
||||||
|
|
||||||
self.assertEqual(A.d.name, "d")
|
self.assertEqual(A.d.name, "d")
|
||||||
|
@ -121,12 +121,12 @@ class Test(TestCase):
|
||||||
self.assertIs(ret.d.owner, ret)
|
self.assertIs(ret.d.owner, ret)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
class Descriptor(object):
|
class Descriptor:
|
||||||
def __set_name__(self, owner, name):
|
def __set_name__(self, owner, name):
|
||||||
self.owner = owner
|
self.owner = owner
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
class A(object, metaclass=Meta):
|
class A(metaclass=Meta):
|
||||||
d = Descriptor()
|
d = Descriptor()
|
||||||
self.assertEqual(A, 0)
|
self.assertEqual(A, 0)
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ class Test(TestCase):
|
||||||
raise RuntimeError
|
raise RuntimeError
|
||||||
|
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(RuntimeError):
|
||||||
class A(object):
|
class A:
|
||||||
d = Descriptor()
|
d = Descriptor()
|
||||||
|
|
||||||
def test_set_name_wrong(self):
|
def test_set_name_wrong(self):
|
||||||
|
@ -145,7 +145,7 @@ class Test(TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
class A(object):
|
class A:
|
||||||
d = Descriptor()
|
d = Descriptor()
|
||||||
|
|
||||||
def test_set_name_init_subclass(self):
|
def test_set_name_init_subclass(self):
|
||||||
|
@ -161,7 +161,7 @@ class Test(TestCase):
|
||||||
self.meta_name = self.name
|
self.meta_name = self.name
|
||||||
return self
|
return self
|
||||||
|
|
||||||
class A(object):
|
class A:
|
||||||
def __init_subclass__(cls):
|
def __init_subclass__(cls):
|
||||||
cls.owner = cls.d.owner
|
cls.owner = cls.d.owner
|
||||||
cls.name = cls.d.name
|
cls.name = cls.d.name
|
||||||
|
@ -179,7 +179,7 @@ class Test(TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
class MyClass(object, metaclass=MyMeta, otherarg=1):
|
class MyClass(metaclass=MyMeta, otherarg=1):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
|
@ -193,7 +193,7 @@ class Test(TestCase):
|
||||||
super().__init__(name, bases, namespace)
|
super().__init__(name, bases, namespace)
|
||||||
|
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
class MyClass(object, metaclass=MyMeta, otherarg=1):
|
class MyClass(metaclass=MyMeta, otherarg=1):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class MyMeta(type):
|
class MyMeta(type):
|
||||||
|
@ -204,7 +204,7 @@ class Test(TestCase):
|
||||||
super().__init__(name, bases, namespace)
|
super().__init__(name, bases, namespace)
|
||||||
self.otherarg = otherarg
|
self.otherarg = otherarg
|
||||||
|
|
||||||
class MyClass(object, metaclass=MyMeta, otherarg=1):
|
class MyClass(metaclass=MyMeta, otherarg=1):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.assertEqual(MyClass.otherarg, 1)
|
self.assertEqual(MyClass.otherarg, 1)
|
||||||
|
@ -217,7 +217,7 @@ class Test(TestCase):
|
||||||
dict=namespace)
|
dict=namespace)
|
||||||
|
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
class MyClass(object, metaclass=MyMeta):
|
class MyClass(metaclass=MyMeta):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class MyMeta(type):
|
class MyMeta(type):
|
||||||
|
@ -226,7 +226,7 @@ class Test(TestCase):
|
||||||
self.otherarg = otherarg
|
self.otherarg = otherarg
|
||||||
return self
|
return self
|
||||||
|
|
||||||
class MyClass(object, metaclass=MyMeta, otherarg=1):
|
class MyClass(metaclass=MyMeta, otherarg=1):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.assertEqual(MyClass.otherarg, 1)
|
self.assertEqual(MyClass.otherarg, 1)
|
||||||
|
@ -241,4 +241,4 @@ class Test(TestCase):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
unittest.main()
|
||||||
|
|
|
@ -4341,11 +4341,10 @@ object_init_subclass(PyObject *cls, PyObject *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(object_init_subclass_doc,
|
PyDoc_STRVAR(object_init_subclass_doc,
|
||||||
"This method is called when a class is subclassed\n"
|
"This method is called when a class is subclassed.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Whenever a class is subclassed, this method is called. The default\n"
|
"The default implementation does nothing. It may be\n"
|
||||||
"implementation does nothing. It may be overridden to extend\n"
|
"overridden to extend subclasses.\n");
|
||||||
"subclasses.\n");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
from PEP 3101, this code implements:
|
from PEP 3101, this code implements:
|
||||||
|
|
Loading…
Reference in New Issue