Import a variable from setup.py from an external script

邮差的信 提交于 2021-01-28 06:01:09

问题


I have a setup.py file like this (not in pwd, not in Python path, a random file somewhere):

import ext_modules

config = {
    'name': 'mesos.executor',
    'version': '1.4.1',
    'description': 'Mesos native executor driver implementation',
    'author': 'Apache Mesos',
    'author_email': 'dev@mesos.apache.org',
    'url': 'http://pypi.python.org/pypi/mesos.executor',
    'namespace_packages': [ 'mesos' ],
    'packages': [ 'mesos', 'mesos.executor' ],
    'package_dir': { '': 'src' },
    'install_requires': [ 'mesos.interface == 1.4.1' ],
    'license': 'Apache 2.0',
    'keywords': 'mesos',
    'classifiers': [ ],
    'ext_modules': [ ext_modules.executor_module ]
}

from setuptools import setup
setup(**config)

And from an external (Python) script I'd like to import config["install_requires"]. I'm looking for the most minimalist way of doing this as it's intended to be run from other scripts that might even not be Python.

A Python one-liner would be awesome.


回答1:


Aside from importing python module from an arbitrary path, you also need to avoid execute setup(), one method is filtering through AST:

import ast, _ast

def filter_setup_st(node):
    if isinstance(node, _ast.Expr) and isinstance(node.value, _ast.Call):
        if node.value.func.id == 'setup':
            return False
    return True

with open('/path/to/example_setup.py') as f:
    c = f.read()   
tree = ast.parse(c)
tree.body = [n for n in tree.body if filter_setup_st(n)]

ns = {}
exec(compile(tree, '__string__', 'exec'), {}, ns)

assert ns['config']['install_requires'] == ['mesos.interface == 1.4.1']

another method is a bit tricky, to nullify setuptools.setup temporarily:

import setuptools
ori_setup = setuptools.setup
setuptools.setup = lambda *a, **k: 0

ns = {}
exec(compile(c, '__string__', 'exec'), {}, ns)
assert ns['config']['install_requires'] == ['mesos.interface == 1.4.1']

setuptools.setup = ori_setup

Update:

In case you also want bypass import of ext_modules:

import sys

class fake_ext_module():

    executor_module = 'spam'

sys.modules['ext_modules'] = fake_ext_module



回答2:


In the doc : https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly

In your case:

import importlib
setup_file = "path/to/setup.py"
spec = importlib.util.spec_from_file_location("setup", setup_file)
setup = importlib.util.module_from_spec(spec)
spec.loader.exec_module(setup)
# And now access it
print(setup.config["install_requires"])


来源:https://stackoverflow.com/questions/47463277/import-a-variable-from-setup-py-from-an-external-script

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!