1

I have his Enum :

class MultiAttr(Enum):
    RED = (1, 10)
    GREEN = (2, 20)
    BLUE = (3, 20)
    def __init__(self, id, val):
        self.id = id
        self.val = val
assert MultiAttr((2, 20)) == MultiAttr.GREEN

Assertion passes.

  1. Why Pylance in VSCode complains Argument missing for parameter "val" ?
  2. As the first attribute is the identifer, is there a way to achieve : MultiAttr(2) == MultiAttr.GREEN ?
Philippe
  • 20,025
  • 2
  • 23
  • 32
  • Pylance complains because given the `__init__` you should pass two arguments, `2` and `20`, but you are only passing one argument, a tuple `(2, 20)`. – mkrieger1 Sep 16 '22 at 22:00
  • @mkrieger1 But `MultiAttr(2, 20)` gives an error. Any thoughts about second question? – Philippe Sep 16 '22 at 22:13

1 Answers1

3

You could make use of __new__, as you want to customize the actual value of the Enum member:

from enum import Enum

class MultiAttr(bytes, Enum):
    def __new__(cls, value, otherVal):
        obj = bytes.__new__(cls, [value])
        obj._value_ = value
        obj.otherVal = otherVal
        return obj
    RED = (1, 10)
    GREEN = (2, 20)
    BLUE = (3, 20)


print(MultiAttr(2) == MultiAttr.GREEN)
print(MultiAttr(2).otherVal)

Out:

True
20
Maurice Meyer
  • 17,279
  • 4
  • 30
  • 47
  • Thanks! One minor issue is that Pylance complains `Member "otherVal" is unknown` on `MultiAttr(2).otherVal`. – Philippe Sep 17 '22 at 00:20
  • You can define a class attribute with a type `otherVal: int` and that should help type checking @Philippe, see further description here: https://rednafi.com/python/add_attributes_to_enum_members – NeilG Sep 01 '23 at 09:41
  • For an optionally dynamically created `enum` which works with `pydantic` by name but supports a value of any type refer to the comprehensive answers here: https://stackoverflow.com/questions/75587442/validate-pydantic-dynamic-float-enum-by-name-with-openapi-description – NeilG Sep 01 '23 at 09:43