Reduce metaclass conflicts with less eager proclamation, automatic metaclass merges

Well I only just noticed that since Python 3.11, there’s this slots option built-in to dataclass already so at least your specific use case has been taken care of:

from enum import Enum
from dataclasses import dataclass
from typing import Literal

@dataclass(slots=True)
class Card:
    value_: Literal[2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K', 'A']
    suite: Literal['heart', 'diamond', 'club', 'spade']

class PlayingCards(Card, Enum):
    TWO_OF_HEART = 2, 'heart'
    THREE_OF_SPADES = 3, 'spade'

print(PlayingCards.__slots__) # outputs ('value_', 'suite')
PlayingCards.TWO_OF_HEART.value.name = 'foo' # raises AttributeError

However, it has to be said that there never was a good reason IMHO for dataclass to be a class decorator to begin with if not for fear of a metaclass conflict. People have to use awkward workarounds to get __init_subclass__ to see dataclass fields, for example, only because dataclass is a decorator and not a metaclass-driven class.

Bottom Line

Reducing metaclass conflicts with a built-in resolution/merging mechanism will encourage developers to make better design choices without fear of affecting user experience.

1 Like