Can I create a package with root directory? - python

Assume the project directory structure is below:
test-package:
__init__.py
hello.py
setup.py
And the setup.py is:
from setuptools import setup, find_packages
setup(
name="test-package",
packages=find_packages(),
version="1.0",
include_package_data=True,
)
'test-package' is the root directory of the project. Then do:
pip install .
In the site-packages directory, there is only:
test_package-1.0-py3.7.egg-info/
I can't see the source file 'hello.py'.
I know most python projects's package name is not the root directory of the project. But in case I want to create a root directory name as the package name like this, is that possible?

You need to make a parent folder for test-package and put setup.py in there also use underscores for the package name. Technically PEP8 recommends all lowercase with no underscores for package names, but it's not a strict recommendation.
my-project:
setup.py
test_package:
__init__.py
hello.py
this has a helpful tutorial: https://packaging.python.org/tutorials/packaging-projects/
Edit: package name should use underscores not dashes

Related

How to configure python setuptools to install modules in the root directory as a single package?

I am using setuptools to create a python package. This is the directory structure:
mypackage
.git
__init__.py
pyproject.toml
setup.cfg
module1.py
module2.py
I have this structured in a flat hierarchy so I can clone this repository/copy this directory into a parent project/repository and directly write from mypackage import something, instead of having to pip install or play around with PYTHONPATH.
What do I specify in the setup.cfg file, such that this is installed as a single package, given the file structure?
# setup.cfg
[options]
package_dir = # What is here?
I tried out the custom discovery options in setuptools, which seems to work. I have to manually specify the root directory for packages. However setuptools fails when it finds multiple top-level modules/packages. So I have to use the find option to explicitly include discovered modules into a single package.
[options]
# Use the find function to find modules/packages
packages = find:
# The root directory is the current directory, relative to setup.cfg
packages_dir =
.
[options.packages.find]
# Options for the find command. Include is implicitly looking for all .py files,
# where the directory is "."
where = .

Add a virtual namespace for a Python package

I have a python package with the following directory structure:
my_package/
my_subpackage/
__init__.py
my_module.py
__init__.py
setup.py
When I generate the Python wheel and pip install it, I am not going to have the my_package namespace, so my_subpackage is going to be part of the global namespace of my virtualenv or whatever.
I know that the solution here is to create another directory called my_package and put everything inside it:
my_package/
my_package/
my_subpackage/
__init__.py
my_module.py
__init__.py
setup.py
But let's say that I cannot change the directory structure for some reason. Is there a way to add a virtual my_package namespace in setup.py with the first layout?
You can specify the package_dir option in your setup.py.
Something like this should work:
setup(
...
package_dir={'': '..'},
packages=['my_package']
...
)
I never used relative paths with package_dir though, so your confirmation would be appreciated.

Why current working directory affects install path of setup.py? How to prevent that?

I have created a custom python package following this guide, so I have the following structure:
mypackage/ <-- VCS root
mypackage/
submodule1/
submodule2/
setup.py
And setup.py contains exactly the same information as in the guide:
from setuptools import setup, find_packages
setup(name='mypackage',
version='0.1',
description='desc',
url='vcs_url',
author='Hodossy, Szabolcs',
author_email='myemail#example.com',
license='MIT',
packages=find_packages(),
install_requires=[
# deps
],
zip_safe=False)
I have noticed if I go into the folder where setup.py is, and then call python setup.py install in a virtual environment, in site-packages the following structure is installed:
.../site-packages/mypackage-0.1-py3.6.egg/mypackage/
submodule1/
submodule2/
but if I call it from one folder up like python mypackage/setup.py install, then the structure is the following:
.../site-packages/mypackage-0.1-py3.6.egg/mypackage/
mypackage/
submodule1/
submodule2/
This later one ruins all imports from my module, as the path is different for the submodules.
Could you explain what is happening here and how to prevent that kind of behaviour?
This is experienced with Python 3.6 on both Windows and Linux.
Your setup.py does not contain any paths, but seems to only find the files via find_packages. So of course it depends from where you run it. The setup.py isn't strictly tied to its location. Of course you could do things like chdir to the basename of the setup file path in sys.argv[0], but that's rather ugly.
The question is, WHY do you want to build it that way? It looks more like you would want a structure like
mypackage-source
mypackage
submodule1
submodule2
setup.py
And then execute setup.py from the work directory. If you want to be able to run it from anywhere, the better workaround would be to put a shellscript next to it, like
#!/bin/sh
cd ``basename $0``
python setup.py $#
which separates the task of changing to the right directory (here I assume the directory with setup.py in the workdir) from running setup.py

How to distribute python module under a specific name

I have python module, named models.py which i would like to upload to PyPi. When afterwards i install it using pip i would like it to appear as a package.
To explain myself, I have following project structure:
my_utils
mapper/
models.py
MANIFEST.in
setup.py
README
logger/
logger.py
logger_conf.json
MANIFEST.in
README
setup.py
I would like to create a distributed package out mapper.models, but when it is being installed on target machine, i would like it to appear in site-packages under mapper_tools.models.
My setup.py:
from distutils.core import setup
setup(
name='mapper_tools',
version='0.1.0',
description='some description',
author='myname',
author_email='my#email.com',
url='https://github.com/mapper-tools',
py_modules=['models'],
)
My MANIFEST.in:
include models.py README
Currently, after running pip install mapper-tools, I find models.py right under site-packages and I would like it to appear under mapper_tools.
Can i specify the structure that should be installed without changing the layout of my project?

Cannot include non-python files with setup.py

I read a lot of answers on this question, but no solution works for me.
Project layout:
generators_data\
en_family_names.txt
en_female_names.txt
__init__.py
generators.py
setup.py
I want include "generators_data" with it's content into installation. My setup.py:
from distutils.core import setup
setup(name='generators',
version='1.0',
package_data={'generators': ['generators_data/*']}
)
I tried
python setup.py install
got
running install
running build
running install_egg_info
Removing c:\Python27\Lib\site-packages\generators-1.0-py2.7.egg-info
Writing c:\Python27\Lib\site-packages\generators-1.0-py2.7.egg-info
but generators_data directory doesn't appear in "c:\Python27\Lib\site-packages\". Why?
The code you posted contains two issues: setup.py should be sibling to the package you want to distribute, not inside it, and you need to list packages in setup.py.
Try with this this layout:
generators/ # project root, the directory you get from git clone or equivalent
setup.py
generators/ # Python package
__init__.py
# other modules
generators_data/
names.txt
And this setup.py:
setup(name='generators',
version='1.0',
packages=['generators'],
package_data={'generators': ['generators_data/*']},
)

Categories