From 01e8341b85547aba3f6c771f579795ced9f35220 Mon Sep 17 00:00:00 2001 From: jicruz96 Date: Thu, 25 Jul 2024 14:15:53 -0400 Subject: [PATCH 1/4] fix mypy errors by loosening type restrictions of helper functions --- geonamescache/__init__.py | 6 +++--- geonamescache/mappers.py | 11 +++++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/geonamescache/__init__.py b/geonamescache/__init__.py index a781ed2..b87577b 100644 --- a/geonamescache/__init__.py +++ b/geonamescache/__init__.py @@ -31,8 +31,8 @@ def __init__(self, min_city_population: int = 15000): self.min_city_population = min_city_population def get_dataset_by_key( - self, dataset: Dict[str, TDict], key: str - ) -> Dict[str, TDict]: + self, dataset: Dict[Any, TDict], key: str + ) -> Dict[Any, TDict]: return dict((d[key], d) for c, d in list(dataset.items())) def get_continents(self) -> Dict[ContinentCode, Continent]: @@ -111,7 +111,7 @@ def search_cities( return results @staticmethod - def _load_data(datadict: Optional[Dict[str, Any]], datafile: str) -> Dict[str, Any]: + def _load_data(datadict: Optional[Dict[Any, Any]], datafile: str) -> Dict[Any, Any]: if datadict is None: with open(os.path.join(os.path.dirname(__file__), 'data', datafile)) as f: datadict = json.load(f) diff --git a/geonamescache/mappers.py b/geonamescache/mappers.py index 5042793..497ea2b 100644 --- a/geonamescache/mappers.py +++ b/geonamescache/mappers.py @@ -1,12 +1,11 @@ # -*- coding: utf-8 -*- -from typing import Callable, Union - +from typing import Any, Callable from geonamescache import GeonamesCache from . import mappings -def country(from_key: str = 'name', to_key: str = 'iso') -> Callable[[str], Union[str, int, None]]: +def country(from_key: str = "name", to_key: str = "iso") -> Callable[[str], Any]: """Creates and returns a mapper function to access country data. The mapper function that is returned must be called with one argument. In @@ -24,13 +23,13 @@ def country(from_key: str = 'name', to_key: str = 'iso') -> Callable[[str], Unio gc = GeonamesCache() dataset = gc.get_dataset_by_key(gc.get_countries(), from_key) - def mapper(input: str) -> Union[str, int, None]: + def mapper(input: str) -> Any: # For country name inputs take the names mapping into account. - if 'name' == from_key: + if "name" == from_key: input = mappings.country_names.get(input, input) # If there is a record return the demanded attribute. item = dataset.get(input) if item: - return item[to_key] + return item[to_key] # type: ignore return mapper From d0cc123232c7a09dcc31c72c7f37432fc9d28396 Mon Sep 17 00:00:00 2001 From: jicruz96 Date: Thu, 25 Jul 2024 14:33:37 -0400 Subject: [PATCH 2/4] add typing overloads for geonamescache.mappers.country --- geonamescache/mappers.py | 45 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/geonamescache/mappers.py b/geonamescache/mappers.py index 497ea2b..41c9af8 100644 --- a/geonamescache/mappers.py +++ b/geonamescache/mappers.py @@ -1,8 +1,51 @@ # -*- coding: utf-8 -*- -from typing import Any, Callable +from typing import Any, Callable, Literal, overload + from geonamescache import GeonamesCache from . import mappings +from .types import ContinentCode + + +@overload +def country( + from_key: str = "name", + *, + to_key: Literal[ + "areakm2", + "isonumeric", + "geonameid", + "population", + ], +) -> Callable[[str], int]: ... + + +@overload +def country( + from_key: str = "name", + to_key: Literal[ + "capital", + "currencycode", + "currencyname", + "iso", + "iso3", + "fips", + "languages", + "name", + "neighbours", + "phone", + "postalcoderegex", + "tld", + ] = "iso", +) -> Callable[[str], str]: ... + + +@overload +def country( + from_key: str = "name", + *, + to_key: Literal["continentcode"], +) -> Callable[[str], ContinentCode]: ... def country(from_key: str = "name", to_key: str = "iso") -> Callable[[str], Any]: From 89ae76680caf2bc0baa7893b99af923a4186183e Mon Sep 17 00:00:00 2001 From: jicruz96 Date: Thu, 25 Jul 2024 14:40:20 -0400 Subject: [PATCH 3/4] explicitly type country field types --- geonamescache/mappers.py | 17 +-- geonamescache/types.py | 237 ++++++++++++++++++++++----------------- 2 files changed, 139 insertions(+), 115 deletions(-) diff --git a/geonamescache/mappers.py b/geonamescache/mappers.py index 41c9af8..3c02c4a 100644 --- a/geonamescache/mappers.py +++ b/geonamescache/mappers.py @@ -4,19 +4,12 @@ from geonamescache import GeonamesCache from . import mappings -from .types import ContinentCode +from .types import ContinentCode, CountryFields, CountryNumericFields @overload def country( - from_key: str = "name", - *, - to_key: Literal[ - "areakm2", - "isonumeric", - "geonameid", - "population", - ], + from_key: str = "name", *, to_key: CountryNumericFields ) -> Callable[[str], int]: ... @@ -48,7 +41,9 @@ def country( ) -> Callable[[str], ContinentCode]: ... -def country(from_key: str = "name", to_key: str = "iso") -> Callable[[str], Any]: +def country( + from_key: str = "name", to_key: CountryFields = "iso" +) -> Callable[[str], Any]: """Creates and returns a mapper function to access country data. The mapper function that is returned must be called with one argument. In @@ -73,6 +68,6 @@ def mapper(input: str) -> Any: # If there is a record return the demanded attribute. item = dataset.get(input) if item: - return item[to_key] # type: ignore + return item[to_key] return mapper diff --git a/geonamescache/types.py b/geonamescache/types.py index 38dea39..f1b033d 100644 --- a/geonamescache/types.py +++ b/geonamescache/types.py @@ -5,114 +5,116 @@ GeoNameIdStr = str ISOStr = str -ContinentCode = Literal['AF', 'AN', 'AS', 'EU', 'NA', 'OC', 'SA'] +ContinentCode = Literal["AF", "AN", "AS", "EU", "NA", "OC", "SA"] USStateCode = Literal[ - 'AK', - 'AL', - 'AR', - 'AZ', - 'CA', - 'CO', - 'CT', - 'DC', - 'DE', - 'FL', - 'GA', - 'HI', - 'IA', - 'ID', - 'IL', - 'IN', - 'KS', - 'KY', - 'LA', - 'MA', - 'MD', - 'ME', - 'MI', - 'MN', - 'MO', - 'MS', - 'MT', - 'NC', - 'ND', - 'NE', - 'NH', - 'NJ', - 'NM', - 'NV', - 'NY', - 'OH', - 'OK', - 'OR', - 'PA', - 'RI', - 'SC', - 'SD', - 'TN', - 'TX', - 'UT', - 'VA', - 'VT', - 'WA', - 'WI', - 'WV', - 'WY', + "AK", + "AL", + "AR", + "AZ", + "CA", + "CO", + "CT", + "DC", + "DE", + "FL", + "GA", + "HI", + "IA", + "ID", + "IL", + "IN", + "KS", + "KY", + "LA", + "MA", + "MD", + "ME", + "MI", + "MN", + "MO", + "MS", + "MT", + "NC", + "ND", + "NE", + "NH", + "NJ", + "NM", + "NV", + "NY", + "OH", + "OK", + "OR", + "PA", + "RI", + "SC", + "SD", + "TN", + "TX", + "UT", + "VA", + "VT", + "WA", + "WI", + "WV", + "WY", ] USStateName = Literal[ - 'Alaska', - 'Alabama', - 'Arkansas', - 'Arizona', - 'California', - 'Colorado', - 'Connecticut', - 'District of Columbia', - 'Delaware', - 'Florida', - 'Georgia', - 'Hawaii', - 'Iowa', - 'Idaho', - 'Illinois', - 'Indiana', - 'Kansas', - 'Kentucky', - 'Louisiana', - 'Massachusetts', - 'Maryland', - 'Maine', - 'Michigan', - 'Minnesota', - 'Missouri', - 'Mississippi', - 'Montana', - 'North Carolina', - 'North Dakota', - 'Nebraska', - 'New Hampshire', - 'New Jersey', - 'New Mexico', - 'Nevada', - 'New York', - 'Ohio', - 'Oklahoma', - 'Oregon', - 'Pennsylvania', - 'Rhode Island', - 'South Carolina', - 'South Dakota', - 'Tennessee', - 'Texas', - 'Utah', - 'Virginia', - 'Vermont', - 'Washington', - 'Wisconsin', - 'West Virginia', - 'Wyoming', + "Alaska", + "Alabama", + "Arkansas", + "Arizona", + "California", + "Colorado", + "Connecticut", + "District of Columbia", + "Delaware", + "Florida", + "Georgia", + "Hawaii", + "Iowa", + "Idaho", + "Illinois", + "Indiana", + "Kansas", + "Kentucky", + "Louisiana", + "Massachusetts", + "Maryland", + "Maine", + "Michigan", + "Minnesota", + "Missouri", + "Mississippi", + "Montana", + "North Carolina", + "North Dakota", + "Nebraska", + "New Hampshire", + "New Jersey", + "New Mexico", + "Nevada", + "New York", + "Ohio", + "Oklahoma", + "Oregon", + "Pennsylvania", + "Rhode Island", + "South Carolina", + "South Dakota", + "Tennessee", + "Texas", + "Utah", + "Virginia", + "Vermont", + "Washington", + "Wisconsin", + "West Virginia", + "Wyoming", +] +CitySearchAttribute = Literal[ + "alternatenames", "admin1code", "countrycode", "name", "timezone" ] -CitySearchAttribute = Literal['alternatenames', 'admin1code', 'countrycode', 'name', 'timezone'] class TimeZone(TypedDict): @@ -176,6 +178,33 @@ class City(TypedDict): timezone: str +CountryNumericFields = Literal[ + "areakm2", + "isonumeric", + "geonameid", + "population", +] +CountryStringFields = Literal[ + "capital", + "currencycode", + "currencyname", + "iso", + "iso3", + "fips", + "languages", + "name", + "neighbours", + "phone", + "postalcoderegex", + "tld", +] +CountryFields = Literal[ + CountryNumericFields, + CountryStringFields, + "continentcode", +] + + class Country(TypedDict): areakm2: int capital: str From ff92eb4af236735bab96996bbf5dc5e3a57bf28a Mon Sep 17 00:00:00 2001 From: jicruz96 Date: Thu, 25 Jul 2024 14:51:39 -0400 Subject: [PATCH 4/4] [nit] use explicit types for country overload --- geonamescache/mappers.py | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/geonamescache/mappers.py b/geonamescache/mappers.py index 3c02c4a..45d1aa4 100644 --- a/geonamescache/mappers.py +++ b/geonamescache/mappers.py @@ -4,7 +4,8 @@ from geonamescache import GeonamesCache from . import mappings -from .types import ContinentCode, CountryFields, CountryNumericFields +from .types import (ContinentCode, CountryFields, CountryNumericFields, + CountryStringFields) @overload @@ -16,20 +17,7 @@ def country( @overload def country( from_key: str = "name", - to_key: Literal[ - "capital", - "currencycode", - "currencyname", - "iso", - "iso3", - "fips", - "languages", - "name", - "neighbours", - "phone", - "postalcoderegex", - "tld", - ] = "iso", + to_key: CountryStringFields = "iso", ) -> Callable[[str], str]: ...