From 5595b2b69d3685a84bd10570b24b77f911a63d65 Mon Sep 17 00:00:00 2001 From: masklinn Date: Wed, 28 Feb 2024 16:53:40 +0100 Subject: [PATCH] Fix typing of Parser's unbound methods All credit due to "Finite State Machine" on the typing gitter, they're the one who had the idea of trying to type `self` in case that would make mypy happy. Which it absolutely does. This does make that use pattern easier to recommend, as it's fully typed as well. --- src/ua_parser/__init__.py | 8 ++++---- tests/test_convenience_parser.py | 14 ++++++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/ua_parser/__init__.py b/src/ua_parser/__init__.py index 2c6121d..dd5343d 100644 --- a/src/ua_parser/__init__.py +++ b/src/ua_parser/__init__.py @@ -93,25 +93,25 @@ def __call__(self, ua: str, domains: Domain, /) -> PartialParseResult: """ return self.resolver(ua, domains) - def parse(self, ua: str) -> ParseResult: + def parse(self: Resolver, ua: str) -> ParseResult: """Convenience method for parsing all domains, and falling back to default values for all failures. """ return self(ua, Domain.ALL).complete() - def parse_user_agent(self, ua: str) -> Optional[UserAgent]: + def parse_user_agent(self: Resolver, ua: str) -> Optional[UserAgent]: """Convenience method for parsing the :class:`UserAgent` domain, falling back to the default value in case of failure. """ return self(ua, Domain.USER_AGENT).user_agent - def parse_os(self, ua: str) -> Optional[OS]: + def parse_os(self: Resolver, ua: str) -> Optional[OS]: """Convenience method for parsing the :class:`OS` domain, falling back to the default value in case of failure. """ return self(ua, Domain.OS).os - def parse_device(self, ua: str) -> Optional[Device]: + def parse_device(self: Resolver, ua: str) -> Optional[Device]: """Convenience method for parsing the :class:`Device` domain, falling back to the default value in case of failure. """ diff --git a/tests/test_convenience_parser.py b/tests/test_convenience_parser.py index 7670e65..7dea6f7 100644 --- a/tests/test_convenience_parser.py +++ b/tests/test_convenience_parser.py @@ -1,4 +1,8 @@ -from ua_parser import Parser, ParseResult, PartialParseResult +from ua_parser import Domain, Parser, ParseResult, PartialParseResult + + +def resolver(s: str, d: Domain) -> PartialParseResult: + return PartialParseResult(d, None, None, None, s) def test_parser_utility() -> None: @@ -6,8 +10,10 @@ def test_parser_utility() -> None: helpers, for users who may not wish to instantiate a parser or something. - Sadly the typing doesn't really play nicely with that. - """ - r = Parser.parse(lambda s, d: PartialParseResult(d, None, None, None, s), "a") # type: ignore + + r = Parser.parse(resolver, "a") assert r == ParseResult(None, None, None, "a") + + os = Parser.parse_os(resolver, "a") + assert os is None