SuffolkLITLab / FormFyxer

A tool for learning about and pre-processing forms
MIT License
11 stars 1 forks source link

Fix typing in get_possible_radios #120

Closed nonprofittechy closed 1 year ago

nonprofittechy commented 1 year ago

Run python -m mypy . formfyxer/pdf_wrangling.py:1110: error: Item "str" of "Union[str, BinaryIO, Mat]" has no attribute "shape" [union-attr] formfyxer/pdf_wrangling.py:1110: error: Item "BinaryIO" of "Union[str, BinaryIO, Mat]" has no attribute "shape" [union-attr] formfyxer/pdf_wrangling.py:1158: error: Item "str" of "Union[str, BinaryIO, Mat]" has no attribute "shape" [union-attr] formfyxer/pdf_wrangling.py:1158: error: Item "BinaryIO" of "Union[str, BinaryIO, Mat]" has no attribute "shape" [union-attr] formfyxer/tests/test_lit_explorer.py:47: note: By default the bodies of untyped functions are not checked, consider using --check-untyped-defs [annotation-unchecked]

looks like the problem is that we re-use the variable img -- starts as a string and gets turned into a cv2 object. so typing is messed up.

def get_possible_radios(img: Union[str, BinaryIO, cv2.Mat]):
    """Even though it's called "radios", it just gets things shaped like circles, not
    doing any semantic analysis yet."""
    if isinstance(img, str):
        # 0 is for the flags: means nothing special is being used
        img = cv2.imread(img, 0)
    if isinstance(img, BinaryIO):
        img = cv2.imdecode(np.frombuffer(img.read(), np.uint8), 0)

    rows = img.shape[0]
nonprofittechy commented 1 year ago

Possible fix to try (use assert to tell mypy we have the proper type by the relevant line)

def get_possible_radios(img: Union[str, BinaryIO, cv2.Mat]):
    """Even though it's called "radios", it just gets things shaped like circles, not
    doing any semantic analysis yet."""
    if isinstance(img, str):
        # 0 is for the flags: means nothing special is being used
        img = cv2.imread(img, 0)
    elif isinstance(img, BinaryIO):
        img = cv2.imdecode(np.frombuffer(img.read(), np.uint8), 0)

    # Assure mypy that the type of img at this point is cv2.Mat
    assert isinstance(img, cv2.Mat), "img must be of type cv2.Mat here"

    rows = img.shape[0]
BryceStevenWilley commented 1 year ago

Fixed in #121. This was fine on mypy 1.2.0, and broke on mypy 1.3.0; I think mypy started changing how they handle typing with isinstance and unions in https://github.com/python/mypy/pull/14923, which is the best possible candidate to what messed this up. Not sure how to fix it, I'm fairly confident the original code is fine, but eh.