Example #1
0
 def __init__(
     self, linter: Optional["PyLinter"] = None
 ):  # pylint: disable=super-init-not-called # See https://github.com/PyCQA/pylint/issues/4941
     BaseChecker.__init__(self, linter)
     self._deprecated_methods: Set[Any] = set()
     self._deprecated_methods.update(DEPRECATED_METHODS[0])
     for since_vers, func_list in DEPRECATED_METHODS[sys.version_info[0]].items():
         if since_vers <= sys.version_info:
             self._deprecated_methods.update(func_list)
     self._deprecated_attributes = {}
     for since_vers, func_list in DEPRECATED_ARGUMENTS.items():
         if since_vers <= sys.version_info:
             self._deprecated_attributes.update(func_list)
     self._deprecated_classes = {}
     for since_vers, class_list in DEPRECATED_CLASSES.items():
         if since_vers <= sys.version_info:
             self._deprecated_classes.update(class_list)
     self._deprecated_modules = set()
     for since_vers, mod_list in DEPRECATED_MODULES.items():
         if since_vers <= sys.version_info:
             self._deprecated_modules.update(mod_list)
     self._deprecated_decorators = set()
     for since_vers, decorator_list in DEPRECATED_DECORATORS.items():
         if since_vers <= sys.version_info:
             self._deprecated_decorators.update(decorator_list)
Example #2
0
def test_bad_import(
    linter: UnittestLinter,
    imports_checker: BaseChecker,
    module_name: str,
    import_from: str,
    import_what: str,
    error_code: str,
) -> None:
    """Ensure bad imports are rejected."""

    import_node = astroid.extract_node(
        f"from {import_from} import {import_what} #@",
        module_name,
    )
    imports_checker.visit_module(import_node.parent)

    with assert_adds_messages(
        linter,
        pylint.testutils.MessageTest(
            msg_id=error_code,
            node=import_node,
            args=None,
            line=1,
            col_offset=0,
            end_line=1,
            end_col_offset=len(import_from) + len(import_what) + 13,
        ),
    ):
        imports_checker.visit_importfrom(import_node)
Example #3
0
    def set_option(self, optname, value, action=None, optdict=None):
        """Method called to set an option (registered in the options list).

        Overridden to report options setting to Similar
        """
        # pylint: disable-next=fixme
        # TODO: Refactor after OptionProvider has been moved to argparse
        BaseChecker.set_option(self, optname, value, action, optdict)
        if optname == "min-similarity-lines":
            self.min_lines = (getattr(self.linter.namespace,
                                      "min_similarity_lines", None)
                              or self.config.min_similarity_lines)
        elif optname == "ignore-comments":
            self.ignore_comments = (getattr(self.linter.namespace,
                                            "ignore_comments", None)
                                    or self.config.ignore_comments)
        elif optname == "ignore-docstrings":
            self.ignore_docstrings = (getattr(self.linter.namespace,
                                              "ignore_docstrings", None)
                                      or self.config.ignore_docstrings)
        elif optname == "ignore-imports":
            self.ignore_imports = (getattr(self.linter.namespace,
                                           "ignore_imports", None)
                                   or self.config.ignore_imports)
        elif optname == "ignore-signatures":
            self.ignore_signatures = (getattr(self.linter.namespace,
                                              "ignore_signatures", None)
                                      or self.config.ignore_signatures)
Example #4
0
    def __init__(self, linter: "PyLinter") -> None:
        BaseChecker.__init__(self, linter)
        self._deprecated_methods: Set[str] = set()
        self._deprecated_arguments: Dict[
            str, Tuple[Tuple[Optional[int], str], ...]
        ] = {}
        self._deprecated_classes: Dict[str, Set[str]] = {}
        self._deprecated_modules: Set[str] = set()
        self._deprecated_decorators: Set[str] = set()

        for since_vers, func_list in DEPRECATED_METHODS[sys.version_info[0]].items():
            if since_vers <= sys.version_info:
                self._deprecated_methods.update(func_list)
        for since_vers, func_list in DEPRECATED_ARGUMENTS.items():
            if since_vers <= sys.version_info:
                self._deprecated_arguments.update(func_list)
        for since_vers, class_list in DEPRECATED_CLASSES.items():
            if since_vers <= sys.version_info:
                self._deprecated_classes.update(class_list)
        for since_vers, mod_list in DEPRECATED_MODULES.items():
            if since_vers <= sys.version_info:
                self._deprecated_modules.update(mod_list)
        for since_vers, decorator_list in DEPRECATED_DECORATORS.items():
            if since_vers <= sys.version_info:
                self._deprecated_decorators.update(decorator_list)
Example #5
0
def test_invalid_list_dict_str_any(
    linter: UnittestLinter, type_hint_checker: BaseChecker
) -> None:
    """Ensure invalid hints are rejected for discovery_info."""
    func_node = astroid.extract_node(
        """
    async def async_get_triggers( #@
        hass: HomeAssistant,
        device_id: str
    ) -> list:
        pass
    """,
        "homeassistant.components.pylint_test.device_trigger",
    )
    type_hint_checker.visit_module(func_node.parent)

    with assert_adds_messages(
        linter,
        pylint.testutils.MessageTest(
            msg_id="hass-return-type",
            node=func_node,
            args=(
                ["list[dict[str, str]]", "list[dict[str, Any]]"],
                "async_get_triggers",
            ),
            line=2,
            col_offset=0,
            end_line=2,
            end_col_offset=28,
        ),
    ):
        type_hint_checker.visit_asyncfunctiondef(func_node)
Example #6
0
def test_invalid_discovery_info(
    linter: UnittestLinter, type_hint_checker: BaseChecker
) -> None:
    """Ensure invalid hints are rejected for discovery_info."""
    func_node, discovery_info_node = astroid.extract_node(
        """
    async def async_setup_scanner( #@
        hass: HomeAssistant,
        config: ConfigType,
        async_see: AsyncSeeCallback,
        discovery_info: dict[str, Any] | None = None, #@
    ) -> bool:
        pass
    """,
        "homeassistant.components.pylint_test.device_tracker",
    )
    type_hint_checker.visit_module(func_node.parent)

    with assert_adds_messages(
        linter,
        pylint.testutils.MessageTest(
            msg_id="hass-argument-type",
            node=discovery_info_node,
            args=(4, "DiscoveryInfoType | None", "async_setup_scanner"),
            line=6,
            col_offset=4,
            end_line=6,
            end_col_offset=41,
        ),
    ):
        type_hint_checker.visit_asyncfunctiondef(func_node)
Example #7
0
def test_valid_config_flow_step(
    linter: UnittestLinter, type_hint_checker: BaseChecker
) -> None:
    """Ensure valid hints are accepted for ConfigFlow step."""
    class_node = astroid.extract_node(
        """
    class FlowHandler():
        pass

    class ConfigFlow(FlowHandler):
        pass

    class AxisFlowHandler( #@
        ConfigFlow, domain=AXIS_DOMAIN
    ):
        async def async_step_zeroconf(
            self,
            device_config: ZeroconfServiceInfo
        ) -> FlowResult:
            pass
    """,
        "homeassistant.components.pylint_test.config_flow",
    )
    type_hint_checker.visit_module(class_node.parent)

    with assert_no_messages(linter):
        type_hint_checker.visit_classdef(class_node)
Example #8
0
def test_media_player_entity(
    linter: UnittestLinter, type_hint_checker: BaseChecker
) -> None:
    """Ensure valid hints are accepted for media_player entity."""
    # Set bypass option
    type_hint_checker.config.ignore_missing_annotations = False

    class_node = astroid.extract_node(
        """
    class Entity():
        pass

    class MediaPlayerEntity(Entity):
        pass

    class MyMediaPlayer( #@
        MediaPlayerEntity
    ):
        async def async_get_media_image(self) -> tuple[bytes | None, str | None]:
            pass
    """,
        "homeassistant.components.pylint_test.media_player",
    )
    type_hint_checker.visit_module(class_node.parent)

    with assert_no_messages(linter):
        type_hint_checker.visit_classdef(class_node)
Example #9
0
def test_valid_mapping_return_type(
    linter: UnittestLinter,
    type_hint_checker: BaseChecker,
    return_hint: str,
) -> None:
    """Check that Mapping[xxx, Any] accepts both Mapping and dict."""
    # Set bypass option
    type_hint_checker.config.ignore_missing_annotations = False

    class_node = astroid.extract_node(
        f"""
    class Entity():
        pass

    class ToggleEntity(Entity):
        pass

    class FanEntity(ToggleEntity):
        pass

    class MyFanA( #@
        FanEntity
    ):
        @property
        def capability_attributes(
            self
        ){return_hint}:
            pass
    """,
        "homeassistant.components.pylint_test.fan",
    )
    type_hint_checker.visit_module(class_node.parent)

    with assert_no_messages(linter):
        type_hint_checker.visit_classdef(class_node)
Example #10
0
 def __init__(self, linter=None):
     BaseChecker.__init__(self, linter)
     Similar.__init__(self,
                      min_lines=4,
                      ignore_comments=True,
                      ignore_docstrings=True)
     self.stats = None
Example #11
0
def test_number_entity(linter: UnittestLinter, type_hint_checker: BaseChecker) -> None:
    """Ensure valid hints are accepted for number entity."""
    # Set bypass option
    type_hint_checker.config.ignore_missing_annotations = False

    # Ensure that device class is valid despite Entity inheritance
    # Ensure that `int` is valid for `float` return type
    class_node = astroid.extract_node(
        """
    class Entity():
        pass

    class RestoreEntity(Entity):
        pass

    class NumberEntity(Entity):
        pass

    class MyNumber( #@
        RestoreEntity, NumberEntity
    ):
        @property
        def device_class(self) -> NumberDeviceClass:
            pass

        @property
        def native_value(self) -> int:
            pass
    """,
        "homeassistant.components.pylint_test.number",
    )
    type_hint_checker.visit_module(class_node.parent)

    with assert_no_messages(linter):
        type_hint_checker.visit_classdef(class_node)
Example #12
0
def test_invalid_long_tuple(
    linter: UnittestLinter, type_hint_checker: BaseChecker
) -> None:
    """Check invalid entity properties are ignored by default."""
    # Set ignore option
    type_hint_checker.config.ignore_missing_annotations = False

    class_node, rgbw_node, rgbww_node = astroid.extract_node(
        """
    class Entity():
        pass

    class ToggleEntity(Entity):
        pass

    class LightEntity(ToggleEntity):
        pass

    class TestLight( #@
        LightEntity
    ):
        @property
        def rgbw_color( #@
            self
        ) -> tuple[int, int, int, int, int]:
            pass

        @property
        def rgbww_color( #@
            self
        ) -> tuple[int, int, int, int, float]:
            pass
    """,
        "homeassistant.components.pylint_test.light",
    )
    type_hint_checker.visit_module(class_node.parent)

    with assert_adds_messages(
        linter,
        pylint.testutils.MessageTest(
            msg_id="hass-return-type",
            node=rgbw_node,
            args=(["tuple[int, int, int, int]", None], "rgbw_color"),
            line=15,
            col_offset=4,
            end_line=15,
            end_col_offset=18,
        ),
        pylint.testutils.MessageTest(
            msg_id="hass-return-type",
            node=rgbww_node,
            args=(["tuple[int, int, int, int, int]", None], "rgbww_color"),
            line=21,
            col_offset=4,
            end_line=21,
            end_col_offset=19,
        ),
    ):
        type_hint_checker.visit_classdef(class_node)
Example #13
0
 def __init__(self, linter=None):
     BaseChecker.__init__(self, linter)
     self.stats = None
     self._returns = None
     self._branches = None
     self._used_ifaces = None
     self._ifaces = None
     self._stmts = 0
    def __init__(self, linter):
        """
        Change function of processing blank lines in pycodestyle.

        @param linter: current C{PyLinter} object.
        """
        BaseChecker.__init__(self, linter)
        self.pycodestyleEnabled = True  # yes of course
Example #15
0
    def __init__(self, linter):
        """
        Change function of processing blank lines in pep8.

        @param linter: current C{PyLinter} object.
        """
        BaseChecker.__init__(self, linter)
        self.pep8Enabled = self.linter.option_value("pep8")
Example #16
0
 def __init__(self, linter=None):
     BaseChecker.__init__(self, linter)
     self.stats = None
     self.import_graph = None
     self.__int_dep_info = self.__ext_dep_info = None
     self.reports = (
         ("RP0401", "External dependencies", self.report_external_dependencies),
         ("RP0402", "Modules dependencies graph", self.report_dependencies_graph),
     )
 def __init__(self, linter=None):
     """
     :param linter: PyLint linter
     :type linter: pylint.lint.PyLinter
     """
     BaseChecker.__init__(self, linter)
     self._current_function = None  # type: astroid.nodes.FunctionDef
     self._current_if = None  # type: astroid.nodes.If
     self._messages_added = set()
Example #18
0
 def __init__(self, linter=None):
     BaseChecker.__init__(self, linter)
     self.stats = None
     self.import_graph = None
     self.__int_dep_info = self.__ext_dep_info = None
     self.reports = (('RP0401', 'External dependencies',
                      self.report_external_dependencies),
                     ('RP0402', 'Modules dependencies graph',
                      self.report_dependencies_graph),
                     )
Example #19
0
 def __init__(self, linter=None):
     BaseChecker.__init__(self, linter)
     self.stats = None
     self.import_graph = None
     self.__int_dep_info = self.__ext_dep_info = None
     self.reports = (('RP0401', 'External dependencies',
                      self.report_external_dependencies),
                     ('RP0402', 'Modules dependencies graph',
                      self.report_dependencies_graph),
                     )
Example #20
0
 def __init__(self, linter=None) -> None:
     BaseChecker.__init__(self, linter)
     Similar.__init__(
         self,
         min_lines=self.linter.namespace.min_similarity_lines,
         ignore_comments=self.linter.namespace.ignore_comments,
         ignore_docstrings=self.linter.namespace.ignore_docstrings,
         ignore_imports=self.linter.namespace.ignore_imports,
         ignore_signatures=self.linter.namespace.ignore_signatures,
     )
def test_ignore_not_annotations(hass_enforce_type_hints: ModuleType,
                                type_hint_checker: BaseChecker,
                                code: str) -> None:
    """Ensure that _is_valid_type is not run if there are no annotations."""
    func_node = astroid.extract_node(code)

    with patch.object(hass_enforce_type_hints,
                      "_is_valid_type",
                      return_value=True) as is_valid_type:
        type_hint_checker.visit_asyncfunctiondef(func_node)
        is_valid_type.assert_not_called()
Example #22
0
    def __init__(self, linter=None):
        # To avoid PyLints deprecation about a missing symbolic name and
        # because I don't want to add descriptions, let's make the descriptions
        # equal to the messages.
        if self.msgs is None:
            self.msgs = {}

        for code, (message, symbolic) in self._msgs.iteritems():
            self.msgs[code] = (message, symbolic, message)

        BaseChecker.__init__(self, linter=linter)
Example #23
0
 def __init__(self, linter=None):
     BaseChecker.__init__(self, linter)
     self._deprecated_methods = set()
     self._deprecated_methods.update(DEPRECATED_METHODS[0])
     for since_vers, func_list in DEPRECATED_METHODS[sys.version_info[0]].items():
         if since_vers <= sys.version_info:
             self._deprecated_methods.update(func_list)
     self._deprecated_attributes = dict()
     for since_vers, func_list in DEPRECATED_ARGUMENTS.items():
         if since_vers <= sys.version_info:
             self._deprecated_attributes.update(func_list)
Example #24
0
 def __init__(self, linter=None) -> None:
     BaseChecker.__init__(self, linter)
     Similar.__init__(
         self,
         min_lines=self.config.min_similarity_lines,
         ignore_comments=self.config.ignore_comments,
         ignore_docstrings=self.config.ignore_docstrings,
         ignore_imports=self.config.ignore_imports,
         ignore_signatures=self.config.ignore_signatures,
     )
     self.stats: CheckerStats = {}
Example #25
0
def test_invalid_config_flow_async_get_options_flow(
    linter: UnittestLinter, type_hint_checker: BaseChecker
) -> None:
    """Ensure invalid hints are rejected for ConfigFlow async_get_options_flow."""
    # AxisOptionsFlow doesn't inherit OptionsFlow, and therefore should fail
    class_node, func_node, arg_node = astroid.extract_node(
        """
    class FlowHandler():
        pass

    class ConfigFlow(FlowHandler):
        pass

    class OptionsFlow(FlowHandler):
        pass

    class AxisOptionsFlow():
        pass

    class AxisFlowHandler( #@
        ConfigFlow, domain=AXIS_DOMAIN
    ):
        def async_get_options_flow( #@
            config_entry #@
        ) -> AxisOptionsFlow:
            return AxisOptionsFlow(config_entry)
    """,
        "homeassistant.components.pylint_test.config_flow",
    )
    type_hint_checker.visit_module(class_node.parent)

    with assert_adds_messages(
        linter,
        pylint.testutils.MessageTest(
            msg_id="hass-argument-type",
            node=arg_node,
            args=(1, "ConfigEntry", "async_get_options_flow"),
            line=18,
            col_offset=8,
            end_line=18,
            end_col_offset=20,
        ),
        pylint.testutils.MessageTest(
            msg_id="hass-return-type",
            node=func_node,
            args=("OptionsFlow", "async_get_options_flow"),
            line=17,
            col_offset=4,
            end_line=17,
            end_col_offset=30,
        ),
    ):
        type_hint_checker.visit_classdef(class_node)
Example #26
0
    def set_option(self, optname, value, action=None, optdict=None):
        """method called to set an option (registered in the options list)

        overridden to report options setting to Similar
        """
        BaseChecker.set_option(self, optname, value, action, optdict)
        if optname == 'min-similarity-lines':
            self.min_lines = self.config.min_similarity_lines
        elif optname == 'ignore-comments':
            self.ignore_comments = self.config.ignore_comments
        elif optname == 'ignore-docstrings':
            self.ignore_docstrings = self.config.ignore_docstrings
Example #27
0
  def __init__(self, *args, **kwargs):
    BaseChecker.__init__(self, *args, **kwargs)

    if self.linter is None:
      # Unit tests don't set this up.
      self._indent_string = '  '
    else:
      cfg = _PylintrcConfig(self.linter.config_file, 'format',
                            (('indent-string', {'default': '    ',
                                                'type': 'string'}),))
      self._indent_string = cfg.option_value('indent-string')
    self._indent_len = len(self._indent_string)
Example #28
0
    def set_option(self, optname, value, action=None, optdict=None):
        """method called to set an option (registered in the options list)

        overridden to report options setting to Similar
        """
        BaseChecker.set_option(self, optname, value, action, optdict)
        if optname == 'min-similarity-lines':
            self.min_lines = self.config.min_similarity_lines
        elif optname == 'ignore-comments':
            self.ignore_comments = self.config.ignore_comments
        elif optname == 'ignore-docstrings':
            self.ignore_docstrings = self.config.ignore_docstrings
Example #29
0
    def __init__(self, linter=None):
        BaseChecker.__init__(self, linter)
        self.stats = None
        self.import_graph = None
        self._imports_stack = []
        self._first_non_import_node = None
        self._module_pkg = {}  # mapping of modules to the pkg they belong in
        self.reports = (
            ("RP0401", "External dependencies", self._report_external_dependencies),
            ("RP0402", "Modules dependencies graph", self._report_dependencies_graph),
        )

        self._site_packages = self._compute_site_packages()
Example #30
0
    def __init__(self, linter=None):
        BaseChecker.__init__(self, linter)
        self.stats = None
        self.import_graph = None
        self._imports_stack = []
        self._first_non_import_node = None
        self._module_pkg = {}  # mapping of modules to the pkg they belong in
        self.reports = (
            ("RP0401", "External dependencies", self._report_external_dependencies),
            ("RP0402", "Modules dependencies graph", self._report_dependencies_graph),
        )

        self._site_packages = self._compute_site_packages()
Example #31
0
    def __init__(self, linter=None):
        BaseChecker.__init__(self, linter)
        self.stats = None
        self.import_graph = None
        self._imports_stack = []
        self._first_non_import_node = None
        self.__int_dep_info = self.__ext_dep_info = None
        self.reports = (
            ("RP0401", "External dependencies", self._report_external_dependencies),
            ("RP0402", "Modules dependencies graph", self._report_dependencies_graph),
        )

        self._site_packages = self._compute_site_packages()
Example #32
0
def test_valid_list_dict_str_any(linter: UnittestLinter,
                                 type_hint_checker: BaseChecker) -> None:
    """Ensure valid hints are accepted for discovery_info."""
    type_hint_checker.module = "homeassistant.components.pylint_test.device_trigger"
    func_node = astroid.extract_node("""
    async def async_get_triggers( #@
        hass: HomeAssistant,
        device_id: str
    ) -> list[dict[str, Any]]:
        pass
    """)

    with assert_no_messages(linter):
        type_hint_checker.visit_asyncfunctiondef(func_node)
Example #33
0
    def __init__(self, linter=None):
        BaseChecker.__init__(self, linter)
        self.stats = None
        self.import_graph = None
        self._imports_stack = []
        self._first_non_import_node = None
        self.__int_dep_info = self.__ext_dep_info = None
        self.reports = (('RP0401', 'External dependencies',
                         self._report_external_dependencies),
                        ('RP0402', 'Modules dependencies graph',
                         self._report_dependencies_graph),
                       )

        self._site_packages = self._compute_site_packages()
Example #34
0
 def __init__(self, linter: "PyLinter") -> None:
     BaseChecker.__init__(self, linter)
     self.import_graph: collections.defaultdict = collections.defaultdict(
         set)
     self._imports_stack: List[Tuple[Any, Any]] = []
     self._first_non_import_node = None
     self._module_pkg: Dict[Any, Any] = {
     }  # mapping of modules to the pkg they belong in
     self._allow_any_import_level: Set[Any] = set()
     self.reports = (
         ("RP0401", "External dependencies",
          self._report_external_dependencies),
         ("RP0402", "Modules dependencies graph",
          self._report_dependencies_graph),
     )
Example #35
0
def test_dont_ignore_partial_annotations(
    hass_enforce_type_hints: ModuleType, type_hint_checker: BaseChecker, code: str
) -> None:
    """Ensure that _is_valid_type is run if there is at least one annotation."""
    func_node = astroid.extract_node(
        code,
        "homeassistant.components.pylint_test",
    )
    type_hint_checker.visit_module(func_node.parent)

    with patch.object(
        hass_enforce_type_hints, "_is_valid_type", return_value=True
    ) as is_valid_type:
        type_hint_checker.visit_asyncfunctiondef(func_node)
        is_valid_type.assert_called()
def test_valid_discovery_info(linter: UnittestLinter,
                              type_hint_checker: BaseChecker) -> None:
    """Ensure valid hints are accepted for discovery_info."""
    type_hint_checker.module = "homeassistant.components.pylint_test.device_tracker"
    func_node = astroid.extract_node("""
    async def async_setup_scanner( #@
        hass: HomeAssistant,
        config: ConfigType,
        async_see: Callable[..., Awaitable[None]],
        discovery_info: DiscoveryInfoType | None = None,
    ) -> bool:
        pass
    """)

    with assert_no_messages(linter):
        type_hint_checker.visit_asyncfunctiondef(func_node)
Example #37
0
 def __init__(self, linter=None):
     BaseChecker.__init__(self, linter)
     self._to_consume = None
     self._checking_mod_attr = None
Example #38
0
 def __init__(self, linter=None):
     BaseChecker.__init__(self, linter)
     self._accessed = []
     self._first_attrs = []
     self._meth_could_be_func = None
Example #39
0
 def __init__(self, linter=None):
     BaseChecker.__init__(self, linter)
     self.generated_members = list(self.config.generated_members)
     if self.config.zope:
         self.generated_members.extend(('REQUEST', 'acl_users', 'aq_parent'))
Example #40
0
 def __init__(self, linter):
     BaseChecker.__init__(self, linter)
     self.stats = None
     self._returns = None
Example #41
0
 def __init__(self, linter=None):
     BaseChecker.__init__(self, linter)
Example #42
0
 def __init__(self, linter=None):
     BaseChecker.__init__(self, linter)
     Similar.__init__(self, min_lines=4,
                      ignore_comments=True, ignore_docstrings=True)
     self.stats = None
Example #43
0
 def __init__(self, linter=None):
     BaseChecker.__init__(self, linter)
     self._rpython = True