diff --git a/bibtexparser/middlewares/names.py b/bibtexparser/middlewares/names.py index 7bb0bdd..d0f893d 100644 --- a/bibtexparser/middlewares/names.py +++ b/bibtexparser/middlewares/names.py @@ -9,6 +9,7 @@ from typing import List from typing import Literal from typing import Tuple +from typing import Union from bibtexparser.model import Block from bibtexparser.model import Entry @@ -73,7 +74,7 @@ def metadata_key(cls) -> str: return "separate_coauthors" # docstr-coverage: inherited - def _transform_field_value(self, name) -> List[str]: + def _transform_field_value(self, name: str) -> List[str]: return split_multiple_persons_names(name) @@ -86,7 +87,7 @@ def metadata_key(cls) -> str: return "merge_coauthors" # docstr-coverage: inherited - def _transform_field_value(self, name): + def _transform_field_value(self, name: Union[List[str], str]) -> str: if isinstance(name, list): return " and ".join(name) return name @@ -160,7 +161,7 @@ class SplitNameParts(_NameTransformerMiddleware): def metadata_key(cls) -> str: return "split_name_parts" - def _transform_field_value(self, name) -> List[NameParts]: + def _transform_field_value(self, name: List[str]) -> List[NameParts]: if not isinstance(name, list): raise ValueError( "Expected a list of strings, got {}. " @@ -195,7 +196,7 @@ def __init__( def metadata_key(cls) -> str: return "merge_name_parts" - def _transform_field_value(self, name) -> List[str]: + def _transform_field_value(self, name: List[NameParts]) -> List[str]: if not (isinstance(name, list) and all(isinstance(n, NameParts) for n in name)): raise ValueError(f"Expected a list of NameParts, got {name}. ") @@ -207,7 +208,7 @@ def _transform_field_value(self, name) -> List[str]: raise ValueError(f"""Expected "first" or "last" style, got {self.style}. """) -def parse_single_name_into_parts(name, strict=True): +def parse_single_name_into_parts(name: str, strict: bool = True) -> NameParts: """ Parse a name into its constituent parts: First, von, Last, and Jr. @@ -502,7 +503,7 @@ def rindex(k, x, default): return parts -def split_multiple_persons_names(names): +def split_multiple_persons_names(names: str) -> List[str]: """ Splits a string of multiple names. diff --git a/bibtexparser/model.py b/bibtexparser/model.py index 1f775c3..4b13935 100644 --- a/bibtexparser/model.py +++ b/bibtexparser/model.py @@ -4,6 +4,7 @@ from typing import List from typing import Optional from typing import Set +from typing import Tuple class Block(abc.ABC): @@ -67,7 +68,7 @@ def set_parser_metadata(self, key: str, value: Any): See attribute ``parser_metadata`` for more information.""" self._parser_metadata[key] = value - def __eq__(self, other): + def __eq__(self, other: object) -> bool: # make sure they have the same type and same content return ( isinstance(other, self.__class__) @@ -108,10 +109,10 @@ def value(self) -> str: def value(self, value: str): self._value = value - def __str__(self): + def __str__(self) -> str: return f"String (line: {self.start_line}, key: `{self.key}`): `{self.value}`" - def __repr__(self): + def __repr__(self) -> str: return ( f"String(key=`{self.key}`, value=`{self.value}`, " f"start_line={self.start_line}, raw=`{self.raw}`)" @@ -134,10 +135,10 @@ def value(self) -> str: def value(self, value: str): self._value = value - def __str__(self): + def __str__(self) -> str: return f"Preamble (line: {self.start_line}): `{self.value}`" - def __repr__(self): + def __repr__(self) -> str: return f"Preamble(value=`{self.value}`, " f"start_line={self.start_line}, raw=`{self.raw}`)" @@ -157,10 +158,10 @@ def comment(self) -> str: def comment(self, value: str): self._comment = value - def __str__(self): + def __str__(self) -> str: return f"ExplicitComment (line: {self.start_line}): `{self.comment}`" - def __repr__(self): + def __repr__(self) -> str: return ( f"ExplicitComment(comment=`{self.comment}`, " f"start_line={self.start_line}, raw=`{self.raw}`)" @@ -183,10 +184,10 @@ def comment(self) -> str: def comment(self, value: str): self._comment = value - def __str__(self): + def __str__(self) -> str: return f"ImplicitComment (line: {self.start_line}): `{self.comment}`" - def __repr__(self): + def __repr__(self) -> str: return ( f"ImplicitComment(comment=`{self.comment}`, " f"start_line={self.start_line}, raw=`{self.raw}`)" @@ -224,7 +225,7 @@ def start_line(self) -> int: """The line number of the first line of this field in the originally parsed string.""" return self._start_line - def __eq__(self, other): + def __eq__(self, other: object) -> bool: # make sure they have the same type and same content return ( isinstance(other, self.__class__) @@ -232,10 +233,10 @@ def __eq__(self, other): and self.__dict__ == other.__dict__ ) - def __str__(self): + def __str__(self) -> str: return f"Field (line: {self.start_line}, key: `{self.key}`): `{self.value}`" - def __repr__(self): + def __repr__(self) -> str: return f"Field(key=`{self.key}`, value=`{self.value}`, " f"start_line={self.start_line})" @@ -256,7 +257,7 @@ def __init__( self._fields = fields @property - def entry_type(self): + def entry_type(self) -> str: """The type of the entry, e.g. ``article`` in ``@article{Cesar2013, ...}``.""" return self._entry_type @@ -265,7 +266,7 @@ def entry_type(self, value: str): self._entry_type = value @property - def key(self): + def key(self) -> str: """The key of the entry, e.g. ``Cesar2013`` in ``@article{Cesar2013, ...}``.""" return self._key @@ -343,7 +344,7 @@ def __setitem__(self, key: str, value: Any): """ self.set_field(Field(key, value)) - def __delitem__(self, key): + def __delitem__(self, key: str) -> None: """Dict-mimicking index. This serves for partial v1.x backwards compatibility, @@ -351,7 +352,7 @@ def __delitem__(self, key): """ self.pop(key) - def items(self): + def items(self) -> List[Tuple[str, Any]]: """Dict-mimicking, for partial v1.x backwards compatibility. For newly written code, it's recommended to use `entry.entry_type`, @@ -361,12 +362,12 @@ def items(self): ("ID", self.key), ] + [(f.key, f.value) for f in self.fields] - def __str__(self): + def __str__(self) -> str: lines = [f"Entry (line: {self.start_line}, type: `{self.entry_type}`, key: `{self.key}`):"] lines.extend([f"\t`{f.key}` = `{f.value}`" for f in self.fields]) return "\n".join(lines) - def __repr__(self): + def __repr__(self) -> str: return ( f"Entry(entry_type=`{self.entry_type}`, key=`{self.key}`, " f"fields=`{self.fields.__repr__()}`, start_line={self.start_line})" diff --git a/bibtexparser/py.typed b/bibtexparser/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/bibtexparser/splitter.py b/bibtexparser/splitter.py index 158924e..b272c9d 100644 --- a/bibtexparser/splitter.py +++ b/bibtexparser/splitter.py @@ -46,7 +46,7 @@ def __init__(self, bibstr: str): self._reset_block_status(current_char_index=0) - def _reset_block_status(self, current_char_index): + def _reset_block_status(self, current_char_index: int) -> None: self._open_brackets = 0 self._is_quote_open = False self._expected_next: Optional[List[str]] = None @@ -131,7 +131,7 @@ def _move_to_closed_bracket(self) -> int: ) def _move_to_comma_or_closing_curly_bracket( - self, currently_quote_escaped=False, num_open_curls=0 + self, currently_quote_escaped: bool = False, num_open_curls: int = 0 ) -> int: """Index of the end of the field, taking quote-escape into account.""" diff --git a/setup.py b/setup.py index 86aada8..d0480ea 100644 --- a/setup.py +++ b/setup.py @@ -31,6 +31,7 @@ def load_readme(): long_description=load_readme(), python_requires=">=3.9", packages=setuptools.find_packages(include=["bibtexparser", "bibtexparser.*"]), + package_data={"bibtexparser": ["py.typed"]}, classifiers=[ "Development Status :: 4 - Beta", "Programming Language :: Python :: 3",