Finish loaddata.pyi

This incorporates all type information I could glean from loaddata at
django/django@adb40d217e.

- Remove `help` per review comment:
  https://github.com/typeddjango/django-stubs/pull/536#discussion_r533179013
- Add `exclude_models` and `exclude_apps` based on the return type of
  `..utils.parse_apps_and_model_labels`.
- Change `loaddata`'s `fixture_labels` to `Sequence` of `str` instead of
  `Iterable` because in practice it's a tuple, but at a type level, the
  important thing is that `loaddata` iterates over `fixture_labels` more than
  once. General iterables (which include iterators) need not support iteration
  more than once.
- Correct the return type of `parse_name` to account for the possibility that
  the data and compression formats are `None`.
- Correct the return type of `find_fixtures` to be a list of the same type that
  `parse_name` returns.
- Add a type annotation for `SingleZipReader.read`. Django implements the method
  in a way that actually conflicts with `zipfile.ZipFile.read`'s type. This
  necessitates a `type: ignore[override]` to keep the tests passing. Mypy is
  correct that there is an override error, but Django's code is what it is.
  (And that method's signature was introduced way back in Django version 1.1,
  commit django/django@089ab18c025917f38a2e3731ae4024d4810df1ec.)
This commit is contained in:
William Schwartz
2020-12-01 11:32:59 -06:00
parent eecf13a2fe
commit d3ff5415db

View File

@@ -1,7 +1,9 @@
import zipfile
from typing import Iterable, List, Optional, Tuple
from typing import List, Optional, Set, Sequence, Tuple, Type
from django.apps.config import AppConfig
from django.core.management.base import BaseCommand
from django.db.models.base import Model
READ_STDIN: str = ...
@@ -10,16 +12,24 @@ class Command(BaseCommand):
using: str = ...
app_label: str = ...
verbosity: int = ...
excluded_models: Set[Type[Model]] = ...
excluded_apps: Set[AppConfig] = ...
format: str = ...
missing_args_message: str = ...
help: str = ...
def loaddata(self, fixture_labels: Iterable[str]) -> None: ...
def loaddata(self, fixture_labels: Sequence[str]) -> None: ...
def load_label(self, fixture_label: str) -> None: ...
def find_fixtures(self, fixture_label: str) -> List[Tuple[str, str, str]]: ...
def find_fixtures(self, fixture_label: str) -> List[Tuple[str, Optional[str], Optional[str]]]: ...
@property
def fixture_dirs(self) -> List[str]: ...
def parse_name(self, fixture_name: str) -> Tuple[str, str, str]: ...
def parse_name(self, fixture_name: str) -> Tuple[str, Optional[str], Optional[str]]: ...
class SingleZipReader(zipfile.ZipFile): ...
class SingleZipReader(zipfile.ZipFile):
# Incompatible override
# zipfile.ZipFile.read(
# self,
# name: typing.Union[typing.Text, zipfile.ZipInfo],
# pwd: Optional[bytes] = ...,
# ) -> bytes: ...
def read(self) -> bytes: ... # type: ignore[override]
def humanize(dirname: str) -> str: ...