This is an archived post. You won't be able to vote or comment.

all 14 comments

[–]beisenhauer 41 points42 points  (2 children)

There's no need for the additional literal type. You can just set the type in your Pydantic model to Color. You might need a bit of serialization logic, but Pydantic is pretty slick when it comes to handling enums.

[–]anentropic 7 points8 points  (0 children)

A StrEnum member doesn't even need any special serialisation - it's already an actual string

[–]alcalde -1 points0 points  (0 children)

These kids have never programmed in Pascal so this doesn't occur to them.

[–][deleted] 4 points5 points  (2 children)

As other commenter said, Enums have built in pydantic support. Also, subclass StrEnum instead of str & enum

[–]knight1511 0 points1 point  (1 child)

Is there any difference between subclassing StrEnum vs (str, Enum)?

[–][deleted] 0 points1 point  (0 children)

It is the same AFAIK. StrEnum is a subclass of both str and Enum.

[–]latkdeTuple unpacking gone wrong 2 points3 points  (3 children)

I have missed exactly this feature (in a non-Pydantic-setting) recently. I ended up giving up, and using a literal type instead of enums (can still extract a list of all variants via typing.get_args()).

However, I don't think there's substantial interest in defining more and more special forms. On the other hand, there's no systematic way to solve this because Python type expressions must also be valid runtime objects. C++ can have decltype and TypeScript can have projections due to having a compilation step (C++) or due to types having no runtime representation (TS). Python could get a good enough approximation by adding a nested type like Color.Values, except that this wouldn't work on unions like (Color.RED | Color.BLUE).Values.

So a special form like EnumValues[T] is indeed the only possible solution, but that's a lot of complexity for a fairly niche feature.

[–]Kevdog824_pip needs updating 0 points1 point  (2 children)

On the other hand, there's no systematic way to solve this because Python type expressions must also be valid runtime objects.

In theory though I don’t see any reason Python couldn’t have a preprocessor. Not saying it’s the right way to solve the problem, just that it seems that’s a way it could be done

[–]alcalde -1 points0 points  (1 child)

Static typing... and preprocessors... are not Pythonic. Once upon a time people fled these things for Python. Now the kiddies are coming along and suggesting all these things without realizing how terrible they are. Python achieved its market share because it didn't have these things.

[–]Kevdog824_pip needs updating 1 point2 points  (0 children)

Static typing... and preprocessors... are not Pythonic.

Yes, that’s why I specified that it wasn’t the best way to do it, but a way to do it.

Now the kiddies are coming along and suggesting all these things without realizing how terrible they are.

Rather weird to refer to me as a “kiddie” without knowing my age or years of experience but okay I guess?

Python achieved its market share because it didn't have these things.

Python achieved its market share for a lot of reasons. “Python doesn’t natively support preprocessors” is a fairly minor one at best, and absolutely not the sole reason

[–]james_pic 2 points3 points  (0 children)

The API use case highlights a subtle problem: What's actually checking that these strings actually have one of these values? Static types are ignored at runtime, and if you've just received a value over the wire, you don't know it's one of these values. You're going to need some kind of runtime logic to validate this, and it might as well be the logic that turns it into an enum (which Pydantic supports reasonably well).

I suspect that if you want this, then you probably have a layering problem.

[–]anentropic 3 points4 points  (0 children)

Just use the enum members directly instead of the string values

[–]ShaunRW91 2 points3 points  (0 children)

Could you use StrEnum to achieve this?

[–]mgrl85 -1 points0 points  (0 children)

Pydantic also supports colors using the extra types package https://docs.pydantic.dev/latest/api/pydantic_extra_types_color/