Skip to main content

A collection of Python mixins, metaclasses, context managers, utility functions, and CLI tools for building robust, configurable classes.

Project description

mixinforge

PyPI version Python versions License: MIT Downloads Documentation Status Code style: pep8 Docstring Style: Google Ruff

A collection of Python mixins, metaclasses, utility functions, and CLI tools for building robust, configurable classes.

What Is It?

mixinforge is a lightweight library providing four key areas of functionality:

  1. Mixins & Metaclasses — Reusable components for parameter management, cache control, initialization contracts, thread safety, singleton pattern, and pickle prevention
  2. Utility Functions — Tools for JSON serialization, nested collection processing, and dictionary operations
  3. Context Managers — Helpers for temporary state/behavior changes
  4. CLI Tools — Command-line utilities for project analysis and maintenance

Quick Example

Here's an example showing thread safety enforcement:

from mixinforge import SingleThreadEnforcerMixin

class DatabaseConnection(SingleThreadEnforcerMixin):
    def __init__(self, connection_string: str):
        super().__init__()
        self.connection_string = connection_string
        self.connection = self._connect()

    def _connect(self):
        return f"Connected to {self.connection_string}"

    def query(self, sql: str):
        self._restrict_to_single_thread()  # Enforces thread safety
        return f"Executing: {sql}"

# Works fine on the owner thread
db = DatabaseConnection("localhost:5432")
result = db.query("SELECT * FROM users")

# Calling from another thread raises RuntimeError
import threading
threading.Thread(
    target=lambda: db.query("SELECT *")
).start()  # Raises RuntimeError!

Installation

The source code is hosted on GitHub at: https://github.com/pythagoras-dev/mixinforge

Binary installers for the latest released version are available at the Python package index at: https://pypi.org/project/mixinforge

Using uv:

uv add mixinforge

Using pip:

pip install mixinforge

Requirements

  • Python >= 3.11
  • Runtime dependencies:
    • tabulate

For development:

  • pytest (optional)

API Overview

Mixins & Metaclasses

Component Description
ParameterizableMixin Base class for parameterizable objects with JSON serialization
ImmutableMixin Base class for immutable objects with customizable identity keys
ImmutableParameterizableMixin Immutable objects with params-based identity
CacheablePropertiesMixin Auto discovery and invalidation of cached_property
NotPicklableMixin Prevents pickling/unpickling of objects
GuardedInitMeta Strict initialization control with lifecycle hooks
SingleThreadEnforcerMixin Enforces single-threaded execution
SingletonMixin Ensures each subclass has exactly one instance

Utility Functions

Function Description
dumpjs(obj) Serialize object to JSON string
loadjs(js) Deserialize JSON string to object
update_jsparams(js, **updates) Update params in JSON
access_jsparams(js, *names) Extract params from JSON
sort_dict_by_keys(d) Sort dictionary keys alphabetically
flatten_nested_collection(obj) Find atomics in nested collections
find_instances_inside_composite_object(obj, classinfo, deep_search=True) Find instances of type(s) in composite
transform_instances_inside_composite_object(obj, classinfo, fn) Transform instances of type(s) in composite
is_executed_in_notebook() Detect if running in Jupyter/IPython notebook
is_valid_env_name(name) Validate environment variable names
install_package(name, ...) Install a Python package from PyPI at runtime
is_package_installed(name) Check if a Python package is currently installed
uninstall_package(name, ...) Remove a Python package from the environment

Context Managers

Component Description
OutputCapturer Captures stdout, stderr, and logging output while preserving display
OutputSuppressor Suppresses stdout and stderr output by redirecting to /dev/null

CLI Tools

Command Description
mf-get-stats Analyze project metrics and generate reports
mf-clear-cache Remove Python cache files and directories
mf-clear-dist Remove distribution artifacts (dist/ directory)

Mixins & Metaclasses

ParameterizableMixin

A base class for objects with configuration parameters. Enables standardized parameter access and JSON serialization.

Key features:

  • get_params() — Returns all parameters as a dictionary
  • get_default_params() — Class method to get default parameter values from __init__ signature
  • get_essential_params() — Returns only essential configuration parameters
  • get_auxiliary_params() — Returns auxiliary parameters (logging, verbosity, etc.)
  • essential_param_names — Property to specify which parameters are core to the object's identity
  • get_jsparams() — Get parameters as JSON string
  • get_essential_jsparams() / get_auxiliary_jsparams() — Get filtered parameters as JSON
  • Works seamlessly with dumpjs() and loadjs() for full object serialization

ImmutableMixin

A base class for creating immutable objects with customizable identity keys. Provides immutability guarantees through the GuardedInitMeta metaclass and enables value-based hashing and equality.

Key features:

  • identity_key() — Abstract method that subclasses override to define what makes an object unique
  • __hash__ / __eq__ — Implements identity-based hashing and equality using cached identity keys
  • GuardedInitMeta — Uses guarded initialization to prevent hash computation on uninitialized objects
  • __copy__ / __deepcopy__ — Returns self since immutable objects don't need copying
  • Flexible design allows any hashable value as identity key (strings, tuples, JSON, etc.)

ImmutableParameterizableMixin

A mixin combining ParameterizableMixin and ImmutableMixin for creating immutable objects defined by their parameters. Uses JSON-serialized parameters as the identity key.

Key features:

  • Inherits from both ParameterizableMixin and ImmutableMixin
  • Automatically uses JSON-serialized parameters for hashing and equality
  • Enables parameter-based identity for dictionary keys and set membership
  • Combines parameter management with immutability guarantees

CacheablePropertiesMixin

A mixin for managing functools.cached_property attributes with automatic discovery and invalidation across the class hierarchy.

Key methods:

  • _get_all_cached_properties_status() — Check which cached properties are currently cached (returns dict)
  • _get_cached_property_status(name) — Check if a specific property is cached
  • _get_all_cached_properties() — Retrieve all currently cached values
  • _get_cached_property(name) — Get a specific cached value
  • _set_cached_properties(**kwargs) — Manually set cached values (useful for testing/restoration)
  • _invalidate_cache() — Clear all cached properties across the entire class hierarchy
  • _all_cached_properties_names — Property returning all cached property names

Automatically discovers cached properties from all classes in the MRO, including decorator-wrapped properties, making it reliable for complex inheritance structures.

NotPicklableMixin

A mixin that explicitly prevents objects from being pickled or unpickled. Useful for objects that hold non-serializable resources like database connections, file handles, or network sockets.

Raises TypeError on any pickling attempt, providing clear error messages about why serialization is blocked.

GuardedInitMeta

A metaclass that enforces strict initialization control and provides lifecycle hooks. It ensures that _init_finished is False during __init__ and automatically sets it to True afterward, enabling reliable initialization state checks.

Key features:

  • Automatic _init_finished flag management (False during init, True after)
  • __post_init__() hook — Called automatically after __init__ completes
  • __post_setstate__() hook — Called after unpickling when restoring object state
  • Automatic __setstate__ wrapping for proper unpickling behavior
  • Validates _init_finished=False in pickled state to prevent corruption
  • Compatible with ABCMeta for abstract base classes
  • Prevents use with dataclasses (incompatible)
  • Validates single GuardedInitMeta base in multiple inheritance

Enforces initialization contracts and provides clear error messages when contracts are violated, making initialization bugs easier to catch.

SingleThreadEnforcerMixin

A mixin to enforce single-threaded execution with multi-process support. Ensures methods are called only from the thread that first instantiated the object, while automatically supporting process-based parallelism through fork detection.

Key method:

  • _restrict_to_single_thread() — Call this at the start of methods that need thread enforcement

Automatically detects process forks and resets ownership, making it safe for multiprocessing workflows.

SingletonMixin

A mixin for implementing the singleton pattern. Ensures each subclass maintains exactly one instance that is returned on every instantiation attempt.

Useful for classes that should have only a single instance throughout the application lifetime, such as configuration managers or resource coordinators. Each subclass gets its own singleton instance.

Utility Functions

JSON Serialization

mixinforge provides a complete JSON serialization system for Python objects:

  • dumpjs(obj) — Serialize any Python object (including classes, instances, nested structures) to a JSON string
  • loadjs(js) — Deserialize a JSON string back to its original Python object
  • update_jsparams(js, **kwargs) — Modify parameters in serialized JSON without full deserialization
  • access_jsparams(js, *names) — Extract specific parameters from serialized JSON

This system handles complex objects including class hierarchies, __slots__, nested collections, and maintains object identity; it seamlessly integrates with ParameterizableMixin.

Nested Collection Processing

Tools for working with nested data structures:

  • flatten_nested_collection(obj) — Recursively find all atomic-type objects (primitives, strings, etc.) within nested collections (returns iterator)
  • find_instances_inside_composite_object(obj, classinfo, deep_search=True) — Recursively find all instances of the specified type(s) within composite structures (returns iterator). Accepts a single type or tuple of types, like isinstance(). Set deep_search=False to stop traversal at matched instances.
  • transform_instances_inside_composite_object(obj, classinfo, transform_fn) — Transform all instances of the specified type(s) within composite structures, reconstructing the object graph with transformed instances (returns transformed object). Accepts a single type or tuple of types, like isinstance().

These functions handle arbitrary nesting depths and complex object graphs including cyclic references. Each object is visited only once (deduplication by identity), making them safe for graphs with cycles or shared references. Useful for introspection, validation, and structural transformations.

Environment Variable Name Validation

  • is_valid_env_name(name) - Enforces a portable, shell-safe subset of environment variable names (POSIX identifiers).

Dictionary Utilities

  • sort_dict_by_keys(d) — Returns a new dictionary with keys sorted alphabetically, useful for consistent serialization and comparison

Package Management

Tools for runtime package installation, checking, and removal:

  • install_package(package_name, upgrade=False, version=None, use_uv=True, import_name=None, verify_import=True) — Install a Python package from PyPI into the current environment. Supports version pinning, upgrade mode, and handles packages where PyPI name differs from import name (e.g., "Pillow" vs "PIL"). Uses uv by default for speed, falling back to pip when needed.

  • is_package_installed(package_name) — Check if a Python package is currently installed in the environment. Returns True if installed, False otherwise. Handles package name variations (hyphens, underscores, capitalization) through canonicalization.

  • uninstall_package(package_name, use_uv=True, import_name=None, verify_uninstall=True) — Remove a Python package from the current environment. Protects critical package managers (pip, uv) from accidental removal. Verifies complete removal by default.

These functions automatically bootstrap missing package managers and invalidate Python's import caches after operations to ensure the import system reflects filesystem changes.

Context Managers

OutputCapturer

A context manager that simultaneously captures and displays stdout, stderr, and logging output. Uses a "tee" strategy where output is duplicated: sent to both the original destination (for normal display) and to an internal buffer (for storage).

Key features:

  • Captures sys.stdout, sys.stderr, and logging output
  • Preserves normal output behavior (output is still visible in console)
  • get_output() — Retrieve all captured output as a single string
  • Ideal for testing CLI tools or logging execution traces without suppressing output

OutputSuppressor

A context manager that suppresses stdout and stderr by redirecting them to the system null device (os.devnull). Useful for silencing noisy operations in background processes or tests.

Key features:

  • Suppresses both sys.stdout and sys.stderr
  • Uses contextlib.ExitStack for reliable cleanup even on exceptions
  • Automatically restores original streams when exiting the context
  • Ideal for background workers, batch processing, or tests that need silence

CLI Tools

mixinforge provides two command-line tools for project analysis and maintenance.

mf-get-stats

Analyzes Python projects and generates comprehensive code metrics.

Usage:

# Analyze current directory
mf-get-stats

# Analyze specific directory
mf-get-stats /path/to/project

# Specify custom output filename
mf-get-stats --output my_metrics.md

Features:

  • Generates markdown report with detailed statistics:
    • Lines of Code (LOC) and Source Lines of Code (SLOC)
    • Class and function counts
    • File counts
    • Breakdown by main code vs. unit tests
  • Displays formatted summary table in console
  • Auto-updates README.md and Sphinx documentation if special markers are present:
    • <!-- MIXINFORGE_STATS_START --> and <!-- MIXINFORGE_STATS_END --> for markdown
    • .. MIXINFORGE_STATS_START and .. MIXINFORGE_STATS_END for reStructuredText
  • Returns list of updated files for CI/CD integration

This tool is ideal for tracking project growth, maintaining documentation, and integrating metrics into automated workflows.

mf-clear-cache

Removes all Python cache files and directories from a project.

Usage:

# Clean current directory
mf-clear-cache

# Clean specific directory
mf-clear-cache /path/to/project

# Specify custom report filename
mf-clear-cache --output cleanup_report.md

What it removes:

  • __pycache__ directories
  • .pyc and .pyo compiled bytecode files
  • Cache directories from:
    • pytest (.pytest_cache)
    • mypy (.mypy_cache)
    • ruff (.ruff_cache)
    • hypothesis (.hypothesis)
    • tox (.tox)
    • coverage (.coverage, htmlcov)

Generates a detailed markdown report categorizing removed items. Useful for cleaning build artifacts before commits or releases.

mf-clear-dist

Removes distribution artifacts (the dist/ directory) created by build tools.

Usage:

# Clean current directory
mf-clear-dist

# Clean specific directory
mf-clear-dist /path/to/project

What it removes:

  • dist/ directory containing:
    • Source distributions (.tar.gz)
    • Wheel files (.whl)
    • Any other build artifacts

This tool is useful for cleaning up after uv build, python -m build, or similar build commands. It reports the number of files removed and total size freed.

Project Statistics

Metric Main code Unit Tests Total
Lines Of Code (LOC) 4941 12286 17227
Source Lines Of Code (SLOC) 2222 7141 9363
Classes 20 211 231
Functions / Methods 170 1030 1200
Files 27 85 112

Development

License

This project is licensed under the MIT License — see LICENSE for details.

Contact

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mixinforge-0.301.0.tar.gz (340.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mixinforge-0.301.0-py3-none-any.whl (63.9 kB view details)

Uploaded Python 3

File details

Details for the file mixinforge-0.301.0.tar.gz.

File metadata

  • Download URL: mixinforge-0.301.0.tar.gz
  • Upload date:
  • Size: 340.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for mixinforge-0.301.0.tar.gz
Algorithm Hash digest
SHA256 5d6c59a106291ce1c822cfbe1b3c6b472b0973bf03f849800f809e5e5d4eadc2
MD5 50b07df773599faf4ac180db9c75a7aa
BLAKE2b-256 229b804b66ec6e8bb75c216ebb22443de13be590f18bf4a5d48f9155f18a96c0

See more details on using hashes here.

File details

Details for the file mixinforge-0.301.0-py3-none-any.whl.

File metadata

  • Download URL: mixinforge-0.301.0-py3-none-any.whl
  • Upload date:
  • Size: 63.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for mixinforge-0.301.0-py3-none-any.whl
Algorithm Hash digest
SHA256 97063969e4d5914471d0fa266bc638eea7b88b2c0eb7b5229498a1334c6e22bc
MD5 b85d4e76f7b4ab0308aaace48e3c5d43
BLAKE2b-256 9a025645f84131c3c9f4ededbc0b71613871c355cc584e2814a3b3fb1b504800

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page