diff --git a/mkdocs/config/config_options.py b/mkdocs/config/config_options.py index d96999016a..8caf16ad5e 100644 --- a/mkdocs/config/config_options.py +++ b/mkdocs/config/config_options.py @@ -193,21 +193,33 @@ class Deprecated(BaseConfigOption): ConfigOption instance, then the value is validated against that type. """ - def __init__(self, moved_to=None, message='', option_type=None): + def __init__(self, moved_to=None, message=None, removed=False, option_type=None): super().__init__() self.default = None self.moved_to = moved_to - self.message = message or ( - 'The configuration option {} has been deprecated and ' - 'will be removed in a future release of MkDocs.' - ) + if not message: + if removed: + message = "The configuration option '{}' was removed from MkDocs." + else: + message = ( + "The configuration option '{}' has been deprecated and " + "will be removed in a future release of MkDocs." + ) + if moved_to: + message += f" Use '{moved_to}' instead." + + self.message = message + self.removed = removed self.option = option_type or BaseConfigOption() + self.warnings = self.option.warnings def pre_validation(self, config, key_name): self.option.pre_validation(config, key_name) if config.get(key_name) is not None: + if self.removed: + raise ValidationError(self.message.format(key_name)) self.warnings.append(self.message.format(key_name)) if self.moved_to is not None: @@ -566,16 +578,6 @@ def _repr_item(cls, value): else: return f"a {type(value).__name__}: {value!r}" - def post_validation(self, config, key_name): - # TODO: remove this when `pages` config setting is fully deprecated. - if key_name == 'pages' and config['pages'] is not None: - if config['nav'] is None: - # copy `pages` config to new 'nav' config setting - config['nav'] = config['pages'] - warning = ("The 'pages' configuration option has been deprecated and will " - "be removed in a future release of MkDocs. Use 'nav' instead.") - self.warnings.append(warning) - class Private(OptionallyRequired): """ diff --git a/mkdocs/config/defaults.py b/mkdocs/config/defaults.py index b3f6ebca02..95d3c44095 100644 --- a/mkdocs/config/defaults.py +++ b/mkdocs/config/defaults.py @@ -20,8 +20,7 @@ def get_schema(): # Defines the structure of the navigation. ('nav', config_options.Nav()), - # TODO: remove this when the `pages` config setting is fully deprecated. - ('pages', config_options.Nav()), + ('pages', config_options.Deprecated(removed=True, moved_to='nav')), # The full URL to where the documentation will be hosted ('site_url', config_options.URL(is_dir=True)), diff --git a/mkdocs/tests/config/config_options_tests.py b/mkdocs/tests/config/config_options_tests.py index 2dd93b389a..db01ba7869 100644 --- a/mkdocs/tests/config/config_options_tests.py +++ b/mkdocs/tests/config/config_options_tests.py @@ -125,6 +125,11 @@ def test_deprecated_option_with_invalid_type(self): with self.assertRaises(config_options.ValidationError): option.validate(config['d']) + def test_removed_option(self): + option = config_options.Deprecated(removed=True, moved_to='foo') + with self.assertRaises(config_options.ValidationError): + option.pre_validation({'d': 'value'}, 'd') + def test_deprecated_option_with_type_undefined(self): option = config_options.Deprecated(option_type=config_options.Type(str)) option.validate(None) diff --git a/mkdocs/tests/config/config_tests.py b/mkdocs/tests/config/config_tests.py index f20b1a81ec..295a9bd492 100644 --- a/mkdocs/tests/config/config_tests.py +++ b/mkdocs/tests/config/config_tests.py @@ -61,13 +61,13 @@ def test_config_option(self): """ expected_result = { 'site_name': 'Example', - 'pages': [ + 'nav': [ {'Introduction': 'index.md'} ], } file_contents = dedent(""" site_name: Example - pages: + nav: - 'Introduction': 'index.md' """) with TemporaryDirectory() as temp_path: @@ -81,7 +81,7 @@ def test_config_option(self): result = config.load_config(config_file=config_file.name) self.assertEqual(result['site_name'], expected_result['site_name']) - self.assertEqual(result['pages'], expected_result['pages']) + self.assertEqual(result['nav'], expected_result['nav']) def test_theme(self): with TemporaryDirectory() as mytheme, TemporaryDirectory() as custom: @@ -219,28 +219,19 @@ def test_empty_nav(self): conf.validate() self.assertEqual(conf['nav'], None) - def test_copy_pages_to_nav(self): - # TODO: remove this when pages config setting is fully deprecated. + def test_error_on_pages(self): conf = config.Config(schema=defaults.get_schema()) conf.load_dict({ 'site_name': 'Example', 'pages': ['index.md', 'about.md'], - 'config_file_path': os.path.join(os.path.abspath('.'), 'mkdocs.yml') - }) - conf.validate() - self.assertEqual(conf['nav'], ['index.md', 'about.md']) - - def test_dont_overwrite_nav_with_pages(self): - # TODO: remove this when pages config setting is fully deprecated. - conf = config.Config(schema=defaults.get_schema()) - conf.load_dict({ - 'site_name': 'Example', - 'pages': ['index.md', 'about.md'], - 'nav': ['foo.md', 'bar.md'], - 'config_file_path': os.path.join(os.path.abspath('.'), 'mkdocs.yml') }) - conf.validate() - self.assertEqual(conf['nav'], ['foo.md', 'bar.md']) + errors, warnings = conf.validate() + self.assertEqual(warnings, []) + self.assertEqual(len(errors), 1) + self.assertEqual( + str(errors[0][1]), + "The configuration option 'pages' was removed from MkDocs. Use 'nav' instead." + ) def test_doc_dir_in_site_dir(self):