From 8339c2b92813fd516d92bef1c4d7d3481b732010 Mon Sep 17 00:00:00 2001 From: Sarah Hoffmann Date: Wed, 3 Sep 2025 21:42:12 +0200 Subject: [PATCH] no longer accept None in result maker functions --- src/nominatim_api/lookup.py | 4 +-- src/nominatim_api/results.py | 31 ++++--------------- src/nominatim_api/reverse.py | 15 ++++----- .../search/db_searches/address_search.py | 10 ++---- .../search/db_searches/country_search.py | 2 -- .../search/db_searches/near_search.py | 1 - .../search/db_searches/place_search.py | 1 - .../search/db_searches/poi_search.py | 1 - .../search/db_searches/postcode_search.py | 1 - test/python/api/test_results.py | 8 ----- 10 files changed, 17 insertions(+), 57 deletions(-) diff --git a/src/nominatim_api/lookup.py b/src/nominatim_api/lookup.py index 3f5b61ae..c44d8f25 100644 --- a/src/nominatim_api/lookup.py +++ b/src/nominatim_api/lookup.py @@ -19,7 +19,7 @@ from .logging import log from . import types as ntyp from . import results as nres -RowFunc = Callable[[Optional[SaRow], Type[nres.BaseResultT]], Optional[nres.BaseResultT]] +RowFunc = Callable[[SaRow, Type[nres.BaseResultT]], nres.BaseResultT] GEOMETRY_TYPE_MAP = { 'POINT': 'ST_Point', @@ -74,7 +74,6 @@ class LookupCollector: for row in await conn.execute(sql): result = row_func(row, nres.SearchResult) - assert result is not None if hasattr(row, 'bbox'): result.bbox = ntyp.Bbox.from_wkb(row.bbox) @@ -116,7 +115,6 @@ class DetailedCollector: for row in await conn.execute(sql): self.result = row_func(row, nres.DetailedResult) - assert self.result is not None # add missing details if 'type' in self.result.geometry: self.result.geometry['type'] = \ diff --git a/src/nominatim_api/results.py b/src/nominatim_api/results.py index ddb15a2e..76e4c2f0 100644 --- a/src/nominatim_api/results.py +++ b/src/nominatim_api/results.py @@ -310,15 +310,11 @@ def _filter_geometries(row: SaRow) -> Dict[str, str]: if k.startswith('geometry_')} -def create_from_placex_row(row: Optional[SaRow], - class_type: Type[BaseResultT]) -> Optional[BaseResultT]: +def create_from_placex_row(row: SaRow, class_type: Type[BaseResultT]) -> BaseResultT: """ Construct a new result and add the data from the result row from the placex table. 'class_type' defines the type of result to return. Returns None if the row is None. """ - if row is None: - return None - return class_type(source_table=SourceTable.PLACEX, place_id=row.place_id, osm_object=(row.osm_type, row.osm_id), @@ -340,8 +336,7 @@ def create_from_placex_row(row: Optional[SaRow], geometry=_filter_geometries(row)) -def create_from_osmline_row(row: Optional[SaRow], - class_type: Type[BaseResultT]) -> Optional[BaseResultT]: +def create_from_osmline_row(row: SaRow, class_type: Type[BaseResultT]) -> BaseResultT: """ Construct a new result and add the data from the result row from the address interpolation table osmline. 'class_type' defines the type of result to return. Returns None if the row is None. @@ -349,9 +344,6 @@ def create_from_osmline_row(row: Optional[SaRow], If the row contains a housenumber, then the housenumber is filled out. Otherwise the result contains the interpolation information in extratags. """ - if row is None: - return None - hnr = getattr(row, 'housenumber', None) res = class_type(source_table=SourceTable.OSMLINE, @@ -375,10 +367,10 @@ def create_from_osmline_row(row: Optional[SaRow], return res -def create_from_tiger_row(row: Optional[SaRow], +def create_from_tiger_row(row: SaRow, class_type: Type[BaseResultT], osm_type: Optional[str] = None, - osm_id: Optional[int] = None) -> Optional[BaseResultT]: + osm_id: Optional[int] = None) -> BaseResultT: """ Construct a new result and add the data from the result row from the Tiger data interpolation table. 'class_type' defines the type of result to return. Returns None if the row is None. @@ -386,9 +378,6 @@ def create_from_tiger_row(row: Optional[SaRow], If the row contains a housenumber, then the housenumber is filled out. Otherwise the result contains the interpolation information in extratags. """ - if row is None: - return None - hnr = getattr(row, 'housenumber', None) res = class_type(source_table=SourceTable.TIGER, @@ -411,15 +400,11 @@ def create_from_tiger_row(row: Optional[SaRow], return res -def create_from_postcode_row(row: Optional[SaRow], - class_type: Type[BaseResultT]) -> Optional[BaseResultT]: +def create_from_postcode_row(row: SaRow, class_type: Type[BaseResultT]) -> BaseResultT: """ Construct a new result and add the data from the result row from the postcode table. 'class_type' defines the type of result to return. Returns None if the row is None. """ - if row is None: - return None - return class_type(source_table=SourceTable.POSTCODE, place_id=row.place_id, parent_place_id=row.parent_place_id, @@ -432,15 +417,11 @@ def create_from_postcode_row(row: Optional[SaRow], geometry=_filter_geometries(row)) -def create_from_country_row(row: Optional[SaRow], - class_type: Type[BaseResultT]) -> Optional[BaseResultT]: +def create_from_country_row(row: SaRow, class_type: Type[BaseResultT]) -> BaseResultT: """ Construct a new result and add the data from the result row from the fallback country tables. 'class_type' defines the type of result to return. Returns None if the row is None. """ - if row is None: - return None - return class_type(source_table=SourceTable.COUNTRY, category=('place', 'country'), centroid=Point.from_wkb(row.centroid), diff --git a/src/nominatim_api/reverse.py b/src/nominatim_api/reverse.py index c9f11b63..a5fd1ea4 100644 --- a/src/nominatim_api/reverse.py +++ b/src/nominatim_api/reverse.py @@ -21,7 +21,7 @@ from .logging import log from .types import AnyPoint, DataLayer, ReverseDetails, GeometryFormat, Bbox -RowFunc = Callable[[Optional[SaRow], Type[nres.ReverseResult]], Optional[nres.ReverseResult]] +RowFunc = Callable[[SaRow, Type[nres.ReverseResult]], nres.ReverseResult] WKT_PARAM: SaBind = sa.bindparam('wkt', type_=Geometry) MAX_RANK_PARAM: SaBind = sa.bindparam('max_rank') @@ -596,12 +596,13 @@ class ReverseGeocoder: if row is None and self.layer_enabled(DataLayer.ADDRESS): row, row_func = await self.lookup_country(ccodes) + if row is None: + return None + result = row_func(row, nres.ReverseResult) - if result is not None: - assert row is not None - result.distance = getattr(row, 'distance', 0) - if hasattr(row, 'bbox'): - result.bbox = Bbox.from_wkb(row.bbox) - await nres.add_result_details(self.conn, [result], self.params) + result.distance = getattr(row, 'distance', 0) + if hasattr(row, 'bbox'): + result.bbox = Bbox.from_wkb(row.bbox) + await nres.add_result_details(self.conn, [result], self.params) return result diff --git a/src/nominatim_api/search/db_searches/address_search.py b/src/nominatim_api/search/db_searches/address_search.py index 32d4555b..883e751e 100644 --- a/src/nominatim_api/search/db_searches/address_search.py +++ b/src/nominatim_api/search/db_searches/address_search.py @@ -78,7 +78,6 @@ async def _get_placex_housenumbers(conn: SearchConnection, for row in await conn.execute(sql): result = nres.create_from_placex_row(row, nres.SearchResult) - assert result result.bbox = Bbox.from_wkb(row.bbox) yield result @@ -102,9 +101,7 @@ async def _get_osmline(conn: SearchConnection, place_ids: List[int], sql = base.add_geometry_columns(sa.select(sub), sub.c.centroid, details) for row in await conn.execute(sql): - result = nres.create_from_osmline_row(row, nres.SearchResult) - assert result - yield result + yield nres.create_from_osmline_row(row, nres.SearchResult) async def _get_tiger(conn: SearchConnection, place_ids: List[int], @@ -126,9 +123,7 @@ async def _get_tiger(conn: SearchConnection, place_ids: List[int], sql = base.add_geometry_columns(sa.select(sub), sub.c.centroid, details) for row in await conn.execute(sql): - result = nres.create_from_tiger_row(row, nres.SearchResult) - assert result - yield result + yield nres.create_from_tiger_row(row, nres.SearchResult) class AddressSearch(base.AbstractSearch): @@ -325,7 +320,6 @@ class AddressSearch(base.AbstractSearch): results = nres.SearchResults() for row in await conn.execute(sql, bind_params): result = nres.create_from_placex_row(row, nres.SearchResult) - assert result result.bbox = Bbox.from_wkb(row.bbox) result.accuracy = row.accuracy if row.rank_address < 30: diff --git a/src/nominatim_api/search/db_searches/country_search.py b/src/nominatim_api/search/db_searches/country_search.py index 30d85f3b..22f73bb1 100644 --- a/src/nominatim_api/search/db_searches/country_search.py +++ b/src/nominatim_api/search/db_searches/country_search.py @@ -56,7 +56,6 @@ class CountrySearch(base.AbstractSearch): results = nres.SearchResults() for row in await conn.execute(sql, bind_params): result = nres.create_from_placex_row(row, nres.SearchResult) - assert result result.accuracy = self.penalty + self.countries.get_penalty(row.country_code, 5.0) result.bbox = Bbox.from_wkb(row.bbox) results.append(result) @@ -111,7 +110,6 @@ class CountrySearch(base.AbstractSearch): results = nres.SearchResults() for row in await conn.execute(sql, bind_params): result = nres.create_from_country_row(row, nres.SearchResult) - assert result result.bbox = Bbox.from_wkb(row.bbox) result.accuracy = self.penalty + self.countries.get_penalty(row.country_code, 5.0) results.append(result) diff --git a/src/nominatim_api/search/db_searches/near_search.py b/src/nominatim_api/search/db_searches/near_search.py index 37f99a6a..551f7eac 100644 --- a/src/nominatim_api/search/db_searches/near_search.py +++ b/src/nominatim_api/search/db_searches/near_search.py @@ -130,7 +130,6 @@ class NearSearch(base.AbstractSearch): 'countries': details.countries} for row in await conn.execute(sql, bind_params): result = nres.create_from_placex_row(row, nres.SearchResult) - assert result result.accuracy = self.penalty + penalty result.bbox = Bbox.from_wkb(row.bbox) results.append(result) diff --git a/src/nominatim_api/search/db_searches/place_search.py b/src/nominatim_api/search/db_searches/place_search.py index e647632d..cab5b74b 100644 --- a/src/nominatim_api/search/db_searches/place_search.py +++ b/src/nominatim_api/search/db_searches/place_search.py @@ -202,7 +202,6 @@ class PlaceSearch(base.AbstractSearch): results = nres.SearchResults() for row in await conn.execute(sql, bind_params): result = nres.create_from_placex_row(row, nres.SearchResult) - assert result result.bbox = Bbox.from_wkb(row.bbox) result.accuracy = row.accuracy results.append(result) diff --git a/src/nominatim_api/search/db_searches/poi_search.py b/src/nominatim_api/search/db_searches/poi_search.py index fd7cdce8..c78f8112 100644 --- a/src/nominatim_api/search/db_searches/poi_search.py +++ b/src/nominatim_api/search/db_searches/poi_search.py @@ -106,7 +106,6 @@ class PoiSearch(base.AbstractSearch): results = nres.SearchResults() for row in rows: result = nres.create_from_placex_row(row, nres.SearchResult) - assert result result.accuracy = self.penalty + self.qualifiers.get_penalty((row.class_, row.type)) result.bbox = Bbox.from_wkb(row.bbox) results.append(result) diff --git a/src/nominatim_api/search/db_searches/postcode_search.py b/src/nominatim_api/search/db_searches/postcode_search.py index c88147d4..bf900b7b 100644 --- a/src/nominatim_api/search/db_searches/postcode_search.py +++ b/src/nominatim_api/search/db_searches/postcode_search.py @@ -121,7 +121,6 @@ class PostcodeSearch(base.AbstractSearch): else: result = nres.create_from_postcode_row(row, nres.SearchResult) - assert result if result.place_id not in details.excluded: result.accuracy = row.accuracy results.append(result) diff --git a/test/python/api/test_results.py b/test/python/api/test_results.py index 8e9fbf68..f7569f62 100644 --- a/test/python/api/test_results.py +++ b/test/python/api/test_results.py @@ -48,14 +48,6 @@ def test_detailed_result_custom_importance(): assert res.calculated_importance() == 0.4563 -@pytest.mark.parametrize('func', (nresults.create_from_placex_row, - nresults.create_from_osmline_row, - nresults.create_from_tiger_row, - nresults.create_from_postcode_row)) -def test_create_row_none(func): - assert func(None, DetailedResult) is None - - @pytest.mark.parametrize('func', (nresults.create_from_osmline_row, nresults.create_from_tiger_row)) def test_create_row_with_housenumber(func): -- 2.39.5