Erreur Python distutils: "[directory] ...n'existe pas ou n'est pas un fichier régulier"

Prenons la mise en page de projet suivante:

$ ls -R .
.:
package  setup.py

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

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

Et le contenu suivant pour setup.py:

$ cat setup.py 
from distutils.core import setup


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

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

Comme vous pouvez le voir, je veux inclure tous les fichiers non-Python dans les répertoires package/ et package/dir/. Cependant, l'exécution de setup.py install provoquerait l'erreur suivante:

$ 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

Qu'est-ce qui donne?

24
demandé sur BuvinJ 2010-09-14 22:59:51

4 réponses

Dans votre package_data, Votre '*' glob correspondra à package/dir lui-même et tentera de copier ce répertoire en tant que Fichier, ce qui entraînera un échec. Trouvez un glob qui ne correspond pas au répertoire package/dir, en réécrivant votre setup.py selon ces lignes:

from distutils.core import setup

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

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

Compte tenu de votre exemple, cela change simplement '*' en '*.dat', bien que vous ayez probablement besoin d'affiner votre glob plus que cela, assurez-vous simplement qu'il ne correspondra pas à 'dir'

19
répondu Jacob Oscarson 2010-09-14 20:34:59

Vous pouvez utiliser Distribuer au lieu de distutils. Cela fonctionne fondamentalement de la même manière (pour la plupart, vous n'aurez pas à changer votre setup.py) et il vous donne l'option 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
répondu mnieber 2011-07-05 07:48:10

J'ai créé une fonction qui me donne tous les fichiers dont j'ai besoin

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

Et utilisé comme roquette pour package_data

0
répondu Niklas R 2016-12-08 04:03:15

Pas tout à fait sûr pourquoi, mais après quelques dépannages, j'ai réalisé que renommer les répertoires qui avaient des points dans leurs noms résolvait le problème. Par exemple

chart.js-2.4.0 => chart_js-2_4_0

Note: j'utilise Python 2.7.10, setuptools 12.2

0
répondu magicrebirth 2017-02-26 19:44:00