web-dev-qa-db-ja.com

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

ご覧のとおり、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

何が得られますか?

26
Santa

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'と一致しないことを確認してください

20
Jacob Oscarson

Distutilsの代わりに Distribute を使用できます。これは基本的に同じように機能し(ほとんどの場合、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'
          ],
      },
     )
4
mnieber

理由はよくわかりませんが、トラブルシューティングを行った結果、名前にドットが含まれているディレクトリの名前を変更すると問題が解決することがわかりました。例えば。

chart.js-2.4.0 => chart_js-2_4_0

注:私はPython 2.7.10、SetupTools 12.2

0
magicrebirth

必要なすべてのファイルを提供する関数を作成しました

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の補強として使用しました

0
Niklas R