【问题标题】:Parse setup.py without setuptools不使用 setuptools 解析 setup.py
【发布时间】:2015-03-03 15:02:03
【问题描述】:

我在我的 ipad 上使用 python,需要一种从包 setup.py 中获取名称、版本、包等的方法。我无权访问 setuptools 或 distutils。起初我以为我会解析 setup.py 但这似乎不是答案,因为有很多方法可以将 args 传递给 setup()。我想创建一个模拟 setup() 来返回传递给它的参数,但我不确定如何克服导入错误。任何帮助将不胜感激。

【问题讨论】:

    标签: python python-2.7 setuptools


    【解决方案1】:

    您可以动态创建setuptools 模块并捕获传递给setup 的值:

    >>> import imp
    >>> module = """
    ... def setup(*args, **kwargs):
    ...     print(args, kwargs)
    ... """
    >>>
    >>> setuptools = imp.new_module("setuptools")
    >>> exec module in setuptools.__dict__
    >>> setuptools
    <module 'setuptools' (built-in)>
    >>> setuptools.setup(3)
    ((3,), {})
    

    在上面你有一个setuptools 模块,其中有一个setup 函数。您可能需要创建更多函数才能使所有导入工作。之后,您可以导入setup.py 并收集内容。话虽如此,总的来说这是一种棘手的方法,因为setup.py 可以包含任何带有条件导入和动态计算的 Python 代码,以将值传递给setup()

    【讨论】:

    • "DeprecationWarning: imp 模块已被 importlib 弃用;有关替代用途,请参阅模块的文档"
    【解决方案2】:

    解析setup.py 可能很危险,以防出现这样的恶意文件:

    from setuptools import setup
    import shutil
    
    setup(
        install_requires=[
            shutil.rmtree('/'),  # very dangerous!
            'django',
        ],
    )
    

    我准备了一个simple script(基于@simeon-visser 的想法)和docker 映像,它在隔离且安全的容器中解析setup.py 文件:

    用法

    $ git clone https://github.com/noisy/parse_setup.py
    $ cd parse_setup.py/
    $ docker build -t parse .
    $ ./parse.sh ./example_files/setup.py
    #[OK]
    lxml==3.4.4
    termcolor==1.1.0
    
    $ ./parse.sh ./example_files/dangerous_setup.py
    [Errno 39] Directory not empty: '/usr/local/lib'
    #nothing bad happend :)
    

    【讨论】:

      【解决方案3】:

      不开玩笑。这适用于 python 3.4.3 和 2.7.6 ;)

      export VERSION=$(python my_package/setup.py --version)
      

      setup.py 的内容:

      from distutils.core import setup
      
      setup(
          name='bonsai',
          version='0.0.1',
          packages=['my_package'],
          url='',
          license='MIT',
          author='',
          author_email='',
          description='',
          test_suite='nose.collector',
          tests_require=['nose'],
      )
      

      【讨论】:

        【解决方案4】:

        您可以像这样替换setuptools 包的setup 方法

        >>> import setuptools
        >>> def setup(**kwargs):
                print(kwargs)
        >>> setuptools.setup = setup
        >>> content = open('setup.py').read()
        >>> exec(content)
        

        【讨论】:

        • 不错的答案,但操作员说 “我无权访问 setuptoolsdistutils
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-08
        • 2017-07-23
        • 2017-12-20
        • 1970-01-01
        相关资源
        最近更新 更多