bitarray icon indicating copy to clipboard operation
bitarray copied to clipboard

Type hint bug for frozenbitarray?

Open larstokle opened this issue 3 years ago • 4 comments

It seems that type checkers give frozenbitarray() & bitarray() -> bitarray etc., whereas the implementation gives frozenbitarray. The implementation is a nice feature when one knows about it, and it would be nice if the type hints would reflect this.

It looks to me, after reading some mypy docs, like it perhaps can be solved with some TypeVar bound to bitarray for self and the return type in __init__.pyi. However, I do not know enough about bitarray and type hinting to know if this would be the way to go.

larstokle avatar Apr 28 '22 23:04 larstokle

Thank for your using bitarray! I'm not too familiar with mypy myself, but it would indeed be nice if mypy or other type checker could reflect this. I just wrote a file .t.py:

from bitarray import bitarray, frozenbitarray
a: frozenbitarray = frozenbitarray() & bitarray()
print(type(a))

Then:

$ python t.py
<class 'bitarray.frozenbitarray'>
$ mypy t.py
t.py:2: error: Incompatible types in assignment (expression has type "bitarray", variable has type "frozenbitarray")
Found 1 error in 1 file (checked 1 source file)

So mypy thinks a is of type bitarray even though it really is frozenbitarray.

I'm not familiar enough with type hinting to solve this, but I'm visiting PyCon 2022 over the next few days, and I'm sure someone can tell me the answer.

ilanschnell avatar Apr 29 '22 01:04 ilanschnell

That was a quick response! 👍 Yes, this is, in essence, what I am experiencing. :)

I see that this also extends to frozenbitarray() & frozenbitarray() which type checks to bitarray, and also to other operators like | and ^, which I guess makes sense from the implementation of frozenbitarray.

If you want to try something, I suspect that making the following changes to the right methods in __init__.pyi should type check correctly:

BA_T1 = TypeVar("BA_T1", bound=bitarray)
BA_T2 = TypeVar("BA_T2", bound=bitarray)
[...]
    def __and__(self: BA_T1, other: BA_T2) -> BA_T1: ...

But do not take my word for it, as I guess there might be some unwanted consequences like usual when I am trying to generalise types hints like this. As you say, the people at PyCon probably have better input on this.

larstokle avatar Apr 29 '22 03:04 larstokle

What you are suggesting makes sense, as frozenbitarray is a subtype of bitarray. However, I still get the same error (I'm using the latest mypy 0.950). Let's see what the mypy expcerts say...

ilanschnell avatar Apr 29 '22 04:04 ilanschnell