Skip to content

Commit f022131

Browse files
committed
imprv: Generator: Add deprecations
1 parent 7e1758c commit f022131

File tree

2 files changed

+70
-5
lines changed

2 files changed

+70
-5
lines changed

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ authors = [
1414
{email = "[email protected]"},
1515
{name = "Christoph Reiter"}
1616
]
17+
dependencies = [
18+
# for @deprecated decorator
19+
'typing_extensions>="4.5.0"; python_version<"3.13"',
20+
]
1721
classifiers = [
1822
"Programming Language :: Python :: 3",
1923
"Intended Audience :: Developers",

tools/generate.py

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from typing import Any
1010
from typing import Callable
11+
from typing import cast
1112
from typing import Optional
1213
from typing import Tuple
1314
from typing import Type
@@ -20,6 +21,7 @@
2021
import pprint
2122
import re
2223
import textwrap
24+
import xml.etree.ElementTree as ET
2325
from types import ModuleType
2426

2527
import gi
@@ -34,6 +36,8 @@
3436

3537
ObjectT = Union[ModuleType, Type[Any]]
3638

39+
DEPRECATION_DOCS: dict[str, str] = {}
40+
3741

3842
def _object_get_props(
3943
obj: GI.ObjectInfo,
@@ -339,9 +343,16 @@ def _build(parent: ObjectT, namespace: str, overrides: dict[str, str]) -> str:
339343
typings = "from typing import Any, Callable, Literal, Optional, Tuple, Type, TypeVar, Sequence"
340344

341345
typevars: list[str] = []
342-
imports: list[str] = []
346+
imports: list[str] = [
347+
"""
348+
try:
349+
from warnings import deprecated
350+
except ImportError:
351+
from typing_extensions import deprecated
352+
"""
353+
]
343354
if "cairo" in ns:
344-
imports = ["import cairo"]
355+
imports += ["import cairo"]
345356
typevars.append('_SomeSurface = TypeVar("_SomeSurface", bound=cairo.Surface)')
346357
ns.remove("cairo")
347358

@@ -368,7 +379,7 @@ def _generate_full_name(prefix: str, name: str) -> str:
368379
def _build_function_info(
369380
current_namespace: str,
370381
name: str,
371-
function: (GI.FunctionInfo | GI.VFuncInfo),
382+
function: GI.FunctionInfo | GI.VFuncInfo,
372383
in_class: Optional[Any],
373384
needed_namespaces: set[str],
374385
return_signature: Optional[str] = None,
@@ -601,6 +612,21 @@ def _gi_build_stub(
601612

602613
# Functions
603614
for name in sorted(functions):
615+
if hasattr(functions[name], "is_deprecated"):
616+
deprecated = functions[name].is_deprecated()
617+
if deprecated:
618+
full_name = _generate_full_name(prefix_name, name)
619+
message = (
620+
functions[name].get_attribute("deprecated")
621+
or (
622+
DEPRECATION_DOCS[full_name]
623+
if full_name in DEPRECATION_DOCS
624+
else None
625+
)
626+
or f"This {'method' if in_class else 'function'} is deprecated"
627+
)
628+
ret += f'@deprecated("{message}")\n'
629+
604630
override = _check_override(prefix_name, name, overrides)
605631
if override:
606632
ret += override + "\n"
@@ -615,13 +641,27 @@ def _gi_build_stub(
615641

616642
# Classes
617643
for name, obj in sorted(classes.items()):
644+
full_name = _generate_full_name(prefix_name, name)
645+
646+
if hasattr(obj, "__info__") and hasattr(obj.__info__, "is_deprecated"):
647+
deprecated = obj.__info__.is_deprecated()
648+
if deprecated:
649+
message = (
650+
obj.__info__.get_attribute("deprecated")
651+
or (
652+
DEPRECATION_DOCS[full_name]
653+
if full_name in DEPRECATION_DOCS
654+
else None
655+
)
656+
or f"This class is deprecated"
657+
)
658+
ret += f'@deprecated("{message}")\n'
659+
618660
override = _check_override(prefix_name, name, overrides)
619661
if override:
620662
ret += override + "\n\n"
621663
continue
622664

623-
full_name = _generate_full_name(prefix_name, name)
624-
625665
classret = _gi_build_stub(
626666
obj,
627667
current_namespace,
@@ -940,6 +980,27 @@ def start(module: str, version: str, overrides: dict[str, str]) -> str:
940980

941981
args = parser.parse_args()
942982

983+
ns = {
984+
"core": "http://www.gtk.org/introspection/core/1.0",
985+
"c": "http://www.gtk.org/introspection/c/1.0",
986+
"glib": "http://www.gtk.org/introspection/glib/1.0",
987+
}
988+
gir_tree = ET.parse(f"/usr/share/gir-1.0/{args.module}-{args.version}.gir")
989+
gir_root = gir_tree.getroot()
990+
gir_parent_map = {c: p for p in gir_tree.iter() for c in p}
991+
for child in gir_root.iterfind(".//core:doc-deprecated", ns):
992+
parents: list[str] = []
993+
parent = gir_parent_map[child]
994+
while True:
995+
try:
996+
parents.insert(0, parent.attrib["name"])
997+
except KeyError:
998+
break
999+
parent = gir_parent_map[parent]
1000+
DEPRECATION_DOCS[".".join(parents[1:])] = (
1001+
cast(str, child.text).replace("\n", "").replace('"', '\\"')
1002+
)
1003+
9431004
if args.output:
9441005
overrides: dict[str, str] = {}
9451006
try:

0 commit comments

Comments
 (0)