add Dict suffix to Dict aliases in models.py

This commit is contained in:
Damien Elmes 2021-03-27 21:46:49 +10:00
parent 9f4a06abee
commit 716b474314
12 changed files with 95 additions and 87 deletions

View File

@ -11,7 +11,7 @@ import anki # pylint: disable=unused-import
import anki._backend.backend_pb2 as _pb
from anki import hooks
from anki.consts import *
from anki.models import NoteType, Template
from anki.models import NotetypeDict, TemplateDict
from anki.notes import Note
from anki.sound import AVTag
@ -148,7 +148,7 @@ class Card:
self._note = self.col.get_note(self.nid)
return self._note
def note_type(self) -> NoteType:
def note_type(self) -> NotetypeDict:
return self.col.models.get(self.note().mid)
# legacy aliases
@ -157,7 +157,7 @@ class Card:
a = answer
model = note_type
def template(self) -> Template:
def template(self) -> TemplateDict:
m = self.model()
if m["type"] == MODEL_STD:
return self.model()["tmpls"][self.ord]

View File

@ -42,7 +42,7 @@ from anki.decks import DeckId, DeckManager
from anki.errors import AnkiError, DBError
from anki.lang import FormatTimeSpan
from anki.media import MediaManager, media_paths_from_col_path
from anki.models import ModelManager, NoteType, NoteTypeId
from anki.models import ModelManager, NotetypeDict, NoteTypeId
from anki.notes import Note, NoteId
from anki.scheduler.v1 import Scheduler as V1Scheduler
from anki.scheduler.v2 import Scheduler as V2Scheduler
@ -365,7 +365,7 @@ class Collection:
# Notes
##########################################################################
def new_note(self, notetype: NoteType) -> Note:
def new_note(self, notetype: NotetypeDict) -> Note:
return Note(self, notetype)
def add_note(self, note: Note, deck_id: DeckId) -> OpChanges:

View File

@ -12,7 +12,7 @@ from typing import Any, List, Optional, Tuple
import anki
import anki._backend.backend_pb2 as _pb
from anki import hooks
from anki.models import NoteType
from anki.models import NotetypeDict
from anki.template import TemplateRenderContext, TemplateRenderOutput
from anki.utils import call, isMac, namedtmp, tmpdir
@ -64,7 +64,9 @@ def on_card_did_render(
output.answer_text = render_latex(output.answer_text, ctx.note_type(), ctx.col())
def render_latex(html: str, model: NoteType, col: anki.collection.Collection) -> str:
def render_latex(
html: str, model: NotetypeDict, col: anki.collection.Collection
) -> str:
"Convert embedded latex tags in text to image links."
html, err = render_latex_returning_errors(html, model, col)
if err:
@ -74,7 +76,7 @@ def render_latex(html: str, model: NoteType, col: anki.collection.Collection) ->
def render_latex_returning_errors(
html: str,
model: NoteType,
model: NotetypeDict,
col: anki.collection.Collection,
expand_clozes: bool = False,
) -> Tuple[str, List[str]]:

View File

@ -32,9 +32,9 @@ NoteTypeNameIdUseCount = _pb.NoteTypeNameIdUseCount
# types
NoteType = Dict[str, Any]
Field = Dict[str, Any]
Template = Dict[str, Union[str, int, None]]
NotetypeDict = Dict[str, Any]
FieldDict = Dict[str, Any]
TemplateDict = Dict[str, Union[str, int, None]]
NoteTypeId = NewType("NoteTypeId", int)
@ -92,7 +92,7 @@ class ModelManager:
def save(
self,
m: NoteType = None,
m: NotetypeDict = None,
# no longer used
templates: bool = False,
updateReqs: bool = True,
@ -115,16 +115,16 @@ class ModelManager:
# need to cache responses from the backend. Please do not
# access the cache directly!
_cache: Dict[NoteTypeId, NoteType] = {}
_cache: Dict[NoteTypeId, NotetypeDict] = {}
def _update_cache(self, nt: NoteType) -> None:
def _update_cache(self, nt: NotetypeDict) -> None:
self._cache[nt["id"]] = nt
def _remove_from_cache(self, ntid: NoteTypeId) -> None:
if ntid in self._cache:
del self._cache[ntid]
def _get_cached(self, ntid: NoteTypeId) -> Optional[NoteType]:
def _get_cached(self, ntid: NoteTypeId) -> Optional[NotetypeDict]:
return self._cache.get(ntid)
def _clear_cache(self) -> None:
@ -156,7 +156,7 @@ class ModelManager:
# Current note type
#############################################################
def current(self, forDeck: bool = True) -> NoteType:
def current(self, forDeck: bool = True) -> NotetypeDict:
"Get current model."
m = self.get(self.col.decks.current().get("mid"))
if not forDeck or not m:
@ -165,7 +165,7 @@ class ModelManager:
return m
return self.get(NoteTypeId(self.all_names_and_ids()[0].id))
def setCurrent(self, m: NoteType) -> None:
def setCurrent(self, m: NotetypeDict) -> None:
self.col.conf["curModel"] = m["id"]
# Retrieving and creating models
@ -177,7 +177,7 @@ class ModelManager:
except NotFoundError:
return None
def get(self, id: NoteTypeId) -> Optional[NoteType]:
def get(self, id: NoteTypeId) -> Optional[NotetypeDict]:
"Get model with ID, or None."
# deal with various legacy input types
if id is None:
@ -194,11 +194,11 @@ class ModelManager:
return None
return nt
def all(self) -> List[NoteType]:
def all(self) -> List[NotetypeDict]:
"Get all models."
return [self.get(NoteTypeId(nt.id)) for nt in self.all_names_and_ids()]
def byName(self, name: str) -> Optional[NoteType]:
def byName(self, name: str) -> Optional[NotetypeDict]:
"Get model with NAME."
id = self.id_for_name(name)
if id:
@ -206,7 +206,7 @@ class ModelManager:
else:
return None
def new(self, name: str) -> NoteType:
def new(self, name: str) -> NotetypeDict:
"Create a new model, and return it."
# caller should call save() after modifying
nt = from_json_bytes(
@ -217,7 +217,7 @@ class ModelManager:
nt["name"] = name
return nt
def rem(self, m: NoteType) -> None:
def rem(self, m: NotetypeDict) -> None:
"Delete model, and all its cards/notes."
self.remove(m["id"])
@ -231,15 +231,15 @@ class ModelManager:
self._remove_from_cache(id)
self.col._backend.remove_notetype(id)
def add(self, m: NoteType) -> None:
def add(self, m: NotetypeDict) -> None:
self.save(m)
def ensureNameUnique(self, m: NoteType) -> None:
def ensureNameUnique(self, m: NotetypeDict) -> None:
existing_id = self.id_for_name(m["name"])
if existing_id is not None and existing_id != m["id"]:
m["name"] += "-" + checksum(str(time.time()))[:5]
def update(self, m: NoteType, preserve_usn: bool = True) -> None:
def update(self, m: NotetypeDict, preserve_usn: bool = True) -> None:
"Add or update an existing model. Use .save() instead."
self._remove_from_cache(m["id"])
self.ensureNameUnique(m)
@ -249,7 +249,7 @@ class ModelManager:
self.setCurrent(m)
self._mutate_after_write(m)
def _mutate_after_write(self, nt: NoteType) -> None:
def _mutate_after_write(self, nt: NotetypeDict) -> None:
# existing code expects the note type to be mutated to reflect
# the changes made when adding, such as ordinal assignment :-(
updated = self.get(nt["id"])
@ -265,14 +265,14 @@ class ModelManager:
ntid = ntid["id"]
return self.col.db.list("select id from notes where mid = ?", ntid)
def useCount(self, m: NoteType) -> int:
def useCount(self, m: NotetypeDict) -> int:
"Number of note using M."
return self.col.db.scalar("select count() from notes where mid = ?", m["id"])
# Copying
##################################################
def copy(self, m: NoteType) -> NoteType:
def copy(self, m: NotetypeDict) -> NotetypeDict:
"Copy, save and return."
m2 = copy.deepcopy(m)
m2["name"] = without_unicode_isolation(
@ -285,20 +285,20 @@ class ModelManager:
# Fields
##################################################
def fieldMap(self, m: NoteType) -> Dict[str, Tuple[int, Field]]:
def fieldMap(self, m: NotetypeDict) -> Dict[str, Tuple[int, FieldDict]]:
"Mapping of field name -> (ord, field)."
return {f["name"]: (f["ord"], f) for f in m["flds"]}
def fieldNames(self, m: NoteType) -> List[str]:
def fieldNames(self, m: NotetypeDict) -> List[str]:
return [f["name"] for f in m["flds"]]
def sortIdx(self, m: NoteType) -> int:
def sortIdx(self, m: NotetypeDict) -> int:
return m["sortf"]
# Adding & changing fields
##################################################
def new_field(self, name: str) -> Field:
def new_field(self, name: str) -> FieldDict:
assert isinstance(name, str)
nt = from_json_bytes(
self.col._backend.get_stock_notetype_legacy(StockNotetypeKind.BASIC)
@ -308,15 +308,15 @@ class ModelManager:
field["ord"] = None
return field
def add_field(self, m: NoteType, field: Field) -> None:
def add_field(self, m: NotetypeDict, field: FieldDict) -> None:
"Modifies schema."
m["flds"].append(field)
def remove_field(self, m: NoteType, field: Field) -> None:
def remove_field(self, m: NotetypeDict, field: FieldDict) -> None:
"Modifies schema."
m["flds"].remove(field)
def reposition_field(self, m: NoteType, field: Field, idx: int) -> None:
def reposition_field(self, m: NotetypeDict, field: FieldDict, idx: int) -> None:
"Modifies schema."
oldidx = m["flds"].index(field)
if oldidx == idx:
@ -325,11 +325,11 @@ class ModelManager:
m["flds"].remove(field)
m["flds"].insert(idx, field)
def rename_field(self, m: NoteType, field: Field, new_name: str) -> None:
def rename_field(self, m: NotetypeDict, field: FieldDict, new_name: str) -> None:
assert field in m["flds"]
field["name"] = new_name
def set_sort_index(self, nt: NoteType, idx: int) -> None:
def set_sort_index(self, nt: NotetypeDict, idx: int) -> None:
"Modifies schema."
assert 0 <= idx < len(nt["flds"])
nt["sortf"] = idx
@ -338,27 +338,27 @@ class ModelManager:
newField = new_field
def addField(self, m: NoteType, field: Field) -> None:
def addField(self, m: NotetypeDict, field: FieldDict) -> None:
self.add_field(m, field)
if m["id"]:
self.save(m)
def remField(self, m: NoteType, field: Field) -> None:
def remField(self, m: NotetypeDict, field: FieldDict) -> None:
self.remove_field(m, field)
self.save(m)
def moveField(self, m: NoteType, field: Field, idx: int) -> None:
def moveField(self, m: NotetypeDict, field: FieldDict, idx: int) -> None:
self.reposition_field(m, field, idx)
self.save(m)
def renameField(self, m: NoteType, field: Field, newName: str) -> None:
def renameField(self, m: NotetypeDict, field: FieldDict, newName: str) -> None:
self.rename_field(m, field, newName)
self.save(m)
# Adding & changing templates
##################################################
def new_template(self, name: str) -> Template:
def new_template(self, name: str) -> TemplateDict:
nt = from_json_bytes(
self.col._backend.get_stock_notetype_legacy(StockNotetypeKind.BASIC)
)
@ -369,16 +369,18 @@ class ModelManager:
template["ord"] = None
return template
def add_template(self, m: NoteType, template: Template) -> None:
def add_template(self, m: NotetypeDict, template: TemplateDict) -> None:
"Modifies schema."
m["tmpls"].append(template)
def remove_template(self, m: NoteType, template: Template) -> None:
def remove_template(self, m: NotetypeDict, template: TemplateDict) -> None:
"Modifies schema."
assert len(m["tmpls"]) > 1
m["tmpls"].remove(template)
def reposition_template(self, m: NoteType, template: Template, idx: int) -> None:
def reposition_template(
self, m: NotetypeDict, template: TemplateDict, idx: int
) -> None:
"Modifies schema."
oldidx = m["tmpls"].index(template)
if oldidx == idx:
@ -391,16 +393,16 @@ class ModelManager:
newTemplate = new_template
def addTemplate(self, m: NoteType, template: Template) -> None:
def addTemplate(self, m: NotetypeDict, template: TemplateDict) -> None:
self.add_template(m, template)
if m["id"]:
self.save(m)
def remTemplate(self, m: NoteType, template: Template) -> None:
def remTemplate(self, m: NotetypeDict, template: TemplateDict) -> None:
self.remove_template(m, template)
self.save(m)
def moveTemplate(self, m: NoteType, template: Template, idx: int) -> None:
def moveTemplate(self, m: NotetypeDict, template: TemplateDict, idx: int) -> None:
self.reposition_template(m, template, idx)
self.save(m)
@ -420,9 +422,9 @@ and notes.mid = ? and cards.ord = ?""",
def change(
self,
m: NoteType,
m: NotetypeDict,
nids: List[anki.notes.NoteId],
newModel: NoteType,
newModel: NotetypeDict,
fmap: Optional[Dict[int, Union[None, int]]],
cmap: Optional[Dict[int, Union[None, int]]],
) -> None:
@ -437,7 +439,7 @@ and notes.mid = ? and cards.ord = ?""",
def _changeNotes(
self,
nids: List[anki.notes.NoteId],
newModel: NoteType,
newModel: NotetypeDict,
map: Dict[int, Union[None, int]],
) -> None:
d = []
@ -469,8 +471,8 @@ and notes.mid = ? and cards.ord = ?""",
def _changeCards(
self,
nids: List[anki.notes.NoteId],
oldModel: NoteType,
newModel: NoteType,
oldModel: NotetypeDict,
newModel: NotetypeDict,
map: Dict[int, Union[None, int]],
) -> None:
d = []
@ -500,7 +502,7 @@ and notes.mid = ? and cards.ord = ?""",
# Schema hash
##########################################################################
def scmhash(self, m: NoteType) -> str:
def scmhash(self, m: NotetypeDict) -> str:
"Return a hash of the schema, to see if models are compatible."
s = ""
for f in m["flds"]:
@ -513,7 +515,7 @@ and notes.mid = ? and cards.ord = ?""",
##########################################################################
def _availClozeOrds(
self, m: NoteType, flds: str, allowEmpty: bool = True
self, m: NotetypeDict, flds: str, allowEmpty: bool = True
) -> List[int]:
print("_availClozeOrds() is deprecated; use note.cloze_numbers_in_fields()")
note = _pb.Note(fields=[flds])

View File

@ -11,7 +11,7 @@ import anki # pylint: disable=unused-import
import anki._backend.backend_pb2 as _pb
from anki import hooks
from anki.consts import MODEL_STD
from anki.models import NoteType, NoteTypeId, Template
from anki.models import NotetypeDict, NoteTypeId, TemplateDict
from anki.utils import joinFields
DuplicateOrEmptyResult = _pb.NoteIsDuplicateOrEmptyOut.State
@ -30,7 +30,7 @@ class Note:
def __init__(
self,
col: anki.collection.Collection,
model: Optional[NoteType] = None,
model: Optional[NotetypeDict] = None,
id: Optional[NoteId] = None,
) -> None:
assert not (model and id)
@ -92,8 +92,8 @@ class Note:
self,
ord: int = 0,
*,
custom_note_type: NoteType = None,
custom_template: Template = None,
custom_note_type: NotetypeDict = None,
custom_template: TemplateDict = None,
fill_empty: bool = False,
) -> anki.cards.Card:
card = anki.cards.Card(self.col)
@ -127,7 +127,7 @@ class Note:
def card_ids(self) -> Sequence[anki.cards.CardId]:
return self.col.card_ids_of_note(self.id)
def model(self) -> Optional[NoteType]:
def model(self) -> Optional[NotetypeDict]:
return self.col.models.get(self.mid)
_model = property(model)

View File

@ -19,37 +19,39 @@ models: List[Tuple] = []
def _add_stock_notetype(
col: anki.collection.Collection, kind: StockNotetypeKind.V
) -> anki.models.NoteType:
) -> anki.models.NotetypeDict:
m = from_json_bytes(col._backend.get_stock_notetype_legacy(kind))
col.models.add(m)
return m
def addBasicModel(col: anki.collection.Collection) -> anki.models.NoteType:
def addBasicModel(col: anki.collection.Collection) -> anki.models.NotetypeDict:
return _add_stock_notetype(col, StockNotetypeKind.BASIC)
def addBasicTypingModel(col: anki.collection.Collection) -> anki.models.NoteType:
def addBasicTypingModel(col: anki.collection.Collection) -> anki.models.NotetypeDict:
return _add_stock_notetype(col, StockNotetypeKind.BASIC_TYPING)
def addForwardReverse(col: anki.collection.Collection) -> anki.models.NoteType:
def addForwardReverse(col: anki.collection.Collection) -> anki.models.NotetypeDict:
return _add_stock_notetype(col, StockNotetypeKind.BASIC_AND_REVERSED)
def addForwardOptionalReverse(col: anki.collection.Collection) -> anki.models.NoteType:
def addForwardOptionalReverse(
col: anki.collection.Collection,
) -> anki.models.NotetypeDict:
return _add_stock_notetype(col, StockNotetypeKind.BASIC_OPTIONAL_REVERSED)
def addClozeModel(col: anki.collection.Collection) -> anki.models.NoteType:
def addClozeModel(col: anki.collection.Collection) -> anki.models.NotetypeDict:
return _add_stock_notetype(col, StockNotetypeKind.CLOZE)
def get_stock_notetypes(
col: anki.collection.Collection,
) -> List[Tuple[str, Callable[[anki.collection.Collection], anki.models.NoteType]]]:
) -> List[Tuple[str, Callable[[anki.collection.Collection], anki.models.NotetypeDict]]]:
out: List[
Tuple[str, Callable[[anki.collection.Collection], anki.models.NoteType]]
Tuple[str, Callable[[anki.collection.Collection], anki.models.NotetypeDict]]
] = []
# add standard
for (kind, func) in [

View File

@ -37,7 +37,7 @@ from anki import hooks
from anki.cards import Card
from anki.decks import DeckManager
from anki.errors import TemplateError
from anki.models import NoteType
from anki.models import NotetypeDict
from anki.notes import Note
from anki.sound import AVTag, SoundOrVideoTag, TTSTag
from anki.utils import to_json_bytes
@ -121,7 +121,7 @@ class TemplateRenderContext:
cls,
note: Note,
card: Card,
notetype: NoteType,
notetype: NotetypeDict,
template: Dict,
fill_empty: bool,
) -> TemplateRenderContext:
@ -140,7 +140,7 @@ class TemplateRenderContext:
card: Card,
note: Note,
browser: bool = False,
notetype: NoteType = None,
notetype: NotetypeDict = None,
template: Optional[Dict] = None,
fill_empty: bool = False,
) -> None:
@ -194,7 +194,7 @@ class TemplateRenderContext:
def note(self) -> Note:
return self._note
def note_type(self) -> NoteType:
def note_type(self) -> NotetypeDict:
return self._note_type
# legacy

View File

@ -96,7 +96,7 @@ hooks = [
),
Hook(
name="note_type_added",
args=["notetype: anki.models.NoteType"],
args=["notetype: anki.models.NotetypeDict"],
doc="Obsolete, do not use.",
),
Hook(

View File

@ -27,7 +27,7 @@ from anki.collection import BrowserRow, Collection, Config, OpChanges, SearchNod
from anki.consts import *
from anki.errors import NotFoundError
from anki.lang import without_unicode_isolation
from anki.models import NoteType
from anki.models import NotetypeDict
from anki.notes import NoteId
from anki.stats import CardStats
from anki.tags import MARKED_TAG
@ -1645,7 +1645,7 @@ class ChangeModel(QDialog):
self.fcombos: List[QComboBox] = []
self.exec_()
def on_note_type_change(self, notetype: NoteType) -> None:
def on_note_type_change(self, notetype: NotetypeDict) -> None:
self.onReset()
def setup(self) -> None:

View File

@ -7,7 +7,7 @@ import aqt
from anki.consts import *
from anki.errors import TemplateError
from anki.lang import without_unicode_isolation
from anki.models import NoteType
from anki.models import NotetypeDict
from aqt import AnkiQt, gui_hooks
from aqt.qt import *
from aqt.schema_change_tracker import ChangeTracker
@ -25,7 +25,7 @@ from aqt.utils import (
class FieldDialog(QDialog):
def __init__(
self, mw: AnkiQt, nt: NoteType, parent: Optional[QWidget] = None
self, mw: AnkiQt, nt: NotetypeDict, parent: Optional[QWidget] = None
) -> None:
QDialog.__init__(self, parent or mw)
self.mw = mw

View File

@ -8,7 +8,7 @@ from typing import List, Optional, Sequence
import aqt.clayout
from anki import Collection, stdmodels
from anki.lang import without_unicode_isolation
from anki.models import NoteType, NoteTypeId, NoteTypeNameIdUseCount
from anki.models import NotetypeDict, NoteTypeId, NoteTypeNameIdUseCount
from anki.notes import Note
from aqt import AnkiQt, gui_hooks
from aqt.qt import *
@ -108,7 +108,7 @@ class Models(QDialog):
nt["name"] = name
self.saveAndRefresh(nt)
def saveAndRefresh(self, nt: NoteType) -> None:
def saveAndRefresh(self, nt: NotetypeDict) -> None:
def save() -> Sequence[NoteTypeNameIdUseCount]:
self.mm.save(nt)
return self.col.models.all_use_counts()
@ -131,7 +131,7 @@ class Models(QDialog):
self.form.modelsList.addItem(item)
self.form.modelsList.setCurrentRow(row)
def current_notetype(self) -> NoteType:
def current_notetype(self) -> NotetypeDict:
row = self.form.modelsList.currentRow()
return self.mm.get(NoteTypeId(self.models[row].id))
@ -217,7 +217,7 @@ class Models(QDialog):
class AddModel(QDialog):
model: Optional[NoteType]
model: Optional[NotetypeDict]
def __init__(self, mw: AnkiQt, parent: Optional[QWidget] = None) -> None:
self.parent_ = parent or mw
@ -229,7 +229,9 @@ class AddModel(QDialog):
self.dialog.setupUi(self)
disable_help_button(self)
# standard models
self.notetypes: List[Union[NoteType, Callable[[Collection], NoteType]]] = []
self.notetypes: List[
Union[NotetypeDict, Callable[[Collection], NotetypeDict]]
] = []
for (name, func) in stdmodels.get_stock_notetypes(self.col):
item = QListWidgetItem(tr.notetypes_add(val=name))
self.dialog.models.addItem(item)
@ -246,7 +248,7 @@ class AddModel(QDialog):
# help
qconnect(self.dialog.buttonBox.helpRequested, self.onHelp)
def get(self) -> Optional[NoteType]:
def get(self) -> Optional[NotetypeDict]:
self.exec_()
return self.model

View File

@ -23,7 +23,7 @@ import aqt
from anki.cards import Card
from anki.decks import DeckDict, DeckConfigDict
from anki.hooks import runFilter, runHook
from anki.models import NoteType
from anki.models import NotetypeDict
from aqt.qt import QDialog, QEvent, QMenu, QWidget
from aqt.tagedit import TagEdit
"""
@ -855,13 +855,13 @@ gui_hooks.webview_did_inject_style_into_page.append(mytest)
name="fields_did_rename_field",
args=[
"dialog: aqt.fields.FieldDialog",
"field: anki.models.Field",
"field: anki.models.FieldDict",
"old_name: str",
],
),
Hook(
name="fields_did_delete_field",
args=["dialog: aqt.fields.FieldDialog", "field: anki.models.Field"],
args=["dialog: aqt.fields.FieldDialog", "field: anki.models.FieldDict"],
),
# Stats
###################
@ -879,7 +879,7 @@ gui_hooks.webview_did_inject_style_into_page.append(mytest)
###################
Hook(
name="current_note_type_did_change",
args=["notetype: NoteType"],
args=["notetype: NotetypeDict"],
legacy_hook="currentModelChanged",
legacy_no_args=True,
),