Search code examples
pythoninstallationsetuptoolsdistutilssetup.py

What's distutils' equivalent of setuptools' `find_packages`? (python)


I have a setup.py file that checks if the user has setuptools and if he doesn't, then I am forced to use distutils. The thing is that, to make sure the submodules are installed, I use setuptools' find package:

from setuptools import setup, find_packages
packages = find_packages()

and then proceed from there.

However, I'm not sure how to do that with distutils. Is there an equivalent function or do I have to manually look for subdirs that have an __init__.py inside of them? If that is the case, is it acceptable for me to require setuptools to install my package and just forget about distutils?

Cheers.


Solution

  • It is perfectly acceptable to use setuptools; the vast majority of packages on PyPI already do.

    If you want to re-invent the find_packages() wheel, then yes, look for directories with __init__.py files in them. This is what the setuptools.PackageFinder class does. A simplified re-implementation would be:

    import os
    from distutils.util import convert_path
    
    
    def find_packages(base_path):
        base_path = convert_path(base_path)
        found = []
        for root, dirs, files in os.walk(base_path, followlinks=True):
            dirs[:] = [d for d in dirs if d[0] != '.' and d not in ('ez_setup', '__pycache__')]
            relpath = os.path.relpath(root, base_path)
            parent = relpath.replace(os.sep, '.').lstrip('.')
            if relpath != '.' and parent not in found:
                # foo.bar package but no foo package, skip
                continue
            for dir in dirs:
                if os.path.isfile(os.path.join(root, dir, '__init__.py')):
                    package = '.'.join((parent, dir)) if parent else dir
                    found.append(package)
        return found
    

    This ignores the include and exclude arguments of setuptools.find_packages().