Skip to content
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

CI: try with 3.11 and 3.12 #902

Merged
merged 1 commit into from
Dec 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/reusable-precommit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ jobs:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
integration_tests:
runs-on: ubuntu-latest
needs:
Expand Down Expand Up @@ -148,6 +150,8 @@ jobs:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
doc_tests:
runs-on: ubuntu-latest
needs:
Expand Down
17 changes: 4 additions & 13 deletions pybatfish/client/asserts.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,20 +134,11 @@ def _get_duplicate_router_ids(
.frame()
)
if ignore_same_node:
# Maps Router_ID to whether multiple nodes have that Router_ID
router_id_on_duplicate_nodes = (
df.drop_duplicates(["Node", "Router_ID"])
.value_counts(["Router_ID"])
.map(lambda x: x > 1)
return df.groupby("Router_ID").filter(
lambda x: x["Node"].nunique() > 1 and x["Node"].nunique() != len(x)
)
df_duplicate = df[
df.apply(lambda x: router_id_on_duplicate_nodes[x["Router_ID"]], axis=1)
].sort_values(["Router_ID"])
else:
df_duplicate = df[df.duplicated(["Router_ID"], keep=False)].sort_values(
["Router_ID"]
)
return df_duplicate
return df[df.duplicated(["Router_ID"], keep=False)].sort_values(["Router_ID"])


def _is_dict_match(actual: Dict[str, Any], expected: Dict[str, Any]) -> bool:
Expand Down Expand Up @@ -782,7 +773,7 @@ def assert_no_duplicate_router_ids(

supported_protocols = {"bgp", "ospf"}
protocols_to_fetch = (
supported_protocols if protocols is None else set(map(str.lower, protocols))
supported_protocols if protocols is None else set(p.lower() for p in protocols)
)
if not protocols_to_fetch.issubset(supported_protocols):
raise ValueError(
Expand Down
2 changes: 1 addition & 1 deletion pybatfish/client/restv2helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ def auto_complete(
if session.snapshot
else "",
CoordConstsV2.RSC_AUTOCOMPLETE,
completion_type,
completion_type.value,
)
params = {} # type: Dict[str, Any]
if query:
Expand Down
87 changes: 46 additions & 41 deletions pybatfish/question/question.py
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@
else:
for i in range(0, len(value)):
valueElement = value[i]
typeValid = _validateType(valueElement, variableType)
typeValid = _validate_type(valueElement, variableType)
if not typeValid:
valid = False
errorMessage += (
Expand Down Expand Up @@ -750,7 +750,7 @@
)

else:
typeValid, typeValidErrorMessage = _validateType(
typeValid, typeValidErrorMessage = _validate_type(
value, variableType
)
if not typeValid:
Expand Down Expand Up @@ -796,7 +796,9 @@
return True


def _validateType(value, expectedType):
def _validate_type(
value: Any, expected_type: Union[str, VariableType]
) -> Tuple[bool, Optional[str]]:
"""
Check if the input `value` have contents that matches the requirements specified by `expectedType`.

Expand All @@ -805,28 +807,31 @@

:raises QuestionValidationException
"""
if expectedType == VariableType.BOOLEAN:
if not isinstance(expected_type, VariableType):
expected_type = VariableType(expected_type)

if expected_type == VariableType.BOOLEAN:
return isinstance(value, bool), None
elif expectedType == VariableType.COMPARATOR:
validComparators = ["<", "<=", "==", ">=", ">", "!="]
if value not in validComparators:
elif expected_type == VariableType.COMPARATOR:
valid_comparators = ["<", "<=", "==", ">=", ">", "!="]
if value not in valid_comparators:
return (
False,
"'{}' is not a known comparator. Valid options are: '{}'".format(
value, ", ".join(validComparators)
value, ", ".join(valid_comparators)
),
)
return True, None
elif expectedType == VariableType.INTEGER:
elif expected_type == VariableType.INTEGER:
INT32_MIN = -(2**32)
INT32_MAX = 2**32 - 1
valid = isinstance(value, int) and INT32_MIN <= value <= INT32_MAX
return valid, None
elif expectedType == VariableType.FLOAT:
elif expected_type == VariableType.FLOAT:
return isinstance(value, float), None
elif expectedType == VariableType.DOUBLE:
elif expected_type == VariableType.DOUBLE:
return isinstance(value, float), None
elif expectedType in [
elif expected_type in [
VariableType.ADDRESS_GROUP_NAME,
VariableType.APPLICATION_SPEC,
VariableType.BGP_PEER_PROPERTY_SPEC,
Expand Down Expand Up @@ -868,46 +873,46 @@
VariableType.ZONE,
]:
if not isinstance(value, str):
return False, f"A Batfish {expectedType} must be a string"
return False, f"A Batfish {expected_type.value} must be a string"
return True, None
elif expectedType == VariableType.IP:
elif expected_type == VariableType.IP:
if not isinstance(value, str):
return False, f"A Batfish {expectedType} must be a string"
return False, f"A Batfish {expected_type.value} must be a string"
else:
return _isIp(value)
elif expectedType == VariableType.IP_WILDCARD:
elif expected_type == VariableType.IP_WILDCARD:
if not isinstance(value, str):
return False, f"A Batfish {expectedType} must be a string"
return False, f"A Batfish {expected_type.value} must be a string"

Check warning on line 885 in pybatfish/question/question.py

View check run for this annotation

Codecov / codecov/patch

pybatfish/question/question.py#L885

Added line #L885 was not covered by tests
else:
return _isIpWildcard(value)
elif expectedType == VariableType.JSON_PATH:
elif expected_type == VariableType.JSON_PATH:
return _isJsonPath(value)
elif expectedType == VariableType.LONG:
elif expected_type == VariableType.LONG:
INT64_MIN = -(2**64)
INT64_MAX = 2**64 - 1
valid = isinstance(value, int) and INT64_MIN <= value <= INT64_MAX
return valid, None
elif expectedType == VariableType.PREFIX:
elif expected_type == VariableType.PREFIX:
if not isinstance(value, str):
return False, f"A Batfish {expectedType} must be a string"
return False, f"A Batfish {expected_type.value} must be a string"
else:
return _isPrefix(value)
elif expectedType == VariableType.PREFIX_RANGE:
elif expected_type == VariableType.PREFIX_RANGE:
if not isinstance(value, str):
return False, f"A Batfish {expectedType} must be a string"
return False, f"A Batfish {expected_type.value} must be a string"

Check warning on line 902 in pybatfish/question/question.py

View check run for this annotation

Codecov / codecov/patch

pybatfish/question/question.py#L902

Added line #L902 was not covered by tests
else:
return _isPrefixRange(value)
elif expectedType == VariableType.QUESTION:
elif expected_type == VariableType.QUESTION:
return isinstance(value, QuestionBase), None
elif expectedType == VariableType.BGP_ROUTES:
elif expected_type == VariableType.BGP_ROUTES:
if not isinstance(value, list) or not all(
isinstance(r, BgpRoute) for r in value
):
return False, f"A Batfish {expectedType} must be a list of BgpRoute"
return False, f"A Batfish {expected_type.value} must be a list of BgpRoute"

Check warning on line 911 in pybatfish/question/question.py

View check run for this annotation

Codecov / codecov/patch

pybatfish/question/question.py#L911

Added line #L911 was not covered by tests
return True, None
elif expectedType == VariableType.STRING:
elif expected_type == VariableType.STRING:
return isinstance(value, str), None
elif expectedType == VariableType.SUBRANGE:
elif expected_type == VariableType.SUBRANGE:
if isinstance(value, int):
return True, None
elif isinstance(value, str):
Expand All @@ -916,12 +921,12 @@
return (
False,
"A Batfish {} must either be a string or an integer".format(
expectedType
expected_type.value
),
)
elif expectedType == VariableType.PROTOCOL:
elif expected_type == VariableType.PROTOCOL:
if not isinstance(value, str):
return False, f"A Batfish {expectedType} must be a string"
return False, f"A Batfish {expected_type.value} must be a string"
else:
validProtocols = ["dns", "ssh", "tcp", "udp"]
if not value.lower() in validProtocols:
Expand All @@ -932,9 +937,9 @@
),
)
return True, None
elif expectedType == VariableType.IP_PROTOCOL:
elif expected_type == VariableType.IP_PROTOCOL:
if not isinstance(value, str):
return False, f"A Batfish {expectedType} must be a string"
return False, f"A Batfish {expected_type.value} must be a string"
else:
try:
intValue = int(value)
Expand All @@ -947,7 +952,7 @@
except ValueError:
# TODO: Should be validated at server side
return True, None
elif expectedType in [
elif expected_type in [
VariableType.ANSWER_ELEMENT,
VariableType.BGP_ROUTE_CONSTRAINTS,
VariableType.HEADER_CONSTRAINT,
Expand All @@ -957,13 +962,13 @@
else:
logging.getLogger(__name__).warning(
"WARNING: skipping validation for unknown argument type {}".format(
expectedType
expected_type.value
)
)
return True, None


def _isJsonPath(value):
def _isJsonPath(value: Any) -> Tuple[bool, Optional[str]]:
"""
Check if the input string represents a valid jsonPath.

Expand Down Expand Up @@ -991,7 +996,7 @@
return True, None


def _isIp(value):
def _isIp(value: str) -> Tuple[bool, Optional[str]]:
"""
Check if the input string represents a valid IP address.

Expand Down Expand Up @@ -1040,7 +1045,7 @@
return True, None


def _isSubRange(value):
def _isSubRange(value: str) -> Tuple[bool, Optional[str]]:
"""
Check if the input string represents a valid subRange.

Expand All @@ -1061,7 +1066,7 @@
return True, None


def _isPrefix(value):
def _isPrefix(value: str) -> Tuple[bool, Optional[str]]:
"""
Check if the input string represents a valid prefix.

Expand All @@ -1081,7 +1086,7 @@
return _isIp(contents[0])


def _isPrefixRange(value):
def _isPrefixRange(value: str) -> Tuple[bool, Optional[str]]:
"""
Check if the input string represents a valid prefix range.

Expand All @@ -1105,7 +1110,7 @@
return True, None


def _isIpWildcard(value):
def _isIpWildcard(value: str) -> Tuple[bool, Optional[str]]:
"""
Check if the input string represents a valid ipWildCard.

Expand Down
2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
],
python_requires=">=3.8",
# What does your project relate to?
Expand Down
Loading