-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Expand file tree
/
Copy pathcompat.py
More file actions
50 lines (38 loc) · 1.46 KB
/
compat.py
File metadata and controls
50 lines (38 loc) · 1.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
"""Compatibility hacks and helpers."""
import sys
from collections.abc import Mapping
from typing import Any
async def windows_hot_reload_lifespan_hack():
"""[REF-3164] A hack to fix hot reload on Windows.
Uvicorn has an issue stopping itself on Windows after detecting changes in
the filesystem.
This workaround repeatedly prints and flushes null characters to stderr,
which seems to allow the uvicorn server to exit when the CTRL-C signal is
sent from the reloader process.
Don't ask me why this works, I discovered it by accident - masenf.
"""
import asyncio
import sys
try:
while True:
sys.stderr.write("\0")
sys.stderr.flush()
await asyncio.sleep(0.5)
except asyncio.CancelledError:
pass
def annotations_from_namespace(namespace: Mapping[str, Any]) -> dict[str, Any]:
"""Get the annotations from a class namespace.
Args:
namespace: The class namespace.
Returns:
The (forward-ref) annotations from the class namespace.
"""
if sys.version_info >= (3, 14) and "__annotations__" not in namespace:
from annotationlib import (
Format,
call_annotate_function,
get_annotate_from_class_namespace,
)
if annotate := get_annotate_from_class_namespace(namespace):
return call_annotate_function(annotate, format=Format.FORWARDREF)
return namespace.get("__annotations__", {})