Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document tuples and __new__ #114071

Closed
blhsing opened this issue Jan 15, 2024 · 2 comments
Closed

Document tuples and __new__ #114071

blhsing opened this issue Jan 15, 2024 · 2 comments
Assignees
Labels
docs Documentation in the Doc dir

Comments

@blhsing
Copy link
Contributor

blhsing commented Jan 15, 2024

In this StackOverflow answer, Ethan Furman, the author of the enum module, demonstrated how a tuple value is special-cased so that it can be unpacked as arguments to the constructor of the mixin type, making it possible to extremely elegantly implement a member type with additional information such as a label for each member as requested by the SO question:

from enum import Enum

class LabelledEnumMixin:

    labels = {}

    def __new__(cls, value, label):
        member = object.__new__(cls)
        member._value_ = value
        member.label = label
        cls.labels[value] = label
        return member

    @classmethod
    def list_labels(cls):
        return list(l for c, l in cls.labels.items())


class Test(LabelledEnumMixin, Enum):
    A = 1, "Label A"
    B = 2, "Custom B"
    C = 3, "Custom label for value C + another string"

print(list(Test))
print(Test.list_labels())

This outputs:

[<Test.A: 1>, <Test.B: 2>, <Test.C: 3>]
['Label A', 'Custom B', 'Custom label for value C + another string']

Such a neat behavior of a tuple value is currently undocumented in the Supported __dunder__ names section of the enum's docs, however, making it more of an implementation detail rather than a publicly usable feature.

Please help document this feature properly so we can all benefit from the new possibilities this feature enables without fearing that we are using an undocumented implementation detail. Thanks.

Linked PRs

@blhsing blhsing added the docs Documentation in the Doc dir label Jan 15, 2024
@SultanOrazbayev
Copy link

SultanOrazbayev commented Jan 15, 2024

Moved to #114149

@ethanfurman ethanfurman changed the title Document the important fact that a tuple value of an Enum member is special-cased to be automatically unpacked as arguments to __new__ Document tuples and __new__ Jan 16, 2024
@ethanfurman
Copy link
Member

The NamedTuple problem is a different problem, and should get its own issue #. @SultanOrazbayev, can you create a new one?

ethanfurman added a commit that referenced this issue Feb 4, 2024
Update documentation with `__new__` and `__init__` entries.

Support use of `auto()` in tuple subclasses on member assignment lines.  Previously, auto() was only supported on the member definition line either solo or as part of a tuple:

    RED = auto()
    BLUE = auto(), 'azul'

However, since Python itself supports using tuple subclasses where tuples are expected, e.g.:

    from collections import namedtuple
    T = namedtuple('T', 'first second third')

    def test(one, two, three):
        print(one, two, three)

    test(*T(4, 5, 6))
    # 4 5 6

it made sense to also support tuple subclasses in enum definitions.
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Feb 4, 2024
…ythonGH-114871)

Update documentation with `__new__` and `__init__` entries.

Support use of `auto()` in tuple subclasses on member assignment lines.  Previously, auto() was only supported on the member definition line either solo or as part of a tuple:

    RED = auto()
    BLUE = auto(), 'azul'

However, since Python itself supports using tuple subclasses where tuples are expected, e.g.:

    from collections import namedtuple
    T = namedtuple('T', 'first second third')

    def test(one, two, three):
        print(one, two, three)

    test(*T(4, 5, 6))
    GH- 4 5 6

it made sense to also support tuple subclasses in enum definitions.
(cherry picked from commit ff7588b)

Co-authored-by: Ethan Furman <ethan@stoneleaf.us>
ethanfurman added a commit that referenced this issue Feb 8, 2024
…H-114871) (GH-114993)

Update documentation with `__new__` and `__init__` entries.

Support use of `auto()` in tuple subclasses on member assignment lines.  Previously, auto() was only supported on the member definition line either solo or as part of a tuple:

    RED = auto()
    BLUE = auto(), 'azul'

However, since Python itself supports using tuple subclasses where tuples are expected, e.g.:

    from collections import namedtuple
    T = namedtuple('T', 'first second third')

    def test(one, two, three):
        print(one, two, three)

    test(*T(4, 5, 6))
    GH- 4 5 6

it made sense to also support tuple subclasses in enum definitions.
(cherry picked from commit ff7588b)

Co-authored-by: Ethan Furman <ethan@stoneleaf.us>
aisk pushed a commit to aisk/cpython that referenced this issue Feb 11, 2024
…ythonGH-114871)

Update documentation with `__new__` and `__init__` entries.

Support use of `auto()` in tuple subclasses on member assignment lines.  Previously, auto() was only supported on the member definition line either solo or as part of a tuple:

    RED = auto()
    BLUE = auto(), 'azul'

However, since Python itself supports using tuple subclasses where tuples are expected, e.g.:

    from collections import namedtuple
    T = namedtuple('T', 'first second third')

    def test(one, two, three):
        print(one, two, three)

    test(*T(4, 5, 6))
    # 4 5 6

it made sense to also support tuple subclasses in enum definitions.
fsc-eriker pushed a commit to fsc-eriker/cpython that referenced this issue Feb 14, 2024
…ythonGH-114871)

Update documentation with `__new__` and `__init__` entries.

Support use of `auto()` in tuple subclasses on member assignment lines.  Previously, auto() was only supported on the member definition line either solo or as part of a tuple:

    RED = auto()
    BLUE = auto(), 'azul'

However, since Python itself supports using tuple subclasses where tuples are expected, e.g.:

    from collections import namedtuple
    T = namedtuple('T', 'first second third')

    def test(one, two, three):
        print(one, two, three)

    test(*T(4, 5, 6))
    # 4 5 6

it made sense to also support tuple subclasses in enum definitions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation in the Doc dir
Projects
None yet
Development

No branches or pull requests

3 participants