Ошибка Python distutils: «[каталог] ... не существует или не является обычным файлом» - PullRequest
25 голосов
/ 14 сентября 2010

Давайте возьмем следующий макет проекта:

$ 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

Что дает?

Ответы [ 4 ]

20 голосов
/ 15 сентября 2010

В вашем package_data ваш '*' глобус будет совпадать с package/dir и попытаться скопировать этот каталог в файл, что приведет к ошибке. Найдите глобус, который не будет соответствовать каталогу package/dir, переписав свой setup.py следующим образом:

from distutils.core import setup

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

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

Учитывая ваш пример, это просто меняет '*' на '*.dat', хотя вам, вероятно, нужно будет улучшить свой глобус больше, просто убедитесь, что он не будет соответствовать 'dir'

4 голосов
/ 05 июля 2011

Вы можете использовать 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'
          ],
      },
     )
0 голосов
/ 26 февраля 2017

Не совсем уверен, почему, но после некоторого устранения неполадок я понял, что переименование каталогов с точками в именах решило проблему. Э.Г.

chart.js-2.4.0 => chart_js-2_4_0

Примечание: я использую Python 2.7.10, SetupTools 12.2

0 голосов
/ 08 декабря 2016

Я создал функцию, которая дает мне все нужные мне файлы

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

И использовал это как arugment для package_data

...