setup.py: renaming src package to project name

后端 未结 4 870
青春惊慌失措
青春惊慌失措 2020-12-24 05:39

Let\'s say you have a project called proj and in this project you have the following structure:

proj/
  dists/
  doc/
  src/
    __init__.py
            


        
相关标签:
4条回答
  • 2020-12-24 05:59

    Building on Jfs' Answer, if like me you had a directory structure already established that you didn't want to/couldn't change for other reasons, one solution is to temporary copy all of the code to be packaged and then build that.

    Here's a makefile with targets which copies all the files across in src to a temp location, and then calls setup.py to build the package, before finally cleaning up after itself.

    SRC_DIR='src'
    TEMP_PACKAGE_DIR='your_shiny_package'
    
    package: prepare_package_dir build_package deploy_package remove_package_dir
    
    # I'm using gemfury, your deployment will probably look different
    deploy_package:
        twine upload --repository fury dist/* --verbose
    
    clean_package:
        rm -r dist || echo 'dist removed'
        rm -r ${TEMP_PACKAGE_DIR}.egg-info || echo 'egg-info removed'
    
    build_package: clean_package
        python setup.py sdist
    
    prepare_package_dir:
        mkdir ${TEMP_PACKAGE_DIR}
        cp -R ${SRC_DIR}/* ${TEMP_PACKAGE_DIR}/
        mv ${TEMP_PACKAGE_DIR} ${SRC_DIR}/${TEMP_PACKAGE_DIR}
    
    remove_package_dir:
        rm -rf ${SRC_DIR}/${TEMP_PACKAGE_DIR}
    
    

    and then a setup.py which looks a bit like this:

    
    setup(
        name='your_shiny_package',
        version=version,
        description='some great package...',
        long_description=readme,
        url='https://whereever',
        author='you',
        packages=['src/your_shiny_package'],
        install_requires=parse_all_requirements(),
        zip_safe=False,
        include_package_data=True)
    
    

    Might not be the most efficient, but saves you having to restructure your whole repo permanently.

    Usage: just call make package either as part of your build pipeline or manually.

    0 讨论(0)
  • 2020-12-24 06:01

    This is due to a bug in setuptools reported here: https://github.com/pypa/setuptools/issues/250

    Basically, it does work but not in dev mode. Now on you have 3 solutions:

    • symlink the src package as proj (and ignore it when comitting), it will works out of the box but is dirty
    • change from src to proj
    • create a subdirectory proj in src and use the following options:
    packages=['proj'],
    package_dir={'proj': 'src/proj'},
    
    0 讨论(0)
  • 2020-12-24 06:03

    You could fix it by putting Python package files into proj/ directory:

    proj/
      src/
        proj/
          __init__.py
          xyz.py
          abc.py
      setup.py
    

    And changing setup.py to:

    # ...
    setup(
       name='proj',
       packages=['proj'],
       package_dir={'':'src'}
    )
    

    It is not required by distutils but other tools might expect the parent directory name of __init__.py file to be the same as Python package name i.e., proj in this case.

    0 讨论(0)
  • 2020-12-24 06:12

    You can try adding the src folder to the PYTHONPATH before you call the setup function:

    import sys, os
    src_path = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'src')
    sys.path.append(src_path)
    

    And also, just to be on the safe side, you then change the working directory:

    os.chdir(src_path)
    

    After that, it should all be OK.

    Some other tools for packaging your app support that from within. I thought it was setuptools, turns out it's PyInstaller. But basically, that's what should be done, just enough for your packages to be imported directly.

    Turns out distutils has the package_dir directive. That is what you should use, but it might work by only adding your package to the PYTHONPATH.

    0 讨论(0)
提交回复
热议问题