1import sys 2from typing import Any, Callable, Dict, List, Optional, Sequence, Text, Tuple, TypeVar, Union, overload 3 4if sys.version_info >= (3,): 5 from tkinter import Canvas, PhotoImage 6else: 7 # TODO: Replace these aliases once we have Python 2 stubs for the Tkinter module. 8 Canvas = Any 9 PhotoImage = Any 10 11# Note: '_Color' is the alias we use for arguments and _AnyColor is the 12# alias we use for return types. Really, these two aliases should be the 13# same, but as per the "no union returns" typeshed policy, we'll return 14# Any instead. 15_Color = Union[Text, Tuple[float, float, float]] 16_AnyColor = Any 17 18# TODO: Replace this with a TypedDict once it becomes standardized. 19_PenState = Dict[str, Any] 20 21_Speed = Union[str, float] 22_PolygonCoords = Sequence[Tuple[float, float]] 23 24# TODO: Type this more accurately 25# Vec2D is actually a custom subclass of 'tuple'. 26Vec2D = Tuple[float, float] 27 28class TurtleScreenBase(object): 29 cv: Canvas = ... 30 canvwidth: int = ... 31 canvheight: int = ... 32 xscale: float = ... 33 yscale: float = ... 34 def __init__(self, cv: Canvas) -> None: ... 35 if sys.version_info >= (3,): 36 def mainloop(self) -> None: ... 37 def textinput(self, title: str, prompt: str) -> Optional[str]: ... 38 def numinput( 39 self, 40 title: str, 41 prompt: str, 42 default: Optional[float] = ..., 43 minval: Optional[float] = ..., 44 maxval: Optional[float] = ..., 45 ) -> Optional[float]: ... 46 47class Terminator(Exception): ... 48class TurtleGraphicsError(Exception): ... 49 50class Shape(object): 51 def __init__(self, type_: str, data: Union[_PolygonCoords, PhotoImage, None] = ...) -> None: ... 52 def addcomponent(self, poly: _PolygonCoords, fill: _Color, outline: Optional[_Color] = ...) -> None: ... 53 54class TurtleScreen(TurtleScreenBase): 55 def __init__(self, cv: Canvas, mode: str = ..., colormode: float = ..., delay: int = ...) -> None: ... 56 def clear(self) -> None: ... 57 @overload 58 def mode(self, mode: None = ...) -> str: ... 59 @overload 60 def mode(self, mode: str) -> None: ... 61 def setworldcoordinates(self, llx: float, lly: float, urx: float, ury: float) -> None: ... 62 def register_shape(self, name: str, shape: Union[_PolygonCoords, Shape, None] = ...) -> None: ... 63 @overload 64 def colormode(self, cmode: None = ...) -> float: ... 65 @overload 66 def colormode(self, cmode: float) -> None: ... 67 def reset(self) -> None: ... 68 def turtles(self) -> List[Turtle]: ... 69 @overload 70 def bgcolor(self) -> _AnyColor: ... 71 @overload 72 def bgcolor(self, color: _Color) -> None: ... 73 @overload 74 def bgcolor(self, r: float, g: float, b: float) -> None: ... 75 @overload 76 def tracer(self, n: None = ...) -> int: ... 77 @overload 78 def tracer(self, n: int, delay: Optional[int] = ...) -> None: ... 79 @overload 80 def delay(self, delay: None = ...) -> int: ... 81 @overload 82 def delay(self, delay: int) -> None: ... 83 def update(self) -> None: ... 84 def window_width(self) -> int: ... 85 def window_height(self) -> int: ... 86 def getcanvas(self) -> Canvas: ... 87 def getshapes(self) -> List[str]: ... 88 def onclick(self, fun: Callable[[float, float], Any], btn: int = ..., add: Optional[Any] = ...) -> None: ... 89 def onkey(self, fun: Callable[[], Any], key: str) -> None: ... 90 def listen(self, xdummy: Optional[float] = ..., ydummy: Optional[float] = ...) -> None: ... 91 def ontimer(self, fun: Callable[[], Any], t: int = ...) -> None: ... 92 @overload 93 def bgpic(self, picname: None = ...) -> str: ... 94 @overload 95 def bgpic(self, picname: str) -> None: ... 96 @overload 97 def screensize(self, canvwidth: None = ..., canvheight: None = ..., bg: None = ...) -> Tuple[int, int]: ... 98 # Looks like if self.cv is not a ScrolledCanvas, this could return a tuple as well 99 @overload 100 def screensize(self, canvwidth: int, canvheight: int, bg: Optional[_Color] = ...) -> None: ... 101 onscreenclick = onclick 102 resetscreen = reset 103 clearscreen = clear 104 addshape = register_shape 105 if sys.version_info >= (3,): 106 def onkeypress(self, fun: Callable[[], Any], key: Optional[str] = ...) -> None: ... 107 onkeyrelease = onkey 108 109class TNavigator(object): 110 START_ORIENTATION: Dict[str, Vec2D] = ... 111 DEFAULT_MODE: str = ... 112 DEFAULT_ANGLEOFFSET: int = ... 113 DEFAULT_ANGLEORIENT: int = ... 114 def __init__(self, mode: str = ...) -> None: ... 115 def reset(self) -> None: ... 116 def degrees(self, fullcircle: float = ...) -> None: ... 117 def radians(self) -> None: ... 118 def forward(self, distance: float) -> None: ... 119 def back(self, distance: float) -> None: ... 120 def right(self, angle: float) -> None: ... 121 def left(self, angle: float) -> None: ... 122 def pos(self) -> Vec2D: ... 123 def xcor(self) -> float: ... 124 def ycor(self) -> float: ... 125 @overload 126 def goto(self, x: Tuple[float, float], y: None = ...) -> None: ... 127 @overload 128 def goto(self, x: float, y: float) -> None: ... 129 def home(self) -> None: ... 130 def setx(self, x: float) -> None: ... 131 def sety(self, y: float) -> None: ... 132 @overload 133 def distance(self, x: Union[TNavigator, Tuple[float, float]], y: None = ...) -> float: ... 134 @overload 135 def distance(self, x: float, y: float) -> float: ... 136 @overload 137 def towards(self, x: Union[TNavigator, Tuple[float, float]], y: None = ...) -> float: ... 138 @overload 139 def towards(self, x: float, y: float) -> float: ... 140 def heading(self) -> float: ... 141 def setheading(self, to_angle: float) -> None: ... 142 def circle(self, radius: float, extent: Optional[float] = ..., steps: Optional[int] = ...) -> None: ... 143 fd = forward 144 bk = back 145 backward = back 146 rt = right 147 lt = left 148 position = pos 149 setpos = goto 150 setposition = goto 151 seth = setheading 152 153class TPen(object): 154 def __init__(self, resizemode: str = ...) -> None: ... 155 @overload 156 def resizemode(self, rmode: None = ...) -> str: ... 157 @overload 158 def resizemode(self, rmode: str) -> None: ... 159 @overload 160 def pensize(self, width: None = ...) -> int: ... 161 @overload 162 def pensize(self, width: int) -> None: ... 163 def penup(self) -> None: ... 164 def pendown(self) -> None: ... 165 def isdown(self) -> bool: ... 166 @overload 167 def speed(self, speed: None = ...) -> int: ... 168 @overload 169 def speed(self, speed: _Speed) -> None: ... 170 @overload 171 def pencolor(self) -> _AnyColor: ... 172 @overload 173 def pencolor(self, color: _Color) -> None: ... 174 @overload 175 def pencolor(self, r: float, g: float, b: float) -> None: ... 176 @overload 177 def fillcolor(self) -> _AnyColor: ... 178 @overload 179 def fillcolor(self, color: _Color) -> None: ... 180 @overload 181 def fillcolor(self, r: float, g: float, b: float) -> None: ... 182 @overload 183 def color(self) -> Tuple[_AnyColor, _AnyColor]: ... 184 @overload 185 def color(self, color: _Color) -> None: ... 186 @overload 187 def color(self, r: float, g: float, b: float) -> None: ... 188 @overload 189 def color(self, color1: _Color, color2: _Color) -> None: ... 190 def showturtle(self) -> None: ... 191 def hideturtle(self) -> None: ... 192 def isvisible(self) -> bool: ... 193 # Note: signatures 1 and 2 overlap unsafely when no arguments are provided 194 @overload 195 def pen(self) -> _PenState: ... # type: ignore 196 @overload 197 def pen( 198 self, 199 pen: Optional[_PenState] = ..., 200 *, 201 shown: bool = ..., 202 pendown: bool = ..., 203 pencolor: _Color = ..., 204 fillcolor: _Color = ..., 205 pensize: int = ..., 206 speed: int = ..., 207 resizemode: str = ..., 208 stretchfactor: Tuple[float, float] = ..., 209 outline: int = ..., 210 tilt: float = ..., 211 ) -> None: ... 212 width = pensize 213 up = penup 214 pu = penup 215 pd = pendown 216 down = pendown 217 st = showturtle 218 ht = hideturtle 219 220_T = TypeVar("_T") 221 222class RawTurtle(TPen, TNavigator): 223 def __init__( 224 self, canvas: Union[Canvas, TurtleScreen, None] = ..., shape: str = ..., undobuffersize: int = ..., visible: bool = ... 225 ) -> None: ... 226 def reset(self) -> None: ... 227 def setundobuffer(self, size: Optional[int]) -> None: ... 228 def undobufferentries(self) -> int: ... 229 def clear(self) -> None: ... 230 def clone(self: _T) -> _T: ... 231 @overload 232 def shape(self, name: None = ...) -> str: ... 233 @overload 234 def shape(self, name: str) -> None: ... 235 # Unsafely overlaps when no arguments are provided 236 @overload 237 def shapesize(self) -> Tuple[float, float, float]: ... # type: ignore 238 @overload 239 def shapesize( 240 self, stretch_wid: Optional[float] = ..., stretch_len: Optional[float] = ..., outline: Optional[float] = ... 241 ) -> None: ... 242 if sys.version_info >= (3,): 243 @overload 244 def shearfactor(self, shear: None = ...) -> float: ... 245 @overload 246 def shearfactor(self, shear: float) -> None: ... 247 # Unsafely overlaps when no arguments are provided 248 @overload 249 def shapetransform(self) -> Tuple[float, float, float, float]: ... # type: ignore 250 @overload 251 def shapetransform( 252 self, t11: Optional[float] = ..., t12: Optional[float] = ..., t21: Optional[float] = ..., t22: Optional[float] = ... 253 ) -> None: ... 254 def get_shapepoly(self) -> Optional[_PolygonCoords]: ... 255 def settiltangle(self, angle: float) -> None: ... 256 @overload 257 def tiltangle(self, angle: None = ...) -> float: ... 258 @overload 259 def tiltangle(self, angle: float) -> None: ... 260 def tilt(self, angle: float) -> None: ... 261 # Can return either 'int' or Tuple[int, ...] based on if the stamp is 262 # a compound stamp or not. So, as per the "no Union return" policy, 263 # we return Any. 264 def stamp(self) -> Any: ... 265 def clearstamp(self, stampid: Union[int, Tuple[int, ...]]) -> None: ... 266 def clearstamps(self, n: Optional[int] = ...) -> None: ... 267 def filling(self) -> bool: ... 268 def begin_fill(self) -> None: ... 269 def end_fill(self) -> None: ... 270 def dot(self, size: Optional[int] = ..., *color: _Color) -> None: ... 271 def write(self, arg: object, move: bool = ..., align: str = ..., font: Tuple[str, int, str] = ...) -> None: ... 272 def begin_poly(self) -> None: ... 273 def end_poly(self) -> None: ... 274 def get_poly(self) -> Optional[_PolygonCoords]: ... 275 def getscreen(self) -> TurtleScreen: ... 276 def getturtle(self: _T) -> _T: ... 277 getpen = getturtle 278 def onclick(self, fun: Callable[[float, float], Any], btn: int = ..., add: Optional[bool] = ...) -> None: ... 279 def onrelease(self, fun: Callable[[float, float], Any], btn: int = ..., add: Optional[bool] = ...) -> None: ... 280 def ondrag(self, fun: Callable[[float, float], Any], btn: int = ..., add: Optional[bool] = ...) -> None: ... 281 def undo(self) -> None: ... 282 turtlesize = shapesize 283 284class _Screen(TurtleScreen): 285 def __init__(self) -> None: ... 286 # Note int and float are interpreted differently, hence the Union instead of just float 287 def setup( 288 self, 289 width: Union[int, float] = ..., 290 height: Union[int, float] = ..., 291 startx: Optional[int] = ..., 292 starty: Optional[int] = ..., 293 ) -> None: ... 294 def title(self, titlestring: str) -> None: ... 295 def bye(self) -> None: ... 296 def exitonclick(self) -> None: ... 297 298class Turtle(RawTurtle): 299 def __init__(self, shape: str = ..., undobuffersize: int = ..., visible: bool = ...) -> None: ... 300 301RawPen = RawTurtle 302Pen = Turtle 303 304def write_docstringdict(filename: str = ...) -> None: ... 305 306# Note: it's somewhat unfortunate that we have to copy the function signatures. 307# It would be nice if we could partially reduce the redundancy by doing something 308# like the following: 309# 310# _screen: Screen 311# clear = _screen.clear 312# 313# However, it seems pytype does not support this type of syntax in pyi files. 314 315# Functions copied from TurtleScreenBase: 316 317# Note: mainloop() was always present in the global scope, but was added to 318# TurtleScreenBase in Python 3.0 319def mainloop() -> None: ... 320 321if sys.version_info >= (3,): 322 def textinput(title: str, prompt: str) -> Optional[str]: ... 323 def numinput( 324 title: str, prompt: str, default: Optional[float] = ..., minval: Optional[float] = ..., maxval: Optional[float] = ... 325 ) -> Optional[float]: ... 326 327# Functions copied from TurtleScreen: 328 329def clear() -> None: ... 330@overload 331def mode(mode: None = ...) -> str: ... 332@overload 333def mode(mode: str) -> None: ... 334def setworldcoordinates(llx: float, lly: float, urx: float, ury: float) -> None: ... 335def register_shape(name: str, shape: Union[_PolygonCoords, Shape, None] = ...) -> None: ... 336@overload 337def colormode(cmode: None = ...) -> float: ... 338@overload 339def colormode(cmode: float) -> None: ... 340def reset() -> None: ... 341def turtles() -> List[Turtle]: ... 342@overload 343def bgcolor() -> _AnyColor: ... 344@overload 345def bgcolor(color: _Color) -> None: ... 346@overload 347def bgcolor(r: float, g: float, b: float) -> None: ... 348@overload 349def tracer(n: None = ...) -> int: ... 350@overload 351def tracer(n: int, delay: Optional[int] = ...) -> None: ... 352@overload 353def delay(delay: None = ...) -> int: ... 354@overload 355def delay(delay: int) -> None: ... 356def update() -> None: ... 357def window_width() -> int: ... 358def window_height() -> int: ... 359def getcanvas() -> Canvas: ... 360def getshapes() -> List[str]: ... 361def onclick(fun: Callable[[float, float], Any], btn: int = ..., add: Optional[Any] = ...) -> None: ... 362def onkey(fun: Callable[[], Any], key: str) -> None: ... 363def listen(xdummy: Optional[float] = ..., ydummy: Optional[float] = ...) -> None: ... 364def ontimer(fun: Callable[[], Any], t: int = ...) -> None: ... 365@overload 366def bgpic(picname: None = ...) -> str: ... 367@overload 368def bgpic(picname: str) -> None: ... 369@overload 370def screensize(canvwidth: None = ..., canvheight: None = ..., bg: None = ...) -> Tuple[int, int]: ... 371@overload 372def screensize(canvwidth: int, canvheight: int, bg: Optional[_Color] = ...) -> None: ... 373 374onscreenclick = onclick 375resetscreen = reset 376clearscreen = clear 377addshape = register_shape 378if sys.version_info >= (3,): 379 def onkeypress(fun: Callable[[], Any], key: Optional[str] = ...) -> None: ... 380 onkeyrelease = onkey 381 382# Functions copied from _Screen: 383 384def setup(width: float = ..., height: float = ..., startx: Optional[int] = ..., starty: Optional[int] = ...) -> None: ... 385def title(titlestring: str) -> None: ... 386def bye() -> None: ... 387def exitonclick() -> None: ... 388def Screen() -> _Screen: ... 389 390# Functions copied from TNavigator: 391 392def degrees(fullcircle: float = ...) -> None: ... 393def radians() -> None: ... 394def forward(distance: float) -> None: ... 395def back(distance: float) -> None: ... 396def right(angle: float) -> None: ... 397def left(angle: float) -> None: ... 398def pos() -> Vec2D: ... 399def xcor() -> float: ... 400def ycor() -> float: ... 401@overload 402def goto(x: Tuple[float, float], y: None = ...) -> None: ... 403@overload 404def goto(x: float, y: float) -> None: ... 405def home() -> None: ... 406def setx(x: float) -> None: ... 407def sety(y: float) -> None: ... 408@overload 409def distance(x: Union[TNavigator, Tuple[float, float]], y: None = ...) -> float: ... 410@overload 411def distance(x: float, y: float) -> float: ... 412@overload 413def towards(x: Union[TNavigator, Tuple[float, float]], y: None = ...) -> float: ... 414@overload 415def towards(x: float, y: float) -> float: ... 416def heading() -> float: ... 417def setheading(to_angle: float) -> None: ... 418def circle(radius: float, extent: Optional[float] = ..., steps: Optional[int] = ...) -> None: ... 419 420fd = forward 421bk = back 422backward = back 423rt = right 424lt = left 425position = pos 426setpos = goto 427setposition = goto 428seth = setheading 429 430# Functions copied from TPen: 431@overload 432def resizemode(rmode: None = ...) -> str: ... 433@overload 434def resizemode(rmode: str) -> None: ... 435@overload 436def pensize(width: None = ...) -> int: ... 437@overload 438def pensize(width: int) -> None: ... 439def penup() -> None: ... 440def pendown() -> None: ... 441def isdown() -> bool: ... 442@overload 443def speed(speed: None = ...) -> int: ... 444@overload 445def speed(speed: _Speed) -> None: ... 446@overload 447def pencolor() -> _AnyColor: ... 448@overload 449def pencolor(color: _Color) -> None: ... 450@overload 451def pencolor(r: float, g: float, b: float) -> None: ... 452@overload 453def fillcolor() -> _AnyColor: ... 454@overload 455def fillcolor(color: _Color) -> None: ... 456@overload 457def fillcolor(r: float, g: float, b: float) -> None: ... 458@overload 459def color() -> Tuple[_AnyColor, _AnyColor]: ... 460@overload 461def color(color: _Color) -> None: ... 462@overload 463def color(r: float, g: float, b: float) -> None: ... 464@overload 465def color(color1: _Color, color2: _Color) -> None: ... 466def showturtle() -> None: ... 467def hideturtle() -> None: ... 468def isvisible() -> bool: ... 469 470# Note: signatures 1 and 2 overlap unsafely when no arguments are provided 471@overload 472def pen() -> _PenState: ... # type: ignore 473@overload 474def pen( 475 pen: Optional[_PenState] = ..., 476 *, 477 shown: bool = ..., 478 pendown: bool = ..., 479 pencolor: _Color = ..., 480 fillcolor: _Color = ..., 481 pensize: int = ..., 482 speed: int = ..., 483 resizemode: str = ..., 484 stretchfactor: Tuple[float, float] = ..., 485 outline: int = ..., 486 tilt: float = ..., 487) -> None: ... 488 489width = pensize 490up = penup 491pu = penup 492pd = pendown 493down = pendown 494st = showturtle 495ht = hideturtle 496 497# Functions copied from RawTurtle: 498 499def setundobuffer(size: Optional[int]) -> None: ... 500def undobufferentries() -> int: ... 501@overload 502def shape(name: None = ...) -> str: ... 503@overload 504def shape(name: str) -> None: ... 505 506# Unsafely overlaps when no arguments are provided 507@overload 508def shapesize() -> Tuple[float, float, float]: ... # type: ignore 509@overload 510def shapesize(stretch_wid: Optional[float] = ..., stretch_len: Optional[float] = ..., outline: Optional[float] = ...) -> None: ... 511 512if sys.version_info >= (3,): 513 @overload 514 def shearfactor(shear: None = ...) -> float: ... 515 @overload 516 def shearfactor(shear: float) -> None: ... 517 # Unsafely overlaps when no arguments are provided 518 @overload 519 def shapetransform() -> Tuple[float, float, float, float]: ... # type: ignore 520 @overload 521 def shapetransform( 522 t11: Optional[float] = ..., t12: Optional[float] = ..., t21: Optional[float] = ..., t22: Optional[float] = ... 523 ) -> None: ... 524 def get_shapepoly() -> Optional[_PolygonCoords]: ... 525 526def settiltangle(angle: float) -> None: ... 527@overload 528def tiltangle(angle: None = ...) -> float: ... 529@overload 530def tiltangle(angle: float) -> None: ... 531def tilt(angle: float) -> None: ... 532 533# Can return either 'int' or Tuple[int, ...] based on if the stamp is 534# a compound stamp or not. So, as per the "no Union return" policy, 535# we return Any. 536def stamp() -> Any: ... 537def clearstamp(stampid: Union[int, Tuple[int, ...]]) -> None: ... 538def clearstamps(n: Optional[int] = ...) -> None: ... 539def filling() -> bool: ... 540def begin_fill() -> None: ... 541def end_fill() -> None: ... 542def dot(size: Optional[int] = ..., *color: _Color) -> None: ... 543def write(arg: object, move: bool = ..., align: str = ..., font: Tuple[str, int, str] = ...) -> None: ... 544def begin_poly() -> None: ... 545def end_poly() -> None: ... 546def get_poly() -> Optional[_PolygonCoords]: ... 547def getscreen() -> TurtleScreen: ... 548def getturtle() -> Turtle: ... 549 550getpen = getturtle 551 552def onrelease(fun: Callable[[float, float], Any], btn: int = ..., add: Optional[Any] = ...) -> None: ... 553def ondrag(fun: Callable[[float, float], Any], btn: int = ..., add: Optional[Any] = ...) -> None: ... 554def undo() -> None: ... 555 556turtlesize = shapesize 557 558# Functions copied from RawTurtle with a few tweaks: 559 560def clone() -> Turtle: ... 561 562# Extra functions present only in the global scope: 563 564done = mainloop 565