Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def rebuild_dynamic_schema(self, data: JsonDict = None) -> None:
"""Rebuild the dynamic Marshmallow schema when needed, adding new fields that were found on the style."""
new_files_found = OrderedDict() # type: Dict[str, fields.Field]
if data is None:
# Data is empty; so this is the first time the dynamic class is being rebuilt.
# Loop on classes with predetermined names, and add fields for them on the dynamic validation schema.
# E.g.: setup.cfg, pre-commit, pyproject.toml: files whose names we already know at this point.
for subclass in NitpickPlugin.fixed_name_classes:
new_files_found.update(self.file_field_pair(subclass.file_name, subclass))
else:
handled_tags = {} # type: Dict[str, Type[NitpickPlugin]]
# Data was provided; search it to find new dynamic files to add to the validation schema).
# E.g.: JSON files that were configured on some TOML style file.
for subclass in NitpickPlugin.dynamic_name_classes:
for tag in subclass.identify_tags:
# A tag can only be handled by a single subclass.
# If more than one class handle a tag, the latest one will be the handler.
handled_tags[tag] = subclass
jmex = subclass.get_compiled_jmespath_file_names()
for configured_file_name in search_dict(jmex, data, []):
new_files_found.update(self.file_field_pair(configured_file_name, subclass))
"""Checker for the `setup.cfg ` config file."""
from configparser import ConfigParser
from io import StringIO
from typing import Any, Dict, List, Optional, Set, Tuple, Type
import dictdiffer
from nitpick.plugins import hookimpl
from nitpick.plugins.base import NitpickPlugin
from nitpick.typedefs import JsonDict, YieldFlake8Error
class SetupCfgPlugin(NitpickPlugin):
"""Checker for the `setup.cfg `_ config file.
Example: :ref:`flake8 configuration `.
"""
file_name = "setup.cfg"
error_base_number = 320
COMMA_SEPARATED_VALUES = "comma_separated_values"
expected_sections = set() # type: Set[str]
missing_sections = set() # type: Set[str]
def __init__(self, config: JsonDict, file_name: str = None) -> None:
super().__init__(config, file_name)
self.comma_separated_values = set(self.nitpick_file_dict.get(self.COMMA_SEPARATED_VALUES, [])) # type: Set[str]
"""Get all hooks from a YAML string. Split the string in hooks and copy the repo info for each."""
yaml = YAMLFormat(string=str_or_yaml).as_list if isinstance(str_or_yaml, str) else str_or_yaml
hooks = []
for repo in yaml:
for index, hook in enumerate(repo.get(KEY_HOOKS, [])):
repo_data_only = repo.copy()
repo_data_only.pop(KEY_HOOKS)
hook_data_only = search_dict("{}[{}]".format(KEY_HOOKS, index), repo, {})
repo_data_only.update({KEY_HOOKS: [hook_data_only]})
hooks.append(
PreCommitHook(repo.get(KEY_REPO), hook[KEY_ID], YAMLFormat(data=[repo_data_only])).key_value_pair
)
return OrderedDict(hooks)
class PreCommitPlugin(NitpickPlugin):
"""Checker for the `.pre-commit-config.yaml `_ file.
Example: :ref:`the default pre-commit hooks `.
"""
file_name = ".pre-commit-config.yaml"
error_base_number = 330
actual_yaml = None # type: YAMLFormat
actual_hooks = OrderedDict() # type: OrderedDict[str, PreCommitHook]
actual_hooks_by_key = {} # type: Dict[str, int]
actual_hooks_by_index = [] # type: List[str]
def suggest_initial_contents(self) -> str:
"""Suggest the initial content for this missing file."""
original = dict(self.file_dict).copy()
# pylint: disable=import-outside-toplevel
from nitpick.config import Config # pylint: disable=redefined-outer-name
from nitpick.plugins.base import NitpickPlugin
app = cls()
cls._current_app = app
app.offline = offline
try:
app.root_dir = app.find_root_dir()
app.cache_dir = app.clear_cache_dir()
app.main_python_file = app.find_main_python_file()
app.config = Config()
app.plugin_manager = app.load_plugins()
NitpickPlugin.load_fixed_dynamic_classes()
except (NoRootDir, NoPythonFile) as err:
app.init_errors.append(err)
return app
"""Checker for `pyproject.toml `_."""
from typing import Optional, Set, Type
from nitpick.app import NitpickApp
from nitpick.plugins import hookimpl
from nitpick.plugins.base import NitpickPlugin
from nitpick.typedefs import JsonDict, YieldFlake8Error
class PyProjectTomlPlugin(NitpickPlugin):
"""Checker for `pyproject.toml `_.
See also `PEP 518 `_.
Example: :ref:`the Python 3.7 default `.
There are many other examples in :ref:`defaults`.
"""
file_name = "pyproject.toml"
error_base_number = 310
def check_rules(self) -> YieldFlake8Error:
"""Check missing key/value pairs in pyproject.toml."""
if NitpickApp.current().config.pyproject_toml:
comparison = NitpickApp.current().config.pyproject_toml.compare_with_flatten(self.file_dict)
yield from self.warn_missing_different(comparison)
def rebuild_dynamic_schema(self, data: JsonDict = None) -> None:
"""Rebuild the dynamic Marshmallow schema when needed, adding new fields that were found on the style."""
new_files_found = OrderedDict() # type: Dict[str, fields.Field]
if data is None:
# Data is empty; so this is the first time the dynamic class is being rebuilt.
# Loop on classes with predetermined names, and add fields for them on the dynamic validation schema.
# E.g.: setup.cfg, pre-commit, pyproject.toml: files whose names we already know at this point.
for subclass in NitpickPlugin.fixed_name_classes:
new_files_found.update(self.file_field_pair(subclass.file_name, subclass))
else:
handled_tags = {} # type: Dict[str, Type[NitpickPlugin]]
# Data was provided; search it to find new dynamic files to add to the validation schema).
# E.g.: JSON files that were configured on some TOML style file.
for subclass in NitpickPlugin.dynamic_name_classes:
for tag in subclass.identify_tags:
# A tag can only be handled by a single subclass.
# If more than one class handle a tag, the latest one will be the handler.
handled_tags[tag] = subclass
jmex = subclass.get_compiled_jmespath_file_names()
for configured_file_name in search_dict(jmex, data, []):
new_files_found.update(self.file_field_pair(configured_file_name, subclass))
self._find_subclasses(data, handled_tags, new_files_found)
# Only recreate the schema if new fields were found.
if new_files_found:
self._dynamic_schema_class = type("DynamicStyleSchema", (self._dynamic_schema_class,), new_files_found)
class TextItemSchema(Schema):
"""Validation schema for the object inside ``contains``."""
error_messages = {"unknown": help_message("Unknown configuration", TEXT_FILE_RTFD_PAGE)}
line = fields.NonEmptyString()
class TextSchema(Schema):
"""Validation schema for the text file TOML configuration."""
error_messages = {"unknown": help_message("Unknown configuration", TEXT_FILE_RTFD_PAGE)}
contains = fields.List(fields.Nested(TextItemSchema))
class TextPlugin(NitpickPlugin):
"""Checker for text files.
To check if ``some.txt`` file contains the lines ``abc`` and ``def`` (in any order):
.. code-block:: toml
[["some.txt".contains]]
line = "abc"
[["some.txt".contains]]
line = "def"
"""
error_base_number = 350
identify_tags = {"plain-text"}
validation_schema = TextSchema
from nitpick.schemas import BaseNitpickSchema
from nitpick.typedefs import JsonDict, YieldFlake8Error
KEY_CONTAINS_KEYS = "contains_keys"
KEY_CONTAINS_JSON = "contains_json"
LOGGER = logging.getLogger(__name__)
class JSONFileSchema(BaseNitpickSchema):
"""Validation schema for any JSON file added to the style."""
contains_keys = fields.List(fields.NonEmptyString)
contains_json = fields.Dict(fields.NonEmptyString, fields.JSONString)
class JSONPlugin(NitpickPlugin):
"""Checker for any JSON file.
Add the configurations for the file name you wish to check.
Example: :ref:`the default config for package.json `.
"""
error_base_number = 340
validation_schema = JSONFileSchema
identify_tags = {"json"}
SOME_VALUE_PLACEHOLDER = ""
def check_rules(self) -> YieldFlake8Error:
"""Check missing keys and JSON content."""
yield from self._check_contained_keys()