Function overriding is a usual practice for python (at least for Django Rest Framework for example).
But! the main problem in your code is the scope. When you overriding module function, the new function will be used in all other parts of the code.
See this example:
import shutil
print('first try')
try:
print(shutil.copymode("a", "b"))
except Exception as e:
print(e)
shutil.copymode = lambda x,y: x + y
print('second try')
print(shutil.copymode("a", "b"))
import shutil
print('third try after re-import')
try:
print(shutil.copymode("a", "b"))
except Exception as e:
print(e)
first try
[Errno 2] No such file or directory: 'a'
second try
ab
third try after re-import
ab
shutil
already has modified copymode
function even if it is re-imported. And that may be super painful for someone who will try to use shutil
for this code in future.
So I recommend to import shutil
as separated copy object. So changes will be affected only for one current file (thanks to this article):
import importlib.util
import sys
SPEC_OS = importlib.util.find_spec('shutil')
custom_shutil = importlib.util.module_from_spec(SPEC_OS)
SPEC_OS.loader.exec_module(custom_shutil)
sys.modules['custom_shutil'] = custom_shutil
custom_shutil.copymode = lambda x, y: x + y
# or
# setattr(custom_shutil, 'copymode', lambda x, y: x + y)
print('first try')
print(custom_shutil.copymode("a", "b"))
import shutil
print('second try')
try:
print(shutil.copymode("a", "b"))
except Exception as e:
print(e)
first try
ab
second try
[Errno 2] No such file or directory: 'a'
However copymode
not just check for a copy mode but also check if file exists. Skipping of this checks may cause unexpected behaviour in future.