打包二级子目录

packaging a second-level sub-directory

我有这个项目架构,我想让 my_package pip 可安装。该项目不仅包含要打包的东西,还包含简单的脚本(快速而肮脏的那种)以及对我的项目很重要但对包不重要的东西(例如外部数据)。

my_project
├── code
│   ├── data          #<-- I don't want to package this
│   │   └── make_dataset.py
│   ├── script        #<-- I don't want to package this
│   │   └── make_experiment.py
│   └── my_package    #<-- This is the module I want to package
│       ├── core.py
│       ├── utils.py
│       └── __init__.py
├── data
│   └── some_data.txt
├── references
│   └── reference_paper.pdf
├── reports
│   └── report.tex
├── LICENSE
├── README.md
├── requirements.txt
└── setup.py

我希望 setup.py 文件位于顶级目录中,以便人们可以执行通常的操作

git clone gitinstance.com/my_project
cd my_project
pip install .

并在他们的环境中安装 my_package 模块,这样他们就可以做到 python -c import my_package; print(my_package.__version__) 并且它有效。

问题是:如何在不将 setup.py 放入 code 目录的情况下使 my_package pip 可安装?

通常,setup.py 看起来像这样:

from setuptools import find_packages, setup

setup(
    name='my_package',
    packages=find_packages(),
    version='0.1.0',
    description='Research project',
    author='Name',
    license='MIT',
)

但它在这里不起作用,因为 setup.py 找不到 my_package

I found an example in the documentation of setuptools that more or less fit my use-case.

解决方案是在 setup 函数的 packagespackage_dir 参数中,它允许指定在哪里找到要安装的包。这通常是隐藏的,因为它默认为当前工作目录。

在我的简单示例中,setup.py 转换为:

from setuptools import find_packages, setup

setup(
    name='my_package',
    packages=find_packages(where="code"),
    package_dir={'': "code"},
    version='0.1.0',
    description='Research project',
    author='Name',
    license='MIT',
)