setup.py isn't including modules - python

setup.py includes modules in the same directory it is in but leaves out modules in the site.packages directory and in a lib folder I have added to the pythonpath.
Don't tell me it doesn't just import files like the python interpreter. It should if you name them.
programdir-->
programdir-->
datadir
program.py
functions.py
setup.py
setup.py
from distutils.core import setup
setup(name = "program",
version = "1.0",
description = "a program",
author = "me",
author_email = "email#email.com",
url = "http://www.url.com",
py_modules = ["program", "functions", "tweepy", "anothermod", "webbrowser","" ],
data_files = [("data", ["data/intros.txt"])],
long_description = """
Descriptttttionnnn
"""
)
What am I doing wrong?

The setup.py is responsible for bundling and installing YOUR sources, not dependencies. However, you can specify requirements with install_requires (read the manual). This will be used by pip or setuptools to install the given dependencies, but it will not bundle them either.

Julius is using distutils, not setuptools. This means that requires shall be passed to the setup() function rather than install_requires. See the docs:
2.4. Relationships between Distributions and Packages

Related

What should my project structure be for distributing a personal python package on PyPi?

I'm trying to distribute a personal python package over PyPi. While it successfully pip installs, there's a ModuleNotFound error when I go to import PythonDebuggerTools locally.
setup.py
from setuptools import setup, find_packages
import codecs
import os
import setuptools
VERSION = '0.0.3'
DESCRIPTION = 'Debugging tools'
LONG_DESCRIPTION = 'A package that gives users access to several debugging functionality to make their development process efficient.'
# Setting up
setup(
name='PythonDebuggerTools',
version=VERSION,
author='Aakash Haran',
author_email='email',
description='Testing installation of Package',
long_description=LONG_DESCRIPTION,
long_description_content_type="text/markdown",
url='https://github.com/Luna-Cake/Logger',
license='MIT',
# packages=setuptools.find_packages(),
py_modules=['PythonDebuggerTools'],
install_requires=[],
)
My project structure looks like this:
>build
>dist
>PythonDebuggerTools-0.0.3.tar.gz
>PythonDebuggerTools
>__init__.py
>logger.py
>PythonDebuggerTools.egg-info
>dependency_links.txt
>PKG-INFO
>SOURCES.txt
>top_level.txt
>README.md
>setup.py
>setup.py~
=======
Any help would be greatly appreciated!
py_modules=['PythonDebuggerTools'],
is for *.py files. There is no PythonDebuggerTools.py so nothing was added to the wheel package.
Your PythonDebuggerTools is an importably directory so declare it as a packge:
packages=['PythonDebuggerTools'],
See https://packaging.python.org/tutorials/packaging-projects/

Setuptools: distribute package composed of a single module

I'm learning how to distribute python packages using setuptools and I have a problem.
setuptools is setting the name of the folder containing a single python file as the name of my package. Below is the structure of my repository:
gerador_endereco/
-- setup.py
-- my_package/
-- __init__.py
-- gerador_endereco.py
My setup.py is:
setup(
name='gerador_endereco',
version='1.0.4',
author='Michel Metran',
description='API para criação ...',
url='https://github.com/open-dsa/gerador_endereco',
packages=find_packages(),
install_requires=requirements,
)
I understand that setuptools is related to the distribution of packages, composed of several modules. But I know that it is possible to distribute a package composed of a single module, but how can I import the package correctly, without the folder name appearing?
# Install
!pip install gerador-endereco
# Import work using "my_package" directory: bad...
from my_package.gerador_endereco import *
# I'd like import like this!!!
from gerador_endereco import *
# Run
listas = get_list_ceps_bairros(estado='sp', municipio='piracicaba')
The PyPi Package is in https://pypi.org/project/gerador-endereco/
setuptools is related to the distribution of packages, period. To install a module restructure you project:
gerador_endereco/
-- setup.py
-- gerador_endereco.py
and change setup.py; remove
packages=find_packages(),
and add
py_modules = ['gerador_endereco']
instead. See the docs at https://docs.python.org/3/distutils/setupscript.html#listing-individual-modules and https://packaging.python.org/guides/distributing-packages-using-setuptools/?#py-modules

How to register Entry Points for network python package installs?

I have a user environment where most python packages are installed on a network share and are made available via the PYTHONPATH environment variable. Python itself is still installed locally. Some of those packages need to register setuptools Entry Points. Normally, this would happen by running the setup.py file for the package, but because these are installed to a network location, that setup.py is never run with the local installation of python.
Is there a way to register Entry Points without installing a package in the local python installation?
An example of an entrypoint that registers a callback for a plugin system
setup(
...
entry_points={
'xx_plugin': ['value = package.module:func'],
}
)
Run setup.py
The console_scripts and gui_scripts entry points create standalone scripts that wrap a callable object. The coverage package is a good example of this. It has an entry point to create a wrapper script for convenience. Example setup.py snippet to create a console script:
setup(
...
entry_points = {
'console_scripts': [
'script_name = package.module:function'
]
}
)
It's possible to only install the scripts to a specified directory via setup.py. An existing script will not be overwritten unless the --force argument is passed.
python setup.py install_scripts --install-dir /some/alternate/location
For a plugin, the entry point is stored as metadata in an egg that's typically installed with the package. Example plugin entry point:
setup(
...
entry_points = {
'group_name': [
'plugin_name = package.module:function'
]
}
)
It's possible to only install the metadata of a package (including any entry points) to a specified directory via setup.py.
python setup.py egg_info --egg-base $PYTHONPATH
Roll your own
If setup.py can't be run to write the egg metadata, it's totally possible to roll your own, as it's only a text file in a directory. Example metadata based on the above entry point:
# $PYTHONPATH/entry_points.egg-info/entry_points.txt
[group_name]
plugin_name = package.module:function
To test entry point lookup:
import pkg_resources as pkg
for entry_point in pkg.iter_entry_points('group_name'):
plugin_name = entry_point.name
plugin_module_name = entry_point.module_name
plugin_callable = entry_point.load()
# do something with plugin

setup.py not installing data files

I have a Python library that, in addition to regular Python modules, has some data files that need to go in /usr/local/lib/python2.7/dist-package/mylibrary.
Unfortunately, I have been unable to convince setup.py to actually install the data files there. Note that this behaviour is under install - not sdist.
Here is a slightly redacted version of setup.py
module_list = list_of_files
setup(name ='Modules',
version ='1.33.7',
description ='My Sweet Module',
author ='PN',
author_email ='email',
url ='url',
packages = ['my_module'],
# I tried this. It got installed in /usr/my_module. Not ok.
# data_files = [ ("my_module", ["my_module/data1",
# "my_module/data2"])]
# This doesn't install it at all.
package_data = {"my_module" : ["my_module/data1",
"my_module/data2"] }
)
This is in Python 2.7 (will have to run in 2.6 eventually), and will have to run on some Ubuntu between 10.04 and 12+. Developing it right now on 12.04.
UPD:
package_data accepts dict in format {'package': ['list', 'of?', 'globs*']}, so to make it work, one should specify shell globs relative to package dir, not the file paths relative to the distribution root.
data_files has a different meaning, and, in general, one should avoid using this parameter.
With setuptools you only need include_package_data=True, but data files should be under version control system, known to setuptools (by default it recognizes only CVS and SVN, install setuptools-git or setuptools-hg if you use git or hg...)
with setuptools you can:
- in MANIFEST.im:
include my_module/data*
- in setup.py:
setup(
...
include_package_data = True,
...
)
http://docs.python.org/distutils/setupscript.html#installing-additional-files
If directory is a relative path, it is interpreted relative to the
installation prefix (Python’s sys.prefix for pure-Python packages,
sys.exec_prefix for packages that contain extension modules).
This will probably do it:
data_files = [ ("my_module", ["local/lib/python2.7/dist-package/my_module/data1",
"local/lib/python2.7/dist-package/my_module/data2"])]
Or just use join to add the prefix:
data_dir = os.path.join(sys.prefix, "local/lib/python2.7/dist-package/my_module")
data_files = [ ("my_module", [os.path.join(data_dir, "data1"),
os.path.join(data_dir, "data2")])]
The following solution worked fine for me.
You should have MANIFEST.in file where setup.py is located.
Add the following code to the manifest file
recursive-include mypackage *.json *.md # can be extended with more extensions or file names.
Another solution is adding the following code to the MANIFEST.in file.
graft mypackage # will copy the entire package including non-python files.
global-exclude __pyache__ *.txt # list files you dont want to include here.
Now, when you do pip install all the necessary files will be included.
Hope this helps.
UPDATE:
Make sure that you also have include_package_data=True in the setup file

How to include license file in setup.py script?

I have written a Python extension module in C++.
I plan to distribute the module with setuptools.
There will be binary distributions for 32- and 64-bit Windows (built with setup.py bdist_egg) and a source distribution for UNIX-like platforms (built with setup.py sdist).
I plan to license the module under the BSD license.
In my source tree, the file LICENSE.txt is in the top folder along with setup.py.
How should I include it in the installation package?
I tried the following setup.py script:
from setuptools import setup, Extension
from glob import glob
setup(
name = 'Foo',
version = '0.1.0',
ext_modules = [Extension('Foo', glob('Source/*.cpp'))],
package_data = {'': ['LICENSE.txt']}
)
It did not work, the license file is not included in the installation package.
Maybe because the setup.py file does not define any packages,
only a single extension module.
How do I fix this?
Write a setup.cfg file and in there specify:
[metadata]
license_files = LICENSE.txt
For this to work it seems like wheel is required to be installed. That is:
pip install wheel
If you have wheel already installed and it doesn't work, try to update it:
pip install --upgrade wheel
Then when installing the package via pip install <path> the LICENSE file gets included.
Since setuptools 42.0.0 you can use the license_files key to specify a list of license files to be included into a distribution. Since version 56.0.0 it supports pattern matching and defaults to ('LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*').
Note that due to implementation details there's actually no need to put this key into setup.cfg file (as another answer suggests). You could supply it as an argument to setup() function instead:
(documentation was unclear on this at the time of writing)
from setuptools import setup
setup(
...
license_files = ('LICENSE.txt',),
...
)
Also note that while these files will be included in both binary (wheel) and source distributions, they won't be installed with your package from setup.py-style source distribution if the user doesn't have a wheel package installed!
To ensure the license files will be installed along with your package you need to make some additional modifications to your setup script:
from setuptools import setup
from setuptools.command.egg_info import egg_info
class egg_info_ex(egg_info):
"""Includes license file into `.egg-info` folder."""
def run(self):
# don't duplicate license into `.egg-info` when building a distribution
if not self.distribution.have_run.get('install', True):
# `install` command is in progress, copy license
self.mkpath(self.egg_info)
self.copy_file('LICENSE.txt', self.egg_info)
egg_info.run(self)
setup(
...
license_files = ('LICENSE.txt',),
cmdclass = {'egg_info': egg_info_ex},
...
)
If your project is a pyproject.toml-style project and you think it will be installed by PEP 517-compatible frontend (e.g. pip>=19), a wheel will be forcibly built from your sources and the license files will be installed into .dist-info folder automatically.
Since version 61.0.0 you could specify project metadata and other configuration options in pyproject.toml file instead.
Using a METADATA.in file, the license can be included both the source package and wheels automatically:
METADATA.in
include README.md
include COPYING
Check out an example here:
https://github.com/node40/smsh
New setuptools (40.x) allows metadata, including license, to be stored in the setup.cfg's "metadata" section. If you use older setuptools you could provide license using the "license" named argument in your setup():
def read_text(file_name: str):
return open(os.path.join(base_path, file_name)).read()
setup(
name = 'Foo',
version = '0.1.0',
ext_modules = [Extension('Foo', glob('Source/*.cpp'))],
# package_data = {'': ['LICENSE.txt']}
license=read_text("LICENSE.txt")
)
You have to move the LICENSE.txt file into the package directory for your project. It cannot reside the top level. Python directories get deployed, not the deployment artifact. If you create a python package, that package actually contains a number of subpackages. Each subpackage must contain ALL the files relevant to deployment.
Do not use data_files as it will actually distribute the files as a separate package. (I've heard package_files works, but I have yet to see a working example to do this).
For example:
setup(
...
license="ZPL",
classifiers=[
...
'License :: OSI Approved :: Zope Public License',
...
],
...)
additionally you can insert your licence text into 'long_description':
setup(
...
long_description="Package description. \nLicense Text",
...)

Categories