micropython-lib icon indicating copy to clipboard operation
micropython-lib copied to clipboard

python-stdlib/enum/enum.py: Add Enum class.

Open IhorNehrutsa opened this issue 10 months ago • 8 comments

Docs in: docs/library/enum.rst: Add Enum class. #16842 Usage example:

from enum import Enum
e = Enum({"X": 1, "Y": 2})                          # create Enum object from dictionary of key-value pairs
print(e)
print("add new key-value pair")
e.A = 'A'                                           # add new key-value pair
e.B = 'B'
print(e)
print("e.X:", e.X)                                  # get value from key
print("e.X.value:", e.X.value)                      # get value from key
print("e(e.X):", e(e.X))                            # get value from key
print("e.key_from_value(1):", e.key_from_value(1))  # get key from value
print("e.is_value(e.B):", e.is_value(e.B))
print("del e.B")
del e.B                                             # delete key-value pair
print(e)
print("e.is_value('B'):", e.is_value('B'))          # check if the value is in the Enum object
print("e.B: will raise the KeyError exception")
print(e.B)                                          # raise an exception due to no such a key attribute

Output is:

Enum({'Y': 2, 'X': 1})
add new key-value pair
Enum({'A': 'A', 'B': 'B', 'Y': 2, 'X': 1})
e.X: 1
e.X.value: 1
e(e.X): 1
e.key_from_value(1): Enum.X
e.is_value(e.B): True
del e.B
Enum({'A': 'A', 'Y': 2, 'X': 1})
e.is_value('B'): False
e.B: will raise the KeyError exception
Traceback (most recent call last):
File "<stdin>", line 234, in <module>
File "<stdin>", line 126, in __getattr__
KeyError: no such attribute: B

EDITED: Inspired by @shariltumin Dot class from the Way to use dot notation to refer to states in a state machine #15694 and @njourdane enum() func from the Request for package: micropython-enum #269

IhorNehrutsa avatar Mar 05 '25 10:03 IhorNehrutsa

Usage example::

from enum import Enum

class State(Enum):
  Stop = 10
  Run = 20
  Ready = 30

state = State()
print("state:", State())

current_state = state.Stop
print("current_state:", current_state, state.key_from_value(current_state))
if current_state == state.Stop:
  print(" Stop state")
if current_state != state.Ready:
  print(" Not a Ready state")
  print(" Run!")
  current_state = state.Run
print("current_state:", current_state, state.key_from_value(current_state))
# some process
i = -1
while current_state != state.Ready:
  i += 1
  if state.is_value(i):
      if state(i) == state.Ready:
          current_state = state.Ready
  print(".", end="")
print()
print("current_state:", current_state, state.key_from_value(current_state))
print("Done!")

Output is::

state: State({'Ready': 30, 'Stop': 10, 'Run': 20})
current_state: 10 State.Stop
Stop state
Not a Ready state
Run!
current_state: 20 State.Run
...............................
current_state: 30 State.Ready
Done!

IhorNehrutsa avatar Mar 05 '25 13:03 IhorNehrutsa

Thanks for the contribution, this looks pretty good!

Did you implement this from scratch, or copy parts from CPython's implementation? I'm just wondering about licensing and copyright.

Can you please add the test to the CI, in tools/ci.sh inside the function ci_package_tests_run.

dpgeorge avatar Mar 11 '25 00:03 dpgeorge

Did you implement this from scratch, or copy parts from CPython's implementation?

I just saw CPython Enum. It looks like incredible magic. :-)

IhorNehrutsa avatar Mar 11 '25 07:03 IhorNehrutsa

I just saw CPython Enum. It looks like incredible magic. :-)

That doesn't really answer the question. Did you copy this implementation from CPython?

Also, please make sure the CI all passes, there's currently a failure.

dpgeorge avatar Mar 11 '25 11:03 dpgeorge

| Did you implement this from scratch, or copy parts from CPython's implementation?

No, I didn't use CPython implementation.

It was inspired by @shariltumin Dot class from the Way to use dot notation to refer to states in a state machine #15694 and @njourdane enum() func from the Request for package: micropython-enum #269

IhorNehrutsa avatar Mar 11 '25 11:03 IhorNehrutsa

Should I squash commits?

IhorNehrutsa avatar Mar 12 '25 07:03 IhorNehrutsa

There is a quite comprehensive set of unit-tests for enum available in CPython: https://github.com/python/cpython/blob/main/Lib/test/test_enum.py With some exceptions like the tests using inspect, threading, pickle it seems possible to port most of them to MicroPython. That would give a very high degree of confidence that the implementation is conformant. And in the cases that one chooses to not be conformant, that can be documented with skipped tests.

jonnor avatar Apr 25 '25 18:04 jonnor

I have successfully completed the task that requires the Enum class. I don't plan to support this PR in the future. You are welcome to continue working with this PR as you wish. Thanks everyone.

IhorNehrutsa avatar Apr 30 '25 13:04 IhorNehrutsa