mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-01-28 22:59:03 -06:00
Adds example type checking configuration, with a default broard ignore and a tight scoped check
This commit is contained in:
@@ -154,10 +154,6 @@ typing = [
|
|||||||
[tool.uv]
|
[tool.uv]
|
||||||
required-version = ">=0.9.0"
|
required-version = ">=0.9.0"
|
||||||
package = false
|
package = false
|
||||||
environments = [
|
|
||||||
"sys_platform == 'darwin'",
|
|
||||||
"sys_platform == 'linux'",
|
|
||||||
]
|
|
||||||
|
|
||||||
[tool.uv.sources]
|
[tool.uv.sources]
|
||||||
# Markers are chosen to select these almost exclusively when building the Docker image
|
# Markers are chosen to select these almost exclusively when building the Docker image
|
||||||
@@ -333,6 +329,10 @@ exclude_also = [
|
|||||||
|
|
||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
mypy_path = "src"
|
mypy_path = "src"
|
||||||
|
files = [
|
||||||
|
"src/documents/plugins/date_parsing",
|
||||||
|
"src/documents/tests/date_parsing",
|
||||||
|
]
|
||||||
plugins = [
|
plugins = [
|
||||||
"mypy_django_plugin.main",
|
"mypy_django_plugin.main",
|
||||||
"mypy_drf_plugin.main",
|
"mypy_drf_plugin.main",
|
||||||
@@ -344,5 +344,28 @@ disallow_untyped_defs = true
|
|||||||
warn_redundant_casts = true
|
warn_redundant_casts = true
|
||||||
warn_unused_ignores = true
|
warn_unused_ignores = true
|
||||||
|
|
||||||
|
# This prevents errors from imports, but allows type-checking logic to work
|
||||||
|
follow_imports = "silent"
|
||||||
|
|
||||||
|
[[tool.mypy.overrides]]
|
||||||
|
module = [
|
||||||
|
"documents.*",
|
||||||
|
"paperless.*",
|
||||||
|
"paperless_ai.*",
|
||||||
|
"paperless_mail.*",
|
||||||
|
"paperless_tesseract.*",
|
||||||
|
"paperless_remote.*",
|
||||||
|
"paperless_text.*",
|
||||||
|
"paperless_tika.*",
|
||||||
|
]
|
||||||
|
ignore_errors = true
|
||||||
|
|
||||||
|
[[tool.mypy.overrides]]
|
||||||
|
module = [
|
||||||
|
"documents.plugins.date_parsing.*",
|
||||||
|
"documents.tests.date_parsing.*",
|
||||||
|
]
|
||||||
|
ignore_errors = false
|
||||||
|
|
||||||
[tool.django-stubs]
|
[tool.django-stubs]
|
||||||
django_settings_module = "paperless.settings"
|
django_settings_module = "paperless.settings"
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import datetime
|
|||||||
import logging
|
import logging
|
||||||
from collections.abc import Iterator
|
from collections.abc import Iterator
|
||||||
from importlib.metadata import EntryPoint
|
from importlib.metadata import EntryPoint
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import pytest_mock
|
import pytest_mock
|
||||||
@@ -17,12 +16,12 @@ from documents.plugins.date_parsing.regex_parser import RegexDateParserPlugin
|
|||||||
|
|
||||||
|
|
||||||
class AlphaParser(DateParserPluginBase):
|
class AlphaParser(DateParserPluginBase):
|
||||||
def parse(self, filename: Path, content: str) -> Iterator[datetime.datetime]:
|
def parse(self, filename: str, content: str) -> Iterator[datetime.datetime]:
|
||||||
yield timezone.now()
|
yield timezone.now()
|
||||||
|
|
||||||
|
|
||||||
class BetaParser(DateParserPluginBase):
|
class BetaParser(DateParserPluginBase):
|
||||||
def parse(self, filename: Path, content: str) -> Iterator[datetime.datetime]:
|
def parse(self, filename: str, content: str) -> Iterator[datetime.datetime]:
|
||||||
yield timezone.now()
|
yield timezone.now()
|
||||||
|
|
||||||
|
|
||||||
@@ -98,17 +97,9 @@ class TestDiscoverParserClass:
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""If exactly one valid plugin is discovered, it should be returned without logging a warning."""
|
"""If exactly one valid plugin is discovered, it should be returned without logging a warning."""
|
||||||
|
|
||||||
class AlphaPlugin(DateParserPluginBase):
|
|
||||||
def parse(
|
|
||||||
self,
|
|
||||||
filename: Path,
|
|
||||||
content: str,
|
|
||||||
) -> Iterator[datetime.datetime]:
|
|
||||||
yield timezone.now()
|
|
||||||
|
|
||||||
ep = mocker.MagicMock(spec=EntryPoint)
|
ep = mocker.MagicMock(spec=EntryPoint)
|
||||||
ep.name = "alpha"
|
ep.name = "alpha"
|
||||||
ep.load.return_value = AlphaPlugin
|
ep.load.return_value = AlphaParser
|
||||||
|
|
||||||
mock_entry_points = mocker.patch(
|
mock_entry_points = mocker.patch(
|
||||||
"documents.plugins.date_parsing.entry_points",
|
"documents.plugins.date_parsing.entry_points",
|
||||||
@@ -124,8 +115,8 @@ class TestDiscoverParserClass:
|
|||||||
# It should have called entry_points with the correct group
|
# It should have called entry_points with the correct group
|
||||||
mock_entry_points.assert_called_once_with(group=DATE_PARSER_ENTRY_POINT_GROUP)
|
mock_entry_points.assert_called_once_with(group=DATE_PARSER_ENTRY_POINT_GROUP)
|
||||||
|
|
||||||
# The discovered class should be exactly our AlphaPlugin
|
# The discovered class should be exactly our AlphaParser
|
||||||
assert result is AlphaPlugin
|
assert result is AlphaParser
|
||||||
|
|
||||||
# No warnings should have been logged
|
# No warnings should have been logged
|
||||||
assert not any(
|
assert not any(
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import pytest_mock
|
import pytest_mock
|
||||||
@@ -261,7 +262,11 @@ class TestRegexDateParser:
|
|||||||
# Patch the dateparser.parse
|
# Patch the dateparser.parse
|
||||||
target = "documents.plugins.date_parsing.base.dateparser.parse"
|
target = "documents.plugins.date_parsing.base.dateparser.parse"
|
||||||
|
|
||||||
def fake_parse(date_string: str, settings=None, locales=None):
|
def fake_parse(
|
||||||
|
date_string: str,
|
||||||
|
settings: dict[str, Any] | None = None,
|
||||||
|
locales: None = None,
|
||||||
|
) -> datetime.datetime | None:
|
||||||
date_order = settings.get("DATE_ORDER") if settings else None
|
date_order = settings.get("DATE_ORDER") if settings else None
|
||||||
|
|
||||||
# Filename-style YYYY-MM-DD / YYYY.MM.DD
|
# Filename-style YYYY-MM-DD / YYYY.MM.DD
|
||||||
@@ -332,7 +337,11 @@ class TestRegexDateParser:
|
|||||||
|
|
||||||
target = "documents.plugins.date_parsing.base.dateparser.parse"
|
target = "documents.plugins.date_parsing.base.dateparser.parse"
|
||||||
|
|
||||||
def fake_parse(date_string: str, settings=None, locales=None):
|
def fake_parse(
|
||||||
|
date_string: str,
|
||||||
|
settings: dict[str, Any] | None = None,
|
||||||
|
locales: None = None,
|
||||||
|
) -> datetime.datetime | None:
|
||||||
if "10/12/2023" in date_string or "10-12-2023" in date_string:
|
if "10/12/2023" in date_string or "10-12-2023" in date_string:
|
||||||
# ignored date
|
# ignored date
|
||||||
return datetime.datetime(2023, 12, 10, tzinfo=datetime.timezone.utc)
|
return datetime.datetime(2023, 12, 10, tzinfo=datetime.timezone.utc)
|
||||||
@@ -393,7 +402,11 @@ class TestRegexDateParser:
|
|||||||
# Patch the module's dateparser.parse so we can inspect calls
|
# Patch the module's dateparser.parse so we can inspect calls
|
||||||
target = "documents.plugins.date_parsing.base.dateparser.parse"
|
target = "documents.plugins.date_parsing.base.dateparser.parse"
|
||||||
|
|
||||||
def fake_parse(date_string: str, settings=None, locales=None):
|
def fake_parse(
|
||||||
|
date_string: str,
|
||||||
|
settings: dict[str, Any] | None = None,
|
||||||
|
locales: None = None,
|
||||||
|
) -> datetime.datetime | None:
|
||||||
# return distinct datetimes so we can tell which source was parsed
|
# return distinct datetimes so we can tell which source was parsed
|
||||||
if "25/12/2022" in date_string:
|
if "25/12/2022" in date_string:
|
||||||
return datetime.datetime(2022, 12, 25, tzinfo=datetime.timezone.utc)
|
return datetime.datetime(2022, 12, 25, tzinfo=datetime.timezone.utc)
|
||||||
|
|||||||
Reference in New Issue
Block a user