setuptools: find_packages() doesn't find PEP 420 packages

Originally reported by: gwideman (Bitbucket: gwideman, GitHub: gwideman)


#!python

setup(...
    packages=find_packages(..)
    )

on the developer machine will fail to find packages that lack a __init__.py file, as is allowed in Python 3.3. However, such packages listed explicitly: packages=[‘mypkg’] do appear to get included and later installed.

Note: When testing this, before each test be sure to delete all generated metadata, including that which setup may previously have placed in the original source directory, as it seems that setup may use metadata created on a previous run in order to include files.

This is part of a general problem reported in issue #83, but I’ve logged it separately as it’s specifically about setuptools.


About this issue

  • Original URL
  • State: closed
  • Created 11 years ago
  • Reactions: 12
  • Comments: 95 (30 by maintainers)

Commits related to this issue

Most upvoted comments

Original comment by jaraco (Bitbucket: jaraco, GitHub: jaraco):


I believe this issue is more than a minor one and should be addressed sooner than later.

@pganssle How do I use find_packages_ns from setup.cfg? It’s not obvious from your commit.

This issue was created on Nov 5, 2013 “You’re welcome”. And 50% of my rationale for raising this issue was that PEP420 seemed to break what people relied upon to indicate a package, further weakening Python’s chronic lack of explicit definition or record of programmers’ intent as to what constitutes a complete “thing”, a la “project” in other development environments. (And obliquely, agronholm’s comment “I’ll remind that PEP 420 namespaces is a feature not needed by most people” somewhat reinforces that observation.) For all that I like about Python, this is a problem area in my view, and continues to be.

My recommendation for now is that package maintainers continue to use __init__.py files in their namespace packages to mark the folder as a package for find_packages. Either that or enumerate the packages explicitly and not use find_packages. I haven’t made any advancement on the branch, but I do agree, what you propose would be preferable.

I’ve flagged this issue as help-wanted because I simply don’t have time to address all of these issues on my own. Please feel free to grab the work I’ve done and advance it, or start again from the current master.

Original comment by jaraco (Bitbucket: jaraco, GitHub: jaraco):


I’d like to say that Setuptools should support PEP 420 packages. The harder question is how should find_packages discover such packages? PEP 420 allows importing of any importable filename ending in .py in any directory in sys.path. However, sys.path isn’t relevant when building distributions and discovering packages.

I imagine setuptools could include all suitable directories, possibly omitting explicitly excluded paths. This change would be backwards-incompatible, but could provide packagers with options to produce compatible dists.

I considered using Python’s import machinery to find packages, but I don’t believe the import machinery provides any discovery tools.

The other thing to consider - if setuptools supports this mode, it will not work on other versions of Python, so will require Python 3.3+.

This gives me an idea - perhaps setuptools can use the package metadata to determine when PEP 420 package discovery is enabled. It could inspect the Trove classifiers and if Python versions are specified and only include versions >= 3.3, the feature would be enabled.

That technique would be somewhat implicit, but properly-documented, it could provide an elegant way to allow a packager to both include PEP 420 packages and declare the Python requirement at the same time.