← Home

004. Python Keywords

Reserved words carry fixed meaning

004. Python Keywords

Aryan wants to name a variable type to store the type of a process (daemon, user, kernel). He writes:

type = "daemon"

It runs. But now type no longer refers to the built-in function — he’s shadowed it. Later, type(some_var) crashes with TypeError: 'str' object is not callable.

Some words are reserved as Python keywords and cannot be used as names at all. Others (like type, list, print) are built-ins — technically re-nameable, but breaking them causes subtle bugs that are hard to trace.

Aryan decides to write a small checker for his RAM monitor’s config parser: before accepting a field name from the config file, validate it isn’t a reserved word.


💡 Fun fact: Python 3 has 35 keywords, up from 31 in Python 2 (adding True, False, None as reserved, and later async/await in Python 3.5). The full list lives in keyword.kwlist — you can print it anytime to see them all.

⚠️ Watch out: The tricky category is built-in names like list, type, and print — they are NOT keywords, so Python lets you overwrite them without complaint. Assigning list = 5 silently breaks list literals for the rest of the module.

🤔 Think about it: keyword.iskeyword("print") returns False — yet naming a variable print will break your code. What does that tell you about the difference between a language rule and a convention?

Learning objectives

  • Know what Python keywords are and why they’re reserved
  • Use the keyword module to check for keywords programmatically
  • Distinguish keywords from built-in names

Key concepts

  • keywords
  • reserved words
  • keyword module

Try it

Concept detail

Python reserves ~35 words as keywords: for, while, if, else, elif, def, class, return, import, from, as, with, try, except, finally, raise, pass, break, continue, in, not, is, and, or, True, False, None, lambda, yield, global, nonlocal, del, assert, async, await.

These are syntactic — the parser treats them specially and you CANNOT use them as names. Attempting to do so raises SyntaxError.

Separate from keywords are built-in names: print, len, list, dict, type, range, etc. These are NOT reserved — Python will let you rebind them (type = “daemon” works). But doing so silently breaks the built-in for the rest of the module, causing TypeErrors or NameErrors that are extremely confusing to debug.

The hardcoded list approach in broken_code fails for ‘lambda’, ‘assert’, ‘async’, and ~25 other keywords. keyword.iskeyword() uses Python’s own parser definition, so it is always correct regardless of Python version.

Solution

import keyword

def is_keyword(word):
    return keyword.iskeyword(word)

Tests

def test_for_is_keyword():
    assert is_keyword("for") == True

def test_while_is_keyword():
    assert is_keyword("while") == True

def test_if_is_keyword():
    assert is_keyword("if") == True

def test_class_is_keyword():
    assert is_keyword("class") == True

def test_lambda_is_keyword():
    assert is_keyword("lambda") == True

def test_normal_word_not_keyword():
    assert is_keyword("banana") == False

def test_print_not_keyword():
    assert is_keyword("print") == False

def test_assert_is_keyword():
    assert is_keyword("assert") == True

Resources