py-flags icon indicating copy to clipboard operation
py-flags copied to clipboard

contrary to doc header, enum.Flag is inadequate

Open belm0 opened this issue 5 years ago • 3 comments

Python 3.6+ users should consider using the Flag and IntFlag classes of the standard enum module. Those are very similar to the flags.Flags class of this repo.

I don't agree that they are very similar. I found py-flags after frustration with enum.Flag. The main problem with enum.Flag is that it doesn't act sufficiently like a set.

  • 0 flag, compound flags, and aliases are included in iteration
  • class instances lack iteration, len, and subset operator

belm0 avatar Sep 22 '19 08:09 belm0

I don't agree with some of the design decisions of the standard flags but that is still the standard (and builtin) so people should consider using it when it covers their use cases. At the same time that module has a python2 port (called aenum) while this is python3 only.

In my opinion the standard module lacks some useful features while my solution is too feature rich. In the future I might compile a list of differences between the two.

Certain aspects of a flags library don't fit into the python language. The language itself doesn't support enums/flags (being a small language isn't necessarily a bad thing...) and some flags related features can't be simulated nicely (e.g.: you have to write enum_member = () to auto-assign a value). For this reason, and because most programs don't really need bit flags (it's a relatively narrow-purpose thing) I'm wondering whether it's a good idea to have a flags as part of the standard library.

pasztorpisti avatar Sep 23 '19 10:09 pasztorpisti

I was surprised that there doesn't seem to be a PEP-like process for stdlib additions. You just open an issue with some patches, and a few people on a thread have some debate, and then... Flag and IntFlag?

One subtle thing I discovered about Flag vs. working with Enum sets: Flag instances have the mysterious ability to represent either a single item or a collection of items. For example, you can use the & operator in both cases. With set, you can only use & with another set, and single item must use the in operator.

belm0 avatar Sep 23 '19 11:09 belm0

Flag vs IntFlag: overcomplicated - it's enough to have an integer flag with the ability to auto-assign flag member values.

One subtle thing I discovered about Flag vs. working with Enum sets: Flag instances have the mysterious ability to represent either a single item or a collection of items.

All flag members (declared and synthesised) and all of their combinations are instances of the declared flag type (and the flag type behaves like a set). This is the most practical way I know to implement type safe flags.

Enums and flags are somewhat related but the correct relation isn't inheritance. I really like how the pascal language allows defining set/flag types from existing enum declarations and then it allows testing against the set instances using the enum members:

TSpeed = (spVerySlow,spSlow,spAVerage,spFast,spVeryFast);
TPossibleSpeeds = set of TSpeed

More on this: https://wiki.freepascal.org/Set

I was thinking about mimicking pascal sets in python but in most cases it would simply make it more difficult for people to understand how the library works. Implementing such a thing as a library versus having it integrated into the language like in case of pascal are two different things.

Even with PEP, I think many of the latest additions to python are overcomplicated. E.g.: asyncio, typing. What happened to the zen of python?

pasztorpisti avatar Sep 23 '19 13:09 pasztorpisti