Skip to content

Commit 4b502c5

Browse files
committed
MNT: Add type annotations and improve function signatures.
>> - Enhanced type annotations across botcity/core/bot.py and botcity/core/cv2find.py for better type safety and developer experience. >> - Added type hints to parameters and return types in key methods like find, find_all, find_until, and _load_cv2. >> - Ensured proper usage of Optional, List, Tuple, and Generator in function definitions. >> - Standardized method signatures for consistency, explicitly defining default values and expected data types. >> - Updated imports to include necessary types like Union, Optional, List, Tuple, Dict, and Generator.
1 parent d42167e commit 4b502c5

File tree

2 files changed

+96
-69
lines changed

2 files changed

+96
-69
lines changed

botcity/core/bot.py

Lines changed: 84 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
import subprocess
77
import time
88
import webbrowser
9-
from typing import Union, Tuple, Optional, List
10-
9+
from typing import Union, Tuple, Optional, List, Dict, Box, Generator, Any
10+
from numpy import ndarray
1111

1212
import pyperclip
1313
from botcity.base import BaseBot, State
@@ -121,7 +121,7 @@ def app(self, app: Union["Application", "WindowSpecification"]):
121121
# Display
122122
##########
123123

124-
def add_image(self, label, path):
124+
def add_image(self, label: str, path: str) -> None:
125125
"""
126126
Add an image into the state image map.
127127
@@ -131,7 +131,7 @@ def add_image(self, label, path):
131131
"""
132132
self.state.map_images[label] = path
133133

134-
def get_image_from_map(self, label):
134+
def get_image_from_map(self, label: str) -> None:
135135
"""
136136
Return an image from teh state image map.
137137
@@ -149,25 +149,25 @@ def get_image_from_map(self, label):
149149

150150
def find_multiple(
151151
self,
152-
labels,
153-
x=None,
154-
y=None,
155-
width=None,
156-
height=None,
152+
labels: List,
153+
x: int = 0,
154+
y: int = 0,
155+
width: Optional[int] = None,
156+
height: Optional[int] = None,
157157
*,
158-
threshold=None,
159-
matching=0.9,
160-
waiting_time=10000,
161-
best=True,
162-
grayscale=False,
163-
):
158+
threshold: Optional[int] = None,
159+
matching: float = 0.9,
160+
waiting_time: int = 10000,
161+
best: bool = True,
162+
grayscale: bool = False,
163+
) -> Dict:
164164
"""
165165
Find multiple elements defined by label on screen until a timeout happens.
166166
167167
Args:
168168
labels (list): A list of image identifiers
169-
x (int, optional): Search region start position x. Defaults to 0.
170-
y (int, optional): Search region start position y. Defaults to 0.
169+
x (int): Search region start position x. Defaults to 0.
170+
y (int): Search region start position y. Defaults to 0.
171171
width (int, optional): Search region width. Defaults to screen width.
172172
height (int, optional): Search region height. Defaults to screen height.
173173
threshold (int, optional): The threshold to be applied when doing grayscale search.
@@ -190,8 +190,6 @@ def _to_dict(lbs, elems):
190190
return {k: v for k, v in zip(lbs, elems)}
191191

192192
screen_w, screen_h = self._fix_display_size()
193-
x = x or 0
194-
y = y or 0
195193
w = width or screen_w
196194
h = height or screen_h
197195

@@ -253,7 +251,14 @@ def _fix_display_size(self) -> Tuple[int, int]:
253251

254252
return int(width * 2), int(height * 2)
255253

256-
def _find_multiple_helper(self, haystack, region, confidence, grayscale, needle):
254+
def _find_multiple_helper(
255+
self,
256+
haystack: Image.Image,
257+
region: Tuple[int, int, int, int],
258+
confidence: float,
259+
grayscale: bool,
260+
needle: Union[Image.Image, ndarray, str]
261+
) -> Union[Box, None]:
257262
ele = cv2find.locate_all_opencv(
258263
needle, haystack, region=region, confidence=confidence, grayscale=grayscale
259264
)
@@ -265,18 +270,18 @@ def _find_multiple_helper(self, haystack, region, confidence, grayscale, needle)
265270

266271
def find(
267272
self,
268-
label,
269-
x=None,
270-
y=None,
271-
width=None,
272-
height=None,
273+
label: str,
274+
x: Optional[int] = None,
275+
y: Optional[int] = None,
276+
width: Optional[int] = None,
277+
height: Optional[int] = None,
273278
*,
274-
threshold=None,
275-
matching=0.9,
276-
waiting_time=10000,
277-
best=True,
278-
grayscale=False,
279-
):
279+
threshold: Optional[int] = None,
280+
matching: float = 0.9,
281+
waiting_time: int = 10000,
282+
best: bool = True,
283+
grayscale: bool = False,
284+
) -> Tuple[int, int, int, int] | None:
280285
"""
281286
Find an element defined by label on screen until a timeout happens.
282287
@@ -315,18 +320,18 @@ def find(
315320

316321
def find_until(
317322
self,
318-
label,
319-
x=None,
320-
y=None,
321-
width=None,
322-
height=None,
323+
label: str,
324+
x: Optional[int] = None,
325+
y: Optional[int] = None,
326+
width: Optional[int] = None,
327+
height: Optional[int] = None,
323328
*,
324-
threshold=None,
325-
matching=0.9,
326-
waiting_time=10000,
327-
best=True,
328-
grayscale=False,
329-
):
329+
threshold: Optional[int] = None,
330+
matching: float = 0.9,
331+
waiting_time: int = 10000,
332+
best: bool = True,
333+
grayscale: bool = False,
334+
) -> Tuple[int, int, int, int] | None:
330335
"""
331336
Find an element defined by label on screen until a timeout happens.
332337
@@ -399,17 +404,17 @@ def find_until(
399404

400405
def find_all(
401406
self,
402-
label,
403-
x=None,
404-
y=None,
405-
width=None,
406-
height=None,
407+
label: str,
408+
x: Optional[int] = None,
409+
y: Optional[int] = None,
410+
width: Optional[int] = None,
411+
height: Optional[int] = None,
407412
*,
408-
threshold=None,
409-
matching=0.9,
410-
waiting_time=10000,
411-
grayscale=False,
412-
):
413+
threshold: Optional[int] = None,
414+
matching: float = 0.9,
415+
waiting_time: int = 10000,
416+
grayscale: bool = False,
417+
) -> Generator[Box, Any, None]:
413418
"""
414419
Find all elements defined by label on screen until a timeout happens.
415420
@@ -504,16 +509,16 @@ def find_same(item, items):
504509

505510
def find_text(
506511
self,
507-
label,
508-
x=None,
509-
y=None,
510-
width=None,
511-
height=None,
512+
label: str,
513+
x: Optional[int] = None,
514+
y: Optional[int] = None,
515+
width: Optional[int] = None,
516+
height: Optional[int] = None,
512517
*,
513-
threshold=None,
514-
matching=0.9,
515-
waiting_time=10000,
516-
best=True,
518+
threshold: Optional[int] = None,
519+
matching: float = 0.9,
520+
waiting_time: int = 10000,
521+
best: bool = True,
517522
):
518523
"""
519524
Find an element defined by label on screen until a timeout happens.
@@ -570,7 +575,7 @@ def find_process(self, name: str = None, pid: str = None) -> Process:
570575
pass
571576
return None
572577

573-
def terminate_process(self, process: Process):
578+
def terminate_process(self, process: Process) -> None:
574579
"""
575580
Terminate the process via the received Process object.
576581
@@ -582,7 +587,7 @@ def terminate_process(self, process: Process):
582587
if process.is_running():
583588
raise Exception("Terminate process failed")
584589

585-
def get_last_element(self):
590+
def get_last_element(self) -> Tuple[int, int, int, int]:
586591
"""
587592
Return the last element found.
588593
@@ -681,8 +686,14 @@ def save_screenshot(self, path: str) -> None:
681686
self.screenshot(path)
682687

683688
def get_element_coords(
684-
self, label, x=None, y=None, width=None, height=None, matching=0.9, best=True
685-
):
689+
self, label: str,
690+
x: Optional[int] = None,
691+
y: Optional[int] = None,
692+
width: Optional[int] = None,
693+
height: Optional[int] = None,
694+
matching: float = 0.9,
695+
best: bool = True
696+
) -> Tuple[int, int] | Tuple[None, None]:
686697
"""
687698
Find an element defined by label on screen and returns its coordinates.
688699
@@ -736,7 +747,14 @@ def get_element_coords(
736747
return ele.left, ele.top
737748

738749
def get_element_coords_centered(
739-
self, label, x=None, y=None, width=None, height=None, matching=0.9, best=True
750+
self,
751+
label: str,
752+
x: Optional[int] = None,
753+
y: Optional[int] = None,
754+
width: Optional[int] = None,
755+
height: Optional[int] = None,
756+
matching: float = 0.9,
757+
best: bool = True
740758
):
741759
"""
742760
Find an element defined by label on screen and returns its centered coordinates.

botcity/core/cv2find.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import collections
3434
import cv2
3535
import numpy
36+
from PIL.Image import Image
37+
from typing import Union, Tuple, Optional, Generator, Any
3638

3739
RUNNING_CV_2 = cv2.__version__[0] < '3'
3840

@@ -46,7 +48,7 @@
4648
LOAD_GRAYSCALE = cv2.IMREAD_GRAYSCALE
4749

4850

49-
def _load_cv2(img, grayscale=False):
51+
def _load_cv2(img: Union[Image, numpy.ndarray, str], grayscale: bool = False) -> numpy.ndarray:
5052
"""
5153
TODO
5254
"""
@@ -86,8 +88,15 @@ def _load_cv2(img, grayscale=False):
8688
return img_cv
8789

8890

89-
def locate_all_opencv(needle_image, haystack_image, grayscale=False, limit=10000, region=None, step=1,
90-
confidence=0.999):
91+
def locate_all_opencv(
92+
needle_image: Union[Image, numpy.ndarray, str],
93+
haystack_image: Union[Image, numpy.ndarray, str],
94+
grayscale: bool = False,
95+
limit: int = 10000,
96+
region: Optional[Tuple[int, int, int, int]] = None,
97+
step: int = 1,
98+
confidence: float = 0.999
99+
) -> Generator[Box, Any, None]:
91100
"""
92101
TODO - rewrite this
93102
faster but more memory-intensive than pure python

0 commit comments

Comments
 (0)