[Python-ideas] IntFlags
Andrew Barnert
abarnert at yahoo.com
Mon Mar 9 13:29:21 CET 2015
On Mar 8, 2015, at 1:45 AM, Neil Girdhar <mistersheik at gmail.com> wrote:
>
>
>
>> On Sat, Mar 7, 2015 at 3:38 PM, Ethan Furman <ethan at stoneleaf.us> wrote:
>> On 03/07/2015 12:28 PM, Georg Brandl wrote:
>> > On 03/07/2015 04:05 PM, Ethan Furman wrote:
>> >
>> >>>> As long as we are dreaming :)
>> >>>>
>> >>>> class Stat(IntFlag):
>> >>>> RDONLY = 1
>> >>>> NOSUID = 2
>> >>>> NODEV = 4
>> >>>> NOEXEC = 8
>> >>>> SYNCHRONOUS = 16
>> >>>> MANDLOCK = 64
>> >>>> WRITE = 128
>> >>>> APPEND = 256
>> >>>> NOATIME = 1024
>> >>>> NODIRATIME = 2048
>> >>>> RELATIME = 4096
>> >>>>
>> >>>> a = Stat.RDONLY # creates a new instance of Stat, not a singleton
>> >>>
>> >>> Why?
>> >>
>> >> Because by having mutable instances of Stat we can have more Python operations:
>> >>
>> >> instead of:
>> >>
>> >> x = Stat(some_Stat_value_from_somewhere)
>> >> x = x | Stat.NOEXEC # to set the bit
>> >>
>> >> we can say:
>> >>
>> >> x = Stat(some_Stat_value_from_somewhere)
>> >> x.NOEXEC = True
>> >
>> > Please no. You're making a mutable type out of something that is conceptually
>> > (and in people's minds) an integer. Remember how long it can take to understand
>> > that
>> >
>> > a = 1
>> > a = 2
>> >
>> > does not change the integer "1" to now be "2".
>
> The fact that the flags are stored in an int — that is, the implementation has nothing at all to do with the conceptual nature of flags. Flags are properties. Your knowledge of the underlying implementation is misleading you. It would be just as easy and intuitive to implement those flags as keys and values in a dict.
Usually that's true. And when it's true, you use a dict (or a set or a namedtuple or whatever's appropriate), so you have no need for IntFlags in the first place. The only reason you'd ever want this class is when the fact that the flags are stored in an int is important.
Sure, an IntFlags that isn't a subclass on int can define an __int__ method. But so can some class that doesn't use an int for storage in the first place. If you want to convert back and forth, that's perfectly fine, but why are you using an int for storage?
> If flags were conceptually subtypes of int, then you should be able to do things like:
>
> flags ** 7
>
> or
>
> flags // 91
>
> Do you agree that this is totally meaningless? There is no "is a" relationship between Flags and int. There is a conversion between the conceptual mapping that is a Flags object to int for the sole purpose of calling into APIs.
>
>>
>> Good point. To do something like that the name would have be BitFlags or something no so solidly tied to "immutable".
>> At any rate, for this to work would require `int(x)` around every call to a lower-level API, and that's a non-starter.
>
> Correct me if I'm wrong, but doesn't Boost.Python when generating Python methods that accept ints, automatically call __int__ on the arguments. Doesn't SWIG do the same? Can you give me some examples of methods that accept ints but don't call __int__? It seems to me to be a bug in those methods than in the caller. A method that wants an int should call __int__ on its argument — not expect that isinstance(X, int) etc.
>
>>
>> --
>> ~Ethan~
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150309/37657e12/attachment.html>
More information about the Python-ideas
mailing list