Usecase: broken feature
¶
Scenario:¶
As a programmer you are working on a new feature (method/function/class/etc.). However, the feature you are programming is not yet working perfectly. Unfortunately, you do not have the time to fix the feature right away. Perhaps, it isn't even your feature. You still want to push/merge the change, but others should not use the broken feature.
class FizzBuzz:
def check_fizz(self, value: int) -> bool:
if value % 3 == 0:
return True
return False
def check_buzz(self, value: int) -> bool:
raise ValueError("Feature not finished, can't work with value.")
In the example above, a FizzBuzz
checker is created. However, the check_buzz
feature doesn't work yet.
fizz_buzz = FizzBuzz()
fizz_buzz.check_fizz(3)
True
fizz_buzz.check_buzz(5)
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[3], line 1 ----> 1 fizz_buzz.check_buzz(5) Cell In[1], line 9, in FizzBuzz.check_buzz(self, value) 8 def check_buzz(self, value: int) -> bool: ----> 9 raise ValueError("Feature not finished, can't work with value.") ValueError: Feature not finished, can't work with value.
With a feature flag, we can easily disable that feature.
from fastfeatureflag.feature_flag import feature_flag
class FizzBuzz:
def check_fizz(self, value: int) -> bool:
if value % 3 == 0:
return True
return False
@feature_flag()
def check_buzz(self, value: int) -> bool:
raise ValueError("Feature not finished, can't work with value.")
fizz_buzz = FizzBuzz()
fizz_buzz.check_buzz(5)
--------------------------------------------------------------------------- NotImplementedError Traceback (most recent call last) Cell In[5], line 2 1 fizz_buzz = FizzBuzz() ----> 2 fizz_buzz.check_buzz(5) File /opt/hostedtoolcache/Python/3.12.0/x64/lib/python3.12/site-packages/fastfeatureflag/feature_flag_configuration.py:62, in FeatureFlagConfiguration.__call__(self, *args, **kwargs) 59 if self.feature.shadow: 60 return self._shadow_function(*args, **kwargs) ---> 62 return self._decorated_function(*args, **kwargs) File /opt/hostedtoolcache/Python/3.12.0/x64/lib/python3.12/site-packages/fastfeatureflag/feature_flag_configuration.py:202, in FeatureFlagConfiguration._decorated_function(self, *args, **kwargs) 199 if self.feature.response: 200 return self.feature.response --> 202 raise NotImplementedError("Feature not implemented") from None 204 if ( 205 self.feature.activation == "on" 206 or os.environ.get(self.feature.activation) == "on" 207 ): 208 self._options = self._options | kwargs NotImplementedError: Feature not implemented
Now a NotImplementedError
appears. The feature is now disabled. This will avoid, that other users might use that feature by accident.
But perhaps an Exception is not what you want. Perhaps you want to have a predefined return value. This might help with testing, etc. Even without the feature being finished.
from fastfeatureflag.feature_flag import feature_flag
class FizzBuzz:
def check_fizz(self, value: int) -> bool:
if value % 3 == 0:
return True
return False
@feature_flag(response=True)
def check_buzz(self, value: int) -> bool:
raise ValueError("Feature not finished, can't work with value.")
fizz_buzz = FizzBuzz()
fizz_buzz.check_buzz(5)
True
Of course, this can also lead to misleading errors/issues/behaviors
fizz_buzz.check_buzz(6)
True
Created: October 28, 2023