Source code for flakeheaven._logic._discover

# built-in
import re
from collections import defaultdict
from typing import Any, Dict, Iterable, Iterator, List, Optional

# app
from ._plugin import get_plugin_name, get_plugin_rules


REX_CODE = re.compile(r'^[A-Z]{1,9}[0-9]{0,5}$')

ALIASES = {
    'flake-mutable': ('M511', ),
    'flake8-bandit': ('S', ),
    'flake8-django': ('DJ', ),  # they say `DJ0` prefix but codes have `DJ10`
    'flake8-future-import': ('FI', ),
    'flake8-mock': ('M001', ),
    'flake8-pytest': ('T003', ),
    'flake8-annotations-complexity': ('TAE002', 'TAE003'),
    'logging-format': ('G', ),
    'pycodestyle': ('W', 'E'),
    'pylint': ('C', 'E', 'F', 'I', 'R', 'W'),
}


[docs]class NoPlugins(Exception): """No plugins are installed and found."""
[docs]def get_installed( app, *, initialize: bool = True, initialize_args: Optional[List[str]] = None, ) -> Iterator[Dict[str, Any]]: plugins_codes = defaultdict(list) versions = dict() if initialize: app.initialize(initialize_args or []) codes: Iterable[str] for check_type in ('ast_plugins', 'logical_line_plugins', 'physical_line_plugins'): for plugin in getattr(app.check_plugins, check_type): key = (check_type, get_plugin_name(plugin.to_dictionary())) versions[key[-1]] = plugin.version # if codes for plugin specified explicitly in ALIASES, use it codes = ALIASES.get(plugin.plugin_name, []) if codes: plugins_codes[key] = list(codes) continue # otherwise get codes from plugin entrypoint code = plugin.name if not REX_CODE.match(code): raise ValueError('Invalid code format: {}'.format(code)) plugins_codes[key].append(code) if 'flake8-docstrings' in versions: versions['flake8-docstrings'] = versions['flake8-docstrings'].split(',')[0] for (check_type, name), codes in plugins_codes.items(): yield dict( type=check_type, name=name, codes=sorted(codes), version=versions[name], )
[docs]def get_missing( app, *, initialize: bool = True, initialize_args: Optional[List[str]] = None, ): installed_plugins = sorted( get_installed(app=app, initialize=initialize, initialize_args=initialize_args), key=lambda p: p['name'], ) if not installed_plugins: raise NoPlugins('No plugins installed') patterns = [] for pattern in app.options.plugins: for plugin in installed_plugins: rules = get_plugin_rules( plugin_name=plugin['name'], plugins={pattern: ['+*']}, ) if rules: break else: patterns.append(pattern) return patterns