Alchemist AB
Alchemist AB

Reputation: 31

eth-brownie - No module named <Users.someuser>

Getting this error while trying to run a eth-brownie script on MacOS

ModuleNotFoundError: No module named 'Users.xyz'

Run command:

brownie run scripts/mainnet/poolUpdaterMainNet.py --network bsc-main

Would be great if someone can help.

Upvotes: 3

Views: 1204

Answers (4)

Gnostication
Gnostication

Reputation: 11

I found MrHamm's solution was nearly perfect, except it was looking at absolute paths (i.e., a /root-directory/path location) instead of relative path.

MrHamm's solution didn't work for me until I adjusted it to make the import path relative, as such:

def _import_from_path(path: Path) -> ModuleType:
    # Imports a module from the given path
    
    import_str = "./" + "/".join(path.parts[1:-1] + (path.stem,))+'.py'
    
    if import_str in _import_cache:
        importlib.reload(_import_cache[import_str])
    else:
        spec = importlib.util.spec_from_file_location('.'+path.stem,import_str)
        module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(module)
        _import_cache[import_str] = module
    return _import_cache[import_str]

That initial "./" in the import string instead of "/" made all the difference for me.

Upvotes: 0

Naman Vyas
Naman Vyas

Reputation: 99

Move your project folder to C:// drive (or wherever pip install packages).

It's not a problem in Linux because there's no disk partition in Linux.

Upvotes: 0

Dilip H
Dilip H

Reputation: 156

I faced a similar issue on windows too and the above fix by MrHamm worked for me by replacing the existing method _import_from_path in C:\Users\d****\AppData\Roaming\Python\Python310\site-packages\brownie\project\scripts.py", line 150

Just replace

def _import_from_path(path: Path) -> ModuleType:
    # Imports a module from the given path
    import_str = ".".join(path.parts[1:-1] + (path.stem,))
    if import_str in _import_cache:
        importlib.reload(_import_cache[import_str])
    else:
        print(import_str)
        _import_cache[import_str] = importlib.import_module(import_str)
    return _import_cache[import_str]

to the code snippet below:

def _import_from_path(path: Path) -> ModuleType:
    # Imports a module from the given path
    
    import_str = "/" + "/".join(path.parts[1:-1] + (path.stem,))+'.py'
    
    if import_str in _import_cache:
        importlib.reload(_import_cache[import_str])
    else:
        spec = importlib.util.spec_from_file_location('.'+path.stem,import_str)
        module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(module)
        _import_cache[import_str] = module
    return _import_cache[import_str]

Upvotes: 1

MrHamm
MrHamm

Reputation: 31

I am on Python 3.9.6, but had a similar problem only using my MacOS, does not occur on my Linux machine.

Either way, I think I found a solution (at least for my version). The issue stems from the function _import_from_path in the file brownie/project/scripts.py (that should be found in your eth-brownie folder, wherever you installed it). The way it is written, it will incorrectly identify Users.username as "not a module."

My solution: replace _import_from_path with the following

def _import_from_path(path: Path) -> ModuleType:
    # Imports a module from the given path
    
    import_str = "/" + "/".join(path.parts[1:-1] + (path.stem,))+'.py'
    
    if import_str in _import_cache:
        importlib.reload(_import_cache[import_str])
    else:
        spec = importlib.util.spec_from_file_location('.'+path.stem,import_str)
        module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(module)
        _import_cache[import_str] = module
    return _import_cache[import_str]

Explanation: import_str is now modified to reflect the exact file location instead of a module name. The else: block now imports the module by specifying the file location and then loading that file as a module. I'm not sure if this will break any of the functionality in other operating systems, but I'm happy with using it as a hotfix for my Mac -- I can now run my scripts folder.

Upvotes: 3

Related Questions