fix pystack exhaustion caused by make_shifted_key.

This removes multiple layers of indirection, effectively making
`make_shifted_key` only as heavy on the stack as the reguler `make_key`.
This commit is contained in:
xs5871 2022-03-31 11:29:30 +00:00 committed by Kyle Brown
parent cc70c8f4a8
commit e5f89963cf

View File

@ -51,9 +51,9 @@ def maybe_make_key(candidate, code, names):
return make_key(code=code, names=names) return make_key(code=code, names=names)
def maybe_make_shifted_key(candidate, target_name, names): def maybe_make_shifted_key(candidate, code, names):
if candidate in names: if candidate in names:
return make_shifted_key(target_name=target_name, names=names) return make_shifted_key(code=code, names=names)
def maybe_make_consumer_key(candidate, code, names): def maybe_make_consumer_key(candidate, code, names):
@ -285,27 +285,27 @@ class KeyAttrDict(AttrDict):
lambda key: left_pipe_until_some( lambda key: left_pipe_until_some(
key, key,
maybe_make_shifted_key, maybe_make_shifted_key,
('GRAVE', ('TILDE', 'TILD', '~')), (30, ('EXCLAIM', 'EXLM', '!')),
('1', ('EXCLAIM', 'EXLM', '!')), (31, ('AT', '@')),
('2', ('AT', '@')), (32, ('HASH', 'POUND', '#')),
('3', ('HASH', 'POUND', '#')), (33, ('DOLLAR', 'DLR', '$')),
('4', ('DOLLAR', 'DLR', '$')), (34, ('PERCENT', 'PERC', '%')),
('5', ('PERCENT', 'PERC', '%')), (35, ('CIRCUMFLEX', 'CIRC', '^')),
('6', ('CIRCUMFLEX', 'CIRC', '^')), (36, ('AMPERSAND', 'AMPR', '&')),
('7', ('AMPERSAND', 'AMPR', '&')), (37, ('ASTERISK', 'ASTR', '*')),
('8', ('ASTERISK', 'ASTR', '*')), (38, ('LEFT_PAREN', 'LPRN', '(')),
('9', ('LEFT_PAREN', 'LPRN', '(')), (39, ('RIGHT_PAREN', 'RPRN', ')')),
('0', ('RIGHT_PAREN', 'RPRN', ')')), (45, ('UNDERSCORE', 'UNDS', '_')),
('MINUS', ('UNDERSCORE', 'UNDS', '_')), (46, ('PLUS', '+')),
('EQUAL', ('PLUS', '+')), (47, ('LEFT_CURLY_BRACE', 'LCBR', '{')),
('LBRACKET', ('LEFT_CURLY_BRACE', 'LCBR', '{')), (48, ('RIGHT_CURLY_BRACE', 'RCBR', '}')),
('RBRACKET', ('RIGHT_CURLY_BRACE', 'RCBR', '}')), (49, ('PIPE', '|')),
('BACKSLASH', ('PIPE', '|')), (51, ('COLON', 'COLN', ':')),
('SEMICOLON', ('COLON', 'COLN', ':')), (52, ('DOUBLE_QUOTE', 'DQUO', 'DQT', '"')),
('QUOTE', ('DOUBLE_QUOTE', 'DQUO', 'DQT', '"')), (53, ('TILDE', 'TILD', '~')),
('COMMA', ('LEFT_ANGLE_BRACKET', 'LABK', '<')), (54, ('LEFT_ANGLE_BRACKET', 'LABK', '<')),
('DOT', ('RIGHT_ANGLE_BRACKET', 'RABK', '>')), (55, ('RIGHT_ANGLE_BRACKET', 'RABK', '>')),
('SLSH', ('QUESTION', 'QUES', '?')), (56, ('QUESTION', 'QUES', '?')),
), ),
# International # International
lambda key: left_pipe_until_some( lambda key: left_pipe_until_some(
@ -672,19 +672,8 @@ def make_mod_key(code, names, *args, **kwargs):
return make_key(code, names, *args, **kwargs, type=KEY_MODIFIER) return make_key(code, names, *args, **kwargs, type=KEY_MODIFIER)
def make_shifted_key(target_name, names=tuple()): # NOQA def make_shifted_key(code, names):
# For... probably a few years, a bug existed here where keys were looked return make_key(code, names, has_modifiers={KC.LSFT.code})
# up by `KC[...]`, but that's incorrect: an AttrDit exposes a dictionary
# with attributes, but key-based dictionary access with brackets does
# *not* implicitly call __getattr__. We got away with this when key defs
# were not lazily created, but now that they are, shifted keys would
# sometimes break, complaining that they couldn't find their underlying
# key to shift. Fixed!
key = KC.LSFT(getattr(KC, target_name))
register_key_names(key, names)
return key
def make_consumer_key(*args, **kwargs): def make_consumer_key(*args, **kwargs):