-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move validation routines to separate submodule #336
Conversation
WalkthroughThe changes involve refactoring the Changes
Sequence Diagram(s)sequenceDiagram
participant A as User
participant B as BasisQueueAdapter
participant C as ValidateFunctions
A->>B: Call check_queue_parameters()
B->>C: Call value_error_if_none(value)
C-->>B: Return validation result
B->>C: Call value_in_range(value, min, max)
C-->>B: Return range check result
B-->>A: Return final result
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Outside diff range and nitpick comments (3)
tests/test_basic.py (2)
44-51
: Consider adding explicit type checking.These assertions test the function's behavior with memory strings and numeric strings. While the functionality seems correct, it might be beneficial to add explicit type checking in the
value_in_range
function to ensure it handles different input types consistently.
60-67
: Consider adding edge case tests.While these tests cover large values and upper limits, consider adding edge case tests, such as values exactly at the minimum and maximum limits, to ensure the function behaves correctly at the boundaries.
tests/test_sge.py (1)
50-66
: LGTM: Test cases updated correctly.The
test_value_in_range
method has been successfully updated to use the newvalue_in_range
function from thepysqa.utils.validate
module. This change is consistent with the refactoring objectives and maintains the same test coverage as before.Consider parameterizing these tests for improved readability and maintainability. Here's an example of how you could refactor this:
import pytest @pytest.mark.parametrize("value, value_min, value_max, expected", [ (None, None, None, None), (None, 1, None, 1), (None, None, 1, 1), (1, None, None, 1), (0, 1, None, 1), (2, None, 1, 1), (1, 0, 2, 1), ]) def test_value_in_range(value, value_min, value_max, expected): assert value_in_range(value, value_min, value_max) == expectedThis approach would make it easier to add new test cases in the future and improve the overall readability of the tests.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (4)
- pysqa/utils/basic.py (3 hunks)
- pysqa/utils/validate.py (1 hunks)
- tests/test_basic.py (2 hunks)
- tests/test_sge.py (2 hunks)
🔇 Additional comments (11)
tests/test_basic.py (5)
9-9
: LGTM: Import statement is correct and consistent with the refactoring.The new import statement correctly imports the
value_in_range
function from thepysqa.utils.validate
module, which aligns with the refactoring described in the PR objectives.
40-43
: LGTM: Basic integer and string input tests look good.These assertions correctly test the
value_in_range
function with both integer and string inputs, verifying its behavior with different minimum values.
52-59
: LGTM: Tests for values within range are correct.These assertions verify that the function correctly handles values within the specified range, both for memory strings and integers.
68-71
: LGTM: Lower limit test is correct.This assertion correctly tests the function's behavior when the input is below the specified minimum value.
40-71
: Overall, the changes look good and align with the PR objectives.The refactoring has been done consistently, replacing all instances of
BasisQueueAdapter._value_in_range
with the newvalue_in_range
function. The test cases cover a wide range of scenarios, ensuring that the functionality remains intact after the refactoring.Some minor suggestions for improvement:
- Consider adding explicit type checking in the
value_in_range
function to handle different input types consistently.- Add edge case tests for values exactly at the minimum and maximum limits.
These additions would further strengthen the test suite and ensure robust behavior of the
value_in_range
function across all possible inputs.To ensure that all instances of
_value_in_range
have been replaced, run the following script:tests/test_sge.py (2)
9-9
: LGTM: Import statement added correctly.The new import statement for
value_in_range
frompysqa.utils.validate
is consistent with the refactoring mentioned in the PR objectives. This change improves the modularity of the code by separating validation functions into their own submodule.
Line range hint
1-166
: Summary: Changes align with PR objectives and maintain test integrity.The modifications in this file successfully implement the PR objective of moving validation routines to a separate submodule. The
value_in_range
function is now imported frompysqa.utils.validate
, and thetest_value_in_range
method has been updated accordingly. These changes improve the modularity of the code while maintaining the same test coverage.The rest of the file remains unchanged, indicating that the refactoring has been done with minimal impact on other parts of the test suite. This is a positive sign, suggesting that the changes are well-contained and focused.
To ensure that no other parts of the file are affected by this change, please run the following command:
If this command returns no results, it confirms that all instances of the old method have been replaced.
✅ Verification successful
Correction Needed: Invalid file type in ripgrep command
Apologies for the oversight. The correct file type for Python in ripgrep is
py
. Please run the following command to check for any remaining references to_value_in_range
intests/test_sge.py
:
Further Verification Needed: Ensure
_value_in_range
is Fully RemovedWhile the test method
test_value_in_range
is correctly present, we need to confirm that there are no lingering references to_value_in_range
elsewhere intests/test_sge.py
. Please run the following command to check for any remaining usages of_value_in_range
outside the test method definition:
Verification Successful: No remaining references to
_value_in_range
foundThe search results indicate that there are no remaining references to
_value_in_range
outside thetest_value_in_range
method intests/test_sge.py
. This confirms that thevalue_in_range
function has been successfully moved to the separate submodule with no lingering dependencies in this test file.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for any remaining references to _value_in_range in the file rg --type python '_value_in_range' tests/test_sge.pyLength of output: 83
Script:
#!/bin/bash # Revised command to check for any remaining references to _value_in_range in tests/test_sge.py rg --type py '_value_in_range' tests/test_sge.pyLength of output: 83
Script:
#!/bin/bash # Search for usages of _value_in_range excluding its definition in test_value_in_range rg --type py -e '_value_in_range\b' tests/test_sge.py | grep -v 'def test_value_in_range'Length of output: 91
pysqa/utils/basic.py (4)
15-15
: LGTM: Import statement added for validation functionsThe addition of this import statement is consistent with the refactoring to move validation routines to a separate submodule. This change improves code organization and modularity.
375-384
: LGTM: Validation logic updated to use imported functionsThe
check_queue_parameters
method has been updated to use the importedvalue_in_range
function instead of the internal_value_in_range
method. This change is consistent with the refactoring goal and maintains the original functionality while improving code modularity.
468-468
: LGTM: Command validation updated to use imported functionThe
_job_submission_template
method now uses the importedvalue_error_if_none
function to validate thecommand
parameter. This change is in line with the refactoring goal and maintains the original functionality while improving code organization.
Line range hint
1-568
: Overall: Successful refactoring of validation routinesThe changes in this file successfully implement the goal of moving validation routines to a separate submodule. The refactoring:
- Removes internal utility methods and replaces them with imported functions.
- Maintains the original functionality while improving code organization and modularity.
- Adheres to the principle of separation of concerns.
These changes will make the code easier to maintain and test in the future. Great job on this refactoring effort!
def value_error_if_none(value: str) -> None: | ||
""" | ||
Raise a ValueError if the value is None or not a string. | ||
|
||
Args: | ||
value (str/None): The value to check. | ||
|
||
Raises: | ||
ValueError: If the value is None. | ||
TypeError: If the value is not a string. | ||
""" | ||
if value is None: | ||
raise ValueError("Value cannot be None.") | ||
if not isinstance(value, str): | ||
raise TypeError() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider renaming the function and adding informative error messages
The function value_error_if_none
checks if value
is None
or not a string, but the name suggests it only raises a ValueError
if value
is None
. Consider renaming the function to better reflect its functionality, such as validate_string_value
.
Additionally, the TypeError
raised at line 19 lacks an informative message. Including an error message will aid in debugging.
Apply this diff to address the issues:
-def value_error_if_none(value: str) -> None:
+def validate_string_value(value: str) -> None:
"""
- Raise a ValueError if the value is None or not a string.
+ Validate that the value is a non-None string.
Args:
- value (str/None): The value to check.
+ value (str): The value to check.
Raises:
ValueError: If the value is None.
TypeError: If the value is not a string.
"""
if value is None:
raise ValueError("Value cannot be None.")
if not isinstance(value, str):
- raise TypeError()
+ raise TypeError("Value must be a string.")
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def value_error_if_none(value: str) -> None: | |
""" | |
Raise a ValueError if the value is None or not a string. | |
Args: | |
value (str/None): The value to check. | |
Raises: | |
ValueError: If the value is None. | |
TypeError: If the value is not a string. | |
""" | |
if value is None: | |
raise ValueError("Value cannot be None.") | |
if not isinstance(value, str): | |
raise TypeError() | |
def validate_string_value(value: str) -> None: | |
""" | |
Validate that the value is a non-None string. | |
Args: | |
value (str): The value to check. | |
Raises: | |
ValueError: If the value is None. | |
TypeError: If the value is not a string. | |
""" | |
if value is None: | |
raise ValueError("Value cannot be None.") | |
if not isinstance(value, str): | |
raise TypeError("Value must be a string.") |
def _is_memory_string(value: str) -> bool: | ||
""" | ||
Check if a string specifies a certain amount of memory. | ||
|
||
Args: | ||
value (str): The string to check. | ||
|
||
Returns: | ||
bool: True if the string matches a memory specification, False otherwise. | ||
""" | ||
memory_spec_pattern = r"[0-9]+[bBkKmMgGtT]?" | ||
return re.findall(memory_spec_pattern, value)[0] == value | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prevent IndexError
in _is_memory_string
when input doesn't match the pattern
In the function _is_memory_string
, if the input value
does not match the memory_spec_pattern
, re.findall
may return an empty list, leading to an IndexError
when accessing [0]
. To avoid this, consider using re.fullmatch
to check if the entire string matches the pattern.
Apply this change to fix the issue:
def _is_memory_string(value: str) -> bool:
"""
Check if a string specifies a certain amount of memory.
"""
memory_spec_pattern = r"[0-9]+[bBkKmMgGtT]?"
- return re.findall(memory_spec_pattern, value)[0] == value
+ return bool(re.fullmatch(memory_spec_pattern, value))
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def _is_memory_string(value: str) -> bool: | |
""" | |
Check if a string specifies a certain amount of memory. | |
Args: | |
value (str): The string to check. | |
Returns: | |
bool: True if the string matches a memory specification, False otherwise. | |
""" | |
memory_spec_pattern = r"[0-9]+[bBkKmMgGtT]?" | |
return re.findall(memory_spec_pattern, value)[0] == value | |
def _is_memory_string(value: str) -> bool: | |
""" | |
Check if a string specifies a certain amount of memory. | |
Args: | |
value (str): The string to check. | |
Returns: | |
bool: True if the string matches a memory specification, False otherwise. | |
""" | |
memory_spec_pattern = r"[0-9]+[bBkKmMgGtT]?" | |
return bool(re.fullmatch(memory_spec_pattern, value)) |
def value_in_range( | ||
value: Union[int, float, None], | ||
value_min: Union[int, float, None] = None, | ||
value_max: Union[int, float, None] = None, | ||
) -> Union[int, float, None]: | ||
""" | ||
Check if a value is within a specified range. | ||
|
||
Args: | ||
value (int/float/None): The value to check. | ||
value_min (int/float/None): The minimum value. Defaults to None. | ||
value_max (int/float/None): The maximum value. Defaults to None. | ||
|
||
Returns: | ||
int/float/None: The value if it is within the range, otherwise the minimum or maximum value. | ||
""" | ||
|
||
if value is not None: | ||
value_, value_min_, value_max_ = [ | ||
( | ||
_memory_spec_string_to_value(v) | ||
if v is not None and isinstance(v, str) | ||
else v | ||
) | ||
for v in (value, value_min, value_max) | ||
] | ||
# ATTENTION: '60000' is interpreted as '60000M' since default magnitude is 'M' | ||
# ATTENTION: int('60000') is interpreted as '60000B' since _memory_spec_string_to_value return the size in | ||
# ATTENTION: bytes, as target_magnitude = 'b' | ||
# We want to compare the the actual (k,m,g)byte value if there is any | ||
if value_min_ is not None and value_ < value_min_: | ||
return value_min | ||
if value_max_ is not None and value_ > value_max_: | ||
return value_max | ||
return value | ||
else: | ||
if value_min is not None: | ||
return value_min | ||
if value_max is not None: | ||
return value_max | ||
return value | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update type annotations and documentation to include string inputs
The function value_in_range
handles value
, value_min
, and value_max
, which can be string representations of memory sizes (e.g., "500M"
). However, the type annotations and docstrings specify these parameters as Union[int, float, None]
. To ensure clarity and type correctness, consider updating the type annotations and documentation to reflect that these parameters can also be strings.
Apply this diff to update the type annotations and documentation:
def value_in_range(
- value: Union[int, float, None],
- value_min: Union[int, float, None] = None,
- value_max: Union[int, float, None] = None,
-) -> Union[int, float, None]:
+ value: Union[int, float, str, None],
+ value_min: Union[int, float, str, None] = None,
+ value_max: Union[int, float, str, None] = None,
+) -> Union[int, float, str, None]:
"""
Check if a value is within a specified range.
Args:
- value (int/float/None): The value to check.
- value_min (int/float/None): The minimum value. Defaults to None.
- value_max (int/float/None): The maximum value. Defaults to None.
+ value (int/float/str/None): The value to check.
+ value_min (int/float/str/None): The minimum value. Defaults to None.
+ value_max (int/float/str/None): The maximum value. Defaults to None.
Returns:
- int/float/None: The value if it is within the range, otherwise the minimum or maximum value.
+ int/float/str/None: The value if it is within the range, otherwise the minimum or maximum value.
"""
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def value_in_range( | |
value: Union[int, float, None], | |
value_min: Union[int, float, None] = None, | |
value_max: Union[int, float, None] = None, | |
) -> Union[int, float, None]: | |
""" | |
Check if a value is within a specified range. | |
Args: | |
value (int/float/None): The value to check. | |
value_min (int/float/None): The minimum value. Defaults to None. | |
value_max (int/float/None): The maximum value. Defaults to None. | |
Returns: | |
int/float/None: The value if it is within the range, otherwise the minimum or maximum value. | |
""" | |
if value is not None: | |
value_, value_min_, value_max_ = [ | |
( | |
_memory_spec_string_to_value(v) | |
if v is not None and isinstance(v, str) | |
else v | |
) | |
for v in (value, value_min, value_max) | |
] | |
# ATTENTION: '60000' is interpreted as '60000M' since default magnitude is 'M' | |
# ATTENTION: int('60000') is interpreted as '60000B' since _memory_spec_string_to_value return the size in | |
# ATTENTION: bytes, as target_magnitude = 'b' | |
# We want to compare the the actual (k,m,g)byte value if there is any | |
if value_min_ is not None and value_ < value_min_: | |
return value_min | |
if value_max_ is not None and value_ > value_max_: | |
return value_max | |
return value | |
else: | |
if value_min is not None: | |
return value_min | |
if value_max is not None: | |
return value_max | |
return value | |
def value_in_range( | |
value: Union[int, float, str, None], | |
value_min: Union[int, float, str, None] = None, | |
value_max: Union[int, float, str, None] = None, | |
) -> Union[int, float, str, None]: | |
""" | |
Check if a value is within a specified range. | |
Args: | |
value (int/float/str/None): The value to check. | |
value_min (int/float/str/None): The minimum value. Defaults to None. | |
value_max (int/float/str/None): The maximum value. Defaults to None. | |
Returns: | |
int/float/str/None: The value if it is within the range, otherwise the minimum or maximum value. | |
""" | |
if value is not None: | |
value_, value_min_, value_max_ = [ | |
( | |
_memory_spec_string_to_value(v) | |
if v is not None and isinstance(v, str) | |
else v | |
) | |
for v in (value, value_min, value_max) | |
] | |
# ATTENTION: '60000' is interpreted as '60000M' since default magnitude is 'M' | |
# ATTENTION: int('60000') is interpreted as '60000B' since _memory_spec_string_to_value return the size in | |
# ATTENTION: bytes, as target_magnitude = 'b' | |
# We want to compare the the actual (k,m,g)byte value if there is any | |
if value_min_ is not None and value_ < value_min_: | |
return value_min | |
if value_max_ is not None and value_ > value_max_: | |
return value_max | |
return value | |
else: | |
if value_min is not None: | |
return value_min | |
if value_max is not None: | |
return value_max | |
return value |
def _memory_spec_string_to_value( | ||
value: str, default_magnitude: str = "m", target_magnitude: str = "b" | ||
) -> Union[int, float]: | ||
""" | ||
Converts a valid memory string (tested by _is_memory_string) into an integer/float value of desired | ||
magnitude `default_magnitude`. If it is a plain integer string (e.g.: '50000') it will be interpreted with | ||
the magnitude passed in by the `default_magnitude`. The output will rescaled to `target_magnitude` | ||
|
||
Args: | ||
value (str): The string to convert. | ||
default_magnitude (str): The magnitude for interpreting plain integer strings [b, B, k, K, m, M, g, G, t, T]. Defaults to "m". | ||
target_magnitude (str): The magnitude to which the output value should be converted [b, B, k, K, m, M, g, G, t, T]. Defaults to "b". | ||
|
||
Returns: | ||
Union[int, float]: The value of the string in `target_magnitude` units. | ||
""" | ||
magnitude_mapping = {"b": 0, "k": 1, "m": 2, "g": 3, "t": 4} | ||
if _is_memory_string(value): | ||
integer_pattern = r"[0-9]+" | ||
magnitude_pattern = r"[bBkKmMgGtT]+" | ||
integer_value = int(re.findall(integer_pattern, value)[0]) | ||
|
||
magnitude = re.findall(magnitude_pattern, value) | ||
if len(magnitude) > 0: | ||
magnitude = magnitude[0].lower() | ||
else: | ||
magnitude = default_magnitude.lower() | ||
# Convert it to default magnitude = megabytes | ||
return (integer_value * 1024 ** magnitude_mapping[magnitude]) / ( | ||
1024 ** magnitude_mapping[target_magnitude] | ||
) | ||
else: | ||
return value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure consistent return types and handle invalid inputs in _memory_spec_string_to_value
The function _memory_spec_string_to_value
is declared to return Union[int, float]
, but if the input value
is not a valid memory string, it returns value
unmodified, which could be a str
. This inconsistency may lead to type errors downstream. Instead, consider raising a ValueError
when the input is invalid to maintain consistent return types.
Also, when extracting integer_value
and magnitude
, there is a potential for IndexError
if re.findall
returns an empty list. Adding checks to ensure matches are found before accessing them will prevent this error.
Apply these changes to address the issues:
def _memory_spec_string_to_value(
value: str, default_magnitude: str = "m", target_magnitude: str = "b"
) -> Union[int, float]:
"""
Converts a valid memory string into an integer/float value.
"""
magnitude_mapping = {"b": 0, "k": 1, "m": 2, "g": 3, "t": 4}
if _is_memory_string(value):
integer_pattern = r"[0-9]+"
magnitude_pattern = r"[bBkKmMgGtT]+"
- integer_value = int(re.findall(integer_pattern, value)[0])
+ integer_match = re.findall(integer_pattern, value)
+ if not integer_match:
+ raise ValueError(f"Invalid integer value in memory specification: {value}")
+ integer_value = int(integer_match[0])
- magnitude = re.findall(magnitude_pattern, value)
- if len(magnitude) > 0:
- magnitude = magnitude[0].lower()
+ magnitude_match = re.findall(magnitude_pattern, value)
+ if magnitude_match:
+ magnitude = magnitude_match[0].lower()
+ else:
+ magnitude = default_magnitude.lower()
return (integer_value * 1024 ** magnitude_mapping[magnitude]) / (
1024 ** magnitude_mapping[target_magnitude]
)
else:
- return value
+ raise ValueError(f"Invalid memory specification: {value}")
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def _memory_spec_string_to_value( | |
value: str, default_magnitude: str = "m", target_magnitude: str = "b" | |
) -> Union[int, float]: | |
""" | |
Converts a valid memory string (tested by _is_memory_string) into an integer/float value of desired | |
magnitude `default_magnitude`. If it is a plain integer string (e.g.: '50000') it will be interpreted with | |
the magnitude passed in by the `default_magnitude`. The output will rescaled to `target_magnitude` | |
Args: | |
value (str): The string to convert. | |
default_magnitude (str): The magnitude for interpreting plain integer strings [b, B, k, K, m, M, g, G, t, T]. Defaults to "m". | |
target_magnitude (str): The magnitude to which the output value should be converted [b, B, k, K, m, M, g, G, t, T]. Defaults to "b". | |
Returns: | |
Union[int, float]: The value of the string in `target_magnitude` units. | |
""" | |
magnitude_mapping = {"b": 0, "k": 1, "m": 2, "g": 3, "t": 4} | |
if _is_memory_string(value): | |
integer_pattern = r"[0-9]+" | |
magnitude_pattern = r"[bBkKmMgGtT]+" | |
integer_value = int(re.findall(integer_pattern, value)[0]) | |
magnitude = re.findall(magnitude_pattern, value) | |
if len(magnitude) > 0: | |
magnitude = magnitude[0].lower() | |
else: | |
magnitude = default_magnitude.lower() | |
# Convert it to default magnitude = megabytes | |
return (integer_value * 1024 ** magnitude_mapping[magnitude]) / ( | |
1024 ** magnitude_mapping[target_magnitude] | |
) | |
else: | |
return value | |
def _memory_spec_string_to_value( | |
value: str, default_magnitude: str = "m", target_magnitude: str = "b" | |
) -> Union[int, float]: | |
""" | |
Converts a valid memory string (tested by _is_memory_string) into an integer/float value of desired | |
magnitude `default_magnitude`. If it is a plain integer string (e.g.: '50000') it will be interpreted with | |
the magnitude passed in by the `default_magnitude`. The output will rescaled to `target_magnitude` | |
Args: | |
value (str): The string to convert. | |
default_magnitude (str): The magnitude for interpreting plain integer strings [b, B, k, K, m, M, g, G, t, T]. Defaults to "m". | |
target_magnitude (str): The magnitude to which the output value should be converted [b, B, k, K, m, M, g, G, t, T]. Defaults to "b". | |
Returns: | |
Union[int, float]: The value of the string in `target_magnitude` units. | |
""" | |
magnitude_mapping = {"b": 0, "k": 1, "m": 2, "g": 3, "t": 4} | |
if _is_memory_string(value): | |
integer_pattern = r"[0-9]+" | |
magnitude_pattern = r"[bBkKmMgGtT]+" | |
integer_match = re.findall(integer_pattern, value) | |
if not integer_match: | |
raise ValueError(f"Invalid integer value in memory specification: {value}") | |
integer_value = int(integer_match[0]) | |
magnitude_match = re.findall(magnitude_pattern, value) | |
if magnitude_match: | |
magnitude = magnitude_match[0].lower() | |
else: | |
magnitude = default_magnitude.lower() | |
# Convert it to default magnitude = megabytes | |
return (integer_value * 1024 ** magnitude_mapping[magnitude]) / ( | |
1024 ** magnitude_mapping[target_magnitude] | |
) | |
else: | |
raise ValueError(f"Invalid memory specification: {value}") |
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Tests