-
-
Notifications
You must be signed in to change notification settings - Fork 2
Enhancement | Issue #21 | OPT-2 | Implement typed argument casting #307
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,53 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Value casting utilities. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from typing import Any | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import yaml | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def as_bool(value: str) -> Any: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""Return the boolean representation of ``value`` if possible.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
parsed = yaml.safe_load(value) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if isinstance(parsed, bool): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return parsed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
except yaml.YAMLError: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pass | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def as_int(value: str) -> Any: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""Return the integer representation of ``value`` if possible.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return int(value) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
except ValueError: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def as_float(value: str) -> Any: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""Return the float representation of ``value`` if possible.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return float(value) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
except ValueError: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def cast_value(value: str) -> Any: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""Try to cast ``value`` to bool, int or float using the helper functions | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
:func:`as_bool`, :func:`as_int` and :func:`as_float`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Args: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
value (str): Value to cast. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Returns: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Any: The value converted to its apparent type or the original string. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
value = as_bool(value) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if isinstance(value, str): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
value = as_int(value) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if isinstance(value, str): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
value = as_float(value) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+37
to
+53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add input validation and improve type safety. The function accepts def cast_value(value: str) -> Any:
- """Try to cast ``value`` to bool, int or float using the helper functions
- :func:`as_bool`, :func:`as_int` and :func:`as_float`.
-
- Args:
- value (str): Value to cast.
-
- Returns:
- Any: The value converted to its apparent type or the original string.
- """
+ """Try to cast ``value`` to bool, int or float using the helper functions
+ :func:`as_bool`, :func:`as_int` and :func:`as_float`.
+
+ Args:
+ value (str): Value to cast.
+
+ Returns:
+ Any: The value converted to its apparent type or the original string.
+ """
+ if not isinstance(value, str):
+ return value
+
value = as_bool(value)
if isinstance(value, str):
+ # Try float before int to handle decimal numbers correctly
+ temp_float = as_float(value)
+ if not isinstance(temp_float, str):
+ # Check if it's actually an integer value
+ if temp_float.is_integer():
+ return int(temp_float)
+ return temp_float
value = as_int(value)
- if isinstance(value, str):
- value = as_float(value)
return value 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import math | ||
|
||
import pytest | ||
|
||
from leverage._casting import as_bool, as_int, as_float, cast_value | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"value, expected", | ||
[ | ||
("true", True), | ||
("False", False), | ||
("1", 1), | ||
("-2", -2), | ||
("3.14", 3.14), | ||
("1e3", 1000.0), | ||
("inf", float("inf")), | ||
("nan", float("nan")), | ||
("007", 7), | ||
("0123", 123), | ||
("foo", "foo"), | ||
], | ||
) | ||
def test_cast_value(value, expected): | ||
result = cast_value(value) | ||
if isinstance(expected, float) and math.isnan(expected): | ||
assert math.isnan(result) | ||
else: | ||
assert result == expected | ||
|
||
|
||
def test_helper_functions(): | ||
assert as_bool("true") is True | ||
assert as_bool("no") is False | ||
assert as_int("42") == 42 | ||
assert as_int("bar") == "bar" | ||
assert as_float("3.14") == 3.14 | ||
assert as_float("not") == "not" |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,9 +30,9 @@ | |
True, | ||
{ | ||
"PROJECT": "foobar", | ||
"MFA_ENABLED": "true", | ||
"MFA_ENABLED": True, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainVerify boolean casting behavior aligns with expectations. The test now expects 🏁 Script executed: #!/bin/bash
# Description: Search for usages of MFA_ENABLED to verify impact of type change
# Search for MFA_ENABLED usage patterns
rg -A 3 -B 3 "MFA_ENABLED" Length of output: 2238 Ensure consistent boolean conversion for MFA_ENABLED across modules. Tests in
Please update these places to use the new casting logic (returning booleans) and adjust the corresponding tests to expect 🤖 Prompt for AI Agents
|
||
"ENTRYPOINT": "/bin/run", | ||
"DEBUG": "true", | ||
"DEBUG": True, | ||
"CONFIG_PATH": "/home/user/.config/", | ||
}, | ||
), | ||
|
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.
Security concern: yaml.safe_load can parse more than just booleans.
Using
yaml.safe_load
for boolean parsing is risky as it can interpret various YAML constructs beyond simple boolean values. This could lead to unexpected behavior or security issues.Consider using a more explicit boolean parsing approach:
📝 Committable suggestion
🤖 Prompt for AI Agents