Last active
December 16, 2024 07:05
-
-
Save jymchng/f21b38a58879a8a2ee0ffb66fe31cb28 to your computer and use it in GitHub Desktop.
Revisions
-
jymchng revised this gist
Dec 16, 2024 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,4 +2,4 @@ In the file, `env_variant.py`, the plan is to have `RollYourOwnNewTypeEnum` with variants that are only in this allowed set (`__VALID_MEMBERS__ = ["LOCAL", "DEV", "SIT", "UAT", "PREPROD", "PROD"]`). However, there seems to be no way to write `ENVVariant.my_replace(..)`? -
jymchng revised this gist
Dec 16, 2024 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1 @@ pytest -
jymchng revised this gist
Dec 16, 2024 . 1 changed file with 5 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,5 @@ # Challenge In the file, `env_variant.py`, the plan is to have `RollYourOwnNewTypeEnum` with variants that are only in this allowed set (`__VALID_MEMBERS__ = ["LOCAL", "DEV", "SIT", "UAT", "PREPROD", "PROD"]`). However, there seems to be no way to read `ENVVariant.my_replace(..)`? -
jymchng revised this gist
Dec 16, 2024 . 1 changed file with 68 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,68 @@ import pytest from enum import Enum class ENVVariant(str): __VALID_MEMBERS__ = ["LOCAL", "DEV", "SIT", "UAT", "PREPROD", "PROD"] def __new__(cls, value: str): members = ENVVariant.__VALID_MEMBERS__ if isinstance(value, RollYourOwnNewTypeEnum): value_as_str = str(value.value) else: value_as_str = str(value) if value_as_str not in members: raise ValueError(f"`value` = {value} must be one of `{members}`; `value_as_str` = {value_as_str}") return super().__new__(cls, value_as_str) # why not i write my own `.replace(..)` # yes, you can but how? def my_replace(self, old: "ENVVariant", new: "ENVVariant", count: int=-1): return ENVVariant(str(self).replace(str(old), str(new), count)) class RollYourOwnNewTypeEnum(ENVVariant, Enum): LOCAL = "LOCAL" DEV = "DEV" SIT = "SIT" UAT = "UAT" PREPROD = "PREPROD" PROD = "PROD" def test_ryont_env_replace(): env = RollYourOwnNewTypeEnum.LOCAL # expected outcomes assert env is RollYourOwnNewTypeEnum.LOCAL # pass assert env is not RollYourOwnNewTypeEnum.DEV # pass assert isinstance(env, RollYourOwnNewTypeEnum) # pass # now we try to replace env = env.replace(RollYourOwnNewTypeEnum.LOCAL, RollYourOwnNewTypeEnum.DEV) # we are hoping that it will continue to be a `RollYourOwnNewTypeEnum.DEV` but it is not assert env is not RollYourOwnNewTypeEnum.DEV # pass, no longer a `RollYourOwnNewTypeEnum` assert env is not RollYourOwnNewTypeEnum.LOCAL # pass, no longer a `RollYourOwnNewTypeEnum` assert not isinstance(env, RollYourOwnNewTypeEnum) assert isinstance(env, str) # 'downcast' (?) to `str` with pytest.raises(AssertionError): assert env is RollYourOwnNewTypeEnum.DEV with pytest.raises(AssertionError): assert env is RollYourOwnNewTypeEnum.DEV with pytest.raises(AssertionError): assert isinstance(env, RollYourOwnNewTypeEnum) env = env.replace("DEV", "NotAnEnv") assert env == "NotAnEnv" # this 'shouldn't' pass but it does env = RollYourOwnNewTypeEnum.LOCAL env = env.my_replace(RollYourOwnNewTypeEnum.LOCAL, RollYourOwnNewTypeEnum.PREPROD) assert isinstance(env, str) assert env is RollYourOwnNewTypeEnum.PREPROD assert isinstance(env, RollYourOwnNewTypeEnum) -
jymchng created this gist
Dec 16, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,134 @@ from newtype import NewType, newtype_exclude from enum import Enum import pytest class ENV(NewType(str), Enum): LOCAL = "LOCAL" DEV = "DEV" SIT = "SIT" UAT = "UAT" PREPROD = "PREPROD" PROD = "PROD" class RegularENV(str, Enum): LOCAL = "LOCAL" DEV = "DEV" SIT = "SIT" UAT = "UAT" PREPROD = "PREPROD" PROD = "PROD" class ENVVariant(str): __VALID_MEMBERS__ = ["LOCAL", "DEV", "SIT", "UAT", "PREPROD", "PROD"] def __new__(cls, value: str): members = ENVVariant.__VALID_MEMBERS__ if isinstance(value, RollYourOwnNewTypeEnum): value_as_str = str(value.value) else: value_as_str = str(value) if value_as_str not in members: raise ValueError(f"`value` = {value} must be one of `{members}`; `value_as_str` = {value_as_str}") return super().__new__(cls, value_as_str) # why not i write my own `.replace(..)` # yes, you can but how? def my_replace(self, old: "ENVVariant", new: "ENVVariant", count: int=-1): return ENVVariant(str(self).replace(str(old), str(new), count)) class RollYourOwnNewTypeEnum(ENVVariant, Enum): LOCAL = "LOCAL" DEV = "DEV" SIT = "SIT" UAT = "UAT" PREPROD = "PREPROD" PROD = "PROD" def test_nt_env_replace(): env = ENV.LOCAL assert env is ENV.LOCAL assert env is not ENV.DEV assert isinstance(env, ENV) # let's say now we want to replace the environment # nevermind about the reason why we want to do so env = env.replace(ENV.LOCAL, ENV.DEV) # replacement is successful assert env is ENV.DEV assert env is not ENV.LOCAL # still an `ENV` assert isinstance(env, ENV) assert isinstance(env, str) with pytest.raises(ValueError): # cannot replace with something that is not a `ENV` env = env.replace(ENV.DEV, "NotAnEnv") with pytest.raises(ValueError): # cannot even make 'DEV' -> 'dev' env = env.lower() def test_reg_env_replace(): env = RegularENV.LOCAL # expected outcomes assert env is RegularENV.LOCAL # pass assert env is not RegularENV.DEV # pass assert isinstance(env, RegularENV) # pass # now we try to replace env = env.replace(RegularENV.LOCAL, RegularENV.DEV) # we are hoping that it will continue to be a `RegularENV.DEV` but it is not assert env is not RegularENV.DEV # pass, no longer a `RegularENV` assert env is not RegularENV.LOCAL # pass, no longer a `RegularENV` assert not isinstance(env, RegularENV) assert isinstance(env, str) # 'downcast' (?) to `str` def test_ryont_env_replace(): env = RollYourOwnNewTypeEnum.LOCAL # expected outcomes assert env is RollYourOwnNewTypeEnum.LOCAL # pass assert env is not RollYourOwnNewTypeEnum.DEV # pass assert isinstance(env, RollYourOwnNewTypeEnum) # pass # now we try to replace env = env.replace(RollYourOwnNewTypeEnum.LOCAL, RollYourOwnNewTypeEnum.DEV) # we are hoping that it will continue to be a `RollYourOwnNewTypeEnum.DEV` but it is not assert env is not RollYourOwnNewTypeEnum.DEV # pass, no longer a `RollYourOwnNewTypeEnum` assert env is not RollYourOwnNewTypeEnum.LOCAL # pass, no longer a `RollYourOwnNewTypeEnum` assert not isinstance(env, RollYourOwnNewTypeEnum) assert isinstance(env, str) # 'downcast' (?) to `str` with pytest.raises(AssertionError): assert env is RollYourOwnNewTypeEnum.DEV with pytest.raises(AssertionError): assert env is RollYourOwnNewTypeEnum.DEV with pytest.raises(AssertionError): assert isinstance(env, RollYourOwnNewTypeEnum) env = env.replace("DEV", "NotAnEnv") assert env == "NotAnEnv" # this 'shouldn't' pass but it does env = RollYourOwnNewTypeEnum.LOCAL env = env.my_replace(RollYourOwnNewTypeEnum.LOCAL, RollYourOwnNewTypeEnum.PREPROD) assert isinstance(env, str) assert env is RollYourOwnNewTypeEnum.PREPROD assert isinstance(env, RollYourOwnNewTypeEnum)