# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

""":py:class:`SessionContext` — entry point for running DataFusion queries.

A :py:class:`SessionContext` holds registered tables, catalogs, and
configuration for the current session. It is the first object most programs
create: from it you register data, run SQL strings
(:py:meth:`SessionContext.sql`), read files
(:py:meth:`SessionContext.read_csv`,
:py:meth:`SessionContext.read_parquet`, ...), and construct
:py:class:`~datafusion.dataframe.DataFrame` objects in memory
(:py:meth:`SessionContext.from_pydict`,
:py:meth:`SessionContext.from_arrow`).

Session behavior (memory limits, batch size, configured optimizer passes,
...) is controlled by :py:class:`SessionConfig` and
:py:class:`RuntimeEnvBuilder`; SQL dialect limits are controlled by
:py:class:`SQLOptions`.

Examples:
    >>> ctx = dfn.SessionContext()
    >>> df = ctx.from_pydict({"a": [1, 2, 3]})
    >>> ctx.sql("SELECT 1 AS n").to_pydict()
    {'n': [1]}

See :ref:`user_guide_concepts` in the online documentation for the broader
execution model.
"""

from __future__ import annotations

import uuid
import warnings
from typing import TYPE_CHECKING, Any, NamedTuple, Protocol

try:
    from warnings import deprecated  # Python 3.13+
except ImportError:
    from typing_extensions import deprecated  # Python 3.12


from urllib.parse import urlparse

import pyarrow as pa

from datafusion.catalog import (
    Catalog,
    CatalogList,
    CatalogProviderExportable,
    CatalogProviderList,
    CatalogProviderListExportable,
    TableProviderFactory,
    TableProviderFactoryExportable,
)
from datafusion.dataframe import DataFrame
from datafusion.expr import sort_list_to_raw_sort_list
from datafusion.extensions import (
    PhysicalOptimizerRuleExportable,
    QueryPlannerExportable,
    SessionComponentsExportable,
    SessionExtensionComponents,
    SessionPlannerExportable,
)
from datafusion.options import (
    DEFAULT_MAX_INFER_SCHEMA,
    CsvReadOptions,
    _convert_table_partition_cols,
)
from datafusion.record_batch import RecordBatchStream

from ._internal import RuntimeEnvBuilder as RuntimeEnvBuilderInternal
from ._internal import SessionConfig as SessionConfigInternal
from ._internal import SessionContext as SessionContextInternal
from ._internal import SQLOptions as SQLOptionsInternal
from ._internal import expr as expr_internal

if TYPE_CHECKING:
    import pathlib
    from collections.abc import Iterable, Sequence

    import pandas as pd
    import polars as pl  # type: ignore[import]
    from _typeshed import CapsuleType as _PyCapsule

    from datafusion.catalog import CatalogProvider, Table
    from datafusion.common import DFSchema
    from datafusion.expr import Expr, SortKey
    from datafusion.plan import ExecutionPlan, LogicalPlan
    from datafusion.user_defined import (
        AggregateUDF,
        LogicalExtensionCodecExportable,
        PhysicalExtensionCodecExportable,
        ScalarUDF,
        TableFunction,
        WindowUDF,
    )


class ArrowStreamExportable(Protocol):
    """Type hint for object exporting Arrow C Stream via Arrow PyCapsule Interface.

    https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html
    """

    def __arrow_c_stream__(  # noqa: D105
        self, requested_schema: object | None = None
    ) -> object: ...


class ArrowArrayExportable(Protocol):
    """Type hint for object exporting Arrow C Array via Arrow PyCapsule Interface.

    https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html
    """

    def __arrow_c_array__(  # noqa: D105
        self, requested_schema: object | None = None
    ) -> tuple[object, object]: ...


class TableProviderExportable(Protocol):
    """Type hint for object that has __datafusion_table_provider__ PyCapsule.

    See :ref:`io_custom_table_provider` for registering one, and
    :ref:`extension_providers` for writing one.

    Args:
        session: See
            :py:class:`~datafusion.user_defined.LogicalExtensionCodecExportable`.
            For this getter it is a session when the provider is registered
            through :py:meth:`SessionContext.register_table` and the host's
            logical codec when it goes through
            :py:meth:`datafusion.catalog.Schema.register_table`, so
            duck-typing it is not optional.
    """

    def __datafusion_table_provider__(self, session: Any) -> object: ...  # noqa: D105


class _FunctionKind(NamedTuple):
    """How one kind of declared function is resolved.

    One row per function field on
    :py:class:`~datafusion.extensions.SessionExtensionComponents`, so adding a
    kind is adding a row rather than editing three places. The dataclass
    metadata says which fields are collections to normalize; this table says
    which of them are functions and how to wrap one. Committing is not here:
    each kind is its own ``_commit_extensions`` parameter, so a kind that
    resolves but never commits cannot be written.
    ``test_every_component_field_has_an_installer`` pins the two together.

    The members naming a ``datafusion.user_defined`` object hold its name
    rather than the object: that module imports this one, so the lookups are
    deferred to :py:meth:`SessionContext.with_extensions`, which runs with the
    cycle long settled.
    """

    field: str
    """The ``SessionExtensionComponents`` field a bundle declares these in."""

    wrapper: str
    """Wrapper class a declaration may already be an instance of."""

    getter: str
    """Capsule getter an unwrapped declaration must expose instead."""

    factory: str
    """Helper that turns an unwrapped declaration into a wrapper."""

    label: str
    """What to call this sort of function in an error message."""


_FUNCTION_KINDS = (
    _FunctionKind(
        field="udfs",
        wrapper="ScalarUDF",
        getter="__datafusion_scalar_udf__",
        factory="udf",
        label="scalar function",
    ),
    _FunctionKind(
        field="udafs",
        wrapper="AggregateUDF",
        getter="__datafusion_aggregate_udf__",
        factory="udaf",
        label="aggregate function",
    ),
    _FunctionKind(
        field="udwfs",
        wrapper="WindowUDF",
        getter="__datafusion_window_udf__",
        factory="udwf",
        label="window function",
    ),
)
"""Every kind of function a bundle can declare, in registration order."""


def _reject_repeated_names(
    declared: list[tuple[int, object, Any]],
    kind: str,
) -> list[tuple[int, object, tuple[str, Any]]]:
    """Refuse a name two extensions both declared, for the pair-shaped fields.

    The sibling of the name check in :py:func:`_resolve_declared_functions`,
    for components whose name is given alongside the value rather than read
    off it. Only names declared *in this call* are compared; whether claiming
    one the session already holds is allowed is the component's own business,
    and for tables it is checked when the name is resolved.

    Args:
        declared: ``(position, extension, (name, value))`` triples in
            declaration order, where ``position`` indexes the
            ``with_extensions`` argument list.
        kind: What to call this sort of component in an error.

    Returns:
        ``declared`` unchanged, so this reads as a step rather than a check.

    Raises:
        ValueError: If two declarations claim the same name.
    """
    claimed: dict[str, tuple[int, object]] = {}
    for position, extension, pair in declared:
        name = pair[0]
        if name in claimed:
            # Keyed on position for the same reason as in
            # `_resolve_declared_functions`: the two cases have different
            # remedies, and only one of them is the caller's.
            claimed_at, claimed_by = claimed[name]
            if claimed_at == position:
                msg = (
                    f"{extension!r} declares two {kind}s named {name!r}. "
                    "Registrations have no fall-through, so the second would "
                    "silently replace the first; rename one of them."
                )
            else:
                msg = (
                    f"Two extensions declare a {kind} named {name!r}: "
                    f"argument {claimed_at} ({claimed_by!r}) and argument "
                    f"{position} ({extension!r}). Registrations have no "
                    "fall-through, so one would silently replace the other; "
                    "install them on separate sessions, or drop the repeat if "
                    "one extension was passed twice."
                )
            raise ValueError(msg)
        claimed[name] = (position, extension)
    return declared


def _collect_contributions(
    extensions: tuple[object, ...],
    ctx: SessionContext,
) -> tuple[list[Any], list[Any], dict[str, list[tuple[int, object, Any]]]]:
    """Run every components hook and gather what the extensions contribute.

    Validates the whole argument list before calling anything, so an argument
    that implements neither hook is refused before a well-formed extension
    ahead of it has done any work. Writes nothing to the session.

    Functions are kept paired with the extension that declared them and with
    that extension's position in the argument list, so a name claimed twice can
    name both sides and tell which remedy applies.

    Args:
        extensions: The arguments ``with_extensions`` was given.
        ctx: The context the components are bound against — the receiver, not a
            context derived from it.

    Returns:
        The logical codecs, the physical codecs, and every other declared
        component as ``(position, extension, declaration)`` triples, keyed by
        the ``SessionExtensionComponents`` field they arrived in.

    Raises:
        TypeError: If an argument implements neither hook, or a hook returns
            something other than ``SessionExtensionComponents``.
    """
    for extension in extensions:
        if not isinstance(
            extension, (SessionComponentsExportable, SessionPlannerExportable)
        ):
            msg = (
                "Extension implements neither "
                "__datafusion_session_components__ nor "
                f"__datafusion_session_planner__: {extension!r}"
            )
            raise TypeError(msg)

    logical_codecs: list[LogicalExtensionCodecExportable] = []
    physical_codecs: list[PhysicalExtensionCodecExportable] = []
    declared: dict[str, list[tuple[int, object, Any]]] = {
        kind.field: [] for kind in _FUNCTION_KINDS
    }
    # The rest are not function kinds: tables and table functions are named by
    # the bundle rather than by the value, and rules carry no name at all, so
    # each has its own collision rule -- or none -- and its own installer.
    for field_name in ("udtfs", "table_providers", "physical_optimizer_rules"):
        declared[field_name] = []
    for position, extension in enumerate(extensions):
        if not isinstance(extension, SessionComponentsExportable):
            continue
        components = extension.__datafusion_session_components__(ctx)
        if not isinstance(components, SessionExtensionComponents):
            msg = (
                "__datafusion_session_components__ must return "
                "SessionExtensionComponents, got "
                f"{type(components).__name__} from {extension!r}"
            )
            raise TypeError(msg)
        logical_codecs.extend(components.logical_extension_codecs)
        physical_codecs.extend(components.physical_extension_codecs)
        for field_name, declarations in declared.items():
            declarations.extend(
                (position, extension, item) for item in getattr(components, field_name)
            )
    return logical_codecs, physical_codecs, declared


def _resolve_declared_functions(
    declared: list[tuple[int, object, Any]],
    wrapper: type,
    getter: str,
    factory: Any,
    label: str,
) -> list[Any]:
    """Wrap every function an extension declared, refusing a name claimed twice.

    Runs before anything is written to the session, so a bundle that hands over
    something unusable — or two bundles that both claim a name — fail with
    nothing registered. The name is read off the wrapper rather than off the
    declaration: on the FFI path the capsule reports it, and the constructor
    argument is ignored.

    Args:
        declared: ``(position, extension, function)`` triples in declaration
            order, where ``position`` indexes the ``with_extensions`` argument
            list.
        wrapper: The wrapper class a declaration may already be an instance of,
            in which case it is taken as-is.
        getter: The capsule getter an unwrapped declaration must expose.
        factory: The helper that wraps a declaration — ``udf`` and friends.
        label: What to call this sort of function in an error.

    Returns:
        The wrappers to register, in declaration order.

    Raises:
        TypeError: If a declaration is neither an instance of ``wrapper`` nor
            an object exposing ``getter``.
        ValueError: If two declarations resolve to the same name.
    """
    resolved = []
    claimed: dict[str, tuple[int, object]] = {}
    for position, extension, function in declared:
        if isinstance(function, wrapper):
            wrapped = function
        elif hasattr(function, getter):
            wrapped = factory(function)
        else:
            msg = (
                f"A declared {label} must be {wrapper.__name__} or expose "
                f"{getter}, got {function!r} from {extension!r}"
            )
            raise TypeError(msg)
        name = wrapped.name
        if name in claimed:
            # Keyed on position, not object identity, so each message names
            # the remedy its reader actually has — see
            # `extension_bundles_collisions` in the extension guide.
            claimed_at, claimed_by = claimed[name]
            if claimed_at == position:
                msg = (
                    f"{extension!r} declares two {label}s named {name!r}. "
                    "Registrations have no fall-through, so the second would "
                    "silently replace the first; rename one of them."
                )
            else:
                msg = (
                    f"Two extensions declare a {label} named {name!r}: "
                    f"argument {claimed_at} ({claimed_by!r}) and argument "
                    f"{position} ({extension!r}). Registrations have no "
                    "fall-through, so one would silently replace the other; "
                    "install them on separate sessions, or drop the repeat if "
                    "one extension was passed twice."
                )
            raise ValueError(msg)
        claimed[name] = (position, extension)
        resolved.append(wrapped)
    return resolved


def _resolve_declared_rules(
    declared: list[tuple[int, object, Any]], resolve: Any
) -> Any:
    """Import the capsule of every physical optimizer rule an extension declared.

    There is no name to check — rules accumulate — so unlike
    :py:func:`_resolve_declared_functions` this only refuses a declaration that
    cannot be a rule. The getter is looked for here rather than left to the
    importer so that the error names the bundle that declared it; a caller who
    passed four bundles cannot otherwise tell which one is at fault.

    Args:
        declared: ``(position, extension, rule)`` triples in declaration order.
        resolve: The primitive that imports a list of rules at once, returning
            an opaque object for the commit step.

    Returns:
        The imported rules, opaque, in declaration order.

    Raises:
        TypeError: If a declaration does not expose
            ``__datafusion_physical_optimizer_rule__``.
    """
    for _, extension, rule in declared:
        if not hasattr(rule, "__datafusion_physical_optimizer_rule__"):
            msg = (
                "A declared optimizer rule must expose "
                f"__datafusion_physical_optimizer_rule__, got {rule!r} "
                f"from {extension!r}"
            )
            raise TypeError(msg)
    return resolve([rule for _, _, rule in declared])


class SessionConfig:
    """Session configuration options."""

    def __init__(self, config_options: dict[str, str] | None = None) -> None:
        """Create a new :py:class:`SessionConfig` with the given configuration options.

        Each entry is applied as though passed to :py:meth:`set`, so the same
        keys are rejected. See :ref:`configuration`.

        Args:
            config_options: Options to apply, keyed by fully qualified name.

        Raises:
            ValueError: If a key names no known option, or a value does not
                parse as that option's declared type. Which of several bad
                entries is reported is not defined.

        Example usage:

        >>> from datafusion import SessionConfig, SessionContext
        >>> ctx = SessionContext(SessionConfig())
        >>> config = SessionConfig(
        ...     config_options={"datafusion.execution.batch_size": "1024"}
        ... )
        >>> ctx = SessionContext(config.with_information_schema(True))
        >>> ctx.sql(
        ...     "select value from information_schema.df_settings"
        ...     " where name = 'datafusion.execution.batch_size'"
        ... ).collect()[0]["value"][0]
        <pyarrow.StringScalar: '1024'>
        """
        self.config_internal = SessionConfigInternal(config_options)

    def with_create_default_catalog_and_schema(
        self, enabled: bool = True
    ) -> SessionConfig:
        """Control if the default catalog and schema will be automatically created.

        Args:
            enabled: Whether the default catalog and schema will be
                automatically created.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = (
            self.config_internal.with_create_default_catalog_and_schema(enabled)
        )
        return self

    def with_default_catalog_and_schema(
        self, catalog: str, schema: str
    ) -> SessionConfig:
        """Select a name for the default catalog and schema.

        Args:
            catalog: Catalog name.
            schema: Schema name.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_default_catalog_and_schema(
            catalog, schema
        )
        return self

    def with_information_schema(self, enabled: bool = True) -> SessionConfig:
        """Enable or disable the inclusion of ``information_schema`` virtual tables.

        Args:
            enabled: Whether to include ``information_schema`` virtual tables.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_information_schema(enabled)
        return self

    def with_batch_size(self, batch_size: int) -> SessionConfig:
        """Customize batch size.

        Args:
            batch_size: Batch size.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_batch_size(batch_size)
        return self

    def with_target_partitions(self, target_partitions: int) -> SessionConfig:
        """Customize the number of target partitions for query execution.

        Increasing partitions can increase concurrency.

        Args:
            target_partitions: Number of target partitions.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_target_partitions(
            target_partitions
        )
        return self

    def with_repartition_aggregations(self, enabled: bool = True) -> SessionConfig:
        """Enable or disable the use of repartitioning for aggregations.

        Enabling this improves parallelism.

        Args:
            enabled: Whether to use repartitioning for aggregations.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_repartition_aggregations(
            enabled
        )
        return self

    def with_repartition_joins(self, enabled: bool = True) -> SessionConfig:
        """Enable or disable the use of repartitioning for joins to improve parallelism.

        Args:
            enabled: Whether to use repartitioning for joins.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_repartition_joins(enabled)
        return self

    def with_repartition_windows(self, enabled: bool = True) -> SessionConfig:
        """Enable or disable the use of repartitioning for window functions.

        This may improve parallelism.

        Args:
            enabled: Whether to use repartitioning for window functions.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_repartition_windows(enabled)
        return self

    def with_repartition_sorts(self, enabled: bool = True) -> SessionConfig:
        """Enable or disable the use of repartitioning for window functions.

        This may improve parallelism.

        Args:
            enabled: Whether to use repartitioning for window functions.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_repartition_sorts(enabled)
        return self

    def with_repartition_file_scans(self, enabled: bool = True) -> SessionConfig:
        """Enable or disable the use of repartitioning for file scans.

        Args:
            enabled: Whether to use repartitioning for file scans.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_repartition_file_scans(enabled)
        return self

    def with_repartition_file_min_size(self, size: int) -> SessionConfig:
        """Set minimum file range size for repartitioning scans.

        Args:
            size: Minimum file range size.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_repartition_file_min_size(size)
        return self

    def with_parquet_pruning(self, enabled: bool = True) -> SessionConfig:
        """Enable or disable the use of pruning predicate for parquet readers.

        Pruning predicates will enable the reader to skip row groups.

        Args:
            enabled: Whether to use pruning predicate for parquet readers.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_parquet_pruning(enabled)
        return self

    def set(self, key: str, value: str) -> SessionConfig:
        """Set a configuration option by its fully qualified key.

        Not every key that ``information_schema.df_settings`` lists can be set
        here: the ``datafusion.runtime.*`` entries come from the runtime
        environment rather than from the session config. See
        :ref:`configuration`.

        Args:
            key: Option key including its namespace, such as
                ``datafusion.execution.batch_size``.
            value: Option value as a string, parsed according to the type the
                option declares.

        Returns:
            This :py:class:`SessionConfig`, modified in place, so that calls
            chain.

        Raises:
            ValueError: If ``key`` names no known option, or if ``value`` does
                not parse as that option's declared type.

        Example usage:

        >>> from datafusion import SessionConfig, SessionContext
        >>> config = SessionConfig().set("datafusion.execution.batch_size", "1024")
        >>> ctx = SessionContext(config.with_information_schema(True))
        >>> ctx.sql(
        ...     "select value from information_schema.df_settings"
        ...     " where name = 'datafusion.execution.batch_size'"
        ... ).collect()[0]["value"][0]
        <pyarrow.StringScalar: '1024'>
        """
        self.config_internal = self.config_internal.set(key, value)
        return self

    def with_extension(self, extension: Any) -> SessionConfig:
        """Create a new configuration using an extension.

        Args:
            extension: A custom configuration extension object. These are
            shared from another DataFusion extension library.

        Returns:
            A new :py:class:`SessionConfig` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_extension(extension)
        return self


class RuntimeEnvBuilder:
    """Runtime configuration options."""

    def __init__(self) -> None:
        """Create a new :py:class:`RuntimeEnvBuilder` with default values."""
        self.config_internal = RuntimeEnvBuilderInternal()

    def with_disk_manager_disabled(self) -> RuntimeEnvBuilder:
        """Disable the disk manager, attempts to create temporary files will error.

        Returns:
            A new :py:class:`RuntimeEnvBuilder` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_disk_manager_disabled()
        return self

    def with_disk_manager_os(self) -> RuntimeEnvBuilder:
        """Use the operating system's temporary directory for disk manager.

        Returns:
            A new :py:class:`RuntimeEnvBuilder` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_disk_manager_os()
        return self

    def with_disk_manager_specified(
        self, *paths: str | pathlib.Path
    ) -> RuntimeEnvBuilder:
        """Use the specified paths for the disk manager's temporary files.

        Args:
            paths: Paths to use for the disk manager's temporary files.

        Returns:
            A new :py:class:`RuntimeEnvBuilder` object with the updated setting.
        """
        paths_list = [str(p) for p in paths]
        self.config_internal = self.config_internal.with_disk_manager_specified(
            paths_list
        )
        return self

    def with_unbounded_memory_pool(self) -> RuntimeEnvBuilder:
        """Use an unbounded memory pool.

        Returns:
            A new :py:class:`RuntimeEnvBuilder` object with the updated setting.
        """
        self.config_internal = self.config_internal.with_unbounded_memory_pool()
        return self

    def with_fair_spill_pool(self, size: int) -> RuntimeEnvBuilder:
        """Use a fair spill pool with the specified size.

        This pool works best when you know beforehand the query has multiple spillable
        operators that will likely all need to spill. Sometimes it will cause spills
        even when there was sufficient memory (reserved for other operators) to avoid
        doing so::

            ┌───────────────────────z──────────────────────z───────────────┐
            │                       z                      z               │
            │                       z                      z               │
            │       Spillable       z       Unspillable    z     Free      │
            │        Memory         z        Memory        z    Memory     │
            │                       z                      z               │
            │                       z                      z               │
            └───────────────────────z──────────────────────z───────────────┘

        Args:
            size: Size of the memory pool in bytes.

        Returns:
            A new :py:class:`RuntimeEnvBuilder` object with the updated setting.

        Examples:
            >>> config = dfn.RuntimeEnvBuilder().with_fair_spill_pool(1024)
        """
        self.config_internal = self.config_internal.with_fair_spill_pool(size)
        return self

    def with_greedy_memory_pool(self, size: int) -> RuntimeEnvBuilder:
        """Use a greedy memory pool with the specified size.

        This pool works well for queries that do not need to spill or have a single
        spillable operator. See :py:func:`with_fair_spill_pool` if there are
        multiple spillable operators that all will spill.

        Args:
            size: Size of the memory pool in bytes.

        Returns:
            A new :py:class:`RuntimeEnvBuilder` object with the updated setting.

        Examples:
            >>> config = dfn.RuntimeEnvBuilder().with_greedy_memory_pool(1024)
        """
        self.config_internal = self.config_internal.with_greedy_memory_pool(size)
        return self

    def with_temp_file_path(self, path: str | pathlib.Path) -> RuntimeEnvBuilder:
        """Use the specified path to create any needed temporary files.

        Args:
            path: Path to use for temporary files.

        Returns:
            A new :py:class:`RuntimeEnvBuilder` object with the updated setting.

        Examples:
            >>> config = dfn.RuntimeEnvBuilder().with_temp_file_path("/tmp")
        """
        self.config_internal = self.config_internal.with_temp_file_path(str(path))
        return self


class SQLOptions:
    """Options to be used when performing SQL queries."""

    def __init__(self) -> None:
        """Create a new :py:class:`SQLOptions` with default values.

        The default values are:
        - DDL commands are allowed
        - DML commands are allowed
        - Statements are allowed
        """
        self.options_internal = SQLOptionsInternal()

    def with_allow_ddl(self, allow: bool = True) -> SQLOptions:
        """Should DDL (Data Definition Language) commands be run?

        Examples of DDL commands include ``CREATE TABLE`` and ``DROP TABLE``.

        Args:
            allow: Allow DDL commands to be run.

        Returns:
            A new :py:class:`SQLOptions` object with the updated setting.

        Examples:
            >>> options = dfn.SQLOptions().with_allow_ddl(True)
        """
        self.options_internal = self.options_internal.with_allow_ddl(allow)
        return self

    def with_allow_dml(self, allow: bool = True) -> SQLOptions:
        """Should DML (Data Manipulation Language) commands be run?

        Examples of DML commands include ``INSERT INTO`` and ``DELETE``.

        Args:
            allow: Allow DML commands to be run.

        Returns:
            A new :py:class:`SQLOptions` object with the updated setting.

        Examples:
            >>> options = dfn.SQLOptions().with_allow_dml(True)
        """
        self.options_internal = self.options_internal.with_allow_dml(allow)
        return self

    def with_allow_statements(self, allow: bool = True) -> SQLOptions:
        """Should statements such as ``SET VARIABLE`` and ``BEGIN TRANSACTION`` be run?

        Args:
            allow: Allow statements to be run.

        Returns:
            A new :py:class:SQLOptions` object with the updated setting.

        Examples:
            >>> options = dfn.SQLOptions().with_allow_statements(True)
        """
        self.options_internal = self.options_internal.with_allow_statements(allow)
        return self


class SessionContext:
    """This is the main interface for executing queries and creating DataFrames.

    See :ref:`user_guide_concepts` in the online documentation for more information.

    **A context is a handle on a session, not the session itself.** The
    ``with_*`` methods — :py:meth:`with_logical_extension_codec`,
    :py:meth:`with_physical_extension_codec`,
    :py:meth:`with_python_udf_inlining`, and :py:meth:`with_extensions` —
    return a new context wrapping the *same* underlying session. Only the
    Python-side codec settings differ; catalogs, tables, registered functions,
    and configuration are the one shared session, so a registration through
    either handle is visible to both.

    A few things therefore belong to the session rather than to a handle, and
    take effect even if the handle that set them is discarded: the query
    planner (see :py:meth:`set_query_planner`), and the rebuild of an installed
    foreign planner that follows installing a codec. :ref:`extension_sessions`
    in the online documentation works through when that matters.

    **Keep a context alive for as long as anything derived from it is in use.**
    A :py:class:`~datafusion.DataFrame`, logical plan, or exported capsule does
    not extend the session's lifetime. Once the last context on a session is
    collected, any operation that reaches an extension codec fails with
    ``TaskContextProvider went out of scope over FFI boundary``.
    """

    def __init__(
        self,
        config: SessionConfig | None = None,
        runtime: RuntimeEnvBuilder | None = None,
    ) -> None:
        """Main interface for executing queries with DataFusion.

        Maintains the state of the connection between a user and an instance
        of the connection between a user and an instance of the DataFusion
        engine.

        Args:
            config: Session configuration options.
            runtime: Runtime configuration options.

        Example usage:

        The following example demonstrates how to use the context to execute
        a query against a CSV data source using the :py:class:`DataFrame` API::

            from datafusion import SessionContext

            ctx = SessionContext()
            df = ctx.read_csv("data.csv")
        """
        config = config.config_internal if config is not None else None
        runtime = runtime.config_internal if runtime is not None else None

        self.ctx = SessionContextInternal(config, runtime)

    def __repr__(self) -> str:
        """Print a string representation of the Session Context."""
        return self.ctx.__repr__()

    @classmethod
    def global_ctx(cls) -> SessionContext:
        """Retrieve the global context as a `SessionContext` wrapper.

        Returns:
            A `SessionContext` object that wraps the global `SessionContextInternal`.
        """
        internal_ctx = SessionContextInternal.global_ctx()
        wrapper = cls()
        wrapper.ctx = internal_ctx
        return wrapper

    def enable_url_table(self) -> SessionContext:
        """Control if local files can be queried as tables.

        Returns:
            A new :py:class:`SessionContext` object with url table enabled.
        """
        klass = self.__class__
        obj = klass.__new__(klass)
        obj.ctx = self.ctx.enable_url_table()
        return obj

    def register_object_store(
        self, schema: str, store: Any, host: str | None = None
    ) -> None:
        """Add a new object store into the session.

        Args:
            schema: The data source schema.
            store: The :py:class:`~datafusion.object_store.ObjectStore` to register.
            host: URL for the host.
        """
        self.ctx.register_object_store(schema, store, host)

    def deregister_object_store(self, schema: str, host: str | None = None) -> None:
        """Remove an object store from the session.

        Args:
            schema: The data source schema (e.g. ``"s3://"``).
            host: URL for the host (e.g. bucket name).
        """
        self.ctx.deregister_object_store(schema, host)

    def _register_object_store_for_path(
        self, path: str | pathlib.Path, store: Any
    ) -> None:
        """Parse a URL path and register the given object store for its scheme and host.

        This is a convenience helper used by methods like
        :py:meth:`register_parquet` and :py:meth:`read_parquet` to
        automatically register an object store when an ``object_store``
        parameter is provided.

        Args:
            path: A URL-style path (e.g. ``"s3://bucket/key.parquet"`` or
                ``"file:///tmp/data.parquet"``).
            store: An object store instance to register.

        Raises:
            ValueError: If the path does not contain a URL scheme, or if
                a non-file scheme is missing a host/bucket component.
        """
        parsed = urlparse(str(path))
        if not parsed.scheme:
            msg = (
                f"Cannot determine object store URL from path {path!r}. "
                "The path must use a URL scheme (e.g. 's3://bucket/key')."
            )
            raise ValueError(msg)
        # file:// URLs typically have an empty netloc (e.g. file:///tmp/a.parquet)
        # For other schemes (s3, gs, az, https) the netloc (bucket/host) is required.
        if parsed.scheme != "file" and not parsed.netloc:
            msg = (
                f"Cannot determine object store URL from path {path!r}. "
                "The path must include a host or bucket "
                "(e.g. 's3://bucket/key')."
            )
            raise ValueError(msg)
        scheme = f"{parsed.scheme}://"
        host = parsed.netloc or None
        self.register_object_store(scheme, store, host=host)

    def register_listing_table(
        self,
        name: str,
        path: str | pathlib.Path,
        table_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        file_extension: str = ".parquet",
        schema: pa.Schema | None = None,
        file_sort_order: Sequence[Sequence[SortKey]] | None = None,
    ) -> None:
        """Register multiple files as a single table.

        Registers a :py:class:`~datafusion.catalog.Table` that can assemble multiple
        files from locations in an :py:class:`~datafusion.object_store.ObjectStore`
        instance.

        Args:
            name: Name of the resultant table.
            path: Path to the file to register.
            table_partition_cols: Partition columns.
            file_extension: File extension of the provided table.
            schema: The data source schema.
            file_sort_order: Sort order for the file. Each sort key can be
                specified as a column name (``str``), an expression
                (``Expr``), or a ``SortExpr``.
        """
        if table_partition_cols is None:
            table_partition_cols = []
        table_partition_cols = _convert_table_partition_cols(table_partition_cols)
        self.ctx.register_listing_table(
            name,
            path,
            table_partition_cols,
            file_extension,
            schema,
            self._convert_file_sort_order(file_sort_order),
        )

    def sql(
        self,
        query: str,
        options: SQLOptions | None = None,
        param_values: dict[str, Any] | None = None,
        **named_params: Any,
    ) -> DataFrame:
        """Create a :py:class:`~datafusion.DataFrame` from SQL query text.

        See the online documentation for a description of how to perform
        parameterized substitution via either the ``param_values`` option
        or passing in ``named_params``.

        Note: This API implements DDL statements such as ``CREATE TABLE`` and
        ``CREATE VIEW`` and DML statements such as ``INSERT INTO`` with in-memory
        default implementation.See
        :py:func:`~datafusion.context.SessionContext.sql_with_options`.

        Args:
            query: SQL query text.
            options: If provided, the query will be validated against these options.
            param_values: Provides substitution of scalar values in the query
                after parsing.
            named_params: Provides string or DataFrame substitution in the query string.

        Returns:
            DataFrame representation of the SQL query.
        """

        def value_to_scalar(value: Any) -> pa.Scalar:
            if isinstance(value, pa.Scalar):
                return value
            return pa.scalar(value)

        def value_to_string(value: Any) -> str:
            if isinstance(value, DataFrame):
                view_name = str(uuid.uuid4()).replace("-", "_")
                view_name = f"view_{view_name}"
                view = value.df.into_view(temporary=True)
                self.ctx.register_table(view_name, view)
                return view_name
            return str(value)

        param_values = (
            {name: value_to_scalar(value) for (name, value) in param_values.items()}
            if param_values is not None
            else {}
        )
        param_strings = (
            {name: value_to_string(value) for (name, value) in named_params.items()}
            if named_params is not None
            else {}
        )

        options_raw = options.options_internal if options is not None else None

        return DataFrame(
            self.ctx.sql_with_options(
                query,
                options=options_raw,
                param_values=param_values,
                param_strings=param_strings,
            )
        )

    def sql_with_options(
        self,
        query: str,
        options: SQLOptions,
        param_values: dict[str, Any] | None = None,
        **named_params: Any,
    ) -> DataFrame:
        """Create a :py:class:`~datafusion.dataframe.DataFrame` from SQL query text.

        This function will first validate that the query is allowed by the
        provided options.

        Args:
            query: SQL query text.
            options: SQL options.
            param_values: Provides substitution of scalar values in the query
                after parsing.
            named_params: Provides string or DataFrame substitution in the query string.

        Returns:
            DataFrame representation of the SQL query.
        """
        return self.sql(
            query, options=options, param_values=param_values, **named_params
        )

    def create_dataframe(
        self,
        partitions: list[list[pa.RecordBatch]],
        name: str | None = None,
        schema: pa.Schema | None = None,
    ) -> DataFrame:
        """Create and return a dataframe using the provided partitions.

        Args:
            partitions: :py:class:`pa.RecordBatch` partitions to register.
            name: Resultant dataframe name.
            schema: Schema for the partitions.

        Returns:
            DataFrame representation of the SQL query.
        """
        return DataFrame(self.ctx.create_dataframe(partitions, name, schema))

    def create_dataframe_from_logical_plan(self, plan: LogicalPlan) -> DataFrame:
        """Create a :py:class:`~datafusion.dataframe.DataFrame` from an existing plan.

        Args:
            plan: Logical plan.

        Returns:
            DataFrame representation of the logical plan.
        """
        return DataFrame(self.ctx.create_dataframe_from_logical_plan(plan._raw_plan))

    def from_pylist(
        self, data: list[dict[str, Any]], name: str | None = None
    ) -> DataFrame:
        """Create a :py:class:`~datafusion.dataframe.DataFrame` from a list.

        Args:
            data: List of dictionaries.
            name: Name of the DataFrame.

        Returns:
            DataFrame representation of the list of dictionaries.
        """
        return DataFrame(self.ctx.from_pylist(data, name))

    def from_pydict(
        self, data: dict[str, list[Any]], name: str | None = None
    ) -> DataFrame:
        """Create a :py:class:`~datafusion.dataframe.DataFrame` from a dictionary.

        Args:
            data: Dictionary of lists.
            name: Name of the DataFrame.

        Returns:
            DataFrame representation of the dictionary of lists.
        """
        return DataFrame(self.ctx.from_pydict(data, name))

    def from_arrow(
        self,
        data: ArrowStreamExportable | ArrowArrayExportable,
        name: str | None = None,
    ) -> DataFrame:
        """Create a :py:class:`~datafusion.dataframe.DataFrame` from an Arrow source.

        The Arrow data source can be any object that implements either
        ``__arrow_c_stream__`` or ``__arrow_c_array__``. For the latter, it must return
        a struct array.

        Arrow data can be Polars, Pandas, Pyarrow etc.

        Args:
            data: Arrow data source.
            name: Name of the DataFrame.

        Returns:
            DataFrame representation of the Arrow table.
        """
        return DataFrame(self.ctx.from_arrow(data, name))

    def from_pandas(self, data: pd.DataFrame, name: str | None = None) -> DataFrame:
        """Create a :py:class:`~datafusion.dataframe.DataFrame` from a Pandas DataFrame.

        Args:
            data: Pandas DataFrame.
            name: Name of the DataFrame.

        Returns:
            DataFrame representation of the Pandas DataFrame.
        """
        return DataFrame(self.ctx.from_pandas(data, name))

    def from_polars(self, data: pl.DataFrame, name: str | None = None) -> DataFrame:
        """Create a :py:class:`~datafusion.dataframe.DataFrame` from a Polars DataFrame.

        Args:
            data: Polars DataFrame.
            name: Name of the DataFrame.

        Returns:
            DataFrame representation of the Polars DataFrame.
        """
        return DataFrame(self.ctx.from_polars(data, name))

    # https://github.com/apache/datafusion-python/pull/1016#discussion_r1983239116
    # is the discussion on how we arrived at adding register_view
    def register_view(self, name: str, df: DataFrame) -> None:
        """Register a :py:class:`~datafusion.dataframe.DataFrame` as a view.

        Args:
            name (str): The name to register the view under.
            df (DataFrame): The DataFrame to be converted into a view and registered.
        """
        view = df.into_view()
        self.ctx.register_table(name, view)

    def register_table(
        self,
        name: str,
        table: Table | TableProviderExportable | DataFrame | pa.dataset.Dataset,
    ) -> None:
        """Register a :py:class:`~datafusion.Table` with this context.

        The registered table can be referenced from SQL statements executed against
        this context.

        Args:
            name: Name of the resultant table.
            table: Any object that can be converted into a :class:`Table`.
        """
        self.ctx.register_table(name, table)

    def deregister_table(self, name: str) -> None:
        """Remove a table from the session."""
        self.ctx.deregister_table(name)

    def register_table_factory(
        self,
        format: str,
        factory: TableProviderFactory | TableProviderFactoryExportable,
    ) -> None:
        """Register a :py:class:`~datafusion.TableProviderFactoryExportable`.

        The registered factory can be referenced from SQL DDL statements executed
        against this context.

        Args:
            format: The value to be used in `STORED AS ${format}` clause.
            factory: A PyCapsule that implements :class:`TableProviderFactoryExportable`
        """
        self.ctx.register_table_factory(format, factory)

    def catalog_names(self) -> set[str]:
        """Returns the list of catalogs in this context."""
        return self.ctx.catalog_names()

    def register_catalog_provider_list(
        self,
        provider: CatalogProviderListExportable | CatalogProviderList | CatalogList,
    ) -> None:
        """Register a catalog provider list."""
        if isinstance(provider, CatalogList):
            self.ctx.register_catalog_provider_list(provider.catalog)
        else:
            self.ctx.register_catalog_provider_list(provider)

    def register_catalog_provider(
        self, name: str, provider: CatalogProviderExportable | CatalogProvider | Catalog
    ) -> None:
        """Register a catalog provider."""
        if isinstance(provider, Catalog):
            self.ctx.register_catalog_provider(name, provider.catalog)
        else:
            self.ctx.register_catalog_provider(name, provider)

    @deprecated("Use register_table() instead.")
    def register_table_provider(
        self,
        name: str,
        provider: Table | TableProviderExportable | DataFrame | pa.dataset.Dataset,
    ) -> None:
        """Register a table provider.

        Deprecated: use :meth:`register_table` instead.
        """
        self.register_table(name, provider)

    def register_udtf(self, func: TableFunction) -> None:
        """Register a user defined table function."""
        self.ctx.register_udtf(func._udtf)

    def register_batch(self, name: str, batch: pa.RecordBatch) -> None:
        """Register a single :py:class:`pa.RecordBatch` as a table.

        Args:
            name: Name of the resultant table.
            batch: Record batch to register as a table.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> batch = pa.RecordBatch.from_pydict({"a": [1, 2, 3]})
            >>> ctx.register_batch("batch_tbl", batch)
            >>> ctx.sql("SELECT * FROM batch_tbl").collect()[0].column(0)
            <pyarrow.lib.Int64Array object at ...>
            [
              1,
              2,
              3
            ]
        """
        self.ctx.register_batch(name, batch)

    def deregister_udtf(self, name: str) -> None:
        """Remove a user-defined table function from the session.

        Args:
            name: Name of the UDTF to deregister.
        """
        self.ctx.deregister_udtf(name)

    def register_record_batches(
        self, name: str, partitions: list[list[pa.RecordBatch]]
    ) -> None:
        """Register record batches as a table.

        This function will convert the provided partitions into a table and
        register it into the session using the given name.

        Args:
            name: Name of the resultant table.
            partitions: Record batches to register as a table.
        """
        self.ctx.register_record_batches(name, partitions)

    def read_batch(self, batch: pa.RecordBatch) -> DataFrame:
        """Return a :py:class:`~datafusion.DataFrame` reading a single batch.

        Convenience wrapper around :py:meth:`read_batches` for the single-batch
        case. Unlike :py:meth:`register_batch`, this does not register the
        batch as a named table; it returns an anonymous
        :py:class:`~datafusion.DataFrame` directly.

        Args:
            batch: Record batch to wrap as a DataFrame.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> batch = pa.RecordBatch.from_pydict({"a": [1, 2, 3]})
            >>> ctx.read_batch(batch).to_pydict()
            {'a': [1, 2, 3]}
        """
        return self.read_batches([batch])

    def read_batches(self, batches: Iterable[pa.RecordBatch]) -> DataFrame:
        """Return a :py:class:`~datafusion.DataFrame` reading the given batches.

        All batches must share the same schema. Any iterable of
        :py:class:`pa.RecordBatch` is accepted (list, tuple, generator);
        it is materialized into a list before being handed to the
        underlying Rust binding. Unlike :py:meth:`register_record_batches`,
        this does not register the batches as a named table; it returns
        an anonymous :py:class:`~datafusion.DataFrame` directly.

        Args:
            batches: Record batches to wrap as a DataFrame.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> b1 = pa.RecordBatch.from_pydict({"a": [1, 2]})
            >>> b2 = pa.RecordBatch.from_pydict({"a": [3, 4]})
            >>> ctx.read_batches([b1, b2]).to_pydict()
            {'a': [1, 2, 3, 4]}

            A generator works too:

            >>> ctx.read_batches(b for b in [b1, b2]).to_pydict()
            {'a': [1, 2, 3, 4]}
        """
        return DataFrame(self.ctx.read_batches(list(batches)))

    def register_parquet(
        self,
        name: str,
        path: str | pathlib.Path,
        table_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        parquet_pruning: bool = True,
        file_extension: str = ".parquet",
        skip_metadata: bool = True,
        schema: pa.Schema | None = None,
        file_sort_order: Sequence[Sequence[SortKey]] | None = None,
        object_store: Any | None = None,
    ) -> None:
        """Register a Parquet file as a table.

        The registered table can be referenced from SQL statement executed
        against this context.

        Args:
            name: Name of the table to register.
            path: Path to the Parquet file.
            table_partition_cols: Partition columns.
            parquet_pruning: Whether the parquet reader should use the
                predicate to prune row groups.
            file_extension: File extension; only files with this extension are
                selected for data input.
            skip_metadata: Whether the parquet reader should skip any metadata
                that may be in the file schema. This can help avoid schema
                conflicts due to metadata.
            schema: The data source schema.
            file_sort_order: Sort order for the file. Each sort key can be
                specified as a column name (``str``), an expression
                (``Expr``), or a ``SortExpr``.
            object_store: A pre-configured object store instance (e.g.
                :py:class:`~datafusion.object_store.AmazonS3`,
                :py:class:`~datafusion.object_store.GoogleCloud`,
                :py:class:`~datafusion.object_store.MicrosoftAzure`) to use
                for accessing the file. When provided, the store is
                automatically registered for the URL scheme and host parsed
                from ``path``, removing the need to call
                :py:meth:`register_object_store` separately. This is
                especially useful in multi-threaded environments where
                setting credentials via ``os.environ`` is not thread-safe.

        Examples:
            Register a local Parquet file:

            >>> import datafusion
            >>> ctx = datafusion.SessionContext()
            >>> ctx.register_parquet("my_table", "data.parquet")  # doctest: +SKIP

            Register from S3 with inline credentials (thread-safe):

            >>> from datafusion.object_store import AmazonS3  # doctest: +SKIP
            >>> store = AmazonS3(
            ...     bucket_name="my-bucket",
            ...     region="us-east-1",
            ...     access_key_id="...",
            ...     secret_access_key="...",
            ... )  # doctest: +SKIP
            >>> ctx.register_parquet(
            ...     "my_table",
            ...     "s3://my-bucket/data.parquet",
            ...     object_store=store,
            ... )  # doctest: +SKIP
        """
        if object_store is not None:
            self._register_object_store_for_path(path, object_store)
        if table_partition_cols is None:
            table_partition_cols = []
        table_partition_cols = _convert_table_partition_cols(table_partition_cols)
        self.ctx.register_parquet(
            name,
            path,
            table_partition_cols,
            parquet_pruning,
            file_extension,
            skip_metadata,
            schema,
            self._convert_file_sort_order(file_sort_order),
        )

    def register_csv(
        self,
        name: str,
        path: str | pathlib.Path | list[str | pathlib.Path],
        schema: pa.Schema | None = None,
        has_header: bool = True,
        delimiter: str = ",",
        schema_infer_max_records: int = DEFAULT_MAX_INFER_SCHEMA,
        file_extension: str = ".csv",
        file_compression_type: str | None = None,
        options: CsvReadOptions | None = None,
        object_store: Any | None = None,
    ) -> None:
        """Register a CSV file as a table.

        The registered table can be referenced from SQL statement executed against.

        Args:
            name: Name of the table to register.
            path: Path to the CSV file. It also accepts a list of Paths.
            schema: An optional schema representing the CSV file. If None, the
                CSV reader will try to infer it based on data in file.
            has_header: Whether the CSV file have a header. If schema inference
                is run on a file with no headers, default column names are
                created.
            delimiter: An optional column delimiter.
            schema_infer_max_records: Maximum number of rows to read from CSV
                files for schema inference if needed.
            file_extension: File extension; only files with this extension are
                selected for data input.
            file_compression_type: File compression type.
            options: Set advanced options for CSV reading. This cannot be
                combined with any of the other options in this method.
            object_store: A pre-configured object store instance to use for
                accessing the file. When provided, the store is automatically
                registered for the URL scheme and host parsed from ``path``.
        """
        if object_store is not None:
            # For list paths, register from the first entry
            register_path = path[0] if isinstance(path, list) else path
            self._register_object_store_for_path(register_path, object_store)
        if options is not None and (
            schema is not None
            or not has_header
            or delimiter != ","
            or schema_infer_max_records != DEFAULT_MAX_INFER_SCHEMA
            or file_extension != ".csv"
            or file_compression_type is not None
        ):
            message = (
                "Combining CsvReadOptions parameter with additional options "
                "is not supported. Use CsvReadOptions to set parameters."
            )
            warnings.warn(
                message,
                category=UserWarning,
                stacklevel=2,
            )

        options = (
            options
            if options is not None
            else CsvReadOptions(
                schema=schema,
                has_header=has_header,
                delimiter=delimiter,
                schema_infer_max_records=schema_infer_max_records,
                file_extension=file_extension,
                file_compression_type=file_compression_type,
            )
        )

        self.ctx.register_csv(
            name,
            path,
            options.to_inner(),
        )

    def register_json(
        self,
        name: str,
        path: str | pathlib.Path,
        schema: pa.Schema | None = None,
        schema_infer_max_records: int = 1000,
        file_extension: str = ".json",
        table_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        file_compression_type: str | None = None,
        object_store: Any | None = None,
    ) -> None:
        """Register a JSON file as a table.

        The registered table can be referenced from SQL statement executed
        against this context.

        Args:
            name: Name of the table to register.
            path: Path to the JSON file.
            schema: The data source schema.
            schema_infer_max_records: Maximum number of rows to read from JSON
                files for schema inference if needed.
            file_extension: File extension; only files with this extension are
                selected for data input.
            table_partition_cols: Partition columns.
            file_compression_type: File compression type.
            object_store: A pre-configured object store instance to use for
                accessing the file. When provided, the store is automatically
                registered for the URL scheme and host parsed from ``path``.
        """
        if object_store is not None:
            self._register_object_store_for_path(path, object_store)
        if table_partition_cols is None:
            table_partition_cols = []
        table_partition_cols = _convert_table_partition_cols(table_partition_cols)
        self.ctx.register_json(
            name,
            path,
            schema,
            schema_infer_max_records,
            file_extension,
            table_partition_cols,
            file_compression_type,
        )

    def register_avro(
        self,
        name: str,
        path: str | pathlib.Path,
        schema: pa.Schema | None = None,
        file_extension: str = ".avro",
        table_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        object_store: Any | None = None,
    ) -> None:
        """Register an Avro file as a table.

        The registered table can be referenced from SQL statement executed against
        this context.

        Args:
            name: Name of the table to register.
            path: Path to the Avro file.
            schema: The data source schema.
            file_extension: File extension to select.
            table_partition_cols:  Partition columns.
            object_store: A pre-configured object store instance to use for
                accessing the file. When provided, the store is automatically
                registered for the URL scheme and host parsed from ``path``.
        """
        if object_store is not None:
            self._register_object_store_for_path(path, object_store)
        if table_partition_cols is None:
            table_partition_cols = []
        table_partition_cols = _convert_table_partition_cols(table_partition_cols)
        self.ctx.register_avro(name, path, schema, file_extension, table_partition_cols)

    def register_arrow(
        self,
        name: str,
        path: str | pathlib.Path,
        schema: pa.Schema | None = None,
        file_extension: str = ".arrow",
        table_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        object_store: Any | None = None,
    ) -> None:
        """Register an Arrow IPC file as a table.

        The registered table can be referenced from SQL statements executed
        against this context.

        Args:
            name: Name of the table to register.
            path: Path to the Arrow IPC file.
            schema: The data source schema.
            file_extension: File extension to select.
            table_partition_cols: Partition columns.
            object_store: A pre-configured object store instance to use for
                accessing the file. When provided, the store is automatically
                registered for the URL scheme and host parsed from ``path``.

        Examples:
            >>> import tempfile, os
            >>> ctx = dfn.SessionContext()
            >>> table = pa.table({"x": [10, 20, 30]})
            >>> with tempfile.TemporaryDirectory() as tmpdir:
            ...     path = os.path.join(tmpdir, "data.arrow")
            ...     with pa.ipc.new_file(path, table.schema) as writer:
            ...         writer.write_table(table)
            ...     ctx.register_arrow("arrow_tbl", path)
            ...     ctx.sql("SELECT * FROM arrow_tbl").collect()[0].column(0)
            <pyarrow.lib.Int64Array object at ...>
            [
              10,
              20,
              30
            ]

            Provide an explicit ``schema`` to override schema inference:

            >>> with tempfile.TemporaryDirectory() as tmpdir:
            ...     path = os.path.join(tmpdir, "data.arrow")
            ...     with pa.ipc.new_file(path, table.schema) as writer:
            ...         writer.write_table(table)
            ...     ctx.register_arrow(
            ...         "arrow_schema",
            ...         path,
            ...         schema=pa.schema([("x", pa.int64())]),
            ...     )
            ...     ctx.sql("SELECT * FROM arrow_schema").collect()[0].column(0)
            <pyarrow.lib.Int64Array object at ...>
            [
              10,
              20,
              30
            ]

            Use ``file_extension`` to read files with a non-default extension:

            >>> with tempfile.TemporaryDirectory() as tmpdir:
            ...     path = os.path.join(tmpdir, "data.ipc")
            ...     with pa.ipc.new_file(path, table.schema) as writer:
            ...         writer.write_table(table)
            ...     ctx.register_arrow(
            ...         "arrow_ipc", path, file_extension=".ipc"
            ...     )
            ...     ctx.sql("SELECT * FROM arrow_ipc").collect()[0].column(0)
            <pyarrow.lib.Int64Array object at ...>
            [
              10,
              20,
              30
            ]
        """
        if object_store is not None:
            self._register_object_store_for_path(path, object_store)
        if table_partition_cols is None:
            table_partition_cols = []
        table_partition_cols = _convert_table_partition_cols(table_partition_cols)
        self.ctx.register_arrow(
            name, path, schema, file_extension, table_partition_cols
        )

    def register_dataset(self, name: str, dataset: pa.dataset.Dataset) -> None:
        """Register a :py:class:`pa.dataset.Dataset` as a table.

        Args:
            name: Name of the table to register.
            dataset: PyArrow dataset.
        """
        self.ctx.register_dataset(name, dataset)

    def register_udf(self, udf: ScalarUDF) -> None:
        """Register a user-defined function (UDF) with the context."""
        self.ctx.register_udf(udf._udf)

    def deregister_udf(self, name: str) -> None:
        """Remove a user-defined scalar function from the session.

        Args:
            name: Name of the UDF to deregister.
        """
        self.ctx.deregister_udf(name)

    def register_udaf(self, udaf: AggregateUDF) -> None:
        """Register a user-defined aggregation function (UDAF) with the context."""
        self.ctx.register_udaf(udaf._udaf)

    def enable_spark_functions(self) -> None:
        """Register all Spark-compatible functions for SQL access.

        Registers every UDF/UDAF/UDWF from the ``datafusion-spark`` crate,
        overriding any DataFusion built-ins of the same name with their
        Spark-semantics version (e.g. ``substring`` becomes 1-indexed,
        ``concat`` propagates NULL, ``round`` uses HALF_UP rounding).

        For DataFrame use, import the typed wrappers from
        :py:mod:`datafusion.functions.spark` directly; this method is only
        needed for SQL queries.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> ctx.enable_spark_functions()
            >>> ctx.sql(
            ...     "SELECT sha2('hello', 256) AS h"
            ... ).collect_column("h")[0].as_py()
            '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
        """
        self.ctx.enable_spark_functions()

    def deregister_udaf(self, name: str) -> None:
        """Remove a user-defined aggregate function from the session.

        Args:
            name: Name of the UDAF to deregister.
        """
        self.ctx.deregister_udaf(name)

    def register_udwf(self, udwf: WindowUDF) -> None:
        """Register a user-defined window function (UDWF) with the context."""
        self.ctx.register_udwf(udwf._udwf)

    def deregister_udwf(self, name: str) -> None:
        """Remove a user-defined window function from the session.

        Args:
            name: Name of the UDWF to deregister.
        """
        self.ctx.deregister_udwf(name)

    def udf(self, name: str) -> ScalarUDF:
        """Look up a registered scalar UDF by name.

        Returns the same ``ScalarUDF`` wrapper that :py:meth:`register_udf`
        accepts, so it can be invoked as an expression in the DataFrame API
        or re-registered into a different :py:class:`SessionContext`.
        Built-in scalar functions from the session's function registry are
        also looked up.

        Args:
            name: Name of the registered scalar UDF.

        Raises:
            KeyError: If no scalar UDF is registered under ``name``.

        Examples:
            Register a UDF, then look it up by name and use it in the
            DataFrame API:

            >>> ctx = dfn.SessionContext()
            >>> nullcheck = dfn.udf(
            ...     lambda x: x.is_null(),
            ...     [pa.int64()],
            ...     pa.bool_(),
            ...     volatility="immutable",
            ...     name="nullcheck",
            ... )
            >>> ctx.register_udf(nullcheck)
            >>> fn = ctx.udf("nullcheck")
            >>> df = ctx.from_pydict({"a": [1, None, 3]})
            >>> df.select(fn(col("a")).alias("is_null")).to_pydict()
            {'is_null': [False, True, False]}

            Late-binding: the function name can come from configuration
            rather than an imported symbol, which is useful when the set
            of UDFs is plugin-driven or chosen at runtime:

            >>> config = {"null_check": "nullcheck"}
            >>> fn = ctx.udf(config["null_check"])
            >>> df.select(fn(col("a")).alias("is_null")).to_pydict()
            {'is_null': [False, True, False]}
        """
        from datafusion.user_defined import ScalarUDF as _ScalarUDF  # noqa: PLC0415

        return _ScalarUDF._from_internal(self.ctx.udf(name))

    def udaf(self, name: str) -> AggregateUDF:
        """Look up a registered aggregate UDF by name.

        Returns the same ``AggregateUDF`` wrapper that :py:meth:`register_udaf`
        accepts. Built-in aggregate functions such as ``sum`` or ``avg`` are
        also discoverable through this lookup. See :py:meth:`udf` for a worked
        late-binding example; the pattern is identical for aggregates.

        Args:
            name: Name of the registered aggregate UDF.

        Raises:
            KeyError: If no aggregate UDF is registered under ``name``.

        Examples:
            Look up a built-in aggregate by name and use it in
            :py:meth:`~datafusion.DataFrame.aggregate`:

            >>> ctx = dfn.SessionContext()
            >>> sum_fn = ctx.udaf("sum")
            >>> df = ctx.from_pydict({"a": [1, 2, 3]})
            >>> df.aggregate([], [sum_fn(col("a")).alias("total")]).to_pydict()
            {'total': [6]}
        """
        from datafusion.user_defined import (  # noqa: PLC0415
            AggregateUDF as _AggregateUDF,
        )

        return _AggregateUDF._from_internal(self.ctx.udaf(name))

    def udwf(self, name: str) -> WindowUDF:
        """Look up a registered window UDF by name.

        Returns the same ``WindowUDF`` wrapper that :py:meth:`register_udwf`
        accepts. Built-in window functions such as ``row_number`` or ``rank``
        are also discoverable through this lookup. See :py:meth:`udf` for a
        worked late-binding example; the pattern is identical for window
        functions.

        Args:
            name: Name of the registered window UDF.

        Raises:
            KeyError: If no window UDF is registered under ``name``.

        Examples:
            Look up a built-in window function by name and use it in
            ``select``:

            >>> ctx = dfn.SessionContext()
            >>> rn = ctx.udwf("row_number")
            >>> df = ctx.from_pydict({"a": [10, 20, 30]})
            >>> df.select(col("a"), rn().alias("rn")).to_pydict()
            {'a': [10, 20, 30], 'rn': [1, 2, 3]}
        """
        from datafusion.user_defined import WindowUDF as _WindowUDF  # noqa: PLC0415

        return _WindowUDF._from_internal(self.ctx.udwf(name))

    def udfs(self) -> list[str]:
        """Return the sorted names of all registered scalar UDFs.

        Includes both user-registered and built-in scalar functions. Pair
        with :py:meth:`udf` to drive discovery, validation, or config-based
        dispatch.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> "abs" in ctx.udfs()
            True
        """
        return self.ctx.udfs()

    def udafs(self) -> list[str]:
        """Return the sorted names of all registered aggregate UDFs.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> "sum" in ctx.udafs()
            True
        """
        return self.ctx.udafs()

    def udwfs(self) -> list[str]:
        """Return the sorted names of all registered window UDFs.

        Examples:
            >>> ctx = dfn.SessionContext()
            >>> "row_number" in ctx.udwfs()
            True
        """
        return self.ctx.udwfs()

    def catalog(self, name: str = "datafusion") -> Catalog:
        """Retrieve a catalog by name."""
        return Catalog(self.ctx.catalog(name))

    def table(self, name: str) -> DataFrame:
        """Retrieve a previously registered table by name."""
        return DataFrame(self.ctx.table(name))

    def table_exist(self, name: str) -> bool:
        """Return whether a table with the given name exists."""
        return self.ctx.table_exist(name)

    def empty_table(self) -> DataFrame:
        """Create an empty :py:class:`~datafusion.dataframe.DataFrame`."""
        return DataFrame(self.ctx.empty_table())

    def session_id(self) -> str:
        """Return an id that uniquely identifies this :py:class:`SessionContext`."""
        return self.ctx.session_id()

    def session_start_time(self) -> str:
        """Return the session start time as an RFC 3339 formatted string.

        Examples:
            >>> ctx = SessionContext()
            >>> ctx.session_start_time()  # doctest: +SKIP
            '2026-01-01T12:34:56.123456789+00:00'
        """
        return self.ctx.session_start_time()

    def enable_ident_normalization(self) -> bool:
        """Return whether identifier normalization (lowercasing) is enabled.

        Examples:
            >>> ctx = SessionContext()
            >>> ctx.enable_ident_normalization()
            True
        """
        return self.ctx.enable_ident_normalization()

    def copied_config(self) -> SessionConfig:
        """Return a copy of the active :py:class:`SessionConfig`.

        Mutating the returned config does not affect this context; use
        the result when you need a starting point for a new context or
        want to inspect the current settings independent of further
        changes here.

        Examples:
            >>> ctx = SessionContext(SessionConfig().with_batch_size(1024))
            >>> isinstance(ctx.copied_config(), SessionConfig)
            True
        """
        config = SessionConfig()
        config.config_internal = self.ctx.copied_config()
        return config

    @staticmethod
    def parse_capacity_limit(config_name: str, limit: str) -> int:
        """Parse a size string into a byte count.

        Accepts strings like ``"100M"``, ``"1.5G"``, or ``"512K"``.
        ``"0"`` is accepted and returns 0. ``config_name`` is used purely
        for error messages and identifies which configuration setting the
        limit belongs to. Use this helper when constructing a
        :py:class:`RuntimeEnvBuilder` from a human-friendly size string.

        Examples:
            >>> SessionContext.parse_capacity_limit(
            ...     "datafusion.runtime.memory_limit", "1M"
            ... )
            1048576
            >>> SessionContext.parse_capacity_limit(
            ...     "datafusion.runtime.memory_limit", "0"
            ... )
            0
        """
        return SessionContextInternal.parse_capacity_limit(config_name, limit)

    def parse_sql_expr(self, sql: str, schema: DFSchema) -> Expr:
        """Parse a SQL expression string into a logical expression.

        Args:
            sql: SQL expression string.
            schema: Schema to use for resolving column references.

        Returns:
            Parsed expression.

        Examples:
            >>> from datafusion.common import DFSchema
            >>> ctx = SessionContext()
            >>> schema = DFSchema.empty()
            >>> ctx.parse_sql_expr("1 + 2", schema=schema)
            Expr(Int64(1) + Int64(2))
        """
        from datafusion.expr import Expr  # noqa: PLC0415

        return Expr(self.ctx.parse_sql_expr(sql, schema))

    def execute_logical_plan(self, plan: LogicalPlan) -> DataFrame:
        """Execute a :py:class:`~datafusion.plan.LogicalPlan` and return a DataFrame.

        Args:
            plan: Logical plan to execute.

        Returns:
            DataFrame resulting from the execution.

        Examples:
            >>> ctx = SessionContext()
            >>> df = ctx.from_pydict({"a": [1, 2, 3]})
            >>> plan = df.logical_plan()
            >>> df2 = ctx.execute_logical_plan(plan)
            >>> df2.collect()[0].column(0)
            <pyarrow.lib.Int64Array object at ...>
            [
              1,
              2,
              3
            ]
        """
        return DataFrame(self.ctx.execute_logical_plan(plan._raw_plan))

    def refresh_catalogs(self) -> None:
        """Refresh catalog metadata.

        Examples:
            >>> ctx = SessionContext()
            >>> ctx.refresh_catalogs()
        """
        self.ctx.refresh_catalogs()

    def remove_optimizer_rule(self, name: str) -> bool:
        """Remove an optimizer rule by name.

        Args:
            name: Name of the optimizer rule to remove.

        Returns:
            True if a rule with the given name was found and removed.

        Examples:
            >>> ctx = SessionContext()
            >>> ctx.remove_optimizer_rule("nonexistent_rule")
            False
        """
        return self.ctx.remove_optimizer_rule(name)

    def add_physical_optimizer_rule(
        self, rule: PhysicalOptimizerRuleExportable
    ) -> None:
        """Append a user-defined physical optimizer rule to the session.

        The rule is imported via its ``__datafusion_physical_optimizer_rule__``
        PyCapsule, typically produced by a separate compiled extension. The
        underlying :class:`SessionState` is rebuilt from its current state
        with the new rule appended, so previously registered tables, UDFs,
        and catalogs are preserved. Prepared statements are not — see
        :ref:`extension_rule_rebuild`.

        Args:
            rule: Object exposing ``__datafusion_physical_optimizer_rule__``,
                a :class:`PhysicalOptimizerRuleExportable`.

        Examples:
            >>> from datafusion import SessionContext
            >>> ctx = SessionContext()
            >>> from my_extension import MyPhysicalOptimizerRule  # doctest: +SKIP
            >>> rule = MyPhysicalOptimizerRule()  # doctest: +SKIP
            >>> ctx.add_physical_optimizer_rule(rule)  # doctest: +SKIP
        """
        self.ctx.add_physical_optimizer_rule(rule)

    def set_query_planner(self, planner: QueryPlannerExportable | _PyCapsule) -> None:
        """Install a custom query planner on this session.

        The planner is imported through its ``__datafusion_query_planner__``
        PyCapsule, in the same way
        :meth:`~SessionContext.add_physical_optimizer_rule` installs a rule.

        Returns nothing, because the planner lives in the session rather than
        in a handle on it — installing one is visible to every context sharing
        that session, including ones an earlier ``with_*`` call returned. See
        :py:class:`SessionContext`.

        A session holds exactly one planner, so calling this again **replaces**
        the previous one rather than layering. To chain planners, have the new
        planner wrap the capsule from
        :meth:`~SessionContext.__datafusion_query_planner__`, captured *before*
        the new planner is installed.

        Install any extension codecs before a layered planner; the rebuild that
        follows a later codec install does not reach the fallback inside one.
        See :ref:`planner_codec_rebinding`, or prefer
        :py:meth:`with_extensions`, which cannot capture a partial chain.

        Args:
            planner: Object exposing ``__datafusion_query_planner__`` (see
                :py:class:`~datafusion.extensions.QueryPlannerExportable`) or a raw
                ``datafusion_query_planner`` PyCapsule.

        Raises:
            ValueError: If the capsule is not named ``datafusion_query_planner``.

        Examples:
            A session exports its own planner, which is what you capture to
            wrap:

            >>> from datafusion import SessionContext
            >>> ctx = SessionContext()
            >>> fallback = ctx.__datafusion_query_planner__()
            >>> type(fallback).__name__
            'PyCapsule'

            Skipped here (needs a built extension library):

            >>> from my_extension import DistributedQueryPlanner  # doctest: +SKIP
            >>> ctx.set_query_planner(
            ...     DistributedQueryPlanner(fallback=fallback)
            ... )  # doctest: +SKIP
            >>> ctx.sql("SELECT * FROM remote_table").collect()  # doctest: +SKIP
        """
        self.ctx.set_query_planner(planner)

    def with_extensions(
        self, *extensions: SessionComponentsExportable | SessionPlannerExportable
    ) -> SessionContext:
        """Create a new session context with the given extension bundles.

        This is the preferred way to install extension codecs and query
        planners, because it removes the ordering question that installing them
        by hand creates.

        Each argument is called twice, in two phases:

        1. ``__datafusion_session_components__(ctx)`` on every extension, then
           all the returned codecs are installed at once.
        2. ``__datafusion_session_planner__(ctx, fallback)`` on every
           extension, **in argument order**, each handed the planner built so
           far and the context carrying every bundle's codecs. The last
           extension listed ends up outermost.

        An extension implements either hook or both. Return ``None`` from the
        planner hook to contribute no planner; see
        :py:class:`~datafusion.extensions.SessionPlannerExportable`.

        Nothing is written to the session until every hook has returned and
        every component has been validated, so a hook that raises leaves the
        session as it was. Declared tables install first and everything else
        after the planner is bound; all of them are visible on every handle
        sharing this session. A hook that *mutates* the context it is handed —
        registering a
        table, say — is not rolled back, which is why bundle objects must be
        configuration-only.

        A call that installs optimizer rules rebuilds the session state, which
        drops the session's prepared statements — see
        :ref:`extension_rule_rebuild`.

        Shares its session with this context — see :py:class:`SessionContext`.

        See :ref:`extension_bundles` in the online documentation for why the
        phases are split, how to contribute a bundle's two halves at different
        positions, and a worked Rust implementation.

        Args:
            extensions: Extension bundles to install. Order is irrelevant for
                codecs and significant for planners, which nest in this order
                with the last one outermost. Passing none installs nothing and
                returns a handle on this session, so a caller assembling the
                list at runtime need not special-case it being empty.

        Returns:
            A new context with all extension components installed.

        Raises:
            TypeError: If an argument implements neither hook, if a hook
                returns the wrong type, if a codec is contributed as a bare
                ``PyCapsule`` rather than an object exposing the getter, or if
                a declared function or optimizer rule does not expose its
                capsule getter and is not already a wrapper.
            ValueError: If two codecs claim the same id, if two extensions
                declare a function, table, or table function of one kind under
                the same name, or if a getter returns a capsule of the wrong
                kind. See :py:meth:`with_logical_extension_codec` for how ids
                are assigned.
            RuntimeError: If a getter is present but returns something that is
                not a ``PyCapsule`` at all. The message comes from the importer
                and does not name the bundle, because by then the declaration
                has already been accepted as the right shape.
            Exception: If a declared table cannot be resolved — the name is
                taken, the schema unknown, or the value not a table.

        Examples:
            The returned handle is a different object sharing one session, and
            an empty call is legal:

            >>> from datafusion import SessionContext
            >>> ctx = SessionContext()
            >>> derived = ctx.with_extensions()
            >>> derived is ctx
            False
            >>> ctx.from_pydict({"a": [1, 2]}, name="t")  # doctest: +ELLIPSIS
            DataFrame()...
            >>> derived.table_exist("t")
            True
            >>> derived.logical_extension_codec_ids()
            []

            A runnable multi-bundle example, showing what a bundle returns and
            how its codec ids accumulate, is in :ref:`extension_bundles`.

            Real usage. Skipped here (needs a built extension library); run
            verbatim by ``test_with_extensions_docstring_example_still_runs``.

            >>> from my_extension import DistributedEngineExtension  # doctest: +SKIP
            >>> ctx = SessionContext().with_extensions(
            ...     DistributedEngineExtension("scheduler:50050")
            ... )  # doctest: +SKIP
            >>> batches = ctx.sql("SELECT 1 AS n").collect()  # doctest: +SKIP
            >>> batches[0].column(0).to_pylist()  # doctest: +SKIP
            [1]
        """
        # Phase one: collect every bundle's components. Components are bound
        # against this context, not a context derived from it. There is one
        # `Arc<SessionContext>` per session, so a component bound here holds a
        # task-context provider that the returned handle keeps alive.
        logical_codecs, physical_codecs, declared = _collect_contributions(
            extensions, self
        )

        # Writes nothing: the chains belong to the new handle, so a failure
        # above or below leaves this context as it was.
        new = SessionContext.__new__(SessionContext)
        new.ctx = self.ctx._install_extension_codecs(logical_codecs, physical_codecs)

        # Resolve every declared function to the wrapper that registers it, and
        # settle name collisions, while a failure still costs nothing. None of
        # these getters take an argument, so unlike a provider they do not care
        # which handle they are resolved against.
        from datafusion import user_defined as _user_defined  # noqa: PLC0415

        resolved: dict[str, list[Any]] = {
            kind.field: _resolve_declared_functions(
                declared[kind.field],
                getattr(_user_defined, kind.wrapper),
                kind.getter,
                getattr(_user_defined, kind.factory),
                kind.label,
            )
            for kind in _FUNCTION_KINDS
        }
        # Tables and table functions are not in that table: their getters *do*
        # take the session, so each is wrapped against `new`, not `self` -- the
        # handle the components hook saw is missing this call's codecs.
        resolved_udtfs = [
            _user_defined.TableFunction(name, func, new)
            for _, _, (name, func) in _reject_repeated_names(
                declared["udtfs"], "table function"
            )
        ]
        # Imports each provider against `new` for the same reason, resolves
        # each name to the schema that will hold it, and refuses a name that is
        # already taken or that a second declaration resolves onto.
        #
        # The pass below is not redundant with that last check, and neither
        # subsumes the other. Only the resolver knows that `Events` and
        # `public.events` are one table, and only this side knows which
        # argument each declaration came from -- the thing that picks the
        # remedy. So the common case, two bundles writing the same name the
        # same way, gets the message that names both of them.
        resolved_tables = new.ctx._resolve_extension_tables(
            [
                pair
                for _, _, pair in _reject_repeated_names(
                    declared["table_providers"], "table"
                )
            ]
        )
        # Rules accumulate, so there is no name to check and nothing to refuse
        # -- only the capsules to import while failing is still free.
        resolved_rules = _resolve_declared_rules(
            declared["physical_optimizer_rules"],
            new.ctx._resolve_extension_physical_optimizer_rules,
        )

        # Phase two: run the planner hooks and commit, in one call. Each hook
        # runs against `new`, which carries the final chains, so a planner
        # captured there never sees a partial codec set. The hook loop, the
        # ordering of the commit, and the guard that skips the planner rebind
        # for a call that installs nothing all live on the Rust side -- see
        # `_commit_extensions` and docs/source/contributor-guide/
        # ffi-internals.md, under "Why `with_extensions` commits last". A new
        # component field must be resolved above and given its own
        # `_commit_extensions` parameter; the call's arity is what keeps a
        # declared component from being quietly dropped.
        new.ctx._commit_extensions(
            list(extensions),
            new,
            bool(logical_codecs or physical_codecs),
            resolved_tables,
            [function._udf for function in resolved["udfs"]],
            [function._udaf for function in resolved["udafs"]],
            [function._udwf for function in resolved["udwfs"]],
            [table_function._udtf for table_function in resolved_udtfs],
            resolved_rules,
        )
        return new

    def table_provider(self, name: str) -> Table:
        """Return the :py:class:`~datafusion.catalog.Table` for the given table name.

        Args:
            name: Name of the table.

        Returns:
            The table provider.

        Raises:
            KeyError: If the table is not found.

        Examples:
            >>> import pyarrow as pa
            >>> ctx = SessionContext()
            >>> batch = pa.RecordBatch.from_pydict({"x": [1, 2]})
            >>> ctx.register_record_batches("my_table", [[batch]])
            >>> tbl = ctx.table_provider("my_table")
            >>> tbl.schema
            x: int64
        """
        from datafusion.catalog import Table  # noqa: PLC0415

        return Table(self.ctx.table_provider(name))

    def read_json(
        self,
        path: str | pathlib.Path,
        schema: pa.Schema | None = None,
        schema_infer_max_records: int = 1000,
        file_extension: str = ".json",
        table_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        file_compression_type: str | None = None,
        object_store: Any | None = None,
    ) -> DataFrame:
        """Read a line-delimited JSON data source.

        Args:
            path: Path to the JSON file.
            schema: The data source schema.
            schema_infer_max_records: Maximum number of rows to read from JSON
                files for schema inference if needed.
            file_extension: File extension; only files with this extension are
                selected for data input.
            table_partition_cols: Partition columns.
            file_compression_type: File compression type.
            object_store: A pre-configured object store instance to use for
                accessing the file. When provided, the store is automatically
                registered for the URL scheme and host parsed from ``path``.

        Returns:
            DataFrame representation of the read JSON files.
        """
        if object_store is not None:
            self._register_object_store_for_path(path, object_store)
        if table_partition_cols is None:
            table_partition_cols = []
        table_partition_cols = _convert_table_partition_cols(table_partition_cols)
        return DataFrame(
            self.ctx.read_json(
                path,
                schema,
                schema_infer_max_records,
                file_extension,
                table_partition_cols,
                file_compression_type,
            )
        )

    def read_csv(
        self,
        path: str | pathlib.Path | list[str] | list[pathlib.Path],
        schema: pa.Schema | None = None,
        has_header: bool = True,
        delimiter: str = ",",
        schema_infer_max_records: int = DEFAULT_MAX_INFER_SCHEMA,
        file_extension: str = ".csv",
        table_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        file_compression_type: str | None = None,
        options: CsvReadOptions | None = None,
        object_store: Any | None = None,
    ) -> DataFrame:
        """Read a CSV data source.

        Args:
            path: Path to the CSV file
            schema: An optional schema representing the CSV files. If None, the
                CSV reader will try to infer it based on data in file.
            has_header: Whether the CSV file have a header. If schema inference
                is run on a file with no headers, default column names are
                created.
            delimiter: An optional column delimiter.
            schema_infer_max_records: Maximum number of rows to read from CSV
                files for schema inference if needed.
            file_extension:  File extension; only files with this extension are
                selected for data input.
            table_partition_cols:  Partition columns.
            file_compression_type:  File compression type.
            options: Set advanced options for CSV reading. This cannot be
                combined with any of the other options in this method.
            object_store: A pre-configured object store instance to use for
                accessing the file. When provided, the store is automatically
                registered for the URL scheme and host parsed from ``path``.

        Returns:
            DataFrame representation of the read CSV files
        """
        if object_store is not None:
            register_path = path[0] if isinstance(path, list) else path
            self._register_object_store_for_path(register_path, object_store)
        if options is not None and (
            schema is not None
            or not has_header
            or delimiter != ","
            or schema_infer_max_records != DEFAULT_MAX_INFER_SCHEMA
            or file_extension != ".csv"
            or table_partition_cols is not None
            or file_compression_type is not None
        ):
            message = (
                "Combining CsvReadOptions parameter with additional options "
                "is not supported. Use CsvReadOptions to set parameters."
            )
            warnings.warn(
                message,
                category=UserWarning,
                stacklevel=2,
            )

        options = (
            options
            if options is not None
            else CsvReadOptions(
                schema=schema,
                has_header=has_header,
                delimiter=delimiter,
                schema_infer_max_records=schema_infer_max_records,
                file_extension=file_extension,
                table_partition_cols=table_partition_cols,
                file_compression_type=file_compression_type,
            )
        )

        return DataFrame(
            self.ctx.read_csv(
                path,
                options.to_inner(),
            )
        )

    def read_parquet(
        self,
        path: str | pathlib.Path,
        table_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        parquet_pruning: bool = True,
        file_extension: str = ".parquet",
        skip_metadata: bool = True,
        schema: pa.Schema | None = None,
        file_sort_order: Sequence[Sequence[SortKey]] | None = None,
        object_store: Any | None = None,
    ) -> DataFrame:
        """Read a Parquet source into a :py:class:`~datafusion.dataframe.Dataframe`.

        Args:
            path: Path to the Parquet file.
            table_partition_cols: Partition columns.
            parquet_pruning: Whether the parquet reader should use the predicate
                to prune row groups.
            file_extension: File extension; only files with this extension are
                selected for data input.
            skip_metadata: Whether the parquet reader should skip any metadata
                that may be in the file schema. This can help avoid schema
                conflicts due to metadata.
            schema: An optional schema representing the parquet files. If None,
                the parquet reader will try to infer it based on data in the
                file.
            file_sort_order: Sort order for the file. Each sort key can be
                specified as a column name (``str``), an expression
                (``Expr``), or a ``SortExpr``.
            object_store: A pre-configured object store instance (e.g.
                :py:class:`~datafusion.object_store.AmazonS3`,
                :py:class:`~datafusion.object_store.GoogleCloud`,
                :py:class:`~datafusion.object_store.MicrosoftAzure`) to use
                for accessing the file. When provided, the store is
                automatically registered for the URL scheme and host parsed
                from ``path``, removing the need to call
                :py:meth:`register_object_store` separately. This is
                especially useful in multi-threaded environments where
                setting credentials via ``os.environ`` is not thread-safe.

        Returns:
            DataFrame representation of the read Parquet files

        Examples:
            Read a local Parquet file:

            >>> import datafusion
            >>> ctx = datafusion.SessionContext()
            >>> df = ctx.read_parquet("data.parquet")  # doctest: +SKIP

            Read from S3 with inline credentials (thread-safe):

            >>> from datafusion.object_store import AmazonS3  # doctest: +SKIP
            >>> store = AmazonS3(
            ...     bucket_name="my-bucket",
            ...     region="us-east-1",
            ...     access_key_id="...",
            ...     secret_access_key="...",
            ... )  # doctest: +SKIP
            >>> df = ctx.read_parquet(
            ...     "s3://my-bucket/data.parquet",
            ...     object_store=store,
            ... )  # doctest: +SKIP
        """
        if object_store is not None:
            self._register_object_store_for_path(path, object_store)
        if table_partition_cols is None:
            table_partition_cols = []
        table_partition_cols = _convert_table_partition_cols(table_partition_cols)
        file_sort_order = self._convert_file_sort_order(file_sort_order)
        return DataFrame(
            self.ctx.read_parquet(
                path,
                table_partition_cols,
                parquet_pruning,
                file_extension,
                skip_metadata,
                schema,
                file_sort_order,
            )
        )

    def read_avro(
        self,
        path: str | pathlib.Path,
        schema: pa.Schema | None = None,
        file_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        file_extension: str = ".avro",
        object_store: Any | None = None,
    ) -> DataFrame:
        """Create a :py:class:`DataFrame` for reading Avro data source.

        Args:
            path: Path to the Avro file.
            schema: The data source schema.
            file_partition_cols: Partition columns.
            file_extension: File extension to select.
            object_store: A pre-configured object store instance to use for
                accessing the file. When provided, the store is automatically
                registered for the URL scheme and host parsed from ``path``.

        Returns:
            DataFrame representation of the read Avro file
        """
        if object_store is not None:
            self._register_object_store_for_path(path, object_store)
        if file_partition_cols is None:
            file_partition_cols = []
        file_partition_cols = _convert_table_partition_cols(file_partition_cols)
        return DataFrame(
            self.ctx.read_avro(path, schema, file_partition_cols, file_extension)
        )

    def read_arrow(
        self,
        path: str | pathlib.Path,
        schema: pa.Schema | None = None,
        file_extension: str = ".arrow",
        file_partition_cols: list[tuple[str, str | pa.DataType]] | None = None,
        object_store: Any | None = None,
    ) -> DataFrame:
        """Create a :py:class:`DataFrame` for reading an Arrow IPC data source.

        Args:
            path: Path to the Arrow IPC file.
            schema: The data source schema.
            file_extension: File extension to select.
            file_partition_cols: Partition columns.
            object_store: A pre-configured object store instance to use for
                accessing the file. When provided, the store is automatically
                registered for the URL scheme and host parsed from ``path``.

        Returns:
            DataFrame representation of the read Arrow IPC file.

        Examples:
            >>> import tempfile, os
            >>> ctx = dfn.SessionContext()
            >>> table = pa.table({"a": [1, 2, 3]})
            >>> with tempfile.TemporaryDirectory() as tmpdir:
            ...     path = os.path.join(tmpdir, "data.arrow")
            ...     with pa.ipc.new_file(path, table.schema) as writer:
            ...         writer.write_table(table)
            ...     df = ctx.read_arrow(path)
            ...     df.collect()[0].column(0)
            <pyarrow.lib.Int64Array object at ...>
            [
              1,
              2,
              3
            ]

            Provide an explicit ``schema`` to override schema inference:

            >>> with tempfile.TemporaryDirectory() as tmpdir:
            ...     path = os.path.join(tmpdir, "data.arrow")
            ...     with pa.ipc.new_file(path, table.schema) as writer:
            ...         writer.write_table(table)
            ...     df = ctx.read_arrow(path, schema=pa.schema([("a", pa.int64())]))
            ...     df.collect()[0].column(0)
            <pyarrow.lib.Int64Array object at ...>
            [
              1,
              2,
              3
            ]

            Use ``file_extension`` to read files with a non-default extension:

            >>> with tempfile.TemporaryDirectory() as tmpdir:
            ...     path = os.path.join(tmpdir, "data.ipc")
            ...     with pa.ipc.new_file(path, table.schema) as writer:
            ...         writer.write_table(table)
            ...     df = ctx.read_arrow(path, file_extension=".ipc")
            ...     df.collect()[0].column(0)
            <pyarrow.lib.Int64Array object at ...>
            [
              1,
              2,
              3
            ]
        """
        if object_store is not None:
            self._register_object_store_for_path(path, object_store)
        if file_partition_cols is None:
            file_partition_cols = []
        file_partition_cols = _convert_table_partition_cols(file_partition_cols)
        return DataFrame(
            self.ctx.read_arrow(path, schema, file_extension, file_partition_cols)
        )

    def read_empty(self) -> DataFrame:
        """Create an empty :py:class:`DataFrame` with no columns or rows.

        See Also:
            This is an alias for :meth:`empty_table`.
        """
        return self.empty_table()

    def read_table(
        self, table: Table | TableProviderExportable | DataFrame | pa.dataset.Dataset
    ) -> DataFrame:
        """Creates a :py:class:`~datafusion.dataframe.DataFrame` from a table."""
        return DataFrame(self.ctx.read_table(table))

    def execute(self, plan: ExecutionPlan, partition: int) -> RecordBatchStream:
        """Execute a single partition of ``plan`` and stream its batches.

        Args:
            plan: The physical plan to execute.
            partition: Index of the partition to execute, in
                ``range(plan.partition_count)``.

        Returns:
            A stream over the record batches that partition produces.

        Raises:
            ValueError: If ``partition`` is not a valid index for ``plan``.
            OverflowError: If ``partition`` is negative, or too large to fit a
                platform-sized unsigned integer.

        Example usage:

        >>> import pyarrow as pa
        >>> from datafusion import SessionContext
        >>> ctx = SessionContext()
        >>> ctx.register_record_batches(
        ...     "t", [[pa.record_batch({"a": [1, 2]})], [pa.record_batch({"a": [3]})]]
        ... )
        >>> plan = ctx.sql("select a from t").execution_plan()
        >>> plan.partition_count
        2
        >>> sum(
        ...     batch.to_pyarrow().num_rows
        ...     for p in range(plan.partition_count)
        ...     for batch in ctx.execute(plan, p)
        ... )
        3
        """
        return RecordBatchStream(self.ctx.execute(plan._raw_plan, partition))

    @staticmethod
    def _convert_file_sort_order(
        file_sort_order: Sequence[Sequence[SortKey]] | None,
    ) -> list[list[expr_internal.SortExpr]] | None:
        """Convert nested ``SortKey`` sequences into raw sort expressions.

        Each ``SortKey`` can be a column name string, an ``Expr``, or a
        ``SortExpr`` and will be converted using
        :func:`datafusion.expr.sort_list_to_raw_sort_list`.
        """
        # Convert each ``SortKey`` in the provided sort order to the low-level
        # representation expected by the Rust bindings.
        return (
            [sort_list_to_raw_sort_list(f) for f in file_sort_order]
            if file_sort_order is not None
            else None
        )

    @staticmethod
    def _convert_table_partition_cols(
        table_partition_cols: list[tuple[str, str | pa.DataType]],
    ) -> list[tuple[str, pa.DataType]]:
        warn = False
        converted_table_partition_cols = []

        for col, data_type in table_partition_cols:
            if isinstance(data_type, str):
                warn = True
                if data_type == "string":
                    converted_data_type = pa.string()
                elif data_type == "int":
                    converted_data_type = pa.int32()
                else:
                    message = (
                        f"Unsupported literal data type '{data_type}' for partition "
                        "column. Supported types are 'string' and 'int'"
                    )
                    raise ValueError(message)
            else:
                converted_data_type = data_type

            converted_table_partition_cols.append((col, converted_data_type))

        if warn:
            message = (
                "using literals for table_partition_cols data types is deprecated,"
                "use pyarrow types instead"
            )
            warnings.warn(
                message,
                category=DeprecationWarning,
                stacklevel=2,
            )

        return converted_table_partition_cols

    def __datafusion_task_context_provider__(self) -> Any:
        """Access the PyCapsule FFI_TaskContextProvider."""
        return self.ctx.__datafusion_task_context_provider__()

    @property
    def __datafusion_codec_id__(self) -> str:
        """Identity this context carries when installed as an extension codec.

        A context can be installed on another session as an extension codec,
        which tags the payloads it writes with this string. It is unique per
        session, so two contexts can be installed on one session and a plan
        written through one will not be decoded by the other.

        Contexts derived from the same session report the same id, so only one
        of them can be installed on a given session. That is the intended
        answer: they are one session — see :py:class:`SessionContext` — so
        their payloads would be indistinguishable on decode.

        Examples:
            >>> from datafusion import SessionContext
            >>> ctx = SessionContext()
            >>> ctx.__datafusion_codec_id__.startswith("session:")
            True
            >>> ctx.__datafusion_codec_id__ == SessionContext().__datafusion_codec_id__
            False
        """
        return self.ctx.__datafusion_codec_id__

    def __datafusion_logical_extension_codec__(self, session: Any = None) -> Any:
        """Access the PyCapsule FFI_LogicalExtensionCodec.

        ``session`` is accepted so a context satisfies the same protocol an
        extension library implements, where the argument is how the library
        reaches the host's codec. A context already carries one, so the
        argument is ignored. See
        :py:class:`~datafusion.user_defined.LogicalExtensionCodecExportable`
        for what an extension library does with it.

        Args:
            session: Accepted and ignored.

        Returns:
            A ``datafusion_logical_extension_codec`` PyCapsule.

        Examples:
            >>> from datafusion import SessionContext
            >>> type(SessionContext().__datafusion_logical_extension_codec__()).__name__
            'PyCapsule'
        """
        return self.ctx.__datafusion_logical_extension_codec__(session)

    def __datafusion_query_planner__(self, session: Any = None) -> Any:
        """Access the ``FFI_QueryPlanner`` PyCapsule for the current planner.

        This is how you capture the planner a session already has in order to
        wrap it. Capture it *before* installing the new one, since
        :py:meth:`set_query_planner` replaces rather than layers.

        Args:
            session: Accepted and ignored. See
                :meth:`__datafusion_logical_extension_codec__`.

        Returns:
            A ``datafusion_query_planner`` PyCapsule wrapping the session's
            current planner, exported for a foreign planner to delegate to.

        Examples:
            >>> from datafusion import SessionContext
            >>> ctx = SessionContext()
            >>> fallback = ctx.__datafusion_query_planner__()
            >>> type(fallback).__name__
            'PyCapsule'

            Both spellings work, since the argument is ignored:

            >>> type(ctx.__datafusion_query_planner__(ctx)).__name__
            'PyCapsule'
        """
        return self.ctx.__datafusion_query_planner__(session)

    def with_logical_extension_codec(
        self,
        codec: LogicalExtensionCodecExportable | _PyCapsule,
        codec_id: str | None = None,
    ) -> SessionContext:
        """Create a new session context with an additional logical codec.

        Only FFI codecs are supported. Pass any object implementing
        ``__datafusion_logical_extension_codec__`` (see
        :py:class:`~datafusion.user_defined.LogicalExtensionCodecExportable`).

        Codecs compose: each call appends the codec rather than replacing
        codecs installed earlier, so one session can carry codecs from several
        independent libraries and the order they are installed in does not
        affect decoding.

        A serialized plan records which codec wrote each payload, as a short id
        taken from the codec's class.

        Shares its session with this context — see :py:class:`SessionContext`.

        See :ref:`extension_codec_ids` in the online documentation for how ids
        are assigned and what an extension codec has to implement, and
        :py:meth:`with_extensions` for installing a library's codecs and planner
        together.

        Args:
            codec: Object implementing ``__datafusion_logical_extension_codec__``
                (see
                :py:class:`~datafusion.user_defined.LogicalExtensionCodecExportable`),
                or a raw ``datafusion_logical_extension_codec`` PyCapsule.
            codec_id: Overrides the id the codec's payloads are tagged with.
                Normally unnecessary. Pass it when installing two instances of
                one class, which otherwise claim the same id, and when
                installing a bare ``PyCapsule``: a capsule has no class to take
                an id from, so it is given a random ``anon:`` id that differs on
                every install, and plans it encodes can never be decoded
                elsewhere.

        Returns:
            A new context carrying this codec in addition to any already
            installed.

        Raises:
            ValueError: If the resolved id is already installed on this session.

        Examples:
            A context exports its own codec, which stands in here for a real
            library's:

            >>> from datafusion import SessionContext
            >>> host = SessionContext()
            >>> capsule = host.__datafusion_logical_extension_codec__()
            >>> ctx = SessionContext().with_logical_extension_codec(
            ...     capsule, codec_id="my_library.Codec"
            ... )
            >>> ctx.logical_extension_codec_ids()
            ['my_library.Codec']

            Without ``codec_id`` a bare capsule gets an anonymous id, which is
            fine only if its plans never leave this session:

            >>> ctx = SessionContext().with_logical_extension_codec(capsule)
            >>> ctx.logical_extension_codec_ids()[0].startswith("anon:")
            True
        """
        new_internal = self.ctx.with_logical_extension_codec(codec, codec_id)
        new = SessionContext.__new__(SessionContext)
        new.ctx = new_internal
        return new

    def logical_extension_codec_ids(self) -> list[str]:
        """List the logical extension codecs installed on this session.

        Returns the identity of each installed codec, in install order. Those
        identities are what encoding stamps onto a payload and what decoding
        dispatches on, so this is how to check which library owns a plan and
        whether a session is able to decode one.

        DataFusion's own default codec is not listed. It handles whatever no
        installed codec claims, and it carries no identity to list.

        Returns:
            The installed codec ids, in install order. Empty if none are
            installed.

        Examples:
            >>> from datafusion import SessionContext
            >>> host = SessionContext()
            >>> host.logical_extension_codec_ids()
            []
            >>> capsule = host.__datafusion_logical_extension_codec__()
            >>> ctx = SessionContext().with_logical_extension_codec(
            ...     capsule, codec_id="my_library.Codec"
            ... )
            >>> ctx.logical_extension_codec_ids()
            ['my_library.Codec']
        """
        return self.ctx.logical_extension_codec_ids()

    def __datafusion_physical_extension_codec__(self, session: Any = None) -> Any:
        """Access the PyCapsule FFI_PhysicalExtensionCodec.

        See :meth:`__datafusion_logical_extension_codec__` for ``session``.

        Args:
            session: Accepted and ignored.

        Returns:
            A ``datafusion_physical_extension_codec`` PyCapsule.

        Examples:
            >>> from datafusion import SessionContext
            >>> ctx = SessionContext()
            >>> type(ctx.__datafusion_physical_extension_codec__()).__name__
            'PyCapsule'
        """
        return self.ctx.__datafusion_physical_extension_codec__(session)

    def physical_extension_codec_ids(self) -> list[str]:
        """List the physical extension codecs installed on this session.

        See :py:meth:`logical_extension_codec_ids`.

        Returns:
            The installed codec ids, in install order. Empty if none are
            installed.

        Examples:
            >>> from datafusion import SessionContext
            >>> host = SessionContext()
            >>> host.physical_extension_codec_ids()
            []
            >>> capsule = host.__datafusion_physical_extension_codec__()
            >>> ctx = SessionContext().with_physical_extension_codec(
            ...     capsule, codec_id="my_library.PhysicalCodec"
            ... )
            >>> ctx.physical_extension_codec_ids()
            ['my_library.PhysicalCodec']
        """
        return self.ctx.physical_extension_codec_ids()

    def with_physical_extension_codec(
        self,
        codec: PhysicalExtensionCodecExportable | _PyCapsule,
        codec_id: str | None = None,
    ) -> SessionContext:
        """Create a new session context with an additional physical codec.

        Only FFI codecs are supported. Pass any object implementing
        ``__datafusion_physical_extension_codec__`` (see
        :py:class:`~datafusion.user_defined.PhysicalExtensionCodecExportable`).

        Composes and assigns an id exactly as
        :py:meth:`with_logical_extension_codec` does, including when to pass
        ``codec_id`` and what the returned context shares. See that method.

        Args:
            codec: As :py:meth:`with_logical_extension_codec`, for the physical
                getter.
            codec_id: As :py:meth:`with_logical_extension_codec`.

        Returns:
            A new context carrying this codec in addition to any already
            installed.

        Raises:
            ValueError: If the resolved id is already installed on this session.

        Examples:
            >>> from datafusion import SessionContext
            >>> host = SessionContext()
            >>> capsule = host.__datafusion_physical_extension_codec__()
            >>> ctx = SessionContext().with_physical_extension_codec(
            ...     capsule, codec_id="my_library.PhysicalCodec"
            ... )
            >>> ctx.physical_extension_codec_ids()
            ['my_library.PhysicalCodec']
        """
        new_internal = self.ctx.with_physical_extension_codec(codec, codec_id)
        new = SessionContext.__new__(SessionContext)
        new.ctx = new_internal
        return new

    def with_python_udf_inlining(self, *, enabled: bool) -> SessionContext:
        """Control whether Python UDFs are embedded in serialized expressions.

        With ``enabled=True``, serialized expressions carry the Python
        code for any scalar, aggregate, or window UDFs they reference.
        The receiver rebuilds the UDFs from those bytes and does not
        need to register them first.

        With ``enabled=False``, serialized expressions store only the
        UDF names. This has two uses:

        * **Cross-language portability.** The bytes can be decoded by a
          non-Python receiver, which must already have UDFs registered
          under matching names.
        * **Safer deserialization.** :meth:`Expr.from_bytes` will refuse
          to rebuild Python UDFs rather than call ``cloudpickle.loads``
          on untrusted input.

        The setting affects :meth:`Expr.to_bytes` and
        :meth:`Expr.from_bytes` whenever this session is passed as the
        ``ctx`` argument. :func:`pickle.dumps` and :func:`pickle.loads`
        do not pass a context, so to apply the setting through pickle,
        register this session with
        :func:`datafusion.ipc.set_sender_ctx` on the sender and
        :func:`datafusion.ipc.set_worker_ctx` on the receiver.

        .. warning:: Security
            This setting narrows only :meth:`Expr.from_bytes`. Calling
            :func:`pickle.loads` on untrusted bytes remains unsafe
            regardless of the toggle.

        Shares its session with this context — see
        :py:class:`SessionContext`. The original context's own codec
        settings are unchanged.

        Args:
            enabled: Whether to embed Python UDFs in serialized
                expressions. Keyword-only and required, so callers must
                pick a mode explicitly. Fresh sessions behave as
                ``enabled=True`` until this method overrides the toggle.

        Returns:
            A new :class:`SessionContext` with the toggle applied.

        Examples:
            >>> import pyarrow as pa
            >>> from datafusion import SessionContext, Expr, col, udf
            >>> ctx = SessionContext()
            >>> identity = udf(lambda a: a, [pa.int64()], pa.int64(),
            ...                volatility="immutable", name="identity_demo")
            >>> ctx.register_udf(identity)
            >>> blob = identity(col("x")).to_bytes(ctx)
            >>> strict = SessionContext().with_python_udf_inlining(enabled=False)
            >>> try:
            ...     Expr.from_bytes(blob, strict)
            ... except Exception as e:
            ...     print("Refusing to deserialize" in str(e))
            True
        """
        new_internal = self.ctx.with_python_udf_inlining(enabled)
        new = SessionContext.__new__(SessionContext)
        new.ctx = new_internal
        return new
