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

时间:2010-09-14 18:59:51

标签: python distutils

我们采取以下项目布局:

$ 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/*',
          ],
      },
     )

如您所见,我想在package/package/dir/目录中包含所有非Python文件。但是,运行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

是什么给出了?

4 个答案:

答案 0 :(得分:20)

package_data中,您的'*' glob将与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'

答案 1 :(得分:4)

您可以使用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'
          ],
      },
     )

答案 2 :(得分:0)

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

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

的句子

答案 3 :(得分:0)

不太确定原因,但经过一些故障排除后,我意识到重命名名称中有点的目录解决了这个问题。 E.g。

chart.js-2.4.0 => chart_js-2_4_0

注意:我使用的是Python 2.7.10,SetupTools 12.2