AI Skill Report Card

Using Python Types Module

B+78·Aug 22, 2026·Source: Web
13 / 15
Python
import types # Create a simple namespace object (lightweight alternative to a class) ns = types.SimpleNamespace(x=1, y=2) print(ns.x, ns.y) # 1 2 # Get the type of a function for isinstance checks def f(): pass print(isinstance(f, types.FunctionType)) # True # Dynamically create a new class NewClass = types.new_class("NewClass", (object,))
Recommendation
Add a 'bad outcome' example showing a common mistake (e.g., misusing type() vs new_class(), or mutating MappingProxyType) to satisfy the good/bad examples criterion
12 / 15
  1. Identify the need: dynamic class creation, type-checking against interpreter internals, or lightweight data containers.
  2. Pick the right type/function from types (see reference table below).
  3. Use isinstance/issubclass with types constants instead of guessing types via type(x).__name__.
  4. For dynamic classes, prefer types.new_class() / types.prepare_class() over type() when metaclasses or __init_subclass__/__set_name__ semantics matter.
  5. For generics, use types.GenericAlias and types.UnionType checks when introspecting typing constructs at runtime.
Recommendation
Description could be tightened to lead with primary use case rather than listing four separate trigger scenarios

Dynamic type creation

  • types.new_class(name, bases=(), kwds=None, exec_body=None) — PEP 3115-compliant dynamic class creation.
  • types.prepare_class(name, bases=(), kwds=None) — resolves metaclass and namespace before class body execution.
  • types.resolve_bases(bases) — resolves __mro_entries__ for dynamic bases.

Simple containers

  • types.SimpleNamespace — mutable attribute-holding object, repr()-friendly. Good for quick objects without defining a class.
  • types.MappingProxyType — read-only view over a dict, used to expose immutable-looking mappings (e.g., cls.__dict__).

Callable / function-related types (for isinstance checks)

  • types.FunctionType / types.LambdaType — user-defined functions and lambdas.
  • types.MethodType — bound methods.
  • types.BuiltinFunctionType / types.BuiltinMethodType — C-implemented functions/methods.
  • types.CoroutineType, types.AsyncGeneratorType, types.GeneratorType — for async def, async generators, and generator functions.

Code & module internals

  • types.CodeType — compiled code objects (func.__code__).
  • types.CellType — closure cell objects.
  • types.ModuleType — used to create modules dynamically: mod = types.ModuleType("mymod").
  • types.TracebackType, types.FrameType — for introspecting exceptions/stack frames.

Typing-adjacent runtime types

  • types.GenericAlias — the runtime type of list[int], dict[str, int], etc.
  • types.UnionType — the runtime type of int | str.
  • types.NoneType — canonical way to reference type(None) since Python 3.10.
  • types.EllipsisType, types.NotImplementedType — canonical types for ... and NotImplemented.

Descriptors

  • types.DynamicClassAttribute — like property() but only triggers on instance access, not class access (used internally by Enum).
  • types.MemberDescriptorType, types.GetSetDescriptorType — descriptor types found on slot-based classes.
15 / 20

Example 1: Dynamic module creation Input: Need to create a module object at runtime and populate it. Output:

Python
import types mod = types.ModuleType("config", "Dynamic config module") mod.DEBUG = True mod.VERSION = "1.0" import sys sys.modules["config"] = mod

Example 2: Checking for None type explicitly Input: Want isinstance check equivalent to x is None but usable in a type tuple. Output:

Python
import types def describe(x): if isinstance(x, types.NoneType): return "none" return "value"

Example 3: Read-only dict view Input: Expose internal state as immutable to callers. Output:

Python
import types _data = {"a": 1, "b": 2} public_view = types.MappingProxyType(_data) # public_view["a"] = 5 -> raises TypeError

Example 4: isinstance check for coroutine functions Input: Distinguish a coroutine object from a plain generator. Output:

Python
import types, inspect async def foo(): pass coro = foo() print(isinstance(coro, types.CoroutineType)) # True
Recommendation
Workflow section is somewhat generic/high-level; could include a decision tree or flowchart for choosing between SimpleNamespace, new_class, and typing constructs
  • Prefer types.SimpleNamespace over dict when attribute-style access reads cleaner, but don't overuse it as a class replacement.
  • Use types.MappingProxyType to protect internal dict state instead of returning copies.
  • When checking "is this a function" broadly, remember types.FunctionType doesn't include builtins or methods — combine with types.BuiltinFunctionType/types.MethodType as needed, or use callable() if you just need "can be called".
  • Use types.NoneType, types.EllipsisType, types.NotImplementedType for readability instead of type(None), type(...), type(NotImplemented).
  • Use types.new_class() instead of manually calling type() when the class hierarchy involves __init_subclass__, __set_name__, or non-trivial metaclasses.
  • Don't confuse types.GenericAlias (runtime object for list[int]) with typing.Generic — they serve different layers (runtime container vs. static typing).
  • Don't mutate a types.MappingProxyType — it's read-only by design; mutate the underlying dict instead.
  • Don't assume types.FunctionType covers lambdas separately — types.LambdaType is just an alias for types.FunctionType.
  • Avoid relying on exact types members across major Python versions without checking docs.python.org for the specific version (e.g., 3.16) since some members are added/deprecated over time.
0
Grade B+AI Skill Framework
Scorecard
Criteria Breakdown
Quick Start
13/15
Workflow
12/15
Examples
15/20
Completeness
18/20
Format
13/15
Conciseness
14/15