From 12a8489502fe948a2a585ad9a44e4339726011bd Mon Sep 17 00:00:00 2001 From: Dorian Lesbre Date: Fri, 16 Feb 2024 22:22:30 +0100 Subject: [PATCH] Format and check --- bibtexautocomplete/APIs/dblp.py | 4 +- bibtexautocomplete/APIs/doi.py | 4 +- bibtexautocomplete/APIs/semantic_scholar.py | 4 +- bibtexautocomplete/bibtex/base_field.py | 8 +--- bibtexautocomplete/bibtex/fields.py | 4 +- bibtexautocomplete/bibtex/normalize.py | 10 +---- bibtexautocomplete/core/autocomplete.py | 30 ++++---------- bibtexautocomplete/core/data_dump.py | 4 +- bibtexautocomplete/core/main.py | 14 ++----- bibtexautocomplete/core/parser.py | 39 ++++++------------- .../lookups/abstract_entry_lookup.py | 4 +- bibtexautocomplete/lookups/https.py | 8 +--- bibtexautocomplete/lookups/multiple_mixin.py | 4 +- bibtexautocomplete/utils/functions.py | 4 +- bibtexautocomplete/utils/logger.py | 26 +++---------- bibtexautocomplete/utils/safe_json.py | 4 +- makefile | 2 +- tests/test_2_bibtex.py | 16 +++----- tests/test_3_lookup.py | 18 ++++----- 19 files changed, 57 insertions(+), 150 deletions(-) diff --git a/bibtexautocomplete/APIs/dblp.py b/bibtexautocomplete/APIs/dblp.py index 7caa564..10537c0 100644 --- a/bibtexautocomplete/APIs/dblp.py +++ b/bibtexautocomplete/APIs/dblp.py @@ -73,9 +73,7 @@ def get_value(self, result: SafeJSON) -> BibtexEntry: values.pages.set_str(info["pages"].to_str()) values.title.set(info["title"].to_str()) values.volume.set(info["volume"].to_str()) - values.url.set( - info["ee"].to_str() if info["access"].to_str() == "open" else None - ) + values.url.set(info["ee"].to_str() if info["access"].to_str() == "open" else None) values.year.set(info["year"].to_str()) return values diff --git a/bibtexautocomplete/APIs/doi.py b/bibtexautocomplete/APIs/doi.py index b398da7..15e3791 100644 --- a/bibtexautocomplete/APIs/doi.py +++ b/bibtexautocomplete/APIs/doi.py @@ -13,9 +13,7 @@ from ..utils.safe_json import SafeJSON -class URLCheck( - ConditionMixin[str, Optional[Data]], RedirectFollower[str, Optional[Data]] -): +class URLCheck(ConditionMixin[str, Optional[Data]], RedirectFollower[str, Optional[Data]]): """Checks that an URL exists (should return 200) Follows redirection (up to a certain depth)""" diff --git a/bibtexautocomplete/APIs/semantic_scholar.py b/bibtexautocomplete/APIs/semantic_scholar.py index cfe0234..4f23373 100644 --- a/bibtexautocomplete/APIs/semantic_scholar.py +++ b/bibtexautocomplete/APIs/semantic_scholar.py @@ -131,9 +131,7 @@ def get_value(self, result: SafeJSON) -> BibtexEntry: # Black formatting is VERY ugly without the two variables j1 = result["publicationVenue"]["type"].to_str() == "journal" - j2 = "JournalArticle" in [ - x.to_str() for x in result["publicationTypes"].iter_list() - ] + j2 = "JournalArticle" in [x.to_str() for x in result["publicationTypes"].iter_list()] is_journal = j1 or j2 venue = result["venue"].to_str() diff --git a/bibtexautocomplete/bibtex/base_field.py b/bibtexautocomplete/bibtex/base_field.py index b308953..f582d24 100644 --- a/bibtexautocomplete/bibtex/base_field.py +++ b/bibtexautocomplete/bibtex/base_field.py @@ -100,9 +100,7 @@ def combine(self, other: "BibtexField[T]") -> "BibtexField[T]": (eg. fewer abbreviations). This will only be called on fields that match""" if self.value is not None: if other.value is not None: - obj = self.__class__( - self.field, self.source + SOURCE_SEPARATOR + other.source - ) + obj = self.__class__(self.field, self.source + SOURCE_SEPARATOR + other.source) obj.value = self.combine_values(self.value, other.value) return obj logger.warn("Combining fields which store None") @@ -267,9 +265,7 @@ def match_values_slow(cls, a: List[T], b: List[T]) -> int: return cls.compute_score(a, b, common_scores, common) @classmethod - def compute_score( - cls, a: List[T], b: List[T], common_scores: int, common: int - ) -> int: + def compute_score(cls, a: List[T], b: List[T], common_scores: int, common: int) -> int: """Compute the final score from the number of common elements and the sum of the scores""" if common == 0: diff --git a/bibtexautocomplete/bibtex/fields.py b/bibtexautocomplete/bibtex/fields.py index 30bbced..cce3159 100644 --- a/bibtexautocomplete/bibtex/fields.py +++ b/bibtexautocomplete/bibtex/fields.py @@ -168,9 +168,7 @@ def match_values(cls, a: Author, b: Author) -> int: return FIELD_FULL_MATCH // 2 if normalize_str(a.firstnames) == normalize_str(b.firstnames): return FIELD_FULL_MATCH - if is_abbrev(a.firstnames, b.firstnames) or is_abbrev( - b.firstnames, a.firstnames - ): + if is_abbrev(a.firstnames, b.firstnames) or is_abbrev(b.firstnames, a.firstnames): return 3 * FIELD_FULL_MATCH // 4 return FIELD_NO_MATCH diff --git a/bibtexautocomplete/bibtex/normalize.py b/bibtexautocomplete/bibtex/normalize.py index d0d4a04..b502a20 100644 --- a/bibtexautocomplete/bibtex/normalize.py +++ b/bibtexautocomplete/bibtex/normalize.py @@ -44,11 +44,7 @@ def has_field(entry: EntryType, field: str) -> bool: def strip_accents(string: str) -> str: """replace accented characters with their non-accented variants""" # Solution from https://stackoverflow.com/a/518232 - return "".join( - c - for c in unicodedata.normalize("NFD", string) - if unicodedata.category(c) != "Mn" - ) + return "".join(c for c in unicodedata.normalize("NFD", string) if unicodedata.category(c) != "Mn") def normalize_str_weak(string: str) -> str: @@ -90,9 +86,7 @@ def normalize_doi(doi_or_url: Optional[str]) -> Optional[str]: return None -def normalize_url( - url: str, previous: Optional[str] = None -) -> Optional[Tuple[str, str]]: +def normalize_url(url: str, previous: Optional[str] = None) -> Optional[Tuple[str, str]]: """Splits and url into domain/path Returns none if url is not valid""" url_copy = url diff --git a/bibtexautocomplete/core/autocomplete.py b/bibtexautocomplete/core/autocomplete.py index ba94eeb..51346e8 100644 --- a/bibtexautocomplete/core/autocomplete.py +++ b/bibtexautocomplete/core/autocomplete.py @@ -124,9 +124,7 @@ def __init__( if ignore_mark: self.filter = lambda x: x["ID"] in self.entries else: - self.filter = ( - lambda x: x["ID"] in self.entries and MARKED_FIELD.lower() not in x - ) + self.filter = lambda x: x["ID"] in self.entries and MARKED_FIELD.lower() not in x self.escape_unicode = escape_unicode self.fields_to_protect_uppercase = fields_to_protect_uppercase @@ -159,9 +157,7 @@ def get_id_padding(self) -> int: """Return the max length of entries' ID to use for pretty printing""" max_id_padding = 40 - return min( - max((len(entry["ID"]) + 1 for entry in self), default=0), max_id_padding - ) + return min(max((len(entry["ID"]) + 1 for entry in self), default=0), max_id_padding) def autocomplete(self, no_progressbar: bool = False) -> None: """Main function that does all the work @@ -209,26 +205,20 @@ def autocomplete(self, no_progressbar: bool = False) -> None: if is_verbose: bar.text = " ".join(thread_positions) else: - bar.text = ( - f"Processed {position}/{nb_entries} entries, " - f"found {self.changed_fields} new fields" - ) + bar.text = f"Processed {position}/{nb_entries} entries, " f"found {self.changed_fields} new fields" if not step: # Some threads have not found data for current entry condition.wait() else: # update data for current entry self.update_entry(entries[position], threads, position) position += 1 logger.info( - "Modified {changed_entries} / {count_entries} entries" - ", added {changed_fields} fields", + "Modified {changed_entries} / {count_entries} entries" ", added {changed_fields} fields", changed_entries=self.changed_entries, count_entries=self.count_entries(), changed_fields=self.changed_fields, ) - def update_entry( - self, entry: EntryType, threads: List[LookupThread], position: int - ) -> None: + def update_entry(self, entry: EntryType, threads: List[LookupThread], position: int) -> None: """Reads all data the threads have found on a new entry, and uses it to update the entry with new fields""" changes: List[Changes] = [] @@ -246,11 +236,7 @@ def update_entry( for field in new_fields: # Filter which fields to add - if not ( - self.force_overwrite_all - or (field in self.force_overwrite) - or (not has_field(entry, field)) - ): + if not (self.force_overwrite_all or (field in self.force_overwrite) or (not has_field(entry, field))): continue bib_field = self.combine_field(results, field) if bib_field is None: @@ -280,9 +266,7 @@ def update_entry( if self.mark: entry[MARKED_FIELD] = datetime.today().strftime("%Y-%m-%d") - def combine_field( - self, results: List[BibtexEntry], fieldname: FieldType - ) -> Optional[BibtexField[Any]]: + def combine_field(self, results: List[BibtexEntry], fieldname: FieldType) -> Optional[BibtexField[Any]]: """Combine the values of a single field""" fields = [entry.get_field(fieldname) for entry in results if fieldname in entry] groups: List[Tuple[int, BibtexField[Any]]] = [] diff --git a/bibtexautocomplete/core/data_dump.py b/bibtexautocomplete/core/data_dump.py index b0dff88..cb05969 100644 --- a/bibtexautocomplete/core/data_dump.py +++ b/bibtexautocomplete/core/data_dump.py @@ -17,9 +17,7 @@ def __init__(self, id: str) -> None: self.new_fields = 0 self.results = {} - def add_entry( - self, lookup_name: str, entry: Optional[BibtexEntry], info: Dict[str, JSONType] - ) -> None: + def add_entry(self, lookup_name: str, entry: Optional[BibtexEntry], info: Dict[str, JSONType]) -> None: if entry is None: self.results[lookup_name] = None return diff --git a/bibtexautocomplete/core/main.py b/bibtexautocomplete/core/main.py index f9fb576..860edc1 100644 --- a/bibtexautocomplete/core/main.py +++ b/bibtexautocomplete/core/main.py @@ -91,11 +91,7 @@ def main(argv: Optional[List[str]] = None) -> None: HTTPSLookup.connection_timeout = args.timeout if args.timeout > 0.0 else None HTTPSLookup.ignore_ssl = args.ignore_ssl - lookups = ( - OnlyExclude[str] - .from_nonempty(args.only_query, args.dont_query) - .filter(LOOKUPS, lambda x: x.name) - ) + lookups = OnlyExclude[str].from_nonempty(args.only_query, args.dont_query).filter(LOOKUPS, lambda x: x.name) if args.only_query != []: # remove duplicate from list args.only_query, dups = list_unduplicate(args.only_query) @@ -110,18 +106,14 @@ def main(argv: Optional[List[str]] = None) -> None: if args.protect_all_uppercase: fields_to_protect_uppercase: Container[str] = FieldNamesSet else: - fields_to_protect_proto = OnlyExclude[str].from_nonempty( - args.protect_uppercase, args.dont_protect_uppercase - ) + fields_to_protect_proto = OnlyExclude[str].from_nonempty(args.protect_uppercase, args.dont_protect_uppercase) fields_to_protect_proto.default = False fields_to_protect_uppercase = fields_to_protect_proto overwrite = OnlyExclude[str].from_nonempty(args.overwrite, args.dont_overwrite) overwrite.default = False - FieldConditionMixin.fields_to_complete = set( - fields.filter(SearchedFields, lambda x: x) - ) + FieldConditionMixin.fields_to_complete = set(fields.filter(SearchedFields, lambda x: x)) FieldConditionMixin.overwrites = set(overwrite.filter(SearchedFields, lambda x: x)) if args.force_overwrite: diff --git a/bibtexautocomplete/core/parser.py b/bibtexautocomplete/core/parser.py index e913052..a358e57 100644 --- a/bibtexautocomplete/core/parser.py +++ b/bibtexautocomplete/core/parser.py @@ -60,10 +60,9 @@ def indent_string(indent: str) -> str: sane = indent.replace("t", "\t").replace("n", "\n").replace("_", " ") if not (sane.isspace() or sane == ""): logger.critical( - ( - "--fi/--indent should be a number or string " - "with spaces, '_', 't' and 'n' only.\nGot: '{}'" - ).format(indent) + ("--fi/--indent should be a number or string " "with spaces, '_', 't' and 'n' only.\nGot: '{}'").format( + indent + ) ) exit(5) return sane @@ -108,36 +107,20 @@ def get_bibfiles(input: Path) -> List[Path]: FIELD_NAMES = sorted(FieldNamesSet) -parser.add_argument( - "--dont-query", "-Q", action="append", default=[], choices=LOOKUP_NAMES -) -parser.add_argument( - "--only-query", "-q", action="append", default=[], choices=LOOKUP_NAMES -) -parser.add_argument( - "--dont-complete", "-C", action="append", default=[], choices=FIELD_NAMES -) -parser.add_argument( - "--only-complete", "-c", action="append", default=[], choices=FIELD_NAMES -) -parser.add_argument( - "--dont-overwrite", "-W", action="append", default=[], choices=FIELD_NAMES -) -parser.add_argument( - "--overwrite", "-w", action="append", default=[], choices=FIELD_NAMES -) +parser.add_argument("--dont-query", "-Q", action="append", default=[], choices=LOOKUP_NAMES) +parser.add_argument("--only-query", "-q", action="append", default=[], choices=LOOKUP_NAMES) +parser.add_argument("--dont-complete", "-C", action="append", default=[], choices=FIELD_NAMES) +parser.add_argument("--only-complete", "-c", action="append", default=[], choices=FIELD_NAMES) +parser.add_argument("--dont-overwrite", "-W", action="append", default=[], choices=FIELD_NAMES) +parser.add_argument("--overwrite", "-w", action="append", default=[], choices=FIELD_NAMES) parser.add_argument("--exclude-entry", "-E", action="append", default=[]) parser.add_argument("--only-entry", "-e", action="append", default=[]) parser.add_argument("--escape-unicode", "--fu", action="store_true") parser.add_argument("--protect-all-uppercase", "--fpa", action="store_true") -parser.add_argument( - "--protect-uppercase", "--fp", action="append", default=[], choices=FIELD_NAMES -) -parser.add_argument( - "--dont-protect-uppercase", "--FP", action="append", default=[], choices=FIELD_NAMES -) +parser.add_argument("--protect-uppercase", "--fp", action="append", default=[], choices=FIELD_NAMES) +parser.add_argument("--dont-protect-uppercase", "--FP", action="append", default=[], choices=FIELD_NAMES) parser.add_argument("--align-values", "--fa", action="store_true") parser.add_argument("--comma-first", "--fc", action="store_true") diff --git a/bibtexautocomplete/lookups/abstract_entry_lookup.py b/bibtexautocomplete/lookups/abstract_entry_lookup.py index 90d6570..1d83274 100644 --- a/bibtexautocomplete/lookups/abstract_entry_lookup.py +++ b/bibtexautocomplete/lookups/abstract_entry_lookup.py @@ -28,9 +28,7 @@ def __init__(self, input: BibtexEntry) -> None: self.entry = input -class FieldConditionMixin( - ConditionMixin["BibtexEntry", "BibtexEntry"], AbstractEntryLookup -): +class FieldConditionMixin(ConditionMixin["BibtexEntry", "BibtexEntry"], AbstractEntryLookup): """Mixin used to query only if there exists a field in self.fields that does not exists in self.entry, or is in self.overwrites diff --git a/bibtexautocomplete/lookups/https.py b/bibtexautocomplete/lookups/https.py index bbd523d..b4e33dc 100644 --- a/bibtexautocomplete/lookups/https.py +++ b/bibtexautocomplete/lookups/https.py @@ -166,17 +166,13 @@ def get_data(self) -> Optional[Data]: reason=" " + self.response.reason if self.response.reason else "", delay=delay, ) - logger.very_verbose_debug( - "response headers: {headers}", headers=self.response.headers - ) + logger.very_verbose_debug("response headers: {headers}", headers=self.response.headers) data = self.response.read() connection.close() except timeout: if self.silent_fail: return None - logger.warn( - "connection timeout ({timeout}s)", timeout=self.connection_timeout - ) + logger.warn("connection timeout ({timeout}s)", timeout=self.connection_timeout) TIMEOUT_Hint.emit() return None except (gaierror, OSError) as err: diff --git a/bibtexautocomplete/lookups/multiple_mixin.py b/bibtexautocomplete/lookups/multiple_mixin.py index ca5d581..92876e3 100644 --- a/bibtexautocomplete/lookups/multiple_mixin.py +++ b/bibtexautocomplete/lookups/multiple_mixin.py @@ -38,9 +38,7 @@ def query(self) -> Optional[Output]: return None -class DAT_Query_Mixin( - MultipleQueryMixin[BibtexEntry, BibtexEntry], AbstractEntryLookup -): +class DAT_Query_Mixin(MultipleQueryMixin[BibtexEntry, BibtexEntry], AbstractEntryLookup): """Performs queries using - the entry's DOI if it is known and if query_doi is True - the entry's title and author if known and if query_author_title is True diff --git a/bibtexautocomplete/utils/functions.py b/bibtexautocomplete/utils/functions.py index f88a7d2..6b73adc 100644 --- a/bibtexautocomplete/utils/functions.py +++ b/bibtexautocomplete/utils/functions.py @@ -17,9 +17,7 @@ def list_unduplicate(lst: List[T]) -> Tuple[List[T], Set[T]]: return unique, dups -def list_sort_using( - to_sort: Iterable[Q], reference: List[T], map: Callable[[Q], T] -) -> List[Q]: +def list_sort_using(to_sort: Iterable[Q], reference: List[T], map: Callable[[Q], T]) -> List[Q]: """Sorts to_sort based on the order in reference, using map for conversion""" order = {q: i for i, q in enumerate(reference)} return sorted(to_sort, key=lambda t: order[map(t)]) diff --git a/bibtexautocomplete/utils/logger.py b/bibtexautocomplete/utils/logger.py index 3b07ef2..beddd9d 100644 --- a/bibtexautocomplete/utils/logger.py +++ b/bibtexautocomplete/utils/logger.py @@ -81,9 +81,7 @@ def to_logger(self, level: int, message: str, *args: Any, **kwargs: Any) -> None message = self.add_thread_info(ansi_format(message, *args, **kwargs)) self.logger.log(level=level, msg=message) - def warn( - self, message: str, error: str = "WARNING", *args: Any, **kwargs: Any - ) -> None: + def warn(self, message: str, error: str = "WARNING", *args: Any, **kwargs: Any) -> None: """Issue a warning, extra arguments are formatter options""" self.to_logger( logging.WARN, @@ -93,21 +91,17 @@ def warn( **kwargs, ) - def error( - self, message: str, error: str = "ERROR", *args: Any, **kwargs: Any - ) -> None: + def error(self, message: str, error: str = "ERROR", *args: Any, **kwargs: Any) -> None: """Issue an error, extra arguments are formatter options""" self.to_logger( logging.ERROR, "{FgRed}{error}:{Reset} " + message, - error=error, *args, + error=error, **kwargs, ) - def critical( - self, message: str, error: str = "CRITICAL ERROR", *args: Any, **kwargs: Any - ) -> None: + def critical(self, message: str, error: str = "CRITICAL ERROR", *args: Any, **kwargs: Any) -> None: """Issue a critical error, extra arguments are formatter options""" self.to_logger( logging.CRITICAL, @@ -178,13 +172,7 @@ def get_level(self) -> int: def header(self, title: str, level: Level = logging.INFO) -> None: """Shows a pretty header, 100% inspired by opam's output""" self.to_logger(level, "") # newline - title = ( - "{FgBlue}===={Reset} {StBold}" - + title - + "{Reset} {FgBlue}" - + ("=" * (74 - len(title))) - + "{Reset}" - ) + title = "{FgBlue}===={Reset} {StBold}" + title + "{Reset} {FgBlue}" + ("=" * (74 - len(title))) + "{Reset}" self.to_logger(level, title) def traceback(self, message: str, _err: Exception) -> None: @@ -212,9 +200,7 @@ def traceback(self, message: str, _err: Exception) -> None: error="UNEXPECTED ERROR", tmessage=message, ISSUES_URL=ISSUES_URL, - exn=format_exc() - .strip() - .replace("\n", "\n" + prefix + ansi_format("{FgRed}")), + exn=format_exc().strip().replace("\n", "\n" + prefix + ansi_format("{FgRed}")), ) diff --git a/bibtexautocomplete/utils/safe_json.py b/bibtexautocomplete/utils/safe_json.py index 5ba2b40..d1c4a08 100644 --- a/bibtexautocomplete/utils/safe_json.py +++ b/bibtexautocomplete/utils/safe_json.py @@ -39,9 +39,7 @@ def __getitem__(self, key: Union[int, str]) -> "SafeJSON": else: log("SafeJSON: dict has no key {}", key) elif self.value is not None: - log( - "SafeJSON: access to {} on non-dict {}", repr(key), type(self.value) - ) + log("SafeJSON: access to {} on non-dict {}", repr(key), type(self.value)) return SafeJSON(result) @staticmethod diff --git a/makefile b/makefile index 06fdfa0..3f95890 100644 --- a/makefile +++ b/makefile @@ -93,7 +93,7 @@ coverage: ## build html coverage and open in browser .PHONY: mypy mypy: ## Typecheck all files $(call print,Running mypy) - $(MYPY) --strict ./bibtexautocomplete/ ./tests ./setup.py + $(MYPY) --strict ./bibtexautocomplete/ ./tests .PHONY: format format: ## Format files with black and isort diff --git a/tests/test_2_bibtex.py b/tests/test_2_bibtex.py index b6794cc..f40099d 100644 --- a/tests/test_2_bibtex.py +++ b/tests/test_2_bibtex.py @@ -167,8 +167,8 @@ def test_BibtexEntry_editor_set(author: str, res: List[Author]) -> None: def iterate_nested(list: List[List[str]]) -> Iterator[Tuple[int, str]]: """Iterate over a nested list, returning (index of sublist, element)""" - for i, l in enumerate(list): - for x in l: + for i, sublist in enumerate(list): + for x in sublist: yield (i, x) @@ -323,9 +323,7 @@ def test_listify_to_from(source: str, converted: Optional[str]) -> None: @pytest.mark.parametrize(("a", "b", "matches", "merged"), listify_match_merge) -def test_listify_match_merge( - a: str, b: str, matches: bool, merged: Optional[str] -) -> None: +def test_listify_match_merge(a: str, b: str, matches: bool, merged: Optional[str]) -> None: field_a = ListString("list_string", "test") field_a.set_str(a) field_b = ListString("list_string", "test") @@ -365,9 +363,7 @@ def test_listify_match_merge( @pytest.mark.parametrize(("a", "b", "matches", "merged"), author_match_merge) -def test_author_match_merge( - a: str, b: str, matches: bool, merged: Optional[str] -) -> None: +def test_author_match_merge(a: str, b: str, matches: bool, merged: Optional[str]) -> None: field_a = NameField("author", "test") field_a.set_str(a) field_b = NameField("author", "test") @@ -409,9 +405,7 @@ def test_author_match_merge( @pytest.mark.parametrize(("a", "b", "matches", "merged"), abbrevs) -def test_abbrev_match_merge( - a: str, b: str, matches: bool, merged: Optional[str] -) -> None: +def test_abbrev_match_merge(a: str, b: str, matches: bool, merged: Optional[str]) -> None: field_a = AbbreviatedStringField("abbrev", "test") field_a.set_str(a) field_b = AbbreviatedStringField("abbrev", "test") diff --git a/tests/test_3_lookup.py b/tests/test_3_lookup.py index bf9f06a..eff437d 100644 --- a/tests/test_3_lookup.py +++ b/tests/test_3_lookup.py @@ -18,12 +18,16 @@ class SearchEval(AbstractLookup[BibtexEntry, BibtexEntry]): index: int = 0 expected: List[ToCheck] = [] + doi: Optional[str] + title: Optional[str] + authors: Optional[List[str]] + def query(self) -> Optional[BibtexEntry]: test = self.expected[self.index] - assert getattr(self, "doi") == test.doi - assert getattr(self, "authors") == test.author + assert self.doi == test.doi + assert self.authors == test.author title = None if test.title is None else normalize_str(test.title) - assert getattr(self, "title") == title + assert self.title == title self.index += 1 return None @@ -184,9 +188,7 @@ def test_empty(self) -> None: self.run({"junk": "junk", "more junk": "more junk"}, True) def test_full(self) -> None: - self.run( - {"doi": "10.1234/1234", "title": "A Title", "author": "John Jones"}, False - ) + self.run({"doi": "10.1234/1234", "title": "A Title", "author": "John Jones"}, False) def test_partial(self) -> None: self.run( @@ -217,9 +219,7 @@ def test_partial(self) -> None: def test_invalid(self) -> None: self.run({"doi": "", "title": "A Title", "author": "John Jones"}, True) self.run({"doi": "10.1234/1234", "title": "A Title", "author": "{}"}, True) - self.run( - {"doi": "10.1234/1234", "title": "A Title", "author": "{{}{{}}}"}, True - ) + self.run({"doi": "10.1234/1234", "title": "A Title", "author": "{{}{{}}}"}, True) def test_filter(self) -> None: old = self.parent.fields_to_complete