Type checker reports error when using the `Use` class in a boolean operator
Here is a minimal example:
schema = Schema({
'party': And(str, Use(str.lower), lambda s: s in ('alice', 'bob'))
})
This code works fine. However, the type checker reports an error saying that a Use instance cannot be used as an argument of And(). This is true in both VS Code (which uses pyright by default) and PyCharm.
I'm using similar validation rules in many places. As a result, my code is full of # type: ignores because otherwise I will have to disable type checking completely.
Is it possible to solve this issue?
I am not able to reproduce your issue. Is mypy also complaining ? what version of python/schema are you using ?
Mypy does not complain in that minimal example (even when in strict mode), but does complain when moving And out of the schema:
And(str, Use(str.lower), lambda s: s in ('alice', 'bob'))
# Mypy reports: Argument 2 to "And" has incompatible type "Use"; expected "Callable[..., Any]"
# VS Code (pyright) reports: The type 'Use' is incompatible with the types 'Schema' and '(...) -> Any'
# PyCharm reports something similar to VS Code
{'party': And(str, Use(str.lower), lambda s: s in ('alice', 'bob'))}
# Mypy still complains
Schema({'party': And(str, Use(str.lower), lambda s: s in ('alice', 'bob'))})
# Mypy does not report anything
I haven't used Mypy before, so I'm not sure if it is a bug.
I'm using schema 0.7.7 on Python 3.12. Mypy's version 1.11.1.
ok, I now have the same issue. No solution yet but as a dirty workaround you can replace
Use(str.lower)
with
eval("Use(str.lower)")
ok, I now have the same issue. No solution yet but as a dirty workaround you can replace
Use(str.lower)with
eval("Use(str.lower)")
That's really ugly. Why not just ignore the error?
# type: ignore
@mutricyl By the way, not to criticize, but I noticed your markdown code snippet looks like this (copy and pasted from your comment):
> ```python
> print("Hello World!")
> ```
Those greater than symbols are unnecessary. Just typing ``` is sufficient:
```python
print("Hello World!")
```
Hope this helps!
ok, I now have the same issue. No solution yet but as a dirty workaround you can replace
Use(str.lower)with
eval("Use(str.lower)")
Understood, thank you. Now I've put all schemas in a single file, so I can just disable type checking for that file. I'm comfortable with this.
I agree that the eval trick is ugly. You can narrow the type ignore to the specific issue : # type: ignore[call-arg] likewise if pyright complains: # pyright: ignore[<whateverPyrightIssueName>]
Apparently mypy does not consider Use as being a callable. I have added a __call__ function to Use class and it looks to solve the issue.
class Use:
(...)
def __call__(self, *args: Any, **kwds: Any) -> Any:
pass
However I still have an issue mixing And and Or.