pip Install Editable Package Produces ModuleNotFoundError
Asked Answered
B

2

20

Due to import issues, I've followed the steps shown here to install my Python project as an editable pip package. Basically this entails running pip install -e . from my project root directory. The name of the project is 'myproject', with the setup.py configured as such:

from setuptools import setup, find_packages

setup(name='myproject', version='1.0', packages=find_packages())

The project structure is like so:

.
├── myproject
│   ├── core
│   │   ├── core.py
│   │   └── __init__.py
│   └── tests
│       ├── __init__.py
│       └── test_one.py
├── setup.py
└── env
    └── ...

With the venv activated, I get the following output:

(env) [root@localhost /]$ python -V
Python 3.6.3

(env) [root@localhost /]$ pip -V
pip 9.0.1 from /myproject/venv/lib64/python3.6/site-packages (python 3.6)

However, when running an interpreted session I experience the following:

(env) [root@localhost /]$ python
>>> import myproject
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'myproject'
>>> from myproject.core import *
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'myproject'

Starting up another interpreted session and running the setuptools stuff myself results in:

(env) [root@localhost /]$ python
>>> from setuptools import find_packages
>>> find_packages()
>>> ['core', 'tests']

I've also tried other methods of installing it, including:

python -m pip install -e .

And still get the same problems. Finally, I can do the following:

(env) [root@localhost /] pip list installed | grep myproject
myproject (1.0, /myproject)

UPDATE: As shown here and as mentioned by @Fletchy1995 below, changing the directory structure so that it is instead like:

.
├── setup.py
├── myproject
│   ├── core
│   │   ├── core.py
│   │   └── __init__.py
│   └── tests
│       ├── __init__.py
│       └── test_one.py
├── __init__.py
└── env
    └── ...

And modifying setup.py to look like:

from setuptools import setup

setup(name='myproject', version='1.0', packages=['myproject'])

along with running pip install -e . from the top level directory seems to have fixed the problem. But in the previous case, even though the packages loaded include all sub-packages of 'myproject', why can I still not do something like:

(env) [root@localhost /]$ python
>>> from myproject.core import *

as 'myproject' is listed in pip?

Baryta answered 28/8, 2019 at 15:23 Comment(5)
(env) $ python are you in a Anaconda environment (or similar) or are you just stating the directory you are currently in? If its a directory, perhaps try backing out one directory and trying again.Linis
That is just to show the commands are being executed from the shell and with the venv activated. I've tried it from the directory containing setup.py as well as the directory above it. Also, I've edited the question to make my first statement more apparent.Baryta
#45334Caro
I've been facing similar issues with frappe as well, which installs all its apps in editable mode. However, the problem exists only in macOS currently. any distro of Linux works just fine.Bashemath
I think you should post your "update" part as the solution. Your post is literally the only resource I could find after hours of scouring online resources to understand what I was supposed to do for a simple situation like yours. I would add that unfortunately this still brings on another problem, which is type checking with certain interpreters, namely MyPy within Pylance in Visual Studio Code. After installing the local package as editable, the static type checker is unable to see it, as I'm reporting in my comment here.Phase
J
2

At first glance, it appears you are missing __init__.py in your myproject subdirectory. Python does not consider a directory to be a package/subpackage unless it contains __init__.py.

Jentoft answered 24/4, 2023 at 22:15 Comment(0)
S
-1

It may work if you modify the setup.py to

from setuptools import setup, find_packages

setup(name='myproject', version='1.0', packages=find_packages(where='myproject'))

Then, you can then run pip install -e from the root directory to install the package in editable mode.

Sparoid answered 3/1, 2023 at 18:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.