Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 0 additions & 104 deletions crates/core/src/config.rs

This file was deleted.

3 changes: 0 additions & 3 deletions crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ use pyo3::prelude::*;
pub mod catalog;
pub mod common;

#[allow(clippy::borrow_deref_ref)]
mod config;
#[allow(clippy::borrow_deref_ref)]
pub mod context;
#[allow(clippy::borrow_deref_ref)]
Expand Down Expand Up @@ -90,7 +88,6 @@ fn _internal(py: Python, m: Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<udaf::PyAggregateUDF>()?;
m.add_class::<udwf::PyWindowUDF>()?;
m.add_class::<udtf::PyTableFunction>()?;
m.add_class::<config::PyConfig>()?;
m.add_class::<sql::logical::PyLogicalPlan>()?;
m.add_class::<physical_plan::PyExecutionPlan>()?;
m.add_class::<record_batch::PyRecordBatch>()?;
Expand Down
15 changes: 1 addition & 14 deletions docs/source/contributor-guide/ffi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -149,20 +149,7 @@ interior-mutable state. In practice this means that any ``#[pyclass]`` containin
``Arc<RwLock<_>>`` or similar synchronized primitive must opt into ``#[pyclass(frozen)]``
unless there is a compelling reason not to.

The :mod:`datafusion` configuration helpers illustrate the preferred pattern. The
``PyConfig`` class in :file:`src/config.rs` stores an ``Arc<RwLock<ConfigOptions>>`` and is
explicitly frozen so callers interact with configuration state through provided methods
instead of mutating the container directly:

.. code-block:: rust

#[pyclass(from_py_object, name = "Config", module = "datafusion", subclass, frozen)]
#[derive(Clone)]
pub(crate) struct PyConfig {
config: Arc<RwLock<ConfigOptions>>,
}

The same approach applies to execution contexts. ``PySessionContext`` in
The execution context illustrates the preferred pattern. ``PySessionContext`` in
:file:`src/context.rs` stays frozen even though it shares mutable state internally via
``SessionContext``. This ensures PyO3 tracks borrows correctly while Python-facing APIs
clone the inner ``SessionContext`` or return new wrappers instead of mutating the
Expand Down
27 changes: 27 additions & 0 deletions docs/source/user-guide/upgrade-guides.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,33 @@
Upgrade Guides
==============

DataFusion 54.0.0
-----------------

The ``Config`` class has been removed. It was a standalone wrapper around
``ConfigOptions`` that could not be connected to a ``SessionContext``, making it
effectively unusable. Use :py:class:`~datafusion.context.SessionConfig` instead,
which is passed directly to ``SessionContext``.

Before:

.. code-block:: python

from datafusion import Config

config = Config()
config.set("datafusion.execution.batch_size", "4096")
# config could not be passed to SessionContext

After:

.. code-block:: python

from datafusion import SessionConfig, SessionContext

config = SessionConfig().set("datafusion.execution.batch_size", "4096")
ctx = SessionContext(config)

DataFusion 53.0.0
-----------------

Expand Down
2 changes: 0 additions & 2 deletions python/datafusion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
from . import functions, object_store, substrait, unparser

# The following imports are okay to remain as opaque to the user.
from ._internal import Config
from .catalog import Catalog, Table
from .col import col, column
from .common import DFSchema
Expand Down Expand Up @@ -76,7 +75,6 @@
"Accumulator",
"AggregateUDF",
"Catalog",
"Config",
"CsvReadOptions",
"DFSchema",
"DataFrame",
Expand Down
35 changes: 2 additions & 33 deletions python/tests/test_concurrency.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from concurrent.futures import ThreadPoolExecutor

import pyarrow as pa
from datafusion import Config, SessionContext, col, lit
from datafusion import SessionContext, col, lit
from datafusion import functions as f
from datafusion.common import SqlSchema

Expand All @@ -34,16 +34,14 @@ def _run_in_threads(fn, count: int = 8) -> None:


def test_concurrent_access_to_shared_structures() -> None:
"""Exercise SqlSchema, Config, and DataFrame concurrently."""
"""Exercise SqlSchema and DataFrame concurrently."""

schema = SqlSchema("concurrency")
config = Config()
ctx = SessionContext()

batch = pa.record_batch([pa.array([1, 2, 3], type=pa.int32())], names=["value"])
df = ctx.create_dataframe([[batch]])

config_key = "datafusion.execution.batch_size"
expected_rows = batch.num_rows

def worker(index: int) -> None:
Expand All @@ -54,41 +52,12 @@ def worker(index: int) -> None:
assert isinstance(schema.views, list)
assert isinstance(schema.functions, list)

config.set(config_key, str(1024 + index))
assert config.get(config_key) is not None
# Access the full config map to stress lock usage.
assert config_key in config.get_all()

batches = df.collect()
assert sum(batch.num_rows for batch in batches) == expected_rows

_run_in_threads(worker, count=12)


def test_config_set_during_get_all() -> None:
"""Ensure config writes proceed while another thread reads all entries."""

config = Config()
key = "datafusion.execution.batch_size"

def reader() -> None:
for _ in range(200):
# get_all should not hold the lock while converting to Python objects
config.get_all()

def writer() -> None:
for index in range(200):
config.set(key, str(1024 + index))

with ThreadPoolExecutor(max_workers=2) as executor:
reader_future = executor.submit(reader)
writer_future = executor.submit(writer)
reader_future.result(timeout=10)
writer_future.result(timeout=10)

assert config.get(key) is not None


def test_case_builder_reuse_from_multiple_threads() -> None:
"""Ensure the case builder can be safely reused across threads."""

Expand Down
42 changes: 0 additions & 42 deletions python/tests/test_config.py

This file was deleted.

Loading