def from_string(cls, key_sequence_string): modifiers_key_state = ModifiersKeyState() func_pattern_match = cls.FUNC_PATTERN.match(key_sequence_string) if func_pattern_match: return cls(Function(func_pattern_match.group(cls.FUNC_NAME_STRING), func_pattern_match.group(cls.ARGS_STRING))) pattern_match = cls.SURROUNDED_PATTERN.match(key_sequence_string) if pattern_match: key_string = pattern_match.group(cls.KEY_STRING) if pattern_match.group(cls.WINDOWS_STRING): modifiers_key_state.windows = True if pattern_match.group(cls.ALT_STRING): modifiers_key_state.alt = True if pattern_match.group(cls.CONTROL_STRING): modifiers_key_state.control = True if pattern_match.group(cls.SHIFT_STRING): modifiers_key_state.shift = True else: key_string = key_sequence_string for key_class in cls.KEY_CLASSES: key, shift = key_class.from_string(key_string, modifiers_key_state.shift) if key is not None: modifiers_key_state.shift = shift return cls(key, modifiers_key_state.presses()) else: return cls(NoneKey.NONE, modifiers_key_state.presses())