Skip to content

Commit 9a0235b

Browse files
committed
set base model + update release history
Signed-off-by: geo-martino <gm.login+tech@pm.me>
1 parent 6d04af2 commit 9a0235b

8 files changed

Lines changed: 42 additions & 26 deletions

File tree

dbt_contracts/_core.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from pydantic import BaseModel, ConfigDict
2+
3+
4+
class BaseModelConfig(BaseModel):
5+
"""
6+
Base class for all models in the dbt_contracts package.
7+
8+
Sets common config and functionality as required.
9+
"""
10+
model_config = ConfigDict(validate_assignment=True, validate_default=True)

dbt_contracts/contracts/_core.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66

77
from dbt.artifacts.schemas.catalog import CatalogArtifact
88
from dbt.contracts.graph.manifest import Manifest
9-
from pydantic import BaseModel
109

10+
from dbt_contracts._core import BaseModelConfig
1111
from dbt_contracts.contracts.result import Result, RESULT_PROCESSOR_MAP
1212
from dbt_contracts.properties import PropertiesIO
1313
from dbt_contracts.types import ItemT, ParentT
1414

1515

16-
class ContractPart(BaseModel, metaclass=ABCMeta):
16+
class ContractPart(BaseModelConfig, metaclass=ABCMeta):
1717
"""
1818
A part of a contract.
1919

dbt_contracts/contracts/conditions/properties.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,16 @@ class PathCondition(ContractCondition[BaseResource], PatternMatcher):
4242
- ["path", "to", "another", "folder2"]
4343
- ["path", "to", "another", "folder3"]
4444
"""
45-
model_config = ConfigDict(validate_assignment=True)
46-
45+
# noinspection PyNestedDecorators
4746
@field_validator("include", "exclude", mode="after", check_fields=True)
4847
@classmethod
49-
def _escape_backslashes_in_windows_paths(cls, values: Sequence[str]) -> Sequence[str]:
50-
return [path.replace("\\", "\\\\") for path in values]
48+
def escape_backslashes_in_windows_paths[T: Sequence[str]](cls, values: T) -> T:
49+
"""
50+
Replace all single backslashes with double backslashes in Windows paths.
51+
52+
This is needed to ensure regex patterns are correctly interpreted and avoid any 'bad escape' errors.
53+
"""
54+
return values.__class__(path.replace("\\", "\\\\") for path in values)
5155

5256
# noinspection PyNestedDecorators
5357
@field_validator("include", "exclude", mode="before")

dbt_contracts/contracts/matchers.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
from collections.abc import Sequence, Collection
33
from typing import Annotated, Self
44

5-
from pydantic import BaseModel, Field, BeforeValidator, model_validator
5+
from pydantic import Field, BeforeValidator, model_validator
66

7+
from dbt_contracts._core import BaseModelConfig
78
from dbt_contracts.contracts.utils import to_tuple
89

910

10-
class RangeMatcher(BaseModel):
11+
class RangeMatcher(BaseModelConfig):
1112
min_count: int = Field(
1213
description="The minimum count allowed.",
1314
ge=1,
@@ -39,7 +40,7 @@ def _match(self, count: int, kind: str) -> str | None:
3940
return f"Too {quantifier} {kind} found: {count}. Expected: {expected}."
4041

4142

42-
class StringMatcher(BaseModel):
43+
class StringMatcher(BaseModelConfig):
4344
ignore_whitespace: bool = Field(
4445
description="Ignore any whitespaces when comparing data type keys.",
4546
default=False,
@@ -78,7 +79,7 @@ def _match(self, actual: str | None, expected: str | None) -> bool:
7879
return match
7980

8081

81-
class PatternMatcher(BaseModel):
82+
class PatternMatcher(BaseModelConfig):
8283
include: Annotated[Sequence[str], BeforeValidator(to_tuple)] = Field(
8384
description="Patterns to match against for values to include",
8485
default=tuple(),

dbt_contracts/contracts/result.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
from dbt.artifacts.resources.v1.components import ColumnInfo
88
from dbt.artifacts.resources.v1.macro import MacroArgument
99
from dbt.contracts.graph.nodes import ModelNode, SourceDefinition, Macro
10-
from pydantic import BaseModel
1110

11+
from dbt_contracts._core import BaseModelConfig
1212
from dbt_contracts.properties import PropertiesIO
1313
from dbt_contracts.types import ItemT, ParentT
1414

1515

16-
class Result[I: ItemT, P: ParentT](BaseModel, metaclass=ABCMeta):
16+
class Result[I: ItemT, P: ParentT](BaseModelConfig, metaclass=ABCMeta):
1717
"""Store information of the result from a contract execution."""
1818
name: str
1919
path: Path | None

dbt_contracts/formatters/_core.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
from collections.abc import Callable, Collection, Iterable
33
from typing import Any
44

5-
from pydantic import BaseModel
6-
5+
from dbt_contracts._core import BaseModelConfig
76
from dbt_contracts.contracts.result import Result
87

98
type KeysT[T] = str | Callable[[T], Any]
@@ -34,7 +33,7 @@ def get_values_from_object[T](obj: T, keys: Collection[KeysT[T]]) -> Iterable[An
3433
return (get_value_from_object(obj, key) for key in keys)
3534

3635

37-
class ResultsFormatter[T: Result](BaseModel, metaclass=ABCMeta):
36+
class ResultsFormatter[T: Result](BaseModelConfig, metaclass=ABCMeta):
3837
"""
3938
Base class for implementations which format a set of :py:class:`.Result` objects to a string for displaying results.
4039
Usually used to format results for logging purposes.

dbt_contracts/formatters/table.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
from typing import Self, Any, Annotated, Literal
66

77
from colorama import Fore
8-
from pydantic import BaseModel, Field, model_validator, BeforeValidator
8+
from pydantic import Field, model_validator, BeforeValidator
99

10+
from dbt_contracts._core import BaseModelConfig
1011
from dbt_contracts.contracts.result import Result
1112
from dbt_contracts.contracts.utils import to_tuple
1213
from dbt_contracts.formatters import ResultsFormatter
@@ -22,7 +23,7 @@ def _align_and_pad_print_length(value: str, alignment: Literal["<", "^", ">"], w
2223
return f"{value:{alignment}{width}}"
2324

2425

25-
class TableCellBuilder[T: Result](BaseModel):
26+
class TableCellBuilder[T: Result](BaseModelConfig):
2627
key: str | Callable[[T], str] = Field(
2728
description="The key to use to get the value from the :py:class:`.Result` "
2829
"or a callable object which returns a formatted string for the value",
@@ -151,7 +152,7 @@ def build(self, result: T, min_width: int = None) -> str:
151152
return value
152153

153154

154-
class TableRowBuilder[T: Result](BaseModel):
155+
class TableRowBuilder[T: Result](BaseModelConfig):
155156
cells: Sequence[TableCellBuilder[T]] | Sequence[Sequence[TableCellBuilder[T] | None]] = Field(
156157
description="The cell builders to use to build the row.",
157158
)

docs/info/release-history.rst

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,20 @@ The format is based on `Keep a Changelog <https://keepachangelog.com/en>`_,
3232
and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_
3333

3434

35-
1.0.8
35+
1.0.9
3636
=====
3737

3838
Fixed
3939
-----
40+
* Path separators in Windows paths were being intepreted as special characters when path filtering.
41+
All backslashes in paths are now double escaped to prevent issues with regex matching.
42+
4043

44+
1.0.8
45+
=====
46+
47+
Fixed
48+
-----
4149
* :py:class:`.PathCondition` now excludes paths correctly
4250

4351

@@ -46,7 +54,6 @@ Fixed
4654

4755
Changed
4856
-------
49-
5057
* Properties files now outputted with extra indentation for arrays
5158

5259

@@ -55,7 +62,6 @@ Changed
5562

5663
Fixed
5764
-----
58-
5965
* When selecting only a child contract with ``dbt-validate``,
6066
paths were not being set on parent contracts leading to overprocessing. Paths are now set correctly.
6167

@@ -65,7 +71,6 @@ Fixed
6571

6672
Fixed
6773
-----
68-
6974
* Paths were not assigned to runner when passed via CLI. Now passed as expected.
7075

7176

@@ -74,7 +79,6 @@ Fixed
7479

7580
Fixed
7681
-----
77-
7882
* :py:class:`.HasAllColumns` was not logging the correct extra columns. This is now fixed.
7983

8084

@@ -83,7 +87,6 @@ Fixed
8387

8488
Changed
8589
-------
86-
8790
* Drop requirement for pre-release pydantic version
8891

8992

@@ -92,7 +95,6 @@ Changed
9295

9396
Fixed
9497
-----
95-
9698
* CLI functions now set logging to INFO by default. Results can now be viewed in terminal output.
9799

98100

@@ -101,7 +103,6 @@ Fixed
101103

102104
Fixed
103105
-----
104-
105106
* Fixed the hooks IDs and added generate hook
106107

107108

0 commit comments

Comments
 (0)