diff --git a/ChangeLog b/ChangeLog index d1ae7b6ff5..97578d7737 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,16 @@ Release date: TBA Closes #5224 +* The ``config`` attribute of ``BaseChecker`` has been deprecated. You can use ``checker.linter.config`` + to access the global configuration object instead of a checker-specific object. + + Ref #5392 + +* The ``config`` attribute of ``PyLinter`` is now of the ``argparse.Namespace`` type instead of + ``optparse.Values``. + + Ref #5392 + * ``OptionsManagerMixIn`` has been replaced with ``ArgumentsManager``. ``ArgumentsManager`` is considered private API and most methods that were public on ``OptionsManagerMixIn`` have now been deprecated and will be removed in a future release. diff --git a/doc/whatsnew/2.14.rst b/doc/whatsnew/2.14.rst index 8763a8179a..3e31f447ab 100644 --- a/doc/whatsnew/2.14.rst +++ b/doc/whatsnew/2.14.rst @@ -73,6 +73,16 @@ Other Changes Closes #5283 Closes #1887 +* The ``config`` attribute of ``BaseChecker`` has been deprecated. You can use ``checker.linter.config`` + to access the global configuration object instead of a checker-specific object. + + Ref #5392 + +* The ``config`` attribute of ``PyLinter`` is now of the ``argparse.Namespace`` type instead of + ``optparse.Values``. + + Ref #5392 + * ``OptionsManagerMixIn`` has been replaced with ``ArgumentsManager``. ``ArgumentsManager`` is considered private API and most methods that were public on ``OptionsManagerMixIn`` have now been deprecated and will be removed in a future release. diff --git a/pylint/config/arguments_manager.py b/pylint/config/arguments_manager.py index 2a07d999f4..bc58a8244e 100644 --- a/pylint/config/arguments_manager.py +++ b/pylint/config/arguments_manager.py @@ -86,6 +86,10 @@ def __init__(self, prog: str, usage: Optional[str] = None) -> None: # verbosity self._maxlevel: int = 0 + @property + def config(self) -> argparse.Namespace: + return self.namespace + def _register_options_provider(self, provider: "_ArgumentsProvider") -> None: """Register an options provider and load its defaults.""" for opt, optdict in provider.options: diff --git a/pylint/config/arguments_provider.py b/pylint/config/arguments_provider.py index 55a2f4ade6..d61ce52bb8 100644 --- a/pylint/config/arguments_provider.py +++ b/pylint/config/arguments_provider.py @@ -40,12 +40,21 @@ def __init__(self, arguments_manager: _ArgumentsManager) -> None: # pylint: disable=fixme # TODO: Optparse: Added to keep API parity with OptionsProvider # They should be removed/deprecated when refactoring the copied methods - self.config = optparse.Values() + self._config = optparse.Values() with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning) self.load_defaults() self.level = 0 + @property + def config(self) -> optparse.Values: + warnings.warn( + "The checker-specific config attribute has been deprecated. Please use " + "'linter.config' to access the global configuration object.", + DeprecationWarning, + ) + return self._config + def load_defaults(self) -> None: """DEPRECATED: Initialize the provider using default values.""" warnings.warn( diff --git a/pylint/lint/pylinter.py b/pylint/lint/pylinter.py index f37b05c2e5..1faeb0a891 100644 --- a/pylint/lint/pylinter.py +++ b/pylint/lint/pylinter.py @@ -195,7 +195,7 @@ def _load_reporter_by_class(reporter_class: str) -> type: # pylint: disable=too-many-instance-attributes,too-many-public-methods -class PyLinter( +class PyLinter( # type: ignore[misc] _ArgumentsManager, reporters.ReportsHandlerMixIn, checkers.BaseTokenChecker, diff --git a/tests/test_func.py b/tests/test_func.py index 2de78c5d0f..207c9b8c9b 100644 --- a/tests/test_func.py +++ b/tests/test_func.py @@ -123,19 +123,17 @@ def gen_tests(filter_rgx): gen_tests(FILTER_RGX), ids=[o[0] for o in gen_tests(FILTER_RGX)], ) -def test_functionality(module_file, messages_file, dependencies, recwarn): +def test_functionality( + module_file, messages_file, dependencies, recwarn: pytest.WarningsRecorder +) -> None: __test_functionality(module_file, messages_file, dependencies) - warning = None - try: - # Catch :x: DeprecationWarning: invalid escape sequence - # so it's not shown during tests - warning = recwarn.pop() - except AssertionError: - pass - if warning is not None: + if recwarn.list: if module_file in TEST_WITH_EXPECTED_DEPRECATION and sys.version_info.minor > 5: - assert issubclass(warning.category, DeprecationWarning) - assert "invalid escape sequence" in str(warning.message) + assert any( + "invalid escape sequence" in str(i.message) + for i in recwarn.list + if issubclass(i.category, DeprecationWarning) + ) def __test_functionality( diff --git a/tests/test_functional.py b/tests/test_functional.py index b328af5fcc..14d2384d9f 100644 --- a/tests/test_functional.py +++ b/tests/test_functional.py @@ -53,20 +53,16 @@ def test_functional( lint_test = testutils.LintModuleTest(test_file, pytestconfig) lint_test.setUp() lint_test.runTest() - warning = None - try: - # Catch :x: DeprecationWarning: invalid escape sequence, - # so, it's not shown during tests - warning = recwarn.pop() - except AssertionError: - pass - if warning is not None: + if recwarn.list: if ( test_file.base in TEST_WITH_EXPECTED_DEPRECATION and sys.version_info.minor > 5 ): - assert issubclass(warning.category, DeprecationWarning) - assert "invalid escape sequence" in str(warning.message) + assert any( + "invalid escape sequence" in str(i.message) + for i in recwarn.list + if issubclass(i.category, DeprecationWarning) + ) if __name__ == "__main__": diff --git a/tests/test_regr.py b/tests/test_regr.py index dd0a27133f..4c7a64a93c 100644 --- a/tests/test_regr.py +++ b/tests/test_regr.py @@ -132,9 +132,9 @@ def test_pylint_config_attr() -> None: assert [c.name for c in pylinter.ancestors()] == expect assert list(astroid.Instance(pylinter).getattr("config")) inferred = list(astroid.Instance(pylinter).igetattr("config")) - assert len(inferred) == 1 - assert inferred[0].root().name == "optparse" - assert inferred[0].name == "Values" + assert len(inferred) >= 1 + assert inferred[0].root().name == "argparse" + assert inferred[0].name == "Namespace" @pytest.mark.timeout(30)