diff --git a/python-stdlib/enum/enum.py b/python-stdlib/enum/enum.py
new file mode 100644
index 000000000..9d62faaf4
--- /dev/null
+++ b/python-stdlib/enum/enum.py
@@ -0,0 +1,211 @@
+# enum.py
+
+_Err = "no such attribute: "
+
+
+class int_value(int):
+    @property
+    def value(self) -> int:
+        return self
+
+    def __call__(self) -> int:
+        return self
+
+
+class str_value(str):
+    @property
+    def value(self) -> str:
+        return self
+
+    def __call__(self) -> str:
+        return self
+
+
+class bool_value(bool):
+    @property
+    def value(self) -> bool:
+        return self
+
+    def __call__(self) -> bool:
+        return self
+
+
+class float_value(float):
+    @property
+    def value(self) -> float:
+        return self
+
+    def __call__(self) -> float:
+        return self
+
+
+def get_class_value(value):
+    if type(value) is int:
+        return int_value(value)
+    elif type(value) is bool:
+        return bool_value(value)
+    elif type(value) is float:
+        return float_value(value)
+    elif type(value) is str:
+        return str_value(value)
+    else:
+        return value
+
+
+def enum(**kw_args):  # `**kw_args` kept backwards compatible as in the Internet examples
+    return Enum(kw_args)
+
+
+class Enum(dict):
+    def __init__(self, arg=None):  # `arg` is dict() compatible
+        super().__init__()
+        self._arg = None
+        if not arg is None:
+            self.append(arg)
+        self._is_enums_from_class = False
+        self._get_enums_from_class()
+
+    def _update(self, key, value):
+        self.update({key: get_class_value(value)})
+
+    def append(self, arg=None, **kw_args):
+        if len(kw_args):
+            for key, value in kw_args.items():
+                self._update(key, value)
+        if type(arg) == type(dict()):
+            for key, value in arg.items():
+                self._update(key, value)
+        else:
+            self._arg = arg  # for __str__()
+        return self
+
+    def __repr__(self):
+        d = self.copy()
+        try:
+            d.pop("_arg")
+        except:
+            pass
+        return str(d)
+
+    def __str__(self):
+        value = None
+        try:
+            value = self._arg
+        except:
+            pass
+        if not value is None:
+            if self.is_value(value):
+                self._arg = None
+                return value
+            raise ValueError(_Err + f"{value}")
+        return self.__qualname__ + "(" + self.__repr__() + ")"
+
+    def is_value(self, value):
+        if value in self.values():
+            return True
+        return False
+
+    def key_from_value(self, value):
+        for key in self:
+            if self.get(key) == value:
+                return self.__qualname__ + "." + key
+        raise ValueError(_Err + f"{value}")
+
+    def __call__(self, value):
+        if self.is_value(value):
+            return value
+        raise ValueError(_Err + f"{value}")
+
+    def __getattr__(self, key):
+        try:
+            if key in self:
+                return self[key]
+            else:
+                raise KeyError(_Err + f"{key}")
+        except:
+            raise KeyError(_Err + f"{key}")
+
+    def __setattr__(self, key, value):
+        if key == "_arg":
+            self[key] = value
+            return
+        try:
+            self[key] = get_class_value(value)
+        except:
+            raise KeyError(_Err + f"{key}")
+
+    def __delattr__(self, key):
+        try:
+            if key in self:
+                del self[key]
+            else:
+                raise KeyError(_Err + f"{key}")
+        except:
+            raise KeyError(_Err + f"{key}")
+
+    def __len__(self):
+        return len(tuple(self.keys()))
+
+    def __dir__(self):
+        return dir(Enum)
+
+    def _get_enums_from_class(self):
+        ## Class XX(Enum):
+        ##     X1 = 1
+        ##     X2 = 2
+
+        if not self._is_enums_from_class:
+            keys = dir(eval(self.__qualname__))
+
+            def try_remove(item):
+                try:
+                    keys.remove(item)
+                except:
+                    pass
+
+            for item in dir(dict):
+                try_remove(item)
+
+            _list = [
+                "__init__",
+                "__class__init__",
+                "__call__",
+                "__Errases__",
+                "__module__",
+                "__qualname__",
+                "__len__",
+                "__lt__",
+                "__le__",
+                "__eq__",
+                "__ne__",
+                "__gt__",
+                "__ge__",
+                "__dir__",
+                "__delattr__",
+                "__getattr__",
+                "__setattr__",
+                "__str__",
+                "__repr__",
+                "_get_enums_from_class",
+                "_arg",
+                "_update",
+                "is_value",
+                "key_from_value",
+                "append",
+            ]
+            for item in _list:
+                try_remove(item)
+            module = ""
+            if self.__module__ != "__main__":
+                module = self.__module__ + "."
+            for key in keys:
+                try:
+                    value = eval(f"{module}{self.__qualname__}.{key}")
+                except:
+                    value = eval(f"{self.__qualname__}.{key}")
+                self._update(key, value)
+            keys.clear()
+            del keys
+            self._is_enums_from_class = True  # 1 !!!
+            self.pop("_is_enums_from_class")  # 2 !!!
+        return self
diff --git a/python-stdlib/enum/manifest.py b/python-stdlib/enum/manifest.py
new file mode 100644
index 000000000..6b6b821ca
--- /dev/null
+++ b/python-stdlib/enum/manifest.py
@@ -0,0 +1,3 @@
+metadata(version="1.0.0")
+
+module("enum.py")
diff --git a/python-stdlib/enum/test_enum.py b/python-stdlib/enum/test_enum.py
new file mode 100644
index 000000000..1ad848f0a
--- /dev/null
+++ b/python-stdlib/enum/test_enum.py
@@ -0,0 +1,91 @@
+# enum_test.py
+
+from enum import Enum, enum
+
+
+class Direction(Enum):
+    CW = "CW"
+    CCW = "CCW"
+
+
+class State(Direction):
+    Stop = 1
+    Run = 2
+    Ready = 3
+    Disabled = False
+    Enabled = True
+
+
+state = Enum()
+print(state)
+state = Direction()
+print(state)
+state = State()
+print(state)
+state = State({"X": 1.0, "Y": 2.0})
+print(state)
+state.Idle = 10
+state.Triggered = 20
+state.Lockout = 30
+print(state)
+
+print("Direction(Direction.CCW):", Direction(Direction.CCW))
+print("Direction('CW'):", Direction("CW"))
+print("state(10):", state(10))
+
+print("state('CW'):", state("CW"))
+print("type(state('CW')):", type(state("CW")))
+
+print("state.key_from_value(20):", state.key_from_value(20))
+print("len(state):", len(state))
+
+print("state.Idle:", state.Idle)
+print("type(state.Idle):", type(state.Idle))
+
+current_state = state.Idle
+print("current_state:", current_state)
+if current_state == state.Idle:
+    print(" Idle state")
+if current_state != state.Triggered:
+    print(" Not a triggered state")
+    current_state = state.Idle
+print("current_state:", current_state)
+print("state.key_from_value(current_state):", state.key_from_value(current_state))
+
+state2 = eval(str(state))
+print(state2)
+print("state == state2:", state == state2)
+
+del state.Triggered
+print(state)
+print("state == state2:", state == state2)
+
+print("state.keys():", state.keys())
+print("state.values():", state.values())
+print("state.items():", state.items())
+
+try:
+    del state.stop
+except Exception as e:
+    print("Exception:", e)
+
+assert current_state == state.Idle
+assert current_state != state.Disabled
+assert state.Idle != state.Disabled
+print(
+    "State(State.Ready):",
+    State(State.Ready),
+    "type(State.Ready):",
+    type(State(State.Ready)),
+    "type(State.Ready):",
+    type(State.Ready),
+)
+assert int(str(State(State.Ready))) == State.Ready
+assert int(str(State(State.Ready))) != State.Disabled
+print("will raise exception")
+try:
+    del state.Triggered
+except Exception as e:
+    print("Exception:", e)
+
+print("OK")
diff --git a/tools/ci.sh b/tools/ci.sh
index a5fcdf22e..a109d1c45 100755
--- a/tools/ci.sh
+++ b/tools/ci.sh
@@ -54,6 +54,7 @@ function ci_package_tests_run {
         python-stdlib/base64/test_base64.py \
         python-stdlib/binascii/test_binascii.py \
         python-stdlib/collections-defaultdict/test_defaultdict.py \
+        python-stdlib/enum/test_enum.py \
         python-stdlib/functools/test_partial.py \
         python-stdlib/functools/test_reduce.py \
         python-stdlib/heapq/test_heapq.py \