Keyword arguments in python class inheritance - python

Hello I am recently looking about the metaclass in Python.
I learned about we can attach a metaclass to a class in this way:
class Metaclass(type):
...
class MyClass(metaclass=Metaclass):
...
The first question
I wonder what's the principle of the keyword argument (metaclass=...) in the above example. There seems no description for that in the doc
I know that there is keyword argument for a function, but I've never seen the form occurred in class inheritance.
The second question
We know that we can create a class using type() function in this way
cls = type(class_name, (base_class,), {func_name: func_ref})
Considering the metaclass=... form, how can I pass metaclass when creating class using type() instead of class keyword?
Thanks stackoverflowers!

In general, the keyword arguments used with a class statement are passed to __init_subclass__, to be used however that function sees fit. metaclass, however, is used by the code generator itself to determine what gets called in order to define the class.
The metaclass is not an argument to be passed to a call to type; it is the callable that gets called instead of type. Very roughly speaking,
class MyClass(metaclass=Metaclass):
...
is turned into
MyClass = Metaclass('MyClass', (), ...)
type is simply the default metaclass.
(The gory details of how a class statement is executed can be found in Section 3.3.3 of the language documentation.)
Note that a metaclass does not have to be a subclass of type. You can do truly horrific things with metaclasses, like
>>> class A(metaclass=lambda x, y, z: 3): pass
...
>>> type(A)
<class 'int'>
>>> A
3
It doesn't really matter what the metaclass returns, as long as it accepts 3 arguments.
Please don't write actual code like this, though. A class statement should produce something that at least resembles a type.
In some sense, class statements are less magical than other statements. def statements, for example, can't be customized to produce something other than instances of function, and it's far harder to create a function object by calling types.FunctionType explicitly.

Yes I've looked this, but it doesn't provide something about principle of keyword argument in class inheritance, I am still confused
metaclass=... is not about inheritance.
Everything in Python is an object. So when you define a class MyClass, not only is MyClass() an object but the class MyClass itself is an object.
MyClass() is an instance of MyClass, simple enough.
But if MyClass is also an object, what class is it an instance of?
If you do nothing, the object (!) MyClass is an instance of the class type.
If you do class MyClass(metaclass=Metaclass) then MyClass is an instance of Metaclass.
Consider
class Metaclass(type):
pass
class MyClass1:
pass
class MyClass2(metaclass=Metaclass):
pass
Both MyClass1 and MyClass2 inherit from object and only object.
>>> MyClass1.__mro__
(<class '__main__.MyClass1'>, <class 'object'>)
>>> MyClass2.__mro__
(<class '__main__.MyClass2'>, <class 'object'>)
But their types differ:
>>> type(MyClass1)
<class 'type'>
>>> type(MyClass2)
<class '__main__.Metaclass'>
When would you need this? Usually, you don't. And when you do, you do the kind of metaprogramming where you already know the why and how.

Related

Is int() a standalone function or it is actually an _init_ constructor method of the int class under covers?

(a) I am trying to figure out whether int(), float(), tuple() and similar functions are standalone functons or they work like constructors for user classes (i.e. invoking class __init__() method under covers.)
(b) I wanted to find available signatures of these methods, like int(str), int(str, base).
(c) I tried peeking into the source code on github, but it seems to be implemented on the c-layer, not on Python-layer. There is even no header-like stub Python code for this.
If you use help(int) you'll see that it's the name of a class:
Help on class int in module builtins:
class int(object)
| int(x=0) -> integer
| int(x, base=10) -> integer
However, if you scan further down, you won't see an __init__ method. Instances are initialized by internal C code in the __new__ method of the class.
Yes, all of those are classes, they are class objects. Their type is type (which itself, is a class, a metaclass):
>>> type(int)
<class 'type'>
Same as a custom class:
>>> class Foo: pass
...
>>> type(Foo)
<class 'type'>
And seemingly paradoxically:
>>> type(type)
<class 'type'>
NOTE: None of these objects are the __init__. That is a special method that gets called by the constructor to run custom initialization. IOW:
>>> Foo.__init__ is Foo
False

type(MyClass.myclassmethod) returns "method", not "classmethod"

I just stumbled over this strange behavior when the type of a method changes during subclassing:
class A:
def f(self, x):
return x**2
class B(A):
#classmethod
def f(cls, x):
return x**2
If I now ask for the type of B.f, I'll get the (supposedly) wrong answer:
In [37]: type(B.f)
Out[37]: method
Whereas this works as expected:
In [39]: type(B.__dict__["f"])
Out[39]: classmethod
(Seen in Python 3.4 and 3.6.)
Is this just a bug or is there a specific reason for this?
What's the difference between the attribute f and the .__dict__["f"] item? I thought they were the same.
In a testing suite, I was trying to support both types of methods inside a class to be tested. To be able to do that, I need to know the type in order to pass the correct number of arguments. If it's a normal method (i.e. self is the first argument), I'd just pass None explicitly, which by design shouldn't be used inside the method anyway, since it's not instance-dependent.
Maybe there's a better way to do this, like duck typing the call to the method. But there might be cases where this is not so easy to do, like if the method had *args and **kwargs... Therefore I went with the explicit type check, but got stuck at this point.
No, this is not a bug, this is normal behaviour. A classmethod produces a bound method when accessed on a class. That's exactly the point of a classmethod, to bind a function to the class you access it on or the class of an instance you access it on.
Like function and property objects, classmethod is a descriptor object, it implements a __get__ method. Accessing attributes on an instance or a class is delegated to the __getattribute__ method, and the default implementation of that hook will not just return what it found in object.__dict__[attributename]; it will also bind descriptors, by calling the descriptor.__get__() method. This is a hugely important aspect of Python, it is this mechanism that makes methods and attributes and loads of other things work.
classmethod objects, when bound by the descriptor protocol, return a method object. Method objects are wrappers that record the object bound to, and the function to call when they are called; calling a method really calls the underlying method with the bound object as first argument:
>>> class Foo:
... pass
...
>>> def bar(*args): print(args)
...
>>> classmethod(bar).__get__(None, Foo) # decorate with classmethod and bind
<bound method bar of <class '__main__.Foo'>>
>>> method = classmethod(bar).__get__(None, Foo)
>>> method.__self__
<class '__main__.Foo'>
>>> method.__func__
<function bar at 0x1056f0e18>
>>> method()
(<class '__main__.Foo'>,)
>>> method('additional arguments')
(<class '__main__.Foo'>, 'additional arguments')
So the method object returned for a classmethod object references the class (the second argument to __get__, the owner), and the original function. If you use a class method on an instance, the first argument is still ignored:
>>> classmethod(bar).__get__(Foo(), Foo).__self__ # called on an instance
<class '__main__.Foo'>
Functions, on the other hand, want to bind only to instances; so if the first argument to __get__ is set to None, they simply return self:
>>> bar.__get__(None, Foo) # access on a class
<function bar at 0x1056f0e18>
>>> bar.__get__(Foo(), Foo) # access on an instance
<bound method bar of <__main__.Foo object at 0x105833a90>>
>>> bar.__get__(Foo(), Foo).__self__
<__main__.Foo object at 0x105833160>
If accessing ClassObject.classmethod_object would return the classmethod object itself, like a function object would, then you could never actually use the class method on a class. That'd be rather pointless.
So no, object.attribute is not always the same thing as object.__dict__['attribute']. If object.__dict__['attribute'] supports the descriptor protocol, it'll be invoked.

Explicitly inheriting from 'type' to implement metaclass in python3.x

I was trying to get some intuition about metaclass in Python. I have tried on both Python2.7 and and Python3.5. In Python3.5 I found every class we define is of type <class 'type'> whether we explicitly inherit or not. But if not inherited from type we can't use that class as a metaclass for another class.
>>> class foo:
pass
>>> class Metafoo(type):
pass
>>> foo
<class '__main__.foo'>
>>> Metafoo
<class '__main__.Metafoo'>
>>> type(foo)
<class 'type'>
>>> type(Metafoo)
<class 'type'>
>>>
>>> class foocls1(metaclass=foo):
pass
doing the above I get the following error:
Traceback (most recent call last):
File "<pyshell#52>", line 1, in <module>
class foocls1(metaclass=foo):
TypeError: object() takes no parameters
But that is not in the case while using Metafoo as metaclass for the new class
>>> class foocls3(metaclass=Metafoo):
pass
>>> foocls3
<class '__main__.foocls3'>
>>> type(foocls3)
<class '__main__.Metafoo'>
Can anyone explain why this is the case that we need to explicitly inherit if we want to use a class as metaclass in other class.
"type" is the base class for all class objects in Python 3, and in Python 2 post version 2.2. (It is just that on Python 2, you are supposed to inherit from object. Classes that do not explicitly inherit from "object" in Python 2 were called "old style classes", and kept for backward compatibility purposes, but were of little use.)
So, what happens is that inheritance: what are the superclasses of a class, and "metaclass" that is "since in Python a class is an object itself, what is the class of that object" are two different things. The classes you inherit from define the order of attribute (and method) lookup on the instances of your class, and therefore you have a common behavior.
The metaclass is rather "the class your class is built with", and although it can serve other purposes, is most used to modify the construction step of your classes itself. Search around and you will see metaclasses mostly implementing the __new__ and __init__ methods. (Although it is ok to have other methods there, but yu have to know what you are doing)
It happens that to build a class some actions are needed that are not required to build normal objects. These actions are performed on the native-code layer (C in CPython) and are not even reproducible in pure Python code, like populating the class's special method slots- the pointers to the functions that implement the __add__, __eq__ and such methods. The only class that does that in CPython is "type". So any code you want to use to build a class, i.e. as a metaclass, will have to at some point call type.__new__ method. (Just as any thing you want to create a new object in Python will at some point call the code in object.__new__.).
Your error happened not because Python goes checking whether you made a direct or indirect call to type.__new__ ahead of time. The error: "TypeError: object() takes no parameters" is simply due to the fact that __new__ method of the metaclass is passed 3 parameters (name, bases, namespace), while the same method in object is passed no parameters. (Both get te extra "cls", equivalent to self as well, but this is not counted).
You can use any callable as the metaclass, even an ordinary function. It is just that it will have to take the 3 explicit parameters. Whatever this callable returns is used as the class from that point on, but if at some point you don't call type.__new__ (even indirectly), you don't have a valid class to return.
For example, one could create a simple method just in order to be able to use class bodies as dictionary declarations:
def dictclass(name, bases, namespace):
return namespace
class mydict(metaclass=dictclass):
a = 1
b = 2
c = 3
mydict["a"]
So, one interesting fact with all that is that type is its own metaclass. (that is hardcoded in the Python implementation). But type itself also inherits from object:
In [21]: type.__class__
Out[21]: type
In [22]: type.__mro__
Out[22]: (type, object)
And just to end this: it is possible to create classes without calling type.__new__ and objects without calling object.__new__, but not ordinarily from pure Python code, as data structures at the C-API level have to be filled for both actions. One could either do a native-code implementation of functions to do it, or hack it with ctypes.

Are there more than three types of methods in Python?

I understand there are at least 3 kinds of methods in Python having different first arguments:
instance method - instance, i.e. self
class method - class, i.e. cls
static method - nothing
These classic methods are implemented in the Test class below including an usual method:
class Test():
def __init__(self):
pass
def instance_mthd(self):
print("Instance method.")
#classmethod
def class_mthd(cls):
print("Class method.")
#staticmethod
def static_mthd():
print("Static method.")
def unknown_mthd():
# No decoration --> instance method, but
# No self (or cls) --> static method, so ... (?)
print("Unknown method.")
In Python 3, the unknown_mthd can be called safely, yet it raises an error in Python 2:
>>> t = Test()
>>> # Python 3
>>> t.instance_mthd()
>>> Test.class_mthd()
>>> t.static_mthd()
>>> Test.unknown_mthd()
Instance method.
Class method.
Static method.
Unknown method.
>>> # Python 2
>>> Test.unknown_mthd()
TypeError: unbound method unknown_mthd() must be called with Test instance as first argument (got nothing instead)
This error suggests such a method was not intended in Python 2. Perhaps its allowance now is due to the elimination of unbound methods in Python 3 (REF 001). Moreover, unknown_mthd does not accept args, and it can be bound to called by a class like a staticmethod, Test.unknown_mthd(). However, it is not an explicit staticmethod (no decorator).
Questions
Was making a method this way (without args while not explicitly decorated as staticmethods) intentional in Python 3's design? UPDATED
Among the classic method types, what type of method is unknown_mthd?
Why can unknown_mthd be called by the class without passing an argument?
Some preliminary inspection yields inconclusive results:
>>> # Types
>>> print("i", type(t.instance_mthd))
>>> print("c", type(Test.class_mthd))
>>> print("s", type(t.static_mthd))
>>> print("u", type(Test.unknown_mthd))
>>> print()
>>> # __dict__ Types, REF 002
>>> print("i", type(t.__class__.__dict__["instance_mthd"]))
>>> print("c", type(t.__class__.__dict__["class_mthd"]))
>>> print("s", type(t.__class__.__dict__["static_mthd"]))
>>> print("u", type(t.__class__.__dict__["unknown_mthd"]))
>>> print()
i <class 'method'>
c <class 'method'>
s <class 'function'>
u <class 'function'>
i <class 'function'>
c <class 'classmethod'>
s <class 'staticmethod'>
u <class 'function'>
The first set of type inspections suggests unknown_mthd is something similar to a staticmethod. The second suggests it resembles an instance method. I'm not sure what this method is or why it should be used over the classic ones. I would appreciate some advice on how to inspect and understand it better. Thanks.
REF 001: What's New in Python 3: “unbound methods” has been removed
REF 002: How to distinguish an instance method, a class method, a static method or a function in Python 3?
REF 003: What's the point of #staticmethod in Python?
Some background: In Python 2, "regular" instance methods could give rise to two kinds of method objects, depending on whether you accessed them via an instance or the class. If you did inst.meth (where inst is an instance of the class), you got a bound method object, which keeps track of which instance it is attached to, and passes it as self. If you did Class.meth (where Class is the class), you got an unbound method object, which had no fixed value of self, but still did a check to make sure a self of the appropriate class was passed when you called it.
In Python 3, unbound methods were removed. Doing Class.meth now just gives you the "plain" function object, with no argument checking at all.
Was making a method this way intentional in Python 3's design?
If you mean, was removal of unbound methods intentional, the answer is yes. You can see discussion from Guido on the mailing list. Basically it was decided that unbound methods add complexity for little gain.
Among the classic method types, what type of method is unknown_mthd?
It is an instance method, but a broken one. When you access it, a bound method object is created, but since it accepts no arguments, it's unable to accept the self argument and can't be successfully called.
Why can unknown_mthd be called by the class without passing an argument?
In Python 3, unbound methods were removed, so Test.unkown_mthd is just a plain function. No wrapping takes place to handle the self argument, so you can call it as a plain function that accepts no arguments. In Python 2, Test.unknown_mthd is an unbound method object, which has a check that enforces passing a self argument of the appropriate class; since, again, the method accepts no arguments, this check fails.
#BrenBarn did a great job answering your question. This answer however, adds a plethora of details:
First of all, this change in bound and unbound method is version-specific, and it doesn't relate to new-style or classic classes:
2.X classic classes by default
>>> class A:
... def meth(self): pass
...
>>> A.meth
<unbound method A.meth>
>>> class A(object):
... def meth(self): pass
...
>>> A.meth
<unbound method A.meth>
3.X new-style classes by default
>>> class A:
... def meth(self): pass
...
>>> A.meth
<function A.meth at 0x7efd07ea0a60>
You've already mentioned this in your question, it doesn't hurt to mention it twice as a reminder.
>>> # Python 2
>>> Test.unknown_mthd()
TypeError: unbound method unknown_mthd() must be called with Test instance as first argument (got nothing instead)
Moreover, unknown_mthd does not accept args, and it can be bound to a class like a staticmethod, Test.unknown_mthd(). However, it is not an explicit staticmethod (no decorator)
unknown_meth doesn't accept args, normally because you've defined the function without so that it does not take any parameter. Be careful and cautious, static methods as well as your coded unknown_meth method will not be magically bound to a class when you reference them through the class name (e.g, Test.unknown_meth). Under Python 3.X Test.unknow_meth returns a simple function object in 3.X, not a method bound to a class.
1 - Was making a method this way (without args while not explicitly decorated as staticmethods) intentional in Python 3's design? UPDATED
I cannot speak for CPython developers nor do I claim to be their representative, but from my experience as a Python programmer, it seems like they wanted to get rid of a bad restriction, especially given the fact that Python is extremely dynamic, not a language of restrictions; why would you test the type of objects passed to class methods and hence restrict the method to specific instances of classes? Type testing eliminates polymorphism. It would be decent if you just return a simple function when a method is fetched through the class which functionally behaves like a static method, you can think of unknown_meth to be static method under 3.X so long as you're careful not to fetch it through an instance of Test you're good to go.
2- Among the classic method types, what type of method is unknown_mthd?
Under 3.X:
>>> from types import *
>>> class Test:
... def unknown_mthd(): pass
...
>>> type(Test.unknown_mthd) is FunctionType
True
It's simply a function in 3.X as you could see. Continuing the previous session under 2.X:
>>> type(Test.__dict__['unknown_mthd']) is FunctionType
True
>>> type(Test.unknown_mthd) is MethodType
True
unknown_mthd is a simple function that lives inside Test__dict__, really just a simple function which lives inside the namespace dictionary of Test. Then, when does it become an instance of MethodType? Well, it becomes an instance of MethodType when you fetch the method attribute either from the class itself which returns an unbound method or its instances which returns a bound method. In 3.X, Test.unknown_mthd is a simple function--instance of FunctionType, and Test().unknown_mthd is an instance of MethodType that retains the original instance of class Test and adds it as the first argument implicitly on function calls.
3- Why can unknown_mthd be called by the class without passing an argument?
Again, because Test.unknown_mthd is just a simple function under 3.X. Whereas in 2.X, unknown_mthd not a simple function and must be called be passed an instance of Test when called.
Are there more than three types of methods in Python?
Yes. There are the three built-in kinds that you mention (instance method, class method, static method), four if you count #property, and anyone can define new method types.
Once you understand the mechanism for doing this, it's easy to explain why unknown_mthd is callable from the class in Python 3.
A new kind of method
Suppose we wanted to create a new type of method, call it optionalselfmethod so that we could do something like this:
class Test(object):
#optionalselfmethod
def optionalself_mthd(self, *args):
print('Optional-Self Method:', self, *args)
The usage is like this:
In [3]: Test.optionalself_mthd(1, 2)
Optional-Self Method: None 1 2
In [4]: x = Test()
In [5]: x.optionalself_mthd(1, 2)
Optional-Self Method: <test.Test object at 0x7fe80049d748> 1 2
In [6]: Test.instance_mthd(1, 2)
Instance method: 1 2
optionalselfmethod works like a normal instance method when called on an instance, but when called on the class, it always receives None for the first parameter. If it were a normal instance method, you would always have to pass an explicit value for the self parameter in order for it to work.
So how does this work? How you can you create a new method type like this?
The Descriptor Protocol
When Python looks up a field of an instance, i.e. when you do x.whatever, it check in several places. It checks the instance's __dict__ of course, but it also checks the __dict__ of the object's class, and base classes thereof. In the instance dict, Python is just looking for the value, so if x.__dict__['whatever'] exists, that's the value. However, in the class dict, Python is looking for an object which implements the Descriptor Protocol.
The Descriptor Protocol is how all three built-in kinds of methods work, it's how #property works, and it's how our special optionalselfmethod will work.
Basically, if the class dict has a value with the correct name1, Python checks if it has an __get__ method, and calls it like type(x).whatever.__get__(x, type(x)) Then, the value returned from __get__ is used as the field value.
So for example, a trivial descriptor which always returns 3:
class GetExample:
def __get__(self, instance, cls):
print("__get__", instance, cls)
return 3
class Test:
get_test = GetExample()
Usage is like this:
In[22]: x = Test()
In[23]: x.get_test
__get__ <__main__.Test object at 0x7fe8003fc470> <class '__main__.Test'>
Out[23]: 3
Notice that the descriptor is called with both the instance and the class type. It can also be used on the class:
In [29]: Test.get_test
__get__ None <class '__main__.Test'>
Out[29]: 3
When a descriptor is used on a class rather than an instance, the __get__ method gets None for self, but still gets the class argument.
This allows a simple implementation of methods: functions simply implement the descriptor protocol. When you call __get__ on a function, it returns a bound method of instance. If the instance is None, it returns the original function. You can actually call __get__ yourself to see this:
In [30]: x = object()
In [31]: def test(self, *args):
...: print(f'Not really a method: self<{self}>, args: {args}')
...:
In [32]: test
Out[32]: <function __main__.test>
In [33]: test.__get__(None, object)
Out[33]: <function __main__.test>
In [34]: test.__get__(x, object)
Out[34]: <bound method test of <object object at 0x7fe7ff92d890>>
#classmethod and #staticmethod are similar. These decorators create proxy objects with __get__ methods which provide different binding. Class method's __get__ binds the method to the instance, and static method's __get__ doesn't bind to anything, even when called on an instance.
The Optional-Self Method Implementation
We can do something similar to create a new method which optionally binds to an instance.
import functools
class optionalselfmethod:
def __init__(self, function):
self.function = function
functools.update_wrapper(self, function)
def __get__(self, instance, cls):
return boundoptionalselfmethod(self.function, instance)
class boundoptionalselfmethod:
def __init__(self, function, instance):
self.function = function
self.instance = instance
functools.update_wrapper(self, function)
def __call__(self, *args, **kwargs):
return self.function(self.instance, *args, **kwargs)
def __repr__(self):
return f'<bound optionalselfmethod {self.__name__} of {self.instance}>'
When you decorate a function with optionalselfmethod, the function is replaced with our proxy. This proxy saves the original method and supplies a __get__ method which returns a boudnoptionalselfmethod. When we create a boundoptionalselfmethod, we tell it both the function to call and the value to pass as self. Finally, calling the boundoptionalselfmethod calls the original function, but with the instance or None inserted into the first parameter.
Specific Questions
Was making a method this way (without args while not explicitly
decorated as staticmethods) intentional in Python 3's design? UPDATED
I believe this was intentional; however the intent would have been to eliminate unbound methods. In both Python 2 and Python 3, def always creates a function (you can see this by checking a type's __dict__: even though Test.instance_mthd comes back as <unbound method Test.instance_mthd>, Test.__dict__['instance_mthd'] is still <function instance_mthd at 0x...>).
In Python 2, function's __get__ method always returns a instancemethod, even when accessed through the class. When accessed through an instance, the method is bound to that instance. When accessed through the class, the method is unbound, and includes a mechanism which checks that the first argument is an instance of the correct class.
In Python 3, function's __get__ method will return the original function unchanged when accessed through the class, and a method when accessed through the instance.
I don't know the exact rationale but I would guess that type-checking of the first argument to a class-level function was deemed unnecessary, maybe even harmful; Python allows duck-typing after all.
Among the classic method types, what type of method is unknown_mthd?
unknown_mthd is a plain function, just like any normal instance method. It only fails when called through the instance because when method.__call__ attempts to call the function unknown_mthd with the bound instance, it doesn't accept enough parameters to receive the instance argument.
Why can unknown_mthd be called by the class without passing an
argument?
Because it's just a plain function, same as any other function. I just doesn't take enough arguments to work correctly when used as an instance method.
You may note that both classmethod and staticmethod work the same whether they're called through an instance or a class, whereas unknown_mthd will only work correctly when when called through the class and fail when called through an instance.
1. If a particular name has both a value in the instance dict and a descriptor in the class dict, which one is used depends on what kind of descriptor it is. If the descriptor only defines __get__, the value in the instance dict is used. If the descriptor also defines __set__, then it's a data-descriptor and the descriptor always wins. This is why you can assign over top of a method but not a #property; method only define __get__, so you can put things in the same-named slot in the instance dict, while #properties define __set__, so even if they're read-only, you'll never get a value from the instance __dict__ even if you've previously bypassed property lookup and stuck a value in the dict with e.g. x.__dict__['whatever'] = 3.

Python Data Model : confused again with classmethod

It's said that :
When it would yield a class method object, it is transformed into a
bound user-defined method object whose im_class and im_self attributes
are both C.
in the Reference
And I did an EX.
>>> class C(object) :
... #classmethod
... def cm(cls) : print cls
...
>>> C.cm
<bound method type.cm of <class '__main__.C'>>
>>> C.cm.im_self
<class '__main__.C'>
>>> C.cm.im_class
<type 'type'>
It's not hard for me to understand the phenomenon. But unfortunately, in the reference, it's told that im_self should be the same as im_class. How to explain the inconsistency?
I read that the same way you do. It appears that what Python is actually doing is not exactly what the documentation says.
It sets im_self to the class, and im_class to the class's type, i.e., its metaclass. The default metaclass for classes in Python is type. This is analogous to what happens with methods that are bound to instances: im_self is the instance and im_class is the type of the instance. In the case of #classmethod, in other words, the class is treated as the instance (which it is; it's an instance of type).
Possibly the behavior was changed without the documentation being updated, or the documentation was just wrong to begin with. I write documentation for a living and I can confirm that it is almost impossible to keep it 100% correct for something the size of Python -- especially for obscure details like this one.
The Python developers have a procedure for reporting bugs in the documentation. Give it a try!

Categories