2

I found this issue in the thread: https://bugs.python.org/issue18195

>>> from copy import deepcopy
>>> import types
>>> origin_types = deepcopy(types)
Traceback (most recent call last):
...
AttributeError: 'NoneType' object has no attribute 'update'

If I really want to deepcopy a module, what to do?


[Updated] Why I want this?

import os
from copy import deepcopy
from importlib import reload

def disabled_func(f):
    def inner(*args, **kwargs):
        return f(*args, **kwargs)
    return inner

class OSModuleCustomizer(object):

    def disable_method(self, os_method):
        setattr(os, os_method, disabled_func)

    def save_customized_module(self):
        self.custom_module = deepcopy(os)

    def get_customized_module(self):
        return self.custom_module

#original function
os.system("ls") # works

#modifying module
omc = OSModuleCustomizer()
omc.disable_method("system")
os.system("ls") # empty

#saving customized module
omc.save_customized_module();

#reload
reload(__import__("os"))
os.system("ls") # works

#reload saved customized-module
os = omc.get_customized_module()
os.system("ls") # empty
3
  • 2
    This sounds like an XY problem. For what purpose do you want to copy a module? What is your end goal? Commented Oct 27, 2016 at 11:30
  • Why do you want to copy a module? Can you please explain the purpose of your problem, because I do not think that you are going in right direction. Commented Oct 27, 2016 at 11:51
  • Just updating question with my purpose. Commented Oct 27, 2016 at 12:14

1 Answer 1

0

This answer shows how to clone a module.

Below is my solution with hacking sys.modules.

import importlib
import os
import sys
from importlib import reload

class ModuleCustomizer:
    def __init__(self, fullname):
        self.custom_module = sys.modules[fullname]

    def disable_method(self, method):
        setattr(
            self.custom_module,
            method, 
            lambda *args, **kwargs: print(
                f'{self.custom_module.__name__}: {method} is disabled.')
        )

    def save_customized_module(self):
        fullname = self.custom_module.__name__
        spec = importlib.util.find_spec(fullname)
        clone = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(clone)
        sys.modules[fullname] = clone


    def get_customized_module(self):
        return self.custom_module

#original function
os.system('ls') # works

#modifying module
omc = ModuleCustomizer('os')
omc.disable_method('system')
os.system('ls') # disabled

#saving customized module
omc.save_customized_module()

#reload
os = reload(__import__('os'))
# In this case, below line works too.
# os = reload(sys.modules['os'])

os.system("ls") # works
omc.get_customized_module().system('ls') # disabled

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.