Move forward with some deprecations (#3425)

This commit is contained in:
Oleh Prypin
2023-10-16 22:32:08 +02:00
committed by GitHub
parent 44e6536060
commit b3992222b1
4 changed files with 32 additions and 104 deletions

View File

@@ -18,7 +18,6 @@ import threading
import time
import traceback
import urllib.parse
import warnings
import wsgiref.simple_server
import wsgiref.util
from typing import Any, BinaryIO, Callable, Iterable
@@ -119,10 +118,8 @@ class LiveReloadServer(socketserver.ThreadingMixIn, wsgiref.simple_server.WSGISe
self._visible_epoch = self._wanted_epoch # Latest fully built version of the site.
self._epoch_cond = threading.Condition() # Must be held when accessing _visible_epoch.
self._to_rebuild: dict[
Callable[[], None], bool
] = {} # Used as an ordered set of functions to call.
self._rebuild_cond = threading.Condition() # Must be held when accessing _to_rebuild.
self._want_rebuild: bool = False
self._rebuild_cond = threading.Condition() # Must be held when accessing _want_rebuild.
self._shutdown = False
self.serve_thread = threading.Thread(target=lambda: self.serve_forever(shutdown_delay))
@@ -131,21 +128,11 @@ class LiveReloadServer(socketserver.ThreadingMixIn, wsgiref.simple_server.WSGISe
self._watched_paths: dict[str, int] = {}
self._watch_refs: dict[str, Any] = {}
def watch(
self, path: str, func: Callable[[], None] | None = None, recursive: bool = True
) -> None:
def watch(self, path: str, func: None = None, *, recursive: bool = True) -> None:
"""Add the 'path' to watched paths, call the function and reload when any file changes under it."""
path = os.path.abspath(path)
if func is None or func is self.builder:
funct = self.builder
else:
funct = func
warnings.warn(
"Plugins should not pass the 'func' parameter of watch(). "
"The ability to execute custom callbacks will be removed soon.",
DeprecationWarning,
stacklevel=2,
)
if not (func is None or func is self.builder): # type: ignore[unreachable]
raise TypeError("Plugins can no longer pass a 'func' parameter to watch().")
if path in self._watched_paths:
self._watched_paths[path] += 1
@@ -157,7 +144,7 @@ class LiveReloadServer(socketserver.ThreadingMixIn, wsgiref.simple_server.WSGISe
return
log.debug(str(event))
with self._rebuild_cond:
self._to_rebuild[funct] = True
self._want_rebuild = True
self._rebuild_cond.notify_all()
handler = watchdog.events.FileSystemEventHandler()
@@ -193,7 +180,7 @@ class LiveReloadServer(socketserver.ThreadingMixIn, wsgiref.simple_server.WSGISe
while True:
with self._rebuild_cond:
while not self._rebuild_cond.wait_for(
lambda: self._to_rebuild or self._shutdown, timeout=self.shutdown_delay
lambda: self._want_rebuild or self._shutdown, timeout=self.shutdown_delay
):
# We could have used just one wait instead of a loop + timeout, but we need
# occasional breaks, otherwise on Windows we can't receive KeyboardInterrupt.
@@ -205,12 +192,10 @@ class LiveReloadServer(socketserver.ThreadingMixIn, wsgiref.simple_server.WSGISe
log.debug("Waiting for file changes to stop happening")
self._wanted_epoch = _timestamp()
funcs = list(self._to_rebuild)
self._to_rebuild.clear()
self._want_rebuild = False
try:
for func in funcs:
func()
self.builder()
except Exception as e:
if isinstance(e, SystemExit):
print(e, file=sys.stderr) # noqa: T201

View File

@@ -181,28 +181,6 @@ class BuildTests(unittest.TestCase):
with self.assertRaises(KeyError):
server.unwatch(site_dir)
@tempdir({"foo.docs": "a"})
@tempdir({"foo.site": "original"})
def test_custom_action_warns(self, site_dir, docs_dir):
started_building = threading.Event()
def rebuild():
started_building.set()
content = Path(docs_dir, "foo.docs").read_text()
Path(site_dir, "foo.site").write_text(content * 5)
with testing_server(site_dir) as server:
with self.assertWarnsRegex(DeprecationWarning, "func") as cm:
server.watch(docs_dir, rebuild)
time.sleep(0.01)
self.assertIn("livereload_tests.py", cm.filename)
Path(docs_dir, "foo.docs").write_text("b")
self.assertTrue(started_building.wait(timeout=10))
_, output = do_request(server, "GET /foo.site")
self.assertEqual(output, "bbbbb")
@tempdir({"foo.docs": "docs1"})
@tempdir({"foo.extra": "extra1"})
@tempdir({"foo.site": "original"})

View File

@@ -2,6 +2,7 @@ from __future__ import annotations
import logging
import os
import warnings
from typing import Any, Collection, MutableMapping
import jinja2
@@ -37,8 +38,7 @@ class Theme(MutableMapping[str, Any]):
self.name = name
self._custom_dir = custom_dir
_vars: dict[str, Any] = {'name': name, 'locale': 'en'}
# _vars is soft-deprecated, intentionally hide it from mypy.
setattr(self, '_vars', _vars)
self.__vars = _vars
# MkDocs provided static templates are always included
package_dir = os.path.abspath(os.path.dirname(__file__))
@@ -62,9 +62,9 @@ class Theme(MutableMapping[str, Any]):
_vars.update(user_config)
# Validate locale and convert to Locale object
_vars['locale'] = localization.parse_locale(
locale if locale is not None else _vars['locale']
)
if locale is None:
locale = _vars['locale']
_vars['locale'] = localization.parse_locale(locale)
name: str | None
@@ -76,6 +76,14 @@ class Theme(MutableMapping[str, Any]):
def custom_dir(self) -> str | None:
return self._custom_dir
@property
def _vars(self) -> dict[str, Any]:
warnings.warn(
"Do not access Theme._vars, instead access the keys of Theme directly.",
DeprecationWarning,
)
return self.__vars
dirs: list[str]
static_templates: set[str]
@@ -90,22 +98,22 @@ class Theme(MutableMapping[str, Any]):
)
def __getitem__(self, key: str) -> Any:
return self._vars[key] # type: ignore[attr-defined]
return self.__vars[key]
def __setitem__(self, key: str, value):
self._vars[key] = value # type: ignore[attr-defined]
self.__vars[key] = value
def __delitem__(self, key: str):
del self._vars[key] # type: ignore[attr-defined]
del self.__vars[key]
def __contains__(self, item: object) -> bool:
return item in self._vars # type: ignore[attr-defined]
return item in self.__vars
def __len__(self):
return len(self._vars) # type: ignore[attr-defined]
return len(self.__vars)
def __iter__(self):
return iter(self._vars) # type: ignore[attr-defined]
return iter(self.__vars)
def _load_theme_config(self, name: str) -> None:
"""Recursively load theme and any parent themes."""
@@ -137,7 +145,7 @@ class Theme(MutableMapping[str, Any]):
self._load_theme_config(parent_theme)
self.static_templates.update(theme_config.pop('static_templates', []))
self._vars.update(theme_config) # type: ignore[attr-defined]
self.__vars.update(theme_config)
def get_env(self) -> jinja2.Environment:
"""Return a Jinja environment for the theme."""

View File

@@ -44,16 +44,6 @@ markdown_extensions = (
)
def modified_time(file_path):
warnings.warn(
"modified_time is never used in MkDocs and will be removed soon.", DeprecationWarning
)
if os.path.exists(file_path):
return os.path.getmtime(file_path)
else:
return 0.0
def get_build_timestamp() -> int:
"""
Returns the number of seconds since the epoch.
@@ -162,27 +152,6 @@ def clean_directory(directory: str) -> None:
os.unlink(path)
def get_html_path(path):
warnings.warn(
"get_html_path is never used in MkDocs and will be removed soon.", DeprecationWarning
)
path = os.path.splitext(path)[0]
if os.path.basename(path) == 'index':
return path + '.html'
return "/".join((path, 'index.html'))
def get_url_path(path, use_directory_urls=True):
warnings.warn(
"get_url_path is never used in MkDocs and will be removed soon.", DeprecationWarning
)
path = get_html_path(path)
url = '/' + path.replace(os.sep, '/')
if use_directory_urls:
return url[: -len('index.html')]
return url
def is_markdown_file(path: str) -> bool:
"""
Return True if the given file path is a Markdown file.
@@ -192,20 +161,6 @@ def is_markdown_file(path: str) -> bool:
return path.endswith(markdown_extensions)
def is_html_file(path):
warnings.warn(
"is_html_file is never used in MkDocs and will be removed soon.", DeprecationWarning
)
return path.lower().endswith(('.html', '.htm'))
def is_template_file(path):
warnings.warn(
"is_template_file is never used in MkDocs and will be removed soon.", DeprecationWarning
)
return path.lower().endswith(('.html', '.htm', '.xml'))
_ERROR_TEMPLATE_RE = re.compile(r'^\d{3}\.html?$')
@@ -297,7 +252,9 @@ def create_media_urls(
def path_to_url(path):
"""Soft-deprecated, do not use."""
warnings.warn(
"path_to_url is never used in MkDocs and will be removed soon.", DeprecationWarning
)
return path.replace('\\', '/')