Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

An extension to marshmallow to support fast schema (de)multiplexing.

marshmallow is a fantastic library for serialization and deserialization of data. For more on that project see its GitHub page or its Documentation.

This library adds a special kind of schema that actually multiplexes other schemas based on object type. When serializing values, it uses get_obj_type() method to get object type name. Then it uses type_schemas name-to-Schema mapping to get schema for that particular object type, serializes object using that schema and adds an extra field with name of object type. Deserialization is reverse.

Installing

This fork is designed to be a drop‑in replacement for marshmallow-oneofschema.

Using uv:

$ uv add marshmallow-fastoneofschema

Using poetry:

$ poetry add marshmallow-fastoneofschema

pip:

$ pip install marshmallow-fastoneofschema

Note: If marshmallow-oneofschema remains installed alongside this fork, the library logs an error and uses the fast fork. For reliability, uninstall the upstream package to avoid any packaging/order surprises. This wheel also includes a small startup hook (.pth) that redirects imports of marshmallow_oneofschema to the fast fork, even if the upstream was installed later. You can disable this behavior by setting FASTONEOFSCHEMA_DISABLE_PTH=1.

Example

The code below demonstrates how to set up a polymorphic schema. For the full context check out the tests. Once setup the schema should act like any other schema. If it does not then please file an Issue.

import marshmallow
import marshmallow.fields
from marshmallow_fastoneofschema import OneOfSchema


class Foo:
    def __init__(self, foo):
        self.foo = foo


class Bar:
    def __init__(self, bar):
        self.bar = bar


class FooSchema(marshmallow.Schema):
    foo = marshmallow.fields.String(required=True)

    @marshmallow.post_load
    def make_foo(self, data, **kwargs):
        return Foo(**data)


class BarSchema(marshmallow.Schema):
    bar = marshmallow.fields.Integer(required=True)

    @marshmallow.post_load
    def make_bar(self, data, **kwargs):
        return Bar(**data)


class MyUberSchema(OneOfSchema):
    type_schemas = {"foo": FooSchema, "bar": BarSchema}

    def get_obj_type(self, obj):
        if isinstance(obj, Foo):
            return "foo"
        elif isinstance(obj, Bar):
            return "bar"
        else:
            raise Exception("Unknown object type: {}".format(obj.__class__.__name__))


MyUberSchema().dump([Foo(foo="hello"), Bar(bar=123)], many=True)
# => [{'type': 'foo', 'foo': 'hello'}, {'type': 'bar', 'bar': 123}]

MyUberSchema().load(
    [{"type": "foo", "foo": "hello"}, {"type": "bar", "bar": 123}], many=True
)
# => [Foo('hello'), Bar(123)]

By default get_obj_type() returns obj.__class__.__name__, so you can just reuse that to save some typing:

class MyUberSchema(OneOfSchema):
    type_schemas = {"Foo": FooSchema, "Bar": BarSchema}

You can customize type field with type_field class property:

class MyUberSchema(OneOfSchema):
    type_field = "object_type"
    type_schemas = {"Foo": FooSchema, "Bar": BarSchema}


MyUberSchema().dump([Foo(foo="hello"), Bar(bar=123)], many=True)
# => [{'object_type': 'Foo', 'foo': 'hello'}, {'object_type': 'Bar', 'bar': 123}]

You can use resulting schema everywhere marshmallow.Schema can be used, e.g.

import marshmallow as m
import marshmallow.fields as f


class MyOtherSchema(m.Schema):
    items = f.List(f.Nested(MyUberSchema))

License

MIT licensed. See the bundled LICENSE file for more details.

Performance & Compatibility Notes

  • This fork preserves the public API and error shapes of the upstream package.

  • Optimizations avoid unnecessary copies when type_field_remove is False and reduce overhead for many=True in default configurations.

  • Aggressive instance caching can be disabled via FOO_DISABLE_AGGRESSIVE_MODE=1 if needed.

  • Supported Python versions: 3.11+.

DeepFriedMarshmallow Plugin

This fork ships a DFM plugin that can enable JIT inlining for Nested(OneOfSchema) fields.

  • Discovery: via entry point group deepfriedmarshmallow.plugins or env DFM_PLUGINS.

  • Initial scope: Only engages when get_data_type/get_obj_type are default and all type_schemas keys are strings.

  • Fallback: If conditions aren’t met, DFM falls back to its standard generation.

Per‑Schema Controls & Flags

Migration

Basic usage stays the same (plug‑and‑play). For projects that want to migrate explicitly to the new names:

  • Replace dependency marshmallow-oneofschema with this fork.

  • Optionally switch imports to the new package/class names: - from marshmallow_fastoneofschema import FastOneOfSchema - Or keep from marshmallow_oneofschema import OneOfSchema (alias provided). - Existing code continues to work; new names are recommended for clarity.

  • Env flags: - FOO_DISABLE_AGGRESSIVE_MODE=1: disable instance caching. - FOO_CONTEXT_ISOLATION=1: enable per-task schema instance caching (ContextVars).

  • Per-schema overrides via class Meta: fastoneof = {...}: - aggressive_mode: bool - context_isolation: bool

  • Per-request overrides via ContextVars (advanced): - OneOfSchema._foo_aggressive_ctx.set(True|False) - OneOfSchema._foo_isolation_ctx.set(True|False)

Metadata

Release files for marshmallow-fastoneofschema 2025.9.2.1.dev7

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for marshmallow-fastoneofschema 2025.9.2.1.dev7
File Size Uploaded
marshmallow_fastoneofschema-2025.9.2.1.dev7.tar.gz 46.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for marshmallow-fastoneofschema 2025.9.2.1.dev7
File Interpreter ABI Platform
marshmallow_fastoneofschema-2025.9.2.1.dev7-py3-none-any.whl Python 3 none any Details

Total release size: 61.8 kB

Release files / marshmallow_fastoneofschema-2025.9.2.1.dev7.tar.gz

Download URL marshmallow_fastoneofschema-2025.9.2.1.dev7.tar.gz
Size 46.0 kB
Tags Source
SHA-256 checksum
How to use checksums
e0a58c1932edcd04be3ec51e847f10271e4271079e462e1b225494b5198bdca2
BLAKE2b-256 checksum
How to use checksums
7656ce2500f8d71102c31ba09c7c06fe61fa743c447c833e203c9ee686633a56
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2025.

Transparency log

Release files / marshmallow_fastoneofschema-2025.9.2.1.dev7-py3-none-any.whl

Download URL marshmallow_fastoneofschema-2025.9.2.1.dev7-py3-none-any.whl
Size 15.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
41a8614f98c543c0185849bcb9665ff2247f67cb4202eba9e2f8f4e14c4e94f5
BLAKE2b-256 checksum
How to use checksums
406a843917ac434154e96006510828ab9644b81ffe3a99ed02d204ca0c435fbd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2025.

Transparency log
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page