'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.



Solution 1:[1]

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.

Solution 2:[2]

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]

Solution 3:[3]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 MrHamm
Solution 2 Dilip H
Solution 3 anonymous