Skip to content

Add materials for Python Metaclasses - #843

Open
realpython-bot wants to merge 1 commit into
masterfrom
materials/python-metaclasses-20260916
Open

realpython-bot wants to merge 1 commit into
masterfrom
materials/python-metaclasses-20260916

Conversation

@realpython-bot

Copy link
Copy Markdown
Collaborator

This is a NEW folder for a tutorial that never had companion code, so it needs an editorial eye as well as a code review — nothing here can be diffed against a previous version of the folder.

What's here

The tutorial demonstrates everything in the interactive interpreter — it contains no named scripts at all, only pycon blocks. Following the team's instruction, each REPL sequence is collected into a runnable .py file that uses print() so the reader sees the output the article shows. Article order and variable names are preserved, and nothing has been added or "improved".

File Article section
new_style_classes.py Old-Style vs. New-Style Classes → New-Style Classes
type_and_class.py Type and Class
type_with_one_argument.py Defining a Class Dynamically (the one-argument type() intro)
dynamic_class_example_1.py Defining a Class Dynamically → Example 1
dynamic_class_example_2.py Defining a Class Dynamically → Example 2
dynamic_class_example_3.py Defining a Class Dynamically → Example 3
dynamic_class_example_4.py Defining a Class Dynamically → Example 4
custom_new_method.py Custom Metaclasses (assigning a custom __new__() to a normal class)
reassigning_type_new.py Custom Metaclasses (the "Spoiler alert: this doesn't work!" block)
custom_metaclass.py Custom Metaclasses (Meta(type), then Foo/Bar/Qux)
object_factory.py Custom Metaclasses → Object Factory
class_factory.py Custom Metaclasses → Class Factory
simple_inheritance.py Is This Really Necessary? → Simple Inheritance
class_decorator.py Is This Really Necessary? → Class Decorator

Each Example N file keeps both halves the article shows — the dynamic type() definition and the equivalent class statement — one after the other, because the point of those subsections is that the two are equivalent. dynamic_class_example_2.py re-creates Foo with type() at the top, because the article's Example 2 relies on the Foo left over from Example 1 in the same REPL session; the line is commented as such.

reassigning_type_new.py wraps type.__new__ = new in try/except TypeError as ex: print(ex) (the pattern already used in python-mixins/ and python-enum/) so the file runs to completion while still printing the article's error. It prints the article's message verbatim: cannot set '__new__' attribute of immutable type 'type'.

Deliberately not included

The one block in Old-Style vs. New-Style Classes → Old-Style Classes is captured from Python 2.7 (<type 'instance'>). It cannot run on Python 3 and its output cannot be reproduced in this repo, so it is not shipped as a file. Flagging it here rather than skipping it quietly — if the editorial view is that it should ship (e.g. as a commented-out reference), say so and I'll add it.

No requirements.txt

The draft's dependencies field is python==3.14 — stdlib only, no third-party packages — so this folder ships no requirements.txt, matching siblings such as python-namespace/, python-isinstance/ and python-double-underscore/.

How this was verified

  • Built a venv on the article's pin (uv venv --python 3.14, CPython 3.14.6) and executed all 14 scripts. Every one exits 0, and the printed output matches the article block for block. The only differences are the object memory addresses in dynamic_class_example_1.py (<__main__.Foo object at 0x...>), which are per-run by nature.
  • Repo gates at the version the root requirements.txt pins (ruff 0.14.1): uvx ruff@0.14.1 format --check python-metaclasses14 files already formatted; uvx ruff@0.14.1 check python-metaclassesAll checks passed!
  • Nothing in this tutorial needs a server, GUI, or paid API key, so nothing was skipped apart from the Python 2.7 block noted above.
  • git clean -nd and git status --porcelain are both empty; no venv, cache, or generated output is committed.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant