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