-
-
Notifications
You must be signed in to change notification settings - Fork 487
Description
Describe the bug
PRAW includes respectable coverage type annotations where practical (particularly given its dynamic nature), which have the potential to be very helpful to downstream developers seeking to catch many bugs statically without having to hit the live Reddit API, as well as PRAW development itself.
PRAW modules that use relative imports include the following block, presumably to help the type checker find the parent package (example from praw/reddit.py):
if TYPE_CHECKING: # pragma: no cover
from .. import praw...with the number of .. increasing with each level deep the given module is in the package. However, this results in the relative import going outside the package, which is neither valid Python (without PEP 420 namespace packages) nor works with MyPy, as it means it recurses into a directory that is not itself a package. In addition, one file (praw/objector.py) has an extra .. (the only file that did not consistently follow this pattern), either due to a typo or being previously located in a subpackage.
The net result is that running mypy (and presumably other type checkers) on the PRAW package, or on user code importing praw after adding a py.typed file to the PRAW package root per PEP 561, will fail with a critical error and prevent type checking entirely, as the . Furthermore, this not only prevents type-checking what is often the most critical code in a Reddit-bot or client (along with PRAW's own correctness), but also causes stubgen to fail with a similar error, so users can't even provide their own stubs.
To Reproduce
Steps to reproduce the behavior:
- Install PRAW and MyPy
- Run
stubgen -p praw-> Error occurs - Run
mypy $SITE_PACKAGES/praw-> Error occurs - Run
touch $SITE_PACKAGES/praw/py.typedto enable type-checking for PRAW and thenmypy $YOUR_PACKAGEon a local package that users PRAW -> Error occurs
Expected behavior
Type checking to work without errors. To fix this issue, the relative imports for TYPE_CHECKING only can be simply changed to absolute imports (import praw), which are shorter, simpler and other than avoiding the errors/invalid behavior, have the exact same intended effect. Because all of these blocks are protected by if TYPE_CHECKING, there is zero runtime impact, it just fixes the type checker.
In addition, to allow PRAW users to take advantage of PRAW's existing type hints to type check their own code, I advise per PEP 561 adding an empty file named py.typed to the root of the package.
I've manually hacked it in there, and it provided helpful type hinting with no major issues and minimal false positives . However, to make this work for other devs locally and on our CIs, we have to run a script that implements these same hacks, which is fragile, ugly and has the potential to break the install. Fixing the import statements will alleviate 90% of that (we'll just have to touch one file), and adding the py.typed will do the rest.
I'm happy to submit a PR to fix this; let me know and I'll go ahead. I'd also be interested in cleaning up the remaining flagged typing inconsistencies in PRAW and getting it set up to continually check for bad types (e.g. with pre-commit, either locally or CI-only) so there isn't a regression on this front. I'd also hope to help add typing to prawcore, if that's desirable, as it currently seems to be missing at least some of it. Thanks!
Code/Logs
Error with mypy $SITE_PACKAGES/praw:
$SITE_PACKAGES/praw/models/base.py:6: error: No parent module -- cannot perform relative import
Found 1 error in 1 file (errors prevented further checking)
Same error with stubgen -p praw:
Critical error during semantic analysis: $SITE_PACKAGES/praw/models/base.py:6: error: No parent module -- cannot perform relative import
System Info
- OS: Windows 8.1 x64, Ubuntu 20.04 LTS, Raspbian 10
- Python: 3.7, 3.8, 3.9
- PRAW Version: 7.2.0, 7.3.0, latest
master - MyPy Version: 0.902, 0.910 (latest as of when I tested)