Skip to content

Parsers

Pipeline

A parser pipeline is a sequence of parser steps that process type annotations to produce Narwhals dtypes.

anyschema.parsers.ParserPipeline

A pipeline of parser steps that tries each parser in sequence.

This allows for composable parsing where multiple parsers can be tried until one successfully handles the type.

Parameters:

Name Type Description Default
steps IntoParserPipeline

Control how parser steps are configured:

  • "auto" (default): Automatically select appropriate parser steps based on installed dependencies.
  • A ParserPipeline instance: Use the pipeline as-is.
  • A sequence of ParserStep instances: Create pipeline with these steps.
'auto'

Raises:

Type Description
TypeError

If the steps are not a sequence of ParserStep instances or a ParserPipeline.

from_auto(steps: ParserStep | Sequence[ParserStep], *more_steps: ParserStep, at_position: int | Literal['auto'] = 'auto') -> Self classmethod

Create an auto pipeline with custom steps efficiently (no copying needed).

Tip

This is the most efficient way to create a pipeline with custom steps when starting from the auto configuration, as it doesn't need to copy the auto pipeline's steps.

Parameters:

Name Type Description Default
steps ParserStep | Sequence[ParserStep]

ParserStep(s) to add to the auto pipeline.

required
*more_steps ParserStep

Additional ParserStep(s) to add, specified as positional arguments.

()
at_position int | Literal['auto']

Position where to insert the step(s). Options:

  • An integer index (can be negative for counting from the end).
  • "auto" (default): Automatically determines the "best" position. The step(s) will be inserted after the last preprocessing step found.
'auto'

Returns:

Type Description
Self

A new ParserPipeline instance with the auto steps and custom steps.

Examples:

>>> from anyschema.parsers import ParserPipeline, ParserStep
>>> import narwhals as nw
>>> from anyschema.typing import FieldConstraints, FieldMetadata, FieldType
>>>
>>> class CustomType: ...
>>>
>>> class CustomParserStep(ParserStep):
...     def parse(
...         self, input_type: FieldType, constraints: FieldConstraints, metadata: FieldMetadata
...     ) -> nw.DType | None:
...         return nw.String() if input_type is CustomType else None
>>>
>>> pipeline = ParserPipeline.from_auto(CustomParserStep())
>>>
>>> # Add multiple custom steps
>>> pipeline = ParserPipeline.from_auto(CustomParserStep(), CustomParserStep())
>>>
>>> pipeline.parse(CustomType, constraints=(), metadata={})
String

parse(input_type: FieldType, constraints: FieldConstraints, metadata: FieldMetadata, *, strict: bool = True) -> DType | None

parse(
    input_type: FieldType,
    constraints: FieldConstraints,
    metadata: FieldMetadata,
    *,
    strict: Literal[True] = True
) -> DType
parse(
    input_type: FieldType,
    constraints: FieldConstraints,
    metadata: FieldMetadata,
    *,
    strict: Literal[False]
) -> DType | None

Try each parser in sequence until one succeeds.

Parameters:

Name Type Description Default
input_type FieldType

The type to parse.

required
constraints FieldConstraints

Constraints associated with the type.

required
metadata FieldMetadata

Custom metadata dictionary.

required
strict bool

Whether or not to raise if unable to parse input_type.

True

Returns:

Type Description
DType | None

A Narwhals DType from the first successful parser, or None if no parser succeeded and strict=False.

parse_into_field(name: str, input_type: FieldType, constraints: FieldConstraints, metadata: FieldMetadata) -> AnyField

Parse a field specification into a AnyField object.

This is the recommended method for parsing field specifications at the top level. It wraps the DType parsing with additional field-level information like nullability, uniqueness, and custom metadata.

The metadata dictionary is populated during parsing (e.g., UnionTypeStep sets {"anyschema": {"nullable": True}} for Optional[T] types), ensuring that forward references are properly evaluated and avoiding code duplication.

Parameters:

Name Type Description Default
name str

The name of the field.

required
input_type FieldType

The type to parse.

required
constraints FieldConstraints

Constraints associated with the type.

required
metadata FieldMetadata

Custom metadata dictionary. This dictionary may be modified during parsing to add field-level metadata like {"anyschema": {"nullable": True}}.

required

Returns:

Type Description
AnyField

A AnyField instance containing the parsed dtype and field-level metadata.

Examples:

>>> from anyschema.parsers import make_pipeline
>>> pipeline = make_pipeline()
>>> field = pipeline.parse_into_field("age", int, (), {})
>>> field
AnyField(name='age', dtype=Int64, nullable=False, unique=False, description=None, metadata={})

With nullable=True metadata:

>>> field = pipeline.parse_into_field("email", str, (), {"anyschema": {"nullable": True}})
>>> field.nullable
True

With Optional type (auto-detected as nullable):

>>> from typing import Optional
>>> field = pipeline.parse_into_field("email", Optional[str], (), {})
>>> field.nullable
True

with_steps(steps: ParserStep | Sequence[ParserStep], *more_steps: ParserStep, at_position: int | Literal['auto'] = 'auto') -> Self

Create a new pipeline with additional parser step(s) inserted at the specified position.

Parameters:

Name Type Description Default
steps ParserStep | Sequence[ParserStep]

ParserStep(s) to add to the pipeline.

required
*more_steps ParserStep

Additional ParserStep(s) to add, specified as positional arguments.

()
at_position int | Literal['auto']

Position where to insert the step(s). Options:

  • An integer index (can be negative for counting from the end).
  • "auto" (default): Automatically determines the "best" position. The step(s) will be inserted after the last preprocessing step found (trying AnnotatedStep, UnionTypeStep, ForwardRefStep in that order), ensuring custom parsers run after type preprocessing but before library-specific or fallback parsers. If no preprocessing steps are found, inserts at the beginning.
'auto'

Returns:

Type Description
Self

A new ParserPipeline instance with the step(s) added at the specified position.

Examples:

>>> from anyschema.parsers import ParserPipeline, ParserStep
>>> import narwhals as nw
>>> from anyschema.typing import FieldConstraints, FieldMetadata, FieldType
>>>
>>> class CustomType: ...
>>>
>>> class CustomParserStep(ParserStep):
...     def parse(
...         self, input_type: FieldType, constraints: FieldConstraints, metadata: FieldMetadata
...     ) -> nw.DType | None:
...         if input_type is CustomType:
...             return nw.String()
...         return None
>>>
>>> pipeline = ParserPipeline("auto")  # Start with auto pipeline
>>>
>>> # Add single custom step
>>> custom_pipeline = pipeline.with_steps(CustomParserStep())
>>>
>>> # Add multiple custom steps at once
>>> custom_pipeline = pipeline.with_steps([CustomParserStep(), CustomParserStep()])
>>>
>>> # Or add at specific position
>>> custom_pipeline = pipeline.with_steps(CustomParserStep(), at_position=0)
>>>
>>> custom_pipeline.parse(CustomType, constraints=(), metadata={})
String

anyschema.parsers.make_pipeline(steps: IntoParserPipeline = 'auto') -> ParserPipeline

Create a ParserPipeline with the specified steps.

Parameters:

Name Type Description Default
steps IntoParserPipeline

Control how parser steps are configured:

  • "auto" (default): Automatically select appropriate parser steps based on installed dependencies.
  • A ParserPipeline instance: Return the pipeline as-is.
  • A sequence of ParserStep instances: Create pipeline with these steps.
'auto'

Returns:

Type Description
ParserPipeline

A ParserPipeline instance with the configured steps.

Examples:

>>> from anyschema.parsers import make_pipeline
>>> from anyschema.parsers import PyTypeStep, UnionTypeStep, AnnotatedStep
>>>
>>> pipeline = make_pipeline(steps=[UnionTypeStep(), AnnotatedStep(), PyTypeStep()])
>>> print(pipeline.steps)
(UnionTypeStep, AnnotatedStep, PyTypeStep)
>>> pipeline = make_pipeline(steps="auto")
>>> print(pipeline.steps)
(ForwardRefStep, UnionTypeStep, ..., PydanticTypeStep, SQLAlchemyTypeStep, PyTypeStep)

Raises:

Type Description
TypeError

If the steps are not a sequence of ParserStep instances or a ParserPipeline.

Parser Steps

Parser steps are the building blocks of the type parsing pipeline. Each step handles specific type patterns.

For more details on how these work together, see the parser steps section in the Architecture guide.

anyschema.parsers.ParserStep

Bases: ABC

Abstract base class for parser steps that convert type annotations to Narwhals dtypes.

This class provides a framework for parsing different types of type annotations and converting them into appropriate Narwhals data types. Each concrete parser implementation handles specific type patterns or annotation styles.

Attributes:

Name Type Description
pipeline ParserPipeline

Property to access the ParserPipeline, raises UnavailablePipelineError if not set.

Raises:

Type Description
UnavailablePipelineError

When accessing pipeline before it's been set.

TypeError

When setting pipeline with an object that's not a ParserPipeline instance.

Note

Subclasses must implement the parse method to define their specific parsing logic.

Examples:

>>> from typing import get_origin, get_args
>>> import narwhals as nw
>>> from anyschema.parsers import ParserPipeline, ParserStep, PyTypeStep
>>> from anyschema.typing import FieldConstraints, FieldMetadata, FieldType
>>>
>>> class CustomType: ...
>>> class CustomList[T]: ...
>>>
>>> class CustomParserStep(ParserStep):
...     def parse(
...         self, input_type: FieldType, constraints: FieldConstraints, metadata: FieldMetadata
...     ) -> DType | None:
...         if input_type is CustomType:
...             return nw.String()
...
...         if get_origin(input_type) is CustomList:
...             inner = get_args(input_type)[0]
...             # Delegate to pipeline for recursion
...             inner_dtype = self.pipeline.parse(inner, constraints=constraints, metadata=metadata)
...             return nw.List(inner_dtype)
...
...         # Return None if we can't handle it
...         return None
>>>
>>> pipeline = ParserPipeline(steps=[CustomParserStep(), PyTypeStep()])
>>> pipeline.parse(CustomType, constraints=(), metadata={})
String
>>> pipeline.parse(CustomList[int], constraints=(), metadata={})
List(Int64)
>>> pipeline.parse(CustomList[str], constraints=(), metadata={})
List(String)

pipeline: ParserPipeline property writable

Property that returns the parser chain instance.

Returns:

Name Type Description
ParserPipeline ParserPipeline

The parser chain object used for parsing operations.

Raises:

Type Description
UnavailablePipelineError

If the parser chain has not been initialized (i.e., _pipeline is None).

clone() -> Self

Create a clone of this parser step without a pipeline reference.

This method creates a shallow copy of the step, preserving any internal state (such as configuration parameters) but resetting the pipeline reference to None. This allows the cloned step to be added to a different pipeline without violating the "pipeline can only be set once" constraint.

Returns:

Type Description
Self

A new instance of the same parser step class with the same configuration

Self

but without a pipeline reference.

Examples:

>>> from anyschema.parsers import ParserPipeline, PyTypeStep
>>>
>>> # Create a step and assign it to a pipeline
>>> step = PyTypeStep()
>>> pipeline1 = ParserPipeline([step])
>>>
>>> # Clone the step to use in another pipeline
>>> cloned_step = step.clone()
>>> pipeline2 = ParserPipeline([cloned_step])
>>>
>>> # Both pipelines work independently
>>> pipeline1.parse(int, (), {})
Int64
>>> pipeline2.parse(int, (), {})
Int64

parse(input_type: FieldType, constraints: FieldConstraints, metadata: FieldMetadata) -> DType | None abstractmethod

Parse a type annotation into a Narwhals dtype.

Parameters:

Name Type Description Default
input_type FieldType

The type to parse (e.g., int, str, list[int], etc.)

required
constraints FieldConstraints

Constraints associated with the type (e.g., Gt, Le from annotated-types)

required
metadata FieldMetadata

Custom metadata dictionary

required

Returns:

Type Description
DType | None

A Narwhals DType if the parser can handle this type, None otherwise.


The following steps are built-in and come dependency-free.

anyschema.parsers.ForwardRefStep

Bases: ParserStep

Parser for ForwardRef types (string annotations and forward references).

This parser handles type annotations that are forward references (ForwardRef), which occur when using string annotations or referencing types before they're defined.

The parser resolves the ForwardRef to the actual type and delegates to the parser chain.

Initialization can be customized by providing a global and local namespace that will be used to evaluate the forward references when resolving the type. The default namespace is built with common types, yet you can override it with your own types.

Parameters:

Name Type Description Default
globalns dict[str, Any] | None

Global namespace for evaluating forward references. Defaults to a namespace with common types.

None
localns Mapping[str, Any] | None

Local namespace for evaluating forward references. Defaults to an empty namespace.

None

parse(input_type: FieldType, constraints: FieldConstraints, metadata: FieldMetadata) -> DType | None

Parse ForwardRef types by resolving them and delegating to the chain.

Parameters:

Name Type Description Default
input_type FieldType

The type to parse (may be a ForwardRef).

required
constraints FieldConstraints

Constraints associated with the type.

required
metadata FieldMetadata

Custom metadata dictionary.

required

Returns:

Type Description
DType | None

A Narwhals DType if this is a ForwardRef that can be resolved, None otherwise.

anyschema.parsers.UnionTypeStep

Bases: ParserStep

Parser for Union types including Optional.

Handles:

  • Union[T, None], T | None, Optional[T]
  • Extracts the non-None type and its metadata for further parsing

parse(input_type: FieldType, constraints: FieldConstraints, metadata: FieldMetadata) -> DType | None

Parse Union types, particularly Optional types.

Parameters:

Name Type Description Default
input_type FieldType

The type to parse.

required
constraints FieldConstraints

Constraints associated with the type (will be preserved and passed through).

required
metadata FieldMetadata

Custom metadata dictionary (will be preserved and passed through).

required

Returns:

Type Description
DType | None

A Narwhals DType by extracting the non-None type and delegating to the chain.

anyschema.parsers.AnnotatedStep

Bases: ParserStep

Parser for typing.Annotated types.

Handles:

  • Annotated[T, metadata...] - extracts the type and metadata for further parsing

parse(input_type: FieldType, constraints: FieldConstraints, metadata: FieldMetadata) -> DType | None

Parse Annotated types by extracting the base type and constraints.

Parameters:

Name Type Description Default
input_type FieldType

The type to parse.

required
constraints FieldConstraints

Constraints associated with the type.

required
metadata FieldMetadata

Custom metadata dictionary.

required

Returns:

Type Description
DType | None

A Narwhals DType by extracting the base type and delegating to the chain.

anyschema.parsers.PyTypeStep

Bases: ParserStep

Parser for Python builtin types.

Handles:

  • int, float, decimal, str, bytes, bool, date, datetime, timedelta, time, object, Enum, Literal
  • generics: list[T], Sequence[T], Iterable[T], tuple[T, ...]
  • dict,Mapping[K, V], and typed dictionaries (TypedDict)

parse(input_type: FieldType, constraints: FieldConstraints, metadata: FieldMetadata) -> DType | None

Parse Python type annotations into Narwhals dtypes.

Parameters:

Name Type Description Default
input_type FieldType

The type to parse.

required
constraints FieldConstraints

Constraints associated with the type.

required
metadata FieldMetadata

Custom metadata dictionary.

required

Returns:

Type Description
DType | None

A Narwhals DType if this parser can handle the type, None otherwise.


anyschema.parsers.annotated_types.AnnotatedTypesStep

Bases: ParserStep

Parser for types with annotated_types metadata.

Handles:

  • Integer constraints (Gt, Ge, Lt, Le, Interval)
  • Type refinement based on metadata
Warning

It requires annotated-types to be installed.

parse(input_type: FieldType, constraints: FieldConstraints, metadata: FieldMetadata) -> DType | None

Parse types with annotated constraints into refined Narwhals dtypes.

Parameters:

Name Type Description Default
input_type FieldType

The type to parse.

required
constraints FieldConstraints

Constraints associated with the type (e.g., Gt, Ge, Lt, Le).

required
metadata FieldMetadata

Custom metadata dictionary (not used in this parser).

required

Returns:

Type Description
DType | None

A Narwhals DType if this parser can refine the type based on constraints, None otherwise.

anyschema.parsers.attrs.AttrsTypeStep

Bases: ParserStep

Parser for attrs-specific types.

Handles:

  • attrs classes (Struct types)
Warning

It requires attrs to be installed.

parse(input_type: FieldType, constraints: FieldConstraints, metadata: FieldMetadata) -> DType | None

Parse attrs-specific types into Narwhals dtypes.

Parameters:

Name Type Description Default
input_type FieldType

The type to parse.

required
constraints FieldConstraints

Constraints associated with the type.

required
metadata FieldMetadata

Custom metadata dictionary.

required

Returns:

Type Description
DType | None

A Narwhals DType if this parser can handle the type, None otherwise.

anyschema.parsers.pydantic.PydanticTypeStep

Bases: ParserStep

Parser for Pydantic-specific types.

Handles:

  • Pydantic datetime types (AwareDatetime, NaiveDatetime, etc.)
  • Pydantic date types (PastDate, FutureDate)
  • Pydantic BaseModel (Struct types)
Warning

It requires pydantic to be installed.

parse(input_type: FieldType, constraints: FieldConstraints, metadata: FieldMetadata) -> DType | None

Parse Pydantic-specific types into Narwhals dtypes.

Parameters:

Name Type Description Default
input_type FieldType

The type to parse.

required
constraints FieldConstraints

Constraints associated with the type.

required
metadata FieldMetadata

Custom metadata dictionary.

required

Returns:

Type Description
DType | None

A Narwhals DType if this parser can handle the type, None otherwise.

anyschema.parsers.sqlalchemy.SQLAlchemyTypeStep

Bases: ParserStep

Parser for SQLAlchemy-specific types.

Handles:

  • SQLAlchemy column types (Integer, String, DateTime, etc.)
  • SQLAlchemy relationship types
  • SQLAlchemy custom types
Warning

It requires sqlalchemy to be installed.

parse(input_type: FieldType, constraints: FieldConstraints, metadata: FieldMetadata) -> DType | None

Parse SQLAlchemy-specific types into Narwhals dtypes.

Parameters:

Name Type Description Default
input_type FieldType

The type to parse.

required
constraints FieldConstraints

Constraints associated with the type.

required
metadata FieldMetadata

Custom metadata dictionary.

required

Returns:

Type Description
DType | None

A Narwhals DType if this parser can handle the type, None otherwise.