Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure PlatformDirs is valid superclass type for mypy AND not an abstract class for other checkers #295

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions src/platformdirs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@
from pathlib import Path
from typing import Literal

if sys.platform == "win32":
from platformdirs.windows import Windows as _Result
elif sys.platform == "darwin":
from platformdirs.macos import MacOS as _Result
else:
from platformdirs.unix import Unix as _Result

def _set_platform_dir_class() -> type[PlatformDirsABC]:
if sys.platform == "win32":
from platformdirs.windows import Windows as Result # noqa: PLC0415
elif sys.platform == "darwin":
from platformdirs.macos import MacOS as Result # noqa: PLC0415
else:
from platformdirs.unix import Unix as Result # noqa: PLC0415

def _set_platform_dir_class() -> type[PlatformDirsABC]:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that if python/mypy#10962 is fixed, this should become

Suggested change
def _set_platform_dir_class() -> type[PlatformDirsABC]:
def _set_platform_dir_class() -> type[_Result | Android]:

But that'd require duplicating the from platformdirs.android import Android import in the TYPE_CHECKING block to keep it a lazy import. And it brings no benefit at the current time.

if os.getenv("ANDROID_DATA") == "/data" and os.getenv("ANDROID_ROOT") == "/system":
if os.getenv("SHELL") or os.getenv("PREFIX"):
return Result
return _Result

from platformdirs.android import _android_folder # noqa: PLC0415

Expand All @@ -39,10 +39,14 @@ def _set_platform_dir_class() -> type[PlatformDirsABC]:

return Android # return to avoid redefinition of a result

return Result
return _Result


PlatformDirs = _set_platform_dir_class() #: Currently active platform
if TYPE_CHECKING:
# Work around mypy issue: https://github.com/python/mypy/issues/10962
PlatformDirs = _Result
else:
PlatformDirs = _set_platform_dir_class() #: Currently active platform
AppDirs = PlatformDirs #: Backwards compatibility with appdirs


Expand Down
2 changes: 1 addition & 1 deletion tests/test_android.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def test_android_folder_from_jnius(mocker: MockerFixture, monkeypatch: pytest.Mo

_android_folder.cache_clear()

if PlatformDirs is Android:
if PlatformDirs is Android: # type: ignore[comparison-overlap] # See https://github.com/platformdirs/platformdirs/pull/295
import jnius # pragma: no cover # noqa: PLC0415

autoclass = mocker.spy(jnius, "autoclass") # pragma: no cover
Expand Down
9 changes: 9 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,12 @@ def test_no_ctypes() -> None:
import platformdirs # noqa: PLC0415

assert platformdirs


def test_mypy_subclassing() -> None:
# Ensure that PlatformDirs / AppDirs is seen as a valid superclass by mypy
# This is a static type-checking test to ensure we work around
# the following mypy issue: https://github.com/python/mypy/issues/10962
class PlatformDirsSubclass(platformdirs.PlatformDirs): ...

class AppDirsSubclass(platformdirs.AppDirs): ...
Loading