Skip to content

Commit d2b17c2

Browse files
committed
Merge origin/dev into fix/yagni-dead-code
2 parents 67cff7d + 942f4ca commit d2b17c2

3 files changed

Lines changed: 98 additions & 24 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ All notable changes to the `unplug-ai` SDK.
66

77
### Added
88

9+
- Coverage tests for v1.0 deprecation shim re-exports (`unplug.core.*`, `guard_scan`, `scanner`, `safeguards`)
910
- Offline synthetic BIOES checkpoint fixture for ML unit tests (no real weights required)
1011
- CI wheel-only resolve for `unplug-ai[ml]` on Python 3.13 (catches sdist-only breakage)
1112

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
"""Deprecation shims must re-export canonical symbols and warn on import.
2+
3+
Flat ``unplug.core.*`` modules (and a few package-root paths) exist until v1.0
4+
so old imports keep working. See ``sdk/MIGRATION.md``.
5+
6+
Shims that still need DeprecationWarning (used internally today, so warning
7+
on import would fire for ``import unplug``):
8+
- ``unplug.core.models`` → ``unplug.ml.models``
9+
- ``unplug.core.extras`` → ``unplug.optional._base``
10+
"""
11+
12+
from __future__ import annotations
13+
14+
import importlib
15+
import sys
16+
17+
import pytest
18+
19+
# (shim_module, canonical_module, attr)
20+
# All of these emit DeprecationWarning on (re)import.
21+
_WARNING_SHIMS: list[tuple[str, str, str]] = [
22+
("unplug.core.approval", "unplug.core.agent.approval", "ApprovalProvider"),
23+
("unplug.core.asyncio_compat", "unplug.core.runtime.asyncio_compat", "run_coroutine_sync"),
24+
("unplug.core.boundaries", "unplug.core.agent.boundaries", "wrap_external_content"),
25+
("unplug.core.cache", "unplug.core.runtime.cache", "ScanCache"),
26+
("unplug.core.canary", "unplug.core.agent.canary", "CanaryRegistry"),
27+
("unplug.core.collusion", "unplug.core.agent.collusion", "collusion_findings"),
28+
("unplug.core.config", "unplug.config.guard", "PipelineConfig"),
29+
("unplug.core.config_loader", "unplug.config.loader", "load_from_file"),
30+
("unplug.core.content", "unplug.providers.content.protocol", "ContentProvider"),
31+
("unplug.core.decision", "unplug.core.policy.decision", "should_invoke_ml"),
32+
("unplug.core.degradation", "unplug.core.agent.degradation", "degraded_tool_findings"),
33+
("unplug.core.disposition", "unplug.core.policy.disposition", "DispositionLabel"),
34+
("unplug.core.encodings", "unplug.core.normalize.encodings", "HeuristicEncodingClassifier"),
35+
("unplug.core.intent", "unplug.core.agent.intent", "check_intent_mismatch"),
36+
("unplug.core.limits", "unplug.config.limits", "LimitConfig"),
37+
("unplug.core.logging", "unplug.core.runtime.logging", "get_correlation_id"),
38+
("unplug.core.luhn", "unplug.core.privacy.luhn", "luhn_valid"),
39+
(
40+
"unplug.core.model_runtime",
41+
"unplug.core.runtime.model_runtime",
42+
"load_active_model_provider",
43+
),
44+
("unplug.core.secrets", "unplug.core.privacy.secrets", "SecretsRegistry"),
45+
(
46+
"unplug.core.sensitive_context",
47+
"unplug.core.policy.sensitive_context",
48+
"apply_sensitive_context_boost",
49+
),
50+
("unplug.core.stats", "unplug.core.runtime.stats", "MetricsCollector"),
51+
("unplug.core.toolchain", "unplug.core.agent.toolchain", "toolchain_findings"),
52+
("unplug.core.trajectory", "unplug.core.agent.trajectory", "trajectory_findings"),
53+
("unplug.core.versions", "unplug.core.runtime.versions", "NORMALIZER_VERSION"),
54+
("unplug.guard_scan", "unplug.api.results", "refresh_scan_result"),
55+
("unplug.scanner", "unplug.scanners.base", "Scanner"),
56+
("unplug.safeguards", "unplug.scanners", "ScannerRegistry"),
57+
]
58+
59+
# Re-export only (no DeprecationWarning yet — see module docstring).
60+
_SILENT_SHIMS: list[tuple[str, str, str]] = [
61+
("unplug.core.models", "unplug.ml.models", "ModelProvider"),
62+
("unplug.core.extras", "unplug.optional._base", "require_extra"),
63+
]
64+
65+
66+
def _reload_fresh(module_name: str) -> object:
67+
"""Drop cached module so the next import re-runs module-level warn()."""
68+
sys.modules.pop(module_name, None)
69+
return importlib.import_module(module_name)
70+
71+
72+
@pytest.mark.parametrize(("shim", "canonical", "attr"), _WARNING_SHIMS)
73+
def test_deprecation_shim_warns_and_reexports(shim: str, canonical: str, attr: str) -> None:
74+
canon_mod = importlib.import_module(canonical)
75+
expected = getattr(canon_mod, attr)
76+
77+
with pytest.warns(DeprecationWarning, match="deprecated"):
78+
shim_mod = _reload_fresh(shim)
79+
80+
assert getattr(shim_mod, attr) is expected
81+
82+
83+
@pytest.mark.parametrize(("shim", "canonical", "attr"), _SILENT_SHIMS)
84+
def test_silent_reexport_shim_identity(shim: str, canonical: str, attr: str) -> None:
85+
# Intentionally no DeprecationWarning yet (see module docstring).
86+
canon_mod = importlib.import_module(canonical)
87+
shim_mod = importlib.import_module(shim)
88+
assert getattr(shim_mod, attr) is getattr(canon_mod, attr)
89+
90+
91+
def test_safeguards_registry_alias_is_scanner_registry() -> None:
92+
with pytest.warns(DeprecationWarning, match="deprecated"):
93+
safeguards = _reload_fresh("unplug.safeguards")
94+
from unplug.scanners import ScannerRegistry
95+
96+
assert safeguards.SafeguardRegistry is ScannerRegistry
97+
assert safeguards.ScannerRegistry is ScannerRegistry

‎sdk/tests/unit/core/test_shim_deprecation.py‎

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)