Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

registry.py 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. from itertools import chain
  2. from django.utils.itercompat import is_iterable
  3. class Tags:
  4. """
  5. Built-in tags for internal checks.
  6. """
  7. admin = 'admin'
  8. caches = 'caches'
  9. compatibility = 'compatibility'
  10. database = 'database'
  11. models = 'models'
  12. security = 'security'
  13. signals = 'signals'
  14. templates = 'templates'
  15. urls = 'urls'
  16. class CheckRegistry:
  17. def __init__(self):
  18. self.registered_checks = set()
  19. self.deployment_checks = set()
  20. def register(self, check=None, *tags, **kwargs):
  21. """
  22. Can be used as a function or a decorator. Register given function
  23. `f` labeled with given `tags`. The function should receive **kwargs
  24. and return list of Errors and Warnings.
  25. Example::
  26. registry = CheckRegistry()
  27. @registry.register('mytag', 'anothertag')
  28. def my_check(apps, **kwargs):
  29. # ... perform checks and collect `errors` ...
  30. return errors
  31. # or
  32. registry.register(my_check, 'mytag', 'anothertag')
  33. """
  34. def inner(check):
  35. check.tags = tags
  36. checks = self.deployment_checks if kwargs.get('deploy') else self.registered_checks
  37. checks.add(check)
  38. return check
  39. if callable(check):
  40. return inner(check)
  41. else:
  42. if check:
  43. tags += (check,)
  44. return inner
  45. def run_checks(self, app_configs=None, tags=None, include_deployment_checks=False):
  46. """
  47. Run all registered checks and return list of Errors and Warnings.
  48. """
  49. errors = []
  50. checks = self.get_checks(include_deployment_checks)
  51. if tags is not None:
  52. checks = [check for check in checks if not set(check.tags).isdisjoint(tags)]
  53. else:
  54. # By default, 'database'-tagged checks are not run as they do more
  55. # than mere static code analysis.
  56. checks = [check for check in checks if Tags.database not in check.tags]
  57. for check in checks:
  58. new_errors = check(app_configs=app_configs)
  59. assert is_iterable(new_errors), (
  60. "The function %r did not return a list. All functions registered "
  61. "with the checks registry must return a list." % check)
  62. errors.extend(new_errors)
  63. return errors
  64. def tag_exists(self, tag, include_deployment_checks=False):
  65. return tag in self.tags_available(include_deployment_checks)
  66. def tags_available(self, deployment_checks=False):
  67. return set(chain.from_iterable(
  68. check.tags for check in self.get_checks(deployment_checks)
  69. ))
  70. def get_checks(self, include_deployment_checks=False):
  71. checks = list(self.registered_checks)
  72. if include_deployment_checks:
  73. checks.extend(self.deployment_checks)
  74. return checks
  75. registry = CheckRegistry()
  76. register = registry.register
  77. run_checks = registry.run_checks
  78. tag_exists = registry.tag_exists