VSCode 对 tkinter.Canvas 的类型提示从何而来?
Where do VSCode's type hints for tkinter.Canvas come from?
我发现了一些困扰我的想法。
VSCode 的一个重要特征是 type-hinting 我在写 tkinter
class 时得到 **kw
。这是一个例子:
现在我正在尝试从 Tk.Canvas()
class 制作一个 child class,幸运的是 vscode 已经完成了写作的艰苦工作这下:
class MyCanvas(Tk.Canvas):
def __init__(self, master: Misc | None, cnf: dict[str, Any] | None, *, background: _Color, bd: _ScreenUnits, bg: _Color, border: _ScreenUnits, borderwidth: _ScreenUnits, closeenough: float, confine: bool, cursor: _Cursor, height: _ScreenUnits, highlightbackground: _Color, highlightcolor: _Color, highlightthickness: _ScreenUnits, insertbackground: _Color, insertborderwidth: _ScreenUnits, insertofftime: int, insertontime: int, insertwidth: _ScreenUnits, name: str, offset: Any, relief: _Relief, scrollregion: Tuple[_ScreenUnits, _ScreenUnits, _ScreenUnits, _ScreenUnits] | Tuple[()], selectbackground: _Color, selectborderwidth: _ScreenUnits, selectforeground: _Color, state: Literal["normal", "disabled"], takefocus: _TakeFocusValue, width: _ScreenUnits, xscrollcommand: _XYScrollCommand, xscrollincrement: _ScreenUnits, yscrollcommand: _XYScrollCommand, yscrollincrement: _ScreenUnits) -> None:
super().__init__(master=master, cnf=cnf, background=background, bd=bd, bg=bg, border=border, borderwidth=borderwidth, closeenough=closeenough, confine=confine, cursor=cursor, height=height, highlightbackground=highlightbackground, highlightcolor=highlightcolor, highlightthickness=highlightthickness, insertbackground=insertbackground, insertborderwidth=insertborderwidth, insertofftime=insertofftime, insertontime=insertontime, insertwidth=insertwidth, name=name, offset=offset, relief=relief, scrollregion=scrollregion, selectbackground=selectbackground, selectborderwidth=selectborderwidth, selectforeground=selectforeground, state=state, takefocus=takefocus, width=width, xscrollcommand=xscrollcommand, xscrollincrement=xscrollincrement, yscrollcommand=yscrollcommand, yscrollincrement=yscrollincrement)
但这个定义是完全错误的:它将属性视为变量而不是 **kw
,并引用未定义的 classes,如 _Color
和 [=19] =].所以我去 Tk.Canvas.__init__()
定义看看是怎么回事,我发现了这个:
def __init__(self, master=None, cnf={}, **kw):
"""Construct a canvas widget with the parent MASTER.
Valid resource names: background, bd, bg, borderwidth, closeenough,
confine, cursor, height, highlightbackground, highlightcolor,
highlightthickness, insertbackground, insertborderwidth,
insertofftime, insertontime, insertwidth, offset, relief,
scrollregion, selectbackground, selectborderwidth, selectforeground,
state, takefocus, width, xscrollcommand, xscrollincrement,
yscrollcommand, yscrollincrement."""
Widget.__init__(self, master, 'canvas', cnf, kw)
所以在这里我很困惑,因为在 class 定义中没有单一的类型提示。那么我得到的所有这些“类型提示”是从哪里来的呢?有没有办法让它出现在我的 child class 的 **kw
?
VSCode 对 python 标准库的类型提示来自 Typeshed,这是一个标准库存根文件的存储库(参见此处:). The stub for Tk.Canvas
can be found here on github。在顶部在该文件中,您可以找到 _Color
、_ScreenUnits
等的定义。(我同意 VSCode 在自动完成中提供这些内容而不告诉您它们的定义甚至是这些“外来”类型来自哪里。)
截至 2021 年 8 月 28 日存根文件的第 84-111 行:
_T = TypeVar("_T")
_TkinterSequence = Union[List[_T], Tuple[_T, ...]]
_TkinterSequence2D = Union[List[List[_T]], List[Tuple[_T, ...]], Tuple[List[_T], ...], Tuple[Tuple[_T, ...], ...]]
# Some widgets have an option named -compound that accepts different values
# than the _Compound defined here. Many other options have similar things.
_Anchor = Literal["nw", "n", "ne", "w", "center", "e", "sw", "s", "se"] # manual page: Tk_GetAnchor
_Bitmap = str # manual page: Tk_GetBitmap
_ButtonCommand = Union[str, Callable[[], Any]] # return value is returned from Button.invoke()
_CanvasItemId = int
_Color = str # typically '#rrggbb', '#rgb' or color names.
_Compound = Literal["top", "left", "center", "right", "bottom", "none"] # -compound in manual page named 'options'
_Cursor = Union[str, Tuple[str], Tuple[str, str], Tuple[str, str, str], Tuple[str, str, str, str]] # manual page: Tk_GetCursor
_EntryValidateCommand = Union[
Callable[[], bool], str, _TkinterSequence[str]
] # example when it's sequence: entry['invalidcommand'] = [entry.register(print), '%P']
_ImageSpec = Union[_Image, str] # str can be from e.g. tkinter.image_names()
_Padding = Union[
_ScreenUnits,
Tuple[_ScreenUnits],
Tuple[_ScreenUnits, _ScreenUnits],
Tuple[_ScreenUnits, _ScreenUnits, _ScreenUnits],
Tuple[_ScreenUnits, _ScreenUnits, _ScreenUnits, _ScreenUnits],
]
_Relief = Literal["raised", "sunken", "flat", "ridge", "solid", "groove"] # manual page: Tk_GetRelief
_ScreenUnits = Union[str, float] # manual page: Tk_GetPixels
_XYScrollCommand = Union[str, Callable[[float, float], Any]] # -xscrollcommand and -yscrollcommand in 'options' manual page
_TakeFocusValue = Union[int, Literal[""], Callable[[str], Optional[bool]]] # -takefocus in manual page named 'options'
另外,请注意函数定义中 *
之后的所有参数都是 。因此,我不同意 Tk.canvas.__init__
的 typeshed 中的类型注释是错误的——在我看来,当它们应该被标记为仅限关键字时,它们并没有将任何参数标记为位置参数.
我发现了一些困扰我的想法。
VSCode 的一个重要特征是 type-hinting 我在写 tkinter
class 时得到 **kw
。这是一个例子:
现在我正在尝试从 Tk.Canvas()
class 制作一个 child class,幸运的是 vscode 已经完成了写作的艰苦工作这下:
class MyCanvas(Tk.Canvas):
def __init__(self, master: Misc | None, cnf: dict[str, Any] | None, *, background: _Color, bd: _ScreenUnits, bg: _Color, border: _ScreenUnits, borderwidth: _ScreenUnits, closeenough: float, confine: bool, cursor: _Cursor, height: _ScreenUnits, highlightbackground: _Color, highlightcolor: _Color, highlightthickness: _ScreenUnits, insertbackground: _Color, insertborderwidth: _ScreenUnits, insertofftime: int, insertontime: int, insertwidth: _ScreenUnits, name: str, offset: Any, relief: _Relief, scrollregion: Tuple[_ScreenUnits, _ScreenUnits, _ScreenUnits, _ScreenUnits] | Tuple[()], selectbackground: _Color, selectborderwidth: _ScreenUnits, selectforeground: _Color, state: Literal["normal", "disabled"], takefocus: _TakeFocusValue, width: _ScreenUnits, xscrollcommand: _XYScrollCommand, xscrollincrement: _ScreenUnits, yscrollcommand: _XYScrollCommand, yscrollincrement: _ScreenUnits) -> None:
super().__init__(master=master, cnf=cnf, background=background, bd=bd, bg=bg, border=border, borderwidth=borderwidth, closeenough=closeenough, confine=confine, cursor=cursor, height=height, highlightbackground=highlightbackground, highlightcolor=highlightcolor, highlightthickness=highlightthickness, insertbackground=insertbackground, insertborderwidth=insertborderwidth, insertofftime=insertofftime, insertontime=insertontime, insertwidth=insertwidth, name=name, offset=offset, relief=relief, scrollregion=scrollregion, selectbackground=selectbackground, selectborderwidth=selectborderwidth, selectforeground=selectforeground, state=state, takefocus=takefocus, width=width, xscrollcommand=xscrollcommand, xscrollincrement=xscrollincrement, yscrollcommand=yscrollcommand, yscrollincrement=yscrollincrement)
但这个定义是完全错误的:它将属性视为变量而不是 **kw
,并引用未定义的 classes,如 _Color
和 [=19] =].所以我去 Tk.Canvas.__init__()
定义看看是怎么回事,我发现了这个:
def __init__(self, master=None, cnf={}, **kw):
"""Construct a canvas widget with the parent MASTER.
Valid resource names: background, bd, bg, borderwidth, closeenough,
confine, cursor, height, highlightbackground, highlightcolor,
highlightthickness, insertbackground, insertborderwidth,
insertofftime, insertontime, insertwidth, offset, relief,
scrollregion, selectbackground, selectborderwidth, selectforeground,
state, takefocus, width, xscrollcommand, xscrollincrement,
yscrollcommand, yscrollincrement."""
Widget.__init__(self, master, 'canvas', cnf, kw)
所以在这里我很困惑,因为在 class 定义中没有单一的类型提示。那么我得到的所有这些“类型提示”是从哪里来的呢?有没有办法让它出现在我的 child class 的 **kw
?
VSCode 对 python 标准库的类型提示来自 Typeshed,这是一个标准库存根文件的存储库(参见此处:Tk.Canvas
can be found here on github。在顶部在该文件中,您可以找到 _Color
、_ScreenUnits
等的定义。(我同意 VSCode 在自动完成中提供这些内容而不告诉您它们的定义甚至是这些“外来”类型来自哪里。)
截至 2021 年 8 月 28 日存根文件的第 84-111 行:
_T = TypeVar("_T")
_TkinterSequence = Union[List[_T], Tuple[_T, ...]]
_TkinterSequence2D = Union[List[List[_T]], List[Tuple[_T, ...]], Tuple[List[_T], ...], Tuple[Tuple[_T, ...], ...]]
# Some widgets have an option named -compound that accepts different values
# than the _Compound defined here. Many other options have similar things.
_Anchor = Literal["nw", "n", "ne", "w", "center", "e", "sw", "s", "se"] # manual page: Tk_GetAnchor
_Bitmap = str # manual page: Tk_GetBitmap
_ButtonCommand = Union[str, Callable[[], Any]] # return value is returned from Button.invoke()
_CanvasItemId = int
_Color = str # typically '#rrggbb', '#rgb' or color names.
_Compound = Literal["top", "left", "center", "right", "bottom", "none"] # -compound in manual page named 'options'
_Cursor = Union[str, Tuple[str], Tuple[str, str], Tuple[str, str, str], Tuple[str, str, str, str]] # manual page: Tk_GetCursor
_EntryValidateCommand = Union[
Callable[[], bool], str, _TkinterSequence[str]
] # example when it's sequence: entry['invalidcommand'] = [entry.register(print), '%P']
_ImageSpec = Union[_Image, str] # str can be from e.g. tkinter.image_names()
_Padding = Union[
_ScreenUnits,
Tuple[_ScreenUnits],
Tuple[_ScreenUnits, _ScreenUnits],
Tuple[_ScreenUnits, _ScreenUnits, _ScreenUnits],
Tuple[_ScreenUnits, _ScreenUnits, _ScreenUnits, _ScreenUnits],
]
_Relief = Literal["raised", "sunken", "flat", "ridge", "solid", "groove"] # manual page: Tk_GetRelief
_ScreenUnits = Union[str, float] # manual page: Tk_GetPixels
_XYScrollCommand = Union[str, Callable[[float, float], Any]] # -xscrollcommand and -yscrollcommand in 'options' manual page
_TakeFocusValue = Union[int, Literal[""], Callable[[str], Optional[bool]]] # -takefocus in manual page named 'options'
另外,请注意函数定义中 *
之后的所有参数都是 Tk.canvas.__init__
的 typeshed 中的类型注释是错误的——在我看来,当它们应该被标记为仅限关键字时,它们并没有将任何参数标记为位置参数.