Search code examples
pythonpython-3.xillegalargumentexception

Python - 2 arguments instead of one?


Python Code:

class Importer:
    from importlib import __import__, reload
    from sys import modules

    libname = ""
    import_count = 0
    module = None

    def __init__(self, name):
        self.libname = name
        self.import_count = 0

    def importm(self):
        if self.libname not in self.modules:
            self.module = __import__(self.libname)
        else:
            print("must reload")
            self.module = self.reload(self.module)
        self.import_count += 1

# test out Importer

importer = Importer("module")

importer.importm() # prints Hello
importer.importm() # prints Hello
importer.importm() # prints Hello (again)
print(importer.import_count)

The above Python (3.8.1) code is at OnlineGDB, which if you run, will give an error:

TypeError: reload() takes 1 positional argument but 2 were given

When I open up the importlib library in Python, I see this:


# ... (previous code; unnecessary)

_RELOADING = {}


def reload(module): ## this is where reload is defined (one argument)
    """Reload the module and return it.

    The module must have been successfully imported before.

    """
    if not module or not isinstance(module, types.ModuleType): ## check for type of module
        raise TypeError("reload() argument must be a module")
    try:
        name = module.__spec__.name
    except AttributeError:
        name = module.__name__

    if sys.modules.get(name) is not module: ## other code you (probably) don't have to care about
        msg = "module {} not in sys.modules"
        raise ImportError(msg.format(name), name=name)
    if name in _RELOADING:
        return _RELOADING[name]
    _RELOADING[name] = module
    try:
        parent_name = name.rpartition('.')[0]
        if parent_name:
            try:
                parent = sys.modules[parent_name]
            except KeyError:
                msg = "parent {!r} not in sys.modules"
                raise ImportError(msg.format(parent_name),
                                  name=parent_name) from None
            else:
                pkgpath = parent.__path__
        else:
            pkgpath = None
        target = module
        spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target)
        if spec is None:
            raise ModuleNotFoundError(f"spec not found for the module {name!r}", name=name)
        _bootstrap._exec(spec, module)
        # The module may have replaced itself in sys.modules!
        return sys.modules[name]
    finally:
        try:
            del _RELOADING[name]
        except KeyError:
            pass

# ... (After code; unnecessary)

All double hashtag (##) comments are mine

It is clearly visible that reload DOES have 1 argument, and it checks if that argument is a module. In the OGDB (OnineGDB) code, I am only passing one argument (pretty sure) and it is of type module (most likely). If I remove that argument (you can edit the OGDB), it gives:

TypeError: reload() argument must be module

So for some reason, Python keeps thinking I have one more argument than I do actually have. The only way I made it work was editing the importlib file to have reload have two arguments (not a good idea).

I tried running PDB, not helpful.

Can anyone spot anything obviously wrong, like actually having two arguments?


Solution

  • What I needed to do is put the imports outside the class for it to work. Here is the new OGDB. Credits to @L3viathan. Code below:

    from importlib import __import__, reload
    from sys import modules
    
    class Importer:
        libname = ""
        import_count = 0
        module = None
    
        def __init__(self, name):
            self.libname = name
            self.import_count = 0
    
        def importm(self):
            if self.libname not in modules:
                self.module = __import__(self.libname)
            else:
                print("must reload")
                self.module = reload(self.module)
            self.import_count += 1
    
    # test out Importer
    
    importer = Importer("module")
    
    importer.importm() # prints Hello
    importer.importm() # prints Hello
    importer.importm() # prints Hello (again)
    print(importer.import_count)