Reputation: 2966
Suppose I have the following directory structure:
src/
└── python/
└── generated/
├── __init__.py
├── a.py
└── lib/
├── __init__.py
└── b.py
What does my setup.py
need to look like in order to create a dist with a directory layout like:
src/
└── python/
├── __init__.py
├── a.py
└── lib/
├── __init__.py
└── b.py
The goal is to simply eliminate the generated
folder. I've tried endless variations with package_dir
and can't get anything produced other than the original directory structure.
Upvotes: 6
Views: 5820
Reputation: 22295
In this specific case, for this specific project directory structure, the setup.py
script should be placed in the src
directory and should look like this:
#!/usr/bin/env python
import setuptools
setuptools.setup(
name='Thing',
version='1.2.3',
packages=[
'python',
'python.lib',
],
package_dir={
'python': 'python/generated',
},
)
Note the package_dir
setting. It instructs setuptools
to get the code for the python
package from the directory python/generated
. In the built distributions you will then find the right directory structure.
Upvotes: 6
Reputation: 511
First, here is my solution:
#!/usr/bin/env python
import os, shutil
from setuptools import setup
from setuptools.command.build_py import build_py
class BuildPyCommand(build_py):
"""Custom build command."""
def run(self):
shutil.rmtree('src.tmp', ignore_errors=True)
os.mkdir('src.tmp')
shutil.copytree('src/python/generated', 'src.tmp/python')
build_py.run(self)
setup(cmdclass={ 'build_py': BuildPyCommand },
name='Blabla',
version='1.0',
description='best desc ever',
author='Me',
packages=['python', 'python.lib'],
package_dir={'': 'src.tmp'},
setup_requires=['wheel']
)
And you can generate your distribution with:
python setup.py build bdist_wheel
The idea is perform a two steps build:
And I deliver it in a wheel because it doesn't require future users to understand my trick. If you give it a try with a source distribution, you will notice that you need to publish the generated files as data (not difficult, but troublesome, and, I guess you will want to hide your tricks from your users).
But, I think that there is a design flaw in your process. The file src/python/generated/__init__.py
, assumed to be a module <something>.generated
eventually becomes your <something>.python
, which is troublesome. It would be much simpler and more robust to generate a valid Python structure: src/generated/python/__init__.py
. The setup.py would become trivial and your generator wouldn't be more complex.
Upvotes: 0