Skip to content

Commit e9d3115

Browse files
committed
fix: allow subclassing of config again
1 parent 9952bbb commit e9d3115

2 files changed

Lines changed: 39 additions & 34 deletions

File tree

sqlmesh/core/config/root.py

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import zlib
77

88
from pydantic import Field
9+
from pydantic.functional_validators import BeforeValidator
910
from sqlglot import exp
1011
from sqlglot.helper import first
1112
from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
@@ -45,9 +46,40 @@
4546
from sqlmesh.utils.errors import ConfigError
4647
from sqlmesh.utils.pydantic import model_validator
4748

49+
50+
def validate_no_past_ttl(v: str) -> str:
51+
current_time = now()
52+
if to_timestamp(v, relative_base=current_time) < to_timestamp(current_time):
53+
raise ValueError(
54+
f"TTL '{v}' is in the past. Please specify a relative time in the future. Ex: `in 1 week` instead of `1 week`."
55+
)
56+
return v
57+
58+
59+
def gateways_ensure_dict(value: t.Dict[str, t.Any]) -> t.Dict[str, t.Any]:
60+
try:
61+
if not isinstance(value, GatewayConfig):
62+
GatewayConfig.parse_obj(value)
63+
return {"": value}
64+
except Exception:
65+
return value
66+
67+
68+
def validate_regex_key_dict(value: t.Dict[str | re.Pattern, t.Any]) -> t.Dict[re.Pattern, t.Any]:
69+
return compile_regex_mapping(value)
70+
71+
4872
if t.TYPE_CHECKING:
4973
from sqlmesh.core._typing import Self
5074

75+
NoPastTTLString = str
76+
GatewayDict = t.Dict[str, GatewayConfig]
77+
RegexKeyDict = t.Dict[re.Pattern, str]
78+
else:
79+
NoPastTTLString = t.Annotated[str, BeforeValidator(validate_no_past_ttl)]
80+
GatewayDict = t.Annotated[t.Dict[str, GatewayConfig], BeforeValidator(gateways_ensure_dict)]
81+
RegexKeyDict = t.Annotated[t.Dict[re.Pattern, str], BeforeValidator(validate_regex_key_dict)]
82+
5183

5284
class Config(BaseConfig):
5385
"""An object used by a Context to configure your SQLMesh project.
@@ -286,37 +318,3 @@ def dialect(self) -> t.Optional[str]:
286318
@property
287319
def fingerprint(self) -> str:
288320
return str(zlib.crc32(pickle.dumps(self.dict(exclude={"loader", "notification_targets"}))))
289-
290-
291-
def validate_no_past_ttl(v: str) -> str:
292-
current_time = now()
293-
if to_timestamp(v, relative_base=current_time) < to_timestamp(current_time):
294-
raise ValueError(
295-
f"TTL '{v}' is in the past. Please specify a relative time in the future. Ex: `in 1 week` instead of `1 week`."
296-
)
297-
return v
298-
299-
300-
def gateways_ensure_dict(value: t.Dict[str, t.Any]) -> t.Dict[str, t.Any]:
301-
try:
302-
if not isinstance(value, GatewayConfig):
303-
GatewayConfig.parse_obj(value)
304-
return {"": value}
305-
except Exception:
306-
return value
307-
308-
309-
def validate_regex_key_dict(value: t.Dict[str | re.Pattern, t.Any]) -> t.Dict[re.Pattern, t.Any]:
310-
return compile_regex_mapping(value)
311-
312-
313-
if t.TYPE_CHECKING:
314-
NoPastTTLString = str
315-
GatewayDict = t.Dict[str, GatewayConfig]
316-
RegexKeyDict = t.Dict[re.Pattern, str]
317-
else:
318-
from pydantic.functional_validators import BeforeValidator
319-
320-
NoPastTTLString = t.Annotated[str, BeforeValidator(validate_no_past_ttl)]
321-
GatewayDict = t.Annotated[t.Dict[str, GatewayConfig], BeforeValidator(gateways_ensure_dict)]
322-
RegexKeyDict = t.Annotated[t.Dict[re.Pattern, str], BeforeValidator(validate_regex_key_dict)]

tests/core/test_config.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -974,3 +974,10 @@ class TestConfig(DuckDBConnectionConfig):
974974
pass
975975

976976
TestConfig()
977+
978+
979+
@pytest.mark.isolated
980+
def test_config_subclassing() -> None:
981+
class ConfigSubclass(Config): ...
982+
983+
ConfigSubclass()

0 commit comments

Comments
 (0)