decorators.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. """Helpful decorators that subcommands can use.
  2. """
  3. import functools
  4. from time import monotonic
  5. from milc import cli
  6. from qmk.keyboard import find_keyboard_from_dir
  7. from qmk.keymap import find_keymap_from_dir
  8. def automagic_keyboard(func):
  9. """Sets `cli.config.<subcommand>.keyboard` based on environment.
  10. This will rewrite cli.config.<subcommand>.keyboard if the user did not pass `--keyboard` and the directory they are currently in is a keyboard or keymap directory.
  11. """
  12. @functools.wraps(func)
  13. def wrapper(*args, **kwargs):
  14. # Ensure that `--keyboard` was not passed and CWD is under `qmk_firmware/keyboards`
  15. if cli.config_source[cli._subcommand.__name__]['keyboard'] != 'argument':
  16. keyboard = find_keyboard_from_dir()
  17. if keyboard:
  18. cli.config[cli._subcommand.__name__]['keyboard'] = keyboard
  19. cli.config_source[cli._subcommand.__name__]['keyboard'] = 'keyboard_directory'
  20. return func(*args, **kwargs)
  21. return wrapper
  22. def automagic_keymap(func):
  23. """Sets `cli.config.<subcommand>.keymap` based on environment.
  24. This will rewrite cli.config.<subcommand>.keymap if the user did not pass `--keymap` and the directory they are currently in is a keymap, layout, or user directory.
  25. """
  26. @functools.wraps(func)
  27. def wrapper(*args, **kwargs):
  28. # Ensure that `--keymap` was not passed and that we're under `qmk_firmware`
  29. if cli.config_source[cli._subcommand.__name__]['keymap'] != 'argument':
  30. keymap_name, keymap_type = find_keymap_from_dir()
  31. if keymap_name:
  32. cli.config[cli._subcommand.__name__]['keymap'] = keymap_name
  33. cli.config_source[cli._subcommand.__name__]['keymap'] = keymap_type
  34. return func(*args, **kwargs)
  35. return wrapper
  36. def lru_cache(timeout=10, maxsize=128, typed=False):
  37. """Least Recently Used Cache- cache the result of a function.
  38. Args:
  39. timeout
  40. How many seconds to cache results for.
  41. maxsize
  42. The maximum size of the cache in bytes
  43. typed
  44. When `True` argument types will be taken into consideration, for example `3` and `3.0` will be treated as different keys.
  45. """
  46. def wrapper_cache(func):
  47. func = functools.lru_cache(maxsize=maxsize, typed=typed)(func)
  48. func.expiration = monotonic() + timeout
  49. @functools.wraps(func)
  50. def wrapped_func(*args, **kwargs):
  51. if monotonic() >= func.expiration:
  52. func.expiration = monotonic() + timeout
  53. func.cache_clear()
  54. return func(*args, **kwargs)
  55. wrapped_func.cache_info = func.cache_info
  56. wrapped_func.cache_clear = func.cache_clear
  57. return wrapped_func
  58. return wrapper_cache