Why Typical?#

There are many libaries out there that do some or most of what Typical can do. Why should you pick Typical out of the pack? Here’s a short list:

  1. Simplicity.

    • Typical doesn’t require you to learn a new DSL - all you need to know is how to use Python’s standard type-annotations.
  2. No Metaclasses.

    • Typical doesn’t use metaclasses. We don’t infect your inheritance. When you wrap a class with @typic.al, the class you get is the one you defined. That’s it.
  3. Flexibility.

    • Typical works for you and doesn’t enforce arbitrarily strict rules.
    • Because of an emphasis on simplicity and an aversion to inheritance-mangling, you’re free to use this library as it works for your use-case.
  4. Performance.

  5. Typical is the fastest pure-Python (no Cython!) library out there. Just check out the histograms below. It achieves this performance with finely-tuned code-generation which allows Typical to localize namespaces and minimize branching logic.

Benchmarks#

The following benchmarks Typical’s three public APIs against:

As can be seen, Typical’s three APIs are neck-in-neck with Pydantic, without the need for Cython as a build-dependency, making it far more portable.

Validation Only#

Average time (in μs) for validation of invalid data in
a complex, nested
object.

Average time (in μs) for validation of valid data in a
complex, nested object.

Deserialization & Validation#

Average time (in μs) for attempted deserialization of
invalid data in a complex, nested
object.

Average time (in μs) for deserialization of valid data in a
complex, nested object.

Serialization & Validation#

It should be noted that at the time of this writing, both Pydantic and Marshmallow will passively allow or ignore invalid data in certain cases by default. This was the case with the test-case used for these benchmarks, which can be found here.

Average time (in μs) for attempted serialization of
invalid data in a complex, nested
object.

Average time (in μs) for serialization of valid data in
a complex, nested object.

Translate to an Arbitrary Class#

Typical supports automated translation of one known, custom class to an unknown, unlike other popular libraries.

Average time (in μs) for translation of a known class
to another unknown class a complex, nested
object.

Translate from an Arbitrary Class#

Typical also supports translation from an arbitrary class to a known class. Pydantic supports this feature with the from_orm() method.

Average time (in μs) for translation of a known class
to another unknown class a complex, nested
object.