Orientation: Running and Reading Python
What Python is, where the interpreter fits in, how indentation replaces braces, and how to read a traceback.
By the end of this lesson, you can
- Distinguish the Python language from CPython, its reference implementation, and the standard library
- Run the same short program from the REPL, as a script file, and via python -m
- Explain why indentation, not braces, marks a block in Python
- Read a traceback bottom-up to find the line and exception that actually caused a failure
Why it matters
βPythonβ usually refers to three different things at once: a language specification, a program that runs it, and a large library that ships alongside it. Keeping those apart early avoids a whole category of confusion later β βis this guaranteed, or does it just happen to work on my machine?β β and getting comfortable running a program three different ways, and reading its tracebacks calmly, makes every lesson after this one faster to work through.
Mental model
Python is a language specification: the grammar, the built-in types, the rules for how code
behaves. CPython is the program β the interpreter β that most people mean when they type
python: it reads your source, compiles it to an internal bytecode form, and executes that
bytecode. Itβs the reference implementation and by far the most common one, but it isnβt the only
one (PyPy and MicroPython exist for different goals). The standard library is the large
collection of ready-to-use modules (json, pathlib, math, and hundreds more) that ships with
every CPython install.
| Layer | Example | Guaranteed by every implementation? |
|---|---|---|
| The Python language | def, for, +, exceptions |
Yes |
| The standard library | json.loads, pathlib.Path |
Yes (it ships with the language) |
| CPython specifics | reference-counted garbage collection | No β a CPython implementation detail |
Worked example: three ways to run the same program
The same short program, run three different ways, produces the same output every time β because it only uses language features, nothing implementation- or environment-specific.
def greet(name: str) -> str:
if name:
return f"Hello, {name}!"
return "Hello, stranger!"
def main() -> None:
print(greet("Ada"))
print(greet(""))
if __name__ == "__main__":
main()Hello, Ada!
Hello, stranger!Running the same file with python3 orientation_and_execution.py, or with py orientation_and_execution.py on Windows, prints the identical two lines β only the launcher
command differs, not the language underneath it.
| Situation | Typical command | Why |
|---|---|---|
| macOS or Linux, system Python | python3 | python is often missing entirely, or still points at an ancient Python 2 install on older systems. |
| Windows | py | The Python Launcher for Windows; py -3.13 picks a specific installed version explicitly. |
| Inside an active virtual environment (any platform) | python | The environment's own interpreter shadows the system one, so the short name is safe and unambiguous there. |
Common mistakes: reading a traceback
Errors are evidence, not failures β and Python hands you a specific, structured report to work from. Suppose the call site had a typo:
def greet(name: str) -> str:
if name:
return f"Hello, {name}!"
return "Hello, stranger!"
print(greett("Ada"))Traceback (most recent call last):
File "orientation_and_execution.py", line 6, in <module>
print(greett("Ada"))
^^^^^^
NameError: name 'greett' is not defined. Did you mean: 'greet'?A NameError means the code was syntactically valid β it parsed and started running β but at the
moment that line executed, no binding named greett existed. Compare that with a mistake the
interpreter catches before running anything at all, such as a missing closing parenthesis: that
raises a SyntaxError, and in that case no line of the file runs, not even ones before the
typo, because the file never became valid Python to begin with.
Check your understanding
Or reveal the answer without checking
Answer:Nothing prints, and no error is raised
def main(): ... only defines the function β it does not run its body. Without a call to main() anywhere, the function is defined and then simply never invoked, and defining an unused function is not an error.
Or reveal the answer without checking
Answer:The call print(greet()) β it's missing the argument the function requires
The exception type and message on the last line is the actual cause: greet() was called without the name argument its definition requires. The line pointed to just above it is exactly where to look β no need to check version or file extension for this kind of error.
Practice: warm-up
Save the worked example above as orientation_and_execution.py. Run it three ways: paste the two
function definitions and the two print(greet(...)) lines into a REPL one block at a time; run it
as a script (python orientation_and_execution.py); and run it as a module from its parent
directory (python -m orientation_and_execution, no .py). Note anything that differs between the
three.
Stuck? Reveal one hint at a time.
Hint 1
In the REPL, you'll need to enter the two function definitions before the print(...) calls reference them β order matters there just like it does top-to-bottom in a file.
Hint 2
python -m looks up the module by name on the Python path rather than by file path, and expects to be run from the directory containing the file (or a directory it can import from) β the .py extension is left off deliberately.
Hint 3
The printed output itself is identical in all three cases: 'Hello, Ada!' followed by 'Hello, stranger!'. The interpreter executing your code is the same program regardless of how you invoked it.
Reveal what to expect from each method
Try the problem yourself before reading this. There is often more than one reasonable approach β treat this as one worked example, not the only correct answer.
REPL (paste definitions, then each print call):
Hello, Ada!
Hello, stranger!
(each printed immediately after its own print(...) line is entered)
python orientation_and_execution.py:
Hello, Ada!
Hello, stranger!
python -m orientation_and_execution (run from the file's own directory):
Hello, Ada!
Hello, stranger!All three produce identical program output. What differs is only the mechanics of how the code reached the interpreter β pasted interactively, read from a file path, or looked up as a module β never the language semantics underneath.
Practice: apply it
Introduce the typo from the traceback example above (greett instead of greet) into your saved
file and run it again.
Or reveal the answer without checking
Answer:NameError, because no binding named 'greett' exists at that point
greett is a perfectly valid identifier syntactically β Python has no way to know it was meant to be greet until it tries to look up that name while running and finds nothing bound to it, which is exactly what NameError reports (the 'Did you mean' suggestion is a helpful hint, not automatic correction).
Modification challenge: fix the typo, then add a third call, print(greet(42)). Predict what
happens before running it β name: str is a type hint, not an enforced constraint at runtime, so
nothing stops you from passing an int.
Summary
- βPythonβ is the language; CPython is the interpreter most people run; the standard library ships alongside CPython. Content on this site labels which of these a claim depends on.
- The REPL, a script file, and
python -mall run the same language the same way β only how the code reaches the interpreter differs, not what it means once running. - Blocks are marked by indentation, not braces β see Indentation and Blocks for the exact rules.
- A traceback is read bottom-up: the last line names the exception and its message, and the line just above it points at the exact source location β thatβs where the real cause almost always is.
SyntaxError(includingIndentationError) means the file never became valid Python, so nothing in it ran at all;NameError,TypeError, and similar exceptions mean the code parsed fine but something went wrong while it was actually executing.