From 854a4d6b85be81df14315e2aa780426f8d11e415 Mon Sep 17 00:00:00 2001 From: jicruz96 Date: Thu, 18 Jul 2024 08:31:59 -0400 Subject: [PATCH 1/7] add type hints --- geonamescache/__init__.py | 50 +++++--- geonamescache/geonamesdata.py | 5 +- geonamescache/mappers.py | 9 +- geonamescache/mappings.py | 5 +- geonamescache/types.py | 209 ++++++++++++++++++++++++++++++++++ requirements-dev.txt | 1 + setup.py | 1 + 7 files changed, 256 insertions(+), 24 deletions(-) create mode 100644 geonamescache/types.py diff --git a/geonamescache/__init__.py b/geonamescache/__init__.py index d43b23e..a781ed2 100644 --- a/geonamescache/__init__.py +++ b/geonamescache/__init__.py @@ -7,54 +7,62 @@ import json import os +from typing import Any, Dict, List, Mapping, Optional, Tuple, TypeVar from . import geonamesdata +from .types import (City, CitySearchAttribute, Continent, ContinentCode, + Country, GeoNameIdStr, ISOStr, USCounty, USState, + USStateCode, USStateName) + +TDict = TypeVar('TDict', bound=Mapping[str, Any]) class GeonamesCache: - us_states = geonamesdata.us_states - continents = None - countries = None - cities = None - cities_items = None - cities_by_names = {} - us_counties = None + us_states: Dict[USStateCode, USState] = geonamesdata.us_states + continents: Optional[Dict[ContinentCode, Continent]] = None + countries: Optional[Dict[ISOStr, Country]] = None + cities: Optional[Dict[GeoNameIdStr, City]] = None + cities_items: Optional[List[Tuple[GeoNameIdStr, City]]] = None + cities_by_names: Dict[str, List[Dict[GeoNameIdStr, City]]] = {} + us_counties: Optional[List[USCounty]] = None - def __init__(self, min_city_population=15000): + def __init__(self, min_city_population: int = 15000): self.min_city_population = min_city_population - def get_dataset_by_key(self, dataset, key): + def get_dataset_by_key( + self, dataset: Dict[str, TDict], key: str + ) -> Dict[str, TDict]: return dict((d[key], d) for c, d in list(dataset.items())) - def get_continents(self): + def get_continents(self) -> Dict[ContinentCode, Continent]: if self.continents is None: self.continents = self._load_data( self.continents, 'continents.json') return self.continents - def get_countries(self): + def get_countries(self) -> Dict[ISOStr, Country]: if self.countries is None: self.countries = self._load_data(self.countries, 'countries.json') return self.countries - def get_us_states(self): + def get_us_states(self) -> Dict[USStateCode, USState]: return self.us_states - def get_countries_by_names(self): + def get_countries_by_names(self) -> Dict[str, Country]: return self.get_dataset_by_key(self.get_countries(), 'name') - def get_us_states_by_names(self): + def get_us_states_by_names(self) -> Dict[USStateName, USState]: return self.get_dataset_by_key(self.get_us_states(), 'name') - def get_cities(self): + def get_cities(self) -> Dict[GeoNameIdStr, City]: """Get a dictionary of cities keyed by geonameid.""" if self.cities is None: self.cities = self._load_data(self.cities, f'cities{self.min_city_population}.json') return self.cities - def get_cities_by_name(self, name): + def get_cities_by_name(self, name: str) -> List[Dict[GeoNameIdStr, City]]: """Get a list of city dictionaries with the given name. City names cannot be used as keys, as they are not unique. @@ -72,7 +80,13 @@ def get_us_counties(self): self.us_counties = self._load_data(self.us_counties, 'us_counties.json') return self.us_counties - def search_cities(self, query, attribute='alternatenames', case_sensitive=False, contains_search=True): + def search_cities( + self, + query: str, + attribute: CitySearchAttribute = 'alternatenames', + case_sensitive: bool = False, + contains_search: bool = True, + ) -> List[City]: """Search all city records and return list of records, that match query for given attribute.""" results = [] query = (case_sensitive and query) or query.casefold() @@ -97,7 +111,7 @@ def search_cities(self, query, attribute='alternatenames', case_sensitive=False, return results @staticmethod - def _load_data(datadict, datafile): + def _load_data(datadict: Optional[Dict[str, Any]], datafile: str) -> Dict[str, 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/geonamesdata.py b/geonamescache/geonamesdata.py index a244815..184a153 100644 --- a/geonamescache/geonamesdata.py +++ b/geonamescache/geonamesdata.py @@ -1,5 +1,8 @@ # -*- coding: utf-8 -*- -us_states = { +from . import types +from typing import Dict + +us_states: Dict[types.USStateCode, types.USState] = { 'AK': {'code': 'AK', 'name': 'Alaska', 'fips': '02', 'geonameid': 5879092}, 'AL': {'code': 'AL', 'name': 'Alabama', 'fips': '01', 'geonameid': 4829764}, 'AR': {'code': 'AR', 'name': 'Arkansas', 'fips': '05', 'geonameid': 4099753}, diff --git a/geonamescache/mappers.py b/geonamescache/mappers.py index 5879f1e..5042793 100644 --- a/geonamescache/mappers.py +++ b/geonamescache/mappers.py @@ -1,9 +1,12 @@ # -*- coding: utf-8 -*- +from typing import Callable, Union + from geonamescache import GeonamesCache + from . import mappings -def country(from_key='name', to_key='iso'): +def country(from_key: str = 'name', to_key: str = 'iso') -> Callable[[str], Union[str, int, None]]: """Creates and returns a mapper function to access country data. The mapper function that is returned must be called with one argument. In @@ -21,7 +24,7 @@ def country(from_key='name', to_key='iso'): gc = GeonamesCache() dataset = gc.get_dataset_by_key(gc.get_countries(), from_key) - def mapper(input): + def mapper(input: str) -> Union[str, int, None]: # For country name inputs take the names mapping into account. if 'name' == from_key: input = mappings.country_names.get(input, input) @@ -30,4 +33,4 @@ def mapper(input): if item: return item[to_key] - return mapper \ No newline at end of file + return mapper diff --git a/geonamescache/mappings.py b/geonamescache/mappings.py index 8d1c08a..d953a90 100644 --- a/geonamescache/mappings.py +++ b/geonamescache/mappings.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- +from typing import Dict # Map country name variants to the ones used in GeoNames. -country_names = { +country_names: Dict[str, str] = { 'Bolivia (Plurinational State of)': 'Bolivia', 'Bosnia-Herzegovina': 'Bosnia and Herzegovina', 'Brunei Darussalam': 'Brunei', @@ -72,4 +73,4 @@ 'Venezuela (Bolivarian Republic of)': 'Venezuela', 'Viet Nam': 'Vietnam', 'West Bank and Gaza Strip': 'Palestinian Territory' -} \ No newline at end of file +} diff --git a/geonamescache/types.py b/geonamescache/types.py new file mode 100644 index 0000000..0ba21b9 --- /dev/null +++ b/geonamescache/types.py @@ -0,0 +1,209 @@ +# -*- coding: utf-8 -*- +from typing import List + +from typing_extensions import Literal, NotRequired, TypedDict + +GeoNameIdStr = str +ISOStr = str +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', +] +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', +] +CitySearchAttribute = Literal['alternatenames', 'admin1code', 'countrycode', 'name', 'timezone'] + + +class TimeZone(TypedDict): + dstOffset: int + gmtOffset: int + timeZoneId: str + + +class BBox(TypedDict): + accuracyLevel: int + east: float + north: float + south: float + west: float + + +class ContinentAlternateName(TypedDict): + lang: str + name: str + isPreferredName: NotRequired[bool] + isShortName: NotRequired[bool] + isColloquial: NotRequired[bool] + + +class Continent(TypedDict): + alternateNames: List[ContinentAlternateName] + adminName1: str + adminName2: str + adminName3: str + adminName4: str + adminName5: str + asciiName: str + continentCode: ContinentCode + fclName: str + fcodeName: str + astergdem: int + bbox: BBox + geonameId: int + fcl: str + fcode: str + lat: str + lng: str + name: str + population: int + timezone: TimeZone + toponymName: str + srtm3: int + wikipediaURL: str + cc2: NotRequired[str] + + +class City(TypedDict): + alternatenames: List[str] + admin1code: str + countrycode: str + geonameid: int + latitude: float + longitude: float + name: str + population: int + timezone: str + + +class Country(TypedDict): + areakm2: int + capital: str + continentcode: str + currencycode: str + currencyname: str + iso: str + isonumeric: int + iso3: str + fips: str + geonameid: int + languages: str + name: str + neighbours: str + phone: str + population: int + postalcoderegex: str + tld: str + + +class USState(TypedDict): + code: USStateCode + fips: str + geonameid: int + name: USStateName + + +class USCounty(TypedDict): + fips: str + name: str + state: USStateCode diff --git a/requirements-dev.txt b/requirements-dev.txt index d506377..375ddc5 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -5,4 +5,5 @@ ipython ipdb pytest twine +typing-extensions wheel \ No newline at end of file diff --git a/setup.py b/setup.py index 077f356..431ba99 100644 --- a/setup.py +++ b/setup.py @@ -31,4 +31,5 @@ ], test_suite='tests', tests_require=['pytest'], + install_requires=["typing-extensions"] ) From 407e516f9925258c73ff94eeb52b22b6ce2eadfc Mon Sep 17 00:00:00 2001 From: jicruz96 Date: Thu, 18 Jul 2024 09:42:49 -0400 Subject: [PATCH 2/7] [nit] standardize imports --- geonamescache/geonamesdata.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/geonamescache/geonamesdata.py b/geonamescache/geonamesdata.py index 184a153..271e2ce 100644 --- a/geonamescache/geonamesdata.py +++ b/geonamescache/geonamesdata.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- -from . import types from typing import Dict -us_states: Dict[types.USStateCode, types.USState] = { +from .types import USState, USStateCode + +us_states: Dict[USStateCode, USState] = { 'AK': {'code': 'AK', 'name': 'Alaska', 'fips': '02', 'geonameid': 5879092}, 'AL': {'code': 'AL', 'name': 'Alabama', 'fips': '01', 'geonameid': 4829764}, 'AR': {'code': 'AR', 'name': 'Arkansas', 'fips': '05', 'geonameid': 4099753}, @@ -54,4 +55,4 @@ 'WI': {'code': 'WI', 'name': 'Wisconsin', 'fips': '55', 'geonameid': 5279468}, 'WV': {'code': 'WV', 'name': 'West Virginia', 'fips': '54', 'geonameid': 4826850}, 'WY': {'code': 'WY', 'name': 'Wyoming', 'fips': '56', 'geonameid': 5843591} -} \ No newline at end of file +} From d491cf3ead2d4569dc4e554555182212c0d713f8 Mon Sep 17 00:00:00 2001 From: jicruz96 Date: Thu, 18 Jul 2024 09:43:25 -0400 Subject: [PATCH 3/7] use ContinentCode type for Country.continentcode --- geonamescache/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geonamescache/types.py b/geonamescache/types.py index 0ba21b9..38dea39 100644 --- a/geonamescache/types.py +++ b/geonamescache/types.py @@ -179,7 +179,7 @@ class City(TypedDict): class Country(TypedDict): areakm2: int capital: str - continentcode: str + continentcode: ContinentCode currencycode: str currencyname: str iso: str From 01e8341b85547aba3f6c771f579795ced9f35220 Mon Sep 17 00:00:00 2001 From: jicruz96 Date: Thu, 25 Jul 2024 14:15:53 -0400 Subject: [PATCH 4/7] 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 5/7] 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 6/7] 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 7/7] [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]: ...