move+rename deprecated decorators to _legacy.py

+ take method instead of string, so we can ensure symbol exists
This commit is contained in:
Damien Elmes 2021-06-26 15:50:07 +10:00
parent fee486aaa1
commit 1cabe9507c
3 changed files with 28 additions and 30 deletions

View File

@ -3,7 +3,7 @@
from __future__ import annotations from __future__ import annotations
from typing import Any, Callable, Dict, Tuple, Union from typing import Any, Callable, Dict, Optional, Tuple, Union
import stringcase import stringcase
@ -41,3 +41,23 @@ class DeprecatedNamesMixin:
are valid symbols, and we can't get a variable's name easily. are valid symbols, and we can't get a variable's name easily.
""" """
cls._deprecated_aliases = {k: _target_to_string(v) for k, v in kwargs.items()} cls._deprecated_aliases = {k: _target_to_string(v) for k, v in kwargs.items()}
def deprecated(replaced_by: Optional[Callable] = None, info: str = "") -> Callable:
"""Print a deprecation warning, telling users to use `replaced_by`, or show `doc`."""
def decorator(func: Callable) -> Callable:
def decorated_func(*args: Any, **kwargs: Any) -> Any:
if replaced_by:
doc = f"please use {replaced_by.__name__} instead."
else:
doc = info
print(
f"'{func.__name__}' is deprecated, and will be removed in the future: ",
doc,
)
return func(*args, **kwargs)
return decorated_func
return decorator

View File

@ -11,11 +11,12 @@ from typing import Any, Dict, Iterable, List, NewType, Optional, Sequence, Tuple
import anki # pylint: disable=unused-import import anki # pylint: disable=unused-import
import anki._backend.backend_pb2 as _pb import anki._backend.backend_pb2 as _pb
from anki._legacy import deprecated
from anki.cards import CardId from anki.cards import CardId
from anki.collection import OpChanges, OpChangesWithCount, OpChangesWithId from anki.collection import OpChanges, OpChangesWithCount, OpChangesWithId
from anki.consts import * from anki.consts import *
from anki.errors import NotFoundError from anki.errors import NotFoundError
from anki.utils import from_json_bytes, ids2str, intTime, legacy_func, to_json_bytes from anki.utils import from_json_bytes, ids2str, intTime, to_json_bytes
# public exports # public exports
DeckTreeNode = _pb.DeckTreeNode DeckTreeNode = _pb.DeckTreeNode
@ -142,7 +143,10 @@ class DeckManager:
out = self.add_deck_legacy(deck) out = self.add_deck_legacy(deck)
return DeckId(out.id) return DeckId(out.id)
@legacy_func(sub="remove") def remove(self, dids: Sequence[DeckId]) -> OpChangesWithCount:
return self.col._backend.remove_decks(dids)
@deprecated(replaced_by=remove)
def rem(self, did: DeckId, cardsToo: bool = True, childrenToo: bool = True) -> None: def rem(self, did: DeckId, cardsToo: bool = True, childrenToo: bool = True) -> None:
"Remove the deck. If cardsToo, delete any cards inside." "Remove the deck. If cardsToo, delete any cards inside."
if isinstance(did, str): if isinstance(did, str):
@ -150,9 +154,6 @@ class DeckManager:
assert cardsToo and childrenToo assert cardsToo and childrenToo
self.remove([did]) self.remove([did])
def remove(self, dids: Sequence[DeckId]) -> OpChangesWithCount:
return self.col._backend.remove_decks(dids)
def all_names_and_ids( def all_names_and_ids(
self, skip_empty_default: bool = False, include_filtered: bool = True self, skip_empty_default: bool = False, include_filtered: bool = True
) -> Sequence[DeckNameId]: ) -> Sequence[DeckNameId]:

View File

@ -18,7 +18,7 @@ import traceback
from contextlib import contextmanager from contextlib import contextmanager
from hashlib import sha1 from hashlib import sha1
from html.entities import name2codepoint from html.entities import name2codepoint
from typing import Any, Callable, Iterable, Iterator, List, Match, Optional, Union from typing import Any, Iterable, Iterator, List, Match, Optional, Union
from anki.dbproxy import DBProxy from anki.dbproxy import DBProxy
@ -372,26 +372,3 @@ def pointVersion() -> int:
from anki.buildinfo import version from anki.buildinfo import version
return int(version.split(".")[-1]) return int(version.split(".")[-1])
# Legacy support
##############################################################################
def legacy_func(sub: Optional[str] = None) -> Callable:
"""Print a deprecation warning for the decorated callable recommending the use of
'sub' instead, if provided.
"""
if sub:
hint = f", use '{sub}' instead"
else:
hint = ""
def decorator(func: Callable) -> Callable:
def decorated_func(*args: Any, **kwargs: Any) -> Any:
print(f"'{func.__name__}' is deprecated{hint}.")
return func(*args, **kwargs)
return decorated_func
return decorator