Skip to content

Commit

Permalink
Merge branch 'main' into feature/add-python-toolbox-support
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicoretti authored Jun 7, 2024
2 parents d93739e + ce3edcf commit c4d947a
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 15 deletions.
11 changes: 2 additions & 9 deletions doc/changes/unreleased.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
# exasol-error-reporting X.Y.Z, released YYYY-MM-DD
# Unreleased

Code Name:

## Summary

### Security
### Bugfix
### Feature
### Refactoring
### Documentation
- #25: Add support for named parameters.
29 changes: 23 additions & 6 deletions exasol/error/_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ def __iter__(self) -> Generator[ast.Call, None, None]:
)


def _extract_parameters(node: ast.Call):
kwargs = {}
params = ["code", "message", "mitigations", "parameters"]

for arg in node.args:
name = params.pop(0)
kwargs[name] = arg

for keyword_argument in node.keywords:
kwargs[keyword_argument.arg] = keyword_argument.value

return kwargs["code"], kwargs["message"], kwargs["mitigations"], kwargs["parameters"]


class Validator:
@dataclass(frozen=True)
class Error:
Expand Down Expand Up @@ -55,13 +69,14 @@ def warnings(self) -> Iterable["Validator.Warning"]:
return self._warnings

def validate(
self, node: ast.Call, file: str
self, node: ast.Call, file: str
) -> Tuple[List["Validator.Error"], List["Validator.Warning"]]:
code: ast.Constant
message: ast.Constant
mitigations: Union[ast.Constant, ast.List]
parameters: ast.Dict
code, message, mitigations, parameters = node.args

code, message, mitigations, parameters = _extract_parameters(node)

# TODO: Add/Collect additional warnings:
# * error message/mitigation defines a placeholder, but no parameter is provided
Expand Down Expand Up @@ -95,7 +110,8 @@ def _validate_message(self, node: ast.Constant, file: str):
if not isinstance(node, ast.Constant):
self._errors.append(
self.Error(
message=self._error_msg.format(type="message", value=type(node)),
message=self._error_msg.format(
type="message", value=type(node)),
file=file,
line_number=node.lineno,
)
Expand Down Expand Up @@ -134,7 +150,8 @@ def _validate_parameters(self, node: ast.Dict, file: str):
if not isinstance(key, ast.Constant):
self._errors.append(
self.Error(
message=self._error_msg.format(type="key", value=type(key)),
message=self._error_msg.format(
type="key", value=type(key)),
file=file,
line_number=key.lineno,
)
Expand Down Expand Up @@ -178,7 +195,7 @@ def _make_error(self, node: ast.Call) -> ErrorCodeDetails:
message: ast.Constant
mitigations: Union[ast.List, ast.Constant]
parameters: ast.Dict
code, message, mitigations, parameters = node.args
code, message, mitigations, parameters = _extract_parameters(node)

def normalize(params):
for k, v in zip(params.keys, params.keys):
Expand Down Expand Up @@ -220,7 +237,7 @@ def collect(self) -> None:


def parse_file(
file: Union[str, Path, io.FileIO]
file: Union[str, Path, io.FileIO]
) -> Tuple[
Iterable[ErrorCodeDetails],
Iterable["Validator.Warning"],
Expand Down
152 changes: 152 additions & 0 deletions test/unit/named_parameters_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import io
import pytest
from inspect import cleandoc

from exasol.error._parse import parse_file
from exasol.error._report import ErrorCodeDetails


@pytest.fixture
def expected():
yield (
[
ErrorCodeDetails(
identifier='E-TEST-1',
message='this is an error',
messagePlaceholders=[],
description=None,
internalDescription=None,
potentialCauses=None,
mitigations=['no mitigation available'],
sourceFile='<StringIO>',
sourceLine=6,
contextHash=None),
],
[],
[]
)


def test_use_only_named_parameters(expected):
file = io.StringIO(initial_value=cleandoc(
"""
from exasol import error
from exasol.error import Parameter
var = input("description: ")
error1 = error.ExaError(
code="E-TEST-1",
message="this is an error",
mitigations="no mitigation available",
parameters={},
)
"""
))

expected_defs, expected_warnings, expected_errors = expected
definitions, warnings, errors = parse_file(file)

assert expected_defs == definitions
assert expected_warnings == warnings
assert expected_errors == errors


def test_dont_name_the_code_parameter(expected):
file = io.StringIO(initial_value=cleandoc(
"""
from exasol import error
from exasol.error import Parameter
var = input("description: ")
error1 = error.ExaError(
"E-TEST-1",
message="this is an error",
mitigations="no mitigation available",
parameters={},
)
"""
))

expected_defs, expected_warnings, expected_errors = expected
definitions, warnings, errors = parse_file(file)

assert expected_defs == definitions
assert expected_warnings == warnings
assert expected_errors == errors


def test_dont_name_the_code_and_message_parameter(expected):
file = io.StringIO(initial_value=cleandoc(
"""
from exasol import error
from exasol.error import Parameter
var = input("description: ")
error1 = error.ExaError(
"E-TEST-1",
"this is an error",
mitigations="no mitigation available",
parameters={},
)
"""
))

expected_defs, expected_warnings, expected_errors = expected
definitions, warnings, errors = parse_file(file)

assert expected_defs == definitions
assert expected_warnings == warnings
assert expected_errors == errors


def test_dont_name_the_code_message_and_mitigations_parameter(expected):
file = io.StringIO(initial_value=cleandoc(
"""
from exasol import error
from exasol.error import Parameter
var = input("description: ")
error1 = error.ExaError(
"E-TEST-1",
"this is an error",
"no mitigation available",
parameters={},
)
"""
))

expected_defs, expected_warnings, expected_errors = expected
definitions, warnings, errors = parse_file(file)

assert expected_defs == definitions
assert expected_warnings == warnings
assert expected_errors == errors


def test_dont_name_any_parameter(expected):
file = io.StringIO(initial_value=cleandoc(
"""
from exasol import error
from exasol.error import Parameter
var = input("description: ")
error1 = error.ExaError(
"E-TEST-1",
"this is an error",
"no mitigation available",
{},
)
"""
))

expected_defs, expected_warnings, expected_errors = expected
definitions, warnings, errors = parse_file(file)

assert expected_defs == definitions
assert expected_warnings == warnings
assert expected_errors == errors

0 comments on commit c4d947a

Please sign in to comment.