できない.dev

Python で「attempted relative import with no known parent package」が解決できない

相対インポートを含むファイルをスクリプトとして直接実行すると、親パッケージを特定できずこのエラーになる。python -m パッケージ.モジュール で実行するか絶対インポートに変える。

公開: 更新:

実行例あり(2026-08-28 に実環境で検証)

要約

ImportError: attempted relative import with no known parent package は、相対インポート(先頭がドットの from . import ...)を、パッケージの一部としてではなく単体スクリプトとして実行したときに出ます。
相対インポートはモジュールの __package__ を起点に親パッケージを辿りますが、ファイルを直接実行すると __main__ 扱いになり起点が空になるため、親パッケージを特定できません。python -m でパッケージとして実行するのが基本の解決策です。

ImportError: attempted relative import with no known parent package

実行例

python:3.12 で python mypkg/main.py のようにパッケージ内のファイルをパス指定で起動すると、attempted relative import with no known parent package が出て終了コード 1 で止まる。
コードを 1 文字も変えずに python -m mypkg.main で起動した場合と、パッケージの外に置いた run.py を入口にした場合は、どちらも helper called を出して 0 で終わる。

$ python --version
Python 3.12.14
$ python mypkg/main.py
Traceback (most recent call last):
  File "/tmp/tmp.RjurFhG5SI/mypkg/main.py", line 1, in <module>
    from .utils import helper
ImportError: attempted relative import with no known parent package
$ echo $?
1
$ python -m mypkg.main
helper called
$ echo $?
0
$ python run.py
helper called
$ echo $?
0

— 2026-08-28 時点の出力

検証環境

検証日
実行環境
python:3.12Debian GNU/Linux 13 (trixie)
バージョン
  • Python 3.12.14
  • Git 2.47.3

この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。

よくある原因

  1. スクリプトとして直接実行: python mypkg/main.py のように単体実行すると、そのファイルは __main__ になり相対インポートの基準を失う。
  2. __init__.py が無い: ディレクトリがパッケージとして認識されず、ドット表記の親を辿れない。
  3. 実行位置とパッケージ構成の不一致: プロジェクトルート以外から実行していて sys.path にルートが入っていない。
  4. エントリポイント自身が相対インポートを使っている: 起動ファイルでドット表記を使うと、起動方法によっては必ず失敗する。

解決策

1. -m でパッケージとして実行する

mypkg/main.py を直接叩くのではなく、プロジェクトルートからモジュール指定で実行します。
これで __package__ が正しく設定され、相対インポートが解決します。

# NG: python mypkg/main.py
python -m mypkg.main

ディレクトリ構成の例です。
各パッケージに __init__.py を置きます。

project/
  mypkg/
    __init__.py
    main.py
    utils.py

2. 絶対インポートに書き換える

ドット表記をやめ、パッケージ名から書く絶対インポートにすると、実行方法に左右されにくくなります。

# from .utils import helper  →
from mypkg.utils import helper

3. エントリポイントを分離する

ライブラリ本体は相対インポートのままにし、起動用のファイルをパッケージの外(または python -m mypkg 用の __main__.py)に置いて、そこからパッケージを呼び出す構成にすると安定します。

この記事は役立ちましたか?