From 01d17190627ea7b33d7a36cbaf22b7dd9799b72f Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Sat, 30 Jul 2016 14:06:15 +0300 Subject: [PATCH] Issue #27366: Tweak PEP 487 documentation * Added versionadded directives * Deleted duplicate sentence from __init_subclass__ docstring * Modernized tests --- Doc/reference/datamodel.rst | 5 ++++ Lib/test/test_subclassinit.py | 44 +++++++++++++++++------------------ Objects/typeobject.c | 7 +++--- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 2a857981232..075f0967e96 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1497,6 +1497,8 @@ class' :attr:`~object.__dict__`. Called at the time the owning class *owner* is created. The descriptor has been assigned to *name*. + .. versionadded:: 3.6 + The attribute :attr:`__objclass__` is interpreted by the :mod:`inspect` module 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. .. classmethod:: object.__init_subclass__(cls) + This method is called whenever the containing class is subclassed. *cls* is then the new subclass. If defined as a normal instance 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 nothing, but raises an error if it is called with any arguments. + .. versionadded:: 3.6 + .. _metaclasses: diff --git a/Lib/test/test_subclassinit.py b/Lib/test/test_subclassinit.py index eb5ed706ff7..ea6de757c61 100644 --- a/Lib/test/test_subclassinit.py +++ b/Lib/test/test_subclassinit.py @@ -1,11 +1,11 @@ -from unittest import TestCase, main import sys import types +import unittest -class Test(TestCase): +class Test(unittest.TestCase): def test_init_subclass(self): - class A(object): + class A: initialized = False def __init_subclass__(cls): @@ -19,7 +19,7 @@ class Test(TestCase): self.assertTrue(B.initialized) def test_init_subclass_dict(self): - class A(dict, object): + class A(dict): initialized = False def __init_subclass__(cls): @@ -33,7 +33,7 @@ class Test(TestCase): self.assertTrue(B.initialized) def test_init_subclass_kwargs(self): - class A(object): + class A: def __init_subclass__(cls, **kwargs): cls.kwargs = kwargs @@ -43,7 +43,7 @@ class Test(TestCase): self.assertEqual(B.kwargs, dict(x=3)) def test_init_subclass_error(self): - class A(object): + class A: def __init_subclass__(cls): raise RuntimeError @@ -52,7 +52,7 @@ class Test(TestCase): pass def test_init_subclass_wrong(self): - class A(object): + class A: def __init_subclass__(cls, whatever): pass @@ -61,7 +61,7 @@ class Test(TestCase): pass def test_init_subclass_skipped(self): - class BaseWithInit(object): + class BaseWithInit: def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) cls.initialized = cls @@ -76,7 +76,7 @@ class Test(TestCase): self.assertIs(BaseWithoutInit.initialized, BaseWithoutInit) def test_init_subclass_diamond(self): - class Base(object): + class Base: def __init_subclass__(cls, **kwargs): super().__init_subclass__(**kwargs) cls.calls = [] @@ -84,7 +84,7 @@ class Test(TestCase): class Left(Base): pass - class Middle(object): + class Middle: def __init_subclass__(cls, middle, **kwargs): super().__init_subclass__(**kwargs) cls.calls += [middle] @@ -107,7 +107,7 @@ class Test(TestCase): self.owner = owner self.name = name - class A(object): + class A: d = Descriptor() self.assertEqual(A.d.name, "d") @@ -121,12 +121,12 @@ class Test(TestCase): self.assertIs(ret.d.owner, ret) return 0 - class Descriptor(object): + class Descriptor: def __set_name__(self, owner, name): self.owner = owner self.name = name - class A(object, metaclass=Meta): + class A(metaclass=Meta): d = Descriptor() self.assertEqual(A, 0) @@ -136,7 +136,7 @@ class Test(TestCase): raise RuntimeError with self.assertRaises(RuntimeError): - class A(object): + class A: d = Descriptor() def test_set_name_wrong(self): @@ -145,7 +145,7 @@ class Test(TestCase): pass with self.assertRaises(TypeError): - class A(object): + class A: d = Descriptor() def test_set_name_init_subclass(self): @@ -161,7 +161,7 @@ class Test(TestCase): self.meta_name = self.name return self - class A(object): + class A: def __init_subclass__(cls): cls.owner = cls.d.owner cls.name = cls.d.name @@ -179,7 +179,7 @@ class Test(TestCase): pass with self.assertRaises(TypeError): - class MyClass(object, metaclass=MyMeta, otherarg=1): + class MyClass(metaclass=MyMeta, otherarg=1): pass with self.assertRaises(TypeError): @@ -193,7 +193,7 @@ class Test(TestCase): super().__init__(name, bases, namespace) with self.assertRaises(TypeError): - class MyClass(object, metaclass=MyMeta, otherarg=1): + class MyClass(metaclass=MyMeta, otherarg=1): pass class MyMeta(type): @@ -204,7 +204,7 @@ class Test(TestCase): super().__init__(name, bases, namespace) self.otherarg = otherarg - class MyClass(object, metaclass=MyMeta, otherarg=1): + class MyClass(metaclass=MyMeta, otherarg=1): pass self.assertEqual(MyClass.otherarg, 1) @@ -217,7 +217,7 @@ class Test(TestCase): dict=namespace) with self.assertRaises(TypeError): - class MyClass(object, metaclass=MyMeta): + class MyClass(metaclass=MyMeta): pass class MyMeta(type): @@ -226,7 +226,7 @@ class Test(TestCase): self.otherarg = otherarg return self - class MyClass(object, metaclass=MyMeta, otherarg=1): + class MyClass(metaclass=MyMeta, otherarg=1): pass self.assertEqual(MyClass.otherarg, 1) @@ -241,4 +241,4 @@ class Test(TestCase): if __name__ == "__main__": - main() + unittest.main() diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 2498b1f6fde..683484abb4e 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4341,11 +4341,10 @@ object_init_subclass(PyObject *cls, PyObject *arg) } 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" -"Whenever a class is subclassed, this method is called. The default\n" -"implementation does nothing. It may be overridden to extend\n" -"subclasses.\n"); +"The default implementation does nothing. It may be\n" +"overridden to extend subclasses.\n"); /* from PEP 3101, this code implements: