Problème d'import avec Typer
Bonjour à tous,
je suis en train de m'amuser à faire une app avec typer et je bloque bêtement sur un import...
La structure de mon paquet:

Le contenu de mon fichier ____init.py____:
__app_name__ = 'my_cli_library'
__version__ = '0.1.0'
Le contenu de mon fichier cli.py:
from typing import Optional
import typer
from library import __app_name__, __version__
app = typer.Typer(no_args_is_help=True)
def _version_callback(value: bool) -> None:
if value:
typer.echo(f'{__app_name__} v{__version__}')
raise typer.Exit()
@app.callback()
def main(
version: Optional[bool] = typer.Option(
None,
'--version',
'-v',
help='Show the application version.',
callback=_version_callback,
is_eager=True,
)
) -> None:
return
if __name__ == '__main__':
app()
Lorsque je lance python cli.py, j'obtiens l'erreur suivante:
from library import __app_name__, __version__
ModuleNotFoundError: No module named 'library'
Merci d'avance! :)
Salut David,
Ahhh les imports, c'est toujours un casse-tête ^^
Il y a plusieurs choses à comprendre ici. Quand tu lances ton script cli.py, Python va ajouter le dossier parent dans ton pythonpath (tu peux t'en rendre compte en faisant un import de sys et un print de sys.path).
Du coup, ton dossier library sera dans ton pythonpath, ce qui te permet d'importer depuis les fichiers contenus à l'intérieur de ce dossier (donc config, datbase, etc).
Mais pas depuis library !
Si je fais un print de mon sys.path ça me donne ça :
['/Users/thibh/Documents/library', '/Library/Frameworks/Python.framework/Versions/3.12/lib/python312.zip', '/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12', '/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages']
Tu vois que le dossier library apparaît bien en premier, donc tu peux importer tout ce qui est à l'intérieur mais library lui-même, non.
Ce que tu peux faire : te déplacer dans le dossier Documents (dans mon cas spécifique ici) et exécuter ton fichier en tant que module (-m) :
cd /Users/thibh/Documents
python3 -m library.cli
Dans ce cas-ci, c'est le dossier Documents qui sera en premier dans le pythonpath et tu pourras donc faire ton from library import __app_name__, __version__. Tu pourrais aussi faire un import relatif avec from . import __app_name__, __version__.
Comme je vois que tu as déjà un fichier __main__.py tu pourrais aussi t'en servir.
Tu aurais quelque chose du genre :
# cli.py
from . import __app_name__, __version__
def app():
print(__app_name__, __version__)
# __main__.py
from .cli import app
if __name__ == "__main__":
app()
Et tu peux ensuite lancer directement ton module library :
python3 -m library
Salut Thibault!
Merci beaucoup pour ta réponse très détaillée!!!
Je vois qu'il y a un vrai boulot à faire sur les imports de mon côté... je croyais avoir compris le concept globalement, mais visiblement pas! Direction donc la doc pour tout reprendre sur ce point!
Par contre, ce qui est étrange, c'est que j'avais déjà testé les imports relatifs, et ça ne fonctionnait pas.
Si je fais un:
# cli.py
from . import __app_name__, __version__
j'obtiens le message d'erreur suivant:
ImportError: attempted relative import with no known parent package
Inscris-toi
(c'est gratuit !)
Tu dois créer un compte pour participer aux discussions.
Créer un compte