NameError: name '__file__' is not defined (tested fix)

NameError: name '__file__' is not defined means the code isn't running from a file: a notebook, the REPL, python -c or exec(). We reproduced each case in Python 3.13 and tested a fallback.

1. Code not run from a file

__file__ is set only when Python runs or imports a file. python -c, the interactive prompt, Jupyter notebooks and many IDE "run selection" consoles don't have one:

import subprocess, sys
code = "print(repr(__file__))"
r = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True)
print("python -c:     ", r.stderr.strip().splitlines()[-1])
r = subprocess.run([sys.executable, "-"], input=code, capture_output=True, text=True)
print("python - <stdin:", r.stdout.strip())

Output:

python -c:      NameError: name '__file__' is not defined. Did you mean: '__name__'?
python - <stdin: '<stdin>'

Newer versions (3.11 and 3.13 here) add Did you mean: '__name__'?; 3.8 prints the bare message (we ran this block on 3.8, 3.11 and 3.13). The hint is wrong for this case: __name__ is something else. Piped stdin is the odd one out: __file__ exists there but is the string '<stdin>', so os.path.dirname(__file__) is the empty string, and os.path.dirname(os.path.abspath(__file__)) silently gives the working directory instead of failing.

2. exec() with fresh globals

src = "print(__file__)"
try:
    exec(src, {})                       # fresh globals: no __file__
except NameError as e:
    print(type(e).__name__ + ":", e)
exec(src, {"__file__": "/tmp/fake.py"})
exec(src)                               # shares this module's globals

Output:

NameError: name '__file__' is not defined
/tmp/fake.py
/tmp/nf/b2.py

Code run through exec(src, {}) gets an empty namespace. Pass __file__ in the globals dict if the code needs it, or use runpy.run_path(), which sets it for you.

3. Fix: fall back to the working directory

import os
from pathlib import Path
try:
    here = Path(__file__).resolve().parent
except NameError:
    here = Path.cwd()                   # REPL / notebook fallback
print(here)
print(globals().get("__file__", "no __file__"))

Output:

/tmp/nf
/tmp/nf/b3.py

The fallback makes the same code work as a script and in a notebook. In a notebook the working directory is normally the notebook's folder, but that depends on how it was launched, so check Path.cwd() once. We did not run Jupyter for this page.

4. module.__file__ is a different error

import json, sys
print(json.__file__)
try:
    print(sys.__file__)                 # built-in module, compiled into python
except AttributeError as e:
    print(type(e).__name__ + ":", e)

Output:

/usr/lib/python3.13/json/__init__.py
AttributeError: module 'sys' has no attribute '__file__'

Modules compiled into the interpreter, like sys, have no __file__, and the error is an AttributeError, not a NameError. Related: NameError: name is not defined and FileNotFoundError: No such file or directory (often a relative path resolved from the wrong directory).

Frequently asked questions

Why is __file__ not defined in Jupyter?

Notebook cells aren't run from a .py file, so Python never sets __file__. Use Path.cwd() or a try/except NameError fallback.

How do I get the script directory reliably?

Path(__file__).resolve().parent when running from a file; fall back to Path.cwd() when __file__ is missing.

Should I use __name__ as the error suggests?

No. __name__ is the module name ('__main__'), not a path. The suggestion is just a similar-looking name.

Written with AI assistance. Measured on 2026-10-22 on Debian with Python 3.13.5 (block 1 also in the official python:3.8-alpine and python:3.11-alpine images): python -c, piped stdin, exec() with and without globals, a Path.cwd() fallback, and module __file__ attributes. Jupyter was not tested. Every block was run verbatim and its output pasted unedited. PlainHeaders is our extension; Python is free.