From dcbfdb5cfcd22653bb9aa146d6c64e92f2554bb6 Mon Sep 17 00:00:00 2001 From: Zach White Date: Sun, 27 Jun 2021 14:38:52 -0700 Subject: [PATCH] lru_cache everywhere --- lib/python/qmk/c_parse.py | 9 ++++++++- lib/python/qmk/commands.py | 3 +++ lib/python/qmk/comment_remover.py | 2 ++ lib/python/qmk/converter.py | 2 ++ lib/python/qmk/json_schema.py | 1 + lib/python/qmk/keyboard.py | 6 ++++-- lib/python/qmk/keymap.py | 13 +++++++++++-- lib/python/qmk/makefile.py | 2 ++ lib/python/qmk/math.py | 15 +++++++++++++-- lib/python/qmk/path.py | 6 ++++++ lib/python/qmk/submodules.py | 2 ++ 11 files changed, 54 insertions(+), 7 deletions(-) diff --git a/lib/python/qmk/c_parse.py b/lib/python/qmk/c_parse.py index 991373d569..d6582ac670 100644 --- a/lib/python/qmk/c_parse.py +++ b/lib/python/qmk/c_parse.py @@ -1,7 +1,8 @@ """Functions for working with config.h files. """ -from pathlib import Path import re +from functools import lru_cache +from pathlib import Path from milc import cli @@ -12,18 +13,21 @@ single_comment_regex = re.compile(r'\s+/[/*].*$') multi_comment_regex = re.compile(r'/\*(.|\n)*?\*/', re.MULTILINE) +@lru_cache(maxsize=0) def strip_line_comment(string): """Removes comments from a single line string. """ return single_comment_regex.sub('', string) +@lru_cache(maxsize=0) def strip_multiline_comment(string): """Removes comments from a single line string. """ return multi_comment_regex.sub('', string) +@lru_cache(maxsize=0) def c_source_files(dir_names): """Returns a list of all *.c, *.h, and *.cpp files for a given list of directories @@ -38,6 +42,7 @@ def c_source_files(dir_names): return files +@lru_cache(maxsize=0) def find_layouts(file): """Returns list of parsed LAYOUT preprocessor macros found in the supplied include file. """ @@ -144,6 +149,7 @@ def _default_key(label=None): return new_key +@lru_cache(maxsize=0) def _parse_layout_macro(layout_macro): """Split the LAYOUT macro into its constituent parts """ @@ -154,6 +160,7 @@ def _parse_layout_macro(layout_macro): return macro_name, layout, matrix +@lru_cache(maxsize=0) def _parse_matrix_locations(matrix, file, macro_name): """Parse raw matrix data into a dictionary keyed by the LAYOUT identifier. """ diff --git a/lib/python/qmk/commands.py b/lib/python/qmk/commands.py index bff4c2437e..7a067a7da6 100644 --- a/lib/python/qmk/commands.py +++ b/lib/python/qmk/commands.py @@ -22,6 +22,7 @@ from qmk.keyboard import list_keyboards time_fmt = '%Y-%m-%d-%H:%M:%S' +@lru_cache(maxsize=0) def _find_make(): """Returns the correct make command for this environment. """ @@ -106,6 +107,7 @@ def create_make_command(keyboard, keymap, target=None, parallel=1, silent=False, return make_cmd +@lru_cache(maxsize=0) def get_git_version(current_time, repo_dir='.', check_dir='.'): """Returns the current git version for a repo, or the current time. """ @@ -258,6 +260,7 @@ def compile_configurator_json(user_keymap, bootloader=None, parallel=1, **env_va return user_keymap['keyboard'], user_keymap['keymap'], make_command +@lru_cache(maxsize=0) def parse_configurator_json(configurator_file): """Open and parse a configurator json export """ diff --git a/lib/python/qmk/comment_remover.py b/lib/python/qmk/comment_remover.py index 45a25257f8..e2edfcc667 100644 --- a/lib/python/qmk/comment_remover.py +++ b/lib/python/qmk/comment_remover.py @@ -3,6 +3,7 @@ Gratefully adapted from https://stackoverflow.com/a/241506 """ import re +from functools import lru_cache comment_pattern = re.compile(r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', re.DOTALL | re.MULTILINE) @@ -14,6 +15,7 @@ def _comment_stripper(match): return ' ' if s.startswith('/') else s +@lru_cache(maxsize=0) def comment_remover(text): """Remove C/C++ style comments from text. """ diff --git a/lib/python/qmk/converter.py b/lib/python/qmk/converter.py index bbd3531317..0dfbdf068b 100644 --- a/lib/python/qmk/converter.py +++ b/lib/python/qmk/converter.py @@ -1,8 +1,10 @@ """Functions to convert to and from QMK formats """ from collections import OrderedDict +from functools import lru_cache +@lru_cache(maxsize=0) def kle2qmk(kle): """Convert a KLE layout to QMK's layout format. """ diff --git a/lib/python/qmk/json_schema.py b/lib/python/qmk/json_schema.py index ffc7c6bcd1..3db679cd28 100644 --- a/lib/python/qmk/json_schema.py +++ b/lib/python/qmk/json_schema.py @@ -10,6 +10,7 @@ import jsonschema from milc import cli +@lru_cache(maxsize=0) def json_load(json_file): """Load a json file from disk. diff --git a/lib/python/qmk/keyboard.py b/lib/python/qmk/keyboard.py index 77fd9b92d5..d5598013c0 100644 --- a/lib/python/qmk/keyboard.py +++ b/lib/python/qmk/keyboard.py @@ -1,10 +1,11 @@ """Functions that help us work with keyboards. """ +import os from array import array +from functools import lru_cache +from glob import glob from math import ceil from pathlib import Path -import os -from glob import glob import qmk.path from qmk.c_parse import parse_config_h_file @@ -217,6 +218,7 @@ def render_layout(layout_data, render_ascii, key_labels=None): return '\n'.join(lines) +@lru_cache(maxsize=0) def render_layouts(info_json, render_ascii): """Renders all the layouts from an `info_json` structure. """ diff --git a/lib/python/qmk/keymap.py b/lib/python/qmk/keymap.py index ea3eb94fae..b6a94536b6 100644 --- a/lib/python/qmk/keymap.py +++ b/lib/python/qmk/keymap.py @@ -1,8 +1,8 @@ """Functions that help you work with QMK keymaps. """ -from functools import lru_cache import json import sys +from functools import lru_cache from pathlib import Path from subprocess import DEVNULL @@ -32,6 +32,7 @@ __KEYMAP_GOES_HERE__ """ +@lru_cache(maxsize=0) def template_json(keyboard): """Returns a `keymap.json` template for a keyboard. @@ -49,6 +50,7 @@ def template_json(keyboard): return template +@lru_cache(maxsize=0) def template_c(keyboard): """Returns a `keymap.c` template for a keyboard. @@ -124,6 +126,7 @@ def keymap_completer(prefix, action, parser, parsed_args): return [] +@lru_cache(maxsize=0) def is_keymap_dir(keymap, c=True, json=True, additional_files=None): """Return True if Path object `keymap` has a keymap file inside. @@ -182,6 +185,7 @@ def generate_json(keymap, keyboard, layout, layers): return new_keymap +@lru_cache(maxsize=0) def generate_c(keyboard, layout, layers): """Returns a `keymap.c` or `keymap.json` for the specified keyboard, layout, and layers. @@ -268,6 +272,7 @@ def write(keyboard, keymap, layout, layers): return write_file(keymap_file, keymap_content) +@lru_cache(maxsize=0) def locate_keymap(keyboard, keymap): """Returns the path to a keymap for a specific keyboard. """ @@ -307,7 +312,7 @@ def locate_keymap(keyboard, keymap): return community_layout / 'keymap.c' -@lru_cache() +@lru_cache(maxsize=0) def list_keymaps(keyboard, c=True, json=True, additional_files=None, fullpath=False): """List the available keymaps for a keyboard. @@ -361,6 +366,7 @@ def list_keymaps(keyboard, c=True, json=True, additional_files=None, fullpath=Fa return sorted(names) +@lru_cache(maxsize=0) def _c_preprocess(path, stdin=DEVNULL): """ Run a file through the C pre-processor @@ -380,6 +386,7 @@ def _c_preprocess(path, stdin=DEVNULL): return pre_processed_keymap.stdout +@lru_cache(maxsize=0) def _get_layers(keymap): # noqa C901 : until someone has a good idea how to simplify/split up this code """ Find the layers in a keymap.c file. @@ -500,6 +507,7 @@ def _get_layers(keymap): # noqa C901 : until someone has a good idea how to sim return layers +@lru_cache(maxsize=0) def parse_keymap_c(keymap_file, use_cpp=True): """ Parse a keymap.c file. @@ -529,6 +537,7 @@ def parse_keymap_c(keymap_file, use_cpp=True): return keymap +@lru_cache(maxsize=0) def c2json(keyboard, keymap, keymap_file, use_cpp=True): """ Convert keymap.c to keymap.json diff --git a/lib/python/qmk/makefile.py b/lib/python/qmk/makefile.py index 02c2e70050..e2c0514667 100644 --- a/lib/python/qmk/makefile.py +++ b/lib/python/qmk/makefile.py @@ -1,8 +1,10 @@ """ Functions for working with Makefiles """ +from functools import lru_cache from pathlib import Path +@lru_cache(maxsize=0) def parse_rules_mk_file(file, rules_mk=None): """Turn a rules.mk file into a dictionary. diff --git a/lib/python/qmk/math.py b/lib/python/qmk/math.py index 88dc4a300c..ec967f0807 100644 --- a/lib/python/qmk/math.py +++ b/lib/python/qmk/math.py @@ -3,12 +3,22 @@ Gratefully copied from https://stackoverflow.com/a/9558001 """ import ast -import operator as op +import operator +from functools import lru_cache # supported operators -operators = {ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul, ast.Div: op.truediv, ast.Pow: op.pow, ast.BitXor: op.xor, ast.USub: op.neg} +operators = { + ast.Add: operator.add, + ast.Sub: operator.sub, + ast.Mult: operator.mul, + ast.Div: operator.truediv, + ast.Pow: operator.pow, + ast.BitXor: operator.xor, + ast.USub: operator.neg, +} +@lru_cache(maxsize=0) def compute(expr): """Parse a mathematical expression and return the answer. @@ -22,6 +32,7 @@ def compute(expr): return _eval(ast.parse(expr, mode='eval').body) +@lru_cache(maxsize=0) def _eval(node): if isinstance(node, ast.Num): # return node.n diff --git a/lib/python/qmk/path.py b/lib/python/qmk/path.py index 72bae59273..4425810867 100644 --- a/lib/python/qmk/path.py +++ b/lib/python/qmk/path.py @@ -3,12 +3,14 @@ import logging import os import argparse +from functools import lru_cache from pathlib import Path from qmk.constants import MAX_KEYBOARD_SUBFOLDERS, QMK_FIRMWARE from qmk.errors import NoSuchKeyboardError +@lru_cache(maxsize=0) def is_keyboard(keyboard_name): """Returns True if `keyboard_name` is a keyboard we can compile. """ @@ -19,6 +21,7 @@ def is_keyboard(keyboard_name): return rules_mk.exists() +@lru_cache(maxsize=0) def under_qmk_firmware(): """Returns a Path object representing the relative path under qmk_firmware, or None. """ @@ -30,12 +33,14 @@ def under_qmk_firmware(): return None +@lru_cache(maxsize=0) def keyboard(keyboard_name): """Returns the path to a keyboard's directory relative to the qmk root. """ return Path('keyboards') / keyboard_name +@lru_cache(maxsize=0) def keymap(keyboard_name): """Locate the correct directory for storing a keymap. @@ -56,6 +61,7 @@ def keymap(keyboard_name): raise NoSuchKeyboardError('Could not find keymaps directory for: %s' % keyboard_name) +@lru_cache(maxsize=0) def normpath(path): """Returns a `pathlib.Path()` object for a given path. diff --git a/lib/python/qmk/submodules.py b/lib/python/qmk/submodules.py index 6a272dae50..09acd68161 100644 --- a/lib/python/qmk/submodules.py +++ b/lib/python/qmk/submodules.py @@ -1,8 +1,10 @@ """Functions for working with QMK's submodules. """ +from functools import lru_cache from milc import cli +@lru_cache(maxsize=0) def status(): """Returns a dictionary of submodules.