Import a script from package in setup.py
Asked Answered
I

2

7

I want to use a setup.py which imports from a script which is part of the package that has to be installed. This script just contains a dict that contains the strings for creating entry points. I haven't hardcoded them in the setup.py because I want to use this list again later from the installed package.

Just for clearance here my directory structure and important files:

PackageA
|_package_a
| |_models
| |_modules
| | |_do_query.py
| | |_...
| |_setup_cfg.py
| |_ __init__.py
| |_...
|_ __init__.py
|_setup.py

__init__.py in package_a:

from .setup_cfg import setup_config

setup_cfg.py:

setup_config = {
    'scripts': [
        'do_query'
    ]
}

setup.py:

    # -*- coding: utf-8 -*-

from setuptools import setup, find_packages
from .package_a import setup_config

with open('README.rst') as f:
    readme = f.read()

with open('LICENSE') as f:
    license = f.read()

setup(
    ...,
    entry_points={
        'console_scripts': ['{}=package_a.modules.{}:main'.format(script, script) for script in setup_config.get('scripts')]
    },
)

I can make the import from .package_a import setup_config and pycharm resolves this import correctly. However, if I try to install the package via pip3 install . it fails with ModuleNotFoundError: No module named '__main__.package_a'; '__main__' is not a package (we use pip instead of python setup.py install as we want to have the whole source folder installed in site-packages instead of a bundled version)

Can anyone explain me that exception or provide a proper way to achieve such a configuration? (The dict in setup_config.py must be accesible from setup.py as well when importing the installed package.

Interleave answered 24/7, 2017 at 12:27 Comment(3)
you are trying to import everything * from directory. you can use such import method in file only. i.e. you can use from .package_a.modules._do_query import *Fulllength
Sorry, already corrected this one but posted it wrong. I corrected it. Same exception anyway.Interleave
Five and a half years late, here's the official guide on slurping in a package resource in setup.py, focuses on the version number but the techniques should work equally well for a dict: packaging.python.org/en/latest/guides/…Chairman
P
1

I faced the similar problem, and also resolved it in very strange way, i really don't know the reason it is working, even i thought it should not work.

i just imported without relative path

eg:

from package_a import setup_config

just removed the relative path(dot removed), it worked. pycharm is throwing error, but when in ran pip3 install . it worked. please let me know if it works for you.

Preestablish answered 16/11, 2017 at 11:18 Comment(0)
C
0

This technique is really useful if you want to keep a version string in exactly one file within your package, and reuse that version string in your setup.py file. For example I have an open API spec file that starts:

openapi: 3.0.3

info:
  version: 0.5.8
  title: Super Data Service
  ...

The module version.py parses and publishes the version string:

import importlib_resources

__version__ = "0.0.0"
yaml_path = importlib_resources.files('mypackage').joinpath('openapi.yml')
with importlib_resources.as_file(yaml_path) as yaml:
    with open(yaml, "r") as fileh:
        for line in fileh:
            line = line.strip()
            if line.startswith('version:'):
                __version__ = line.split()[1]
                break

And finally here's how I used that in setup.py:

from setuptools import setup, find_packages
from mypackage import version


setup(
    name="mypackage",
    version=version.__version__,
    packages=find_packages(exclude=["tests.*", "tests"]),
    ...

HTH

Chairman answered 31/3, 2022 at 18:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.