JohannesBuchner / imagehash

A Python Perceptual Image Hashing Module
BSD 2-Clause "Simplified" License
3.28k stars 331 forks source link

Help wanted to use `ImageHash` with `pyright` in `typeCheckingMode = strict` #206

Closed adamtheturtle closed 10 months ago

adamtheturtle commented 10 months ago

Create a directory with the following files:

# pyproject.toml

[tool.pyright]
typeCheckingMode = "strict"
# example.py

# This matches https://github.com/JohannesBuchner/imagehash#basic-usage.

from PIL import Image
import imagehash
hash = imagehash.average_hash(Image.open('tests/data/imagehash.png'))

Run the following:

$ pip install imagehash pyright
$ pyright example.py

See the following error:

/Users/adam/Desktop/example/example.py
  /Users/adam/Desktop/example/example.py:3:8 - error: Type of "average_hash" is partially unknown
    Type of "average_hash" is "(image: Image, hash_size: int = 8, mean: Unknown = numpy.mean) -> ImageHash" (reportUnknownMemberType)

The issue is that the type of mean is Unknown to pyright.

I see in the codebase that mean is typed as MeanFunc.

MeanFunc is a type alias to Callable, with the parameter and return types set conditionally. pyright does not work well with those conditionals.

I see two conditions which lead to the type inference difficulty:

  1. Numpy array typing

https://github.com/JohannesBuchner/imagehash/blob/38005924fe9be17cfed145bbc6d83b09ef8be025/imagehash/__init__.py#L142-L147

  1. A potential type error

https://github.com/JohannesBuchner/imagehash/blob/38005924fe9be17cfed145bbc6d83b09ef8be025/imagehash/__init__.py#L156-L161

I'm happy to contribute changes to this project to get pyright passing on my project, and I would like some guidance.

For (1): Can this be removed? Python 3.6 has been EOL'd for a couple of years (EOL date 2021-12-23).

For (2): Can you give some insight into when the TypeError may be expected?

JohannesBuchner commented 10 months ago

ad 1: no, imagehash supports very old versions (python 2 was only removed very recently). ad 2: you would have to @ tag the person here who wrote that code.

To give additional guidance, as you may be able to see from previous issues, type checking has been somewhat of a headache for me. I wish it had been possible to keep a single script imagehash.py. It breaks the appeal of imagehash being a simple self-contained file that can be read and understood. TLDR: KISS.

adamtheturtle commented 10 months ago

Thank you for the response @JohannesBuchner . I will close, and in my project I have copied average_hash to achieve type safety.