web-dev-qa-db-fra.com

pip installer. crée seulement l'info-dist, pas le paquet

J'essaie de créer un paquet Python que je veux installer en utilisant pip install . localement. Le nom du package est répertorié dans pip freeze, mais import <package> génère une erreur No module named <package>. De plus, le dossier site-packages ne contient qu'un dossier dist-info. find_packages() est capable de trouver des paquets. Qu'est-ce que je rate?

import io
import os
import sys
from shutil import rmtree

from setuptools import find_packages, setup, Command

# Package meta-data.
NAME = '<package>'
DESCRIPTION = 'description'
URL = ''
EMAIL = 'email'
AUTHOR = 'name'

# What packages are required for this module to be executed?
REQUIRED = [
    # 'requests', 'maya', 'records',
]

# The rest you shouldn't have to touch too much :)
# ------------------------------------------------
# Except, perhaps the License and Trove Classifiers!
# If you do change the License, remember to change the Trove Classifier for that!

here = os.path.abspath(os.path.dirname(__file__))



# Where the magic happens:
setup(
    name=NAME,
    #version=about['__version__'],
    description=DESCRIPTION,
    # long_description=long_description,
    author=AUTHOR,
    author_email=EMAIL,
    url=URL,
    packages=find_packages(),
    # If your package is a single module, use this instead of 'packages':
    # py_modules=['mypackage'],

    # entry_points={
    #     'console_scripts': ['mycli=mymodule:cli'],
    # },
    install_requires=REQUIRED,
    include_package_data=True,
    license='MIT',
    classifiers=[
        # Trove classifiers
        # Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers
        'License :: OSI Approved :: MIT License',
        'Programming Language :: Python',
        'Programming Language :: Python :: 2.6',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.3',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
        'Programming Language :: Python :: Implementation :: CPython',
        'Programming Language :: Python :: Implementation :: PyPy'
    ],

)
13
André Betz

Depuis que la question est devenue très populaire, voici les étapes de diagnostic à suivre lorsqu'il vous manque des fichiers après l'installation. Imaginez avoir un exemple de projet avec la structure suivante:

root
├── spam
│   ├── __init__.py
│   ├── data.txt
│   ├── eggs.py
│   └── fizz
│       ├── __init__.py
│       └── buzz.py
├── bacon.py
└── setup.py

Maintenant, je lance pip install ., vérifie que le paquet est installé:

$ pip list
Package    Version
---------- -------
mypkg      0.1    
pip        19.0.1 
setuptools 40.6.3 
wheel      0.32.3 

mais ne voyez ni spam, ni spam/eggs.py ni bacon.py ni spam/fizz/buzz.py dans la liste des fichiers appartenant au package installé:

$ pip show -f mypkg
Name: mypkg
Version: 0.1
...
Files:
  mypkg-0.1.dist-info/DESCRIPTION.rst
  mypkg-0.1.dist-info/INSTALLER
  mypkg-0.1.dist-info/METADATA
  mypkg-0.1.dist-info/RECORD
  mypkg-0.1.dist-info/WHEEL
  mypkg-0.1.dist-info/metadata.json
  mypkg-0.1.dist-info/top_level.txt

Alors que faire maintenant?

Diagnostiquer en inspectant le journal de fabrication de la roue

pip essaiera toujours de créer un fichier .wray et d’installer votre paquet à partir de celui-ci. Nous pouvons examiner le journal pour le processus de construction de la roue si vous réinstallez en mode prolixe. La première étape consiste à désinstaller le package:

$ pip uninstall -y mypkg
...

puis réinstallez-le, mais maintenant avec un argument supplémentaire:

$ pip install . -vvv
...

Maintenant, si j'inspecte le journal:

$ pip install . -vvv | grep 'adding'
  adding 'mypkg-0.1.dist-info/METADATA'
  adding 'mypkg-0.1.dist-info/WHEEL'
  adding 'mypkg-0.1.dist-info/top_level.txt'
  adding 'mypkg-0.1.dist-info/RECORD'

Je remarque qu'aucun fichier du répertoire spam ou bacon.py n'est mentionné nulle part. Cela signifie qu'ils n'étaient tout simplement pas inclus dans le fichier wheel et donc pas installés par pip. Les sources d'erreur les plus courantes sont:

Paquets manquants: vérifiez l'argument packages

Vérifiez que vous avez passé l'argument packages à la fonction d'installation. Vérifiez que vous avez mentionné tous des packages à installer. Les sous-packages ne seront pas collectés automatiquement si seul le package parent est mentionné! Par exemple, dans le script d'installation

from setuptools import setup

setup(
    name='mypkg',
    version='0.1',
    packages=['spam']
)

spam sera installé, mais pas spam.fizz car il s’agit d’un package lui-même et doit être mentionné explicitement. Le réparer:

from setuptools import setup

setup(
    name='mypkg',
    version='0.1',
    packages=['spam', 'spam.fizz']
)

Si vous avez beaucoup de paquets, utilisez setuptools.find_packages pour automatiser le processus:

from setuptools import find_packages, setup

setup(
    name='mypkg',
    version='0.1',
    packages=find_packages()  # will return a list ['spam', 'spam.fizz']
)

Au cas où il vous manque un module:

Modules manquants: vérifiez l'argument py_modules

Dans les exemples ci-dessus, il me manquera bacon.py après l'installation car il n'appartient à aucun package. Je dois fournir son nom de module dans l'argument séparé py_modules:

from setuptools import find_packages, setup

setup(
    name='mypkg',
    version='0.1',
    packages=find_packages(),
    py_modules=['bacon']
)

Fichiers de données manquants: vérifiez l'argument package_data

J'ai tous les fichiers de code source en place maintenant, mais le fichier data.txt n'est toujours pas installé. Les fichiers de données situés sous les répertoires du paquet doivent être ajoutés via l'argument package_data. Correction du script d'installation ci-dessus:

from setuptools import find_packages, setup

setup(
    name='mypkg',
    version='0.1',
    packages=find_packages(),
    package_data={'spam': ['data.txt']},
    py_modules=['bacon']
)

Ne soyez pas tenté d'utiliser l'argument data_files. Placez les fichiers de données sous un paquet et configurez plutôt package_data.

Après avoir corrigé le script d'installation, vérifiez que les fichiers de package sont en place après l'installation

Si je réinstalle maintenant le paquet, je remarquerai que tous les fichiers sont ajoutés à la roue:

$ pip install . -vvv | grep 'adding'
  adding 'bacon.py'
  adding 'spam/__init__.py'
  adding 'spam/data.txt'
  adding 'spam/eggs.py'
  adding 'spam/fizz/__init__.py'
  adding 'spam/fizz/buzz.py'
  adding 'mypkg-0.1.dist-info/METADATA'
  adding 'mypkg-0.1.dist-info/WHEEL'
  adding 'mypkg-0.1.dist-info/top_level.txt'
  adding 'mypkg-0.1.dist-info/RECORD'

Ils seront également visibles dans la liste des fichiers appartenant à mypkg:

$ pip show -f mypkg
Name: mypkg
Version: 0.1
...
Files:
  __pycache__/bacon.cpython-36.pyc
  bacon.py
  mypkg-0.1.dist-info/INSTALLER
  mypkg-0.1.dist-info/METADATA
  mypkg-0.1.dist-info/RECORD
  mypkg-0.1.dist-info/WHEEL
  mypkg-0.1.dist-info/top_level.txt
  spam/__init__.py
  spam/__pycache__/__init__.cpython-36.pyc
  spam/__pycache__/eggs.cpython-36.pyc
  spam/data.txt
  spam/eggs.py
  spam/fizz/__init__.py
  spam/fizz/__pycache__/__init__.cpython-36.pyc
  spam/fizz/__pycache__/buzz.cpython-36.pyc
  spam/fizz/buzz.py
4
hoefling

Si vous utilisez Windows 10+, vous pouvez vous assurer que toutes les installations sont correctes: cliquez sur Démarrer dans le coin inférieur gauche, recherchez cmd.exe, puis cliquez avec le bouton droit de la souris sur "Invite de commande". choisissez "Exécuter en tant qu'administrateur"). Tapez "cd path to your Python 3.X installation". Vous pouvez trouver ce chemin dans l'Explorateur de fichiers (allez dans le dossier où Python est installé), puis en haut. Copiez ceci et mettez-le là où j'ai écrit ci-dessus path to your Python 3.X installation. Une fois que vous avez fait cela et cliqué sur Entrée, tapez "python -m pip install package" (package signifie le paquet que vous souhaitez installer). Votre programme Python devrait maintenant fonctionner parfaitement. 

0
Arnav Poddar