We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Empty mkdocs_theme.yml breaks build
Hello! In the docs its [stated](https://www.mkdocs.org/dev-guide/themes/#theme-configuration) that a theme **can** have an empty `mkdocs_theme.yml` file:

> However, if the theme offers no configuration options, the file is still required and can be left blank.

Unfortunately this seems to have changed recently and now themes with empty `mkdocs_theme.yml` files are causing an exception when building:

```shell
> mkdocs build --verbose
DEBUG   -  Loading configuration file: ./mkdocs.yml
DEBUG   -  Loaded theme configuration for 'custom_theme' from
           './venv/lib/python3.12/site-packages/custom_theme/mkdocs_theme.yml':
           None
Traceback (most recent call last):
  [...]
  File "./venv/lib/python3.12/site-packages/mkdocs/config/config_options.py", line 868, in run_validation
    return theme.Theme(**theme_config)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "./venv/lib/python3.12/site-packages/mkdocs/theme.py", line 61, in __init__
    self._load_theme_config(name)
  File "./venv/lib/python3.12/site-packages/mkdocs/theme.py", line 143, in _load_theme_config
    if parent_theme := theme_config.pop('extends', None):
                       ^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'pop'
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mkdocs/theme.py`
Content:
```
1 from __future__ import annotations
2 
3 import logging
4 import os
5 import warnings
6 from typing import Any, Collection, MutableMapping
7 
8 import jinja2
9 import yaml
10 
11 try:
12     from yaml import CSafeLoader as SafeLoader
13 except ImportError:  # pragma: no cover
14     from yaml import SafeLoader  # type: ignore
15 
16 from mkdocs import localization, utils
17 from mkdocs.config.base import ValidationError
18 from mkdocs.utils import templates
19 
20 log = logging.getLogger(__name__)
21 
22 
23 class Theme(MutableMapping[str, Any]):
24     """
25     A Theme object.
26 
27     Args:
28         name: The name of the theme as defined by its entrypoint.
29         custom_dir: User defined directory for custom templates.
30         static_templates: A list of templates to render as static pages.
31 
32     All other keywords are passed as-is and made available as a key/value mapping.
33     """
34 
35     def __init__(
36         self,
37         name: str | None = None,
38         *,
39         custom_dir: str | None = None,
40         static_templates: Collection[str] = (),
41         locale: str | None = None,
42         **user_config,
43     ) -> None:
44         self.name = name
45         self._custom_dir = custom_dir
46         _vars: dict[str, Any] = {'name': name, 'locale': 'en'}
47         self.__vars = _vars
48 
49         # MkDocs provided static templates are always included
50         package_dir = os.path.abspath(os.path.dirname(__file__))
51         mkdocs_templates = os.path.join(package_dir, 'templates')
52         self.static_templates = set(os.listdir(mkdocs_templates))
53 
54         # Build self.dirs from various sources in order of precedence
55         self.dirs = []
56 
57         if custom_dir is not None:
58             self.dirs.append(custom_dir)
59 
60         if name:
61             self._load_theme_config(name)
62 
63         # Include templates provided directly by MkDocs (outside any theme)
64         self.dirs.append(mkdocs_templates)
65 
66         # Handle remaining user configs. Override theme configs (if set)
67         self.static_templates.update(static_templates)
68         _vars.update(user_config)
69 
70         # Validate locale and convert to Locale object
71         if locale is None:
72             locale = _vars['locale']
73         _vars['locale'] = localization.parse_locale(locale)
74 
75     name: str | None
76 
77     @property
78     def locale(self) -> localization.Locale:
79         return self['locale']
80 
81     @property
82     def custom_dir(self) -> str | None:
83         return self._custom_dir
84 
85     @property
86     def _vars(self) -> dict[str, Any]:
87         warnings.warn(
88             "Do not access Theme._vars, instead access the keys of Theme directly.",
89             DeprecationWarning,
90         )
91         return self.__vars
92 
93     dirs: list[str]
94 
95     static_templates: set[str]
96 
97     def __repr__(self) -> str:
98         return "{}(name={!r}, dirs={!r}, static_templates={!r}, {})".format(
99             self.__class__.__name__,
100             self.name,
101             self.dirs,
102             self.static_templates,
103             ', '.join(f'{k}={v!r}' for k, v in self.items()),
104         )
105 
106     def __getitem__(self, key: str) -> Any:
107         return self.__vars[key]
108 
109     def __setitem__(self, key: str, value):
110         self.__vars[key] = value
111 
112     def __delitem__(self, key: str):
113         del self.__vars[key]
114 
115     def __contains__(self, item: object) -> bool:
116         return item in self.__vars
117 
118     def __len__(self):
119         return len(self.__vars)
120 
121     def __iter__(self):
122         return iter(self.__vars)
123 
124     def _load_theme_config(self, name: str) -> None:
125         """Recursively load theme and any parent themes."""
126         theme_dir = utils.get_theme_dir(name)
127         utils.get_themes.cache_clear()
128         self.dirs.append(theme_dir)
129 
130         try:
131             file_path = os.path.join(theme_dir, 'mkdocs_theme.yml')
132             with open(file_path, 'rb') as f:
133                 theme_config = yaml.load(f, SafeLoader)
134         except OSError as e:
135             log.debug(e)
136             raise ValidationError(
137                 f"The theme '{name}' does not appear to have a configuration file. "
138                 f"Please upgrade to a current version of the theme."
139             )
140 
141         log.debug(f"Loaded theme configuration for '{name}' from '{file_path}': {theme_config}")
142 
143         if parent_theme := theme_config.pop('extends', None):
144             themes = utils.get_theme_names()
145             if parent_theme not in themes:
146                 raise ValidationError(
147                     f"The theme '{name}' inherits from '{parent_theme}', which does not appear to be installed. "
148                     f"The available installed themes are: {', '.join(themes)}"
149                 )
150             self._load_theme_config(parent_theme)
151 
152         self.static_templates.update(theme_config.pop('static_templates', []))
153         self.__vars.update(theme_config)
154 
155     def get_env(self) -> jinja2.Environment:
156         """Return a Jinja environment for the theme."""
157         loader = jinja2.FileSystemLoader(self.dirs)
158         # No autoreload because editing a template in the middle of a build is not useful.
159         env = jinja2.Environment(loader=loader, auto_reload=False)
160         env.filters['url'] = templates.url_filter
161         env.filters['script_tag'] = templates.script_tag_filter
162         localization.install_translations(env, self.locale, self.dirs)
163         return env
164
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mkdocs/theme.py b/mkdocs/theme.py
--- a/mkdocs/theme.py
+++ b/mkdocs/theme.py
@@ -138,6 +138,9 @@
                 f"Please upgrade to a current version of the theme."
             )
 
+        if theme_config is None:
+            theme_config = {}
+
         log.debug(f"Loaded theme configuration for '{name}' from '{file_path}': {theme_config}")
 
         if parent_theme := theme_config.pop('extends', None):

{"golden_diff": "diff --git a/mkdocs/theme.py b/mkdocs/theme.py\n--- a/mkdocs/theme.py\n+++ b/mkdocs/theme.py\n@@ -138,6 +138,9 @@\n                 f\"Please upgrade to a current version of the theme.\"\n             )\n \n+        if theme_config is None:\n+            theme_config = {}\n+\n         log.debug(f\"Loaded theme configuration for '{name}' from '{file_path}': {theme_config}\")\n \n         if parent_theme := theme_config.pop('extends', None):\n", "issue": "Empty mkdocs_theme.yml breaks build\nHello! In the docs its [stated](https://www.mkdocs.org/dev-guide/themes/#theme-configuration) that a theme **can** have an empty `mkdocs_theme.yml` file:\r\n\r\n> However, if the theme offers no configuration options, the file is still required and can be left blank.\r\n\r\nUnfortunately this seems to have changed recently and now themes with empty `mkdocs_theme.yml` files are causing an exception when building:\r\n\r\n```shell\r\n> mkdocs build --verbose\r\nDEBUG   -  Loading configuration file: ./mkdocs.yml\r\nDEBUG   -  Loaded theme configuration for 'custom_theme' from\r\n           './venv/lib/python3.12/site-packages/custom_theme/mkdocs_theme.yml':\r\n           None\r\nTraceback (most recent call last):\r\n  [...]\r\n  File \"./venv/lib/python3.12/site-packages/mkdocs/config/config_options.py\", line 868, in run_validation\r\n    return theme.Theme(**theme_config)\r\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n  File \"./venv/lib/python3.12/site-packages/mkdocs/theme.py\", line 61, in __init__\r\n    self._load_theme_config(name)\r\n  File \"./venv/lib/python3.12/site-packages/mkdocs/theme.py\", line 143, in _load_theme_config\r\n    if parent_theme := theme_config.pop('extends', None):\r\n                       ^^^^^^^^^^^^^^^^\r\nAttributeError: 'NoneType' object has no attribute 'pop'\r\n```\r\n\n", "before_files": [{"content": "from __future__ import annotations\n\nimport logging\nimport os\nimport warnings\nfrom typing import Any, Collection, MutableMapping\n\nimport jinja2\nimport yaml\n\ntry:\n    from yaml import CSafeLoader as SafeLoader\nexcept ImportError:  # pragma: no cover\n    from yaml import SafeLoader  # type: ignore\n\nfrom mkdocs import localization, utils\nfrom mkdocs.config.base import ValidationError\nfrom mkdocs.utils import templates\n\nlog = logging.getLogger(__name__)\n\n\nclass Theme(MutableMapping[str, Any]):\n    \"\"\"\n    A Theme object.\n\n    Args:\n        name: The name of the theme as defined by its entrypoint.\n        custom_dir: User defined directory for custom templates.\n        static_templates: A list of templates to render as static pages.\n\n    All other keywords are passed as-is and made available as a key/value mapping.\n    \"\"\"\n\n    def __init__(\n        self,\n        name: str | None = None,\n        *,\n        custom_dir: str | None = None,\n        static_templates: Collection[str] = (),\n        locale: str | None = None,\n        **user_config,\n    ) -> None:\n        self.name = name\n        self._custom_dir = custom_dir\n        _vars: dict[str, Any] = {'name': name, 'locale': 'en'}\n        self.__vars = _vars\n\n        # MkDocs provided static templates are always included\n        package_dir = os.path.abspath(os.path.dirname(__file__))\n        mkdocs_templates = os.path.join(package_dir, 'templates')\n        self.static_templates = set(os.listdir(mkdocs_templates))\n\n        # Build self.dirs from various sources in order of precedence\n        self.dirs = []\n\n        if custom_dir is not None:\n            self.dirs.append(custom_dir)\n\n        if name:\n            self._load_theme_config(name)\n\n        # Include templates provided directly by MkDocs (outside any theme)\n        self.dirs.append(mkdocs_templates)\n\n        # Handle remaining user configs. Override theme configs (if set)\n        self.static_templates.update(static_templates)\n        _vars.update(user_config)\n\n        # Validate locale and convert to Locale object\n        if locale is None:\n            locale = _vars['locale']\n        _vars['locale'] = localization.parse_locale(locale)\n\n    name: str | None\n\n    @property\n    def locale(self) -> localization.Locale:\n        return self['locale']\n\n    @property\n    def custom_dir(self) -> str | None:\n        return self._custom_dir\n\n    @property\n    def _vars(self) -> dict[str, Any]:\n        warnings.warn(\n            \"Do not access Theme._vars, instead access the keys of Theme directly.\",\n            DeprecationWarning,\n        )\n        return self.__vars\n\n    dirs: list[str]\n\n    static_templates: set[str]\n\n    def __repr__(self) -> str:\n        return \"{}(name={!r}, dirs={!r}, static_templates={!r}, {})\".format(\n            self.__class__.__name__,\n            self.name,\n            self.dirs,\n            self.static_templates,\n            ', '.join(f'{k}={v!r}' for k, v in self.items()),\n        )\n\n    def __getitem__(self, key: str) -> Any:\n        return self.__vars[key]\n\n    def __setitem__(self, key: str, value):\n        self.__vars[key] = value\n\n    def __delitem__(self, key: str):\n        del self.__vars[key]\n\n    def __contains__(self, item: object) -> bool:\n        return item in self.__vars\n\n    def __len__(self):\n        return len(self.__vars)\n\n    def __iter__(self):\n        return iter(self.__vars)\n\n    def _load_theme_config(self, name: str) -> None:\n        \"\"\"Recursively load theme and any parent themes.\"\"\"\n        theme_dir = utils.get_theme_dir(name)\n        utils.get_themes.cache_clear()\n        self.dirs.append(theme_dir)\n\n        try:\n            file_path = os.path.join(theme_dir, 'mkdocs_theme.yml')\n            with open(file_path, 'rb') as f:\n                theme_config = yaml.load(f, SafeLoader)\n        except OSError as e:\n            log.debug(e)\n            raise ValidationError(\n                f\"The theme '{name}' does not appear to have a configuration file. \"\n                f\"Please upgrade to a current version of the theme.\"\n            )\n\n        log.debug(f\"Loaded theme configuration for '{name}' from '{file_path}': {theme_config}\")\n\n        if parent_theme := theme_config.pop('extends', None):\n            themes = utils.get_theme_names()\n            if parent_theme not in themes:\n                raise ValidationError(\n                    f\"The theme '{name}' inherits from '{parent_theme}', which does not appear to be installed. \"\n                    f\"The available installed themes are: {', '.join(themes)}\"\n                )\n            self._load_theme_config(parent_theme)\n\n        self.static_templates.update(theme_config.pop('static_templates', []))\n        self.__vars.update(theme_config)\n\n    def get_env(self) -> jinja2.Environment:\n        \"\"\"Return a Jinja environment for the theme.\"\"\"\n        loader = jinja2.FileSystemLoader(self.dirs)\n        # No autoreload because editing a template in the middle of a build is not useful.\n        env = jinja2.Environment(loader=loader, auto_reload=False)\n        env.filters['url'] = templates.url_filter\n        env.filters['script_tag'] = templates.script_tag_filter\n        localization.install_translations(env, self.locale, self.dirs)\n        return env\n", "path": "mkdocs/theme.py"}], "after_files": [{"content": "from __future__ import annotations\n\nimport logging\nimport os\nimport warnings\nfrom typing import Any, Collection, MutableMapping\n\nimport jinja2\nimport yaml\n\ntry:\n    from yaml import CSafeLoader as SafeLoader\nexcept ImportError:  # pragma: no cover\n    from yaml import SafeLoader  # type: ignore\n\nfrom mkdocs import localization, utils\nfrom mkdocs.config.base import ValidationError\nfrom mkdocs.utils import templates\n\nlog = logging.getLogger(__name__)\n\n\nclass Theme(MutableMapping[str, Any]):\n    \"\"\"\n    A Theme object.\n\n    Args:\n        name: The name of the theme as defined by its entrypoint.\n        custom_dir: User defined directory for custom templates.\n        static_templates: A list of templates to render as static pages.\n\n    All other keywords are passed as-is and made available as a key/value mapping.\n    \"\"\"\n\n    def __init__(\n        self,\n        name: str | None = None,\n        *,\n        custom_dir: str | None = None,\n        static_templates: Collection[str] = (),\n        locale: str | None = None,\n        **user_config,\n    ) -> None:\n        self.name = name\n        self._custom_dir = custom_dir\n        _vars: dict[str, Any] = {'name': name, 'locale': 'en'}\n        self.__vars = _vars\n\n        # MkDocs provided static templates are always included\n        package_dir = os.path.abspath(os.path.dirname(__file__))\n        mkdocs_templates = os.path.join(package_dir, 'templates')\n        self.static_templates = set(os.listdir(mkdocs_templates))\n\n        # Build self.dirs from various sources in order of precedence\n        self.dirs = []\n\n        if custom_dir is not None:\n            self.dirs.append(custom_dir)\n\n        if name:\n            self._load_theme_config(name)\n\n        # Include templates provided directly by MkDocs (outside any theme)\n        self.dirs.append(mkdocs_templates)\n\n        # Handle remaining user configs. Override theme configs (if set)\n        self.static_templates.update(static_templates)\n        _vars.update(user_config)\n\n        # Validate locale and convert to Locale object\n        if locale is None:\n            locale = _vars['locale']\n        _vars['locale'] = localization.parse_locale(locale)\n\n    name: str | None\n\n    @property\n    def locale(self) -> localization.Locale:\n        return self['locale']\n\n    @property\n    def custom_dir(self) -> str | None:\n        return self._custom_dir\n\n    @property\n    def _vars(self) -> dict[str, Any]:\n        warnings.warn(\n            \"Do not access Theme._vars, instead access the keys of Theme directly.\",\n            DeprecationWarning,\n        )\n        return self.__vars\n\n    dirs: list[str]\n\n    static_templates: set[str]\n\n    def __repr__(self) -> str:\n        return \"{}(name={!r}, dirs={!r}, static_templates={!r}, {})\".format(\n            self.__class__.__name__,\n            self.name,\n            self.dirs,\n            self.static_templates,\n            ', '.join(f'{k}={v!r}' for k, v in self.items()),\n        )\n\n    def __getitem__(self, key: str) -> Any:\n        return self.__vars[key]\n\n    def __setitem__(self, key: str, value):\n        self.__vars[key] = value\n\n    def __delitem__(self, key: str):\n        del self.__vars[key]\n\n    def __contains__(self, item: object) -> bool:\n        return item in self.__vars\n\n    def __len__(self):\n        return len(self.__vars)\n\n    def __iter__(self):\n        return iter(self.__vars)\n\n    def _load_theme_config(self, name: str) -> None:\n        \"\"\"Recursively load theme and any parent themes.\"\"\"\n        theme_dir = utils.get_theme_dir(name)\n        utils.get_themes.cache_clear()\n        self.dirs.append(theme_dir)\n\n        try:\n            file_path = os.path.join(theme_dir, 'mkdocs_theme.yml')\n            with open(file_path, 'rb') as f:\n                theme_config = yaml.load(f, SafeLoader)\n        except OSError as e:\n            log.debug(e)\n            raise ValidationError(\n                f\"The theme '{name}' does not appear to have a configuration file. \"\n                f\"Please upgrade to a current version of the theme.\"\n            )\n\n        if theme_config is None:\n            theme_config = {}\n\n        log.debug(f\"Loaded theme configuration for '{name}' from '{file_path}': {theme_config}\")\n\n        if parent_theme := theme_config.pop('extends', None):\n            themes = utils.get_theme_names()\n            if parent_theme not in themes:\n                raise ValidationError(\n                    f\"The theme '{name}' inherits from '{parent_theme}', which does not appear to be installed. \"\n                    f\"The available installed themes are: {', '.join(themes)}\"\n                )\n            self._load_theme_config(parent_theme)\n\n        self.static_templates.update(theme_config.pop('static_templates', []))\n        self.__vars.update(theme_config)\n\n    def get_env(self) -> jinja2.Environment:\n        \"\"\"Return a Jinja environment for the theme.\"\"\"\n        loader = jinja2.FileSystemLoader(self.dirs)\n        # No autoreload because editing a template in the middle of a build is not useful.\n        env = jinja2.Environment(loader=loader, auto_reload=False)\n        env.filters['url'] = templates.url_filter\n        env.filters['script_tag'] = templates.script_tag_filter\n        localization.install_translations(env, self.locale, self.dirs)\n        return env\n", "path": "mkdocs/theme.py"}]}