Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit95b7426

Browse files
authored
gh-105497: [Enum] Fix flag mask inversion when unnamed flags exist (#106468)
For example: class Flag(enum.Flag): A = 0x01 B = 0x02 MASK = 0xff ~Flag.MASK is Flag(0)
1 parentaf5cf1e commit95b7426

File tree

3 files changed

+86
-61
lines changed

3 files changed

+86
-61
lines changed

‎Lib/enum.py‎

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,14 +1515,10 @@ def __xor__(self, other):
15151515

15161516
def__invert__(self):
15171517
ifself._inverted_isNone:
1518-
ifself._boundary_isKEEP:
1519-
# use all bits
1518+
ifself._boundary_in (EJECT,KEEP):
15201519
self._inverted_=self.__class__(~self._value_)
15211520
else:
1522-
# use canonical bits (i.e. calculate flags not in this member)
1523-
self._inverted_=self.__class__(self._singles_mask_^self._value_)
1524-
ifisinstance(self._inverted_,self.__class__):
1525-
self._inverted_._inverted_=self
1521+
self._inverted_=self.__class__(self._singles_mask_&~self._value_)
15261522
returnself._inverted_
15271523

15281524
__rand__=__and__

‎Lib/test/test_enum.py‎

Lines changed: 83 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,89 @@ def test_default_missing_with_wrong_type_value(self):
818818
self.MainEnum('RED')
819819
self.assertIs(ctx.exception.__context__,None)
820820

821+
deftest_closed_invert_expectations(self):
822+
classClosedAB(self.enum_type):
823+
A=1
824+
B=2
825+
MASK=3
826+
A,B=ClosedAB
827+
AB_MASK=ClosedAB.MASK
828+
#
829+
self.assertIs(~A,B)
830+
self.assertIs(~B,A)
831+
self.assertIs(~(A|B),ClosedAB(0))
832+
self.assertIs(~AB_MASK,ClosedAB(0))
833+
self.assertIs(~ClosedAB(0), (A|B))
834+
#
835+
classClosedXYZ(self.enum_type):
836+
X=4
837+
Y=2
838+
Z=1
839+
MASK=7
840+
X,Y,Z=ClosedXYZ
841+
XYZ_MASK=ClosedXYZ.MASK
842+
#
843+
self.assertIs(~X,Y|Z)
844+
self.assertIs(~Y,X|Z)
845+
self.assertIs(~Z,X|Y)
846+
self.assertIs(~(X|Y),Z)
847+
self.assertIs(~(X|Z),Y)
848+
self.assertIs(~(Y|Z),X)
849+
self.assertIs(~(X|Y|Z),ClosedXYZ(0))
850+
self.assertIs(~XYZ_MASK,ClosedXYZ(0))
851+
self.assertIs(~ClosedXYZ(0), (X|Y|Z))
852+
853+
deftest_open_invert_expectations(self):
854+
classOpenAB(self.enum_type):
855+
A=1
856+
B=2
857+
MASK=255
858+
A,B=OpenAB
859+
AB_MASK=OpenAB.MASK
860+
#
861+
ifOpenAB._boundary_in (EJECT,KEEP):
862+
self.assertIs(~A,OpenAB(254))
863+
self.assertIs(~B,OpenAB(253))
864+
self.assertIs(~(A|B),OpenAB(252))
865+
self.assertIs(~AB_MASK,OpenAB(0))
866+
self.assertIs(~OpenAB(0),AB_MASK)
867+
else:
868+
self.assertIs(~A,B)
869+
self.assertIs(~B,A)
870+
self.assertIs(~(A|B),OpenAB(0))
871+
self.assertIs(~AB_MASK,OpenAB(0))
872+
self.assertIs(~OpenAB(0), (A|B))
873+
#
874+
classOpenXYZ(self.enum_type):
875+
X=4
876+
Y=2
877+
Z=1
878+
MASK=31
879+
X,Y,Z=OpenXYZ
880+
XYZ_MASK=OpenXYZ.MASK
881+
#
882+
ifOpenXYZ._boundary_in (EJECT,KEEP):
883+
self.assertIs(~X,OpenXYZ(27))
884+
self.assertIs(~Y,OpenXYZ(29))
885+
self.assertIs(~Z,OpenXYZ(30))
886+
self.assertIs(~(X|Y),OpenXYZ(25))
887+
self.assertIs(~(X|Z),OpenXYZ(26))
888+
self.assertIs(~(Y|Z),OpenXYZ(28))
889+
self.assertIs(~(X|Y|Z),OpenXYZ(24))
890+
self.assertIs(~XYZ_MASK,OpenXYZ(0))
891+
self.assertTrue(~OpenXYZ(0),XYZ_MASK)
892+
else:
893+
self.assertIs(~X,Y|Z)
894+
self.assertIs(~Y,X|Z)
895+
self.assertIs(~Z,X|Y)
896+
self.assertIs(~(X|Y),Z)
897+
self.assertIs(~(X|Z),Y)
898+
self.assertIs(~(Y|Z),X)
899+
self.assertIs(~(X|Y|Z),OpenXYZ(0))
900+
self.assertIs(~XYZ_MASK,OpenXYZ(0))
901+
self.assertTrue(~OpenXYZ(0), (X|Y|Z))
902+
903+
821904
classTestPlainEnum(_EnumTests,_PlainOutputTests,unittest.TestCase):
822905
enum_type=Enum
823906

@@ -3045,33 +3128,6 @@ class Color(Flag):
30453128
WHITE=RED|GREEN|BLUE
30463129
BLANCO=RED|GREEN|BLUE
30473130

3048-
classComplete(Flag):
3049-
A=0x01
3050-
B=0x02
3051-
3052-
classPartial(Flag):
3053-
A=0x01
3054-
B=0x02
3055-
MASK=0xff
3056-
3057-
classCompleteInt(IntFlag):
3058-
A=0x01
3059-
B=0x02
3060-
3061-
classPartialInt(IntFlag):
3062-
A=0x01
3063-
B=0x02
3064-
MASK=0xff
3065-
3066-
classCompleteIntStrict(IntFlag,boundary=STRICT):
3067-
A=0x01
3068-
B=0x02
3069-
3070-
classPartialIntStrict(IntFlag,boundary=STRICT):
3071-
A=0x01
3072-
B=0x02
3073-
MASK=0xff
3074-
30753131
deftest_or(self):
30763132
Perm=self.Perm
30773133
foriinPerm:
@@ -3115,34 +3171,6 @@ def test_xor(self):
31153171
self.assertIs(Open.RO^Open.CE,Open.CE)
31163172
self.assertIs(Open.CE^Open.CE,Open.RO)
31173173

3118-
deftest_invert(self):
3119-
Perm=self.Perm
3120-
RW=Perm.R|Perm.W
3121-
RX=Perm.R|Perm.X
3122-
WX=Perm.W|Perm.X
3123-
RWX=Perm.R|Perm.W|Perm.X
3124-
values=list(Perm)+ [RW,RX,WX,RWX,Perm(0)]
3125-
foriinvalues:
3126-
self.assertIs(type(~i),Perm)
3127-
self.assertEqual(~~i,i)
3128-
foriinPerm:
3129-
self.assertIs(~~i,i)
3130-
Open=self.Open
3131-
self.assertIs(Open.WO&~Open.WO,Open.RO)
3132-
self.assertIs((Open.WO|Open.CE)&~Open.WO,Open.CE)
3133-
Complete=self.Complete
3134-
self.assertIs(~Complete.A,Complete.B)
3135-
Partial=self.Partial
3136-
self.assertIs(~Partial.A,Partial.B)
3137-
CompleteInt=self.CompleteInt
3138-
self.assertIs(~CompleteInt.A,CompleteInt.B)
3139-
PartialInt=self.PartialInt
3140-
self.assertIs(~PartialInt.A,PartialInt(254))
3141-
CompleteIntStrict=self.CompleteIntStrict
3142-
self.assertIs(~CompleteIntStrict.A,CompleteIntStrict.B)
3143-
PartialIntStrict=self.PartialIntStrict
3144-
self.assertIs(~PartialIntStrict.A,PartialIntStrict.B)
3145-
31463174
deftest_bool(self):
31473175
Perm=self.Perm
31483176
forfinPerm:
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix flag mask inversion when unnamed flags exist.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp