Skip to content

Commit

Permalink
refactor(errors): centralize validation error messages for better mai…
Browse files Browse the repository at this point in the history
…ntainability

- Added specific error messages for filename, version, environment variables, and class/attribute mismatches.
- Enhanced clarity and reusability of validation errors in SpyModel.
- Organized errors for SpyModel validation, including environment and variable mismatches
  • Loading branch information
atellaluca committed Nov 20, 2024
1 parent 18b57be commit 035e5ca
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 26 deletions.
17 changes: 16 additions & 1 deletion src/importspy/errors.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
class Errors:


ANALYSIS_RECURSION_WARNING = ("Warning: You cannot analyze the code that itself handles analysis, as this may result "
"in uncontrolled deep recursion. To avoid potential performance issues or stack overflow "
"errors, ensure that the analysis process does not recursively attempt to evaluate itself.")
"errors, ensure that the analysis process does not recursively attempt to evaluate itself.")

### Spy model validation
FILENAME_MISMATCH = "Filename mismatch: {0} != {1}"
VERSION_MISMATCH = "Version mismatch: {0} != {1}"
ENV_VAR_MISMATCH = "Value mismatch for environment variable '{0}': expected '{1}', found '{2}'."
ENV_VAR_MISSING = "Missing environment variable: '{0}'. Ensure it is defined in the system."
VAR_MISMATCH = "Value mismatch for variable '{0}': expected '{1}', found '{2}'"
VAR_MISSING = "Missing variable: '{0}'. Ensure it is defined."
GENERIC_FUNCTIONS_MISMATCH = "Functions mismatch: Some functions are not defined."
CLASS_MISSING = "Missing class: {0} Ensure it is defined."
GENERIC_CLASS_ATTRIBUTES_MISMATCH = "Class attributes mismatch in Class {0}: some attributes are not defined in the class {0}."
GENERIC_INSTANCE_ATTRIBUTES_MISMATCH = "Instance attributes mismatch in Class {0}: some attributes are not defined in the __init__ method of the class {0}."
GENERIC_CLASS_METHODS_MISMATCH = "Methods mismatch in Class {0}: some attributes are not defined in the class {0}."
GENERIC_CLASS_SUPERCLASSES_MISMATCH = "Superclass mismatch in Class: {0} some superclasses are not defined in the class {0}."
47 changes: 22 additions & 25 deletions src/importspy/utils/spy_model_utils.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from importspy.models import SpyModel
from ..errors import Errors

def is_subset(spy_model_1: SpyModel, spy_model_2: SpyModel) -> bool:
"""
Determine if the first SpyModel is a subset of the second SpyModel.
This function checks whether all relevant attributes (such as functions, classes, methods,
superclasses, filename, and version) specified in `spy_model_1` are present in `spy_model_2`.
superclassesf"Superclass mismatch in {}", filename, and version) specified in `spy_model_1` are present in `spy_model_2`.
It throws a ValueError with a specific message indicating the type of mismatch.
Parameters:
Expand All @@ -32,37 +33,33 @@ def is_subset(spy_model_1: SpyModel, spy_model_2: SpyModel) -> bool:
```
"""
if spy_model_1.filename and spy_model_1.filename != spy_model_2.filename:
raise ValueError(f"Filename mismatch: {spy_model_1.filename} != {spy_model_2.filename}")
raise ValueError(Errors.FILENAME_MISMATCH.format(spy_model_1.filename, spy_model_2.filename))
if spy_model_1.version and spy_model_1.version != spy_model_2.version:
raise ValueError(f"Version mismatch: {spy_model_1.version} != {spy_model_2.version}")
spy_model_2_env_vars = spy_model_2.env_vars
for expected_key, expected_value in spy_model_1.env_vars.items():
if expected_key in spy_model_2_env_vars:
if expected_value != spy_model_2_env_vars[expected_key]:
raise ValueError(f"Value mismatch for environment variable '{expected_key}': expected '{expected_value}', found '{spy_model_2_env_vars[expected_key]}'."
)
else:
raise ValueError(f"Missing environment variable: '{expected_key}'. Ensure it is defined in the system.")
spy_model_2_variables = spy_model_2.variables
for expected_key, expected_value in spy_model_1.variables.items():
if expected_key in spy_model_2_variables:
if expected_value != spy_model_2_variables[expected_key]:
raise ValueError(f"Value mismatch for variable '{expected_key}': expected '{expected_value}', found '{spy_model_2_variables[expected_key]}'."
)
else:
raise ValueError(f"Missing variable: '{expected_key}'. Ensure it is defined.")
raise ValueError(Errors.VERSION_MISMATCH.format(spy_model_1.version, spy_model_2.version))
#Env vars validation
dict_compare(spy_model_1.env_vars, spy_model_2.env_vars, Errors.ENV_VAR_MISSING, Errors.ENV_VAR_MISMATCH)
#Variables validation
dict_compare(spy_model_1.variables, spy_model_2.variables, Errors.VAR_MISSING, Errors.VAR_MISMATCH)
if spy_model_1.functions and not set(spy_model_1.functions).issubset(spy_model_2.functions):
raise ValueError("Functions mismatch: Some functions are not present in the second model.")
raise ValueError(Errors.GENERIC_FUNCTIONS_MISMATCH)
for class_1 in spy_model_1.classes:
class_2 = next((cls for cls in spy_model_2.classes if cls.name == class_1.name), None)
if not class_2:
raise ValueError(f"Class not found: {class_1.name}")
raise ValueError(Errors.CLASS_MISSING.format(class_1.name))
if class_1.class_attr and not set(class_1.class_attr).issubset(class_2.class_attr):
raise ValueError(f"Class attributes mismatch in {class_1.name}")
raise ValueError(Errors.GENERIC_CLASS_ATTRIBUTES_MISMATCH.format(class_1.name))
if class_1.instance_attr and not set(class_1.instance_attr).issubset(class_2.instance_attr):
raise ValueError(f"Instance attributes mismatch in {class_1.name}")
raise ValueError(Errors.GENERIC_INSTANCE_ATTRIBUTES_MISMATCH.format(class_1.name))
if class_1.methods and not set(class_1.methods).issubset(class_2.methods):
raise ValueError(f"Methods mismatch in {class_1.name}")
raise ValueError(Errors.GENERIC_CLASS_METHODS_MISMATCH.format(class_1.name))
if class_1.superclasses and not set(class_1.superclasses).issubset(class_2.superclasses):
raise ValueError(f"Superclass mismatch in {class_1.name}")
raise ValueError(Errors.GENERIC_CLASS_SUPERCLASSES_MISMATCH.format(class_1.name))
return True

def dict_compare(dict1:dict, dict2:dict, missing_error:str, mismatch_error:str):
for expected_key, expected_value in dict1.items():
if expected_key in dict2:
if expected_value != dict2[expected_key]:
raise ValueError(mismatch_error.format(expected_key, expected_value, dict2[expected_key]))
else:
raise ValueError(missing_error.format(expected_key))

0 comments on commit 035e5ca

Please sign in to comment.