tompollard / tableone

Create "Table 1" for research papers in Python
https://pypi.python.org/pypi/tableone/
MIT License
159 stars 38 forks source link

type hints: fix errors and warnings reported by mypy #148

Closed tompollard closed 1 year ago

tompollard commented 1 year ago

mypy is a type checker. It can be installed with:

pip install mypy

...and then run with:

mypy tableone/tableone.py

mypy reports the following issues:

tableone/modality.py:13: error: Skipping analyzing "scipy.special": module is installed, but missing library stubs or py.typed marker  [import]
tableone/modality.py:15: error: Skipping analyzing "scipy.optimize": module is installed, but missing library stubs or py.typed marker  [import]
tableone/modality.py:17: error: Skipping analyzing "pandas": module is installed, but missing library stubs or py.typed marker  [import]
tableone/tableone.py:10: error: Skipping analyzing "pandas": module is installed, but missing library stubs or py.typed marker  [import]
tableone/tableone.py:11: error: Skipping analyzing "scipy": module is installed, but missing library stubs or py.typed marker  [import]
tableone/tableone.py:12: error: Skipping analyzing "statsmodels.stats": module is installed, but missing library stubs or py.typed marker  [import]
tableone/tableone.py:12: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
tableone/tableone.py:13: error: Library stubs not installed for "tabulate"  [import]
tableone/tableone.py:13: note: Hint: "python3 -m pip install types-tabulate"
tableone/tableone.py:13: note: (or run "mypy --install-types" to install all missing stub packages)
tableone/tableone.py:229: error: Incompatible types in assignment (expression has type "Optional[Dict[Any, Any]]", variable has type "Dict[Any, Any]")  [assignment]
tableone/tableone.py:245: error: Incompatible types in assignment (expression has type "bool", variable has type "Literal[True]")  [assignment]
tableone/tableone.py:256: error: Incompatible types in assignment (expression has type "bool", variable has type "Literal[True]")  [assignment]
tableone/tableone.py:257: error: Incompatible types in assignment (expression has type "bool", variable has type "Literal[True]")  [assignment]
tableone/tableone.py:258: error: Incompatible types in assignment (expression has type "bool", variable has type "Literal[True]")  [assignment]
tableone/tableone.py:291: error: Argument 1 to "set" has incompatible type "Optional[List[Any]]"; expected "Iterable[Any]"  [arg-type]
tableone/tableone.py:292: error: Argument 1 to "set" has incompatible type "Optional[List[Any]]"; expected "Iterable[Any]"  [arg-type]
tableone/tableone.py:308: error: Item "None" of "Optional[List[Any]]" has no attribute "__iter__" (not iterable)  [union-attr]
tableone/tableone.py:340: error: Argument 1 to "list" has incompatible type "Optional[List[Any]]"; expected "Iterable[Any]"  [arg-type]
tableone/tableone.py:341: error: Item "None" of "Optional[List[Any]]" has no attribute "__iter__" (not iterable)  [union-attr]
tableone/tableone.py:342: error: Unsupported left operand type for + ("None")  [operator]
tableone/tableone.py:342: note: Left operand is of type "Optional[List[Any]]"
tableone/tableone.py:362: error: Need type annotation for "_warnings" (hint: "_warnings: Dict[<type>, <type>] = ...")  [var-annotated]
tableone/tableone.py:945: error: Unsupported right operand type for in ("Union[int, Dict[Any, Any]]")  [operator]
tableone/tableone.py:946: error: Value of type "Union[int, Dict[Any, Any]]" is not indexable  [index]
tableone/tableone.py:1076: error: No overload variant of "__add__" of "list" matches argument type "None"  [operator]
tableone/tableone.py:1076: note: Possible overload variants:
tableone/tableone.py:1076: note:     def __add__(self, List[Any], /) -> List[Any]
tableone/tableone.py:1076: note:     def [_S] __add__(self, List[_S], /) -> List[Union[_S, Any]]
tableone/tableone.py:1076: note: Right operand is of type "Optional[List[Any]]"
tableone/tableone.py:1151: error: No overload variant of "__add__" of "list" matches argument type "None"  [operator]
tableone/tableone.py:1151: note: Possible overload variants:
tableone/tableone.py:1151: note:     def __add__(self, List[Any], /) -> List[Any]
tableone/tableone.py:1151: note:     def [_S] __add__(self, List[_S], /) -> List[Union[_S, Any]]
tableone/tableone.py:1151: note: Right operand is of type "Optional[List[Any]]"
tableone/tableone.py:1619: error: Unsupported right operand type for in ("Optional[List[Any]]")  [operator]
Found 24 errors in 2 files (checked 1 source file)

Fix these issues!

MartinBernstorff commented 1 year ago

Awesome to see you working on this!

Would highly recommend support pyright in addition/instead, for reasons listed here: https://github.com/microsoft/pyright/blob/main/docs/mypy-comparison.md

Moreover, pyright ships with VSCode and can be enabled in the editor by setting type check to basic.

tompollard commented 1 year ago

Thanks Martin, I'll take a look!

MartinBernstorff commented 1 year ago

Sure thing!

If tableone is partially typed, pyright will definitely lead to a more robust package since it infers types – mypy will only find mistakes if you have two type hints that conflict.

Feel free to ping me if you want help, we've recently migrated a few codebases to pyright.

tompollard commented 1 year ago

Thanks @MartinBernstorff, I would definitely appreciate your help in understanding how best to implement this. Any chance we could find a time for a 30min chat? I'll drop you an email!

tompollard commented 1 year ago

I've added pyright to the workflow in the following PR: https://github.com/tompollard/tableone/actions/runs/4852818564/jobs/8648281298.

Plan is to fix the issues in a separate branch, so the PR can eventually be merged.

tompollard commented 1 year ago

We are now running type testing with pyright in the github workflow. Many of the errors are currently being ignored, so I have raised a new issue to remind us to address this: https://github.com/tompollard/tableone/issues/155