Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,31 @@ def __init__(
self._model_providers = self._resolve_model_providers(model_providers)
default_provider_name = None
self._mcp_providers = mcp_providers or []
# When the YAML carries a default, ``get_default_provider_name`` already
# nudged the user with a ``DeprecationWarning``. Building the registry
# below would re-fire ``ModelProviderRegistry._warn_on_explicit_default``
# for the same root cause, so suppress that second warning. See PR #594
# review.
# Suppress ``ModelProviderRegistry._warn_on_explicit_default`` whenever
# *we* are filling ``default=`` on the user's behalf rather than the
# user actively opting into the deprecated registry-level default. Two
# such cases:
# 1. ``model_providers is None`` β€” the caller passed nothing, so we
# load the YAML's ``providers:`` list and (in the multi-provider
# case) ``resolve_model_provider_registry`` synthesises
# ``default=providers[0].name`` to satisfy ``check_implicit_default``.
# The fresh-install YAML ships three providers and no ``default:``
# key, so this fires for every default ``DataDesigner()``
# construction. The user has no actionable lever here, and the
# warning's "Specify provider= on each ModelConfig" remediation
# doesn't apply when they haven't built a ``ModelConfig`` at all.
# 2. ``default_provider_name is not None`` β€” the YAML carried a
# ``default:`` key and ``get_default_provider_name`` already
# emitted the YAML-level ``DeprecationWarning``. The registry
# warning would fire for the same root cause, so suppress it to
# avoid double-warning. See PR #594 review.
# Users who hand-construct a multi-provider list in Python still see
# the warning (they wrote the multi-provider intent themselves), and
# users who hand-construct ``ModelProviderRegistry(default=...)``
# directly always see it β€” those are the entry points #589 targets.
library_synthesised_default = model_providers is None or default_provider_name is not None
with warnings.catch_warnings():
if default_provider_name is not None:
if library_synthesised_default:
warnings.filterwarnings(
"ignore",
message="ModelProviderRegistry.default is deprecated",
Expand Down
54 changes: 54 additions & 0 deletions packages/data-designer/tests/interface/test_data_designer.py
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,60 @@ def test_init_yaml_default_emits_single_deprecation_warning(
)


def test_init_no_user_providers_no_yaml_default_stays_quiet(
stub_artifact_path: Path,
stub_managed_assets_path: Path,
) -> None:
"""Pin the bare-``DataDesigner()`` happy path: when the caller passes
nothing and the YAML carries multiple ``providers:`` but no ``default:``
key, ``resolve_model_provider_registry`` synthesises
``default=providers[0].name`` to satisfy ``check_implicit_default``. The
user did not opt into the deprecated registry-level default β€” the library
filled it in on their behalf β€” so ``_warn_on_explicit_default`` must stay
quiet. The fresh-install YAML ships exactly this shape (3 providers, no
``default:``), so a regression here is what every user sees on their first
``DataDesigner()`` call.

Counterpart to ``test_init_user_supplied_providers_preserve_first_wins_over_yaml_default``,
which pins that the warning *does* fire when the caller hand-builds a
multi-provider list themselves (they wrote the multi-provider intent, so
the deprecation nudge applies).
"""
yaml_providers = [
ModelProvider(
name="yaml-first",
endpoint="https://yaml-first.example.com/v1",
api_key="yaml-first-key",
),
ModelProvider(
name="yaml-second",
endpoint="https://yaml-second.example.com/v1",
api_key="yaml-second-key",
),
]

with warnings.catch_warnings(record=True) as caught:
warnings.simplefilter("always", DeprecationWarning)
with (
patch.object(dd_mod, "get_default_providers", return_value=yaml_providers),
patch.object(dd_mod, "get_default_provider_name", return_value=None),
):
data_designer = DataDesigner(
artifact_path=stub_artifact_path,
secret_resolver=PlaintextResolver(),
managed_assets_path=stub_managed_assets_path,
)

deprecation_messages = [str(w.message) for w in caught if issubclass(w.category, DeprecationWarning)]
registry_default_warnings = [m for m in deprecation_messages if "ModelProviderRegistry.default is deprecated" in m]
assert registry_default_warnings == [], (
"Library-synthesised default must not emit the registry-level deprecation; "
f"the user did not opt into it. Saw: {deprecation_messages}"
)
# Behavioral pin: first-wins still resolves correctly.
assert data_designer.model_provider_registry.get_default_provider_name() == "yaml-first"


def test_run_config_setting_persists(stub_artifact_path, stub_model_providers):
"""Test that run config setting persists across multiple calls."""
data_designer = DataDesigner(artifact_path=stub_artifact_path, model_providers=stub_model_providers)
Expand Down
Loading