5

I use python click package and setuptools to create a simple command line. And I work in a pipenv virtualenv.

My working directory is like this:

jkt/scripts/app.py

And my setup.py is like this:

from setuptools import setup, find_packages

setup(

  name='jkt',
  version='0.1',
  packages=find_packages(),
  include_package_data=True,
  entry_points='''
      [console_scripts]
      jktool=jkt.scripts.app:my_function 
  ''',

)

Then I run the command
pip install --editable .

And run jktool to execute my_function but I get the error:

ModuleNotFoundError No module named 'jkt'.

But when the app.py in jkt directory I can run my function

setup(
    name='app',
    version='0.1',
    py_modules=['app'],
    entry_points='''
        [console_scripts]
        app=app:jktools
    ''',
)

After I run pip install -e . I can use app command to run my function.

2
  • I can't reproduce your error, creating the same directory tree, a trivial app.py with def somefunction(): print("Works"), and installing with --user (to avoid global install). I can get an ImportError on Python 2.7 (if I don't put empty __init__.py files in jkt/ and jkt/scripts/), but for modern Python 3.7 (where ModuleNotFoundError is an ImportError subclass and implicit namespace packages are a thing), it works just fine. Commented Feb 22, 2019 at 3:30
  • @saluton Please share how you solved this. Commented Jul 2, 2021 at 19:32

1 Answer 1

12

As I mentioned, I can't reproduce your error (Python 3.7 with modern pip seems to work just fine), but there are a couple things that could potentially be going wrong on older versions.

Since it doesn't look like you put __init__.py files in your subdirectories, find_packages doesn't actually find any packages at all (python3 -c 'from setuptools import find_packages; print(find_packages()) prints the empty list, []). You can fix this in one of three ways:

  1. Create empty __init__.py files to explicitly mark those folders as package folders; on a UNIX-like system, touch jkt/__init__.py and touch jkt/scripts/__init__.py is enough to create them
  2. Python 3.3+ only: (also requires modern setuptools so pip install --upgrade setuptools might be necessary) Replace your use of find_packages with find_namespace_packages (which recognizes Python 3 era implicit namespace packages).
  3. Just get rid of find_packages entirely and list the packages directly, e.g. replace packages=find_packages(), with packages=['jkt', 'jkt.scripts'],

Options #2 only works on Python 3.3+, so if your package is intended to work on older versions of Python, go with option #1 or #3.

Sign up to request clarification or add additional context in comments.

2 Comments

oh Thanks but it doesn't work I don't know where went wrong. I create a virtualenv 3.7 and have a init file. And when I run pipenv graph it has a packeage named jkt but the program when I run it, it still can not find the module jkt. I will create a simple case to test. I have a question about when I run pip install -e . if it create a package named jkt? and when I run myfunction in shell if it will to load the package first and where the package is.
I solved this problem.thanks again, maybe I I don't have a clear list of directories and packages.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.