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
3 changes: 2 additions & 1 deletion .github/workflows/auto-pr-description.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ jobs:
contents: read
pull-requests: write
if: >-
github.event_name == 'pull_request' && (
github.event_name == 'pull_request' &&
!contains(github.event.pull_request.labels.*.name, 'dependencies') && (
(github.event.pull_request.base.ref == 'release' && github.event.pull_request.head.ref == 'main') ||
(github.event.pull_request.base.ref == 'main' && github.event.pull_request.head.ref != 'release')
)
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ systems) can rely on a consistent log structure.
problem.
- Any mismatch between runtime values and the declared types (wrong types,
`None` values, disallowed list elements) is also treated as a data error.
Type checks use `type()`, not `isinstance()`: `bool` is **not** accepted
where `int` is declared, and `int` is **not** accepted where `float` is
declared. There are no implicit type conversions.
- All validation problems are aggregated and logged as a single ERROR message
**after** the log record has been emitted, ensuring 100% compatibility with
standard logger behavior (no exceptions are raised).
Expand Down
7 changes: 3 additions & 4 deletions src/logging_objects_with_schema/schema_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,15 +491,15 @@ def _validate_and_create_leaf(
problems.append(
_SchemaProblem(
f"Incomplete leaf at {_format_path(path, key)}: "
f"type cannot be None or empty",
f"type must be a non-empty string",
),
)

if source_invalid:
problems.append(
_SchemaProblem(
f"Incomplete leaf at {_format_path(path, key)}: "
f"source cannot be None or empty",
f"source must be a non-empty string",
),
)

Expand All @@ -526,8 +526,7 @@ def _validate_and_create_leaf(
problems.append(
_SchemaProblem(
f"Incomplete leaf at {_format_path(path, key)}: "
f"item_type is required for list type and "
f"cannot be None or empty",
f"item_type must be a non-empty string",
),
)
return None
Expand Down
42 changes: 21 additions & 21 deletions tests/private/test_schema_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ def test_incomplete_leaf_missing_type(
compiled, problems = compile_schema_internal()
assert isinstance(compiled, _CompiledSchema)
assert compiled.is_empty
assert any("type cannot be None or empty" in p.message for p in problems)
assert any("type must be a non-empty string" in p.message for p in problems)


def test_incomplete_leaf_missing_source(
Expand All @@ -332,7 +332,7 @@ def test_incomplete_leaf_missing_source(
compiled, problems = compile_schema_internal()
assert isinstance(compiled, _CompiledSchema)
assert compiled.is_empty
assert any("source cannot be None or empty" in p.message for p in problems)
assert any("source must be a non-empty string" in p.message for p in problems)


def test_incomplete_leaf_empty_source(
Expand All @@ -354,7 +354,7 @@ def test_incomplete_leaf_empty_source(
compiled, problems = compile_schema_internal()
assert isinstance(compiled, _CompiledSchema)
assert compiled.is_empty
assert any("source cannot be None or empty" in p.message for p in problems)
assert any("source must be a non-empty string" in p.message for p in problems)


def test_incomplete_leaf_empty_type(
Expand All @@ -376,7 +376,7 @@ def test_incomplete_leaf_empty_type(
compiled, problems = compile_schema_internal()
assert isinstance(compiled, _CompiledSchema)
assert compiled.is_empty
assert any("type cannot be None or empty" in p.message for p in problems)
assert any("type must be a non-empty string" in p.message for p in problems)


def test_multiple_root_keys_with_valid_leaves(
Expand Down Expand Up @@ -666,7 +666,7 @@ def test_validate_and_create_leaf_missing_type() -> None:

assert leaf is None
assert len(problems) == 1
assert "type cannot be None or empty" in problems[0].message
assert "type must be a non-empty string" in problems[0].message


def test_validate_and_create_leaf_missing_source() -> None:
Expand All @@ -680,7 +680,7 @@ def test_validate_and_create_leaf_missing_source() -> None:

assert leaf is None
assert len(problems) == 1
assert "source cannot be None or empty" in problems[0].message
assert "source must be a non-empty string" in problems[0].message


def test_validate_and_create_leaf_empty_type() -> None:
Expand All @@ -694,7 +694,7 @@ def test_validate_and_create_leaf_empty_type() -> None:

assert leaf is None
assert len(problems) == 1
assert "type cannot be None or empty" in problems[0].message
assert "type must be a non-empty string" in problems[0].message


def test_validate_and_create_leaf_whitespace_type() -> None:
Expand All @@ -708,7 +708,7 @@ def test_validate_and_create_leaf_whitespace_type() -> None:

assert leaf is None
assert len(problems) == 1
assert "type cannot be None or empty" in problems[0].message
assert "type must be a non-empty string" in problems[0].message


def test_validate_and_create_leaf_empty_source() -> None:
Expand All @@ -722,7 +722,7 @@ def test_validate_and_create_leaf_empty_source() -> None:

assert leaf is None
assert len(problems) == 1
assert "source cannot be None or empty" in problems[0].message
assert "source must be a non-empty string" in problems[0].message


def test_validate_and_create_leaf_whitespace_source() -> None:
Expand All @@ -736,7 +736,7 @@ def test_validate_and_create_leaf_whitespace_source() -> None:

assert leaf is None
assert len(problems) == 1
assert "source cannot be None or empty" in problems[0].message
assert "source must be a non-empty string" in problems[0].message


def test_validate_and_create_leaf_unknown_type() -> None:
Expand All @@ -763,7 +763,7 @@ def test_validate_and_create_leaf_list_missing_item_type() -> None:

assert leaf is None
assert len(problems) == 1
assert "item_type is required for list type" in problems[0].message
assert "item_type must be a non-empty string" in problems[0].message


def test_validate_and_create_leaf_list_empty_item_type() -> None:
Expand All @@ -775,7 +775,7 @@ def test_validate_and_create_leaf_list_empty_item_type() -> None:

assert leaf is None
assert len(problems) == 1
assert "item_type is required for list type" in problems[0].message
assert "item_type must be a non-empty string" in problems[0].message


def test_validate_and_create_leaf_list_invalid_item_type() -> None:
Expand Down Expand Up @@ -1832,7 +1832,7 @@ def test_node_with_only_item_type_as_string_produces_problem(
assert isinstance(compiled, _CompiledSchema)
assert compiled.is_empty
# Should have problems because type and source are required
assert any("type cannot be None or empty" in p.message for p in problems)
assert any("type must be a non-empty string" in p.message for p in problems)


def test_node_with_type_as_number_produces_problem(
Expand All @@ -1859,7 +1859,7 @@ def test_node_with_type_as_number_produces_problem(
assert isinstance(compiled, _CompiledSchema)
assert compiled.is_empty
# Should have problem because type must be a string, not a number
assert any("type cannot be None or empty" in p.message for p in problems)
assert any("type must be a non-empty string" in p.message for p in problems)


def test_node_with_type_as_boolean_produces_problem(
Expand All @@ -1886,7 +1886,7 @@ def test_node_with_type_as_boolean_produces_problem(
assert isinstance(compiled, _CompiledSchema)
assert compiled.is_empty
# Should have problem because type must be a string, not boolean
assert any("type cannot be None or empty" in p.message for p in problems)
assert any("type must be a non-empty string" in p.message for p in problems)


def test_node_with_source_as_boolean_produces_problem(
Expand All @@ -1913,7 +1913,7 @@ def test_node_with_source_as_boolean_produces_problem(
assert isinstance(compiled, _CompiledSchema)
assert compiled.is_empty
# Should have problem because source must be a string, not boolean
assert any("source cannot be None or empty" in p.message for p in problems)
assert any("source must be a non-empty string" in p.message for p in problems)


def test_node_with_source_as_number_produces_problem(
Expand All @@ -1940,7 +1940,7 @@ def test_node_with_source_as_number_produces_problem(
assert isinstance(compiled, _CompiledSchema)
assert compiled.is_empty
# Should have problem because source must be a string, not number
assert any("source cannot be None or empty" in p.message for p in problems)
assert any("source must be a non-empty string" in p.message for p in problems)


def test_node_with_type_and_source_as_numbers_produces_problem(
Expand Down Expand Up @@ -2021,7 +2021,7 @@ def test_node_with_item_type_as_number_produces_problem(
assert isinstance(compiled, _CompiledSchema)
assert compiled.is_empty
# Should have problem because item_type must be a string, not a number
assert any("item_type is required for list type" in p.message for p in problems)
assert any("item_type must be a non-empty string" in p.message for p in problems)


def test_node_with_item_type_as_boolean_produces_problem(
Expand Down Expand Up @@ -2052,7 +2052,7 @@ def test_node_with_item_type_as_boolean_produces_problem(
assert isinstance(compiled, _CompiledSchema)
assert compiled.is_empty
# Should have problem because item_type must be a string, not a boolean
assert any("item_type is required for list type" in p.message for p in problems)
assert any("item_type must be a non-empty string" in p.message for p in problems)


def test_node_with_item_type_as_object_is_determined_as_inner(
Expand Down Expand Up @@ -2113,7 +2113,7 @@ def test_node_with_type_as_list_produces_problem(
assert isinstance(compiled, _CompiledSchema)
assert compiled.is_empty
# Should have problem because type must be a string, not a list
assert any("type cannot be None or empty" in p.message for p in problems)
assert any("type must be a non-empty string" in p.message for p in problems)


def test_node_with_source_as_list_produces_problem(
Expand Down Expand Up @@ -2143,4 +2143,4 @@ def test_node_with_source_as_list_produces_problem(
assert isinstance(compiled, _CompiledSchema)
assert compiled.is_empty
# Should have problem because source must be a string, not a list
assert any("source cannot be None or empty" in p.message for p in problems)
assert any("source must be a non-empty string" in p.message for p in problems)
Loading