Python distutils错误:“[目录]。。。不存在或不是常规文件“

2024-05-05 10:20:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我们采用以下项目布局:

$ ls -R .
.:
package  setup.py

./package:
__init__.py  dir  file.dat  module.py

./package/dir:
tool1.dat  tool2.dat

以及setup.py的以下内容:

$ cat setup.py 
from distutils.core import setup


setup(name='pyproj',
      version='0.1',

      packages=[
          'package',
      ],
      package_data={
          'package': [
              '*',
              'dir/*',
          ],
      },
     )

如您所见,我希望将所有非Python文件包含在package/package/dir/目录中。但是,运行setup.py install将引发以下错误:

$ python setup.py install
running install
running build
running build_py
creating build
creating build/lib
creating build/lib/package
copying package/module.py -> build/lib/package
copying package/__init__.py -> build/lib/package
error: can't copy 'package/dir': doesn't exist or not a regular file

给什么?


Tags: install项目pybuildcreatingpackageinitlib
3条回答

您可以使用Distribute而不是distutils。它的工作原理基本相同(在大多数情况下,您不必更改setup.py),它为您提供了exclude_package_data选项:

from distribute_setup import use_setuptools
use_setuptools()

from setuptools import setup

setup(name='pyproj',
      version='0.1',

      packages=[
          'package',
      ],
      package_data={
          'package': [
              '*.dat',
              'dir/*'
          ],
      },
      exclude_package_data={
          'package': [
              'dir'
          ],
      },
     )

我创建了一个函数,它提供了我需要的所有文件

def find_files(directory, strip):
  """
  Using glob patterns in ``package_data`` that matches a directory can
  result in setuptools trying to install that directory as a file and
  the installation to fail.

  This function walks over the contents of *directory* and returns a list
  of only filenames found. The filenames will be stripped of the *strip*
  directory part.
  """

  result = []
  for root, dirs, files in os.walk(directory):
    for filename in files:
      filename = os.path.join(root, filename)
      result.append(os.path.relpath(filename, strip))
  return result

并将其用作package_data的数组

package_data中,您的'*'全局将匹配package/dir本身,并尝试将该目录作为文件复制,从而导致失败。找到一个与目录package/dir不匹配的glob,沿着以下几行重写您的setup.py

from distutils.core import setup

setup(name='pyproj',
      version='0.1',

      packages=[
          'package',
      ],
      package_data={
          'package': [
              '*.dat',
              'dir/*'
          ],
      },
     )

以您的示例为例,这只是将'*'更改为'*.dat',尽管您可能需要对glob进行更多的优化,但请确保它与'dir'不匹配

相关问题 更多 >