TomCho
TomCho

Reputation: 3507

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.

Upvotes: 7

Views: 1284

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1122352

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().

Upvotes: 7

Related Questions