Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(config): remove option_context #10438

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
85 changes: 45 additions & 40 deletions ibis/backends/clickhouse/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import ibis.common.exceptions as exc
import ibis.expr.datatypes as dt
import ibis.expr.types as ir
from ibis import config, udf
from ibis import udf
from ibis.backends.clickhouse.tests.conftest import (
CLICKHOUSE_HOST,
CLICKHOUSE_PASS,
Expand Down Expand Up @@ -72,21 +72,19 @@ def test_limit_overrides_expr(con, alltypes):
assert len(result) == 5


def test_limit_equals_none_no_limit(alltypes):
with config.option_context("sql.default_limit", 10):
result = alltypes.execute(limit=None)
assert len(result) > 10
def test_limit_equals_none_no_limit(alltypes, monkeypatch):
monkeypatch.setattr(ibis.options.sql, "default_limit", 10)
result = alltypes.execute(limit=None)
assert len(result) > 10


def test_verbose_log_queries(con):
def test_verbose_log_queries(con, monkeypatch):
queries = []

def logger(x):
queries.append(x)
monkeypatch.setattr(ibis.options, "verbose", True)
monkeypatch.setattr(ibis.options, "verbose_log", queries.append)

with config.option_context("verbose", True):
with config.option_context("verbose_log", logger):
con.table("functional_alltypes")
con.table("functional_alltypes")

expected = "DESCRIBE functional_alltypes"

Expand All @@ -95,36 +93,43 @@ def logger(x):
assert expected in queries


def test_sql_query_limits(alltypes):
table = alltypes
with config.option_context("sql.default_limit", 100000):
# table has 25 rows
assert len(table.execute()) == 7300
# comply with limit arg for Table
assert len(table.execute(limit=10)) == 10
# state hasn't changed
assert len(table.execute()) == 7300
# non-Table ignores default_limit
assert table.count().execute() == 7300
# non-Table doesn't observe limit arg
assert table.count().execute(limit=10) == 7300
with config.option_context("sql.default_limit", 20):
# Table observes default limit setting
assert len(table.execute()) == 20
# explicit limit= overrides default
assert len(table.execute(limit=15)) == 15
assert len(table.execute(limit=23)) == 23
# non-Table ignores default_limit
assert table.count().execute() == 7300
# non-Table doesn't observe limit arg
assert table.count().execute(limit=10) == 7300
def test_sql_query_limits_big(alltypes, monkeypatch):
monkeypatch.setattr(ibis.options.sql, "default_limit", 100_000)

# alltypes has 7300 rows
assert len(alltypes.execute()) == 7300 # comply with limit arg for alltypes
assert len(alltypes.execute(limit=10)) == 10
# state hasn't changed
assert len(alltypes.execute()) == 7300
# non-alltypes ignores default_limit
assert alltypes.count().execute() == 7300
# non-alltypes doesn't observe limit arg
assert alltypes.count().execute(limit=10) == 7300


def test_sql_query_limits_small(alltypes, monkeypatch):
monkeypatch.setattr(ibis.options.sql, "default_limit", 20)

# alltypes observes default limit setting
assert len(alltypes.execute()) == 20
# explicit limit= overrides default
assert len(alltypes.execute(limit=15)) == 15
assert len(alltypes.execute(limit=23)) == 23
# non-alltypes ignores default_limit
assert alltypes.count().execute() == 7300
# non-alltypes doesn't observe limit arg
assert alltypes.count().execute(limit=10) == 7300


def test_sql_query_limits_none(alltypes, monkeypatch):
monkeypatch.setattr(ibis.options.sql, "default_limit", None)

# eliminating default_limit doesn't break anything
with config.option_context("sql.default_limit", None):
assert len(table.execute()) == 7300
assert len(table.execute(limit=15)) == 15
assert len(table.execute(limit=10000)) == 7300
assert table.count().execute() == 7300
assert table.count().execute(limit=10) == 7300
assert len(alltypes.execute()) == 7300
assert len(alltypes.execute(limit=15)) == 15
assert len(alltypes.execute(limit=10000)) == 7300
assert alltypes.count().execute() == 7300
assert alltypes.count().execute(limit=10) == 7300


def test_embedded_identifier_quoting(alltypes):
Expand Down
102 changes: 58 additions & 44 deletions ibis/backends/impala/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import ibis
import ibis.expr.datatypes as dt
import ibis.expr.types as ir
from ibis import config
from ibis.tests.util import assert_equal

pytest.importorskip("impala")
Expand Down Expand Up @@ -66,16 +65,17 @@ def test_result_as_dataframe(con, alltypes):
assert len(result) == 10


def test_adapt_scalar_array_results(con, alltypes):
def test_adapt_scalar_array_results(con, alltypes, monkeypatch):
table = alltypes

expr = table.double_col.sum()
result = con.execute(expr)
assert isinstance(result, float)

with config.option_context("interactive", True):
result2 = expr.execute()
assert isinstance(result2, float)
monkeypatch.setattr(ibis.options, "interactive", True)

result2 = expr.execute()
assert isinstance(result2, float)

expr = (
table.group_by("string_col").aggregate([table.count().name("count")]).string_col
Expand All @@ -85,7 +85,7 @@ def test_adapt_scalar_array_results(con, alltypes):
assert isinstance(result, pd.Series)


def test_interactive_repr_call_failure(con):
def test_interactive_repr_call_failure(con, monkeypatch):
t = con.table("lineitem").limit(100000)

t = t.select(t, t.l_receiptdate.cast("timestamp").name("date"))
Expand All @@ -100,8 +100,9 @@ def test_interactive_repr_call_failure(con):

metric = expr["avg_px"].mean().over(w2)
enriched = expr.select(expr, metric)
with config.option_context("interactive", True):
repr(enriched)

monkeypatch.setattr(ibis.options, "interactive", True)
repr(enriched)


def test_array_default_limit(con, alltypes):
Expand All @@ -118,20 +119,22 @@ def test_limit_overrides_expr(con, alltypes):
assert len(result) == 5


def test_limit_equals_none_no_limit(alltypes):
def test_limit_equals_none_no_limit(alltypes, monkeypatch):
t = alltypes

with config.option_context("sql.default_limit", 10):
result = t.execute(limit=None)
assert len(result) > 10
monkeypatch.setattr(ibis.options.sql, "default_limit", 10)

result = t.execute(limit=None)
assert len(result) > 10

def test_verbose_log_queries(con, test_data_db):

def test_verbose_log_queries(con, test_data_db, monkeypatch):
queries = []

with config.option_context("verbose", True):
with config.option_context("verbose_log", queries.append):
con.table("orders", database=test_data_db)
monkeypatch.setattr(ibis.options, "verbose", True)
monkeypatch.setattr(ibis.options, "verbose_log", queries.append)

con.table("orders", database=test_data_db)

# we can't make assertions about the length of queries, since the Python GC
# could've collected a temporary pandas table any time between construction
Expand All @@ -140,36 +143,47 @@ def test_verbose_log_queries(con, test_data_db):
assert expected in queries


def test_sql_query_limits(con, test_data_db):
def test_sql_query_limits_big(con, test_data_db, monkeypatch):
table = con.table("nation", database=test_data_db)
with config.option_context("sql.default_limit", 100000):
# table has 25 rows
assert len(table.execute()) == 25
# comply with limit arg for Table
assert len(table.execute(limit=10)) == 10
# state hasn't changed
assert len(table.execute()) == 25
# non-Table ignores default_limit
assert table.count().execute() == 25
# non-Table doesn't observe limit arg
assert table.count().execute(limit=10) == 25
with config.option_context("sql.default_limit", 20):
# Table observes default limit setting
assert len(table.execute()) == 20
# explicit limit= overrides default
assert len(table.execute(limit=15)) == 15
assert len(table.execute(limit=23)) == 23
# non-Table ignores default_limit
assert table.count().execute() == 25
# non-Table doesn't observe limit arg
assert table.count().execute(limit=10) == 25
monkeypatch.setattr(ibis.options.sql, "default_limit", 100_000)

# table has 25 rows
assert len(table.execute()) == 25
# comply with limit arg for Table
assert len(table.execute(limit=10)) == 10
# state hasn't changed
assert len(table.execute()) == 25
# non-Table ignores default_limit
assert table.count().execute() == 25
# non-Table doesn't observe limit arg
assert table.count().execute(limit=10) == 25


def test_sql_query_limits_small(con, test_data_db, monkeypatch):
table = con.table("nation", database=test_data_db)
monkeypatch.setattr(ibis.options.sql, "default_limit", 20)

# Table observes default limit setting
assert len(table.execute()) == 20
# explicit limit= overrides default
assert len(table.execute(limit=15)) == 15
assert len(table.execute(limit=23)) == 23
# non-Table ignores default_limit
assert table.count().execute() == 25
# non-Table doesn't observe limit arg
assert table.count().execute(limit=10) == 25


def test_sql_query_limits_none(con, test_data_db, monkeypatch):
table = con.table("nation", database=test_data_db)
monkeypatch.setattr(ibis.options.sql, "default_limit", None)

# eliminating default_limit doesn't break anything
with config.option_context("sql.default_limit", None):
assert len(table.execute()) == 25
assert len(table.execute(limit=15)) == 15
assert len(table.execute(limit=10000)) == 25
assert table.count().execute() == 25
assert table.count().execute(limit=10) == 25
assert len(table.execute()) == 25
assert len(table.execute(limit=15)) == 15
assert len(table.execute(limit=10000)) == 25
assert table.count().execute() == 25
assert table.count().execute(limit=10) == 25


def test_set_compression_codec(con):
Expand Down
8 changes: 4 additions & 4 deletions ibis/backends/postgres/tests/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import ibis
import ibis.expr.datatypes as dt
import ibis.expr.types as ir
from ibis import config
from ibis import literal as L

pytest.importorskip("psycopg2")
Expand Down Expand Up @@ -656,11 +655,12 @@ def test_not_exists(alltypes, df):
tm.assert_frame_equal(result, expected, check_index_type=False, check_dtype=False)


def test_interactive_repr_shows_error(alltypes):
def test_interactive_repr_shows_error(alltypes, monkeypatch):
expr = alltypes.int_col.convert_base(10, 2)

with config.option_context("interactive", True):
result = repr(expr)
monkeypatch.setattr(ibis.options, "interactive", True)

result = repr(expr)

assert "OperationNotDefinedError" in result
assert "BaseConvert" in result
Expand Down
31 changes: 17 additions & 14 deletions ibis/backends/tests/test_interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
# limitations under the License.
from __future__ import annotations

import shutil

import pytest

import ibis
import ibis.common.exceptions as exc
from ibis import config


@pytest.fixture
Expand All @@ -40,19 +41,19 @@
assert len(queries) >= 1


def test_repr_png_is_none_in_interactive(table):
with config.option_context("interactive", True):
assert table._repr_png_() is None
def test_repr_png_is_none_in_interactive(table, monkeypatch):
monkeypatch.setattr(ibis.options, "interactive", True)
assert table._repr_png_() is None


def test_repr_png_is_not_none_in_not_interactive(table):
def test_repr_png_is_not_none_in_not_interactive(table, monkeypatch):
pytest.importorskip("ibis.expr.visualize")

with (
config.option_context("interactive", False),
config.option_context("graphviz_repr", True),
):
assert table._repr_png_() is not None
monkeypatch.setattr(ibis.options, "interactive", False)
monkeypatch.setattr(ibis.options, "graphviz_repr", True)

Check warning on line 53 in ibis/backends/tests/test_interactive.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/tests/test_interactive.py#L52-L53

Added lines #L52 - L53 were not covered by tests

assert shutil.which("dot") is not None
assert table._repr_png_() is not None

Check warning on line 56 in ibis/backends/tests/test_interactive.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/tests/test_interactive.py#L55-L56

Added lines #L55 - L56 were not covered by tests


@pytest.mark.notimpl(["polars"])
Expand All @@ -70,12 +71,14 @@


@pytest.mark.notimpl(["polars"])
def test_disable_query_limit(table, queries):
def test_disable_query_limit(table, queries, monkeypatch):
assert ibis.options.sql.default_limit is None

with config.option_context("sql.default_limit", 10):
assert ibis.options.sql.default_limit == 10
repr(table.select("id", "bool_col"))
monkeypatch.setattr(ibis.options.sql, "default_limit", 10)

assert ibis.options.sql.default_limit == 10

repr(table.select("id", "bool_col"))

assert len(queries) >= 1

Expand Down
21 changes: 0 additions & 21 deletions ibis/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from __future__ import annotations

import contextlib
from collections.abc import Callable # noqa: TCH003
from typing import Annotated, Any, Optional

Expand All @@ -27,21 +26,6 @@ def set(self, key: str, value: Any) -> None:
conf = getattr(conf, field)
setattr(conf, key, value)

@contextlib.contextmanager
def _with_temporary(self, options):
try:
old = {}
for key, value in options.items():
old[key] = self.get(key)
self.set(key, value)
yield
finally:
for key, value in old.items():
self.set(key, value)

def __call__(self, options):
return self._with_temporary(options)


class SQL(Config):
"""SQL-related options.
Expand Down Expand Up @@ -207,9 +191,4 @@ def _default_backend() -> Any:
options = Options()


@public
def option_context(key, new_value):
return options({key: new_value})


public(options=options)
Loading