Configuring Python C extensions for pip - python

I wrote a Python C extension, and it works great. Installing via python setup.py install works. However, pip cannot find my header files - so a pip installation doesn't work.
> pip install
Collecting jcalg1==1.0.1
Downloading https://files.pythonhosted.org/packages/a1/83/08b5fc2fbd36c8ac0668ae64c05cc88f3f6bd8fe68f058b19b11a463afa1/jcalg1-1.0.1.tar.gz
Installing collected packages: jcalg1
Running setup.py install for jcalg1 ... error
ERROR: Command errored out with exit status 1:
(...)
src\main.cpp(7): fatal error C1083: Cannot open include file: 'jcalg1.h': No such file or directory
(...)
This is my setup.py, the header file is located in the src folder.
from setuptools import setup,Extension
import setuptools
from setuptools import find_packages
import pathlib
# The actual C extension
jc_module = Extension('jcalg1', include_dirs=["src"], sources = ['src\main.cpp'], libraries =["src\jcalg1_static"])
# The directory containing this file
HERE = pathlib.Path(__file__).parent
# The text of the README file
README = (HERE / "README.md").read_text()
# This call to setup() does all the work
setup(
name="jcalg1",
version="1.0.1",
description="Interface to the JCALG1 compression library",
long_description=README,
long_description_content_type="text/markdown",
url="https://github.com/CallMeAlexO/jcalg1",
author="Alex Osheter",
author_email="alex.osheter#gmail.com",
license="MIT",
classifiers=[
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
],
ext_modules = [ jc_module ],
packages=find_packages()
)

You can create a MANIFEST.in file in your project root directory:
include src\*.h
include src\*.lib
Then rebuild your package. It will add the header files and library files into your package.

Related

Installing c library with setup.py

I have written a python package I'm trying to install. With a structure:
packagename
|
|--- setup.py
|--- module_name
|
|--- library.c
The library.c file has been successfully installed outside of this package using:
gcc library.c -Wall -pedantic -o spec_conv -lm -O2
My setup.py file looks like:
from setuptools import setup, Extension
with open("README.md", "r") as fh:
long_description = fh.read()
module = Extension('library',
sources = ['module_name/library.c'],
extra_compile_args=['-Wall', '-pedantic', '-o', 'library', '-lm', '-O2'])
setup(
name="module_name", # Replace with your own username
version="0.0.1",
author="",
author_email="",
description="",
long_description=long_description,
long_description_content_type="text/markdown",
packages=setuptools.find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.6',
install_requires=[
'pandas',
'pexpect'],
#cmdclass={'install': CustomInstall},
#include_package_data=True,
ext_modules=[module],
)
When I run pip install -e . the compile returns an error message:
https://pastebin.com/hMLA95G9
Following on from #9769953's comment I've tried to edit the setup.py to directly link to the full path of the file:
from pathlib import Path
ROOT_PATH = Path(__file__).parent.resolve()
module = Extension('spec_con',
sources = ['spec_conv/spec_con.c'],
extra_compile_args=['-Wall', '-pedantic', '-o', f'{ROOT_PATH}/module_name/library', '-lm', '-O2'],
library_dirs=["/home/alletro/python_packages"])
But I still get the same error.
The error is from the linker, that can't find the object file build by the compiler. The object file can't be found, because you specify the object file path manually, and it ends up in the wrong place.
The solution is to remove the '-o', 'library' items from the extra_compile_args option to Extension.
That way, Distutils and gcc will then automatically provide the correct name for the resulting object file (in particular, the correct full directory path), which can then be picked by the linker successfully.

python package not packaging files under a subdirectory

Here is my setup.py
from setuptools import setup, find_packages
import versioneer
REQUIRES = [
"requests",
"subprocess32",
"systemd"
]
CLASSIFIERS = [
...
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6"
]
setup(
author="IBM",
cmdclass=versioneer.get_cmdclass(),
description="A collections of utilities",
entry_points={},
install_requires=REQUIRES,
keywords=["management", "segment_sqls"],
license="XXX",
long_description="""Utilities for instance management and house keeping""",
packages=find_packages(),
tests_require=["pytest"],
url="https://github.ibm.com/myrepo/management",
name="management",
version=versioneer.get_version(),
classifiers=CLASSIFIERS
)
I am trying to run python3 setup.py sdist upload -r local to package and upload to my artifactory.The package's tar.gz is uploaded to artifactory with all files except the ones under segment_sqls. Here is my directory structure. init.py under segment_sqls is packaged but not the actual sql files. Is there any additional param that needs to be specified in setup.py to include all files?

Python wheel: "ModuleNotFoundError" after installing package

OS: Windows 7
Python: 3.6
I'm trying to create and installing a python wheel package. The building works fine but when i import the module into project after installing it, i get a "ModuleNotFound" error. My project has the following structure:
my_lib/
__init__.py
phlayer/
__init___.py
uart.py
utils/
__init___.py
ctimer.py
My setup.py for creating the wheel package:
import setuptools
with open("README.md", "r") as fh:
long_description = fh.read()
setuptools.setup(
name="my_lib",
version="0.0.1",
author="",
author_email="",
description="",
packages=setuptools.find_packages(),
classifiers=(
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
),
)
In uart.py i do:
from utils import ctimer
After installing i import the package into another project:
#Test.py
from my_lib.phlayer.uart import Uart
def main(args=None):
pass
if __name__ == "__main__":
main()
And i get the error:
File "C:/.../.../.../Test.py", line 9, in <module>
from my_lib.phlayer.uart import Uart
File "C:\...\...\...\...\...\...\test\env\lib\site-packages\my_lib\phlayer\uart.py", line 3, in <module>
from utils import ctimer
ModuleNotFoundError: No module named 'utils'
So it seems that python cannot find the correct module in the other package. Do i need to specify the correct paths in the setup.py
before creating the wheel package?
You have to specify full module names:
from my_lib.utils import ctimer

python setup.py install shows success message but pip freeze cannot see and script is not a valid command

I am trying to install a package that I just developed locally (Python 3.6, setuptools 35.0.2) and I see success message:
Copying mon_agent-0.0.1-py3.6.egg to /home/jgu/repos/.venv36/lib/python3.6/site-packages
mon-agent 0.0.1 is already the active version in easy-install.pth
Installing mon_agent_worker.py script to /home/jgu/repos/.venv36/bin
Installed /home/jgu/repos/.venv36/lib/python3.6/site-packages/mon_agent-0.0.1-py3.6.egg
Processing dependencies for mon-agent==0.0.1
Finished processing dependencies for mon-agent==0.0.1
But when I do pip freeze | grep mon (I did pip list and did not find mon_agent either) I see nothing and when I type mon_agent_worker in command line, it says command does not exist.
I can open python shell and import mon_agent and prints out it version and use it normally. However I cannot run script -- command not found
Edit:
I just run python setup.py bdist_wheel --universal and pip install mon_agent-0.0.1-py2.py3-none-any.whl and the script is working, and pip freeze shows it
Edit (Added my setup.py for more debugging info):
#!/usr/bin/env python
from __future__ import absolute_import, print_function
try:
from setuptools import setup
except ImportError:
from distutils.core import setup
import mon_agent
NAME = 'mon_agent'
PACKAGES = [
'mon_agent', 'mon_agent.collectors'
]
PACKAGE_DATA = {
'': ['resources/*.txt']
}
AUTHOR = mon_agent.__author__
AUTHOR_EMAIL = 'franklingujunchao#gmail.com'
URL = '***something***'
REQUIRES = []
with open('requirements.txt', 'r') as ifile:
for line in ifile:
REQUIRES.append(line.strip())
VERSION = mon_agent.__version__
DESCRIPTION = 'Log monitor agent'
KEYWORDS = 'monitor data log agent'
LONG_DESC = mon_agent.__doc__
setup(
name=NAME,
version=VERSION,
author=AUTHOR,
author_email=AUTHOR_EMAIL,
description=DESCRIPTION,
long_description=LONG_DESC,
url=URL,
keywords=KEYWORDS,
scripts=['bin/mon_agent_worker'],
package_dir={'': './'},
packages=PACKAGES,
package_data=PACKAGE_DATA,
include_package_data=True,
install_requires=REQUIRES,
python_requires='>=3.5',
classifiers=[
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python',
],
)

pip installation throws IOerror - no setup.py

I'm packaging my project via setup.py of a following structure:
import os
from setuptools import setup
def read(fname):
return open(os.path.join(os.path.dirname(__file__), fname)).read()
setup(
name = "blah",
version = "0.0.1",
author = "Chuck Norris",
author_email = "xyz#gmail.com",
description = ("blah blah blah."),
license = "BSD",
keywords = "django",
url = "http://packages.python.org/blah",
packages=['blah'],
long_description=read('README'),
classifiers=[
"Development Status :: 3 - Alpha",
"Topic :: Utilities",
"License :: OSI Approved :: BSD License",
],
)
My directory structure is
folder/
--blah/__init__.py
--blah/other stuff
--readme
--setup.py
When installing the .egg with pip, I get error IOError: [Errno 2] No such file or directory: '/tmp/pip-Us23IZ-build/setup.py'.
When unzipped, egg does not contain setup.py, indeed. I'm not sure whether it should, or not, or is it of any relevance to the error at all.
Thanks.
It is likely, you have setup.py in wrong directory.
Proper directory structure is:
projectroot/
setup.py
README
blah/
__init__.py
<whatever other modules your package needs>
Packaging (calling the setup.py to build an egg or other distribution package) shall be done from projectroot.
After creation of the egg file, you shall visit it (the egg file is zip archive) and check, if setup.py is present.

Categories

Resources