Table of Contents
Using Python in EasyMorph
EasyMorph provides tight integration with Python by means of the "Call Python" action and the "easymorph" Python module that contains low-level bindings for use in Python scripts and is installed automatically with every EasyMorph installation. The action and the module allow:
- Executing a Python script from an EasyMorph workflow
- Obtaining the workflow parameters in the Python script
- Obtaining the input dataset of the "Call Python" action in the Python script
- Returning a result dataset from the Python script as the action's output
- Setting workflow status messages from the Python script
- Monitoring workflow cancellation requests in the script
- Generating EasyMorph warnings
Developing Python scripts for EasyMorph
The "easymorph" Python module can (and should) be used when writing Python scripts outside EasyMorph. The module gracefully handles the absence of a calling EasyMorph workflow, which is convenient for Python development in a standalone IDE. The module provides options for substituting workflow parameters and the input dataset with sample values for development and debugging without EasyMorph.
The "easymorph" module is located in the EasyMorph installation folder. Using the module without EasyMorph requires installing the module with the help of Python Wheels from the subfolder Python\dist
in the EasyMorph installation folder.
Supported Python versions
- 3.11
- 3.12
- 3.13
Limits
The current implementation of Python integration in EasyMorph has the following limits:
Description | Value |
---|---|
Max text string length | 1,073,741,823 characters |
Max rows in a dataset | 536,870,897 rows |
Max columns in a dataset | 100,000 columns |
Max number value* in a dataset cell | 79228162514264337593543950335.0 |
Min number value* in a dataset cell | -79228162514264337593543950335.0 |
* Number values in EasyMorph are 128-bit fixed-point decimals with 28-29 significant digits with or without the decimal point between them. A loss of precision is possible when converting numbers with a long fractional part to/from the popular Python float data type (64-bit floating point, 15 to 17 significant digits).
Sample Python script
- example.py
from datetime import datetime import time, math # Import easymorph module. If the script is started by EasyMorph workflow, import # would automatically read parameters and the input dataset of the Call Python action. # Module does not have to be installed in this case, EasyMorph would make it available # for this script via PYTHONPATH envar. import easymorph as em # EasyMorph module can used directly from command line as well, which we would refer as 'standalone' mode # For standalone usage you would need to either add EasyMorph/Python/modules # to PYTHONPATH or install WHL:` pip install --force-reinstall --no-index --find-links="Python/modules" easymorph ` # (assuming current working dir is EasyMorph installation location) if em.standalone: print("Running in standalone mode; easymorph.input is not available") else: print( f"Running from workflow: {em.input.length=}, {em.input.width=}" ) # print rows & columns counts # Immutable input dataset is provided via easymorph.input. # Simple way to define default dataset for standalone (when em.input is None): src: em.Dataset = ( em.input or em.DatasetBuilder().add_column("count", [1, 2, 3]).to_dataset() ) def build_dataset(): # Build dataset with mixed types and both dict/positional rows ds = ( em.DatasetBuilder().add_rows( [ { "sensor": "S1", "reading": 0.5, "status": "ok", "timestamp": datetime(2025, 1, 1), }, { "sensor": "S2", "reading": None, # 'status' column value is missing, will insert None and report warning # "status": "ok", - uncommenting this will fix the warning "timestamp": None, }, ["S3", 19.8, "ok", datetime(2025, 1, 3)], # positional row ] ) # Columns can be inserted via add_column; values are filled starting from the first row, # rest padded to None. Note that there is a fast path for float arrays. .add_column("last_reported", [1.0, math.nan, 2.0]) ).to_dataset() # Dataset info print("Column names:", [c.name for c in ds.columns]) print("Row count:", ds.length) # Columns can be indexed: c0 = ds.columns[0] # by index cs = ds.columns["sensor"] # by name print("ds.columns[0].name:", c0.name, "ds.columns['sensor'].name:", cs.name) # First value from column 'status' print("ds['status'][0]:", ds.columns["status"][0]) # Rows are convertible to 'dict' print("Last row as dict:", ds.rows[-1].to_dict()) print("Last row [reading] value:", ds.rows[-1]["reading"]) # Read a few values from columns print("sensor[0:2]:", list(cs[0:2])) print("reading[all]:", list(ds.columns["reading"])) # Column view to numbers (non-numbers are converted to NaN). This is the most efficient way to get numeric data. print("Readings as array:", ds.columns["reading"].to_numbers_array()) # Slice rows first_two = ds.rows[:2] print("First two statuses:", [r["status"] for r in first_two]) em.yield_output(ds) # Simple passthrough demo. Note: this is lossy because numbers on the Python side are floats, not decimals def passthrough(): # yield_output is used to set output of the calling action and can be called only once # per script exectution. em.yield_output(None) is allowed to explicitly 'return' empty dataset em.yield_output( src # em.input can be None if the calling action is set to not pass it ) # You can get all workflow parameters by calling em.get_params_as_dict() def show_params(): params = em.get_params_as_dict() or {"placeholder":True} print("Workflow parameters:", params) # return params as dataset em.yield_output(em.DatasetBuilder().add_row(params)) # Shows how to read/write .dset file def file_operations(): ds = em.DatasetBuilder().add_column("count", [1, 2, 3]).to_dataset() # Save a dataset to file and read it back em.save_dataset(ds, "example.dset") em.yield_output( em.read_dataset( "example.dset" ) # returned dataset is immutable just as em.input ) # Shows how cancellation can be handled in long running script def cancellation(timeout=20.0): start_time = time.time() print("- waiting for cancellation (timeout", timeout, "s)") while not em.is_cancellation_requested(): if time.time() - start_time > timeout: raise SystemError("Example script timed out. Expected cancellation.") time.sleep(0.2) # At any point where it is logically appropriate you can check if running workflow # is requesting cancellation. In standalone mode `is_cancellation_requested` returns False. # Script is not required to raise an exception on cancellation: this is simply one way to handle it if em.is_cancellation_requested(): raise RuntimeError("Cancelled") # It is possible to report warnings back to EasyMorp workflow using em.warn function # Up to 128 warnings can be reported. def warnings(): em.warn("First warning") # Unequal column lengths result in a warning issued by DatasetBuilder em.yield_output( em.DatasetBuilder().add_column("id", [1, 2]).add_column("count", [1, 2, 3]).to_dataset() ) # warnings can be reported even after yield_output em.warn("Second warning", show_callsite=False) # this warning will not include call-site information # Note: In version 1.0.0 there is no dedicated from/to_df functions yet. # With glue code (fairly slow) there is a way to convert to/from DataFrame, if needed. def pandas_interop(): import pandas as pd def dataset_to_df(ds: em.Dataset) -> pd.DataFrame: return pd.DataFrame({col.name: list(col) for col in ds.columns}) def dataset_to_df_numeric(ds: em.Dataset) -> pd.DataFrame: # All columns as float, non-numeric -> NaN. # This is much faster option for numeric data return pd.DataFrame({col.name: col.to_numbers_array() for col in ds.columns}) def df_to_dataset(df: pd.DataFrame) -> em.Dataset: b = em.DatasetBuilder() for name, series in df.items(): b.add_column(name, series) return b.to_dataset() src_df = pd.DataFrame( { "C1": [1.0, float("nan"), 3.5], "C2": [3, None, "c"] } ) ds_from_df = df_to_dataset(src_df) df_from_ds = dataset_to_df(ds_from_df) out_ds = df_to_dataset(df_from_ds) em.yield_output(out_ds) def run_example(mode="standalone"): print(f"Running in mode '{mode}'") modes = { "build_dataset": build_dataset, "passthrough": passthrough, "cancellation": cancellation, "file_operations": file_operations, "warnings": warnings, "show_params": show_params, "pandas_interop": pandas_interop, } try: modes[mode]() except KeyError: raise KeyError(f"Unknown mode '{mode}'. Valid modes: {list(modes)}") # In the workflow, parameter 'mode' is expected to be set; otherwise use 'when_standalone' run_example(em.get_param("mode", when_standalone="show_params"))
Public interface
- easymorph.pyi
import collections.abc import numpy import numpy.typing import typing from typing import Any, overload input: None standalone: bool class Column: def __init__(self, *args, **kwargs) -> None: """Initialize self. See help(type(self)) for accurate signature.""" def to_numbers_array(self) -> numpy.typing.NDArray[numpy.float64]: """to_numbers_array(self: easymorph.Column) -> numpy.typing.NDArray[numpy.float64] Returns a copy of the column as an array of floats. Non-numeric values are NaNs. """ def __array__(self) -> numpy.typing.NDArray[numpy.float64]: """__array__(self: easymorph.Column) -> numpy.typing.NDArray[numpy.float64] Returns a copy of the column as an array of floats. Non-numeric values are NaNs. """ @overload def __getitem__(self, arg0: typing.SupportsInt) -> None | str | float | bool: """__getitem__(*args, **kwargs) Overloaded function. 1. __getitem__(self: easymorph.Column, arg0: typing.SupportsInt) -> None | str | float | bool 2. __getitem__(self: easymorph.Column, arg0: slice) -> easymorph.ColumnSliceView """ @overload def __getitem__(self, arg0: slice) -> ColumnSliceView: """__getitem__(*args, **kwargs) Overloaded function. 1. __getitem__(self: easymorph.Column, arg0: typing.SupportsInt) -> None | str | float | bool 2. __getitem__(self: easymorph.Column, arg0: slice) -> easymorph.ColumnSliceView """ def __iter__(self) -> collections.abc.Iterator[None | str | float | bool]: """__iter__(self: easymorph.Column) -> collections.abc.Iterator[None | str | float | bool]""" def __len__(self) -> int: """__len__(self: easymorph.Column) -> int""" @property def name(self) -> str: """(arg0: easymorph.Column) -> str""" class ColumnSliceView: def __init__(self, *args, **kwargs) -> None: """Initialize self. See help(type(self)) for accurate signature.""" def __getitem__(self, arg0: typing.SupportsInt) -> None | str | float | bool: """__getitem__(self: easymorph.ColumnSliceView, arg0: typing.SupportsInt) -> None | str | float | bool""" def __iter__(self) -> collections.abc.Iterator[None | str | float | bool]: """__iter__(self: easymorph.ColumnSliceView) -> collections.abc.Iterator[None | str | float | bool]""" def __len__(self) -> int: """__len__(self: easymorph.ColumnSliceView) -> int""" class ColumnsRange: def __init__(self, *args, **kwargs) -> None: """Initialize self. See help(type(self)) for accurate signature.""" def __contains__(self, arg0: str) -> bool: """__contains__(self: easymorph.ColumnsRange, arg0: str) -> bool""" @overload def __getitem__(self, arg0: typing.SupportsInt) -> Column: """__getitem__(*args, **kwargs) Overloaded function. 1. __getitem__(self: easymorph.ColumnsRange, arg0: typing.SupportsInt) -> easymorph.Column 2. __getitem__(self: easymorph.ColumnsRange, arg0: str) -> easymorph.Column """ @overload def __getitem__(self, arg0: str) -> Column: """__getitem__(*args, **kwargs) Overloaded function. 1. __getitem__(self: easymorph.ColumnsRange, arg0: typing.SupportsInt) -> easymorph.Column 2. __getitem__(self: easymorph.ColumnsRange, arg0: str) -> easymorph.Column """ def __iter__(self) -> collections.abc.Iterator[Column]: """__iter__(self: easymorph.ColumnsRange) -> collections.abc.Iterator[easymorph.Column]""" def __len__(self) -> int: """__len__(self: easymorph.ColumnsRange) -> int""" class Dataset: """Immutable columnar dataset.""" def __init__(self, *args, **kwargs) -> None: """Initialize self. See help(type(self)) for accurate signature.""" @overload def get_cell(self, column: typing.SupportsInt, row: typing.SupportsInt) -> None | str | float | bool: """get_cell(*args, **kwargs) Overloaded function. 1. get_cell(self: easymorph.Dataset, column: typing.SupportsInt, row: typing.SupportsInt) -> None | str | float | bool Get cell data as bool | str | float or None. 2. get_cell(self: easymorph.Dataset, column: str, row: typing.SupportsInt) -> None | str | float | bool Get cell data as bool | str | float or None. """ @overload def get_cell(self, column: str, row: typing.SupportsInt) -> None | str | float | bool: """get_cell(*args, **kwargs) Overloaded function. 1. get_cell(self: easymorph.Dataset, column: typing.SupportsInt, row: typing.SupportsInt) -> None | str | float | bool Get cell data as bool | str | float or None. 2. get_cell(self: easymorph.Dataset, column: str, row: typing.SupportsInt) -> None | str | float | bool Get cell data as bool | str | float or None. """ def get_cell_as_date(self, column: typing.SupportsInt, row: typing.SupportsInt) -> object: """get_cell_as_date(self: easymorph.Dataset, column: typing.SupportsInt, row: typing.SupportsInt) -> object Try converting numeric cell value to datetime. """ @overload def get_cell_as_text(self, column: typing.SupportsInt, row: typing.SupportsInt) -> str: """get_cell_as_text(*args, **kwargs) Overloaded function. 1. get_cell_as_text(self: easymorph.Dataset, column: typing.SupportsInt, row: typing.SupportsInt) -> str Get cell content as text string. 2. get_cell_as_text(self: easymorph.Dataset, column: str, row: typing.SupportsInt) -> str Get cell content as text string. """ @overload def get_cell_as_text(self, column: str, row: typing.SupportsInt) -> str: """get_cell_as_text(*args, **kwargs) Overloaded function. 1. get_cell_as_text(self: easymorph.Dataset, column: typing.SupportsInt, row: typing.SupportsInt) -> str Get cell content as text string. 2. get_cell_as_text(self: easymorph.Dataset, column: str, row: typing.SupportsInt) -> str Get cell content as text string. """ @property def columns(self) -> ColumnsRange: """Column view. (arg0: easymorph.Dataset) -> easymorph.ColumnsRange """ @property def length(self) -> int: """Number of rows. (arg0: easymorph.Dataset) -> int """ @property def rows(self) -> RowsView: """Row view. (arg0: easymorph.Dataset) -> easymorph.RowsView """ @property def width(self) -> int: """Number of columns. (arg0: easymorph.Dataset) -> int """ class DatasetBuilder: """Incrementally builds a columnar Dataset in native memory.""" def __init__(self) -> None: """__init__(self: easymorph.DatasetBuilder) -> None""" @overload def add_column(self, arg0: str, arg1: collections.abc.Iterable) -> DatasetBuilder: """add_column(*args, **kwargs) Overloaded function. 1. add_column(self: easymorph.DatasetBuilder, arg0: str, arg1: collections.abc.Iterable) -> easymorph.DatasetBuilder add_column(name, values) Bulk append rows to specified column. Creates column if it is not found. Notes ----- - This is fastest way to build a dataset. 2. add_column(self: easymorph.DatasetBuilder, arg0: str, arg1: collections.abc.Sequence[typing.SupportsFloat]) -> easymorph.DatasetBuilder add_column(name, values) Bulk append rows to specified column. Creates column if it is not found. Notes ----- - This is fastest way to build a dataset. """ @overload def add_column(self, name, values) -> Any: """add_column(*args, **kwargs) Overloaded function. 1. add_column(self: easymorph.DatasetBuilder, arg0: str, arg1: collections.abc.Iterable) -> easymorph.DatasetBuilder add_column(name, values) Bulk append rows to specified column. Creates column if it is not found. Notes ----- - This is fastest way to build a dataset. 2. add_column(self: easymorph.DatasetBuilder, arg0: str, arg1: collections.abc.Sequence[typing.SupportsFloat]) -> easymorph.DatasetBuilder add_column(name, values) Bulk append rows to specified column. Creates column if it is not found. Notes ----- - This is fastest way to build a dataset. """ @overload def add_column(self, arg0: str, arg1: collections.abc.Sequence[typing.SupportsFloat]) -> DatasetBuilder: """add_column(*args, **kwargs) Overloaded function. 1. add_column(self: easymorph.DatasetBuilder, arg0: str, arg1: collections.abc.Iterable) -> easymorph.DatasetBuilder add_column(name, values) Bulk append rows to specified column. Creates column if it is not found. Notes ----- - This is fastest way to build a dataset. 2. add_column(self: easymorph.DatasetBuilder, arg0: str, arg1: collections.abc.Sequence[typing.SupportsFloat]) -> easymorph.DatasetBuilder add_column(name, values) Bulk append rows to specified column. Creates column if it is not found. Notes ----- - This is fastest way to build a dataset. """ @overload def add_column(self, name, values) -> Any: """add_column(*args, **kwargs) Overloaded function. 1. add_column(self: easymorph.DatasetBuilder, arg0: str, arg1: collections.abc.Iterable) -> easymorph.DatasetBuilder add_column(name, values) Bulk append rows to specified column. Creates column if it is not found. Notes ----- - This is fastest way to build a dataset. 2. add_column(self: easymorph.DatasetBuilder, arg0: str, arg1: collections.abc.Sequence[typing.SupportsFloat]) -> easymorph.DatasetBuilder add_column(name, values) Bulk append rows to specified column. Creates column if it is not found. Notes ----- - This is fastest way to build a dataset. """ @overload def add_columns(self, columns: dict) -> DatasetBuilder: """add_columns(self: easymorph.DatasetBuilder, columns: dict) -> easymorph.DatasetBuilder add_columns(columns) Add several columns in a single call. Parameters ---------- columns : Mapping[str, Iterable[Any] | numpy.ndarray] Dict mapping column names to data. - Fast path: a 1D float64 array. - Otherwise: any iterable of convertible values. Returns ------- DatasetBuilder The builder itself (chainable). Raises ------ TypeError | ValueError When a value cannot be represented as EasyMorph cell type. """ @overload def add_columns(self, columns) -> Any: """add_columns(self: easymorph.DatasetBuilder, columns: dict) -> easymorph.DatasetBuilder add_columns(columns) Add several columns in a single call. Parameters ---------- columns : Mapping[str, Iterable[Any] | numpy.ndarray] Dict mapping column names to data. - Fast path: a 1D float64 array. - Otherwise: any iterable of convertible values. Returns ------- DatasetBuilder The builder itself (chainable). Raises ------ TypeError | ValueError When a value cannot be represented as EasyMorph cell type. """ @overload def add_row(self, record: object) -> DatasetBuilder: """add_row(self: easymorph.DatasetBuilder, record: object) -> easymorph.DatasetBuilder add_row(record) Append a single row. Parameters ---------- record : dict[str, Any] | Sequence[Any] - Mapping: keys become column names; missing columns are padded with empty cells. Extra keys create new columns on the fly. - Sequence: values are written by position; missing tail values are padded. New columns are created when the sequence is longer than the current width. Raises ------ TypeError If *record* is neither a dict nor a sequence. """ @overload def add_row(self, record) -> Any: """add_row(self: easymorph.DatasetBuilder, record: object) -> easymorph.DatasetBuilder add_row(record) Append a single row. Parameters ---------- record : dict[str, Any] | Sequence[Any] - Mapping: keys become column names; missing columns are padded with empty cells. Extra keys create new columns on the fly. - Sequence: values are written by position; missing tail values are padded. New columns are created when the sequence is longer than the current width. Raises ------ TypeError If *record* is neither a dict nor a sequence. """ @overload def add_rows(self, records: collections.abc.Iterable) -> DatasetBuilder: """add_rows(self: easymorph.DatasetBuilder, records: collections.abc.Iterable) -> easymorph.DatasetBuilder add_rows(records) Bulk append rows from any iterable that yields row objects. Parameters ---------- records : Iterable[Any] Objects accepted by add_row. Notes ----- - This is a bit faster than calling `add_row` in a Python loop. """ @overload def add_rows(self, records) -> Any: """add_rows(self: easymorph.DatasetBuilder, records: collections.abc.Iterable) -> easymorph.DatasetBuilder add_rows(records) Bulk append rows from any iterable that yields row objects. Parameters ---------- records : Iterable[Any] Objects accepted by add_row. Notes ----- - This is a bit faster than calling `add_row` in a Python loop. """ @overload def to_dataset(self, reset: bool = ...) -> Dataset: """to_dataset(self: easymorph.DatasetBuilder, reset: bool = True) -> easymorph.Dataset to_dataset(reset=True) Finalize the builder and return an immutable dataset. Parameters ---------- reset : bool, default True Clear the builder after the dataset is created. Returns ------- Dataset Resulting immutable dataset. """ @overload def to_dataset(self, reset=...) -> Any: """to_dataset(self: easymorph.DatasetBuilder, reset: bool = True) -> easymorph.Dataset to_dataset(reset=True) Finalize the builder and return an immutable dataset. Parameters ---------- reset : bool, default True Clear the builder after the dataset is created. Returns ------- Dataset Resulting immutable dataset. """ @property def column_names(self) -> list[str]: """Return a list of all column names. (arg0: easymorph.DatasetBuilder) -> list[str] """ @property def length(self) -> int: """Number of rows. (arg0: easymorph.DatasetBuilder) -> int """ @property def width(self) -> int: """Number of columns. (arg0: easymorph.DatasetBuilder) -> int """ class ErrorValue: """EasyMorph error cell value.""" def __init__(self, arg0: str) -> None: """__init__(self: easymorph.ErrorValue, arg0: str) -> None""" @property def text(self) -> str: """(self: easymorph.ErrorValue) -> str""" class Row: def __init__(self, *args, **kwargs) -> None: """Initialize self. See help(type(self)) for accurate signature.""" def to_dict(self) -> dict: """to_dict(self: easymorph.Row) -> dict""" @overload def __getitem__(self, arg0: typing.SupportsInt) -> None | str | float | bool: """__getitem__(*args, **kwargs) Overloaded function. 1. __getitem__(self: easymorph.Row, arg0: typing.SupportsInt) -> None | str | float | bool 2. __getitem__(self: easymorph.Row, arg0: str) -> None | str | float | bool """ @overload def __getitem__(self, arg0: str) -> None | str | float | bool: """__getitem__(*args, **kwargs) Overloaded function. 1. __getitem__(self: easymorph.Row, arg0: typing.SupportsInt) -> None | str | float | bool 2. __getitem__(self: easymorph.Row, arg0: str) -> None | str | float | bool """ def __len__(self) -> int: """__len__(self: easymorph.Row) -> int""" class RowsView: def __init__(self, *args, **kwargs) -> None: """Initialize self. See help(type(self)) for accurate signature.""" @overload def __getitem__(self, arg0: typing.SupportsInt) -> Row: """__getitem__(*args, **kwargs) Overloaded function. 1. __getitem__(self: easymorph.RowsView, arg0: typing.SupportsInt) -> easymorph.Row 2. __getitem__(self: easymorph.RowsView, arg0: slice) -> easymorph.RowsView """ @overload def __getitem__(self, arg0: slice) -> RowsView: """__getitem__(*args, **kwargs) Overloaded function. 1. __getitem__(self: easymorph.RowsView, arg0: typing.SupportsInt) -> easymorph.Row 2. __getitem__(self: easymorph.RowsView, arg0: slice) -> easymorph.RowsView """ def __iter__(self) -> collections.abc.Iterator[Row]: """__iter__(self: easymorph.RowsView) -> collections.abc.Iterator[easymorph.Row]""" def __len__(self) -> int: """__len__(self: easymorph.RowsView) -> int""" def get_param(key: str, when_standalone: object = ...) -> object: """get_param(key: str, when_standalone: object = None) -> object Get parameter passed from the calling workflow. Optional argument for standalone scripts. """ def get_param_as_date(key: str, when_standalone: object = ...) -> object: """get_param_as_date(key: str, when_standalone: object = None) -> object Return a workflow parameter converted to datetime. Raises if not convertible. Optional argument for standalone scripts. """ def get_params_as_dict(errors_as_values: bool = ...) -> dict: """get_params_as_dict(errors_as_values: bool = False) -> dict Return all workflow parameters as a dict. """ def is_cancellation_requested() -> bool: """is_cancellation_requested() -> bool Return True if the EasyMorph engine requested cancellation; the script should exit soon. """ def number_to_date(arg0: typing.SupportsFloat) -> object: """number_to_date(arg0: typing.SupportsFloat) -> object Convert OADate number to datetime. """ def read_dataset(arg0: str) -> Dataset: """read_dataset(arg0: str) -> easymorph.Dataset Read a dataset from disk. Parameters ---------- fname : str | os.PathLike Path to an EasyMorph .dset file. Returns ------- Dataset Immutable dataset loaded into native memory. Raises ------ RuntimeError | ValueError When the file is not a valid dataset. """ def save_dataset(arg0: Dataset, arg1: str) -> None: """save_dataset(arg0: easymorph.Dataset, arg1: str) -> None Save a dataset to disk. Parameters ---------- output_dset : Dataset Dataset to write. fname : str | os.PathLike Target file path. Raises ------ ValueError If *output_dset* is None. """ def warn(msg: str, show_callsite: bool = ...) -> None: """warn(msg: str, show_callsite: bool = True) -> None Log a warning message to the EasyMorph engine. Parameters ---------- msg : str Warning text. show_callsite : bool, default True Include the call-site line when True. Notes ----- - The message is recorded only in the module's internal warning collection, it's not passed to python's `warnings`. """ @overload def yield_output(arg0: Dataset) -> None: """yield_output(*args, **kwargs) Overloaded function. 1. yield_output(arg0: easymorph.Dataset) -> None Sets the output of calling EasyMorph action. Has no effect in standalone mode. 2. yield_output(arg0: easymorph.DatasetBuilder) -> None Sets the output of calling EasyMorph action. Has no effect in standalone mode. """ @overload def yield_output(arg0: DatasetBuilder) -> None: """yield_output(*args, **kwargs) Overloaded function. 1. yield_output(arg0: easymorph.Dataset) -> None Sets the output of calling EasyMorph action. Has no effect in standalone mode. 2. yield_output(arg0: easymorph.DatasetBuilder) -> None Sets the output of calling EasyMorph action. Has no effect in standalone mode. """