From af6d0e51a4c7b15431dfff1e441a0a674aa77332 Mon Sep 17 00:00:00 2001 From: Augusto Wagner Andreoli Date: Wed, 21 Aug 2019 21:11:08 +0200 Subject: [PATCH] refactor: load fixed and dynamic classes on BaseFile --- poetry.lock | 6 +++--- src/nitpick/app.py | 2 ++ src/nitpick/files/base.py | 18 ++++++++++++++++-- src/nitpick/style.py | 16 +++------------- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index 215f60d5..1060a8ac 100644 --- a/poetry.lock +++ b/poetry.lock @@ -278,7 +278,7 @@ description = "A lightweight library for converting complex datatypes to and fro name = "marshmallow" optional = false python-versions = ">=3.5" -version = "3.0.0" +version = "3.0.1" [[package]] category = "main" @@ -737,7 +737,7 @@ version = "0.1.7" [[package]] category = "dev" description = "Enable Unicode input and display when running Python from Windows console." -marker = "sys_platform == \"win32\" and python_version < \"3.6\" or sys_platform == \"win32\" and python_version < \"3.6\" and python_version >= \"3.4\"" +marker = "sys_platform == \"win32\" and python_version < \"3.6\" and python_version >= \"3.4\" or sys_platform == \"win32\" and python_version < \"3.6\"" name = "win-unicode-console" optional = false python-versions = "*" @@ -792,7 +792,7 @@ jinja2 = ["065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", "1 jmespath = ["3720a4b1bd659dd2eecad0666459b9788813e032b83e7ba58578e48254e0a0e6", "bde2aef6f44302dfb30320115b17d030798de8c4110e28d5cf6cf91a7a31074c"] lazy-object-proxy = ["159a745e61422217881c4de71f9eafd9d703b93af95618635849fe469a283661", "23f63c0821cc96a23332e45dfaa83266feff8adc72b9bcaef86c202af765244f", "3b11be575475db2e8a6e11215f5aa95b9ec14de658628776e10d96fa0b4dac13", "3f447aff8bc61ca8b42b73304f6a44fa0d915487de144652816f950a3f1ab821", "4ba73f6089cd9b9478bc0a4fa807b47dbdb8fad1d8f31a0f0a5dbf26a4527a71", "4f53eadd9932055eac465bd3ca1bd610e4d7141e1278012bd1f28646aebc1d0e", "64483bd7154580158ea90de5b8e5e6fc29a16a9b4db24f10193f0c1ae3f9d1ea", "6f72d42b0d04bfee2397aa1862262654b56922c20a9bb66bb76b6f0e5e4f9229", "7c7f1ec07b227bdc561299fa2328e85000f90179a2f44ea30579d38e037cb3d4", "7c8b1ba1e15c10b13cad4171cfa77f5bb5ec2580abc5a353907780805ebe158e", "8559b94b823f85342e10d3d9ca4ba5478168e1ac5658a8a2f18c991ba9c52c20", "a262c7dfb046f00e12a2bdd1bafaed2408114a89ac414b0af8755c696eb3fc16", "acce4e3267610c4fdb6632b3886fe3f2f7dd641158a843cf6b6a68e4ce81477b", "be089bb6b83fac7f29d357b2dc4cf2b8eb8d98fe9d9ff89f9ea6012970a853c7", "bfab710d859c779f273cc48fb86af38d6e9210f38287df0069a63e40b45a2f5c", "c10d29019927301d524a22ced72706380de7cfc50f767217485a912b4c8bd82a", "dd6e2b598849b3d7aee2295ac765a578879830fb8966f70be8cd472e6069932e", "e408f1eacc0a68fed0c08da45f31d0ebb38079f043328dce69ff133b95c29dc1"] markupsafe = ["00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", "09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", "09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", "1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", "24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", "29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", "43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", "46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", "500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", "535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", "62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", "6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", "717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", "79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", "7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", "88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", "8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", "98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", "9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", "9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", "ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", "b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", "b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", "b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", "ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", "c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", "cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", "e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"] -marshmallow = ["e5e9fd0c2e919b4ece915eb30808206349a49a45df72e99ed20e27a9053d574b", "fa2d8a4b61d09b0e161a14acc5ad8ab7aaaf1477f3dd52819ddd6c6c8275733a"] +marshmallow = ["23f684b54b1955ebd5bdfbdda4062e438ef86218f14f1a356f570cdf0c016ab3", "fcfc9ffd75a883da06f30f604a4e81dd0b56eb9438f4d0a8de6bbaa163ce9ec3"] marshmallow-polyfield = ["963a01e80bca5cb4da42b8d2f7e6e90946257ae22d22ff2ed104a8a863eeb0c6"] mccabe = ["ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", "dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"] more-itertools = ["409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832", "92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4"] diff --git a/src/nitpick/app.py b/src/nitpick/app.py index cc3a071e..25dd9610 100644 --- a/src/nitpick/app.py +++ b/src/nitpick/app.py @@ -36,6 +36,7 @@ def __init__(self) -> None: def create_app(cls) -> "Nitpick": """Create a single application.""" from nitpick.config import Config # pylint: disable=redefined-outer-name + from nitpick.files.base import BaseFile app = cls() cls._current_app = app @@ -46,6 +47,7 @@ def create_app(cls) -> "Nitpick": app.main_python_file = app.find_main_python_file() app.config = Config() + BaseFile.load_fixed_dynamic_classes() except (NoRootDir, NoPythonFile) as err: app.init_errors.append(err) diff --git a/src/nitpick/files/base.py b/src/nitpick/files/base.py index 3b3501c4..73f30c3d 100644 --- a/src/nitpick/files/base.py +++ b/src/nitpick/files/base.py @@ -1,13 +1,13 @@ """Base class for file checkers.""" import abc from pathlib import Path -from typing import Generator, List +from typing import Generator, List, Set, Type import jmespath from nitpick import Nitpick from nitpick.formats import TomlFormat -from nitpick.generic import search_dict +from nitpick.generic import get_subclasses, search_dict from nitpick.mixin import NitpickMixin from nitpick.typedefs import JsonDict, YieldFlake8Error @@ -24,6 +24,9 @@ class BaseFile(NitpickMixin, metaclass=abc.ABCMeta): file_dict = {} # type: JsonDict nitpick_file_dict = {} # type: JsonDict + fixed_name_classes = set() # type: Set[Type[BaseFile]] + dynamic_name_classes = set() # type: Set[Type[BaseFile]] + def __init__(self) -> None: if self.has_multiple_files: key = "{}.file_names".format(self.__class__.__name__) @@ -32,6 +35,17 @@ def __init__(self) -> None: self._multiple_files = [self.file_name] self._set_current_data(self.file_name) + @classmethod + def load_fixed_dynamic_classes(cls) -> None: + """Separate classes with fixed file names from classes with dynamic files names.""" + cls.fixed_name_classes = set() + cls.dynamic_name_classes = set() + for subclass in get_subclasses(BaseFile): + if subclass.file_name: + cls.fixed_name_classes.add(subclass) + else: + cls.dynamic_name_classes.add(subclass) + def _set_current_data(self, file_name: str) -> None: """Set data for the current file name, either if there are multiple or single files.""" if self.has_multiple_files: diff --git a/src/nitpick/style.py b/src/nitpick/style.py index 9df4620e..94181458 100644 --- a/src/nitpick/style.py +++ b/src/nitpick/style.py @@ -20,7 +20,7 @@ from nitpick.files.base import BaseFile from nitpick.files.pyproject_toml import PyProjectTomlFile from nitpick.formats import TomlFormat -from nitpick.generic import MergeDict, climb_directory_tree, get_subclasses, is_url, search_dict +from nitpick.generic import MergeDict, climb_directory_tree, is_url, search_dict from nitpick.schemas import BaseStyleSchema, flatten_marshmallow_errors from nitpick.typedefs import JsonDict, StrOrList @@ -35,16 +35,6 @@ def __init__(self) -> None: self._already_included = set() # type: Set[str] self._first_full_path = "" # type: str - # Separate classes with fixed file names from classes with dynamic files names. - # FIXME do only once on app init (Nitpick.__init__(); or create_app(), mimicking Flask) - self.files_predetermined_names = set() # type: Set[Type[BaseFile]] - self.files_dynamic_names = set() # type: Set[Type[BaseFile]] - for subclass in get_subclasses(BaseFile): - if subclass.file_name: - self.files_predetermined_names.add(subclass) - else: - self.files_dynamic_names.add(subclass) - self._dynamic_schema_class = BaseStyleSchema # type: type self.rebuild_dynamic_schema() @@ -217,12 +207,12 @@ def rebuild_dynamic_schema(self, data: JsonDict = None) -> 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 self.files_predetermined_names: + for subclass in BaseFile.fixed_name_classes: self.append_field_from_file(new_files_found, subclass, subclass.file_name) else: # 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 self.files_dynamic_names: + for subclass in BaseFile.dynamic_name_classes: jmex = subclass.get_compiled_jmespath_file_names() for file_name in search_dict(jmex, data, []): self.append_field_from_file(new_files_found, subclass, file_name)