From ec7adb1aaf8908d52b7831d10ed86250789ec45a Mon Sep 17 00:00:00 2001 From: Sam Muralidhar Date: Tue, 30 Dec 2025 03:35:43 -0600 Subject: [PATCH] fix: correct FeatureUsageFlag to use IntFlag and return str from __str__ The FeatureUsageFlag enum has two issues: 1. The __str__ method returns self.value (an int) instead of a string, violating Python's data model requirement that __str__ must return str. This causes TypeError on all Python versions when calling str() on enum members. 2. The class inherits from (int, Enum) instead of IntFlag, even though the values are clearly bit flags (powers of 2). This prevents proper bitwise operations - combining flags with | returns plain int instead of FeatureUsageFlag. Changes Made: - Changed FeatureUsageFlag base class from (int, Enum) to IntFlag - Fixed __str__ to return str(self.value) instead of self.value - Added test suite for all enum classes --- src/msgraph_core/_enums.py | 6 +- tests/test_enums.py | 114 +++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 tests/test_enums.py diff --git a/src/msgraph_core/_enums.py b/src/msgraph_core/_enums.py index 5f217fe8..74918f15 100644 --- a/src/msgraph_core/_enums.py +++ b/src/msgraph_core/_enums.py @@ -4,7 +4,7 @@ # ------------------------------------ #pylint: disable=invalid-name -from enum import Enum +from enum import Enum, IntFlag class APIVersion(str, Enum): @@ -16,7 +16,7 @@ def __str__(self): return self.value -class FeatureUsageFlag(int, Enum): +class FeatureUsageFlag(IntFlag): """Enumerated list of values used to flag usage of specific middleware""" NONE = 0 @@ -27,7 +27,7 @@ class FeatureUsageFlag(int, Enum): LOGGING_HANDLER_ENABLED = 16 def __str__(self): - return self.value + return str(self.value) class NationalClouds(str, Enum): diff --git a/tests/test_enums.py b/tests/test_enums.py new file mode 100644 index 00000000..547883eb --- /dev/null +++ b/tests/test_enums.py @@ -0,0 +1,114 @@ +"""Tests for msgraph_core._enums module.""" +from enum import Enum, IntFlag + +from msgraph_core._enums import APIVersion, FeatureUsageFlag, NationalClouds + + +def test_feature_usage_flag_str_returns_string_type(): + """__str__() must return str, not int (Python data model requirement).""" + for flag in FeatureUsageFlag: + result = str(flag) + assert isinstance(result, str), ( + f"str({flag.name}) returned {type(result).__name__}, expected str" + ) + + +def test_feature_usage_flag_str_returns_numeric_value_as_string(): + """__str__() should return the numeric value as a string.""" + assert str(FeatureUsageFlag.NONE) == "0" + assert str(FeatureUsageFlag.REDIRECT_HANDLER_ENABLED) == "1" + assert str(FeatureUsageFlag.RETRY_HANDLER_ENABLED) == "2" + assert str(FeatureUsageFlag.AUTH_HANDLER_ENABLED) == "4" + assert str(FeatureUsageFlag.DEFAULT_HTTP_PROVIDER_ENABLED) == "8" + assert str(FeatureUsageFlag.LOGGING_HANDLER_ENABLED) == "16" + + +def test_feature_usage_flag_is_intflag(): + """FeatureUsageFlag should be an IntFlag for proper bitwise operations.""" + assert issubclass(FeatureUsageFlag, IntFlag) + + +def test_feature_usage_flag_is_int_instance(): + """FeatureUsageFlag members should be instances of int.""" + for flag in FeatureUsageFlag: + assert isinstance(flag, int) + + +def test_feature_usage_flag_is_enum_instance(): + """FeatureUsageFlag members should be instances of Enum.""" + for flag in FeatureUsageFlag: + assert isinstance(flag, Enum) + + +def test_feature_usage_flag_bitwise_or_returns_feature_usage_flag(): + """Bitwise OR should return FeatureUsageFlag, not plain int.""" + combined = FeatureUsageFlag.REDIRECT_HANDLER_ENABLED | FeatureUsageFlag.RETRY_HANDLER_ENABLED + assert isinstance(combined, FeatureUsageFlag) + assert combined.value == 3 + + +def test_feature_usage_flag_bitwise_and_returns_feature_usage_flag(): + """Bitwise AND should return FeatureUsageFlag, not plain int.""" + combined = FeatureUsageFlag.REDIRECT_HANDLER_ENABLED | FeatureUsageFlag.RETRY_HANDLER_ENABLED + result = combined & FeatureUsageFlag.REDIRECT_HANDLER_ENABLED + assert isinstance(result, FeatureUsageFlag) + assert result.value == 1 + + +def test_feature_usage_flag_bitwise_xor_returns_feature_usage_flag(): + """Bitwise XOR should return FeatureUsageFlag, not plain int.""" + combined = FeatureUsageFlag.REDIRECT_HANDLER_ENABLED | FeatureUsageFlag.RETRY_HANDLER_ENABLED + result = combined ^ FeatureUsageFlag.REDIRECT_HANDLER_ENABLED + assert isinstance(result, FeatureUsageFlag) + assert result.value == 2 + + +def test_feature_usage_flag_bitwise_invert_returns_feature_usage_flag(): + """Bitwise invert should return FeatureUsageFlag, not plain int.""" + result = ~FeatureUsageFlag.NONE + assert isinstance(result, FeatureUsageFlag) + + +def test_feature_usage_flag_combined_flags_str(): + """Combined flags should also return string from __str__().""" + combined = FeatureUsageFlag.REDIRECT_HANDLER_ENABLED | FeatureUsageFlag.RETRY_HANDLER_ENABLED + result = str(combined) + assert isinstance(result, str) + assert result == "3" + + +def test_feature_usage_flag_values_are_powers_of_two(): + """Flag values should be powers of 2 (except NONE=0) for proper bitmask behavior.""" + assert FeatureUsageFlag.NONE.value == 0 + assert FeatureUsageFlag.REDIRECT_HANDLER_ENABLED.value == 1 + assert FeatureUsageFlag.RETRY_HANDLER_ENABLED.value == 2 + assert FeatureUsageFlag.AUTH_HANDLER_ENABLED.value == 4 + assert FeatureUsageFlag.DEFAULT_HTTP_PROVIDER_ENABLED.value == 8 + assert FeatureUsageFlag.LOGGING_HANDLER_ENABLED.value == 16 + + +def test_api_version_str_returns_string_type(): + """__str__() must return str.""" + for version in APIVersion: + result = str(version) + assert isinstance(result, str) + + +def test_api_version_str_returns_value(): + """__str__() should return the enum value.""" + assert str(APIVersion.beta) == "beta" + assert str(APIVersion.v1) == "v1.0" + + +def test_national_clouds_str_returns_string_type(): + """__str__() must return str.""" + for cloud in NationalClouds: + result = str(cloud) + assert isinstance(result, str) + + +def test_national_clouds_str_returns_url_value(): + """__str__() should return the cloud URL.""" + assert str(NationalClouds.Global) == "https://graph.microsoft.com" + assert str(NationalClouds.US_GOV) == "https://graph.microsoft.us" + assert str(NationalClouds.China) == "https://microsoftgraph.chinacloudapi.cn"