Why does “python setup.py sdist” create unwanted “PROJECT-egg.info” in project root directory?

前端 未结 4 818
我在风中等你
我在风中等你 2020-12-15 02:57

When I run

  python setup.py sdist

it creates an sdist in my ./dist directory. This includes a \"PROJECT-egg.info\" file in the zip inside

相关标签:
4条回答
  • 2020-12-15 02:59

    The -egg.info folder isn't always a temporary artifact you can delete.

    For example, if you use pip install -e YOURPACKAGE for an "editable" install (works via symlink like python setup.py develop so you don't have to re-install a package every time you edit it locally), the -egg.info folder is required at runtime when your package is imported in another source. If it doesn't exist, you will get a DistributionNotFound error.

    0 讨论(0)
  • 2020-12-15 03:14

    Note that you can have the PROJECT.egg-info artifacts disappear completely from your sdist.

    The command setup.py egg_info will use the source root as the egg base by default, resulting in the PROJECT.egg-info directory being packaged into the sdist.

    You can configure the egg base by passing the option --egg-base. This will create the PROJECT.egg-info directory somewhere else, leaving it out of your source distribution completely. You might also use a setup.cfg to set that property.

    The following command to create a sdist without a PROJECT.egg-info works for me:

    python setup.py egg_info --egg-base /tmp sdist
    

    Or in a setup.cfg:

    [egg_info]
    egg_base = /tmp
    
    0 讨论(0)
  • 2020-12-15 03:17

    Pythons packaging and build system is broken imho. So there are many hacks and workarounds for things that one would belive work out of the box.

    However, the "cleanest" hack I found for deleting the *.egg-info is using the normal clean --all switch along with the egg_info to place the *.egg-info file in a subfolder that will be cleaned by the clean command. Here an example:

    In your setup.cfg use something like this:

    [egg_info]
    egg_base = ./build/lib
    

    where ./build/lib is a folder that clean --all will delete. Then when building your project with setuptools use the clean command with the --all flag, e.g.

    python setup.py bdist_wheel clean --all

    if you want to build a source bundle as well just make sure to build bdist_wheel before sdist so the build/lib folder exists, e.g.:

    python setup.py bdist_wheel sdist clean --all

    0 讨论(0)
  • 2020-12-15 03:21

    This directory is created intentionally as part of the build process for a source distribution. A little gander at the developer guide for setuptools gives you a hint as to why:

    But, be sure to ignore any part of the distutils documentation that deals with MANIFEST or how it's generated from MANIFEST.in; setuptools shields you from these issues and doesn't work the same way in any case. Unlike the distutils, setuptools regenerates the source distribution manifest file every time you build a source distribution, and it builds it inside the project's .egg-info directory, out of the way of your main project directory. You therefore need not worry about whether it is up-to-date or not.

    You may safely delete the directory after your build has completed.

    Bonus edit:

    I customize the clean command within my setup.py on many of my Python projects to delete *.egg-info, dist, build, and *.pyc and other files. Here's an example of how it's done in setup.py:

    import os
    from setuptools import setup, Command
    
    class CleanCommand(Command):
        """Custom clean command to tidy up the project root."""
        user_options = []
        def initialize_options(self):
            pass
        def finalize_options(self):
            pass
        def run(self):
            os.system('rm -vrf ./build ./dist ./*.pyc ./*.tgz ./*.egg-info')
    
    # Further down when you call setup()
    setup(
        # ... Other setup options
        cmdclass={
            'clean': CleanCommand,
        }
    )
    

    To illustrate, after running python setup.py build on a dummy project called "poop" (Yes, I'm very mature), this happens:

    $ python setup.py build
    running build
    running build_py
    creating build
    creating build/lib
    creating build/lib/poop
    copying poop/__init__.py -> build/lib/poop
    

    And now if we run python setup.py clean:

    $ python setup.py clean
    running clean
    removed `./build/lib/poop/__init__.py'
    removed directory: `./build/lib/poop'
    removed directory: `./build/lib'
    removed directory: `./build'
    

    Tada!

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