Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ Section Order:

<!-- Your changes go here -->

### Changed

- (Internal) Better type hinting

## [4.0.1] - 2026-02-27

### Removed
Expand Down
6 changes: 6 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ dependencies = [
"django-esi>=8.3.1",
"django-eveonline-sde>=0.0.1b1",
]
optional-dependencies.tests-allianceauth-development = [
"allianceauth @ git+https://gitlab.com/allianceauth/allianceauth#egg=master",
"coverage",
"django-webtest",
"requests-mock",
]
optional-dependencies.tests-allianceauth-latest = [
"coverage",
"django-webtest",
Expand Down
21 changes: 15 additions & 6 deletions sovtimer/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

# Standard Library
import logging
import typing
from typing import Any

# Third Party
Expand All @@ -24,6 +25,14 @@
__version__,
)

if typing.TYPE_CHECKING:
# Alliance Auth
from esi.stubs import (
AllianceDetail,
SovereigntyCampaignsGet,
SovereigntyStructuresGet,
)

# ESI client
esi = ESIClientProvider(
# Use the latest compatibility date, see https://esi.evetech.net/meta/compatibility-dates
Expand Down Expand Up @@ -108,7 +117,7 @@ def result( # pylint: disable=too-many-arguments, too-many-positional-arguments
@classmethod
def get_alliances_alliance_id(
cls, alliance_id: int, force_refresh: bool = False
) -> dict | None:
) -> "AllianceDetail | None":
"""
Get alliance information from ESI.

Expand All @@ -117,7 +126,7 @@ def get_alliances_alliance_id(
:param force_refresh: Whether to force a refresh of the data from ESI, bypassing any caches.
:type force_refresh: bool
:return: Alliance information or None if an error occurred.
:rtype: dict | None
:rtype: AllianceDetail | None
"""

logger.debug(
Expand All @@ -134,12 +143,12 @@ def get_alliances_alliance_id(
@classmethod
def get_sovereignty_campaigns(
cls, force_refresh: bool = False
) -> list[dict] | None:
) -> "list[SovereigntyCampaignsGet] | None":
"""
Get sovereignty campaigns from ESI.

:return: List of sovereignty campaigns or None if an error occurred.
:rtype: list[dict] | None
:rtype: list[SovereigntyCampaignsGet] | None
"""

logger.debug("Fetching sovereignty campaigns from ESI...")
Expand All @@ -152,12 +161,12 @@ def get_sovereignty_campaigns(
@classmethod
def get_sovereignty_structures(
cls, force_refresh: bool = False
) -> list[dict] | None:
) -> "list[SovereigntyStructuresGet] | None":
"""
Get sovereignty structures from ESI.

:return: List of sovereignty structures or None if an error occurred.
:rtype: list[dict] | None
:rtype: list[SovereigntyStructuresGet] | None
"""

logger.debug("Fetching sovereignty structures from ESI...")
Expand Down
41 changes: 41 additions & 0 deletions sovtimer/tests/test_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
"""

# Standard Library
import importlib
import logging
import sys
import types
import typing
from http import HTTPStatus
from unittest.mock import MagicMock, patch

Expand All @@ -18,6 +22,43 @@
from sovtimer.tests import BaseTestCase


class TestTypingTypeCheckingIfCondition(BaseTestCase):
def test_when_typing_TYPE_CHECKING_true_then_stub_types_are_imported_into_module_namespace(
self,
):
"""
Test that when `typing.TYPE_CHECKING` is set to `True`, the stub types from `esi.stubs` are imported into the module namespace.

:return:
:rtype:
"""
fake_stubs = types.ModuleType("esi.stubs")
fake_stubs.AllianceDetail = type("AllianceDetail", (), {})
fake_stubs.SovereigntyCampaignsGet = type("SovereigntyCampaignsGet", (), {})
fake_stubs.SovereigntyStructuresGet = type("SovereigntyStructuresGet", (), {})

original_sys_modules = sys.modules.copy()

try:
sys.modules["esi.stubs"] = fake_stubs

with patch.object(typing, "TYPE_CHECKING", True):
providers = importlib.import_module("sovtimer.providers")
importlib.reload(providers)

self.assertTrue(hasattr(providers, "AllianceDetail"))
self.assertTrue(hasattr(providers, "SovereigntyCampaignsGet"))
self.assertTrue(hasattr(providers, "SovereigntyStructuresGet"))
finally:
sys.modules.clear()
sys.modules.update(original_sys_modules)

try:
importlib.reload(importlib.import_module("sovtimer.providers"))
except Exception:
pass


class TestESIHandlerResult(BaseTestCase):
"""
Test the ESIHandler.result method.
Expand Down
10 changes: 5 additions & 5 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
requires =
tox>=4.2
env_list =
allianceauth-{latest, testing}
allianceauth-{latest, development}
py{312, 311, 310}
no_package = true
usedevelop = True
Expand All @@ -25,10 +25,10 @@ commands =
set_env =
DJANGO_SETTINGS_MODULE = testauth.settings.local
install_command =
python -m pip install -e ".[tests-allianceauth-latest]" -U {opts} {packages}
python -m pip install --ignore-requires-python -e ".[tests-allianceauth-latest]" -U {opts} {packages}

[testenv:allianceauth-testing]
[testenv:allianceauth-development]
set_env =
DJANGO_SETTINGS_MODULE = testauth.settings.testing.local
DJANGO_SETTINGS_MODULE = testauth.settings.development.local
install_command =
python -m pip install -e ".[tests-allianceauth-testing]" -U {opts} {packages}
python -m pip install --ignore-requires-python -e ".[tests-allianceauth-development]" -U {opts} {packages}
Loading