-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #38 from MolarVerse/feature/beartype_exceptions
Feature/beartype exceptions
- Loading branch information
Showing
16 changed files
with
223 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
""" | ||
A module for type checking of arguments passed to functions at runtime. | ||
""" | ||
|
||
import logging | ||
|
||
from decorator import decorator | ||
from beartype.door import is_bearable | ||
|
||
from PQAnalysis.utils.custom_logging import setup_logger | ||
from .types import ( | ||
Np1DIntArray, | ||
Np2DIntArray, | ||
Np1DNumberArray, | ||
Np2DNumberArray, | ||
Np3x3NumberArray, | ||
NpnDNumberArray, | ||
) | ||
|
||
__logger_name__ = "PQAnalysis.TypeChecking" | ||
|
||
if not logging.getLogger(__logger_name__).handlers: | ||
logger = setup_logger(logging.getLogger(__logger_name__)) | ||
else: | ||
logger = logging.getLogger(__logger_name__) | ||
|
||
|
||
@decorator | ||
def runtime_type_checking(func, *args, **kwargs): | ||
""" | ||
A decorator to check the type of the arguments passed to a function at runtime. | ||
""" | ||
|
||
# Get the type hints of the function | ||
type_hints = func.__annotations__ | ||
|
||
# Check the type of each argument | ||
for arg_name, arg_value in zip(func.__code__.co_varnames, args): | ||
if arg_name in type_hints: | ||
if not is_bearable(arg_value, type_hints[arg_name]): | ||
logger.error( | ||
_get_type_error_message( | ||
arg_name, | ||
arg_value, | ||
type_hints[arg_name], | ||
), | ||
exception=TypeError, | ||
) | ||
|
||
# Check the type of each keyword argument | ||
for kwarg_name, kwarg_value in kwargs.items(): | ||
if kwarg_name in type_hints: | ||
if not is_bearable(kwarg_value, type_hints[kwarg_name]): | ||
logger.error( | ||
_get_type_error_message( | ||
kwarg_name, | ||
kwarg_value, | ||
type_hints[kwarg_name], | ||
), | ||
exception=TypeError, | ||
) | ||
|
||
# Call the function | ||
return func(*args, **kwargs) | ||
|
||
|
||
def _get_type_error_message(arg_name, value, expected_type): | ||
""" | ||
Get the error message for a type error. | ||
""" | ||
|
||
actual_type = type(value) | ||
|
||
header = ( | ||
f"Argument '{arg_name}' with {value=} should be " | ||
f"of type {expected_type}, but got {actual_type}." | ||
) | ||
|
||
if expected_type is Np1DIntArray: | ||
header += " Expected a 1D numpy integer array." | ||
elif expected_type is Np2DIntArray: | ||
header += " Expected a 2D numpy integer array." | ||
elif expected_type is Np1DNumberArray: | ||
header += " Expected a 1D numpy number array." | ||
elif expected_type is Np2DNumberArray: | ||
header += " Expected a 2D numpy number array." | ||
elif expected_type is Np3x3NumberArray: | ||
header += " Expected a 3x3 numpy number array." | ||
elif expected_type is NpnDNumberArray: | ||
header += " Expected an n-dimensional numpy number array." | ||
|
||
return header |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ markers = | |
topology | ||
traj | ||
io | ||
analysis | ||
|
||
testpaths = | ||
tests | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
""" | ||
Unit tests for the PQAnalysis package. | ||
""" | ||
|
||
import os | ||
|
||
os.environ['PQANALYSIS_BEARTYPE_LEVEL'] = "RELEASE" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import pytest | ||
|
||
pytestmark = pytest.mark.analysis |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
""" | ||
A module to test the RDF API. | ||
""" | ||
|
||
import pytest # pylint: disable=unused-import | ||
|
||
from PQAnalysis.analysis.rdf.api import rdf | ||
from PQAnalysis.type_checking import _get_type_error_message | ||
|
||
from .. import pytestmark # pylint: disable=unused-import | ||
from ...conftest import assert_logging_with_exception | ||
|
||
|
||
class TestRDFAPI: | ||
def test_wrong_param_types(self, caplog): | ||
assert_logging_with_exception( | ||
caplog=caplog, | ||
logging_name="TypeChecking", | ||
logging_level="ERROR", | ||
message_to_test=_get_type_error_message( | ||
"input_file", 1, str, | ||
), | ||
exception=TypeError, | ||
function=rdf, | ||
input_file=1, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.