Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-39102: Increase Enum performance up to 10x times (3x average) #17669

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
cad12cc
Added class attributes access trough DynamicClassProperty (first atte…
Bobronium Aug 9, 2019
d6a48c3
Added class attributes access trough DynamicClassProperty (first atte…
Bobronium Aug 9, 2019
923902e
Replaced dynamic attributes Enum.name and .value to instance attrs
Bobronium Dec 20, 2019
8f2f90c
Improve values check speed (e.g. Color(3))
Bobronium Dec 20, 2019
ed43320
Replace tuples with sets for faster lookups
Bobronium Dec 20, 2019
2c0372a
Used cls variable instead if multiple self.__class__
Bobronium Dec 20, 2019
cdc7041
Merge remote-tracking branch 'origin/fast-enum' into fast-enum
Bobronium Dec 20, 2019
48d75d0
Fix whitespace in types
Bobronium Dec 20, 2019
ce84f10
📜🤖 Added by blurb_it.
blurb-it[bot] Dec 20, 2019
0d1996f
Rename DynamicClassAttribute.__init__(name -> alias), add tests
Bobronium Dec 21, 2019
2f6b977
DynamicClassAttribute.class_attr_name -> alias
Bobronium Dec 21, 2019
1cedc4c
Use _unique_member_map_ instead of _member_names_ to store unique enu…
Bobronium Dec 21, 2019
8304b6f
Use members dict instead of _member_names and _last_values on _EnumDict
Bobronium Dec 21, 2019
4051208
Restore original formatting
Bobronium Dec 21, 2019
a90a4aa
Fix whitespaces
Bobronium Dec 21, 2019
4436cbf
Use dict instead of list to check values in _create_pseudo_member_
Bobronium Dec 21, 2019
45be0c6
Deprecate getting values through _value_ and _name_
Bobronium Dec 22, 2019
eabb7e3
Add 'name' and 'value' to Enum.__dir__
Bobronium Dec 22, 2019
fab4c97
Remove '_member_names' and return 'list(cls._unique_member_map_)' ins…
Bobronium Dec 23, 2019
54e1eff
Use builtin dict() instead of _EnumDict for class creation
Bobronium Dec 23, 2019
378dc88
Use f-strings instead of %s formatting
Bobronium Dec 23, 2019
ecd41fe
Fix missing '>' in repr, add test for that
Bobronium Dec 24, 2019
948d3de
Add cache for repr, str and invert on Flag and IntFlag
Bobronium Dec 24, 2019
a668e2a
Remove redundant name and value setattr
Bobronium Dec 24, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
400 changes: 239 additions & 161 deletions Lib/enum.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -2420,7 +2420,7 @@ class _ParameterKind(enum.IntEnum):
VAR_KEYWORD = 4

def __str__(self):
return self._name_
return self.name

@property
def description(self):
Expand Down
12 changes: 6 additions & 6 deletions Lib/re.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,17 +153,17 @@ class RegexFlag(enum.IntFlag):
DEBUG = sre_compile.SRE_FLAG_DEBUG # dump pattern after compilation

def __repr__(self):
if self._name_ is not None:
return f're.{self._name_}'
value = self._value_
if self.name is not None:
return f're.{self.name}'
value = self.value
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use _repr_ cache here

members = []
negative = value < 0
if negative:
value = ~value
for m in self.__class__:
if value & m._value_:
value &= ~m._value_
members.append(f're.{m._name_}')
if value & m.value:
value &= ~m.value
members.append(f're.{m.name}')
if value:
members.append(hex(value))
res = '|'.join(members)
Expand Down
30 changes: 30 additions & 0 deletions Lib/test/test_dynamicclassattribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,36 @@ def spam(self):
self.assertEqual(Foo.__dict__['spam'].__doc__, "a new docstring")


class TestSetClassAttr(unittest.TestCase):
def test_set_class_attr(self):
class Foo:
def __init__(self, value):
self._value = value
self._spam = 'spam'

@DynamicClassAttribute
def value(self):
return self._value

spam = DynamicClassAttribute(
lambda s: s._spam,
alias='my_shiny_spam'
)

self.assertFalse(hasattr(Foo, 'value'))
self.assertFalse(hasattr(Foo, 'name'))

foo_bar = Foo('bar')
value_desc = Foo.__dict__['value']
value_desc.set_class_attr(Foo, foo_bar)
self.assertIs(Foo.value, foo_bar)
self.assertEqual(Foo.value.value, 'bar')

foo_baz = Foo('baz')
Foo.my_shiny_spam = foo_baz
self.assertIs(Foo.spam, foo_baz)
self.assertEqual(Foo.spam.spam, 'spam')


if __name__ == '__main__':
unittest.main()
Loading