In setup.py or pip requirements file, how to control order of installing package dependencies?

后端 未结 4 1675
情歌与酒
情歌与酒 2021-01-02 02:35

I\'ve got a Python package with its setup.py having dependencies declared via the usual way, in install_requires=[...]. One of the packages there, scikits.timeseries, has a

4条回答
  •  旧巷少年郎
    2021-01-02 03:04

    Here's a solution which actually works. It's not an overly "pleasant" method to have to resort to, but "desperate times...".

    Basically, you have to:

    • Override the setuptools "install command" class (plus the closely related analogs)
    • Execute pip from the script via command line statements for which you can enforce the order

    The drawbacks to this are:

    • Pip must be installed. You can't just execute setup.py in an environment without that.
    • The console output of the initial "prerequisite" installs don't appear for some weird reason. (Perhaps I'll post an update here down the line fixing that...)

    The code:

    from setuptools import setup
    
    # Override standard setuptools commands. 
    # Enforce the order of dependency installation.
    #-------------------------------------------------
    PREREQS = [ "ORDERED-INSTALL-PACKAGE" ]
    
    from setuptools.command.install import install
    from setuptools.command.develop import develop
    from setuptools.command.egg_info import egg_info
    
    def requires( packages ): 
        from os import system
        from sys import executable as PYTHON_PATH
        from pkg_resources import require
        require( "pip" )
        CMD_TMPLT = '"' + PYTHON_PATH + '" -m pip install %s'
        for pkg in packages: system( CMD_TMPLT % (pkg,) )       
    
    class OrderedInstall( install ):
        def run( self ):
            requires( PREREQS )
            install.run( self )        
    
    class OrderedDevelop( develop ):
        def run( self ):
            requires( PREREQS )
            develop.run( self )        
    
    class OrderedEggInfo( egg_info ):
        def run( self ):
            requires( PREREQS )
            egg_info.run( self )        
    
    CMD_CLASSES = { 
         "install" : OrderedInstall
       , "develop" : OrderedDevelop
       , "egg_info": OrderedEggInfo 
    }        
    #-------------------------------------------------
    
    setup ( 
         ...
        install_requires = [ "UNORDERED-INSTALL-PACKAGE" ],
        cmdclass = CMD_CLASSES
    )
    

提交回复
热议问题