If I do something like this :
from mailbox import Mailbox
Mailbox.get = 'dummy'
There is no error, I just replaced the get
method.
But if I do a :
from datetime import datetime
datetime.now = 'dummy'
I get :
TypeError: can't set attributes of built-in/extension type 'datetime.datetime'
This is strange because the source code is readable at /usr/lib/python3.6/datetime.py
.
I guess this library has been compiled for performance reason, that is why it cannot be modified. But, then, the question is : how I can know a class is immutable because it is built-in or an extension (without just testing like I did) ? why can I patch Mailbox
class and not datetime
class ?
It won't tell you directly, but for your case, you can test the method you're trying to replace to see if it's an instance of types.BuiltinMethodType
:
>>> isinstance(Mailbox.get, types.BuiltinMethodType)
False
>>> isinstance(datetime.now, types.BuiltinMethodType)
True
inspect.isbuiltin
provides the same info:
>>> inspect.isbuiltin(Mailbox.get)
False
>>> inspect.isbuiltin(datetime.now)
True
To be clear, this is a limitation of the CPython reference interpreter; nothing requires attributes/methods of built-in types to be immutable, and in other interpreters (e.g. PyPy) they may be mutable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With