-2

I want my code to import all modules from path and allow user to access command class, but after I trying to import class command, __import__ fails to do this.

core.py:

def import_modules(path):
    modules = dict()
    for mod in os.listdir(path):
        if mod == '__init__.py' or mod[-3:] != '.py':
            continue
        else:
            m = __import__(mod[:-3]).command() # error here
            modules[m.name] = m
    return modules

commands = import_modules('test_directory/tests')
commands["test"].run()

test.py:

class command:
    def __init__(self):
        self.name = "test"
        self.description = "test"
        self.usage = "Usage: test"
        self.args = 1

    def run(self):
        print("test")

error:

AttributeError: module 'test' has no attribute 'command'

I really need help with this.

I tried via import lib, via getattr nothing works. Please help me solve this problem.

Enty AV
  • 65
  • 4
  • 1
    May I ask what functionality you're trying to implement with all this hackery? – Andras Deak -- Слава Україні Nov 02 '20 at 09:52
  • This is a part of big code. This function should import module and save it class to dict. After this user will be able to execute module from dict. – Enty AV Nov 02 '20 at 09:53
  • `from test import command` ? – Matiiss Nov 02 '20 at 09:55
  • No! I need import all modules from path, test1 test2 test3, testN. import_modules() imports all modules from path not only test! – Enty AV Nov 02 '20 at 10:00
  • Does this answer your question? [How to load all modules in a folder?](https://stackoverflow.com/questions/1057431/how-to-load-all-modules-in-a-folder) – Kirill Zaitsev Nov 02 '20 at 10:18
  • 1
    This setup is sensitive to import paths. How do you call ``import_modules``? Note that there is a standard library ``test`` module which might shadow your ``test.py``. Does ``from test import command`` work? Does ``__import__('test').__file__`` point to your ``test.py``? – MisterMiyagi Nov 02 '20 at 10:24
  • Yes. check this, I took code from here but in my program in does not works: https://github.com/neoneggplant/EggShell/blob/eaeeea7f806b157a0a7e234b618c72ecb8cb1650/modules/server.py#L26 – Enty AV Nov 02 '20 at 11:03
  • Instead of reposting exactly the same question [three](https://stackoverflow.com/q/64644916/4642212) [separate](https://meta.stackexchange.com/q/356104/289905) [times](https://stackoverflow.com/q/64647106/4642212), [edit] this original post to include the missing details. – Sebastian Simon Nov 02 '20 at 14:21

1 Answers1

1

You haven't provided how exactly you're using import_modules, but most likely you end up importing https://docs.python.org/3/library/test.html this module.

I suspect, that you're passing something like 'test.py' to import_modules and it ends up like that on sys.path. That's not how sys path works — it should be a list of directories, see https://docs.python.org/3/library/sys.html#sys.path

Also this looks like a duplicate to How to load all modules in a folder?

Kirill Zaitsev
  • 4,511
  • 3
  • 21
  • 29
  • NO! This is not question I asked, I asked why__import__ can't find class command in module! – Enty AV Nov 02 '20 at 10:20
  • It can't because you're importing a different module. Try to check m.__path__ of the module you've imported and see if it is the one you were trying to import. – Kirill Zaitsev Nov 02 '20 at 10:22
  • The issue might be ``sys.path.append(path)`` – putting the new search path *at the end*. The standard library paths are definitely in front of the end. – MisterMiyagi Nov 02 '20 at 10:27
  • Ok. Can you explain why this works in this project: https://github.com/neoneggplant/EggShell/blob/eaeeea7f806b157a0a7e234b618c72ecb8cb1650/modules/server.py#L26 – Enty AV Nov 02 '20 at 10:36
  • I don't know whether it works or not there. Or even what that code is supposed to do in that project. On a side note: try changing test.py to something less generic, like test_me.py – Kirill Zaitsev Nov 02 '20 at 11:00