]> git.openstreetmap.org Git - nominatim.git/commitdiff
enable flake for Python tests
authorSarah Hoffmann <lonvia@denofr.de>
Sun, 9 Mar 2025 14:33:24 +0000 (15:33 +0100)
committerSarah Hoffmann <lonvia@denofr.de>
Sun, 9 Mar 2025 14:33:24 +0000 (15:33 +0100)
93 files changed:
.flake8
Makefile
test/python/api/conftest.py
test/python/api/fake_adaptor.py
test/python/api/query_processing/test_normalize.py
test/python/api/query_processing/test_split_japanese_phrases.py
test/python/api/search/test_api_search_query.py
test/python/api/search/test_db_search_builder.py
test/python/api/search/test_icu_query_analyzer.py
test/python/api/search/test_postcode_parser.py
test/python/api/search/test_query.py
test/python/api/search/test_query_analyzer_factory.py
test/python/api/search/test_search_country.py
test/python/api/search/test_search_near.py
test/python/api/search/test_search_places.py
test/python/api/search/test_search_poi.py
test/python/api/search/test_search_postcode.py
test/python/api/search/test_token_assignment.py
test/python/api/test_api_connection.py
test/python/api/test_api_deletable_v1.py
test/python/api/test_api_details.py
test/python/api/test_api_lookup.py
test/python/api/test_api_polygons_v1.py
test/python/api/test_api_reverse.py
test/python/api/test_api_search.py
test/python/api/test_api_status.py
test/python/api/test_api_types.py
test/python/api/test_export.py
test/python/api/test_helpers_v1.py
test/python/api/test_localization.py
test/python/api/test_result_formatting_v1.py
test/python/api/test_result_formatting_v1_reverse.py
test/python/api/test_results.py
test/python/api/test_server_glue_v1.py
test/python/api/test_warm.py
test/python/cli/conftest.py
test/python/cli/test_cli.py
test/python/cli/test_cmd_admin.py
test/python/cli/test_cmd_api.py
test/python/cli/test_cmd_import.py
test/python/cli/test_cmd_refresh.py
test/python/cli/test_cmd_replication.py
test/python/config/test_config.py
test/python/config/test_config_load_module.py
test/python/conftest.py
test/python/cursor.py
test/python/data/test_country_info.py
test/python/db/test_connection.py
test/python/db/test_properties.py
test/python/db/test_sql_preprocessor.py
test/python/db/test_status.py
test/python/db/test_utils.py
test/python/dummy_tokenizer.py
test/python/indexer/test_indexing.py
test/python/mock_icu_word_table.py
test/python/mocks.py
test/python/tokenizer/sanitizers/test_clean_housenumbers.py
test/python/tokenizer/sanitizers/test_clean_postcodes.py
test/python/tokenizer/sanitizers/test_clean_tiger_tags.py
test/python/tokenizer/sanitizers/test_delete_tags.py
test/python/tokenizer/sanitizers/test_sanitizer_config.py
test/python/tokenizer/sanitizers/test_split_name_list.py
test/python/tokenizer/sanitizers/test_strip_brace_terms.py
test/python/tokenizer/sanitizers/test_tag_analyzer_by_language.py
test/python/tokenizer/sanitizers/test_tag_japanese.py
test/python/tokenizer/test_factory.py
test/python/tokenizer/test_icu.py
test/python/tokenizer/test_icu_rule_loader.py
test/python/tokenizer/test_place_sanitizer.py
test/python/tokenizer/token_analysis/test_analysis_postcodes.py
test/python/tokenizer/token_analysis/test_generic.py
test/python/tokenizer/token_analysis/test_generic_mutation.py
test/python/tokenizer/token_analysis/test_simple_trie.py
test/python/tools/conftest.py
test/python/tools/test_add_osm_data.py
test/python/tools/test_admin.py
test/python/tools/test_check_database.py
test/python/tools/test_database_import.py
test/python/tools/test_exec_utils.py
test/python/tools/test_freeze.py
test/python/tools/test_import_special_phrases.py
test/python/tools/test_migration.py
test/python/tools/test_postcodes.py
test/python/tools/test_refresh.py
test/python/tools/test_refresh_address_levels.py
test/python/tools/test_refresh_create_functions.py
test/python/tools/test_refresh_wiki_data.py
test/python/tools/test_replication.py
test/python/tools/test_sp_csv_loader.py
test/python/tools/test_sp_wiki_loader.py
test/python/tools/test_tiger_data.py
test/python/utils/test_centroid.py
test/python/utils/test_json_writer.py

diff --git a/.flake8 b/.flake8
index 82d77ed37fffc613def880af5601bf7294983e5e..f3e0db567eb78ea0c7665fc86e3de1ce9a862018 100644 (file)
--- a/.flake8
+++ b/.flake8
@@ -6,3 +6,5 @@ extend-ignore =
     E711
 per-file-ignores =
     __init__.py: F401
     E711
 per-file-ignores =
     __init__.py: F401
+    test/python/utils/test_json_writer.py: E131
+    test/python/conftest.py: E402
index 9e914850b783400e9f2c1d0b6c6d9548b3678c14..72072a59778163b423e5dda70438b992993deba5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,7 @@ pytest:
        pytest test/python
 
 lint:
        pytest test/python
 
 lint:
-       flake8 src
+       flake8 src test/python
 
 bdd:
        cd test/bdd; behave -DREMOVE_TEMPLATE=1
 
 bdd:
        cd test/bdd; behave -DREMOVE_TEMPLATE=1
index 3ca0720b4da24f76a76b0f30e3084af5e87d2802..bde0afc41807daceb9dece48e17db937e5166b44 100644 (file)
@@ -2,14 +2,13 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Helper fixtures for API call tests.
 """
 import pytest
 import pytest_asyncio
 # For a full list of authors see the git log.
 """
 Helper fixtures for API call tests.
 """
 import pytest
 import pytest_asyncio
-import time
 import datetime as dt
 
 import sqlalchemy as sa
 import datetime as dt
 
 import sqlalchemy as sa
@@ -20,27 +19,25 @@ from nominatim_api.search.query_analyzer_factory import make_query_analyzer
 from nominatim_db.tools import convert_sqlite
 import nominatim_api.logging as loglib
 
 from nominatim_db.tools import convert_sqlite
 import nominatim_api.logging as loglib
 
+
 class APITester:
 
     def __init__(self):
         self.api = napi.NominatimAPI()
         self.async_to_sync(self.api._async_api.setup_database())
 
 class APITester:
 
     def __init__(self):
         self.api = napi.NominatimAPI()
         self.async_to_sync(self.api._async_api.setup_database())
 
-
     def async_to_sync(self, func):
         """ Run an asynchronous function until completion using the
             internal loop of the API.
         """
         return self.api._loop.run_until_complete(func)
 
     def async_to_sync(self, func):
         """ Run an asynchronous function until completion using the
             internal loop of the API.
         """
         return self.api._loop.run_until_complete(func)
 
-
     def add_data(self, table, data):
         """ Insert data into the given table.
         """
         sql = getattr(self.api._async_api._tables, table).insert()
         self.async_to_sync(self.exec_async(sql, data))
 
     def add_data(self, table, data):
         """ Insert data into the given table.
         """
         sql = getattr(self.api._async_api._tables, table).insert()
         self.async_to_sync(self.exec_async(sql, data))
 
-
     def add_placex(self, **kw):
         name = kw.get('name')
         if isinstance(name, str):
     def add_placex(self, **kw):
         name = kw.get('name')
         if isinstance(name, str):
@@ -50,30 +47,29 @@ class APITester:
         geometry = kw.get('geometry', 'POINT(%f %f)' % centroid)
 
         self.add_data('placex',
         geometry = kw.get('geometry', 'POINT(%f %f)' % centroid)
 
         self.add_data('placex',
-                     {'place_id': kw.get('place_id', 1000),
-                      'osm_type': kw.get('osm_type', 'W'),
-                      'osm_id': kw.get('osm_id', 4),
-                      'class_': kw.get('class_', 'highway'),
-                      'type': kw.get('type', 'residential'),
-                      'name': name,
-                      'address': kw.get('address'),
-                      'extratags': kw.get('extratags'),
-                      'parent_place_id': kw.get('parent_place_id'),
-                      'linked_place_id': kw.get('linked_place_id'),
-                      'admin_level': kw.get('admin_level', 15),
-                      'country_code': kw.get('country_code'),
-                      'housenumber': kw.get('housenumber'),
-                      'postcode': kw.get('postcode'),
-                      'wikipedia': kw.get('wikipedia'),
-                      'rank_search': kw.get('rank_search', 30),
-                      'rank_address': kw.get('rank_address', 30),
-                      'importance': kw.get('importance'),
-                      'centroid': 'POINT(%f %f)' % centroid,
-                      'indexed_status': kw.get('indexed_status', 0),
-                      'indexed_date': kw.get('indexed_date',
-                                             dt.datetime(2022, 12, 7, 14, 14, 46, 0)),
-                      'geometry': geometry})
-
+                      {'place_id': kw.get('place_id', 1000),
+                       'osm_type': kw.get('osm_type', 'W'),
+                       'osm_id': kw.get('osm_id', 4),
+                       'class_': kw.get('class_', 'highway'),
+                       'type': kw.get('type', 'residential'),
+                       'name': name,
+                       'address': kw.get('address'),
+                       'extratags': kw.get('extratags'),
+                       'parent_place_id': kw.get('parent_place_id'),
+                       'linked_place_id': kw.get('linked_place_id'),
+                       'admin_level': kw.get('admin_level', 15),
+                       'country_code': kw.get('country_code'),
+                       'housenumber': kw.get('housenumber'),
+                       'postcode': kw.get('postcode'),
+                       'wikipedia': kw.get('wikipedia'),
+                       'rank_search': kw.get('rank_search', 30),
+                       'rank_address': kw.get('rank_address', 30),
+                       'importance': kw.get('importance'),
+                       'centroid': 'POINT(%f %f)' % centroid,
+                       'indexed_status': kw.get('indexed_status', 0),
+                       'indexed_date': kw.get('indexed_date',
+                                              dt.datetime(2022, 12, 7, 14, 14, 46, 0)),
+                       'geometry': geometry})
 
     def add_address_placex(self, object_id, **kw):
         self.add_placex(**kw)
 
     def add_address_placex(self, object_id, **kw):
         self.add_placex(**kw)
@@ -85,46 +81,42 @@ class APITester:
                        'fromarea': kw.get('fromarea', False),
                        'isaddress': kw.get('isaddress', True)})
 
                        'fromarea': kw.get('fromarea', False),
                        'isaddress': kw.get('isaddress', True)})
 
-
     def add_osmline(self, **kw):
         self.add_data('osmline',
     def add_osmline(self, **kw):
         self.add_data('osmline',
-                     {'place_id': kw.get('place_id', 10000),
-                      'osm_id': kw.get('osm_id', 4004),
-                      'parent_place_id': kw.get('parent_place_id'),
-                      'indexed_date': kw.get('indexed_date',
-                                             dt.datetime(2022, 12, 7, 14, 14, 46, 0)),
-                      'startnumber': kw.get('startnumber', 2),
-                      'endnumber': kw.get('endnumber', 6),
-                      'step': kw.get('step', 2),
-                      'address': kw.get('address'),
-                      'postcode': kw.get('postcode'),
-                      'country_code': kw.get('country_code'),
-                      'linegeo': kw.get('geometry', 'LINESTRING(1.1 -0.2, 1.09 -0.22)')})
-
+                      {'place_id': kw.get('place_id', 10000),
+                       'osm_id': kw.get('osm_id', 4004),
+                       'parent_place_id': kw.get('parent_place_id'),
+                       'indexed_date': kw.get('indexed_date',
+                                              dt.datetime(2022, 12, 7, 14, 14, 46, 0)),
+                       'startnumber': kw.get('startnumber', 2),
+                       'endnumber': kw.get('endnumber', 6),
+                       'step': kw.get('step', 2),
+                       'address': kw.get('address'),
+                       'postcode': kw.get('postcode'),
+                       'country_code': kw.get('country_code'),
+                       'linegeo': kw.get('geometry', 'LINESTRING(1.1 -0.2, 1.09 -0.22)')})
 
     def add_tiger(self, **kw):
         self.add_data('tiger',
 
     def add_tiger(self, **kw):
         self.add_data('tiger',
-                     {'place_id': kw.get('place_id', 30000),
-                      'parent_place_id': kw.get('parent_place_id'),
-                      'startnumber': kw.get('startnumber', 2),
-                      'endnumber': kw.get('endnumber', 6),
-                      'step': kw.get('step', 2),
-                      'postcode': kw.get('postcode'),
-                      'linegeo': kw.get('geometry', 'LINESTRING(1.1 -0.2, 1.09 -0.22)')})
-
+                      {'place_id': kw.get('place_id', 30000),
+                       'parent_place_id': kw.get('parent_place_id'),
+                       'startnumber': kw.get('startnumber', 2),
+                       'endnumber': kw.get('endnumber', 6),
+                       'step': kw.get('step', 2),
+                       'postcode': kw.get('postcode'),
+                       'linegeo': kw.get('geometry', 'LINESTRING(1.1 -0.2, 1.09 -0.22)')})
 
     def add_postcode(self, **kw):
         self.add_data('postcode',
 
     def add_postcode(self, **kw):
         self.add_data('postcode',
-                     {'place_id': kw.get('place_id', 1000),
-                      'parent_place_id': kw.get('parent_place_id'),
-                      'country_code': kw.get('country_code'),
-                      'postcode': kw.get('postcode'),
-                      'rank_search': kw.get('rank_search', 20),
-                      'rank_address': kw.get('rank_address', 22),
-                      'indexed_date': kw.get('indexed_date',
-                                             dt.datetime(2022, 12, 7, 14, 14, 46, 0)),
-                      'geometry': kw.get('geometry', 'POINT(23 34)')})
-
+                      {'place_id': kw.get('place_id', 1000),
+                       'parent_place_id': kw.get('parent_place_id'),
+                       'country_code': kw.get('country_code'),
+                       'postcode': kw.get('postcode'),
+                       'rank_search': kw.get('rank_search', 20),
+                       'rank_address': kw.get('rank_address', 22),
+                       'indexed_date': kw.get('indexed_date',
+                                              dt.datetime(2022, 12, 7, 14, 14, 46, 0)),
+                       'geometry': kw.get('geometry', 'POINT(23 34)')})
 
     def add_country(self, country_code, geometry):
         self.add_data('country_grid',
 
     def add_country(self, country_code, geometry):
         self.add_data('country_grid',
@@ -132,14 +124,12 @@ class APITester:
                        'area': 0.1,
                        'geometry': geometry})
 
                        'area': 0.1,
                        'geometry': geometry})
 
-
     def add_country_name(self, country_code, names, partition=0):
         self.add_data('country_name',
                       {'country_code': country_code,
                        'name': names,
                        'partition': partition})
 
     def add_country_name(self, country_code, names, partition=0):
         self.add_data('country_name',
                       {'country_code': country_code,
                        'name': names,
                        'partition': partition})
 
-
     def add_search_name(self, place_id, **kw):
         centroid = kw.get('centroid', (23.0, 34.0))
         self.add_data('search_name',
     def add_search_name(self, place_id, **kw):
         centroid = kw.get('centroid', (23.0, 34.0))
         self.add_data('search_name',
@@ -152,7 +142,6 @@ class APITester:
                        'country_code': kw.get('country_code', 'xx'),
                        'centroid': 'POINT(%f %f)' % centroid})
 
                        'country_code': kw.get('country_code', 'xx'),
                        'centroid': 'POINT(%f %f)' % centroid})
 
-
     def add_class_type_table(self, cls, typ):
         self.async_to_sync(
             self.exec_async(sa.text(f"""CREATE TABLE place_classtype_{cls}_{typ}
     def add_class_type_table(self, cls, typ):
         self.async_to_sync(
             self.exec_async(sa.text(f"""CREATE TABLE place_classtype_{cls}_{typ}
@@ -160,7 +149,6 @@ class APITester:
                                              WHERE class = '{cls}' AND type = '{typ}')
                                      """)))
 
                                              WHERE class = '{cls}' AND type = '{typ}')
                                      """)))
 
-
     def add_word_table(self, content):
         data = [dict(zip(['word_id', 'word_token', 'type', 'word', 'info'], c))
                 for c in content]
     def add_word_table(self, content):
         data = [dict(zip(['word_id', 'word_token', 'type', 'word', 'info'], c))
                 for c in content]
@@ -176,12 +164,10 @@ class APITester:
 
         self.async_to_sync(_do_sql())
 
 
         self.async_to_sync(_do_sql())
 
-
     async def exec_async(self, sql, *args, **kwargs):
         async with self.api._async_api.begin() as conn:
             return await conn.execute(sql, *args, **kwargs)
 
     async def exec_async(self, sql, *args, **kwargs):
         async with self.api._async_api.begin() as conn:
             return await conn.execute(sql, *args, **kwargs)
 
-
     async def create_tables(self):
         async with self.api._async_api._engine.begin() as conn:
             await conn.run_sync(self.api._async_api._tables.meta.create_all)
     async def create_tables(self):
         async with self.api._async_api._engine.begin() as conn:
             await conn.run_sync(self.api._async_api._tables.meta.create_all)
@@ -212,11 +198,12 @@ def frontend(request, event_loop, tmp_path):
         db = str(tmp_path / 'test_nominatim_python_unittest.sqlite')
 
         def mkapi(apiobj, options={'reverse'}):
         db = str(tmp_path / 'test_nominatim_python_unittest.sqlite')
 
         def mkapi(apiobj, options={'reverse'}):
-            apiobj.add_data('properties',
-                        [{'property': 'tokenizer', 'value': 'icu'},
-                         {'property': 'tokenizer_import_normalisation', 'value': ':: lower();'},
-                         {'property': 'tokenizer_import_transliteration', 'value': "'1' > '/1/'; 'ä' > 'ä '"},
-                        ])
+            apiobj.add_data(
+                'properties',
+                [{'property': 'tokenizer', 'value': 'icu'},
+                 {'property': 'tokenizer_import_normalisation', 'value': ':: lower();'},
+                 {'property': 'tokenizer_import_transliteration',
+                  'value': "'1' > '/1/'; 'ä' > 'ä '"}])
 
             async def _do_sql():
                 async with apiobj.api._async_api.begin() as conn:
 
             async def _do_sql():
                 async with apiobj.api._async_api.begin() as conn:
index 4b64c17d9a25fe9ee630dc10653fd27d5e17c779..a3a3bcf9f47db798ae9a6e44d6880b4edeed4a38 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Provides dummy implementations of ASGIAdaptor for testing.
 # For a full list of authors see the git log.
 """
 Provides dummy implementations of ASGIAdaptor for testing.
@@ -13,6 +13,7 @@ import nominatim_api.v1.server_glue as glue
 from nominatim_api.v1.format import dispatch as formatting
 from nominatim_api.config import Configuration
 
 from nominatim_api.v1.format import dispatch as formatting
 from nominatim_api.config import Configuration
 
+
 class FakeError(BaseException):
 
     def __init__(self, msg, status):
 class FakeError(BaseException):
 
     def __init__(self, msg, status):
@@ -22,8 +23,10 @@ class FakeError(BaseException):
     def __str__(self):
         return f'{self.status} -- {self.msg}'
 
     def __str__(self):
         return f'{self.status} -- {self.msg}'
 
+
 FakeResponse = namedtuple('FakeResponse', ['status', 'output', 'content_type'])
 
 FakeResponse = namedtuple('FakeResponse', ['status', 'output', 'content_type'])
 
+
 class FakeAdaptor(glue.ASGIAdaptor):
 
     def __init__(self, params=None, headers=None, config=None):
 class FakeAdaptor(glue.ASGIAdaptor):
 
     def __init__(self, params=None, headers=None, config=None):
@@ -31,23 +34,18 @@ class FakeAdaptor(glue.ASGIAdaptor):
         self.headers = headers or {}
         self._config = config or Configuration(None)
 
         self.headers = headers or {}
         self._config = config or Configuration(None)
 
-
     def get(self, name, default=None):
         return self.params.get(name, default)
 
     def get(self, name, default=None):
         return self.params.get(name, default)
 
-
     def get_header(self, name, default=None):
         return self.headers.get(name, default)
 
     def get_header(self, name, default=None):
         return self.headers.get(name, default)
 
-
     def error(self, msg, status=400):
         return FakeError(msg, status)
 
     def error(self, msg, status=400):
         return FakeError(msg, status)
 
-
     def create_response(self, status, output, num_results):
         return FakeResponse(status, output, self.content_type)
 
     def create_response(self, status, output, num_results):
         return FakeResponse(status, output, self.content_type)
 
-
     def base_uri(self):
         return 'http://test'
 
     def base_uri(self):
         return 'http://test'
 
@@ -56,5 +54,3 @@ class FakeAdaptor(glue.ASGIAdaptor):
 
     def formatting(self):
         return formatting
 
     def formatting(self):
         return formatting
-
-
index 12a8de2a2e0ea15bf7dbedf01581173198112dc1..35f5fcd76e601ef046c36b8f8be98630d7479768 100644 (file)
@@ -2,21 +2,18 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for normalizing search queries.
 """
 # For a full list of authors see the git log.
 """
 Tests for normalizing search queries.
 """
-from pathlib import Path
-
-import pytest
-
 from icu import Transliterator
 
 import nominatim_api.search.query as qmod
 from nominatim_api.query_preprocessing.config import QueryConfig
 from nominatim_api.query_preprocessing import normalize
 
 from icu import Transliterator
 
 import nominatim_api.search.query as qmod
 from nominatim_api.query_preprocessing.config import QueryConfig
 from nominatim_api.query_preprocessing import normalize
 
+
 def run_preprocessor_on(query, norm):
     normalizer = Transliterator.createFromRules("normalization", norm)
     proc = normalize.create(QueryConfig().set_normalizer(normalizer))
 def run_preprocessor_on(query, norm):
     normalizer = Transliterator.createFromRules("normalization", norm)
     proc = normalize.create(QueryConfig().set_normalizer(normalizer))
index 51d592e3a724ca55c57c623ad5687123a254658e..30f22e7bbac864bc95fa8f93a198baf21c9802eb 100644 (file)
@@ -7,16 +7,13 @@
 """
 Tests for japanese phrase splitting.
 """
 """
 Tests for japanese phrase splitting.
 """
-from pathlib import Path
-
 import pytest
 
 import pytest
 
-from icu import Transliterator
-
 import nominatim_api.search.query as qmod
 from nominatim_api.query_preprocessing.config import QueryConfig
 from nominatim_api.query_preprocessing import split_japanese_phrases
 
 import nominatim_api.search.query as qmod
 from nominatim_api.query_preprocessing.config import QueryConfig
 from nominatim_api.query_preprocessing import split_japanese_phrases
 
+
 def run_preprocessor_on(query):
     proc = split_japanese_phrases.create(QueryConfig().set_normalizer(None))
 
 def run_preprocessor_on(query):
     proc = split_japanese_phrases.create(QueryConfig().set_normalizer(None))
 
index 08a1f7aafb02ac3d8228f20382bf4b9461c07502..c9e8de93683f419ad7cd1b9b1d9a7d163d986070 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for tokenized query data structures.
 # For a full list of authors see the git log.
 """
 Tests for tokenized query data structures.
@@ -11,6 +11,7 @@ import pytest
 
 from nominatim_api.search import query
 
 
 from nominatim_api.search import query
 
+
 class MyToken(query.Token):
 
     def get_category(self):
 class MyToken(query.Token):
 
     def get_category(self):
@@ -21,9 +22,11 @@ def mktoken(tid: int):
     return MyToken(penalty=3.0, token=tid, count=1, addr_count=1,
                    lookup_word='foo')
 
     return MyToken(penalty=3.0, token=tid, count=1, addr_count=1,
                    lookup_word='foo')
 
+
 @pytest.fixture
 def qnode():
 @pytest.fixture
 def qnode():
-    return query.QueryNode(query.BREAK_PHRASE, query.PHRASE_ANY, 0.0 ,'', '')
+    return query.QueryNode(query.BREAK_PHRASE, query.PHRASE_ANY, 0.0, '', '')
+
 
 @pytest.mark.parametrize('ptype,ttype', [(query.PHRASE_ANY, 'W'),
                                          (query.PHRASE_AMENITY, 'Q'),
 
 @pytest.mark.parametrize('ptype,ttype', [(query.PHRASE_ANY, 'W'),
                                          (query.PHRASE_AMENITY, 'Q'),
@@ -132,4 +135,3 @@ def test_query_struct_amenity_two_words():
     assert len(q.get_tokens(query.TokenRange(1, 2), query.TOKEN_PARTIAL)) == 1
     assert len(q.get_tokens(query.TokenRange(1, 2), query.TOKEN_NEAR_ITEM)) == 0
     assert len(q.get_tokens(query.TokenRange(1, 2), query.TOKEN_QUALIFIER)) == 1
     assert len(q.get_tokens(query.TokenRange(1, 2), query.TOKEN_PARTIAL)) == 1
     assert len(q.get_tokens(query.TokenRange(1, 2), query.TOKEN_NEAR_ITEM)) == 0
     assert len(q.get_tokens(query.TokenRange(1, 2), query.TOKEN_QUALIFIER)) == 1
-
index 49d5f303dee26378479d230dc574602a68245558..be34fbea070a2859de238bb563d5ca2e0033917c 100644 (file)
@@ -16,6 +16,7 @@ from nominatim_api.search.token_assignment import TokenAssignment
 from nominatim_api.types import SearchDetails
 import nominatim_api.search.db_searches as dbs
 
 from nominatim_api.types import SearchDetails
 import nominatim_api.search.db_searches as dbs
 
+
 class MyToken(Token):
     def get_category(self):
         return 'this', 'that'
 class MyToken(Token):
     def get_category(self):
         return 'this', 'that'
@@ -36,7 +37,6 @@ def make_query(*args):
                                     token=tid, count=1, addr_count=1,
                                     lookup_word=word))
 
                                     token=tid, count=1, addr_count=1,
                                     lookup_word=word))
 
-
     return q
 
 
     return q
 
 
@@ -241,8 +241,7 @@ def test_name_and_address():
                    [(2, qmod.TOKEN_PARTIAL, [(2, 'b')]),
                     (2, qmod.TOKEN_WORD, [(101, 'b')])],
                    [(3, qmod.TOKEN_PARTIAL, [(3, 'c')]),
                    [(2, qmod.TOKEN_PARTIAL, [(2, 'b')]),
                     (2, qmod.TOKEN_WORD, [(101, 'b')])],
                    [(3, qmod.TOKEN_PARTIAL, [(3, 'c')]),
-                    (3, qmod.TOKEN_WORD, [(102, 'c')])]
-                  )
+                    (3, qmod.TOKEN_WORD, [(102, 'c')])])
     builder = SearchBuilder(q, SearchDetails())
 
     searches = list(builder.build(TokenAssignment(name=TokenRange(0, 1),
     builder = SearchBuilder(q, SearchDetails())
 
     searches = list(builder.build(TokenAssignment(name=TokenRange(0, 1),
@@ -267,8 +266,7 @@ def test_name_and_complex_address():
                     (3, qmod.TOKEN_WORD, [(101, 'bc')])],
                    [(3, qmod.TOKEN_PARTIAL, [(3, 'c')])],
                    [(4, qmod.TOKEN_PARTIAL, [(4, 'd')]),
                     (3, qmod.TOKEN_WORD, [(101, 'bc')])],
                    [(3, qmod.TOKEN_PARTIAL, [(3, 'c')])],
                    [(4, qmod.TOKEN_PARTIAL, [(4, 'd')]),
-                    (4, qmod.TOKEN_WORD, [(103, 'd')])]
-                  )
+                    (4, qmod.TOKEN_WORD, [(103, 'd')])])
     builder = SearchBuilder(q, SearchDetails())
 
     searches = list(builder.build(TokenAssignment(name=TokenRange(0, 1),
     builder = SearchBuilder(q, SearchDetails())
 
     searches = list(builder.build(TokenAssignment(name=TokenRange(0, 1),
@@ -423,8 +421,8 @@ def test_infrequent_partials_in_name():
     assert len(search.lookups) == 2
     assert len(search.rankings) == 2
 
     assert len(search.lookups) == 2
     assert len(search.rankings) == 2
 
-    assert set((l.column, l.lookup_type.__name__) for l in search.lookups) == \
-            {('name_vector', 'LookupAll'), ('nameaddress_vector', 'Restrict')}
+    assert set((s.column, s.lookup_type.__name__) for s in search.lookups) == \
+        {('name_vector', 'LookupAll'), ('nameaddress_vector', 'Restrict')}
 
 
 def test_frequent_partials_in_name_and_address():
 
 
 def test_frequent_partials_in_name_and_address():
@@ -435,10 +433,10 @@ def test_frequent_partials_in_name_and_address():
     assert all(isinstance(s, dbs.PlaceSearch) for s in searches)
     searches.sort(key=lambda s: s.penalty)
 
     assert all(isinstance(s, dbs.PlaceSearch) for s in searches)
     searches.sort(key=lambda s: s.penalty)
 
-    assert set((l.column, l.lookup_type.__name__) for l in searches[0].lookups) == \
-            {('name_vector', 'LookupAny'), ('nameaddress_vector', 'Restrict')}
-    assert set((l.column, l.lookup_type.__name__) for l in searches[1].lookups) == \
-            {('nameaddress_vector', 'LookupAll'), ('name_vector', 'LookupAll')}
+    assert set((s.column, s.lookup_type.__name__) for s in searches[0].lookups) == \
+        {('name_vector', 'LookupAny'), ('nameaddress_vector', 'Restrict')}
+    assert set((s.column, s.lookup_type.__name__) for s in searches[1].lookups) == \
+        {('nameaddress_vector', 'LookupAll'), ('name_vector', 'LookupAll')}
 
 
 def test_too_frequent_partials_in_name_and_address():
 
 
 def test_too_frequent_partials_in_name_and_address():
@@ -449,5 +447,5 @@ def test_too_frequent_partials_in_name_and_address():
     assert all(isinstance(s, dbs.PlaceSearch) for s in searches)
     searches.sort(key=lambda s: s.penalty)
 
     assert all(isinstance(s, dbs.PlaceSearch) for s in searches)
     searches.sort(key=lambda s: s.penalty)
 
-    assert set((l.column, l.lookup_type.__name__) for l in searches[0].lookups) == \
-            {('name_vector', 'LookupAny'), ('nameaddress_vector', 'Restrict')}
+    assert set((s.column, s.lookup_type.__name__) for s in searches[0].lookups) == \
+        {('name_vector', 'LookupAny'), ('nameaddress_vector', 'Restrict')}
index fc200bca55baf9fff3ef31f576f8680a9e3316a3..725350266cf455baedc5a3e5e537fdae2fe6ea66 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for query analyzer for ICU tokenizer.
 # For a full list of authors see the git log.
 """
 Tests for query analyzer for ICU tokenizer.
@@ -16,7 +16,8 @@ import nominatim_api.search.query as qmod
 import nominatim_api.search.icu_tokenizer as tok
 from nominatim_api.logging import set_log_output, get_and_disable
 
 import nominatim_api.search.icu_tokenizer as tok
 from nominatim_api.logging import set_log_output, get_and_disable
 
-async def add_word(conn, word_id, word_token, wtype, word, info = None):
+
+async def add_word(conn, word_id, word_token, wtype, word, info=None):
     t = conn.t.meta.tables['word']
     await conn.execute(t.insert(), {'word_id': word_id,
                                     'word_token': word_token,
     t = conn.t.meta.tables['word']
     await conn.execute(t.insert(), {'word_id': word_id,
                                     'word_token': word_token,
@@ -28,6 +29,7 @@ async def add_word(conn, word_id, word_token, wtype, word, info = None):
 def make_phrase(query):
     return [Phrase(qmod.PHRASE_ANY, s) for s in query.split(',')]
 
 def make_phrase(query):
     return [Phrase(qmod.PHRASE_ANY, s) for s in query.split(',')]
 
+
 @pytest_asyncio.fixture
 async def conn(table_factory):
     """ Create an asynchronous SQLAlchemy engine for the test DB.
 @pytest_asyncio.fixture
 async def conn(table_factory):
     """ Create an asynchronous SQLAlchemy engine for the test DB.
@@ -102,8 +104,7 @@ async def test_splitting_in_transliteration(conn):
 
 @pytest.mark.asyncio
 @pytest.mark.parametrize('term,order', [('23456', ['P', 'H', 'W', 'w']),
 
 @pytest.mark.asyncio
 @pytest.mark.parametrize('term,order', [('23456', ['P', 'H', 'W', 'w']),
-                                        ('3', ['H', 'W', 'w'])
-                                       ])
+                                        ('3', ['H', 'W', 'w'])])
 async def test_penalty_postcodes_and_housenumbers(conn, term, order):
     ana = await tok.create_query_analyzer(conn)
 
 async def test_penalty_postcodes_and_housenumbers(conn, term, order):
     ana = await tok.create_query_analyzer(conn)
 
@@ -120,6 +121,7 @@ async def test_penalty_postcodes_and_housenumbers(conn, term, order):
 
     assert [t[1] for t in torder] == order
 
 
     assert [t[1] for t in torder] == order
 
+
 @pytest.mark.asyncio
 async def test_category_words_only_at_beginning(conn):
     ana = await tok.create_query_analyzer(conn)
 @pytest.mark.asyncio
 async def test_category_words_only_at_beginning(conn):
     ana = await tok.create_query_analyzer(conn)
index 284aba5b932b3c96bb60187f003da3402fe18561..38638e075f53e1d816e0cafcd8d4813d8707966b 100644 (file)
@@ -16,6 +16,7 @@ import pytest
 from nominatim_api.search.postcode_parser import PostcodeParser
 from nominatim_api.search.query import QueryStruct, PHRASE_ANY, PHRASE_POSTCODE, PHRASE_STREET
 
 from nominatim_api.search.postcode_parser import PostcodeParser
 from nominatim_api.search.query import QueryStruct, PHRASE_ANY, PHRASE_POSTCODE, PHRASE_STREET
 
+
 @pytest.fixture
 def pc_config(project_env):
     country_file = project_env.project_dir / 'country_settings.yaml'
 @pytest.fixture
 def pc_config(project_env):
     country_file = project_env.project_dir / 'country_settings.yaml'
@@ -55,6 +56,7 @@ ky:
 
     return project_env
 
 
     return project_env
 
+
 def mk_query(inp):
     query = QueryStruct([])
     phrase_split = re.split(r"([ ,:'-])", inp)
 def mk_query(inp):
     query = QueryStruct([])
     phrase_split = re.split(r"([ ,:'-])", inp)
@@ -80,6 +82,7 @@ def test_simple_postcode(pc_config, query, pos):
 
     assert result == {(pos, pos + 1, '45325'), (pos, pos + 1, '453 25')}
 
 
     assert result == {(pos, pos + 1, '45325'), (pos, pos + 1, '453 25')}
 
+
 def test_contained_postcode(pc_config):
     parser = PostcodeParser(pc_config)
 
 def test_contained_postcode(pc_config):
     parser = PostcodeParser(pc_config)
 
@@ -87,7 +90,6 @@ def test_contained_postcode(pc_config):
                                                   (0, 2, '12345 DX')}
 
 
                                                   (0, 2, '12345 DX')}
 
 
-
 @pytest.mark.parametrize('query,frm,to', [('345987', 0, 1), ('345 987', 0, 2),
                                           ('Aina 345 987', 1, 3),
                                           ('Aina 23 345 987 ff', 2, 4)])
 @pytest.mark.parametrize('query,frm,to', [('345987', 0, 1), ('345 987', 0, 2),
                                           ('Aina 345 987', 1, 3),
                                           ('Aina 23 345 987 ff', 2, 4)])
@@ -98,6 +100,7 @@ def test_postcode_with_space(pc_config, query, frm, to):
 
     assert result == {(frm, to, '345987')}
 
 
     assert result == {(frm, to, '345987')}
 
+
 def test_overlapping_postcode(pc_config):
     parser = PostcodeParser(pc_config)
 
 def test_overlapping_postcode(pc_config):
     parser = PostcodeParser(pc_config)
 
@@ -131,6 +134,7 @@ def test_postcode_with_non_matching_country_prefix(pc_config):
 
     assert not parser.parse(mk_query('ky12233'))
 
 
     assert not parser.parse(mk_query('ky12233'))
 
+
 def test_postcode_inside_postcode_phrase(pc_config):
     parser = PostcodeParser(pc_config)
 
 def test_postcode_inside_postcode_phrase(pc_config):
     parser = PostcodeParser(pc_config)
 
index bfed38df57f5b5993dd0cdf804ac79288cd81d46..09f25f8e273850b7bada2bb4af09a687c25e8129 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Test data types for search queries.
 # For a full list of authors see the git log.
 """
 Test data types for search queries.
@@ -11,14 +11,15 @@ import pytest
 
 import nominatim_api.search.query as nq
 
 
 import nominatim_api.search.query as nq
 
+
 def test_token_range_equal():
     assert nq.TokenRange(2, 3) == nq.TokenRange(2, 3)
     assert not (nq.TokenRange(2, 3) != nq.TokenRange(2, 3))
 
 
 @pytest.mark.parametrize('lop,rop', [((1, 2), (3, 4)),
 def test_token_range_equal():
     assert nq.TokenRange(2, 3) == nq.TokenRange(2, 3)
     assert not (nq.TokenRange(2, 3) != nq.TokenRange(2, 3))
 
 
 @pytest.mark.parametrize('lop,rop', [((1, 2), (3, 4)),
-                                    ((3, 4), (3, 5)),
-                                    ((10, 12), (11, 12))])
+                                     ((3, 4), (3, 5)),
+                                     ((10, 12), (11, 12))])
 def test_token_range_unequal(lop, rop):
     assert not (nq.TokenRange(*lop) == nq.TokenRange(*rop))
     assert nq.TokenRange(*lop) != nq.TokenRange(*rop)
 def test_token_range_unequal(lop, rop):
     assert not (nq.TokenRange(*lop) == nq.TokenRange(*rop))
     assert nq.TokenRange(*lop) != nq.TokenRange(*rop)
@@ -28,17 +29,17 @@ def test_token_range_lt():
     assert nq.TokenRange(1, 3) < nq.TokenRange(10, 12)
     assert nq.TokenRange(5, 6) < nq.TokenRange(7, 8)
     assert nq.TokenRange(1, 4) < nq.TokenRange(4, 5)
     assert nq.TokenRange(1, 3) < nq.TokenRange(10, 12)
     assert nq.TokenRange(5, 6) < nq.TokenRange(7, 8)
     assert nq.TokenRange(1, 4) < nq.TokenRange(4, 5)
-    assert not(nq.TokenRange(5, 6) < nq.TokenRange(5, 6))
-    assert not(nq.TokenRange(10, 11) < nq.TokenRange(4, 5))
+    assert not (nq.TokenRange(5, 6) < nq.TokenRange(5, 6))
+    assert not (nq.TokenRange(10, 11) < nq.TokenRange(4, 5))
 
 
 def test_token_rankge_gt():
     assert nq.TokenRange(3, 4) > nq.TokenRange(1, 2)
     assert nq.TokenRange(100, 200) > nq.TokenRange(10, 11)
     assert nq.TokenRange(10, 11) > nq.TokenRange(4, 10)
 
 
 def test_token_rankge_gt():
     assert nq.TokenRange(3, 4) > nq.TokenRange(1, 2)
     assert nq.TokenRange(100, 200) > nq.TokenRange(10, 11)
     assert nq.TokenRange(10, 11) > nq.TokenRange(4, 10)
-    assert not(nq.TokenRange(5, 6) > nq.TokenRange(5, 6))
-    assert not(nq.TokenRange(1, 2) > nq.TokenRange(3, 4))
-    assert not(nq.TokenRange(4, 10) > nq.TokenRange(3, 5))
+    assert not (nq.TokenRange(5, 6) > nq.TokenRange(5, 6))
+    assert not (nq.TokenRange(1, 2) > nq.TokenRange(3, 4))
+    assert not (nq.TokenRange(4, 10) > nq.TokenRange(3, 5))
 
 
 def test_token_range_unimplemented_ops():
 
 
 def test_token_range_unimplemented_ops():
@@ -58,8 +59,7 @@ def test_query_extract_words():
     words = q.extract_words(base_penalty=1.0)
 
     assert set(words.keys()) \
     words = q.extract_words(base_penalty=1.0)
 
     assert set(words.keys()) \
-             == {'12', 'ab', 'hallo', '12 ab', 'ab 12', '12 ab 12'}
+        == {'12', 'ab', 'hallo', '12 ab', 'ab 12', '12 ab 12'}
     assert sorted(words['12']) == [nq.TokenRange(0, 1, 1.0), nq.TokenRange(2, 3, 1.0)]
     assert words['12 ab'] == [nq.TokenRange(0, 2, 1.1)]
     assert words['hallo'] == [nq.TokenRange(3, 4, 1.0)]
     assert sorted(words['12']) == [nq.TokenRange(0, 1, 1.0), nq.TokenRange(2, 3, 1.0)]
     assert words['12 ab'] == [nq.TokenRange(0, 2, 1.1)]
     assert words['hallo'] == [nq.TokenRange(3, 4, 1.0)]
-
index 42220b55958116a5ab6f26448e6a8431539e486f..933bdd1f73340c7e3a0a3915810cd9ab09ae7f8d 100644 (file)
@@ -2,18 +2,17 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for query analyzer creation.
 """
 # For a full list of authors see the git log.
 """
 Tests for query analyzer creation.
 """
-from pathlib import Path
-
 import pytest
 
 from nominatim_api.search.query_analyzer_factory import make_query_analyzer
 from nominatim_api.search.icu_tokenizer import ICUQueryAnalyzer
 
 import pytest
 
 from nominatim_api.search.query_analyzer_factory import make_query_analyzer
 from nominatim_api.search.icu_tokenizer import ICUQueryAnalyzer
 
+
 @pytest.mark.asyncio
 async def test_import_icu_tokenizer(table_factory, api):
     table_factory('nominatim_properties',
 @pytest.mark.asyncio
 async def test_import_icu_tokenizer(table_factory, api):
     table_factory('nominatim_properties',
index 2109ecb0bb7fb5ff4cd54ed08e913e446c476a95..46875a2c8323c347c79d5afda3c1619bf96cb4c4 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for running the country searcher.
 # For a full list of authors see the git log.
 """
 Tests for running the country searcher.
@@ -48,6 +48,7 @@ def test_find_from_placex(apiobj, frontend):
     assert results[0].place_id == 55
     assert results[0].accuracy == 0.8
 
     assert results[0].place_id == 55
     assert results[0].accuracy == 0.8
 
+
 def test_find_from_fallback_countries(apiobj, frontend):
     apiobj.add_country('ro', 'POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))')
     apiobj.add_country_name('ro', {'name': 'România'})
 def test_find_from_fallback_countries(apiobj, frontend):
     apiobj.add_country('ro', 'POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))')
     apiobj.add_country_name('ro', {'name': 'România'})
@@ -87,7 +88,6 @@ class TestCountryParameters:
         apiobj.add_country('ro', 'POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))')
         apiobj.add_country_name('ro', {'name': 'România'})
 
         apiobj.add_country('ro', 'POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))')
         apiobj.add_country_name('ro', {'name': 'România'})
 
-
     @pytest.mark.parametrize('geom', [napi.GeometryFormat.GEOJSON,
                                       napi.GeometryFormat.KML,
                                       napi.GeometryFormat.SVG,
     @pytest.mark.parametrize('geom', [napi.GeometryFormat.GEOJSON,
                                       napi.GeometryFormat.KML,
                                       napi.GeometryFormat.SVG,
@@ -100,7 +100,6 @@ class TestCountryParameters:
         assert len(results) == 1
         assert geom.name.lower() in results[0].geometry
 
         assert len(results) == 1
         assert geom.name.lower() in results[0].geometry
 
-
     @pytest.mark.parametrize('pid,rids', [(76, [55]), (55, [])])
     def test_exclude_place_id(self, apiobj, frontend, pid, rids):
         results = run_search(apiobj, frontend, 0.5, ['yw', 'ro'],
     @pytest.mark.parametrize('pid,rids', [(76, [55]), (55, [])])
     def test_exclude_place_id(self, apiobj, frontend, pid, rids):
         results = run_search(apiobj, frontend, 0.5, ['yw', 'ro'],
@@ -108,7 +107,6 @@ class TestCountryParameters:
 
         assert [r.place_id for r in results] == rids
 
 
         assert [r.place_id for r in results] == rids
 
-
     @pytest.mark.parametrize('viewbox,rids', [((9, 9, 11, 11), [55]),
                                               ((-10, -10, -3, -3), [])])
     def test_bounded_viewbox_in_placex(self, apiobj, frontend, viewbox, rids):
     @pytest.mark.parametrize('viewbox,rids', [((9, 9, 11, 11), [55]),
                                               ((-10, -10, -3, -3), [])])
     def test_bounded_viewbox_in_placex(self, apiobj, frontend, viewbox, rids):
@@ -118,9 +116,8 @@ class TestCountryParameters:
 
         assert [r.place_id for r in results] == rids
 
 
         assert [r.place_id for r in results] == rids
 
-
     @pytest.mark.parametrize('viewbox,numres', [((0, 0, 1, 1), 1),
     @pytest.mark.parametrize('viewbox,numres', [((0, 0, 1, 1), 1),
-                                              ((-10, -10, -3, -3), 0)])
+                                                ((-10, -10, -3, -3), 0)])
     def test_bounded_viewbox_in_fallback(self, apiobj, frontend, viewbox, numres):
         results = run_search(apiobj, frontend, 0.5, ['ro'],
                              details=SearchDetails.from_kwargs({'viewbox': viewbox,
     def test_bounded_viewbox_in_fallback(self, apiobj, frontend, viewbox, numres):
         results = run_search(apiobj, frontend, 0.5, ['ro'],
                              details=SearchDetails.from_kwargs({'viewbox': viewbox,
index 43098ddd20e5af93ca3c5b4f76235f2d565c58fa..e9650168cbba62a7d9c875fe583776aa75137216 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for running the near searcher.
 # For a full list of authors see the git log.
 """
 Tests for running the near searcher.
@@ -12,8 +12,8 @@ import pytest
 import nominatim_api as napi
 from nominatim_api.types import SearchDetails
 from nominatim_api.search.db_searches import NearSearch, PlaceSearch
 import nominatim_api as napi
 from nominatim_api.types import SearchDetails
 from nominatim_api.search.db_searches import NearSearch, PlaceSearch
-from nominatim_api.search.db_search_fields import WeightedStrings, WeightedCategories,\
-                                                  FieldLookup, FieldRanking, RankedTokens
+from nominatim_api.search.db_search_fields import WeightedStrings, WeightedCategories, \
+                                                  FieldLookup
 from nominatim_api.search.db_search_lookups import LookupAll
 
 
 from nominatim_api.search.db_search_lookups import LookupAll
 
 
@@ -80,7 +80,6 @@ class TestNearSearch:
         apiobj.add_search_name(101, names=[56], country_code='mx',
                                centroid=(-10.3, 56.9))
 
         apiobj.add_search_name(101, names=[56], country_code='mx',
                                centroid=(-10.3, 56.9))
 
-
     def test_near_in_placex(self, apiobj, frontend):
         apiobj.add_placex(place_id=22, class_='amenity', type='bank',
                           centroid=(5.6001, 4.2994))
     def test_near_in_placex(self, apiobj, frontend):
         apiobj.add_placex(place_id=22, class_='amenity', type='bank',
                           centroid=(5.6001, 4.2994))
@@ -91,7 +90,6 @@ class TestNearSearch:
 
         assert [r.place_id for r in results] == [22]
 
 
         assert [r.place_id for r in results] == [22]
 
-
     def test_multiple_types_near_in_placex(self, apiobj, frontend):
         apiobj.add_placex(place_id=22, class_='amenity', type='bank',
                           importance=0.002,
     def test_multiple_types_near_in_placex(self, apiobj, frontend):
         apiobj.add_placex(place_id=22, class_='amenity', type='bank',
                           importance=0.002,
@@ -105,7 +103,6 @@ class TestNearSearch:
 
         assert [r.place_id for r in results] == [22, 23]
 
 
         assert [r.place_id for r in results] == [22, 23]
 
-
     def test_near_in_classtype(self, apiobj, frontend):
         apiobj.add_placex(place_id=22, class_='amenity', type='bank',
                           centroid=(5.6, 4.34))
     def test_near_in_classtype(self, apiobj, frontend):
         apiobj.add_placex(place_id=22, class_='amenity', type='bank',
                           centroid=(5.6, 4.34))
@@ -118,7 +115,6 @@ class TestNearSearch:
 
         assert [r.place_id for r in results] == [22]
 
 
         assert [r.place_id for r in results] == [22]
 
-
     @pytest.mark.parametrize('cc,rid', [('us', 22), ('mx', 23)])
     def test_restrict_by_country(self, apiobj, frontend, cc, rid):
         apiobj.add_placex(place_id=22, class_='amenity', type='bank',
     @pytest.mark.parametrize('cc,rid', [('us', 22), ('mx', 23)])
     def test_restrict_by_country(self, apiobj, frontend, cc, rid):
         apiobj.add_placex(place_id=22, class_='amenity', type='bank',
@@ -138,7 +134,6 @@ class TestNearSearch:
 
         assert [r.place_id for r in results] == [rid]
 
 
         assert [r.place_id for r in results] == [rid]
 
-
     @pytest.mark.parametrize('excluded,rid', [(22, 122), (122, 22)])
     def test_exclude_place_by_id(self, apiobj, frontend, excluded, rid):
         apiobj.add_placex(place_id=22, class_='amenity', type='bank',
     @pytest.mark.parametrize('excluded,rid', [(22, 122), (122, 22)])
     def test_exclude_place_by_id(self, apiobj, frontend, excluded, rid):
         apiobj.add_placex(place_id=22, class_='amenity', type='bank',
@@ -148,13 +143,11 @@ class TestNearSearch:
                           centroid=(5.6001, 4.2994),
                           country_code='us')
 
                           centroid=(5.6001, 4.2994),
                           country_code='us')
 
-
         results = run_search(apiobj, frontend, 0.1, [('amenity', 'bank')],
                              details=SearchDetails(excluded=[excluded]))
 
         assert [r.place_id for r in results] == [rid]
 
         results = run_search(apiobj, frontend, 0.1, [('amenity', 'bank')],
                              details=SearchDetails(excluded=[excluded]))
 
         assert [r.place_id for r in results] == [rid]
 
-
     @pytest.mark.parametrize('layer,rids', [(napi.DataLayer.POI, [22]),
                                             (napi.DataLayer.MANMADE, [])])
     def test_with_layer(self, apiobj, frontend, layer, rids):
     @pytest.mark.parametrize('layer,rids', [(napi.DataLayer.POI, [22]),
                                             (napi.DataLayer.MANMADE, [])])
     def test_with_layer(self, apiobj, frontend, layer, rids):
index c6ff16b83e8a81a62c2107cd7868b0aeab5c9f00..ed0722c3c218821e733126cb18cc295a5be3f38b 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for running the generic place searcher.
 # For a full list of authors see the git log.
 """
 Tests for running the generic place searcher.
@@ -14,12 +14,13 @@ import pytest
 import nominatim_api as napi
 from nominatim_api.types import SearchDetails
 from nominatim_api.search.db_searches import PlaceSearch
 import nominatim_api as napi
 from nominatim_api.types import SearchDetails
 from nominatim_api.search.db_searches import PlaceSearch
-from nominatim_api.search.db_search_fields import WeightedStrings, WeightedCategories,\
+from nominatim_api.search.db_search_fields import WeightedStrings, WeightedCategories, \
                                                   FieldLookup, FieldRanking, RankedTokens
 from nominatim_api.search.db_search_lookups import LookupAll, LookupAny, Restrict
 
 APIOPTIONS = ['search']
 
                                                   FieldLookup, FieldRanking, RankedTokens
 from nominatim_api.search.db_search_lookups import LookupAll, LookupAny, Restrict
 
 APIOPTIONS = ['search']
 
+
 def run_search(apiobj, frontend, global_penalty, lookup, ranking, count=2,
                hnrs=[], pcs=[], ccodes=[], quals=[],
                details=SearchDetails()):
 def run_search(apiobj, frontend, global_penalty, lookup, ranking, count=2,
                hnrs=[], pcs=[], ccodes=[], quals=[],
                details=SearchDetails()):
@@ -55,29 +56,27 @@ class TestNameOnlySearches:
     def fill_database(self, apiobj):
         apiobj.add_placex(place_id=100, country_code='us',
                           centroid=(5.6, 4.3))
     def fill_database(self, apiobj):
         apiobj.add_placex(place_id=100, country_code='us',
                           centroid=(5.6, 4.3))
-        apiobj.add_search_name(100, names=[1,2,10,11], country_code='us',
+        apiobj.add_search_name(100, names=[1, 2, 10, 11], country_code='us',
                                centroid=(5.6, 4.3))
         apiobj.add_placex(place_id=101, country_code='mx',
                           centroid=(-10.3, 56.9))
                                centroid=(5.6, 4.3))
         apiobj.add_placex(place_id=101, country_code='mx',
                           centroid=(-10.3, 56.9))
-        apiobj.add_search_name(101, names=[1,2,20,21], country_code='mx',
+        apiobj.add_search_name(101, names=[1, 2, 20, 21], country_code='mx',
                                centroid=(-10.3, 56.9))
 
                                centroid=(-10.3, 56.9))
 
-
     @pytest.mark.parametrize('lookup_type', [LookupAll, Restrict])
     @pytest.mark.parametrize('rank,res', [([10], [100, 101]),
                                           ([20], [101, 100])])
     def test_lookup_all_match(self, apiobj, frontend, lookup_type, rank, res):
     @pytest.mark.parametrize('lookup_type', [LookupAll, Restrict])
     @pytest.mark.parametrize('rank,res', [([10], [100, 101]),
                                           ([20], [101, 100])])
     def test_lookup_all_match(self, apiobj, frontend, lookup_type, rank, res):
-        lookup = FieldLookup('name_vector', [1,2], lookup_type)
+        lookup = FieldLookup('name_vector', [1, 2], lookup_type)
         ranking = FieldRanking('name_vector', 0.4, [RankedTokens(0.0, rank)])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking])
 
         assert [r.place_id for r in results] == res
 
         ranking = FieldRanking('name_vector', 0.4, [RankedTokens(0.0, rank)])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking])
 
         assert [r.place_id for r in results] == res
 
-
     @pytest.mark.parametrize('lookup_type', [LookupAll, Restrict])
     def test_lookup_all_partial_match(self, apiobj, frontend, lookup_type):
     @pytest.mark.parametrize('lookup_type', [LookupAll, Restrict])
     def test_lookup_all_partial_match(self, apiobj, frontend, lookup_type):
-        lookup = FieldLookup('name_vector', [1,20], lookup_type)
+        lookup = FieldLookup('name_vector', [1, 20], lookup_type)
         ranking = FieldRanking('name_vector', 0.4, [RankedTokens(0.0, [21])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking])
         ranking = FieldRanking('name_vector', 0.4, [RankedTokens(0.0, [21])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking])
@@ -88,14 +87,13 @@ class TestNameOnlySearches:
     @pytest.mark.parametrize('rank,res', [([10], [100, 101]),
                                           ([20], [101, 100])])
     def test_lookup_any_match(self, apiobj, frontend, rank, res):
     @pytest.mark.parametrize('rank,res', [([10], [100, 101]),
                                           ([20], [101, 100])])
     def test_lookup_any_match(self, apiobj, frontend, rank, res):
-        lookup = FieldLookup('name_vector', [11,21], LookupAny)
+        lookup = FieldLookup('name_vector', [11, 21], LookupAny)
         ranking = FieldRanking('name_vector', 0.4, [RankedTokens(0.0, rank)])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking])
 
         assert [r.place_id for r in results] == res
 
         ranking = FieldRanking('name_vector', 0.4, [RankedTokens(0.0, rank)])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking])
 
         assert [r.place_id for r in results] == res
 
-
     def test_lookup_any_partial_match(self, apiobj, frontend):
         lookup = FieldLookup('name_vector', [20], LookupAll)
         ranking = FieldRanking('name_vector', 0.4, [RankedTokens(0.0, [21])])
     def test_lookup_any_partial_match(self, apiobj, frontend):
         lookup = FieldLookup('name_vector', [20], LookupAll)
         ranking = FieldRanking('name_vector', 0.4, [RankedTokens(0.0, [21])])
@@ -105,19 +103,17 @@ class TestNameOnlySearches:
         assert len(results) == 1
         assert results[0].place_id == 101
 
         assert len(results) == 1
         assert results[0].place_id == 101
 
-
     @pytest.mark.parametrize('cc,res', [('us', 100), ('mx', 101)])
     def test_lookup_restrict_country(self, apiobj, frontend, cc, res):
     @pytest.mark.parametrize('cc,res', [('us', 100), ('mx', 101)])
     def test_lookup_restrict_country(self, apiobj, frontend, cc, res):
-        lookup = FieldLookup('name_vector', [1,2], LookupAll)
+        lookup = FieldLookup('name_vector', [1, 2], LookupAll)
         ranking = FieldRanking('name_vector', 0.4, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking], ccodes=[cc])
 
         assert [r.place_id for r in results] == [res]
 
         ranking = FieldRanking('name_vector', 0.4, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking], ccodes=[cc])
 
         assert [r.place_id for r in results] == [res]
 
-
     def test_lookup_restrict_placeid(self, apiobj, frontend):
     def test_lookup_restrict_placeid(self, apiobj, frontend):
-        lookup = FieldLookup('name_vector', [1,2], LookupAll)
+        lookup = FieldLookup('name_vector', [1, 2], LookupAll)
         ranking = FieldRanking('name_vector', 0.4, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking],
         ranking = FieldRanking('name_vector', 0.4, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking],
@@ -125,7 +121,6 @@ class TestNameOnlySearches:
 
         assert [r.place_id for r in results] == [100]
 
 
         assert [r.place_id for r in results] == [100]
 
-
     @pytest.mark.parametrize('geom', [napi.GeometryFormat.GEOJSON,
                                       napi.GeometryFormat.KML,
                                       napi.GeometryFormat.SVG,
     @pytest.mark.parametrize('geom', [napi.GeometryFormat.GEOJSON,
                                       napi.GeometryFormat.KML,
                                       napi.GeometryFormat.SVG,
@@ -139,7 +134,6 @@ class TestNameOnlySearches:
 
         assert geom.name.lower() in results[0].geometry
 
 
         assert geom.name.lower() in results[0].geometry
 
-
     @pytest.mark.parametrize('factor,npoints', [(0.0, 3), (1.0, 2)])
     def test_return_simplified_geometry(self, apiobj, frontend, factor, npoints):
         apiobj.add_placex(place_id=333, country_code='us',
     @pytest.mark.parametrize('factor,npoints', [(0.0, 3), (1.0, 2)])
     def test_return_simplified_geometry(self, apiobj, frontend, factor, npoints):
         apiobj.add_placex(place_id=333, country_code='us',
@@ -162,7 +156,6 @@ class TestNameOnlySearches:
         assert result.place_id == 333
         assert len(geom['coordinates']) == npoints
 
         assert result.place_id == 333
         assert len(geom['coordinates']) == npoints
 
-
     @pytest.mark.parametrize('viewbox', ['5.0,4.0,6.0,5.0', '5.7,4.0,6.0,5.0'])
     @pytest.mark.parametrize('wcount,rids', [(2, [100, 101]), (20000, [100])])
     def test_prefer_viewbox(self, apiobj, frontend, viewbox, wcount, rids):
     @pytest.mark.parametrize('viewbox', ['5.0,4.0,6.0,5.0', '5.7,4.0,6.0,5.0'])
     @pytest.mark.parametrize('wcount,rids', [(2, [100, 101]), (20000, [100])])
     def test_prefer_viewbox(self, apiobj, frontend, viewbox, wcount, rids):
@@ -177,18 +170,16 @@ class TestNameOnlySearches:
                              details=SearchDetails.from_kwargs({'viewbox': viewbox}))
         assert [r.place_id for r in results] == rids
 
                              details=SearchDetails.from_kwargs({'viewbox': viewbox}))
         assert [r.place_id for r in results] == rids
 
-
     @pytest.mark.parametrize('viewbox', ['5.0,4.0,6.0,5.0', '5.55,4.27,5.62,4.31'])
     def test_force_viewbox(self, apiobj, frontend, viewbox):
         lookup = FieldLookup('name_vector', [1, 2], LookupAll)
 
     @pytest.mark.parametrize('viewbox', ['5.0,4.0,6.0,5.0', '5.55,4.27,5.62,4.31'])
     def test_force_viewbox(self, apiobj, frontend, viewbox):
         lookup = FieldLookup('name_vector', [1, 2], LookupAll)
 
-        details=SearchDetails.from_kwargs({'viewbox': viewbox,
-                                           'bounded_viewbox': True})
+        details = SearchDetails.from_kwargs({'viewbox': viewbox,
+                                             'bounded_viewbox': True})
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [], details=details)
         assert [r.place_id for r in results] == [100]
 
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [], details=details)
         assert [r.place_id for r in results] == [100]
 
-
     def test_prefer_near(self, apiobj, frontend):
         lookup = FieldLookup('name_vector', [1, 2], LookupAll)
         ranking = FieldRanking('name_vector', 0.4, [RankedTokens(0.0, [21])])
     def test_prefer_near(self, apiobj, frontend):
         lookup = FieldLookup('name_vector', [1, 2], LookupAll)
         ranking = FieldRanking('name_vector', 0.4, [RankedTokens(0.0, [21])])
@@ -202,13 +193,12 @@ class TestNameOnlySearches:
         results.sort(key=lambda r: -r.importance)
         assert [r.place_id for r in results] == [100, 101]
 
         results.sort(key=lambda r: -r.importance)
         assert [r.place_id for r in results] == [100, 101]
 
-
     @pytest.mark.parametrize('radius', [0.09, 0.11])
     def test_force_near(self, apiobj, frontend, radius):
         lookup = FieldLookup('name_vector', [1, 2], LookupAll)
 
     @pytest.mark.parametrize('radius', [0.09, 0.11])
     def test_force_near(self, apiobj, frontend, radius):
         lookup = FieldLookup('name_vector', [1, 2], LookupAll)
 
-        details=SearchDetails.from_kwargs({'near': '5.6,4.3',
-                                           'near_radius': radius})
+        details = SearchDetails.from_kwargs({'near': '5.6,4.3',
+                                             'near_radius': radius})
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [], details=details)
 
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [], details=details)
 
@@ -228,7 +218,7 @@ class TestStreetWithHousenumber:
         apiobj.add_placex(place_id=1000, class_='highway', type='residential',
                           rank_search=26, rank_address=26,
                           country_code='es')
         apiobj.add_placex(place_id=1000, class_='highway', type='residential',
                           rank_search=26, rank_address=26,
                           country_code='es')
-        apiobj.add_search_name(1000, names=[1,2,10,11],
+        apiobj.add_search_name(1000, names=[1, 2, 10, 11],
                                search_rank=26, address_rank=26,
                                country_code='es')
         apiobj.add_placex(place_id=91, class_='place', type='house',
                                search_rank=26, address_rank=26,
                                country_code='es')
         apiobj.add_placex(place_id=91, class_='place', type='house',
@@ -243,26 +233,24 @@ class TestStreetWithHousenumber:
         apiobj.add_placex(place_id=2000, class_='highway', type='residential',
                           rank_search=26, rank_address=26,
                           country_code='pt')
         apiobj.add_placex(place_id=2000, class_='highway', type='residential',
                           rank_search=26, rank_address=26,
                           country_code='pt')
-        apiobj.add_search_name(2000, names=[1,2,20,21],
+        apiobj.add_search_name(2000, names=[1, 2, 20, 21],
                                search_rank=26, address_rank=26,
                                country_code='pt')
 
                                search_rank=26, address_rank=26,
                                country_code='pt')
 
-
     @pytest.mark.parametrize('hnr,res', [('20', [91, 1]), ('20 a', [1]),
                                          ('21', [2]), ('22', [2, 92]),
                                          ('24', [93]), ('25', [])])
     def test_lookup_by_single_housenumber(self, apiobj, frontend, hnr, res):
     @pytest.mark.parametrize('hnr,res', [('20', [91, 1]), ('20 a', [1]),
                                          ('21', [2]), ('22', [2, 92]),
                                          ('24', [93]), ('25', [])])
     def test_lookup_by_single_housenumber(self, apiobj, frontend, hnr, res):
-        lookup = FieldLookup('name_vector', [1,2], LookupAll)
+        lookup = FieldLookup('name_vector', [1, 2], LookupAll)
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking], hnrs=[hnr])
 
         assert [r.place_id for r in results] == res + [1000, 2000]
 
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking], hnrs=[hnr])
 
         assert [r.place_id for r in results] == res + [1000, 2000]
 
-
     @pytest.mark.parametrize('cc,res', [('es', [2, 1000]), ('pt', [92, 2000])])
     def test_lookup_with_country_restriction(self, apiobj, frontend, cc, res):
     @pytest.mark.parametrize('cc,res', [('es', [2, 1000]), ('pt', [92, 2000])])
     def test_lookup_with_country_restriction(self, apiobj, frontend, cc, res):
-        lookup = FieldLookup('name_vector', [1,2], LookupAll)
+        lookup = FieldLookup('name_vector', [1, 2], LookupAll)
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking], hnrs=['22'],
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking], hnrs=['22'],
@@ -270,9 +258,8 @@ class TestStreetWithHousenumber:
 
         assert [r.place_id for r in results] == res
 
 
         assert [r.place_id for r in results] == res
 
-
     def test_lookup_exclude_housenumber_placeid(self, apiobj, frontend):
     def test_lookup_exclude_housenumber_placeid(self, apiobj, frontend):
-        lookup = FieldLookup('name_vector', [1,2], LookupAll)
+        lookup = FieldLookup('name_vector', [1, 2], LookupAll)
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking], hnrs=['22'],
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking], hnrs=['22'],
@@ -280,9 +267,8 @@ class TestStreetWithHousenumber:
 
         assert [r.place_id for r in results] == [2, 1000, 2000]
 
 
         assert [r.place_id for r in results] == [2, 1000, 2000]
 
-
     def test_lookup_exclude_street_placeid(self, apiobj, frontend):
     def test_lookup_exclude_street_placeid(self, apiobj, frontend):
-        lookup = FieldLookup('name_vector', [1,2], LookupAll)
+        lookup = FieldLookup('name_vector', [1, 2], LookupAll)
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking], hnrs=['22'],
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking], hnrs=['22'],
@@ -290,9 +276,8 @@ class TestStreetWithHousenumber:
 
         assert [r.place_id for r in results] == [2, 92, 2000]
 
 
         assert [r.place_id for r in results] == [2, 92, 2000]
 
-
     def test_lookup_only_house_qualifier(self, apiobj, frontend):
     def test_lookup_only_house_qualifier(self, apiobj, frontend):
-        lookup = FieldLookup('name_vector', [1,2], LookupAll)
+        lookup = FieldLookup('name_vector', [1, 2], LookupAll)
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking], hnrs=['22'],
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking], hnrs=['22'],
@@ -300,9 +285,8 @@ class TestStreetWithHousenumber:
 
         assert [r.place_id for r in results] == [2, 92]
 
 
         assert [r.place_id for r in results] == [2, 92]
 
-
     def test_lookup_only_street_qualifier(self, apiobj, frontend):
     def test_lookup_only_street_qualifier(self, apiobj, frontend):
-        lookup = FieldLookup('name_vector', [1,2], LookupAll)
+        lookup = FieldLookup('name_vector', [1, 2], LookupAll)
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking], hnrs=['22'],
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking], hnrs=['22'],
@@ -310,10 +294,9 @@ class TestStreetWithHousenumber:
 
         assert [r.place_id for r in results] == [1000, 2000]
 
 
         assert [r.place_id for r in results] == [1000, 2000]
 
-
     @pytest.mark.parametrize('rank,found', [(26, True), (27, False), (30, False)])
     def test_lookup_min_rank(self, apiobj, frontend, rank, found):
     @pytest.mark.parametrize('rank,found', [(26, True), (27, False), (30, False)])
     def test_lookup_min_rank(self, apiobj, frontend, rank, found):
-        lookup = FieldLookup('name_vector', [1,2], LookupAll)
+        lookup = FieldLookup('name_vector', [1, 2], LookupAll)
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking], hnrs=['22'],
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, [lookup], [ranking], hnrs=['22'],
@@ -321,7 +304,6 @@ class TestStreetWithHousenumber:
 
         assert [r.place_id for r in results] == ([2, 92, 1000, 2000] if found else [2, 92])
 
 
         assert [r.place_id for r in results] == ([2, 92, 1000, 2000] if found else [2, 92])
 
-
     @pytest.mark.parametrize('geom', [napi.GeometryFormat.GEOJSON,
                                       napi.GeometryFormat.KML,
                                       napi.GeometryFormat.SVG,
     @pytest.mark.parametrize('geom', [napi.GeometryFormat.GEOJSON,
                                       napi.GeometryFormat.KML,
                                       napi.GeometryFormat.SVG,
@@ -343,7 +325,7 @@ def test_very_large_housenumber(apiobj, frontend):
     apiobj.add_placex(place_id=2000, class_='highway', type='residential',
                       rank_search=26, rank_address=26,
                       country_code='pt')
     apiobj.add_placex(place_id=2000, class_='highway', type='residential',
                       rank_search=26, rank_address=26,
                       country_code='pt')
-    apiobj.add_search_name(2000, names=[1,2],
+    apiobj.add_search_name(2000, names=[1, 2],
                            search_rank=26, address_rank=26,
                            country_code='pt')
 
                            search_rank=26, address_rank=26,
                            country_code='pt')
 
@@ -405,7 +387,6 @@ class TestInterpolations:
                            centroid=(10.0, 10.00001),
                            geometry='LINESTRING(9.995 10.00001, 10.005 10.00001)')
 
                            centroid=(10.0, 10.00001),
                            geometry='LINESTRING(9.995 10.00001, 10.005 10.00001)')
 
-
     @pytest.mark.parametrize('hnr,res', [('21', [992]), ('22', []), ('23', [991])])
     def test_lookup_housenumber(self, apiobj, frontend, hnr, res):
         lookup = FieldLookup('name_vector', [111], LookupAll)
     @pytest.mark.parametrize('hnr,res', [('21', [992]), ('22', []), ('23', [991])])
     def test_lookup_housenumber(self, apiobj, frontend, hnr, res):
         lookup = FieldLookup('name_vector', [111], LookupAll)
@@ -414,7 +395,6 @@ class TestInterpolations:
 
         assert [r.place_id for r in results] == res + [990]
 
 
         assert [r.place_id for r in results] == res + [990]
 
-
     @pytest.mark.parametrize('geom', [napi.GeometryFormat.GEOJSON,
                                       napi.GeometryFormat.KML,
                                       napi.GeometryFormat.SVG,
     @pytest.mark.parametrize('geom', [napi.GeometryFormat.GEOJSON,
                                       napi.GeometryFormat.KML,
                                       napi.GeometryFormat.SVG,
@@ -429,7 +409,6 @@ class TestInterpolations:
         assert geom.name.lower() in results[0].geometry
 
 
         assert geom.name.lower() in results[0].geometry
 
 
-
 class TestTiger:
 
     @pytest.fixture(autouse=True)
 class TestTiger:
 
     @pytest.fixture(autouse=True)
@@ -453,7 +432,6 @@ class TestTiger:
                          centroid=(10.0, 10.00001),
                          geometry='LINESTRING(9.995 10.00001, 10.005 10.00001)')
 
                          centroid=(10.0, 10.00001),
                          geometry='LINESTRING(9.995 10.00001, 10.005 10.00001)')
 
-
     @pytest.mark.parametrize('hnr,res', [('21', [992]), ('22', []), ('23', [991])])
     def test_lookup_housenumber(self, apiobj, frontend, hnr, res):
         lookup = FieldLookup('name_vector', [111], LookupAll)
     @pytest.mark.parametrize('hnr,res', [('21', [992]), ('22', []), ('23', [991])])
     def test_lookup_housenumber(self, apiobj, frontend, hnr, res):
         lookup = FieldLookup('name_vector', [111], LookupAll)
@@ -462,7 +440,6 @@ class TestTiger:
 
         assert [r.place_id for r in results] == res + [990]
 
 
         assert [r.place_id for r in results] == res + [990]
 
-
     @pytest.mark.parametrize('geom', [napi.GeometryFormat.GEOJSON,
                                       napi.GeometryFormat.KML,
                                       napi.GeometryFormat.SVG,
     @pytest.mark.parametrize('geom', [napi.GeometryFormat.GEOJSON,
                                       napi.GeometryFormat.KML,
                                       napi.GeometryFormat.SVG,
@@ -513,15 +490,15 @@ class TestLayersRank30:
                                importance=0.0005,
                                address_rank=0, search_rank=30)
 
                                importance=0.0005,
                                address_rank=0, search_rank=30)
 
-
-    @pytest.mark.parametrize('layer,res', [(napi.DataLayer.ADDRESS, [223]),
-                                           (napi.DataLayer.POI, [224]),
-                                           (napi.DataLayer.ADDRESS | napi.DataLayer.POI, [223, 224]),
-                                           (napi.DataLayer.MANMADE, [225]),
-                                           (napi.DataLayer.RAILWAY, [226]),
-                                           (napi.DataLayer.NATURAL, [227]),
-                                           (napi.DataLayer.MANMADE | napi.DataLayer.NATURAL, [225, 227]),
-                                           (napi.DataLayer.MANMADE | napi.DataLayer.RAILWAY, [225, 226])])
+    @pytest.mark.parametrize('layer,res',
+                             [(napi.DataLayer.ADDRESS, [223]),
+                              (napi.DataLayer.POI, [224]),
+                              (napi.DataLayer.ADDRESS | napi.DataLayer.POI, [223, 224]),
+                              (napi.DataLayer.MANMADE, [225]),
+                              (napi.DataLayer.RAILWAY, [226]),
+                              (napi.DataLayer.NATURAL, [227]),
+                              (napi.DataLayer.MANMADE | napi.DataLayer.NATURAL, [225, 227]),
+                              (napi.DataLayer.MANMADE | napi.DataLayer.RAILWAY, [225, 226])])
     def test_layers_rank30(self, apiobj, frontend, layer, res):
         lookup = FieldLookup('name_vector', [34], LookupAny)
 
     def test_layers_rank30(self, apiobj, frontend, layer, res):
         lookup = FieldLookup('name_vector', [34], LookupAny)
 
index d4319a57db2a349897da06a8ed63a59eee837ad5..9387385eb6352d9f3ea9e94d34a6a066ce2d2449 100644 (file)
@@ -2,14 +2,13 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for running the POI searcher.
 """
 import pytest
 
 # For a full list of authors see the git log.
 """
 Tests for running the POI searcher.
 """
 import pytest
 
-import nominatim_api as napi
 from nominatim_api.types import SearchDetails
 from nominatim_api.search.db_searches import PoiSearch
 from nominatim_api.search.db_search_fields import WeightedStrings, WeightedCategories
 from nominatim_api.types import SearchDetails
 from nominatim_api.search.db_searches import PoiSearch
 from nominatim_api.search.db_search_fields import WeightedStrings, WeightedCategories
@@ -84,14 +83,12 @@ class TestPoiSearchWithRestrictions:
         else:
             self.args = {'near': '34.3, 56.100021', 'near_radius': 0.001}
 
         else:
             self.args = {'near': '34.3, 56.100021', 'near_radius': 0.001}
 
-
     def test_unrestricted(self, apiobj, frontend):
         results = run_search(apiobj, frontend, 0.1, [('highway', 'bus_stop')], [0.5],
                              details=SearchDetails.from_kwargs(self.args))
 
         assert [r.place_id for r in results] == [1, 2]
 
     def test_unrestricted(self, apiobj, frontend):
         results = run_search(apiobj, frontend, 0.1, [('highway', 'bus_stop')], [0.5],
                              details=SearchDetails.from_kwargs(self.args))
 
         assert [r.place_id for r in results] == [1, 2]
 
-
     def test_restict_country(self, apiobj, frontend):
         results = run_search(apiobj, frontend, 0.1, [('highway', 'bus_stop')], [0.5],
                              ccodes=['de', 'nz'],
     def test_restict_country(self, apiobj, frontend):
         results = run_search(apiobj, frontend, 0.1, [('highway', 'bus_stop')], [0.5],
                              ccodes=['de', 'nz'],
@@ -99,7 +96,6 @@ class TestPoiSearchWithRestrictions:
 
         assert [r.place_id for r in results] == [2]
 
 
         assert [r.place_id for r in results] == [2]
 
-
     def test_restrict_by_viewbox(self, apiobj, frontend):
         args = {'bounded_viewbox': True, 'viewbox': '34.299,56.0,34.3001,56.10001'}
         args.update(self.args)
     def test_restrict_by_viewbox(self, apiobj, frontend):
         args = {'bounded_viewbox': True, 'viewbox': '34.299,56.0,34.3001,56.10001'}
         args.update(self.args)
index 369e15045e0fd4ecf11721e67ee342cb661ddef3..529fb409609a759c9a01c552bbcb285ba882fe38 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for running the postcode searcher.
 # For a full list of authors see the git log.
 """
 Tests for running the postcode searcher.
@@ -15,6 +15,7 @@ from nominatim_api.search.db_searches import PostcodeSearch
 from nominatim_api.search.db_search_fields import WeightedStrings, FieldLookup, \
                                                   FieldRanking, RankedTokens
 
 from nominatim_api.search.db_search_fields import WeightedStrings, FieldLookup, \
                                                   FieldRanking, RankedTokens
 
+
 def run_search(apiobj, frontend, global_penalty, pcs, pc_penalties=None,
                ccodes=[], lookup=[], ranking=[], details=SearchDetails()):
     if pc_penalties is None:
 def run_search(apiobj, frontend, global_penalty, pcs, pc_penalties=None,
                ccodes=[], lookup=[], ranking=[], details=SearchDetails()):
     if pc_penalties is None:
@@ -85,26 +86,24 @@ class TestPostcodeSearchWithAddress:
         apiobj.add_placex(place_id=1000, class_='place', type='village',
                           rank_search=22, rank_address=22,
                           country_code='ch')
         apiobj.add_placex(place_id=1000, class_='place', type='village',
                           rank_search=22, rank_address=22,
                           country_code='ch')
-        apiobj.add_search_name(1000, names=[1,2,10,11],
+        apiobj.add_search_name(1000, names=[1, 2, 10, 11],
                                search_rank=22, address_rank=22,
                                country_code='ch')
         apiobj.add_placex(place_id=2000, class_='place', type='village',
                           rank_search=22, rank_address=22,
                           country_code='pl')
                                search_rank=22, address_rank=22,
                                country_code='ch')
         apiobj.add_placex(place_id=2000, class_='place', type='village',
                           rank_search=22, rank_address=22,
                           country_code='pl')
-        apiobj.add_search_name(2000, names=[1,2,20,21],
+        apiobj.add_search_name(2000, names=[1, 2, 20, 21],
                                search_rank=22, address_rank=22,
                                country_code='pl')
 
                                search_rank=22, address_rank=22,
                                country_code='pl')
 
-
     def test_lookup_both(self, apiobj, frontend):
     def test_lookup_both(self, apiobj, frontend):
-        lookup = FieldLookup('name_vector', [1,2], 'restrict')
+        lookup = FieldLookup('name_vector', [1, 2], 'restrict')
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, ['12345'], lookup=[lookup], ranking=[ranking])
 
         assert [r.place_id for r in results] == [100, 101]
 
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, ['12345'], lookup=[lookup], ranking=[ranking])
 
         assert [r.place_id for r in results] == [100, 101]
 
-
     def test_restrict_by_name(self, apiobj, frontend):
         lookup = FieldLookup('name_vector', [10], 'restrict')
 
     def test_restrict_by_name(self, apiobj, frontend):
         lookup = FieldLookup('name_vector', [10], 'restrict')
 
@@ -112,11 +111,10 @@ class TestPostcodeSearchWithAddress:
 
         assert [r.place_id for r in results] == [100]
 
 
         assert [r.place_id for r in results] == [100]
 
-
     @pytest.mark.parametrize('coord,place_id', [((16.5, 5), 100),
                                                 ((-45.1, 7.004), 101)])
     def test_lookup_near(self, apiobj, frontend, coord, place_id):
     @pytest.mark.parametrize('coord,place_id', [((16.5, 5), 100),
                                                 ((-45.1, 7.004), 101)])
     def test_lookup_near(self, apiobj, frontend, coord, place_id):
-        lookup = FieldLookup('name_vector', [1,2], 'restrict')
+        lookup = FieldLookup('name_vector', [1, 2], 'restrict')
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, ['12345'],
         ranking = FieldRanking('name_vector', 0.3, [RankedTokens(0.0, [10])])
 
         results = run_search(apiobj, frontend, 0.1, ['12345'],
@@ -126,7 +124,6 @@ class TestPostcodeSearchWithAddress:
 
         assert [r.place_id for r in results] == [place_id]
 
 
         assert [r.place_id for r in results] == [place_id]
 
-
     @pytest.mark.parametrize('geom', [napi.GeometryFormat.GEOJSON,
                                       napi.GeometryFormat.KML,
                                       napi.GeometryFormat.SVG,
     @pytest.mark.parametrize('geom', [napi.GeometryFormat.GEOJSON,
                                       napi.GeometryFormat.KML,
                                       napi.GeometryFormat.SVG,
@@ -138,18 +135,16 @@ class TestPostcodeSearchWithAddress:
         assert results
         assert all(geom.name.lower() in r.geometry for r in results)
 
         assert results
         assert all(geom.name.lower() in r.geometry for r in results)
 
-
-    @pytest.mark.parametrize('viewbox, rids', [('-46,6,-44,8', [101,100]),
-                                               ('16,4,18,6', [100,101])])
+    @pytest.mark.parametrize('viewbox, rids', [('-46,6,-44,8', [101, 100]),
+                                               ('16,4,18,6', [100, 101])])
     def test_prefer_viewbox(self, apiobj, frontend, viewbox, rids):
         results = run_search(apiobj, frontend, 0.1, ['12345'],
                              details=SearchDetails.from_kwargs({'viewbox': viewbox}))
 
         assert [r.place_id for r in results] == rids
 
     def test_prefer_viewbox(self, apiobj, frontend, viewbox, rids):
         results = run_search(apiobj, frontend, 0.1, ['12345'],
                              details=SearchDetails.from_kwargs({'viewbox': viewbox}))
 
         assert [r.place_id for r in results] == rids
 
-
     @pytest.mark.parametrize('viewbox, rid', [('-46,6,-44,8', 101),
     @pytest.mark.parametrize('viewbox, rid', [('-46,6,-44,8', 101),
-                                               ('16,4,18,6', 100)])
+                                              ('16,4,18,6', 100)])
     def test_restrict_to_viewbox(self, apiobj, frontend, viewbox, rid):
         results = run_search(apiobj, frontend, 0.1, ['12345'],
                              details=SearchDetails.from_kwargs({'viewbox': viewbox,
     def test_restrict_to_viewbox(self, apiobj, frontend, viewbox, rid):
         results = run_search(apiobj, frontend, 0.1, ['12345'],
                              details=SearchDetails.from_kwargs({'viewbox': viewbox,
@@ -157,7 +152,6 @@ class TestPostcodeSearchWithAddress:
 
         assert [r.place_id for r in results] == [rid]
 
 
         assert [r.place_id for r in results] == [rid]
 
-
     @pytest.mark.parametrize('coord,rids', [((17.05, 5), [100, 101]),
                                             ((-45, 7.1), [101, 100])])
     def test_prefer_near(self, apiobj, frontend, coord, rids):
     @pytest.mark.parametrize('coord,rids', [((17.05, 5), [100, 101]),
                                             ((-45, 7.1), [101, 100])])
     def test_prefer_near(self, apiobj, frontend, coord, rids):
@@ -166,7 +160,6 @@ class TestPostcodeSearchWithAddress:
 
         assert [r.place_id for r in results] == rids
 
 
         assert [r.place_id for r in results] == rids
 
-
     @pytest.mark.parametrize('pid,rid', [(100, 101), (101, 100)])
     def test_exclude(self, apiobj, frontend, pid, rid):
         results = run_search(apiobj, frontend, 0.1, ['12345'],
     @pytest.mark.parametrize('pid,rid', [(100, 101), (101, 100)])
     def test_exclude(self, apiobj, frontend, pid, rid):
         results = run_search(apiobj, frontend, 0.1, ['12345'],
index fff8d471e246c8fdec6c72346a15c47c43d01fce..2ffba335de9e027c829ad84bfff7160267b25102 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Test for creation of token assignments from tokenized queries.
 # For a full list of authors see the git log.
 """
 Test for creation of token assignments from tokenized queries.
@@ -11,7 +11,10 @@ import pytest
 
 from nominatim_api.search.query import QueryStruct, Phrase, TokenRange, Token
 import nominatim_api.search.query as qmod
 
 from nominatim_api.search.query import QueryStruct, Phrase, TokenRange, Token
 import nominatim_api.search.query as qmod
-from nominatim_api.search.token_assignment import yield_token_assignments, TokenAssignment, PENALTY_TOKENCHANGE
+from nominatim_api.search.token_assignment import (yield_token_assignments,
+                                                   TokenAssignment,
+                                                   PENALTY_TOKENCHANGE)
+
 
 class MyToken(Token):
     def get_category(self):
 
 class MyToken(Token):
     def get_category(self):
@@ -102,8 +105,7 @@ def test_multiple_simple_words(btype):
                       TokenAssignment(penalty=penalty, name=TokenRange(1, 3),
                                       address=[TokenRange(0, 1)]),
                       TokenAssignment(penalty=penalty, name=TokenRange(2, 3),
                       TokenAssignment(penalty=penalty, name=TokenRange(1, 3),
                                       address=[TokenRange(0, 1)]),
                       TokenAssignment(penalty=penalty, name=TokenRange(2, 3),
-                                      address=[TokenRange(0, 2)])
-                     )
+                                      address=[TokenRange(0, 2)]))
 
 
 def test_multiple_words_respect_phrase_break():
 
 
 def test_multiple_words_respect_phrase_break():
@@ -156,6 +158,7 @@ def test_housenumber_and_postcode():
                                       address=[TokenRange(0, 1), TokenRange(2, 3)],
                                       postcode=TokenRange(3, 4)))
 
                                       address=[TokenRange(0, 1), TokenRange(2, 3)],
                                       postcode=TokenRange(3, 4)))
 
+
 def test_postcode_and_housenumber():
     q = make_query((qmod.BREAK_START, qmod.PHRASE_ANY, [(1, qmod.TOKEN_PARTIAL)]),
                    (qmod.BREAK_WORD, qmod.PHRASE_ANY, [(2, qmod.TOKEN_POSTCODE)]),
 def test_postcode_and_housenumber():
     q = make_query((qmod.BREAK_START, qmod.PHRASE_ANY, [(1, qmod.TOKEN_PARTIAL)]),
                    (qmod.BREAK_WORD, qmod.PHRASE_ANY, [(2, qmod.TOKEN_POSTCODE)]),
@@ -211,11 +214,11 @@ def test_housenumber_many_phrases():
     check_assignments(yield_token_assignments(q),
                       TokenAssignment(penalty=0.1,
                                       name=TokenRange(4, 5),
     check_assignments(yield_token_assignments(q),
                       TokenAssignment(penalty=0.1,
                                       name=TokenRange(4, 5),
-                                      housenumber=TokenRange(3, 4),\
+                                      housenumber=TokenRange(3, 4),
                                       address=[TokenRange(0, 1), TokenRange(1, 2),
                                                TokenRange(2, 3)]),
                       TokenAssignment(penalty=0.1,
                                       address=[TokenRange(0, 1), TokenRange(1, 2),
                                                TokenRange(2, 3)]),
                       TokenAssignment(penalty=0.1,
-                                      housenumber=TokenRange(3, 4),\
+                                      housenumber=TokenRange(3, 4),
                                       address=[TokenRange(0, 1), TokenRange(1, 2),
                                                TokenRange(2, 3), TokenRange(4, 5)]))
 
                                       address=[TokenRange(0, 1), TokenRange(1, 2),
                                                TokenRange(2, 3), TokenRange(4, 5)]))
 
@@ -299,7 +302,6 @@ def test_qualifier_at_beginning():
                    (qmod.BREAK_WORD, qmod.PHRASE_ANY, [(2, qmod.TOKEN_PARTIAL)]),
                    (qmod.BREAK_WORD, qmod.PHRASE_ANY, [(3, qmod.TOKEN_PARTIAL)]))
 
                    (qmod.BREAK_WORD, qmod.PHRASE_ANY, [(2, qmod.TOKEN_PARTIAL)]),
                    (qmod.BREAK_WORD, qmod.PHRASE_ANY, [(3, qmod.TOKEN_PARTIAL)]))
 
-
     check_assignments(yield_token_assignments(q),
                       TokenAssignment(penalty=0.1, name=TokenRange(1, 3),
                                       qualifier=TokenRange(0, 1)),
     check_assignments(yield_token_assignments(q),
                       TokenAssignment(penalty=0.1, name=TokenRange(1, 3),
                                       qualifier=TokenRange(0, 1)),
@@ -315,7 +317,6 @@ def test_qualifier_after_name():
                    (qmod.BREAK_WORD, qmod.PHRASE_ANY, [(4, qmod.TOKEN_PARTIAL)]),
                    (qmod.BREAK_WORD, qmod.PHRASE_ANY, [(5, qmod.TOKEN_PARTIAL)]))
 
                    (qmod.BREAK_WORD, qmod.PHRASE_ANY, [(4, qmod.TOKEN_PARTIAL)]),
                    (qmod.BREAK_WORD, qmod.PHRASE_ANY, [(5, qmod.TOKEN_PARTIAL)]))
 
-
     check_assignments(yield_token_assignments(q),
                       TokenAssignment(penalty=0.2, name=TokenRange(0, 2),
                                       qualifier=TokenRange(2, 3),
     check_assignments(yield_token_assignments(q),
                       TokenAssignment(penalty=0.2, name=TokenRange(0, 2),
                                       qualifier=TokenRange(2, 3),
@@ -349,4 +350,3 @@ def test_qualifier_in_middle_of_phrase():
                    (qmod.BREAK_PHRASE, qmod.PHRASE_ANY, [(5, qmod.TOKEN_PARTIAL)]))
 
     check_assignments(yield_token_assignments(q))
                    (qmod.BREAK_PHRASE, qmod.PHRASE_ANY, [(5, qmod.TOKEN_PARTIAL)]))
 
     check_assignments(yield_token_assignments(q))
-
index f62b0d9e346c8357fe9ff5690741bdada8114935..9b29411a027a51bb8267440610c1e24b76d5fae3 100644 (file)
@@ -2,12 +2,11 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for enhanced connection class for API functions.
 """
 # For a full list of authors see the git log.
 """
 Tests for enhanced connection class for API functions.
 """
-from pathlib import Path
 import pytest
 
 import sqlalchemy as sa
 import pytest
 
 import sqlalchemy as sa
@@ -76,7 +75,7 @@ async def test_get_db_property_existing(api):
 
 
 @pytest.mark.asyncio
 
 
 @pytest.mark.asyncio
-async def test_get_db_property_existing(api):
+async def test_get_db_property_bad_name(api):
     async with api.begin() as conn:
         with pytest.raises(ValueError):
             await conn.get_db_property('dfkgjd.rijg')
     async with api.begin() as conn:
         with pytest.raises(ValueError):
             await conn.get_db_property('dfkgjd.rijg')
index 9e1138869e8d632b322dce7d7306c7f9cd920f26..8ea4c9cd165949f6cca3146407254a5c93cc7978 100644 (file)
@@ -2,20 +2,20 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for the deletable v1 API call.
 """
 import json
 # For a full list of authors see the git log.
 """
 Tests for the deletable v1 API call.
 """
 import json
-from pathlib import Path
 
 import pytest
 
 
 import pytest
 
-from fake_adaptor import FakeAdaptor, FakeError, FakeResponse
+from fake_adaptor import FakeAdaptor
 
 import nominatim_api.v1.server_glue as glue
 
 
 import nominatim_api.v1.server_glue as glue
 
+
 class TestDeletableEndPoint:
 
     @pytest.fixture(autouse=True)
 class TestDeletableEndPoint:
 
     @pytest.fixture(autouse=True)
@@ -25,14 +25,13 @@ class TestDeletableEndPoint:
                       content=[(345, 'N', 'boundary', 'administrative'),
                                (781, 'R', 'landuse', 'wood'),
                                (781, 'R', 'landcover', 'grass')])
                       content=[(345, 'N', 'boundary', 'administrative'),
                                (781, 'R', 'landuse', 'wood'),
                                (781, 'R', 'landcover', 'grass')])
-        table_factory('placex',
-                      definition="""place_id bigint, osm_id bigint, osm_type char(1),
-                                    class text, type text, name HSTORE, country_code char(2)""",
-                      content=[(1, 345, 'N', 'boundary', 'administrative', {'old_name': 'Former'}, 'ab'),
-                               (2, 781, 'R', 'landuse', 'wood', {'name': 'Wood'}, 'cd'),
-                               (3, 781, 'R', 'landcover', 'grass', None, 'cd')])
-
-
+        table_factory(
+            'placex',
+            definition="""place_id bigint, osm_id bigint, osm_type char(1),
+                          class text, type text, name HSTORE, country_code char(2)""",
+            content=[(1, 345, 'N', 'boundary', 'administrative', {'old_name': 'Former'}, 'ab'),
+                     (2, 781, 'R', 'landuse', 'wood', {'name': 'Wood'}, 'cd'),
+                     (3, 781, 'R', 'landcover', 'grass', None, 'cd')])
 
     @pytest.mark.asyncio
     async def test_deletable(self, api):
 
     @pytest.mark.asyncio
     async def test_deletable(self, api):
index 7f405728b284536ce6d221c857b0bbc27c46bed0..4f6dd92b06a2c2354ed2c8dcc40b881ff45b08ef 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for details API call.
 # For a full list of authors see the git log.
 """
 Tests for details API call.
@@ -13,23 +13,24 @@ import pytest
 
 import nominatim_api as napi
 
 
 import nominatim_api as napi
 
+
 @pytest.mark.parametrize('idobj', (napi.PlaceID(332), napi.OsmID('W', 4),
                                    napi.OsmID('W', 4, 'highway')))
 def test_lookup_in_placex(apiobj, frontend, idobj):
     import_date = dt.datetime(2022, 12, 7, 14, 14, 46, 0)
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 @pytest.mark.parametrize('idobj', (napi.PlaceID(332), napi.OsmID('W', 4),
                                    napi.OsmID('W', 4, 'highway')))
 def test_lookup_in_placex(apiobj, frontend, idobj):
     import_date = dt.datetime(2022, 12, 7, 14, 14, 46, 0)
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
-                     class_='highway', type='residential',
-                     name={'name': 'Road'}, address={'city': 'Barrow'},
-                     extratags={'surface': 'paved'},
-                     parent_place_id=34, linked_place_id=55,
-                     admin_level=15, country_code='gb',
-                     housenumber='4',
-                     postcode='34425', wikipedia='en:Faa',
-                     rank_search=27, rank_address=26,
-                     importance=0.01,
-                     centroid=(23, 34),
-                     indexed_date=import_date,
-                     geometry='LINESTRING(23 34, 23.1 34, 23.1 34.1, 23 34)')
+                      class_='highway', type='residential',
+                      name={'name': 'Road'}, address={'city': 'Barrow'},
+                      extratags={'surface': 'paved'},
+                      parent_place_id=34, linked_place_id=55,
+                      admin_level=15, country_code='gb',
+                      housenumber='4',
+                      postcode='34425', wikipedia='en:Faa',
+                      rank_search=27, rank_address=26,
+                      importance=0.01,
+                      centroid=(23, 34),
+                      indexed_date=import_date,
+                      geometry='LINESTRING(23 34, 23.1 34, 23.1 34.1, 23 34)')
 
     api = frontend(apiobj, options={'details'})
     result = api.details(idobj)
 
     api = frontend(apiobj, options={'details'})
     result = api.details(idobj)
@@ -73,12 +74,12 @@ def test_lookup_in_placex(apiobj, frontend, idobj):
 def test_lookup_in_placex_minimal_info(apiobj, frontend):
     import_date = dt.datetime(2022, 12, 7, 14, 14, 46, 0)
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 def test_lookup_in_placex_minimal_info(apiobj, frontend):
     import_date = dt.datetime(2022, 12, 7, 14, 14, 46, 0)
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
-                     class_='highway', type='residential',
-                     admin_level=15,
-                     rank_search=27, rank_address=26,
-                     centroid=(23, 34),
-                     indexed_date=import_date,
-                     geometry='LINESTRING(23 34, 23.1 34, 23.1 34.1, 23 34)')
+                      class_='highway', type='residential',
+                      admin_level=15,
+                      rank_search=27, rank_address=26,
+                      centroid=(23, 34),
+                      indexed_date=import_date,
+                      geometry='LINESTRING(23 34, 23.1 34, 23.1 34.1, 23 34)')
 
     api = frontend(apiobj, options={'details'})
     result = api.details(napi.PlaceID(332))
 
     api = frontend(apiobj, options={'details'})
     result = api.details(napi.PlaceID(332))
@@ -131,9 +132,9 @@ def test_lookup_in_placex_with_geometry(apiobj, frontend):
 
 def test_lookup_placex_with_address_details(apiobj, frontend):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 def test_lookup_placex_with_address_details(apiobj, frontend):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
-                     class_='highway', type='residential',  name='Street',
-                     country_code='pl',
-                     rank_search=27, rank_address=26)
+                      class_='highway', type='residential',  name='Street',
+                      country_code='pl',
+                      rank_search=27, rank_address=26)
     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
                               distance=0.0034,
                               place_id=1000, osm_type='N', osm_id=3333,
     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
                               distance=0.0034,
                               place_id=1000, osm_type='N', osm_id=3333,
@@ -178,9 +179,9 @@ def test_lookup_placex_with_address_details(apiobj, frontend):
 
 def test_lookup_place_with_linked_places_none_existing(apiobj, frontend):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 def test_lookup_place_with_linked_places_none_existing(apiobj, frontend):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
-                     class_='highway', type='residential',  name='Street',
-                     country_code='pl', linked_place_id=45,
-                     rank_search=27, rank_address=26)
+                      class_='highway', type='residential',  name='Street',
+                      country_code='pl', linked_place_id=45,
+                      rank_search=27, rank_address=26)
 
     api = frontend(apiobj, options={'details'})
     result = api.details(napi.PlaceID(332), linked_places=True)
 
     api = frontend(apiobj, options={'details'})
     result = api.details(napi.PlaceID(332), linked_places=True)
@@ -190,17 +191,17 @@ def test_lookup_place_with_linked_places_none_existing(apiobj, frontend):
 
 def test_lookup_place_with_linked_places_existing(apiobj, frontend):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 def test_lookup_place_with_linked_places_existing(apiobj, frontend):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
-                     class_='highway', type='residential',  name='Street',
-                     country_code='pl', linked_place_id=45,
-                     rank_search=27, rank_address=26)
+                      class_='highway', type='residential',  name='Street',
+                      country_code='pl', linked_place_id=45,
+                      rank_search=27, rank_address=26)
     apiobj.add_placex(place_id=1001, osm_type='W', osm_id=5,
     apiobj.add_placex(place_id=1001, osm_type='W', osm_id=5,
-                     class_='highway', type='residential',  name='Street',
-                     country_code='pl', linked_place_id=332,
-                     rank_search=27, rank_address=26)
+                      class_='highway', type='residential',  name='Street',
+                      country_code='pl', linked_place_id=332,
+                      rank_search=27, rank_address=26)
     apiobj.add_placex(place_id=1002, osm_type='W', osm_id=6,
     apiobj.add_placex(place_id=1002, osm_type='W', osm_id=6,
-                     class_='highway', type='residential',  name='Street',
-                     country_code='pl', linked_place_id=332,
-                     rank_search=27, rank_address=26)
+                      class_='highway', type='residential',  name='Street',
+                      country_code='pl', linked_place_id=332,
+                      rank_search=27, rank_address=26)
 
     api = frontend(apiobj, options={'details'})
     result = api.details(napi.PlaceID(332), linked_places=True)
 
     api = frontend(apiobj, options={'details'})
     result = api.details(napi.PlaceID(332), linked_places=True)
@@ -221,9 +222,9 @@ def test_lookup_place_with_linked_places_existing(apiobj, frontend):
 
 def test_lookup_place_with_parented_places_not_existing(apiobj, frontend):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 def test_lookup_place_with_parented_places_not_existing(apiobj, frontend):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
-                     class_='highway', type='residential',  name='Street',
-                     country_code='pl', parent_place_id=45,
-                     rank_search=27, rank_address=26)
+                      class_='highway', type='residential',  name='Street',
+                      country_code='pl', parent_place_id=45,
+                      rank_search=27, rank_address=26)
 
     api = frontend(apiobj, options={'details'})
     result = api.details(napi.PlaceID(332), parented_places=True)
 
     api = frontend(apiobj, options={'details'})
     result = api.details(napi.PlaceID(332), parented_places=True)
@@ -233,17 +234,17 @@ def test_lookup_place_with_parented_places_not_existing(apiobj, frontend):
 
 def test_lookup_place_with_parented_places_existing(apiobj, frontend):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 def test_lookup_place_with_parented_places_existing(apiobj, frontend):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
-                     class_='highway', type='residential',  name='Street',
-                     country_code='pl', parent_place_id=45,
-                     rank_search=27, rank_address=26)
+                      class_='highway', type='residential',  name='Street',
+                      country_code='pl', parent_place_id=45,
+                      rank_search=27, rank_address=26)
     apiobj.add_placex(place_id=1001, osm_type='N', osm_id=5,
     apiobj.add_placex(place_id=1001, osm_type='N', osm_id=5,
-                     class_='place', type='house', housenumber='23',
-                     country_code='pl', parent_place_id=332,
-                     rank_search=30, rank_address=30)
+                      class_='place', type='house', housenumber='23',
+                      country_code='pl', parent_place_id=332,
+                      rank_search=30, rank_address=30)
     apiobj.add_placex(place_id=1002, osm_type='W', osm_id=6,
     apiobj.add_placex(place_id=1002, osm_type='W', osm_id=6,
-                     class_='highway', type='residential',  name='Street',
-                     country_code='pl', parent_place_id=332,
-                     rank_search=27, rank_address=26)
+                      class_='highway', type='residential',  name='Street',
+                      country_code='pl', parent_place_id=332,
+                      rank_search=27, rank_address=26)
 
     api = frontend(apiobj, options={'details'})
     result = api.details(napi.PlaceID(332), parented_places=True)
 
     api = frontend(apiobj, options={'details'})
     result = api.details(napi.PlaceID(332), parented_places=True)
@@ -332,9 +333,9 @@ def test_lookup_osmline_with_address_details(apiobj, frontend):
                        startnumber=2, endnumber=4, step=1,
                        parent_place_id=332)
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
                        startnumber=2, endnumber=4, step=1,
                        parent_place_id=332)
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
-                     class_='highway', type='residential',  name='Street',
-                     country_code='pl',
-                     rank_search=27, rank_address=26)
+                      class_='highway', type='residential',  name='Street',
+                      country_code='pl',
+                      rank_search=27, rank_address=26)
     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
                               distance=0.0034,
                               place_id=1000, osm_type='N', osm_id=3333,
     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
                               distance=0.0034,
                               place_id=1000, osm_type='N', osm_id=3333,
@@ -432,9 +433,9 @@ def test_lookup_tiger_with_address_details(apiobj, frontend):
                      startnumber=2, endnumber=4, step=1,
                      parent_place_id=332)
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
                      startnumber=2, endnumber=4, step=1,
                      parent_place_id=332)
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
-                     class_='highway', type='residential',  name='Street',
-                     country_code='us',
-                     rank_search=27, rank_address=26)
+                      class_='highway', type='residential',  name='Street',
+                      country_code='us',
+                      rank_search=27, rank_address=26)
     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
                               distance=0.0034,
                               place_id=1000, osm_type='N', osm_id=3333,
     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
                               distance=0.0034,
                               place_id=1000, osm_type='N', osm_id=3333,
@@ -571,6 +572,7 @@ def test_lookup_postcode_with_address_details(apiobj, frontend):
                                 rank_address=4, distance=0.0)
            ]
 
                                 rank_address=4, distance=0.0)
            ]
 
+
 @pytest.mark.parametrize('objid', [napi.PlaceID(1736),
                                    napi.OsmID('W', 55),
                                    napi.OsmID('N', 55, 'amenity')])
 @pytest.mark.parametrize('objid', [napi.PlaceID(1736),
                                    napi.OsmID('W', 55),
                                    napi.OsmID('N', 55, 'amenity')])
@@ -583,8 +585,8 @@ def test_lookup_missing_object(apiobj, frontend, objid):
 
 
 @pytest.mark.parametrize('gtype', (napi.GeometryFormat.KML,
 
 
 @pytest.mark.parametrize('gtype', (napi.GeometryFormat.KML,
-                                    napi.GeometryFormat.SVG,
-                                    napi.GeometryFormat.TEXT))
+                                   napi.GeometryFormat.SVG,
+                                   napi.GeometryFormat.TEXT))
 def test_lookup_unsupported_geometry(apiobj, frontend, gtype):
     apiobj.add_placex(place_id=332)
 
 def test_lookup_unsupported_geometry(apiobj, frontend, gtype):
     apiobj.add_placex(place_id=332)
 
index 4281cd6c924cfa2dd0b75de50439ace9a8a32190..a2660f51c1a5cb4598b6ec69001f8a2ef2910414 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for lookup API call.
 # For a full list of authors see the git log.
 """
 Tests for lookup API call.
@@ -13,6 +13,7 @@ import pytest
 
 import nominatim_api as napi
 
 
 import nominatim_api as napi
 
+
 def test_lookup_empty_list(apiobj, frontend):
     api = frontend(apiobj, options={'details'})
     assert api.lookup([]) == []
 def test_lookup_empty_list(apiobj, frontend):
     api = frontend(apiobj, options={'details'})
     assert api.lookup([]) == []
@@ -28,17 +29,17 @@ def test_lookup_non_existing(apiobj, frontend):
                                    napi.OsmID('W', 4, 'highway')))
 def test_lookup_single_placex(apiobj, frontend, idobj):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
                                    napi.OsmID('W', 4, 'highway')))
 def test_lookup_single_placex(apiobj, frontend, idobj):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
-                     class_='highway', type='residential',
-                     name={'name': 'Road'}, address={'city': 'Barrow'},
-                     extratags={'surface': 'paved'},
-                     parent_place_id=34, linked_place_id=55,
-                     admin_level=15, country_code='gb',
-                     housenumber='4',
-                     postcode='34425', wikipedia='en:Faa',
-                     rank_search=27, rank_address=26,
-                     importance=0.01,
-                     centroid=(23, 34),
-                     geometry='LINESTRING(23 34, 23.1 34, 23.1 34.1, 23 34)')
+                      class_='highway', type='residential',
+                      name={'name': 'Road'}, address={'city': 'Barrow'},
+                      extratags={'surface': 'paved'},
+                      parent_place_id=34, linked_place_id=55,
+                      admin_level=15, country_code='gb',
+                      housenumber='4',
+                      postcode='34425', wikipedia='en:Faa',
+                      rank_search=27, rank_address=26,
+                      importance=0.01,
+                      centroid=(23, 34),
+                      geometry='LINESTRING(23 34, 23.1 34, 23.1 34.1, 23 34)')
 
     api = frontend(apiobj, options={'details'})
     result = api.lookup([idobj])
 
     api = frontend(apiobj, options={'details'})
     result = api.lookup([idobj])
@@ -79,17 +80,17 @@ def test_lookup_single_placex(apiobj, frontend, idobj):
 
 def test_lookup_multiple_places(apiobj, frontend):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 def test_lookup_multiple_places(apiobj, frontend):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
-                     class_='highway', type='residential',
-                     name={'name': 'Road'}, address={'city': 'Barrow'},
-                     extratags={'surface': 'paved'},
-                     parent_place_id=34, linked_place_id=55,
-                     admin_level=15, country_code='gb',
-                     housenumber='4',
-                     postcode='34425', wikipedia='en:Faa',
-                     rank_search=27, rank_address=26,
-                     importance=0.01,
-                     centroid=(23, 34),
-                     geometry='LINESTRING(23 34, 23.1 34, 23.1 34.1, 23 34)')
+                      class_='highway', type='residential',
+                      name={'name': 'Road'}, address={'city': 'Barrow'},
+                      extratags={'surface': 'paved'},
+                      parent_place_id=34, linked_place_id=55,
+                      admin_level=15, country_code='gb',
+                      housenumber='4',
+                      postcode='34425', wikipedia='en:Faa',
+                      rank_search=27, rank_address=26,
+                      importance=0.01,
+                      centroid=(23, 34),
+                      geometry='LINESTRING(23 34, 23.1 34, 23.1 34.1, 23 34)')
     apiobj.add_osmline(place_id=4924, osm_id=9928,
                        parent_place_id=12,
                        startnumber=1, endnumber=4, step=1,
     apiobj.add_osmline(place_id=4924, osm_id=9928,
                        parent_place_id=12,
                        startnumber=1, endnumber=4, step=1,
@@ -97,7 +98,6 @@ def test_lookup_multiple_places(apiobj, frontend):
                        address={'city': 'Big'},
                        geometry='LINESTRING(23 34, 23 35)')
 
                        address={'city': 'Big'},
                        geometry='LINESTRING(23 34, 23 35)')
 
-
     api = frontend(apiobj, options={'details'})
     result = api.lookup((napi.OsmID('W', 1),
                          napi.OsmID('W', 4),
     api = frontend(apiobj, options={'details'})
     result = api.lookup((napi.OsmID('W', 1),
                          napi.OsmID('W', 4),
@@ -111,17 +111,17 @@ def test_lookup_multiple_places(apiobj, frontend):
 @pytest.mark.parametrize('gtype', list(napi.GeometryFormat))
 def test_simple_place_with_geometry(apiobj, frontend, gtype):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 @pytest.mark.parametrize('gtype', list(napi.GeometryFormat))
 def test_simple_place_with_geometry(apiobj, frontend, gtype):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
-                     class_='highway', type='residential',
-                     name={'name': 'Road'}, address={'city': 'Barrow'},
-                     extratags={'surface': 'paved'},
-                     parent_place_id=34, linked_place_id=55,
-                     admin_level=15, country_code='gb',
-                     housenumber='4',
-                     postcode='34425', wikipedia='en:Faa',
-                     rank_search=27, rank_address=26,
-                     importance=0.01,
-                     centroid=(23, 34),
-                     geometry='POLYGON((23 34, 23.1 34, 23.1 34.1, 23 34))')
+                      class_='highway', type='residential',
+                      name={'name': 'Road'}, address={'city': 'Barrow'},
+                      extratags={'surface': 'paved'},
+                      parent_place_id=34, linked_place_id=55,
+                      admin_level=15, country_code='gb',
+                      housenumber='4',
+                      postcode='34425', wikipedia='en:Faa',
+                      rank_search=27, rank_address=26,
+                      importance=0.01,
+                      centroid=(23, 34),
+                      geometry='POLYGON((23 34, 23.1 34, 23.1 34.1, 23 34))')
 
     api = frontend(apiobj, options={'details'})
     result = api.lookup([napi.OsmID('W', 4)], geometry_output=gtype)
 
     api = frontend(apiobj, options={'details'})
     result = api.lookup([napi.OsmID('W', 4)], geometry_output=gtype)
@@ -137,17 +137,17 @@ def test_simple_place_with_geometry(apiobj, frontend, gtype):
 
 def test_simple_place_with_geometry_simplified(apiobj, frontend):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 
 def test_simple_place_with_geometry_simplified(apiobj, frontend):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
-                     class_='highway', type='residential',
-                     name={'name': 'Road'}, address={'city': 'Barrow'},
-                     extratags={'surface': 'paved'},
-                     parent_place_id=34, linked_place_id=55,
-                     admin_level=15, country_code='gb',
-                     housenumber='4',
-                     postcode='34425', wikipedia='en:Faa',
-                     rank_search=27, rank_address=26,
-                     importance=0.01,
-                     centroid=(23, 34),
-                     geometry='POLYGON((23 34, 22.999 34, 23.1 34, 23.1 34.1, 23 34))')
+                      class_='highway', type='residential',
+                      name={'name': 'Road'}, address={'city': 'Barrow'},
+                      extratags={'surface': 'paved'},
+                      parent_place_id=34, linked_place_id=55,
+                      admin_level=15, country_code='gb',
+                      housenumber='4',
+                      postcode='34425', wikipedia='en:Faa',
+                      rank_search=27, rank_address=26,
+                      importance=0.01,
+                      centroid=(23, 34),
+                      geometry='POLYGON((23 34, 22.999 34, 23.1 34, 23.1 34.1, 23 34))')
 
     api = frontend(apiobj, options={'details'})
     result = api.lookup([napi.OsmID('W', 4)],
 
     api = frontend(apiobj, options={'details'})
     result = api.lookup([napi.OsmID('W', 4)],
@@ -159,5 +159,5 @@ def test_simple_place_with_geometry_simplified(apiobj, frontend):
 
     geom = json.loads(result[0].geometry['geojson'])
 
 
     geom = json.loads(result[0].geometry['geojson'])
 
-    assert geom['type']  == 'Polygon'
+    assert geom['type'] == 'Polygon'
     assert geom['coordinates'] == [[[23, 34], [23.1, 34], [23.1, 34.1], [23, 34]]]
     assert geom['coordinates'] == [[[23, 34], [23.1, 34], [23.1, 34.1], [23, 34]]]
index ac2b4cb9fc09cc2e8662bb2d44a856fde6d0c33b..e4700a95e6599160a06408aa6cd23bbaddb19681 100644 (file)
@@ -2,21 +2,21 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for the deletable v1 API call.
 """
 import json
 import datetime as dt
 # For a full list of authors see the git log.
 """
 Tests for the deletable v1 API call.
 """
 import json
 import datetime as dt
-from pathlib import Path
 
 import pytest
 
 
 import pytest
 
-from fake_adaptor import FakeAdaptor, FakeError, FakeResponse
+from fake_adaptor import FakeAdaptor
 
 import nominatim_api.v1.server_glue as glue
 
 
 import nominatim_api.v1.server_glue as glue
 
+
 class TestPolygonsEndPoint:
 
     @pytest.fixture(autouse=True)
 class TestPolygonsEndPoint:
 
     @pytest.fixture(autouse=True)
@@ -35,13 +35,12 @@ class TestPolygonsEndPoint:
                                     errormessage text,
                                     prevgeometry geometry(Geometry,4326),
                                     newgeometry geometry(Geometry,4326)""",
                                     errormessage text,
                                     prevgeometry geometry(Geometry,4326),
                                     newgeometry geometry(Geometry,4326)""",
-                    content=[(345, 'N', 'boundary', 'administrative',
-                              {'name': 'Foo'}, 'xx', self.recent,
-                              'some text', None, None),
-                             (781, 'R', 'landuse', 'wood',
-                              None, 'ds', self.now,
-                              'Area reduced by lots', None, None)])
-
+                      content=[(345, 'N', 'boundary', 'administrative',
+                               {'name': 'Foo'}, 'xx', self.recent,
+                               'some text', None, None),
+                               (781, 'R', 'landuse', 'wood',
+                                None, 'ds', self.now,
+                                'Area reduced by lots', None, None)])
 
     @pytest.mark.asyncio
     async def test_polygons_simple(self, api):
 
     @pytest.mark.asyncio
     async def test_polygons_simple(self, api):
@@ -63,7 +62,6 @@ class TestPolygonsEndPoint:
                             'errormessage': 'Area reduced by lots',
                             'updated': self.now.isoformat(sep=' ', timespec='seconds')}]
 
                             'errormessage': 'Area reduced by lots',
                             'updated': self.now.isoformat(sep=' ', timespec='seconds')}]
 
-
     @pytest.mark.asyncio
     async def test_polygons_days(self, api):
         a = FakeAdaptor()
     @pytest.mark.asyncio
     async def test_polygons_days(self, api):
         a = FakeAdaptor()
@@ -74,7 +72,6 @@ class TestPolygonsEndPoint:
 
         assert [r['osm_id'] for r in results] == [781]
 
 
         assert [r['osm_id'] for r in results] == [781]
 
-
     @pytest.mark.asyncio
     async def test_polygons_class(self, api):
         a = FakeAdaptor()
     @pytest.mark.asyncio
     async def test_polygons_class(self, api):
         a = FakeAdaptor()
@@ -85,8 +82,6 @@ class TestPolygonsEndPoint:
 
         assert [r['osm_id'] for r in results] == [781]
 
 
         assert [r['osm_id'] for r in results] == [781]
 
-
-
     @pytest.mark.asyncio
     async def test_polygons_reduced(self, api):
         a = FakeAdaptor()
     @pytest.mark.asyncio
     async def test_polygons_reduced(self, api):
         a = FakeAdaptor()
index ff7f402b72f000d9364d716752b992a5e7514b3d..91074ecb3ef8e7ccdd8b1288f4d027a60bc25775 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for reverse API call.
 # For a full list of authors see the git log.
 """
 Tests for reverse API call.
@@ -18,6 +18,7 @@ import nominatim_api as napi
 
 API_OPTIONS = {'reverse'}
 
 
 API_OPTIONS = {'reverse'}
 
+
 def test_reverse_rank_30(apiobj, frontend):
     apiobj.add_placex(place_id=223, class_='place', type='house',
                       housenumber='1',
 def test_reverse_rank_30(apiobj, frontend):
     apiobj.add_placex(place_id=223, class_='place', type='house',
                       housenumber='1',
@@ -35,7 +36,7 @@ def test_reverse_rank_30(apiobj, frontend):
 def test_reverse_street(apiobj, frontend, country):
     apiobj.add_placex(place_id=990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
 def test_reverse_street(apiobj, frontend, country):
     apiobj.add_placex(place_id=990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
-                      name = {'name': 'My Street'},
+                      name={'name': 'My Street'},
                       centroid=(10.0, 10.0),
                       country_code=country,
                       geometry='LINESTRING(9.995 10, 10.005 10)')
                       centroid=(10.0, 10.0),
                       country_code=country,
                       geometry='LINESTRING(9.995 10, 10.005 10)')
@@ -57,16 +58,17 @@ def test_reverse_ignore_unindexed(apiobj, frontend):
     assert result is None
 
 
     assert result is None
 
 
-@pytest.mark.parametrize('y,layer,place_id', [(0.7, napi.DataLayer.ADDRESS, 223),
-                                              (0.70001, napi.DataLayer.POI, 224),
-                                              (0.7, napi.DataLayer.ADDRESS | napi.DataLayer.POI, 224),
-                                              (0.70001, napi.DataLayer.ADDRESS | napi.DataLayer.POI, 223),
-                                              (0.7, napi.DataLayer.MANMADE, 225),
-                                              (0.7, napi.DataLayer.RAILWAY, 226),
-                                              (0.7, napi.DataLayer.NATURAL, 227),
-                                              (0.70003, napi.DataLayer.MANMADE | napi.DataLayer.RAILWAY, 225),
-                                              (0.70003, napi.DataLayer.MANMADE | napi.DataLayer.NATURAL, 225),
-                                              (5, napi.DataLayer.ADDRESS, 229)])
+@pytest.mark.parametrize('y,layer,place_id',
+                         [(0.7, napi.DataLayer.ADDRESS, 223),
+                          (0.70001, napi.DataLayer.POI, 224),
+                          (0.7, napi.DataLayer.ADDRESS | napi.DataLayer.POI, 224),
+                          (0.70001, napi.DataLayer.ADDRESS | napi.DataLayer.POI, 223),
+                          (0.7, napi.DataLayer.MANMADE, 225),
+                          (0.7, napi.DataLayer.RAILWAY, 226),
+                          (0.7, napi.DataLayer.NATURAL, 227),
+                          (0.70003, napi.DataLayer.MANMADE | napi.DataLayer.RAILWAY, 225),
+                          (0.70003, napi.DataLayer.MANMADE | napi.DataLayer.NATURAL, 225),
+                          (5, napi.DataLayer.ADDRESS, 229)])
 def test_reverse_rank_30_layers(apiobj, frontend, y, layer, place_id):
     apiobj.add_placex(place_id=223, osm_type='N', class_='place', type='house',
                       housenumber='1',
 def test_reverse_rank_30_layers(apiobj, frontend, y, layer, place_id):
     apiobj.add_placex(place_id=223, osm_type='N', class_='place', type='house',
                       housenumber='1',
@@ -108,14 +110,14 @@ def test_reverse_poi_layer_with_no_pois(apiobj, frontend):
 
     api = frontend(apiobj, options=API_OPTIONS)
     assert api.reverse((1.3, 0.70001), max_rank=29,
 
     api = frontend(apiobj, options=API_OPTIONS)
     assert api.reverse((1.3, 0.70001), max_rank=29,
-                              layers=napi.DataLayer.POI) is None
+                       layers=napi.DataLayer.POI) is None
 
 
 @pytest.mark.parametrize('with_geom', [True, False])
 def test_reverse_housenumber_on_street(apiobj, frontend, with_geom):
     apiobj.add_placex(place_id=990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
 
 
 @pytest.mark.parametrize('with_geom', [True, False])
 def test_reverse_housenumber_on_street(apiobj, frontend, with_geom):
     apiobj.add_placex(place_id=990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
-                      name = {'name': 'My Street'},
+                      name={'name': 'My Street'},
                       centroid=(10.0, 10.0),
                       geometry='LINESTRING(9.995 10, 10.005 10)')
     apiobj.add_placex(place_id=991, class_='place', type='house',
                       centroid=(10.0, 10.0),
                       geometry='LINESTRING(9.995 10, 10.005 10)')
     apiobj.add_placex(place_id=991, class_='place', type='house',
@@ -125,7 +127,7 @@ def test_reverse_housenumber_on_street(apiobj, frontend, with_geom):
                       centroid=(10.0, 10.00001))
     apiobj.add_placex(place_id=1990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
                       centroid=(10.0, 10.00001))
     apiobj.add_placex(place_id=1990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
-                      name = {'name': 'Other Street'},
+                      name={'name': 'Other Street'},
                       centroid=(10.0, 1.0),
                       geometry='LINESTRING(9.995 1, 10.005 1)')
     apiobj.add_placex(place_id=1991, class_='place', type='house',
                       centroid=(10.0, 1.0),
                       geometry='LINESTRING(9.995 1, 10.005 1)')
     apiobj.add_placex(place_id=1991, class_='place', type='house',
@@ -147,7 +149,7 @@ def test_reverse_housenumber_on_street(apiobj, frontend, with_geom):
 def test_reverse_housenumber_interpolation(apiobj, frontend, with_geom):
     apiobj.add_placex(place_id=990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
 def test_reverse_housenumber_interpolation(apiobj, frontend, with_geom):
     apiobj.add_placex(place_id=990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
-                      name = {'name': 'My Street'},
+                      name={'name': 'My Street'},
                       centroid=(10.0, 10.0),
                       geometry='LINESTRING(9.995 10, 10.005 10)')
     apiobj.add_placex(place_id=991, class_='place', type='house',
                       centroid=(10.0, 10.0),
                       geometry='LINESTRING(9.995 10, 10.005 10)')
     apiobj.add_placex(place_id=991, class_='place', type='house',
@@ -162,7 +164,7 @@ def test_reverse_housenumber_interpolation(apiobj, frontend, with_geom):
                        geometry='LINESTRING(9.995 10.00001, 10.005 10.00001)')
     apiobj.add_placex(place_id=1990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
                        geometry='LINESTRING(9.995 10.00001, 10.005 10.00001)')
     apiobj.add_placex(place_id=1990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
-                      name = {'name': 'Other Street'},
+                      name={'name': 'Other Street'},
                       centroid=(10.0, 20.0),
                       geometry='LINESTRING(9.995 20, 10.005 20)')
     apiobj.add_osmline(place_id=1992,
                       centroid=(10.0, 20.0),
                       geometry='LINESTRING(9.995 20, 10.005 20)')
     apiobj.add_osmline(place_id=1992,
@@ -181,7 +183,7 @@ def test_reverse_housenumber_interpolation(apiobj, frontend, with_geom):
 def test_reverse_housenumber_point_interpolation(apiobj, frontend):
     apiobj.add_placex(place_id=990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
 def test_reverse_housenumber_point_interpolation(apiobj, frontend):
     apiobj.add_placex(place_id=990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
-                      name = {'name': 'My Street'},
+                      name={'name': 'My Street'},
                       centroid=(10.0, 10.0),
                       geometry='LINESTRING(9.995 10, 10.005 10)')
     apiobj.add_osmline(place_id=992,
                       centroid=(10.0, 10.0),
                       geometry='LINESTRING(9.995 10, 10.005 10)')
     apiobj.add_osmline(place_id=992,
@@ -199,7 +201,7 @@ def test_reverse_housenumber_point_interpolation(apiobj, frontend):
 def test_reverse_tiger_number(apiobj, frontend):
     apiobj.add_placex(place_id=990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
 def test_reverse_tiger_number(apiobj, frontend):
     apiobj.add_placex(place_id=990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
-                      name = {'name': 'My Street'},
+                      name={'name': 'My Street'},
                       centroid=(10.0, 10.0),
                       country_code='us',
                       geometry='LINESTRING(9.995 10, 10.005 10)')
                       centroid=(10.0, 10.0),
                       country_code='us',
                       geometry='LINESTRING(9.995 10, 10.005 10)')
@@ -217,7 +219,7 @@ def test_reverse_tiger_number(apiobj, frontend):
 def test_reverse_point_tiger(apiobj, frontend):
     apiobj.add_placex(place_id=990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
 def test_reverse_point_tiger(apiobj, frontend):
     apiobj.add_placex(place_id=990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
-                      name = {'name': 'My Street'},
+                      name={'name': 'My Street'},
                       centroid=(10.0, 10.0),
                       country_code='us',
                       geometry='LINESTRING(9.995 10, 10.005 10)')
                       centroid=(10.0, 10.0),
                       country_code='us',
                       geometry='LINESTRING(9.995 10, 10.005 10)')
@@ -393,14 +395,15 @@ def test_reverse_interpolation_geometry(apiobj, frontend):
                        geometry='LINESTRING(9.995 10.00001, 10.005 10.00001)')
 
     api = frontend(apiobj, options=API_OPTIONS)
                        geometry='LINESTRING(9.995 10.00001, 10.005 10.00001)')
 
     api = frontend(apiobj, options=API_OPTIONS)
-    assert api.reverse((10.0, 10.0), geometry_output=napi.GeometryFormat.TEXT)\
-                     .geometry['text'] == 'POINT(10 10.00001)'
+    result = api.reverse((10.0, 10.0), geometry_output=napi.GeometryFormat.TEXT)
+
+    assert result.geometry['text'] == 'POINT(10 10.00001)'
 
 
 def test_reverse_tiger_geometry(apiobj, frontend):
     apiobj.add_placex(place_id=990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
 
 
 def test_reverse_tiger_geometry(apiobj, frontend):
     apiobj.add_placex(place_id=990, class_='highway', type='service',
                       rank_search=27, rank_address=27,
-                      name = {'name': 'My Street'},
+                      name={'name': 'My Street'},
                       centroid=(10.0, 10.0),
                       country_code='us',
                       geometry='LINESTRING(9.995 10, 10.005 10)')
                       centroid=(10.0, 10.0),
                       country_code='us',
                       geometry='LINESTRING(9.995 10, 10.005 10)')
@@ -411,7 +414,7 @@ def test_reverse_tiger_geometry(apiobj, frontend):
                      geometry='LINESTRING(9.995 10.00001, 10.005 10.00001)')
     apiobj.add_placex(place_id=1000, class_='highway', type='service',
                       rank_search=27, rank_address=27,
                      geometry='LINESTRING(9.995 10.00001, 10.005 10.00001)')
     apiobj.add_placex(place_id=1000, class_='highway', type='service',
                       rank_search=27, rank_address=27,
-                      name = {'name': 'My Street'},
+                      name={'name': 'My Street'},
                       centroid=(11.0, 11.0),
                       country_code='us',
                       geometry='LINESTRING(10.995 11, 11.005 11)')
                       centroid=(11.0, 11.0),
                       country_code='us',
                       geometry='LINESTRING(10.995 11, 11.005 11)')
@@ -426,8 +429,9 @@ def test_reverse_tiger_geometry(apiobj, frontend):
     params = {'geometry_output': napi.GeometryFormat.GEOJSON}
 
     output = api.reverse((10.0, 10.0), **params)
     params = {'geometry_output': napi.GeometryFormat.GEOJSON}
 
     output = api.reverse((10.0, 10.0), **params)
-    assert json.loads(output.geometry['geojson']) == {'coordinates': [10, 10.00001], 'type': 'Point'}
+    assert json.loads(output.geometry['geojson']) \
+        == {'coordinates': [10, 10.00001], 'type': 'Point'}
 
     output = api.reverse((11.0, 11.0), **params)
 
     output = api.reverse((11.0, 11.0), **params)
-    assert json.loads(output.geometry['geojson']) == {'coordinates': [11, 11.00001], 'type': 'Point'}
-
+    assert json.loads(output.geometry['geojson']) \
+        == {'coordinates': [11, 11.00001], 'type': 'Point'}
index 54138e24442056a4dab6027d95bcacb834101414..59a83aa99b69f362ee2ab8681ef89ea8d10db3dc 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for search API calls.
 # For a full list of authors see the git log.
 """
 Tests for search API calls.
@@ -10,17 +10,13 @@ Tests for search API calls.
 These tests make sure that all Python code is correct and executable.
 Functional tests can be found in the BDD test suite.
 """
 These tests make sure that all Python code is correct and executable.
 Functional tests can be found in the BDD test suite.
 """
-import json
-
 import pytest
 
 import pytest
 
-import sqlalchemy as sa
-
-import nominatim_api as napi
 import nominatim_api.logging as loglib
 
 API_OPTIONS = {'search'}
 
 import nominatim_api.logging as loglib
 
 API_OPTIONS = {'search'}
 
+
 @pytest.fixture(autouse=True)
 def setup_icu_tokenizer(apiobj):
     """ Setup the properties needed for using the ICU tokenizer.
 @pytest.fixture(autouse=True)
 def setup_icu_tokenizer(apiobj):
     """ Setup the properties needed for using the ICU tokenizer.
@@ -28,8 +24,9 @@ def setup_icu_tokenizer(apiobj):
     apiobj.add_data('properties',
                     [{'property': 'tokenizer', 'value': 'icu'},
                      {'property': 'tokenizer_import_normalisation', 'value': ':: lower();'},
     apiobj.add_data('properties',
                     [{'property': 'tokenizer', 'value': 'icu'},
                      {'property': 'tokenizer_import_normalisation', 'value': ':: lower();'},
-                     {'property': 'tokenizer_import_transliteration', 'value': "'1' > '/1/'; 'ä' > 'ä '"},
-                    ])
+                     {'property': 'tokenizer_import_transliteration',
+                      'value': "'1' > '/1/'; 'ä' > 'ä '"},
+                     ])
 
 
 def test_search_no_content(apiobj, frontend):
 
 
 def test_search_no_content(apiobj, frontend):
@@ -64,7 +61,7 @@ def test_search_with_debug(apiobj, frontend, logtype):
 
     api = frontend(apiobj, options=API_OPTIONS)
     loglib.set_log_output(logtype)
 
     api = frontend(apiobj, options=API_OPTIONS)
     loglib.set_log_output(logtype)
-    results = api.search('TEST')
+    api.search('TEST')
 
     assert loglib.get_and_disable()
 
 
     assert loglib.get_and_disable()
 
index 9341b52774f5cfe5c0170dff72e743e1a4be1685..a80c8710bb5bd34aeae38e8b402d91ac42384408 100644 (file)
@@ -2,18 +2,17 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for the status API call.
 """
 import datetime as dt
 # For a full list of authors see the git log.
 """
 Tests for the status API call.
 """
 import datetime as dt
-import pytest
 
 
-from nominatim_db.version import NominatimVersion
 from nominatim_api.version import NOMINATIM_API_VERSION
 import nominatim_api as napi
 
 from nominatim_api.version import NOMINATIM_API_VERSION
 import nominatim_api as napi
 
+
 def test_status_no_extra_info(apiobj, frontend):
     api = frontend(apiobj)
     result = api.status()
 def test_status_no_extra_info(apiobj, frontend):
     api = frontend(apiobj)
     result = api.status()
index fbb9b682f499943c503041c61c1ff4d82bddabe2..898b884da6ba57653f133c281b9e16612aff82b0 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for loading of parameter dataclasses.
 # For a full list of authors see the git log.
 """
 Tests for loading of parameter dataclasses.
@@ -12,6 +12,7 @@ import pytest
 from nominatim_api.errors import UsageError
 import nominatim_api.types as typ
 
 from nominatim_api.errors import UsageError
 import nominatim_api.types as typ
 
+
 def test_no_params_defaults():
     params = typ.LookupDetails.from_kwargs({})
 
 def test_no_params_defaults():
     params = typ.LookupDetails.from_kwargs({})
 
@@ -24,7 +25,7 @@ def test_no_params_defaults():
                                  ('geometry_simplification', 'NaN')])
 def test_bad_format_reverse(k, v):
     with pytest.raises(UsageError):
                                  ('geometry_simplification', 'NaN')])
 def test_bad_format_reverse(k, v):
     with pytest.raises(UsageError):
-        params = typ.ReverseDetails.from_kwargs({k: v})
+        typ.ReverseDetails.from_kwargs({k: v})
 
 
 @pytest.mark.parametrize('rin,rout', [(-23, 0), (0, 0), (1, 1),
 
 
 @pytest.mark.parametrize('rin,rout', [(-23, 0), (0, 0), (1, 1),
index b0da52ce0504704e7cb76c9736310381e390f56c..c94cb7fb57624b82ceeb4e07ad9929d3848544fd 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for export CLI function.
 # For a full list of authors see the git log.
 """
 Tests for export CLI function.
@@ -11,12 +11,13 @@ import pytest
 
 import nominatim_db.cli
 
 
 import nominatim_db.cli
 
+
 @pytest.fixture
 def run_export(tmp_path, capsys):
     def _exec(args):
 @pytest.fixture
 def run_export(tmp_path, capsys):
     def _exec(args):
+        cli_args = ['export', '--project-dir', str(tmp_path)] + args
         assert 0 == nominatim_db.cli.nominatim(osm2pgsql_path='OSM2PGSQL NOT AVAILABLE',
         assert 0 == nominatim_db.cli.nominatim(osm2pgsql_path='OSM2PGSQL NOT AVAILABLE',
-                                               cli_args=['export', '--project-dir', str(tmp_path)]
-                                                        + args)
+                                               cli_args=cli_args)
         return capsys.readouterr().out.split('\r\n')
 
     return _exec
         return capsys.readouterr().out.split('\r\n')
 
     return _exec
@@ -25,9 +26,9 @@ def run_export(tmp_path, capsys):
 @pytest.fixture(autouse=True)
 def setup_database_with_context(apiobj):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
 @pytest.fixture(autouse=True)
 def setup_database_with_context(apiobj):
     apiobj.add_placex(place_id=332, osm_type='W', osm_id=4,
-                     class_='highway', type='residential',  name='Street',
-                     country_code='pl', postcode='55674',
-                     rank_search=27, rank_address=26)
+                      class_='highway', type='residential',  name='Street',
+                      country_code='pl', postcode='55674',
+                      rank_search=27, rank_address=26)
     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
                               distance=0.0034,
                               place_id=1000, osm_type='N', osm_id=3333,
     apiobj.add_address_placex(332, fromarea=False, isaddress=False,
                               distance=0.0034,
                               place_id=1000, osm_type='N', osm_id=3333,
index 3a6a9a0b05c4798c6eb4e3b498972e75b4847ad4..10f0921b884058dbeffaca1ee67dddd24bc4bb8b 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for the helper functions for v1 API.
 # For a full list of authors see the git log.
 """
 Tests for the helper functions for v1 API.
@@ -11,6 +11,7 @@ import pytest
 
 import nominatim_api.v1.helpers as helper
 
 
 import nominatim_api.v1.helpers as helper
 
+
 @pytest.mark.parametrize('inp', ['',
                                  'abc',
                                  '12 23',
 @pytest.mark.parametrize('inp', ['',
                                  'abc',
                                  '12 23',
@@ -35,40 +36,42 @@ def test_extract_coords_with_text_before():
 def test_extract_coords_with_text_after():
     assert ('abc', 12.456, -78.90) == helper.extract_coords_from_query('-78.90, 12.456   abc')
 
 def test_extract_coords_with_text_after():
     assert ('abc', 12.456, -78.90) == helper.extract_coords_from_query('-78.90, 12.456   abc')
 
+
 @pytest.mark.parametrize('inp', [' [12.456,-78.90] ', ' 12.456,-78.90 '])
 def test_extract_coords_with_spaces(inp):
     assert ('', -78.90, 12.456) == helper.extract_coords_from_query(inp)
 
 @pytest.mark.parametrize('inp', [' [12.456,-78.90] ', ' 12.456,-78.90 '])
 def test_extract_coords_with_spaces(inp):
     assert ('', -78.90, 12.456) == helper.extract_coords_from_query(inp)
 
+
 @pytest.mark.parametrize('inp', ['40 26.767 N 79 58.933 W',
 @pytest.mark.parametrize('inp', ['40 26.767 N 79 58.933 W',
-                     '40° 26.767′ N 79° 58.933′ W',
-                     "40° 26.767' N 79° 58.933' W",
-                     "40° 26.767'\n"
-                     "    N 79° 58.933' W",
-                     'N 40 26.767, W 79 58.933',
-                     'N 40°26.767′, W 79°58.933′',
-                     ' N 40°26.767′, W 79°58.933′',
-                     "N 40°26.767', W 79°58.933'",
-                     '40 26 46 N 79 58 56 W',
-                     '40° 26′ 46″ N 79° 58′ 56″ W',
-                     '40° 26′ 46.00″ N 79° 58′ 56.00″ W',
-                     '40°26′46″N 79°58′56″W',
-                     'N 40 26 46 W 79 58 56',
-                     'N 40° 26′ 46″, W 79° 58′ 56″',
-                     'N 40° 26\' 46", W 79° 58\' 56"',
-                     'N 40° 26\' 46", W 79° 58\' 56"',
-                     '40.446 -79.982',
-                     '40.446,-79.982',
-                     '40.446° N 79.982° W',
-                     'N 40.446° W 79.982°',
-                     '[40.446 -79.982]',
-                     '[40.446,\v-79.982]',
-                     '       40.446  ,   -79.982     ',
-                     '       40.446  ,   -79.982     ',
-                     '       40.446    ,   -79.982     ',
-                     '       40.446\v,   -79.982        '])
+                                 '40° 26.767′ N 79° 58.933′ W',
+                                 "40° 26.767' N 79° 58.933' W",
+                                 "40° 26.767'\n"
+                                 "    N 79° 58.933' W",
+                                 'N 40 26.767, W 79 58.933',
+                                 'N 40°26.767′, W 79°58.933′',
+                                 '     N 40°26.767′, W 79°58.933′',
+                                 "N 40°26.767', W 79°58.933'",
+
+                                 '40 26 46 N 79 58 56 W',
+                                 '40° 26′ 46″ N 79° 58′ 56″ W',
+                                 '40° 26′ 46.00″ N 79° 58′ 56.00″ W',
+                                 '40°26′46″N 79°58′56″W',
+                                 'N 40 26 46 W 79 58 56',
+                                 'N 40° 26′ 46″, W 79° 58′ 56″',
+                                 'N 40° 26\' 46", W 79° 58\' 56"',
+                                 'N 40° 26\' 46", W 79° 58\' 56"',
+
+                                 '40.446 -79.982',
+                                 '40.446,-79.982',
+                                 '40.446° N 79.982° W',
+                                 'N 40.446° W 79.982°',
+
+                                 '[40.446 -79.982]',
+                                 '[40.446,\v-79.982]',
+                                 '       40.446  ,   -79.982     ',
+                                 '       40.446  ,   -79.982     ',
+                                 '       40.446        ,   -79.982     ',
+                                 '       40.446\v,   -79.982    '])
 def test_extract_coords_formats(inp):
     query, x, y = helper.extract_coords_from_query(inp)
 
 def test_extract_coords_formats(inp):
     query, x, y = helper.extract_coords_from_query(inp)
 
@@ -108,9 +111,11 @@ def test_extract_category_good(inp):
     assert cls == 'shop'
     assert typ == 'fish'
 
     assert cls == 'shop'
     assert typ == 'fish'
 
+
 def test_extract_category_only():
     assert helper.extract_category_from_query('[shop=market]') == ('', 'shop', 'market')
 
 def test_extract_category_only():
     assert helper.extract_category_from_query('[shop=market]') == ('', 'shop', 'market')
 
+
 @pytest.mark.parametrize('inp', ['house []', 'nothing', '[352]'])
 @pytest.mark.parametrize('inp', ['house []', 'nothing', '[352]'])
-def  test_extract_category_no_match(inp):
+def test_extract_category_no_match(inp):
     assert helper.extract_category_from_query(inp) == (inp, None, None)
     assert helper.extract_category_from_query(inp) == (inp, None, None)
index 21fa72c81c9af0cb7326460be11f6461f3722d7c..0a30cdc110b1eac1d1ec825952c6982380162f64 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Test functions for adapting results to the user's locale.
 # For a full list of authors see the git log.
 """
 Test functions for adapting results to the user's locale.
@@ -11,34 +11,36 @@ import pytest
 
 from nominatim_api import Locales
 
 
 from nominatim_api import Locales
 
+
 def test_display_name_empty_names():
 def test_display_name_empty_names():
-    l = Locales(['en', 'de'])
+    loc = Locales(['en', 'de'])
+
+    assert loc.display_name(None) == ''
+    assert loc.display_name({}) == ''
 
 
-    assert l.display_name(None) == ''
-    assert l.display_name({}) == ''
 
 def test_display_name_none_localized():
 
 def test_display_name_none_localized():
-    l = Locales()
+    loc = Locales()
 
 
-    assert l.display_name({}) == ''
-    assert l.display_name({'name:de': 'DE', 'name': 'ALL'}) == 'ALL'
-    assert l.display_name({'ref': '34', 'name:de': 'DE'}) == '34'
+    assert loc.display_name({}) == ''
+    assert loc.display_name({'name:de': 'DE', 'name': 'ALL'}) == 'ALL'
+    assert loc.display_name({'ref': '34', 'name:de': 'DE'}) == '34'
 
 
 def test_display_name_localized():
 
 
 def test_display_name_localized():
-    l = Locales(['en', 'de'])
+    loc = Locales(['en', 'de'])
 
 
-    assert l.display_name({}) == ''
-    assert l.display_name({'name:de': 'DE', 'name': 'ALL'}) == 'DE'
-    assert l.display_name({'ref': '34', 'name:de': 'DE'}) == 'DE'
+    assert loc.display_name({}) == ''
+    assert loc.display_name({'name:de': 'DE', 'name': 'ALL'}) == 'DE'
+    assert loc.display_name({'ref': '34', 'name:de': 'DE'}) == 'DE'
 
 
 def test_display_name_preference():
 
 
 def test_display_name_preference():
-    l = Locales(['en', 'de'])
+    loc = Locales(['en', 'de'])
 
 
-    assert l.display_name({}) == ''
-    assert l.display_name({'name:de': 'DE', 'name:en': 'EN'}) == 'EN'
-    assert l.display_name({'official_name:en': 'EN', 'name:de': 'DE'}) == 'DE'
+    assert loc.display_name({}) == ''
+    assert loc.display_name({'name:de': 'DE', 'name:en': 'EN'}) == 'EN'
+    assert loc.display_name({'official_name:en': 'EN', 'name:de': 'DE'}) == 'DE'
 
 
 @pytest.mark.parametrize('langstr,langlist',
 
 
 @pytest.mark.parametrize('langstr,langlist',
index aaecab4539995121c0b5204b8eec1b6acb22dfec..406c76548e584b1e7ebe95a000947cdec763d293 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for formatting results for the V1 API.
 # For a full list of authors see the git log.
 """
 Tests for formatting results for the V1 API.
@@ -22,6 +22,7 @@ STATUS_FORMATS = {'text', 'json'}
 
 # StatusResult
 
 
 # StatusResult
 
+
 def test_status_format_list():
     assert set(v1_format.list_formats(napi.StatusResult)) == STATUS_FORMATS
 
 def test_status_format_list():
     assert set(v1_format.list_formats(napi.StatusResult)) == STATUS_FORMATS
 
@@ -36,11 +37,13 @@ def test_status_unsupported():
 
 
 def test_status_format_text():
 
 
 def test_status_format_text():
-    assert v1_format.format_result(napi.StatusResult(0, 'message here'), 'text', {}) == 'OK'
+    assert v1_format.format_result(napi.StatusResult(0, 'message here'), 'text', {}) \
+        == 'OK'
 
 
 
 
-def test_status_format_text():
-    assert v1_format.format_result(napi.StatusResult(500, 'message here'), 'text', {}) == 'ERROR: message here'
+def test_status_format_error_text():
+    assert v1_format.format_result(napi.StatusResult(500, 'message here'), 'text', {}) \
+        == 'ERROR: message here'
 
 
 def test_status_format_json_minimal():
 
 
 def test_status_format_json_minimal():
@@ -48,8 +51,9 @@ def test_status_format_json_minimal():
 
     result = v1_format.format_result(status, 'json', {})
 
 
     result = v1_format.format_result(status, 'json', {})
 
-    assert result == \
-           f'{{"status":700,"message":"Bad format.","software_version":"{napi.__version__}"}}'
+    assert json.loads(result) == {'status': 700,
+                                  'message': 'Bad format.',
+                                  'software_version': napi.__version__}
 
 
 def test_status_format_json_full():
 
 
 def test_status_format_json_full():
@@ -59,8 +63,11 @@ def test_status_format_json_full():
 
     result = v1_format.format_result(status, 'json', {})
 
 
     result = v1_format.format_result(status, 'json', {})
 
-    assert result == \
-           f'{{"status":0,"message":"OK","data_updated":"2010-02-07T20:20:03+00:00","software_version":"{napi.__version__}","database_version":"5.6"}}'
+    assert json.loads(result) == {'status': 0,
+                                  'message': 'OK',
+                                  'data_updated': '2010-02-07T20:20:03+00:00',
+                                  'software_version': napi.__version__,
+                                  'database_version': '5.6'}
 
 
 # DetailedResult
 
 
 # DetailedResult
@@ -86,7 +93,7 @@ def test_search_details_minimal():
             'extratags': {},
             'centroid': {'type': 'Point', 'coordinates': [1.0, 2.0]},
             'geometry': {'type': 'Point', 'coordinates': [1.0, 2.0]},
             'extratags': {},
             'centroid': {'type': 'Point', 'coordinates': [1.0, 2.0]},
             'geometry': {'type': 'Point', 'coordinates': [1.0, 2.0]},
-           }
+            }
 
 
 def test_search_details_full():
 
 
 def test_search_details_full():
@@ -110,7 +117,7 @@ def test_search_details_full():
                   rank_search=28,
                   importance=0.0443,
                   country_code='ll',
                   rank_search=28,
                   importance=0.0443,
                   country_code='ll',
-                  indexed_date = import_date
+                  indexed_date=import_date
                   )
     search.localize(napi.Locales())
 
                   )
     search.localize(napi.Locales())
 
@@ -140,7 +147,7 @@ def test_search_details_full():
             'isarea': False,
             'centroid': {'type': 'Point', 'coordinates': [56.947, -87.44]},
             'geometry': {'type': 'Point', 'coordinates': [56.947, -87.44]},
             'isarea': False,
             'centroid': {'type': 'Point', 'coordinates': [56.947, -87.44]},
             'geometry': {'type': 'Point', 'coordinates': [56.947, -87.44]},
-           }
+            }
 
 
 @pytest.mark.parametrize('gtype,isarea', [('ST_Point', False),
 
 
 @pytest.mark.parametrize('gtype,isarea', [('ST_Point', False),
@@ -149,9 +156,9 @@ def test_search_details_full():
                                           ('ST_MultiPolygon', True)])
 def test_search_details_no_geometry(gtype, isarea):
     search = napi.DetailedResult(napi.SourceTable.PLACEX,
                                           ('ST_MultiPolygon', True)])
 def test_search_details_no_geometry(gtype, isarea):
     search = napi.DetailedResult(napi.SourceTable.PLACEX,
-                               ('place', 'thing'),
-                               napi.Point(1.0, 2.0),
-                               geometry={'type': gtype})
+                                 ('place', 'thing'),
+                                 napi.Point(1.0, 2.0),
+                                 geometry={'type': gtype})
 
     result = v1_format.format_result(search, 'json', {})
     js = json.loads(result)
 
     result = v1_format.format_result(search, 'json', {})
     js = json.loads(result)
@@ -161,16 +168,17 @@ def test_search_details_no_geometry(gtype, isarea):
 
 
 def test_search_details_with_geometry():
 
 
 def test_search_details_with_geometry():
-    search = napi.DetailedResult(napi.SourceTable.PLACEX,
-                                 ('place', 'thing'),
-                                 napi.Point(1.0, 2.0),
-                                 geometry={'geojson': '{"type":"Point","coordinates":[56.947,-87.44]}'})
+    search = napi.DetailedResult(
+        napi.SourceTable.PLACEX,
+        ('place', 'thing'),
+        napi.Point(1.0, 2.0),
+        geometry={'geojson': '{"type":"Point","coordinates":[56.947,-87.44]}'})
 
     result = v1_format.format_result(search, 'json', {})
     js = json.loads(result)
 
     assert js['geometry'] == {'type': 'Point', 'coordinates': [56.947, -87.44]}
 
     result = v1_format.format_result(search, 'json', {})
     js = json.loads(result)
 
     assert js['geometry'] == {'type': 'Point', 'coordinates': [56.947, -87.44]}
-    assert js['isarea'] == False
+    assert js['isarea'] is False
 
 
 def test_search_details_with_icon_available():
 
 
 def test_search_details_with_icon_available():
@@ -226,7 +234,7 @@ def test_search_details_with_address_minimal():
 @pytest.mark.parametrize('field,outfield', [('address_rows', 'address'),
                                             ('linked_rows', 'linked_places'),
                                             ('parented_rows', 'hierarchy')
 @pytest.mark.parametrize('field,outfield', [('address_rows', 'address'),
                                             ('linked_rows', 'linked_places'),
                                             ('parented_rows', 'hierarchy')
-                                           ])
+                                            ])
 def test_search_details_with_further_infos(field, outfield):
     search = napi.DetailedResult(napi.SourceTable.PLACEX,
                                  ('place', 'thing'),
 def test_search_details_with_further_infos(field, outfield):
     search = napi.DetailedResult(napi.SourceTable.PLACEX,
                                  ('place', 'thing'),
@@ -249,50 +257,49 @@ def test_search_details_with_further_infos(field, outfield):
     js = json.loads(result)
 
     assert js[outfield] == [{'localname': 'Trespass',
     js = json.loads(result)
 
     assert js[outfield] == [{'localname': 'Trespass',
-                              'place_id': 3498,
-                              'osm_id': 442,
-                              'osm_type': 'R',
-                              'place_type': 'spec',
-                              'class': 'bnd',
-                              'type': 'note',
-                              'admin_level': 4,
-                              'rank_address': 10,
-                              'distance': 0.034,
-                              'isaddress': True}]
+                             'place_id': 3498,
+                             'osm_id': 442,
+                             'osm_type': 'R',
+                             'place_type': 'spec',
+                             'class': 'bnd',
+                             'type': 'note',
+                             'admin_level': 4,
+                             'rank_address': 10,
+                             'distance': 0.034,
+                             'isaddress': True}]
 
 
 def test_search_details_grouped_hierarchy():
     search = napi.DetailedResult(napi.SourceTable.PLACEX,
                                  ('place', 'thing'),
                                  napi.Point(1.0, 2.0),
 
 
 def test_search_details_grouped_hierarchy():
     search = napi.DetailedResult(napi.SourceTable.PLACEX,
                                  ('place', 'thing'),
                                  napi.Point(1.0, 2.0),
-                                 parented_rows =
-                                     [napi.AddressLine(place_id=3498,
-                                             osm_object=('R', 442),
-                                             category=('bnd', 'note'),
-                                             names={'name': 'Trespass'},
-                                             extratags={'access': 'no',
-                                                        'place_type': 'spec'},
-                                             admin_level=4,
-                                             fromarea=True,
-                                             isaddress=True,
-                                             rank_address=10,
-                                             distance=0.034)
-                                     ])
+                                 parented_rows=[napi.AddressLine(
+                                    place_id=3498,
+                                    osm_object=('R', 442),
+                                    category=('bnd', 'note'),
+                                    names={'name': 'Trespass'},
+                                    extratags={'access': 'no',
+                                               'place_type': 'spec'},
+                                    admin_level=4,
+                                    fromarea=True,
+                                    isaddress=True,
+                                    rank_address=10,
+                                    distance=0.034)])
 
     result = v1_format.format_result(search, 'json', {'group_hierarchy': True})
     js = json.loads(result)
 
     assert js['hierarchy'] == {'note': [{'localname': 'Trespass',
 
     result = v1_format.format_result(search, 'json', {'group_hierarchy': True})
     js = json.loads(result)
 
     assert js['hierarchy'] == {'note': [{'localname': 'Trespass',
-                              'place_id': 3498,
-                              'osm_id': 442,
-                              'osm_type': 'R',
-                              'place_type': 'spec',
-                              'class': 'bnd',
-                              'type': 'note',
-                              'admin_level': 4,
-                              'rank_address': 10,
-                              'distance': 0.034,
-                              'isaddress': True}]}
+                                         'place_id': 3498,
+                                         'osm_id': 442,
+                                         'osm_type': 'R',
+                                         'place_type': 'spec',
+                                         'class': 'bnd',
+                                         'type': 'note',
+                                         'admin_level': 4,
+                                         'rank_address': 10,
+                                         'distance': 0.034,
+                                         'isaddress': True}]}
 
 
 def test_search_details_keywords_name():
 
 
 def test_search_details_keywords_name():
@@ -307,7 +314,7 @@ def test_search_details_keywords_name():
     js = json.loads(result)
 
     assert js['keywords'] == {'name': [{'id': 23, 'token': 'foo'},
     js = json.loads(result)
 
     assert js['keywords'] == {'name': [{'id': 23, 'token': 'foo'},
-                                      {'id': 24, 'token': 'foo'}],
+                                       {'id': 24, 'token': 'foo'}],
                               'address': []}
 
 
                               'address': []}
 
 
@@ -323,6 +330,5 @@ def test_search_details_keywords_address():
     js = json.loads(result)
 
     assert js['keywords'] == {'address': [{'id': 23, 'token': 'foo'},
     js = json.loads(result)
 
     assert js['keywords'] == {'address': [{'id': 23, 'token': 'foo'},
-                                      {'id': 24, 'token': 'foo'}],
+                                          {'id': 24, 'token': 'foo'}],
                               'name': []}
                               'name': []}
-
index 2c036a65ba254d9058961a78eb0cfb7f827a45f7..902f0e7939393b13434800a8106a8f3f2e9a1e4c 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for formatting reverse results for the V1 API.
 # For a full list of authors see the git log.
 """
 Tests for formatting reverse results for the V1 API.
@@ -20,6 +20,7 @@ import nominatim_api as napi
 
 FORMATS = ['json', 'jsonv2', 'geojson', 'geocodejson', 'xml']
 
 
 FORMATS = ['json', 'jsonv2', 'geojson', 'geocodejson', 'xml']
 
+
 @pytest.mark.parametrize('fmt', FORMATS)
 def test_format_reverse_minimal(fmt):
     reverse = napi.ReverseResult(napi.SourceTable.PLACEX,
 @pytest.mark.parametrize('fmt', FORMATS)
 def test_format_reverse_minimal(fmt):
     reverse = napi.ReverseResult(napi.SourceTable.PLACEX,
@@ -104,8 +105,7 @@ def test_format_reverse_with_address(fmt):
     reverse.localize(napi.Locales())
 
     raw = v1_format.format_result(napi.ReverseResults([reverse]), fmt,
     reverse.localize(napi.Locales())
 
     raw = v1_format.format_result(napi.ReverseResults([reverse]), fmt,
-                                 {'addressdetails': True})
-
+                                  {'addressdetails': True})
 
     if fmt == 'xml':
         root = ET.fromstring(raw)
 
     if fmt == 'xml':
         root = ET.fromstring(raw)
@@ -168,7 +168,7 @@ def test_format_reverse_geocodejson_special_parts():
     reverse.localize(napi.Locales())
 
     raw = v1_format.format_result(napi.ReverseResults([reverse]), 'geocodejson',
     reverse.localize(napi.Locales())
 
     raw = v1_format.format_result(napi.ReverseResults([reverse]), 'geocodejson',
-                                 {'addressdetails': True})
+                                  {'addressdetails': True})
 
     props = json.loads(raw)['features'][0]['properties']['geocoding']
     assert props['housenumber'] == '1'
 
     props = json.loads(raw)['features'][0]['properties']['geocoding']
     assert props['housenumber'] == '1'
@@ -184,8 +184,7 @@ def test_format_reverse_with_address_none(fmt):
                                  address_rows=napi.AddressLines())
 
     raw = v1_format.format_result(napi.ReverseResults([reverse]), fmt,
                                  address_rows=napi.AddressLines())
 
     raw = v1_format.format_result(napi.ReverseResults([reverse]), fmt,
-                                 {'addressdetails': True})
-
+                                  {'addressdetails': True})
 
     if fmt == 'xml':
         root = ET.fromstring(raw)
 
     if fmt == 'xml':
         root = ET.fromstring(raw)
@@ -211,10 +210,10 @@ def test_format_reverse_with_extratags(fmt):
     reverse = napi.ReverseResult(napi.SourceTable.PLACEX,
                                  ('place', 'thing'),
                                  napi.Point(1.0, 2.0),
     reverse = napi.ReverseResult(napi.SourceTable.PLACEX,
                                  ('place', 'thing'),
                                  napi.Point(1.0, 2.0),
-                                 extratags={'one': 'A', 'two':'B'})
+                                 extratags={'one': 'A', 'two': 'B'})
 
     raw = v1_format.format_result(napi.ReverseResults([reverse]), fmt,
 
     raw = v1_format.format_result(napi.ReverseResults([reverse]), fmt,
-                                 {'extratags': True})
+                                  {'extratags': True})
 
     if fmt == 'xml':
         root = ET.fromstring(raw)
 
     if fmt == 'xml':
         root = ET.fromstring(raw)
@@ -226,7 +225,7 @@ def test_format_reverse_with_extratags(fmt):
         else:
             extra = result['extratags']
 
         else:
             extra = result['extratags']
 
-        assert extra == {'one': 'A', 'two':'B'}
+        assert extra == {'one': 'A', 'two': 'B'}
 
 
 @pytest.mark.parametrize('fmt', ['json', 'jsonv2', 'geojson', 'xml'])
 
 
 @pytest.mark.parametrize('fmt', ['json', 'jsonv2', 'geojson', 'xml'])
@@ -236,7 +235,7 @@ def test_format_reverse_with_extratags_none(fmt):
                                  napi.Point(1.0, 2.0))
 
     raw = v1_format.format_result(napi.ReverseResults([reverse]), fmt,
                                  napi.Point(1.0, 2.0))
 
     raw = v1_format.format_result(napi.ReverseResults([reverse]), fmt,
-                                 {'extratags': True})
+                                  {'extratags': True})
 
     if fmt == 'xml':
         root = ET.fromstring(raw)
 
     if fmt == 'xml':
         root = ET.fromstring(raw)
@@ -256,10 +255,10 @@ def test_format_reverse_with_namedetails_with_name(fmt):
     reverse = napi.ReverseResult(napi.SourceTable.PLACEX,
                                  ('place', 'thing'),
                                  napi.Point(1.0, 2.0),
     reverse = napi.ReverseResult(napi.SourceTable.PLACEX,
                                  ('place', 'thing'),
                                  napi.Point(1.0, 2.0),
-                                 names={'name': 'A', 'ref':'1'})
+                                 names={'name': 'A', 'ref': '1'})
 
     raw = v1_format.format_result(napi.ReverseResults([reverse]), fmt,
 
     raw = v1_format.format_result(napi.ReverseResults([reverse]), fmt,
-                                 {'namedetails': True})
+                                  {'namedetails': True})
 
     if fmt == 'xml':
         root = ET.fromstring(raw)
 
     if fmt == 'xml':
         root = ET.fromstring(raw)
@@ -271,7 +270,7 @@ def test_format_reverse_with_namedetails_with_name(fmt):
         else:
             extra = result['namedetails']
 
         else:
             extra = result['namedetails']
 
-        assert extra == {'name': 'A', 'ref':'1'}
+        assert extra == {'name': 'A', 'ref': '1'}
 
 
 @pytest.mark.parametrize('fmt', ['json', 'jsonv2', 'geojson', 'xml'])
 
 
 @pytest.mark.parametrize('fmt', ['json', 'jsonv2', 'geojson', 'xml'])
@@ -281,7 +280,7 @@ def test_format_reverse_with_namedetails_without_name(fmt):
                                  napi.Point(1.0, 2.0))
 
     raw = v1_format.format_result(napi.ReverseResults([reverse]), fmt,
                                  napi.Point(1.0, 2.0))
 
     raw = v1_format.format_result(napi.ReverseResults([reverse]), fmt,
-                                 {'namedetails': True})
+                                  {'namedetails': True})
 
     if fmt == 'xml':
         root = ET.fromstring(raw)
 
     if fmt == 'xml':
         root = ET.fromstring(raw)
@@ -303,7 +302,7 @@ def test_search_details_with_icon_available(fmt):
                                  napi.Point(1.0, 2.0))
 
     result = v1_format.format_result(napi.ReverseResults([reverse]), fmt,
                                  napi.Point(1.0, 2.0))
 
     result = v1_format.format_result(napi.ReverseResults([reverse]), fmt,
-                                    {'icon_base_url': 'foo'})
+                                     {'icon_base_url': 'foo'})
 
     js = json.loads(result)
 
 
     js = json.loads(result)
 
@@ -317,7 +316,6 @@ def test_search_details_with_icon_not_available(fmt):
                                  napi.Point(1.0, 2.0))
 
     result = v1_format.format_result(napi.ReverseResults([reverse]), fmt,
                                  napi.Point(1.0, 2.0))
 
     result = v1_format.format_result(napi.ReverseResults([reverse]), fmt,
-                                    {'icon_base_url': 'foo'})
+                                     {'icon_base_url': 'foo'})
 
     assert 'icon' not in json.loads(result)
 
     assert 'icon' not in json.loads(result)
-
index f0bfa163cbcb8b41cdf3f90f8fd0d9f68f8809e6..8e9fbf684fc48d06090fbb5b6bb5c9724a6c1634 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for result datatype helper functions.
 # For a full list of authors see the git log.
 """
 Tests for result datatype helper functions.
@@ -11,16 +11,15 @@ import struct
 from binascii import hexlify
 
 import pytest
 from binascii import hexlify
 
 import pytest
-import pytest_asyncio
-import sqlalchemy as sa
-
 
 from nominatim_api import SourceTable, DetailedResult, Point
 import nominatim_api.results as nresults
 
 
 from nominatim_api import SourceTable, DetailedResult, Point
 import nominatim_api.results as nresults
 
+
 def mkpoint(x, y):
     return hexlify(struct.pack("=biidd", 1, 0x20000001, 4326, x, y)).decode('utf-8')
 
 def mkpoint(x, y):
     return hexlify(struct.pack("=biidd", 1, 0x20000001, 4326, x, y)).decode('utf-8')
 
+
 class FakeRow:
     def __init__(self, **kwargs):
         if 'parent_place_id' not in kwargs:
 class FakeRow:
     def __init__(self, **kwargs):
         if 'parent_place_id' not in kwargs:
@@ -39,6 +38,7 @@ def test_minimal_detailed_result():
     assert res.lat == 0.5
     assert res.calculated_importance() == pytest.approx(0.00001)
 
     assert res.lat == 0.5
     assert res.calculated_importance() == pytest.approx(0.00001)
 
+
 def test_detailed_result_custom_importance():
     res = DetailedResult(SourceTable.PLACEX,
                          ('amenity', 'post_box'),
 def test_detailed_result_custom_importance():
     res = DetailedResult(SourceTable.PLACEX,
                          ('amenity', 'post_box'),
index 6ea790c060b21c740c3ff2e985adeb4bf51ba3b5..8d9f09404bfb2cd92c703d136c33fa5784f36c9d 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for the Python web frameworks adaptor, v1 API.
 # For a full list of authors see the git log.
 """
 Tests for the Python web frameworks adaptor, v1 API.
@@ -121,7 +121,6 @@ class TestAdaptorRaiseError:
 
         return excinfo.value
 
 
         return excinfo.value
 
-
     def test_without_content_set(self):
         err = self.run_raise_error('TEST', 404)
 
     def test_without_content_set(self):
         err = self.run_raise_error('TEST', 404)
 
@@ -129,7 +128,6 @@ class TestAdaptorRaiseError:
         assert err.msg == 'ERROR 404: TEST'
         assert err.status == 404
 
         assert err.msg == 'ERROR 404: TEST'
         assert err.status == 404
 
-
     def test_json(self):
         self.adaptor.content_type = 'application/json; charset=utf-8'
 
     def test_json(self):
         self.adaptor.content_type = 'application/json; charset=utf-8'
 
@@ -139,7 +137,6 @@ class TestAdaptorRaiseError:
         assert content['code'] == 501
         assert content['message'] == 'TEST'
 
         assert content['code'] == 501
         assert content['message'] == 'TEST'
 
-
     def test_xml(self):
         self.adaptor.content_type = 'text/xml; charset=utf-8'
 
     def test_xml(self):
         self.adaptor.content_type = 'text/xml; charset=utf-8'
 
@@ -235,7 +232,6 @@ class TestStatusEndpoint:
 
         monkeypatch.setattr(napi.NominatimAPIAsync, 'status', _status)
 
 
         monkeypatch.setattr(napi.NominatimAPIAsync, 'status', _status)
 
-
     @pytest.mark.asyncio
     async def test_status_without_params(self):
         a = FakeAdaptor()
     @pytest.mark.asyncio
     async def test_status_without_params(self):
         a = FakeAdaptor()
@@ -247,7 +243,6 @@ class TestStatusEndpoint:
         assert resp.status == 200
         assert resp.content_type == 'text/plain; charset=utf-8'
 
         assert resp.status == 200
         assert resp.content_type == 'text/plain; charset=utf-8'
 
-
     @pytest.mark.asyncio
     async def test_status_with_error(self):
         a = FakeAdaptor()
     @pytest.mark.asyncio
     async def test_status_with_error(self):
         a = FakeAdaptor()
@@ -259,7 +254,6 @@ class TestStatusEndpoint:
         assert resp.status == 500
         assert resp.content_type == 'text/plain; charset=utf-8'
 
         assert resp.status == 500
         assert resp.content_type == 'text/plain; charset=utf-8'
 
-
     @pytest.mark.asyncio
     async def test_status_json_with_error(self):
         a = FakeAdaptor(params={'format': 'json'})
     @pytest.mark.asyncio
     async def test_status_json_with_error(self):
         a = FakeAdaptor(params={'format': 'json'})
@@ -271,7 +265,6 @@ class TestStatusEndpoint:
         assert resp.status == 200
         assert resp.content_type == 'application/json; charset=utf-8'
 
         assert resp.status == 200
         assert resp.content_type == 'application/json; charset=utf-8'
 
-
     @pytest.mark.asyncio
     async def test_status_bad_format(self):
         a = FakeAdaptor(params={'format': 'foo'})
     @pytest.mark.asyncio
     async def test_status_bad_format(self):
         a = FakeAdaptor(params={'format': 'foo'})
@@ -298,7 +291,6 @@ class TestDetailsEndpoint:
 
         monkeypatch.setattr(napi.NominatimAPIAsync, 'details', _lookup)
 
 
         monkeypatch.setattr(napi.NominatimAPIAsync, 'details', _lookup)
 
-
     @pytest.mark.asyncio
     async def test_details_no_params(self):
         a = FakeAdaptor()
     @pytest.mark.asyncio
     async def test_details_no_params(self):
         a = FakeAdaptor()
@@ -306,7 +298,6 @@ class TestDetailsEndpoint:
         with pytest.raises(FakeError, match='^400 -- .*Missing'):
             await glue.details_endpoint(napi.NominatimAPIAsync(), a)
 
         with pytest.raises(FakeError, match='^400 -- .*Missing'):
             await glue.details_endpoint(napi.NominatimAPIAsync(), a)
 
-
     @pytest.mark.asyncio
     async def test_details_by_place_id(self):
         a = FakeAdaptor(params={'place_id': '4573'})
     @pytest.mark.asyncio
     async def test_details_by_place_id(self):
         a = FakeAdaptor(params={'place_id': '4573'})
@@ -315,7 +306,6 @@ class TestDetailsEndpoint:
 
         assert self.lookup_args[0].place_id == 4573
 
 
         assert self.lookup_args[0].place_id == 4573
 
-
     @pytest.mark.asyncio
     async def test_details_by_osm_id(self):
         a = FakeAdaptor(params={'osmtype': 'N', 'osmid': '45'})
     @pytest.mark.asyncio
     async def test_details_by_osm_id(self):
         a = FakeAdaptor(params={'osmtype': 'N', 'osmid': '45'})
@@ -326,7 +316,6 @@ class TestDetailsEndpoint:
         assert self.lookup_args[0].osm_id == 45
         assert self.lookup_args[0].osm_class is None
 
         assert self.lookup_args[0].osm_id == 45
         assert self.lookup_args[0].osm_class is None
 
-
     @pytest.mark.asyncio
     async def test_details_with_debugging(self):
         a = FakeAdaptor(params={'osmtype': 'N', 'osmid': '45', 'debug': '1'})
     @pytest.mark.asyncio
     async def test_details_with_debugging(self):
         a = FakeAdaptor(params={'osmtype': 'N', 'osmid': '45', 'debug': '1'})
@@ -337,7 +326,6 @@ class TestDetailsEndpoint:
         assert resp.content_type == 'text/html; charset=utf-8'
         assert content.tag == 'html'
 
         assert resp.content_type == 'text/html; charset=utf-8'
         assert content.tag == 'html'
 
-
     @pytest.mark.asyncio
     async def test_details_no_result(self):
         a = FakeAdaptor(params={'place_id': '4573'})
     @pytest.mark.asyncio
     async def test_details_no_result(self):
         a = FakeAdaptor(params={'place_id': '4573'})
@@ -353,14 +341,14 @@ class TestReverseEndPoint:
     @pytest.fixture(autouse=True)
     def patch_reverse_func(self, monkeypatch):
         self.result = napi.ReverseResult(napi.SourceTable.PLACEX,
     @pytest.fixture(autouse=True)
     def patch_reverse_func(self, monkeypatch):
         self.result = napi.ReverseResult(napi.SourceTable.PLACEX,
-                                          ('place', 'thing'),
-                                          napi.Point(1.0, 2.0))
+                                         ('place', 'thing'),
+                                         napi.Point(1.0, 2.0))
+
         async def _reverse(*args, **kwargs):
             return self.result
 
         monkeypatch.setattr(napi.NominatimAPIAsync, 'reverse', _reverse)
 
         async def _reverse(*args, **kwargs):
             return self.result
 
         monkeypatch.setattr(napi.NominatimAPIAsync, 'reverse', _reverse)
 
-
     @pytest.mark.asyncio
     @pytest.mark.parametrize('params', [{}, {'lat': '3.4'}, {'lon': '6.7'}])
     async def test_reverse_no_params(self, params):
     @pytest.mark.asyncio
     @pytest.mark.parametrize('params', [{}, {'lat': '3.4'}, {'lon': '6.7'}])
     async def test_reverse_no_params(self, params):
@@ -371,19 +359,6 @@ class TestReverseEndPoint:
         with pytest.raises(FakeError, match='^400 -- (?s:.*)missing'):
             await glue.reverse_endpoint(napi.NominatimAPIAsync(), a)
 
         with pytest.raises(FakeError, match='^400 -- (?s:.*)missing'):
             await glue.reverse_endpoint(napi.NominatimAPIAsync(), a)
 
-
-    @pytest.mark.asyncio
-    @pytest.mark.parametrize('params', [{'lat': '45.6', 'lon': '4563'}])
-    async def test_reverse_success(self, params):
-        a = FakeAdaptor()
-        a.params = params
-        a.params['format'] = 'json'
-
-        res = await glue.reverse_endpoint(napi.NominatimAPIAsync(), a)
-
-        assert res == ''
-
-
     @pytest.mark.asyncio
     async def test_reverse_success(self):
         a = FakeAdaptor()
     @pytest.mark.asyncio
     async def test_reverse_success(self):
         a = FakeAdaptor()
@@ -392,7 +367,6 @@ class TestReverseEndPoint:
 
         assert await glue.reverse_endpoint(napi.NominatimAPIAsync(), a)
 
 
         assert await glue.reverse_endpoint(napi.NominatimAPIAsync(), a)
 
-
     @pytest.mark.asyncio
     async def test_reverse_from_search(self):
         a = FakeAdaptor()
     @pytest.mark.asyncio
     async def test_reverse_from_search(self):
         a = FakeAdaptor()
@@ -413,12 +387,12 @@ class TestLookupEndpoint:
         self.results = [napi.SearchResult(napi.SourceTable.PLACEX,
                                           ('place', 'thing'),
                                           napi.Point(1.0, 2.0))]
         self.results = [napi.SearchResult(napi.SourceTable.PLACEX,
                                           ('place', 'thing'),
                                           napi.Point(1.0, 2.0))]
+
         async def _lookup(*args, **kwargs):
             return napi.SearchResults(self.results)
 
         monkeypatch.setattr(napi.NominatimAPIAsync, 'lookup', _lookup)
 
         async def _lookup(*args, **kwargs):
             return napi.SearchResults(self.results)
 
         monkeypatch.setattr(napi.NominatimAPIAsync, 'lookup', _lookup)
 
-
     @pytest.mark.asyncio
     async def test_lookup_no_params(self):
         a = FakeAdaptor()
     @pytest.mark.asyncio
     async def test_lookup_no_params(self):
         a = FakeAdaptor()
@@ -428,7 +402,6 @@ class TestLookupEndpoint:
 
         assert res.output == '[]'
 
 
         assert res.output == '[]'
 
-
     @pytest.mark.asyncio
     @pytest.mark.parametrize('param', ['w', 'bad', ''])
     async def test_lookup_bad_params(self, param):
     @pytest.mark.asyncio
     @pytest.mark.parametrize('param', ['w', 'bad', ''])
     async def test_lookup_bad_params(self, param):
@@ -440,7 +413,6 @@ class TestLookupEndpoint:
 
         assert len(json.loads(res.output)) == 1
 
 
         assert len(json.loads(res.output)) == 1
 
-
     @pytest.mark.asyncio
     @pytest.mark.parametrize('param', ['p234234', '4563'])
     async def test_lookup_bad_osm_type(self, param):
     @pytest.mark.asyncio
     @pytest.mark.parametrize('param', ['p234234', '4563'])
     async def test_lookup_bad_osm_type(self, param):
@@ -452,7 +424,6 @@ class TestLookupEndpoint:
 
         assert len(json.loads(res.output)) == 1
 
 
         assert len(json.loads(res.output)) == 1
 
-
     @pytest.mark.asyncio
     async def test_lookup_working(self):
         a = FakeAdaptor()
     @pytest.mark.asyncio
     async def test_lookup_working(self):
         a = FakeAdaptor()
@@ -473,12 +444,12 @@ class TestSearchEndPointSearch:
         self.results = [napi.SearchResult(napi.SourceTable.PLACEX,
                                           ('place', 'thing'),
                                           napi.Point(1.0, 2.0))]
         self.results = [napi.SearchResult(napi.SourceTable.PLACEX,
                                           ('place', 'thing'),
                                           napi.Point(1.0, 2.0))]
+
         async def _search(*args, **kwargs):
             return napi.SearchResults(self.results)
 
         monkeypatch.setattr(napi.NominatimAPIAsync, 'search', _search)
 
         async def _search(*args, **kwargs):
             return napi.SearchResults(self.results)
 
         monkeypatch.setattr(napi.NominatimAPIAsync, 'search', _search)
 
-
     @pytest.mark.asyncio
     async def test_search_free_text(self):
         a = FakeAdaptor()
     @pytest.mark.asyncio
     async def test_search_free_text(self):
         a = FakeAdaptor()
@@ -488,7 +459,6 @@ class TestSearchEndPointSearch:
 
         assert len(json.loads(res.output)) == 1
 
 
         assert len(json.loads(res.output)) == 1
 
-
     @pytest.mark.asyncio
     async def test_search_free_text_xml(self):
         a = FakeAdaptor()
     @pytest.mark.asyncio
     async def test_search_free_text_xml(self):
         a = FakeAdaptor()
@@ -500,7 +470,6 @@ class TestSearchEndPointSearch:
         assert res.status == 200
         assert res.output.index('something') > 0
 
         assert res.status == 200
         assert res.output.index('something') > 0
 
-
     @pytest.mark.asyncio
     async def test_search_free_and_structured(self):
         a = FakeAdaptor()
     @pytest.mark.asyncio
     async def test_search_free_and_structured(self):
         a = FakeAdaptor()
@@ -508,8 +477,7 @@ class TestSearchEndPointSearch:
         a.params['city'] = 'ignored'
 
         with pytest.raises(FakeError, match='^400 -- .*cannot be used together'):
         a.params['city'] = 'ignored'
 
         with pytest.raises(FakeError, match='^400 -- .*cannot be used together'):
-            res = await glue.search_endpoint(napi.NominatimAPIAsync(), a)
-
+            await glue.search_endpoint(napi.NominatimAPIAsync(), a)
 
     @pytest.mark.asyncio
     @pytest.mark.parametrize('dedupe,numres', [(True, 1), (False, 2)])
 
     @pytest.mark.asyncio
     @pytest.mark.parametrize('dedupe,numres', [(True, 1), (False, 2)])
@@ -532,12 +500,12 @@ class TestSearchEndPointSearchAddress:
         self.results = [napi.SearchResult(napi.SourceTable.PLACEX,
                                           ('place', 'thing'),
                                           napi.Point(1.0, 2.0))]
         self.results = [napi.SearchResult(napi.SourceTable.PLACEX,
                                           ('place', 'thing'),
                                           napi.Point(1.0, 2.0))]
+
         async def _search(*args, **kwargs):
             return napi.SearchResults(self.results)
 
         monkeypatch.setattr(napi.NominatimAPIAsync, 'search_address', _search)
 
         async def _search(*args, **kwargs):
             return napi.SearchResults(self.results)
 
         monkeypatch.setattr(napi.NominatimAPIAsync, 'search_address', _search)
 
-
     @pytest.mark.asyncio
     async def test_search_structured(self):
         a = FakeAdaptor()
     @pytest.mark.asyncio
     async def test_search_structured(self):
         a = FakeAdaptor()
@@ -555,12 +523,12 @@ class TestSearchEndPointSearchCategory:
         self.results = [napi.SearchResult(napi.SourceTable.PLACEX,
                                           ('place', 'thing'),
                                           napi.Point(1.0, 2.0))]
         self.results = [napi.SearchResult(napi.SourceTable.PLACEX,
                                           ('place', 'thing'),
                                           napi.Point(1.0, 2.0))]
+
         async def _search(*args, **kwargs):
             return napi.SearchResults(self.results)
 
         monkeypatch.setattr(napi.NominatimAPIAsync, 'search_category', _search)
 
         async def _search(*args, **kwargs):
             return napi.SearchResults(self.results)
 
         monkeypatch.setattr(napi.NominatimAPIAsync, 'search_category', _search)
 
-
     @pytest.mark.asyncio
     async def test_search_category(self):
         a = FakeAdaptor()
     @pytest.mark.asyncio
     async def test_search_category(self):
         a = FakeAdaptor()
index f0c9986d302f9159c017ea72a7a12ac6197daa7c..94081d00051ff5df17695b2168dc058795d6e459 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for warm-up CLI function.
 # For a full list of authors see the git log.
 """
 Tests for warm-up CLI function.
@@ -11,6 +11,7 @@ import pytest
 
 import nominatim_db.cli
 
 
 import nominatim_db.cli
 
+
 @pytest.fixture(autouse=True)
 def setup_database_with_context(apiobj, table_factory):
     table_factory('word',
 @pytest.fixture(autouse=True)
 def setup_database_with_context(apiobj, table_factory):
     table_factory('word',
@@ -21,8 +22,9 @@ def setup_database_with_context(apiobj, table_factory):
     apiobj.add_data('properties',
                     [{'property': 'tokenizer', 'value': 'icu'},
                      {'property': 'tokenizer_import_normalisation', 'value': ':: lower();'},
     apiobj.add_data('properties',
                     [{'property': 'tokenizer', 'value': 'icu'},
                      {'property': 'tokenizer_import_normalisation', 'value': ':: lower();'},
-                     {'property': 'tokenizer_import_transliteration', 'value': "'1' > '/1/'; 'ä' > 'ä '"},
-                    ])
+                     {'property': 'tokenizer_import_transliteration',
+                      'value': "'1' > '/1/'; 'ä' > 'ä '"}
+                     ])
 
 
 @pytest.mark.parametrize('args', [['--search-only'], ['--reverse-only']])
 
 
 @pytest.mark.parametrize('args', [['--search-only'], ['--reverse-only']])
index 84f2d6598ae8adad77efe389d64d3adb31e80604..921a3a322949bcec14d876a8895c6f4b2473c363 100644 (file)
@@ -2,12 +2,13 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 import pytest
 
 import nominatim_db.cli
 
 # For a full list of authors see the git log.
 import pytest
 
 import nominatim_db.cli
 
+
 class MockParamCapture:
     """ Mock that records the parameters with which a function was called
         as well as the number of calls.
 class MockParamCapture:
     """ Mock that records the parameters with which a function was called
         as well as the number of calls.
index d42df50a760066f972628817b830c67899dea04a..a538049e81c52a2056fb20c03fda05baf9e6c6d8 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for command line interface wrapper.
 # For a full list of authors see the git log.
 """
 Tests for command line interface wrapper.
@@ -11,7 +11,6 @@ These tests just check that the various command line parameters route to the
 correct functionality. They use a lot of monkeypatching to avoid executing
 the actual functions.
 """
 correct functionality. They use a lot of monkeypatching to avoid executing
 the actual functions.
 """
-import importlib
 import pytest
 
 import nominatim_db.indexer.indexer
 import pytest
 
 import nominatim_db.indexer.indexer
@@ -28,6 +27,7 @@ def test_cli_help(cli_call, capsys):
     captured = capsys.readouterr()
     assert captured.out.startswith('usage:')
 
     captured = capsys.readouterr()
     assert captured.out.startswith('usage:')
 
+
 def test_cli_version(cli_call, capsys):
     """ Running nominatim tool --version prints a version string.
     """
 def test_cli_version(cli_call, capsys):
     """ Running nominatim tool --version prints a version string.
     """
@@ -46,7 +46,6 @@ class TestCliWithDb:
         # Make sure tools.freeze.is_frozen doesn't report database as frozen. Monkeypatching failed
         table_factory('place')
 
         # Make sure tools.freeze.is_frozen doesn't report database as frozen. Monkeypatching failed
         table_factory('place')
 
-
     @pytest.mark.parametrize("name,oid", [('file', 'foo.osm'), ('diff', 'foo.osc')])
     def test_cli_add_data_file_command(self, cli_call, mock_func_factory, name, oid):
         mock_run_legacy = mock_func_factory(nominatim_db.tools.add_osm_data, 'add_data_from_file')
     @pytest.mark.parametrize("name,oid", [('file', 'foo.osm'), ('diff', 'foo.osc')])
     def test_cli_add_data_file_command(self, cli_call, mock_func_factory, name, oid):
         mock_run_legacy = mock_func_factory(nominatim_db.tools.add_osm_data, 'add_data_from_file')
@@ -54,7 +53,6 @@ class TestCliWithDb:
 
         assert mock_run_legacy.called == 1
 
 
         assert mock_run_legacy.called == 1
 
-
     @pytest.mark.parametrize("name,oid", [('node', 12), ('way', 8), ('relation', 32)])
     def test_cli_add_data_object_command(self, cli_call, mock_func_factory, name, oid):
         mock_run_legacy = mock_func_factory(nominatim_db.tools.add_osm_data, 'add_osm_object')
     @pytest.mark.parametrize("name,oid", [('node', 12), ('way', 8), ('relation', 32)])
     def test_cli_add_data_object_command(self, cli_call, mock_func_factory, name, oid):
         mock_run_legacy = mock_func_factory(nominatim_db.tools.add_osm_data, 'add_osm_object')
@@ -62,8 +60,6 @@ class TestCliWithDb:
 
         assert mock_run_legacy.called == 1
 
 
         assert mock_run_legacy.called == 1
 
-
-
     def test_cli_add_data_tiger_data(self, cli_call, cli_tokenizer_mock, async_mock_func_factory):
         mock = async_mock_func_factory(nominatim_db.tools.tiger_data, 'add_tiger_data')
 
     def test_cli_add_data_tiger_data(self, cli_call, cli_tokenizer_mock, async_mock_func_factory):
         mock = async_mock_func_factory(nominatim_db.tools.tiger_data, 'add_tiger_data')
 
@@ -80,7 +76,6 @@ class TestCliWithDb:
         assert mock_drop.called == 1
         assert mock_flatnode.called == 1
 
         assert mock_drop.called == 1
         assert mock_flatnode.called == 1
 
-
     @pytest.mark.parametrize("params,do_bnds,do_ranks", [
                               ([], 2, 2),
                               (['--boundaries-only'], 2, 0),
     @pytest.mark.parametrize("params,do_bnds,do_ranks", [
                               ([], 2, 2),
                               (['--boundaries-only'], 2, 0),
@@ -89,11 +84,14 @@ class TestCliWithDb:
     def test_index_command(self, monkeypatch, async_mock_func_factory, table_factory,
                            params, do_bnds, do_ranks):
         table_factory('import_status', 'indexed bool')
     def test_index_command(self, monkeypatch, async_mock_func_factory, table_factory,
                            params, do_bnds, do_ranks):
         table_factory('import_status', 'indexed bool')
-        bnd_mock = async_mock_func_factory(nominatim_db.indexer.indexer.Indexer, 'index_boundaries')
-        rank_mock = async_mock_func_factory(nominatim_db.indexer.indexer.Indexer, 'index_by_rank')
-        postcode_mock = async_mock_func_factory(nominatim_db.indexer.indexer.Indexer, 'index_postcodes')
-
-        monkeypatch.setattr(nominatim_db.indexer.indexer.Indexer, 'has_pending', 
+        bnd_mock = async_mock_func_factory(nominatim_db.indexer.indexer.Indexer,
+                                           'index_boundaries')
+        rank_mock = async_mock_func_factory(nominatim_db.indexer.indexer.Indexer,
+                                            'index_by_rank')
+        postcode_mock = async_mock_func_factory(nominatim_db.indexer.indexer.Indexer,
+                                                'index_postcodes')
+
+        monkeypatch.setattr(nominatim_db.indexer.indexer.Indexer, 'has_pending',
                             [False, True].pop)
 
         assert self.call_nominatim('index', *params) == 0
                             [False, True].pop)
 
         assert self.call_nominatim('index', *params) == 0
@@ -102,7 +100,6 @@ class TestCliWithDb:
         assert rank_mock.called == do_ranks
         assert postcode_mock.called == do_ranks
 
         assert rank_mock.called == do_ranks
         assert postcode_mock.called == do_ranks
 
-
     def test_special_phrases_wiki_command(self, mock_func_factory):
         func = mock_func_factory(nominatim_db.clicmd.special_phrases.SPImporter, 'import_phrases')
 
     def test_special_phrases_wiki_command(self, mock_func_factory):
         func = mock_func_factory(nominatim_db.clicmd.special_phrases.SPImporter, 'import_phrases')
 
@@ -110,7 +107,6 @@ class TestCliWithDb:
 
         assert func.called == 1
 
 
         assert func.called == 1
 
-
     def test_special_phrases_csv_command(self, src_dir, mock_func_factory):
         func = mock_func_factory(nominatim_db.clicmd.special_phrases.SPImporter, 'import_phrases')
         testdata = src_dir / 'test' / 'testdb'
     def test_special_phrases_csv_command(self, src_dir, mock_func_factory):
         func = mock_func_factory(nominatim_db.clicmd.special_phrases.SPImporter, 'import_phrases')
         testdata = src_dir / 'test' / 'testdb'
@@ -120,7 +116,6 @@ class TestCliWithDb:
 
         assert func.called == 1
 
 
         assert func.called == 1
 
-
     def test_special_phrases_csv_bad_file(self, src_dir):
         testdata = src_dir / 'something349053905.csv'
 
     def test_special_phrases_csv_bad_file(self, src_dir):
         testdata = src_dir / 'something349053905.csv'
 
index 7b0b9cd466fd6cfa27dd947af8752312f5656f4f..9732d73405b3f1bcb6cfd4995406047fed92d9c1 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Test for the command line interface wrapper admin subcommand.
 # For a full list of authors see the git log.
 """
 Test for the command line interface wrapper admin subcommand.
@@ -39,11 +39,13 @@ def test_admin_clean_deleted_relations(cli_call, mock_func_factory):
     assert cli_call('admin', '--clean-deleted', '1 month') == 0
     assert mock.called == 1
 
     assert cli_call('admin', '--clean-deleted', '1 month') == 0
     assert mock.called == 1
 
+
 def test_admin_clean_deleted_relations_no_age(cli_call, mock_func_factory):
 def test_admin_clean_deleted_relations_no_age(cli_call, mock_func_factory):
-    mock = mock_func_factory(nominatim_db.tools.admin, 'clean_deleted_relations')
+    mock_func_factory(nominatim_db.tools.admin, 'clean_deleted_relations')
 
     assert cli_call('admin', '--clean-deleted') == 1
 
 
     assert cli_call('admin', '--clean-deleted') == 1
 
+
 class TestCliAdminWithDb:
 
     @pytest.fixture(autouse=True)
 class TestCliAdminWithDb:
 
     @pytest.fixture(autouse=True)
@@ -51,7 +53,6 @@ class TestCliAdminWithDb:
         self.call_nominatim = cli_call
         self.tokenizer_mock = cli_tokenizer_mock
 
         self.call_nominatim = cli_call
         self.tokenizer_mock = cli_tokenizer_mock
 
-
     @pytest.mark.parametrize("func, params", [('analyse_indexing', ('--analyse-indexing', ))])
     def test_analyse_indexing(self, mock_func_factory, func, params):
         mock = mock_func_factory(nominatim_db.tools.admin, func)
     @pytest.mark.parametrize("func, params", [('analyse_indexing', ('--analyse-indexing', ))])
     def test_analyse_indexing(self, mock_func_factory, func, params):
         mock = mock_func_factory(nominatim_db.tools.admin, func)
index 1c0750d1dc1cf03630ccf51c9024bbec508562dc..541b680c4c65dacb0489823a4d195a6113f4b6f0 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for API access commands of command-line interface wrapper.
 # For a full list of authors see the git log.
 """
 Tests for API access commands of command-line interface wrapper.
@@ -10,9 +10,9 @@ Tests for API access commands of command-line interface wrapper.
 import json
 import pytest
 
 import json
 import pytest
 
-import nominatim_db.clicmd.api
 import nominatim_api as napi
 
 import nominatim_api as napi
 
+
 @pytest.mark.parametrize('call', ['search', 'reverse', 'lookup', 'details', 'status'])
 def test_list_format(cli_call, call):
     assert 0 == cli_call(call, '--list-formats')
 @pytest.mark.parametrize('call', ['search', 'reverse', 'lookup', 'details', 'status'])
 def test_list_format(cli_call, call):
     assert 0 == cli_call(call, '--list-formats')
@@ -30,13 +30,11 @@ class TestCliStatusCall:
         monkeypatch.setattr(napi.NominatimAPI, 'status',
                             lambda self: napi.StatusResult(200, 'OK'))
 
         monkeypatch.setattr(napi.NominatimAPI, 'status',
                             lambda self: napi.StatusResult(200, 'OK'))
 
-
     def test_status_simple(self, cli_call, tmp_path):
         result = cli_call('status', '--project-dir', str(tmp_path))
 
         assert result == 0
 
     def test_status_simple(self, cli_call, tmp_path):
         result = cli_call('status', '--project-dir', str(tmp_path))
 
         assert result == 0
 
-
     def test_status_json_format(self, cli_call, tmp_path, capsys):
         result = cli_call('status', '--project-dir', str(tmp_path),
                           '--format', 'json')
     def test_status_json_format(self, cli_call, tmp_path, capsys):
         result = cli_call('status', '--project-dir', str(tmp_path),
                           '--format', 'json')
@@ -60,7 +58,6 @@ class TestCliDetailsCall:
                                         ('--way', '1'),
                                         ('--relation', '1'),
                                         ('--place_id', '10001')])
                                         ('--way', '1'),
                                         ('--relation', '1'),
                                         ('--place_id', '10001')])
-
     def test_details_json_format(self, cli_call, tmp_path, capsys, params):
         result = cli_call('details', '--project-dir', str(tmp_path), *params)
 
     def test_details_json_format(self, cli_call, tmp_path, capsys, params):
         result = cli_call('details', '--project-dir', str(tmp_path), *params)
 
@@ -75,15 +72,14 @@ class TestCliReverseCall:
     def setup_reverse_mock(self, monkeypatch):
         result = napi.ReverseResult(napi.SourceTable.PLACEX, ('place', 'thing'),
                                     napi.Point(1.0, -3.0),
     def setup_reverse_mock(self, monkeypatch):
         result = napi.ReverseResult(napi.SourceTable.PLACEX, ('place', 'thing'),
                                     napi.Point(1.0, -3.0),
-                                    names={'name':'Name', 'name:fr': 'Nom'},
-                                    extratags={'extra':'Extra'},
+                                    names={'name': 'Name', 'name:fr': 'Nom'},
+                                    extratags={'extra': 'Extra'},
                                     locale_name='Name',
                                     display_name='Name')
 
         monkeypatch.setattr(napi.NominatimAPI, 'reverse',
                             lambda *args, **kwargs: result)
 
                                     locale_name='Name',
                                     display_name='Name')
 
         monkeypatch.setattr(napi.NominatimAPI, 'reverse',
                             lambda *args, **kwargs: result)
 
-
     def test_reverse_simple(self, cli_call, tmp_path, capsys):
         result = cli_call('reverse', '--project-dir', str(tmp_path),
                           '--lat', '34', '--lon', '34')
     def test_reverse_simple(self, cli_call, tmp_path, capsys):
         result = cli_call('reverse', '--project-dir', str(tmp_path),
                           '--lat', '34', '--lon', '34')
@@ -96,7 +92,6 @@ class TestCliReverseCall:
         assert 'extratags' not in out
         assert 'namedetails' not in out
 
         assert 'extratags' not in out
         assert 'namedetails' not in out
 
-
     @pytest.mark.parametrize('param,field', [('--addressdetails', 'address'),
                                              ('--extratags', 'extratags'),
                                              ('--namedetails', 'namedetails')])
     @pytest.mark.parametrize('param,field', [('--addressdetails', 'address'),
                                              ('--extratags', 'extratags'),
                                              ('--namedetails', 'namedetails')])
@@ -109,7 +104,6 @@ class TestCliReverseCall:
         out = json.loads(capsys.readouterr().out)
         assert field in out
 
         out = json.loads(capsys.readouterr().out)
         assert field in out
 
-
     def test_reverse_format(self, cli_call, tmp_path, capsys):
         result = cli_call('reverse', '--project-dir', str(tmp_path),
                           '--lat', '34', '--lon', '34', '--format', 'geojson')
     def test_reverse_format(self, cli_call, tmp_path, capsys):
         result = cli_call('reverse', '--project-dir', str(tmp_path),
                           '--lat', '34', '--lon', '34', '--format', 'geojson')
@@ -125,11 +119,11 @@ class TestCliLookupCall:
     @pytest.fixture(autouse=True)
     def setup_lookup_mock(self, monkeypatch):
         result = napi.SearchResult(napi.SourceTable.PLACEX, ('place', 'thing'),
     @pytest.fixture(autouse=True)
     def setup_lookup_mock(self, monkeypatch):
         result = napi.SearchResult(napi.SourceTable.PLACEX, ('place', 'thing'),
-                                    napi.Point(1.0, -3.0),
-                                    names={'name':'Name', 'name:fr': 'Nom'},
-                                    extratags={'extra':'Extra'},
-                                    locale_name='Name',
-                                    display_name='Name')
+                                   napi.Point(1.0, -3.0),
+                                   names={'name': 'Name', 'name:fr': 'Nom'},
+                                   extratags={'extra': 'Extra'},
+                                   locale_name='Name',
+                                   display_name='Name')
 
         monkeypatch.setattr(napi.NominatimAPI, 'lookup',
                             lambda *args, **kwargs: napi.SearchResults([result]))
 
         monkeypatch.setattr(napi.NominatimAPI, 'lookup',
                             lambda *args, **kwargs: napi.SearchResults([result]))
@@ -150,19 +144,18 @@ class TestCliLookupCall:
 
 @pytest.mark.parametrize('endpoint, params', [('search', ('--query', 'Berlin')),
                                               ('search_address', ('--city', 'Berlin'))
 
 @pytest.mark.parametrize('endpoint, params', [('search', ('--query', 'Berlin')),
                                               ('search_address', ('--city', 'Berlin'))
-                                             ])
+                                              ])
 def test_search(cli_call, tmp_path, capsys, monkeypatch, endpoint, params):
     result = napi.SearchResult(napi.SourceTable.PLACEX, ('place', 'thing'),
                                napi.Point(1.0, -3.0),
 def test_search(cli_call, tmp_path, capsys, monkeypatch, endpoint, params):
     result = napi.SearchResult(napi.SourceTable.PLACEX, ('place', 'thing'),
                                napi.Point(1.0, -3.0),
-                               names={'name':'Name', 'name:fr': 'Nom'},
-                               extratags={'extra':'Extra'},
+                               names={'name': 'Name', 'name:fr': 'Nom'},
+                               extratags={'extra': 'Extra'},
                                locale_name='Name',
                                display_name='Name')
 
     monkeypatch.setattr(napi.NominatimAPI, endpoint,
                         lambda *args, **kwargs: napi.SearchResults([result]))
 
                                locale_name='Name',
                                display_name='Name')
 
     monkeypatch.setattr(napi.NominatimAPI, endpoint,
                         lambda *args, **kwargs: napi.SearchResults([result]))
 
-
     result = cli_call('search', '--project-dir', str(tmp_path), *params)
 
     assert result == 0
     result = cli_call('search', '--project-dir', str(tmp_path), *params)
 
     assert result == 0
index f833dde347d7b743fbda477b1a2b761b59c6ebf2..e4a86fe0be865bb6e3633f4fd38afb6f492d1f5d 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for import command of the command-line interface wrapper.
 # For a full list of authors see the git log.
 """
 Tests for import command of the command-line interface wrapper.
@@ -24,15 +24,12 @@ class TestCliImportWithDb:
         self.call_nominatim = cli_call
         self.tokenizer_mock = cli_tokenizer_mock
 
         self.call_nominatim = cli_call
         self.tokenizer_mock = cli_tokenizer_mock
 
-
     def test_import_missing_file(self):
         assert self.call_nominatim('import', '--osm-file', 'sfsafegwedgw.reh.erh') == 1
 
     def test_import_missing_file(self):
         assert self.call_nominatim('import', '--osm-file', 'sfsafegwedgw.reh.erh') == 1
 
-
     def test_import_bad_file(self):
         assert self.call_nominatim('import', '--osm-file', '.') == 1
 
     def test_import_bad_file(self):
         assert self.call_nominatim('import', '--osm-file', '.') == 1
 
-
     @pytest.mark.parametrize('with_updates', [True, False])
     def test_import_full(self, mock_func_factory, async_mock_func_factory,
                          with_updates, place_table, property_table):
     @pytest.mark.parametrize('with_updates', [True, False])
     def test_import_full(self, mock_func_factory, async_mock_func_factory,
                          with_updates, place_table, property_table):
@@ -62,7 +59,6 @@ class TestCliImportWithDb:
 
         cf_mock = mock_func_factory(nominatim_db.tools.refresh, 'create_functions')
 
 
         cf_mock = mock_func_factory(nominatim_db.tools.refresh, 'create_functions')
 
-
         assert self.call_nominatim(*params) == 0
         assert self.tokenizer_mock.finalize_import_called
 
         assert self.call_nominatim(*params) == 0
         assert self.tokenizer_mock.finalize_import_called
 
@@ -71,7 +67,6 @@ class TestCliImportWithDb:
         for mock in mocks:
             assert mock.called == 1, "Mock '{}' not called".format(mock.func_name)
 
         for mock in mocks:
             assert mock.called == 1, "Mock '{}' not called".format(mock.func_name)
 
-
     def test_import_continue_load_data(self, mock_func_factory, async_mock_func_factory):
         mocks = [
             mock_func_factory(nominatim_db.tools.database_import, 'truncate_data_tables'),
     def test_import_continue_load_data(self, mock_func_factory, async_mock_func_factory):
         mocks = [
             mock_func_factory(nominatim_db.tools.database_import, 'truncate_data_tables'),
@@ -89,7 +84,6 @@ class TestCliImportWithDb:
         for mock in mocks:
             assert mock.called == 1, "Mock '{}' not called".format(mock.func_name)
 
         for mock in mocks:
             assert mock.called == 1, "Mock '{}' not called".format(mock.func_name)
 
-
     def test_import_continue_indexing(self, mock_func_factory, async_mock_func_factory,
                                       placex_table, temp_db_conn):
         mocks = [
     def test_import_continue_indexing(self, mock_func_factory, async_mock_func_factory,
                                       placex_table, temp_db_conn):
         mocks = [
@@ -107,7 +101,6 @@ class TestCliImportWithDb:
         # Calling it again still works for the index
         assert self.call_nominatim('import', '--continue', 'indexing') == 0
 
         # Calling it again still works for the index
         assert self.call_nominatim('import', '--continue', 'indexing') == 0
 
-
     def test_import_continue_postprocess(self, mock_func_factory, async_mock_func_factory):
         mocks = [
             async_mock_func_factory(nominatim_db.tools.database_import, 'create_search_indices'),
     def test_import_continue_postprocess(self, mock_func_factory, async_mock_func_factory):
         mocks = [
             async_mock_func_factory(nominatim_db.tools.database_import, 'create_search_indices'),
index 9f3d7bb241e46b31e3f4a548722ad3b2c60ee5ad..8121946f775022c75d27c931c168ea3612d09047 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for command line interface wrapper for refresk command.
 # For a full list of authors see the git log.
 """
 Tests for command line interface wrapper for refresk command.
@@ -13,6 +13,7 @@ import nominatim_db.tools.refresh
 import nominatim_db.tools.postcodes
 import nominatim_db.indexer.indexer
 
 import nominatim_db.tools.postcodes
 import nominatim_db.indexer.indexer
 
+
 class TestRefresh:
 
     @pytest.fixture(autouse=True)
 class TestRefresh:
 
     @pytest.fixture(autouse=True)
@@ -20,7 +21,6 @@ class TestRefresh:
         self.call_nominatim = cli_call
         self.tokenizer_mock = cli_tokenizer_mock
 
         self.call_nominatim = cli_call
         self.tokenizer_mock = cli_tokenizer_mock
 
-
     @pytest.mark.parametrize("command,func", [
                              ('address-levels', 'load_address_levels_from_config'),
                              ('wiki-data', 'import_wikipedia_articles'),
     @pytest.mark.parametrize("command,func", [
                              ('address-levels', 'load_address_levels_from_config'),
                              ('wiki-data', 'import_wikipedia_articles'),
@@ -33,17 +33,14 @@ class TestRefresh:
         assert self.call_nominatim('refresh', '--' + command) == 0
         assert func_mock.called == 1
 
         assert self.call_nominatim('refresh', '--' + command) == 0
         assert func_mock.called == 1
 
-
     def test_refresh_word_count(self):
         assert self.call_nominatim('refresh', '--word-count') == 0
         assert self.tokenizer_mock.update_statistics_called
 
     def test_refresh_word_count(self):
         assert self.call_nominatim('refresh', '--word-count') == 0
         assert self.tokenizer_mock.update_statistics_called
 
-
     def test_refresh_word_tokens(self):
         assert self.call_nominatim('refresh', '--word-tokens') == 0
         assert self.tokenizer_mock.update_word_tokens_called
 
     def test_refresh_word_tokens(self):
         assert self.call_nominatim('refresh', '--word-tokens') == 0
         assert self.tokenizer_mock.update_word_tokens_called
 
-
     def test_refresh_postcodes(self, async_mock_func_factory, mock_func_factory, place_table):
         func_mock = mock_func_factory(nominatim_db.tools.postcodes, 'update_postcodes')
         idx_mock = async_mock_func_factory(nominatim_db.indexer.indexer.Indexer, 'index_postcodes')
     def test_refresh_postcodes(self, async_mock_func_factory, mock_func_factory, place_table):
         func_mock = mock_func_factory(nominatim_db.tools.postcodes, 'update_postcodes')
         idx_mock = async_mock_func_factory(nominatim_db.indexer.indexer.Indexer, 'index_postcodes')
@@ -52,12 +49,10 @@ class TestRefresh:
         assert func_mock.called == 1
         assert idx_mock.called == 1
 
         assert func_mock.called == 1
         assert idx_mock.called == 1
 
-
     def test_refresh_postcodes_no_place_table(self):
         # Do nothing without the place table
         assert self.call_nominatim('refresh', '--postcodes') == 0
 
     def test_refresh_postcodes_no_place_table(self):
         # Do nothing without the place table
         assert self.call_nominatim('refresh', '--postcodes') == 0
 
-
     def test_refresh_create_functions(self, mock_func_factory):
         func_mock = mock_func_factory(nominatim_db.tools.refresh, 'create_functions')
 
     def test_refresh_create_functions(self, mock_func_factory):
         func_mock = mock_func_factory(nominatim_db.tools.refresh, 'create_functions')
 
@@ -65,17 +60,14 @@ class TestRefresh:
         assert func_mock.called == 1
         assert self.tokenizer_mock.update_sql_functions_called
 
         assert func_mock.called == 1
         assert self.tokenizer_mock.update_sql_functions_called
 
-
     def test_refresh_wikidata_file_not_found(self, monkeypatch):
         monkeypatch.setenv('NOMINATIM_WIKIPEDIA_DATA_PATH', 'gjoiergjeroi345Q')
 
         assert self.call_nominatim('refresh', '--wiki-data') == 1
 
     def test_refresh_wikidata_file_not_found(self, monkeypatch):
         monkeypatch.setenv('NOMINATIM_WIKIPEDIA_DATA_PATH', 'gjoiergjeroi345Q')
 
         assert self.call_nominatim('refresh', '--wiki-data') == 1
 
-
     def test_refresh_secondary_importance_file_not_found(self):
         assert self.call_nominatim('refresh', '--secondary-importance') == 1
 
     def test_refresh_secondary_importance_file_not_found(self):
         assert self.call_nominatim('refresh', '--secondary-importance') == 1
 
-
     def test_refresh_secondary_importance_new_table(self, mock_func_factory):
         mocks = [mock_func_factory(nominatim_db.tools.refresh, 'import_secondary_importance'),
                  mock_func_factory(nominatim_db.tools.refresh, 'create_functions')]
     def test_refresh_secondary_importance_new_table(self, mock_func_factory):
         mocks = [mock_func_factory(nominatim_db.tools.refresh, 'import_secondary_importance'),
                  mock_func_factory(nominatim_db.tools.refresh, 'create_functions')]
@@ -84,7 +76,6 @@ class TestRefresh:
         assert mocks[0].called == 1
         assert mocks[1].called == 1
 
         assert mocks[0].called == 1
         assert mocks[1].called == 1
 
-
     def test_refresh_importance_computed_after_wiki_import(self, monkeypatch, mock_func_factory):
         calls = []
         monkeypatch.setattr(nominatim_db.tools.refresh, 'import_wikipedia_articles',
     def test_refresh_importance_computed_after_wiki_import(self, monkeypatch, mock_func_factory):
         calls = []
         monkeypatch.setattr(nominatim_db.tools.refresh, 'import_wikipedia_articles',
@@ -102,7 +93,8 @@ class TestRefresh:
                                         ('--data-object', 'N23', '--data-object', 'N24'),
                                         ('--data-area', 'R7723'),
                                         ('--data-area', 'r7723', '--data-area', 'r2'),
                                         ('--data-object', 'N23', '--data-object', 'N24'),
                                         ('--data-area', 'R7723'),
                                         ('--data-area', 'r7723', '--data-area', 'r2'),
-                                        ('--data-area', 'R9284425', '--data-object', 'n1234567894567')])
+                                        ('--data-area', 'R9284425',
+                                         '--data-object', 'n1234567894567')])
     def test_refresh_objects(self, params, mock_func_factory):
         func_mock = mock_func_factory(nominatim_db.tools.refresh, 'invalidate_osm_object')
 
     def test_refresh_objects(self, params, mock_func_factory):
         func_mock = mock_func_factory(nominatim_db.tools.refresh, 'invalidate_osm_object')
 
@@ -110,7 +102,6 @@ class TestRefresh:
 
         assert func_mock.called == len(params)/2
 
 
         assert func_mock.called == len(params)/2
 
-
     @pytest.mark.parametrize('func', ('--data-object', '--data-area'))
     @pytest.mark.parametrize('param', ('234', 'a55', 'R 453', 'Rel'))
     def test_refresh_objects_bad_param(self, func, param, mock_func_factory):
     @pytest.mark.parametrize('func', ('--data-object', '--data-area'))
     @pytest.mark.parametrize('param', ('234', 'a55', 'R 453', 'Rel'))
     def test_refresh_objects_bad_param(self, func, param, mock_func_factory):
index 21c6350d4e762c62f66de007cd147da95d347671..34aafa3ab1cae1453174e0018a07739c16b1449c 100644 (file)
@@ -18,6 +18,7 @@ import nominatim_db.tools.replication
 import nominatim_db.tools.refresh
 from nominatim_db.db import status
 
 import nominatim_db.tools.refresh
 from nominatim_db.db import status
 
+
 @pytest.fixture
 def tokenizer_mock(monkeypatch):
     class DummyTokenizer:
 @pytest.fixture
 def tokenizer_mock(monkeypatch):
     class DummyTokenizer:
@@ -40,7 +41,6 @@ def tokenizer_mock(monkeypatch):
     return tok
 
 
     return tok
 
 
-
 @pytest.fixture
 def init_status(temp_db_conn, status_table):
     status.set_status(temp_db_conn, date=dt.datetime.now(dt.timezone.utc), seq=1)
 @pytest.fixture
 def init_status(temp_db_conn, status_table):
     status.set_status(temp_db_conn, date=dt.datetime.now(dt.timezone.utc), seq=1)
@@ -62,16 +62,14 @@ class TestCliReplication:
     def setup_cli_call(self, cli_call, temp_db):
         self.call_nominatim = lambda *args: cli_call('replication', *args)
 
     def setup_cli_call(self, cli_call, temp_db):
         self.call_nominatim = lambda *args: cli_call('replication', *args)
 
-
     @pytest.fixture(autouse=True)
     def setup_update_function(self, monkeypatch):
         def _mock_updates(states):
             monkeypatch.setattr(nominatim_db.tools.replication, 'update',
     @pytest.fixture(autouse=True)
     def setup_update_function(self, monkeypatch):
         def _mock_updates(states):
             monkeypatch.setattr(nominatim_db.tools.replication, 'update',
-                            lambda *args, **kwargs: states.pop())
+                                lambda *args, **kwargs: states.pop())
 
         self.update_states = _mock_updates
 
 
         self.update_states = _mock_updates
 
-
     @pytest.mark.parametrize("params,func", [
                              (('--init',), 'init_replication'),
                              (('--init', '--no-update-functions'), 'init_replication'),
     @pytest.mark.parametrize("params,func", [
                              (('--init',), 'init_replication'),
                              (('--init', '--no-update-functions'), 'init_replication'),
@@ -88,20 +86,17 @@ class TestCliReplication:
         if params == ('--init',):
             assert umock.called == 1
 
         if params == ('--init',):
             assert umock.called == 1
 
-
     def test_replication_update_bad_interval(self, monkeypatch):
         monkeypatch.setenv('NOMINATIM_REPLICATION_UPDATE_INTERVAL', 'xx')
 
         assert self.call_nominatim() == 1
 
     def test_replication_update_bad_interval(self, monkeypatch):
         monkeypatch.setenv('NOMINATIM_REPLICATION_UPDATE_INTERVAL', 'xx')
 
         assert self.call_nominatim() == 1
 
-
     def test_replication_update_bad_interval_for_geofabrik(self, monkeypatch):
         monkeypatch.setenv('NOMINATIM_REPLICATION_URL',
                            'https://download.geofabrik.de/europe/italy-updates')
 
         assert self.call_nominatim() == 1
 
     def test_replication_update_bad_interval_for_geofabrik(self, monkeypatch):
         monkeypatch.setenv('NOMINATIM_REPLICATION_URL',
                            'https://download.geofabrik.de/europe/italy-updates')
 
         assert self.call_nominatim() == 1
 
-
     def test_replication_update_continuous_no_index(self):
         assert self.call_nominatim('--no-index') == 1
 
     def test_replication_update_continuous_no_index(self):
         assert self.call_nominatim('--no-index') == 1
 
@@ -110,14 +105,12 @@ class TestCliReplication:
 
         assert str(update_mock.last_args[1]['osm2pgsql']).endswith('OSM2PGSQL NOT AVAILABLE')
 
 
         assert str(update_mock.last_args[1]['osm2pgsql']).endswith('OSM2PGSQL NOT AVAILABLE')
 
-
     def test_replication_update_custom_osm2pgsql(self, monkeypatch, update_mock):
         monkeypatch.setenv('NOMINATIM_OSM2PGSQL_BINARY', '/secret/osm2pgsql')
         assert self.call_nominatim('--once', '--no-index') == 0
 
         assert str(update_mock.last_args[1]['osm2pgsql']) == '/secret/osm2pgsql'
 
     def test_replication_update_custom_osm2pgsql(self, monkeypatch, update_mock):
         monkeypatch.setenv('NOMINATIM_OSM2PGSQL_BINARY', '/secret/osm2pgsql')
         assert self.call_nominatim('--once', '--no-index') == 0
 
         assert str(update_mock.last_args[1]['osm2pgsql']) == '/secret/osm2pgsql'
 
-
     @pytest.mark.parametrize("update_interval", [60, 3600])
     def test_replication_catchup(self, placex_table, monkeypatch, index_mock, update_interval):
         monkeypatch.setenv('NOMINATIM_REPLICATION_UPDATE_INTERVAL', str(update_interval))
     @pytest.mark.parametrize("update_interval", [60, 3600])
     def test_replication_catchup(self, placex_table, monkeypatch, index_mock, update_interval):
         monkeypatch.setenv('NOMINATIM_REPLICATION_UPDATE_INTERVAL', str(update_interval))
@@ -125,13 +118,11 @@ class TestCliReplication:
 
         assert self.call_nominatim('--catch-up') == 0
 
 
         assert self.call_nominatim('--catch-up') == 0
 
-
     def test_replication_update_custom_threads(self, update_mock):
         assert self.call_nominatim('--once', '--no-index', '--threads', '4') == 0
 
         assert update_mock.last_args[1]['threads'] == 4
 
     def test_replication_update_custom_threads(self, update_mock):
         assert self.call_nominatim('--once', '--no-index', '--threads', '4') == 0
 
         assert update_mock.last_args[1]['threads'] == 4
 
-
     def test_replication_update_continuous(self, index_mock):
         self.update_states([nominatim_db.tools.replication.UpdateState.UP_TO_DATE,
                             nominatim_db.tools.replication.UpdateState.UP_TO_DATE])
     def test_replication_update_continuous(self, index_mock):
         self.update_states([nominatim_db.tools.replication.UpdateState.UP_TO_DATE,
                             nominatim_db.tools.replication.UpdateState.UP_TO_DATE])
@@ -141,7 +132,6 @@ class TestCliReplication:
 
         assert index_mock.called == 2
 
 
         assert index_mock.called == 2
 
-
     def test_replication_update_continuous_no_change(self, mock_func_factory,
                                                      index_mock):
         self.update_states([nominatim_db.tools.replication.UpdateState.NO_CHANGES,
     def test_replication_update_continuous_no_change(self, mock_func_factory,
                                                      index_mock):
         self.update_states([nominatim_db.tools.replication.UpdateState.NO_CHANGES,
index 9f68fcb9a97e89b2d85058ef6ecccf4d745b3334..a0dbf476b9bf8ce4dbd81705be18704e230d68e5 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Test for loading dotenv configuration.
 # For a full list of authors see the git log.
 """
 Test for loading dotenv configuration.
@@ -13,6 +13,7 @@ import pytest
 from nominatim_db.config import Configuration, flatten_config_list
 from nominatim_db.errors import UsageError
 
 from nominatim_db.config import Configuration, flatten_config_list
 from nominatim_db.errors import UsageError
 
+
 @pytest.fixture
 def make_config():
     """ Create a configuration object from the given project directory.
 @pytest.fixture
 def make_config():
     """ Create a configuration object from the given project directory.
@@ -22,6 +23,7 @@ def make_config():
 
     return _mk_config
 
 
     return _mk_config
 
+
 @pytest.fixture
 def make_config_path(tmp_path):
     """ Create a configuration object with project and config directories
 @pytest.fixture
 def make_config_path(tmp_path):
     """ Create a configuration object with project and config directories
@@ -108,7 +110,7 @@ def test_get_libpq_dsn_convert_php(make_config, monkeypatch):
 
 @pytest.mark.parametrize("val,expect", [('foo bar', "'foo bar'"),
                                         ("xy'z", "xy\\'z"),
 
 @pytest.mark.parametrize("val,expect", [('foo bar', "'foo bar'"),
                                         ("xy'z", "xy\\'z"),
-                                       ])
+                                        ])
 def test_get_libpq_dsn_convert_php_special_chars(make_config, monkeypatch, val, expect):
     config = make_config()
 
 def test_get_libpq_dsn_convert_php_special_chars(make_config, monkeypatch, val, expect):
     config = make_config()
 
@@ -137,6 +139,7 @@ def test_get_bool(make_config, monkeypatch, value, result):
 
     assert config.get_bool('FOOBAR') == result
 
 
     assert config.get_bool('FOOBAR') == result
 
+
 def test_get_bool_empty(make_config):
     config = make_config()
 
 def test_get_bool_empty(make_config):
     config = make_config()
 
@@ -303,7 +306,7 @@ def test_load_subconf_env_absolute_not_found(make_config_path, monkeypatch, tmp_
     (config.config_dir / 'test.yaml').write_text('cow: muh\ncat: miau\n')
 
     with pytest.raises(UsageError, match='Config file not found.'):
     (config.config_dir / 'test.yaml').write_text('cow: muh\ncat: miau\n')
 
     with pytest.raises(UsageError, match='Config file not found.'):
-        rules = config.load_sub_configuration('test.yaml', config='MY_CONFIG')
+        config.load_sub_configuration('test.yaml', config='MY_CONFIG')
 
 
 @pytest.mark.parametrize("location", ['project_dir', 'config_dir'])
 
 
 @pytest.mark.parametrize("location", ['project_dir', 'config_dir'])
@@ -326,7 +329,7 @@ def test_load_subconf_env_relative_not_found(make_config_path, monkeypatch):
     (config.config_dir / 'test.yaml').write_text('cow: muh\ncat: miau\n')
 
     with pytest.raises(UsageError, match='Config file not found.'):
     (config.config_dir / 'test.yaml').write_text('cow: muh\ncat: miau\n')
 
     with pytest.raises(UsageError, match='Config file not found.'):
-        rules = config.load_sub_configuration('test.yaml', config='MY_CONFIG')
+        config.load_sub_configuration('test.yaml', config='MY_CONFIG')
 
 
 def test_load_subconf_json(make_config_path):
 
 
 def test_load_subconf_json(make_config_path):
@@ -338,6 +341,7 @@ def test_load_subconf_json(make_config_path):
 
     assert rules == dict(cow='muh', cat='miau')
 
 
     assert rules == dict(cow='muh', cat='miau')
 
+
 def test_load_subconf_not_found(make_config_path):
     config = make_config_path()
 
 def test_load_subconf_not_found(make_config_path):
     config = make_config_path()
 
@@ -371,7 +375,7 @@ def test_load_subconf_include_relative(make_config_path, tmp_path, location):
     config = make_config_path()
 
     testfile = config.config_dir / 'test.yaml'
     config = make_config_path()
 
     testfile = config.config_dir / 'test.yaml'
-    testfile.write_text(f'base: !include inc.yaml\n')
+    testfile.write_text('base: !include inc.yaml\n')
     (getattr(config, location) / 'inc.yaml').write_text('first: 1\nsecond: 2\n')
 
     rules = config.load_sub_configuration('test.yaml')
     (getattr(config, location) / 'inc.yaml').write_text('first: 1\nsecond: 2\n')
 
     rules = config.load_sub_configuration('test.yaml')
@@ -383,28 +387,28 @@ def test_load_subconf_include_bad_format(make_config_path):
     config = make_config_path()
 
     testfile = config.config_dir / 'test.yaml'
     config = make_config_path()
 
     testfile = config.config_dir / 'test.yaml'
-    testfile.write_text(f'base: !include inc.txt\n')
+    testfile.write_text('base: !include inc.txt\n')
     (config.config_dir / 'inc.txt').write_text('first: 1\nsecond: 2\n')
 
     with pytest.raises(UsageError, match='Cannot handle config file format.'):
     (config.config_dir / 'inc.txt').write_text('first: 1\nsecond: 2\n')
 
     with pytest.raises(UsageError, match='Cannot handle config file format.'):
-        rules = config.load_sub_configuration('test.yaml')
+        config.load_sub_configuration('test.yaml')
 
 
 def test_load_subconf_include_not_found(make_config_path):
     config = make_config_path()
 
     testfile = config.config_dir / 'test.yaml'
 
 
 def test_load_subconf_include_not_found(make_config_path):
     config = make_config_path()
 
     testfile = config.config_dir / 'test.yaml'
-    testfile.write_text(f'base: !include inc.txt\n')
+    testfile.write_text('base: !include inc.txt\n')
 
     with pytest.raises(UsageError, match='Config file not found.'):
 
     with pytest.raises(UsageError, match='Config file not found.'):
-        rules = config.load_sub_configuration('test.yaml')
+        config.load_sub_configuration('test.yaml')
 
 
 def test_load_subconf_include_recursive(make_config_path):
     config = make_config_path()
 
     testfile = config.config_dir / 'test.yaml'
 
 
 def test_load_subconf_include_recursive(make_config_path):
     config = make_config_path()
 
     testfile = config.config_dir / 'test.yaml'
-    testfile.write_text(f'base: !include inc.yaml\n')
+    testfile.write_text('base: !include inc.yaml\n')
     (config.config_dir / 'inc.yaml').write_text('- !include more.yaml\n- upper\n')
     (config.config_dir / 'more.yaml').write_text('- the end\n')
 
     (config.config_dir / 'inc.yaml').write_text('- !include more.yaml\n- upper\n')
     (config.config_dir / 'more.yaml').write_text('- the end\n')
 
@@ -435,6 +439,6 @@ def test_flatten_config_list_nested():
         [[2, 3], [45, [56, 78], 66]],
         'end'
     ]
         [[2, 3], [45, [56, 78], 66]],
         'end'
     ]
+
     assert flatten_config_list(content) == \
     assert flatten_config_list(content) == \
-               [34, {'first': '1st', 'second': '2nd'}, {},
-                2, 3, 45, 56, 78, 66, 'end']
+        [34, {'first': '1st', 'second': '2nd'}, {}, 2, 3, 45, 56, 78, 66, 'end']
index c29121802c2dd69291a97dd8042502a7dc159873..309bd1fc325850c1be2bf5254a5557a49d5bcf5b 100644 (file)
@@ -2,18 +2,18 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Test for loading extra Python modules.
 """
 # For a full list of authors see the git log.
 """
 Test for loading extra Python modules.
 """
-from pathlib import Path
 import sys
 
 import pytest
 
 from nominatim_db.config import Configuration
 
 import sys
 
 import pytest
 
 from nominatim_db.config import Configuration
 
+
 @pytest.fixture
 def test_config(src_dir, tmp_path):
     """ Create a configuration object with project and config directories
 @pytest.fixture
 def test_config(src_dir, tmp_path):
     """ Create a configuration object with project and config directories
@@ -31,6 +31,7 @@ def test_load_default_module(test_config):
 
     assert isinstance(module.NOMINATIM_VERSION, tuple)
 
 
     assert isinstance(module.NOMINATIM_VERSION, tuple)
 
+
 def test_load_default_module_with_hyphen(test_config):
     module = test_config.load_plugin_module('place-info', 'nominatim_db.data')
 
 def test_load_default_module_with_hyphen(test_config):
     module = test_config.load_plugin_module('place-info', 'nominatim_db.data')
 
index a25ff8ec5046766416be3bcb87091dff8ff90fd2..f95da39e4411fd68e8155ebef11643e0308bea4f 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 import itertools
 import sys
 # For a full list of authors see the git log.
 import itertools
 import sys
@@ -69,6 +69,7 @@ def temp_db_with_extensions(temp_db):
 
     return temp_db
 
 
     return temp_db
 
+
 @pytest.fixture
 def temp_db_conn(temp_db):
     """ Connection to the test database.
 @pytest.fixture
 def temp_db_conn(temp_db):
     """ Connection to the test database.
@@ -100,8 +101,9 @@ def table_factory(temp_db_conn):
             if content:
                 sql = pysql.SQL("INSERT INTO {} VALUES ({})")\
                            .format(pysql.Identifier(name),
             if content:
                 sql = pysql.SQL("INSERT INTO {} VALUES ({})")\
                            .format(pysql.Identifier(name),
-                                   pysql.SQL(',').join([pysql.Placeholder() for _ in range(len(content[0]))]))
-                cur.executemany(sql , content)
+                                   pysql.SQL(',').join([pysql.Placeholder()
+                                                        for _ in range(len(content[0]))]))
+                cur.executemany(sql, content)
 
     return mk_table
 
 
     return mk_table
 
@@ -178,6 +180,7 @@ def place_row(place_table, temp_db_cursor):
 
     return _insert
 
 
     return _insert
 
+
 @pytest.fixture
 def placex_table(temp_db_with_extensions, temp_db_conn):
     """ Create an empty version of the place table.
 @pytest.fixture
 def placex_table(temp_db_with_extensions, temp_db_conn):
     """ Create an empty version of the place table.
index b3fc260a2526d016ae2607e681e702baaddb591e..5dc93cd57e3bd66cf1c5d516d2258e1dc7f2c780 100644 (file)
@@ -2,13 +2,14 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Specialised psycopg cursor with shortcut functions useful for testing.
 """
 import psycopg
 
 # For a full list of authors see the git log.
 """
 Specialised psycopg cursor with shortcut functions useful for testing.
 """
 import psycopg
 
+
 class CursorForTesting(psycopg.Cursor):
     """ Extension to the DictCursor class that provides execution
         short-cuts that simplify writing assertions.
 class CursorForTesting(psycopg.Cursor):
     """ Extension to the DictCursor class that provides execution
         short-cuts that simplify writing assertions.
@@ -22,7 +23,6 @@ class CursorForTesting(psycopg.Cursor):
         assert self.rowcount == 1
         return self.fetchone()[0]
 
         assert self.rowcount == 1
         return self.fetchone()[0]
 
-
     def row_set(self, sql, params=None):
         """ Execute a query and return the result as a set of tuples.
             Fails when the SQL command returns duplicate rows.
     def row_set(self, sql, params=None):
         """ Execute a query and return the result as a set of tuples.
             Fails when the SQL command returns duplicate rows.
@@ -34,7 +34,6 @@ class CursorForTesting(psycopg.Cursor):
 
         return result
 
 
         return result
 
-
     def table_exists(self, table):
         """ Check that a table with the given name exists in the database.
         """
     def table_exists(self, table):
         """ Check that a table with the given name exists in the database.
         """
@@ -42,7 +41,6 @@ class CursorForTesting(psycopg.Cursor):
                              WHERE tablename = %s""", (table, ))
         return num == 1
 
                              WHERE tablename = %s""", (table, ))
         return num == 1
 
-
     def index_exists(self, table, index):
         """ Check that an indexwith the given name exists on the given table.
         """
     def index_exists(self, table, index):
         """ Check that an indexwith the given name exists on the given table.
         """
@@ -51,7 +49,6 @@ class CursorForTesting(psycopg.Cursor):
                           (table, index))
         return num == 1
 
                           (table, index))
         return num == 1
 
-
     def table_rows(self, table, where=None):
         """ Return the number of rows in the given table.
         """
     def table_rows(self, table, where=None):
         """ Return the number of rows in the given table.
         """
index 14b306bb764d70717f5c572304a4634af330ba9e..a85b7bf92ac7b56c82fd1a2f2c8299b3f000a7a4 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for function that handle country properties.
 # For a full list of authors see the git log.
 """
 Tests for function that handle country properties.
@@ -12,6 +12,7 @@ import pytest
 
 from nominatim_db.data import country_info
 
 
 from nominatim_db.data import country_info
 
+
 @pytest.fixture
 def loaded_country(def_config):
     country_info.setup_country_config(def_config)
 @pytest.fixture
 def loaded_country(def_config):
     country_info.setup_country_config(def_config)
@@ -115,8 +116,8 @@ def test_setup_country_config_languages_not_loaded(env_with_country_config):
     info = country_info._CountryInfo()
     info.load(config)
     assert dict(info.items()) == {'de': {'partition': 3,
     info = country_info._CountryInfo()
     info.load(config)
     assert dict(info.items()) == {'de': {'partition': 3,
-                                  'languages': [],
-                                  'names': {'name': 'Deutschland'}}}
+                                         'languages': [],
+                                         'names': {'name': 'Deutschland'}}}
 
 
 def test_setup_country_config_name_not_loaded(env_with_country_config):
 
 
 def test_setup_country_config_name_not_loaded(env_with_country_config):
@@ -132,8 +133,7 @@ def test_setup_country_config_name_not_loaded(env_with_country_config):
 
     assert dict(info.items()) == {'de': {'partition': 3,
                                          'languages': ['de'],
 
     assert dict(info.items()) == {'de': {'partition': 3,
                                          'languages': ['de'],
-                                         'names': {}
-                                 }}
+                                         'names': {}}}
 
 
 def test_setup_country_config_names_not_loaded(env_with_country_config):
 
 
 def test_setup_country_config_names_not_loaded(env_with_country_config):
@@ -148,8 +148,7 @@ def test_setup_country_config_names_not_loaded(env_with_country_config):
 
     assert dict(info.items()) == {'de': {'partition': 3,
                                          'languages': ['de'],
 
     assert dict(info.items()) == {'de': {'partition': 3,
                                          'languages': ['de'],
-                                         'names': {}
-                                 }}
+                                         'names': {}}}
 
 
 def test_setup_country_config_special_character(env_with_country_config):
 
 
 def test_setup_country_config_special_character(env_with_country_config):
@@ -157,8 +156,8 @@ def test_setup_country_config_special_character(env_with_country_config):
                                      bq:
                                          partition: 250
                                          languages: nl
                                      bq:
                                          partition: 250
                                          languages: nl
-                                         names: 
-                                             name: 
+                                         names:
+                                             name:
                                                  default: "\\N"
                                      """)
 
                                                  default: "\\N"
                                      """)
 
@@ -167,5 +166,4 @@ def test_setup_country_config_special_character(env_with_country_config):
 
     assert dict(info.items()) == {'bq': {'partition': 250,
                                          'languages': ['nl'],
 
     assert dict(info.items()) == {'bq': {'partition': 250,
                                          'languages': ['nl'],
-                                         'names': {'name': '\x85'}
-                                 }}
+                                         'names': {'name': '\x85'}}}
index a8b5d677ce22e43f8e9b8e69ff222dc08202e560..19b945fda58de90fbd418934f193880bf3b6702c 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for specialised connection and cursor classes.
 # For a full list of authors see the git log.
 """
 Tests for specialised connection and cursor classes.
@@ -12,6 +12,7 @@ import psycopg
 
 import nominatim_db.db.connection as nc
 
 
 import nominatim_db.db.connection as nc
 
+
 @pytest.fixture
 def db(dsn):
     with nc.connect(dsn) as conn:
 @pytest.fixture
 def db(dsn):
     with nc.connect(dsn) as conn:
@@ -36,6 +37,7 @@ def test_has_column(db, table_factory, name, result):
 
     assert nc.table_has_column(db, 'stuff', name) == result
 
 
     assert nc.table_has_column(db, 'stuff', name) == result
 
+
 def test_connection_index_exists(db, table_factory, temp_db_cursor):
     assert not nc.index_exists(db, 'some_index')
 
 def test_connection_index_exists(db, table_factory, temp_db_cursor):
     assert not nc.index_exists(db, 'some_index')
 
@@ -76,6 +78,7 @@ def test_drop_table_non_existing_force(db):
     with pytest.raises(psycopg.ProgrammingError, match='.*does not exist.*'):
         nc.drop_tables(db, 'dfkjgjriogjigjgjrdghehtre', if_exists=False)
 
     with pytest.raises(psycopg.ProgrammingError, match='.*does not exist.*'):
         nc.drop_tables(db, 'dfkjgjriogjigjgjrdghehtre', if_exists=False)
 
+
 def test_connection_server_version_tuple(db):
     ver = nc.server_version_tuple(db)
 
 def test_connection_server_version_tuple(db):
     ver = nc.server_version_tuple(db)
 
index e55bb973467611022791699aa6ad755955a4bdbb..84d7dae06d8b0bd62fdd2e2675edc69d4de13fa5 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for property table manpulation.
 # For a full list of authors see the git log.
 """
 Tests for property table manpulation.
@@ -11,6 +11,7 @@ import pytest
 
 from nominatim_db.db import properties
 
 
 from nominatim_db.db import properties
 
+
 @pytest.fixture
 def property_factory(property_table, temp_db_cursor):
     """ A function fixture that adds a property into the property table.
 @pytest.fixture
 def property_factory(property_table, temp_db_cursor):
     """ A function fixture that adds a property into the property table.
index 45109c70c759452f0c972964944c40e79a322ff1..f2fbbb2af52cad7ead0c62ece5412bdc8b5ddae0 100644 (file)
@@ -2,16 +2,17 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for SQL preprocessing.
 """
 import pytest
 # For a full list of authors see the git log.
 """
 Tests for SQL preprocessing.
 """
 import pytest
-import pytest_asyncio
+import pytest_asyncio  # noqa
 
 from nominatim_db.db.sql_preprocessor import SQLPreprocessor
 
 
 from nominatim_db.db.sql_preprocessor import SQLPreprocessor
 
+
 @pytest.fixture
 def sql_factory(tmp_path):
     def _mk_sql(sql_body):
 @pytest.fixture
 def sql_factory(tmp_path):
     def _mk_sql(sql_body):
@@ -26,6 +27,7 @@ def sql_factory(tmp_path):
 
     return _mk_sql
 
 
     return _mk_sql
 
+
 @pytest.mark.parametrize("expr,ret", [
     ("'a'", 'a'),
     ("'{{db.partitions|join}}'", '012'),
 @pytest.mark.parametrize("expr,ret", [
     ("'a'", 'a'),
     ("'{{db.partitions|join}}'", '012'),
@@ -61,8 +63,7 @@ def test_load_file_with_params(sql_preprocessor, sql_factory, temp_db_conn, temp
 async def test_load_parallel_file(dsn, sql_preprocessor, tmp_path, temp_db_cursor):
     (tmp_path / 'test.sql').write_text("""
         CREATE TABLE foo (a TEXT);
 async def test_load_parallel_file(dsn, sql_preprocessor, tmp_path, temp_db_cursor):
     (tmp_path / 'test.sql').write_text("""
         CREATE TABLE foo (a TEXT);
-        CREATE TABLE foo2(a TEXT);""" + 
-        "\n---\nCREATE TABLE bar (b INT);")
+        CREATE TABLE foo2(a TEXT);""" + "\n---\nCREATE TABLE bar (b INT);")
 
     await sql_preprocessor.run_parallel_sql_file(dsn, 'test.sql', num_threads=4)
 
 
     await sql_preprocessor.run_parallel_sql_file(dsn, 'test.sql', num_threads=4)
 
index 77135a8c7f943c13df96632aa9901e50b9aabed7..462b8e3db809a0e56dd580771fc5c4d6b92a5cd1 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for status table manipulation.
 # For a full list of authors see the git log.
 """
 Tests for status table manipulation.
@@ -19,7 +19,8 @@ OSM_NODE_DATA = """\
 <node id="45673" visible="true" version="1" changeset="2047" timestamp="2006-01-27T22:09:10Z" user="Foo" uid="111" lat="48.7586670" lon="8.1343060">
 </node>
 </osm>
 <node id="45673" visible="true" version="1" changeset="2047" timestamp="2006-01-27T22:09:10Z" user="Foo" uid="111" lat="48.7586670" lon="8.1343060">
 </node>
 </osm>
-"""
+"""  # noqa
+
 
 def iso_date(date):
     return dt.datetime.strptime(date, nominatim_db.db.status.ISODATE_FORMAT)\
 
 def iso_date(date):
     return dt.datetime.strptime(date, nominatim_db.db.status.ISODATE_FORMAT)\
@@ -43,7 +44,8 @@ def test_compute_database_date_from_osm2pgsql(table_factory, temp_db_conn, offli
 def test_compute_database_date_from_osm2pgsql_nodata(table_factory, temp_db_conn):
     table_factory('osm2pgsql_properties', 'property TEXT, value TEXT')
 
 def test_compute_database_date_from_osm2pgsql_nodata(table_factory, temp_db_conn):
     table_factory('osm2pgsql_properties', 'property TEXT, value TEXT')
 
-    with pytest.raises(UsageError, match='Cannot determine database date from data in offline mode'):
+    with pytest.raises(UsageError,
+                       match='Cannot determine database date from data in offline mode'):
         nominatim_db.db.status.compute_database_date(temp_db_conn, offline=True)
 
 
         nominatim_db.db.status.compute_database_date(temp_db_conn, offline=True)
 
 
@@ -56,6 +58,7 @@ def test_compute_database_date_valid(monkeypatch, place_row, temp_db_conn):
     place_row(osm_type='N', osm_id=45673)
 
     requested_url = []
     place_row(osm_type='N', osm_id=45673)
 
     requested_url = []
+
     def mock_url(url):
         requested_url.append(url)
         return OSM_NODE_DATA
     def mock_url(url):
         requested_url.append(url)
         return OSM_NODE_DATA
@@ -72,6 +75,7 @@ def test_compute_database_broken_api(monkeypatch, place_row, temp_db_conn):
     place_row(osm_type='N', osm_id=45673)
 
     requested_url = []
     place_row(osm_type='N', osm_id=45673)
 
     requested_url = []
+
     def mock_url(url):
         requested_url.append(url)
         return '<osm version="0.6" generator="OpenStre'
     def mock_url(url):
         requested_url.append(url)
         return '<osm version="0.6" generator="OpenStre'
@@ -86,8 +90,7 @@ def test_set_status_empty_table(temp_db_conn, temp_db_cursor):
     date = dt.datetime.fromordinal(1000000).replace(tzinfo=dt.timezone.utc)
     nominatim_db.db.status.set_status(temp_db_conn, date=date)
 
     date = dt.datetime.fromordinal(1000000).replace(tzinfo=dt.timezone.utc)
     nominatim_db.db.status.set_status(temp_db_conn, date=date)
 
-    assert temp_db_cursor.row_set("SELECT * FROM import_status") == \
-             {(date, None, True)}
+    assert temp_db_cursor.row_set("SELECT * FROM import_status") == {(date, None, True)}
 
 
 def test_set_status_filled_table(temp_db_conn, temp_db_cursor):
 
 
 def test_set_status_filled_table(temp_db_conn, temp_db_cursor):
@@ -99,8 +102,7 @@ def test_set_status_filled_table(temp_db_conn, temp_db_cursor):
     date = dt.datetime.fromordinal(1000100).replace(tzinfo=dt.timezone.utc)
     nominatim_db.db.status.set_status(temp_db_conn, date=date, seq=456, indexed=False)
 
     date = dt.datetime.fromordinal(1000100).replace(tzinfo=dt.timezone.utc)
     nominatim_db.db.status.set_status(temp_db_conn, date=date, seq=456, indexed=False)
 
-    assert temp_db_cursor.row_set("SELECT * FROM import_status") == \
-             {(date, 456, False)}
+    assert temp_db_cursor.row_set("SELECT * FROM import_status") == {(date, 456, False)}
 
 
 def test_set_status_missing_date(temp_db_conn, temp_db_cursor):
 
 
 def test_set_status_missing_date(temp_db_conn, temp_db_cursor):
@@ -111,8 +113,7 @@ def test_set_status_missing_date(temp_db_conn, temp_db_cursor):
 
     nominatim_db.db.status.set_status(temp_db_conn, date=None, seq=456, indexed=False)
 
 
     nominatim_db.db.status.set_status(temp_db_conn, date=None, seq=456, indexed=False)
 
-    assert temp_db_cursor.row_set("SELECT * FROM import_status") == \
-             {(date, 456, False)}
+    assert temp_db_cursor.row_set("SELECT * FROM import_status") == {(date, 456, False)}
 
 
 def test_get_status_empty_table(temp_db_conn):
 
 
 def test_get_status_empty_table(temp_db_conn):
@@ -123,8 +124,7 @@ def test_get_status_success(temp_db_conn):
     date = dt.datetime.fromordinal(1000000).replace(tzinfo=dt.timezone.utc)
     nominatim_db.db.status.set_status(temp_db_conn, date=date, seq=667, indexed=False)
 
     date = dt.datetime.fromordinal(1000000).replace(tzinfo=dt.timezone.utc)
     nominatim_db.db.status.set_status(temp_db_conn, date=date, seq=667, indexed=False)
 
-    assert nominatim_db.db.status.get_status(temp_db_conn) == \
-             (date, 667, False)
+    assert nominatim_db.db.status.get_status(temp_db_conn) == (date, 667, False)
 
 
 @pytest.mark.parametrize("old_state", [True, False])
 
 
 @pytest.mark.parametrize("old_state", [True, False])
index 7c46846dbdd4fb0ba5c2fc2ae436f7df76005411..2bc7d95934277859593b3fc7cfeb60366749f3e6 100644 (file)
@@ -2,18 +2,17 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for DB utility functions in db.utils
 """
 # For a full list of authors see the git log.
 """
 Tests for DB utility functions in db.utils
 """
-import json
-
 import pytest
 
 import nominatim_db.db.utils as db_utils
 from nominatim_db.errors import UsageError
 
 import pytest
 
 import nominatim_db.db.utils as db_utils
 from nominatim_db.errors import UsageError
 
+
 def test_execute_file_success(dsn, temp_db_cursor, tmp_path):
     tmpfile = tmp_path / 'test.sql'
     tmpfile.write_text('CREATE TABLE test (id INT);\nINSERT INTO test VALUES(56);')
 def test_execute_file_success(dsn, temp_db_cursor, tmp_path):
     tmpfile = tmp_path / 'test.sql'
     tmpfile.write_text('CREATE TABLE test (id INT);\nINSERT INTO test VALUES(56);')
@@ -22,6 +21,7 @@ def test_execute_file_success(dsn, temp_db_cursor, tmp_path):
 
     assert temp_db_cursor.row_set('SELECT * FROM test') == {(56, )}
 
 
     assert temp_db_cursor.row_set('SELECT * FROM test') == {(56, )}
 
+
 def test_execute_file_bad_file(dsn, tmp_path):
     with pytest.raises(FileNotFoundError):
         db_utils.execute_file(dsn, tmp_path / 'test2.sql')
 def test_execute_file_bad_file(dsn, tmp_path):
     with pytest.raises(FileNotFoundError):
         db_utils.execute_file(dsn, tmp_path / 'test2.sql')
index 4739e3f0af831303f4860f601b802537e781d898..08554129257b74fbc43e526d4621deafac42f27f 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tokenizer for testing.
 # For a full list of authors see the git log.
 """
 Tokenizer for testing.
@@ -10,11 +10,13 @@ Tokenizer for testing.
 from nominatim_db.data.place_info import PlaceInfo
 from nominatim_db.config import Configuration
 
 from nominatim_db.data.place_info import PlaceInfo
 from nominatim_db.config import Configuration
 
+
 def create(dsn, data_dir):
     """ Create a new instance of the tokenizer provided by this module.
     """
     return DummyTokenizer(dsn, data_dir)
 
 def create(dsn, data_dir):
     """ Create a new instance of the tokenizer provided by this module.
     """
     return DummyTokenizer(dsn, data_dir)
 
+
 class DummyTokenizer:
 
     def __init__(self, dsn, data_dir):
 class DummyTokenizer:
 
     def __init__(self, dsn, data_dir):
@@ -23,23 +25,19 @@ class DummyTokenizer:
         self.init_state = None
         self.analyser_cache = {}
 
         self.init_state = None
         self.analyser_cache = {}
 
-
     def init_new_db(self, *args, **kwargs):
         assert self.init_state is None
         self.init_state = "new"
 
     def init_new_db(self, *args, **kwargs):
         assert self.init_state is None
         self.init_state = "new"
 
-
     def init_from_project(self, config):
         assert isinstance(config, Configuration)
         assert self.init_state is None
         self.init_state = "loaded"
 
     def init_from_project(self, config):
         assert isinstance(config, Configuration)
         assert self.init_state is None
         self.init_state = "loaded"
 
-
     @staticmethod
     def finalize_import(_):
         pass
 
     @staticmethod
     def finalize_import(_):
         pass
 
-
     def name_analyzer(self):
         return DummyNameAnalyzer(self.analyser_cache)
 
     def name_analyzer(self):
         return DummyNameAnalyzer(self.analyser_cache)
 
@@ -52,12 +50,10 @@ class DummyNameAnalyzer:
     def __exit__(self, exc_type, exc_value, traceback):
         self.close()
 
     def __exit__(self, exc_type, exc_value, traceback):
         self.close()
 
-
     def __init__(self, cache):
         self.analyser_cache = cache
         cache['countries'] = []
 
     def __init__(self, cache):
         self.analyser_cache = cache
         cache['countries'] = []
 
-
     def close(self):
         pass
 
     def close(self):
         pass
 
index fe65b69c4dff04d39ebb04ceb133a42bc2a21f82..79b76c60a62773638d8f75f5f1374f58de872c08 100644 (file)
@@ -2,18 +2,19 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for running the indexing.
 """
 import itertools
 import pytest
 # For a full list of authors see the git log.
 """
 Tests for running the indexing.
 """
 import itertools
 import pytest
-import pytest_asyncio
+import pytest_asyncio  # noqa
 
 from nominatim_db.indexer import indexer
 from nominatim_db.tokenizer import factory
 
 
 from nominatim_db.indexer import indexer
 from nominatim_db.tokenizer import factory
 
+
 class IndexerTestDB:
 
     def __init__(self, conn):
 class IndexerTestDB:
 
     def __init__(self, conn):
@@ -232,6 +233,7 @@ async def test_index_partial_with_30(test_db, threads, test_tokenizer):
                     SELECT count(*) FROM placex
                       WHERE indexed_status = 0 AND rank_address between 1 and 27""") == 0
 
                     SELECT count(*) FROM placex
                       WHERE indexed_status = 0 AND rank_address between 1 and 27""") == 0
 
+
 @pytest.mark.parametrize("threads", [1, 15])
 @pytest.mark.asyncio
 async def test_index_boundaries(test_db, threads, test_tokenizer):
 @pytest.mark.parametrize("threads", [1, 15])
 @pytest.mark.asyncio
 async def test_index_boundaries(test_db, threads, test_tokenizer):
index e8b4390f5fc38c4c6c55c5417f3cc36373a8dc7b..b26025a05a285cd6be0aa4fba2acdb8c27c7ba8e 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Legacy word table for testing with functions to prefil and test contents
 # For a full list of authors see the git log.
 """
 Legacy word table for testing with functions to prefil and test contents
@@ -10,6 +10,7 @@ of the table.
 """
 from nominatim_db.db.connection import execute_scalar
 
 """
 from nominatim_db.db.connection import execute_scalar
 
+
 class MockIcuWordTable:
     """ A word table for testing using legacy word table structure.
     """
 class MockIcuWordTable:
     """ A word table for testing using legacy word table structure.
     """
@@ -31,7 +32,6 @@ class MockIcuWordTable:
                         (word_id, word or word_token, word))
         self.conn.commit()
 
                         (word_id, word or word_token, word))
         self.conn.commit()
 
-
     def add_special(self, word_token, word, cls, typ, oper):
         with self.conn.cursor() as cur:
             cur.execute("""INSERT INTO word (word_token, type, word, info)
     def add_special(self, word_token, word, cls, typ, oper):
         with self.conn.cursor() as cur:
             cur.execute("""INSERT INTO word (word_token, type, word, info)
@@ -42,7 +42,6 @@ class MockIcuWordTable:
                         """, (word_token, word, cls, typ, oper))
         self.conn.commit()
 
                         """, (word_token, word, cls, typ, oper))
         self.conn.commit()
 
-
     def add_country(self, country_code, word_token):
         with self.conn.cursor() as cur:
             cur.execute("""INSERT INTO word (word_token, type, word)
     def add_country(self, country_code, word_token):
         with self.conn.cursor() as cur:
             cur.execute("""INSERT INTO word (word_token, type, word)
@@ -50,7 +49,6 @@ class MockIcuWordTable:
                         (word_token, country_code))
         self.conn.commit()
 
                         (word_token, country_code))
         self.conn.commit()
 
-
     def add_postcode(self, word_token, postcode):
         with self.conn.cursor() as cur:
             cur.execute("""INSERT INTO word (word_token, type, word)
     def add_postcode(self, word_token, postcode):
         with self.conn.cursor() as cur:
             cur.execute("""INSERT INTO word (word_token, type, word)
@@ -58,7 +56,6 @@ class MockIcuWordTable:
                         """, (word_token, postcode))
         self.conn.commit()
 
                         """, (word_token, postcode))
         self.conn.commit()
 
-
     def add_housenumber(self, word_id, word_tokens, word=None):
         with self.conn.cursor() as cur:
             if isinstance(word_tokens, str):
     def add_housenumber(self, word_id, word_tokens, word=None):
         with self.conn.cursor() as cur:
             if isinstance(word_tokens, str):
@@ -71,24 +68,21 @@ class MockIcuWordTable:
                     word = word_tokens[0]
                 for token in word_tokens:
                     cur.execute("""INSERT INTO word (word_id, word_token, type, word, info)
                     word = word_tokens[0]
                 for token in word_tokens:
                     cur.execute("""INSERT INTO word (word_id, word_token, type, word, info)
-                                      VALUES (%s, %s, 'H', %s, jsonb_build_object('lookup', %s::text))
+                                      VALUES (%s, %s, 'H', %s,
+                                              jsonb_build_object('lookup', %s::text))
                                 """, (word_id, token, word, word_tokens[0]))
 
         self.conn.commit()
 
                                 """, (word_id, token, word, word_tokens[0]))
 
         self.conn.commit()
 
-
     def count(self):
         return execute_scalar(self.conn, "SELECT count(*) FROM word")
 
     def count(self):
         return execute_scalar(self.conn, "SELECT count(*) FROM word")
 
-
     def count_special(self):
         return execute_scalar(self.conn, "SELECT count(*) FROM word WHERE type = 'S'")
 
     def count_special(self):
         return execute_scalar(self.conn, "SELECT count(*) FROM word WHERE type = 'S'")
 
-
     def count_housenumbers(self):
         return execute_scalar(self.conn, "SELECT count(*) FROM word WHERE type = 'H'")
 
     def count_housenumbers(self):
         return execute_scalar(self.conn, "SELECT count(*) FROM word WHERE type = 'H'")
 
-
     def get_special(self):
         with self.conn.cursor() as cur:
             cur.execute("SELECT word_token, info, word FROM word WHERE type = 'S'")
     def get_special(self):
         with self.conn.cursor() as cur:
             cur.execute("SELECT word_token, info, word FROM word WHERE type = 'S'")
@@ -97,7 +91,6 @@ class MockIcuWordTable:
             assert len(result) == cur.rowcount, "Word table has duplicates."
             return result
 
             assert len(result) == cur.rowcount, "Word table has duplicates."
             return result
 
-
     def get_country(self):
         with self.conn.cursor() as cur:
             cur.execute("SELECT word, word_token FROM word WHERE type = 'C'")
     def get_country(self):
         with self.conn.cursor() as cur:
             cur.execute("SELECT word, word_token FROM word WHERE type = 'C'")
@@ -105,15 +98,12 @@ class MockIcuWordTable:
             assert len(result) == cur.rowcount, "Word table has duplicates."
             return result
 
             assert len(result) == cur.rowcount, "Word table has duplicates."
             return result
 
-
     def get_postcodes(self):
         with self.conn.cursor() as cur:
             cur.execute("SELECT word FROM word WHERE type = 'P'")
             return set((row[0] for row in cur))
 
     def get_postcodes(self):
         with self.conn.cursor() as cur:
             cur.execute("SELECT word FROM word WHERE type = 'P'")
             return set((row[0] for row in cur))
 
-
     def get_partial_words(self):
         with self.conn.cursor() as cur:
             cur.execute("SELECT word_token, info FROM word WHERE type ='w'")
             return set(((row[0], row[1]['count']) for row in cur))
     def get_partial_words(self):
         with self.conn.cursor() as cur:
             cur.execute("SELECT word_token, info FROM word WHERE type ='w'")
             return set(((row[0], row[1]['count']) for row in cur))
-
index cde0b7bb58e8fdab6208ca6cef05d10c179535ff..fb7f4fa1d6d8e7e42c8b1ab2854f72e9d1f4ac88 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Custom mocks for testing.
 # For a full list of authors see the git log.
 """
 Custom mocks for testing.
@@ -11,8 +11,6 @@ import itertools
 
 from nominatim_db.db import properties
 
 
 from nominatim_db.db import properties
 
-# This must always point to the mock word table for the default tokenizer.
-from mock_icu_word_table import MockIcuWordTable as MockWordTable
 
 class MockPlacexTable:
     """ A placex table for testing.
 
 class MockPlacexTable:
     """ A placex table for testing.
@@ -58,7 +56,8 @@ class MockPlacexTable:
                                                type, name, admin_level, address,
                                                housenumber, rank_search,
                                                extratags, geometry, country_code)
                                                type, name, admin_level, address,
                                                housenumber, rank_search,
                                                extratags, geometry, country_code)
-                            VALUES(nextval('seq_place'), %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
+                            VALUES(nextval('seq_place'), %s, %s, %s, %s, %s, %s,
+                                   %s, %s, %s, %s, %s, %s)""",
                         (osm_type, osm_id or next(self.idseq), cls, typ, names,
                          admin_level, address, housenumber, rank_search,
                          extratags, 'SRID=4326;' + geom,
                         (osm_type, osm_id or next(self.idseq), cls, typ, names,
                          admin_level, address, housenumber, rank_search,
                          extratags, 'SRID=4326;' + geom,
@@ -72,13 +71,11 @@ class MockPropertyTable:
     def __init__(self, conn):
         self.conn = conn
 
     def __init__(self, conn):
         self.conn = conn
 
-
     def set(self, name, value):
         """ Set a property in the table to the given value.
         """
         properties.set_property(self.conn, name, value)
 
     def set(self, name, value):
         """ Set a property in the table to the given value.
         """
         properties.set_property(self.conn, name, value)
 
-
     def get(self, name):
         """ Set a property in the table to the given value.
         """
     def get(self, name):
         """ Set a property in the table to the given value.
         """
index 01fb162b8e78ae4b90b7ac6253ff43dd1212875d..2dd10c5631ad402431f5f0df7dd8af944a0748b6 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for the sanitizer that normalizes housenumbers.
 # For a full list of authors see the git log.
 """
 Tests for the sanitizer that normalizes housenumbers.
@@ -12,11 +12,12 @@ import pytest
 from nominatim_db.tokenizer.place_sanitizer import PlaceSanitizer
 from nominatim_db.data.place_info import PlaceInfo
 
 from nominatim_db.tokenizer.place_sanitizer import PlaceSanitizer
 from nominatim_db.data.place_info import PlaceInfo
 
+
 @pytest.fixture
 def sanitize(request, def_config):
     sanitizer_args = {'step': 'clean-housenumbers'}
     for mark in request.node.iter_markers(name="sanitizer_params"):
 @pytest.fixture
 def sanitize(request, def_config):
     sanitizer_args = {'step': 'clean-housenumbers'}
     for mark in request.node.iter_markers(name="sanitizer_params"):
-        sanitizer_args.update({k.replace('_', '-') : v for k,v in mark.kwargs.items()})
+        sanitizer_args.update({k.replace('_', '-'): v for k, v in mark.kwargs.items()})
 
     def _run(**kwargs):
         place = PlaceInfo({'address': kwargs})
 
     def _run(**kwargs):
         place = PlaceInfo({'address': kwargs})
index 70cc5256640b9918535367d986818b082f67f747..242e9301a9bf34094702f4e95ac559526acef424 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for the sanitizer that normalizes postcodes.
 # For a full list of authors see the git log.
 """
 Tests for the sanitizer that normalizes postcodes.
@@ -13,12 +13,13 @@ from nominatim_db.tokenizer.place_sanitizer import PlaceSanitizer
 from nominatim_db.data.place_info import PlaceInfo
 from nominatim_db.data import country_info
 
 from nominatim_db.data.place_info import PlaceInfo
 from nominatim_db.data import country_info
 
+
 @pytest.fixture
 def sanitize(def_config, request):
     country_info.setup_country_config(def_config)
     sanitizer_args = {'step': 'clean-postcodes'}
     for mark in request.node.iter_markers(name="sanitizer_params"):
 @pytest.fixture
 def sanitize(def_config, request):
     country_info.setup_country_config(def_config)
     sanitizer_args = {'step': 'clean-postcodes'}
     for mark in request.node.iter_markers(name="sanitizer_params"):
-        sanitizer_args.update({k.replace('_', '-') : v for k,v in mark.kwargs.items()})
+        sanitizer_args.update({k.replace('_', '-'): v for k, v in mark.kwargs.items()})
 
     def _run(country=None, **kwargs):
         pi = {'address': kwargs}
 
     def _run(country=None, **kwargs):
         pi = {'address': kwargs}
index 4badb57f7b25f48b90315ba5402ecacadf6560d2..d245f4dff17f716e0baa8f47ec1d8c1e1c7bf258 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for sanitizer that clean up TIGER tags.
 # For a full list of authors see the git log.
 """
 Tests for sanitizer that clean up TIGER tags.
@@ -12,16 +12,17 @@ import pytest
 from nominatim_db.tokenizer.place_sanitizer import PlaceSanitizer
 from nominatim_db.data.place_info import PlaceInfo
 
 from nominatim_db.tokenizer.place_sanitizer import PlaceSanitizer
 from nominatim_db.data.place_info import PlaceInfo
 
+
 class TestCleanTigerTags:
 
     @pytest.fixture(autouse=True)
     def setup_country(self, def_config):
         self.config = def_config
 
 class TestCleanTigerTags:
 
     @pytest.fixture(autouse=True)
     def setup_country(self, def_config):
         self.config = def_config
 
-
     def run_sanitizer_on(self, addr):
         place = PlaceInfo({'address': addr})
     def run_sanitizer_on(self, addr):
         place = PlaceInfo({'address': addr})
-        _, outaddr = PlaceSanitizer([{'step': 'clean-tiger-tags'}], self.config).process_names(place)
+        _, outaddr = PlaceSanitizer([{'step': 'clean-tiger-tags'}],
+                                    self.config).process_names(place)
 
         return sorted([(p.name, p.kind, p.suffix) for p in outaddr])
 
 
         return sorted([(p.name, p.kind, p.suffix) for p in outaddr])
 
@@ -31,13 +32,11 @@ class TestCleanTigerTags:
         assert self.run_sanitizer_on({'tiger:county': inname})\
             == [(outname, 'county', 'tiger')]
 
         assert self.run_sanitizer_on({'tiger:county': inname})\
             == [(outname, 'county', 'tiger')]
 
-
     @pytest.mark.parametrize('name', ('Hamilton', 'Big, Road', ''))
     def test_badly_formatted(self, name):
         assert self.run_sanitizer_on({'tiger:county': name})\
             == [(name, 'county', 'tiger')]
 
     @pytest.mark.parametrize('name', ('Hamilton', 'Big, Road', ''))
     def test_badly_formatted(self, name):
         assert self.run_sanitizer_on({'tiger:county': name})\
             == [(name, 'county', 'tiger')]
 
-
     def test_unmatched(self):
         assert self.run_sanitizer_on({'tiger:country': 'US'})\
             == [('US', 'tiger', 'country')]
     def test_unmatched(self):
         assert self.run_sanitizer_on({'tiger:country': 'US'})\
             == [('US', 'tiger', 'country')]
index f9688c0be14dad44eae47679f18169fe81de582c..9c8f2a90dea872f78737aea62451faaea25a98fe 100644 (file)
@@ -2,7 +2,7 @@
 #\r
 # This file is part of Nominatim. (https://nominatim.org)\r
 #\r
 #\r
 # This file is part of Nominatim. (https://nominatim.org)\r
 #\r
-# Copyright (C) 2024 by the Nominatim developer community.\r
+# Copyright (C) 2025 by the Nominatim developer community.\r
 # For a full list of authors see the git log.\r
 """\r
 Tests for the sanitizer that normalizes housenumbers.\r
 # For a full list of authors see the git log.\r
 """\r
 Tests for the sanitizer that normalizes housenumbers.\r
@@ -22,18 +22,15 @@ class TestWithDefault:
     def run_sanitizer_on(self, type, **kwargs):\r
 \r
         place = PlaceInfo({type: {k.replace('_', ':'): v for k, v in kwargs.items()},\r
     def run_sanitizer_on(self, type, **kwargs):\r
 \r
         place = PlaceInfo({type: {k.replace('_', ':'): v for k, v in kwargs.items()},\r
-                            'country_code': 'de', 'rank_address': 30})\r
+                          'country_code': 'de', 'rank_address': 30})\r
 \r
         sanitizer_args = {'step': 'delete-tags'}\r
 \r
         name, address = PlaceSanitizer([sanitizer_args],\r
 \r
         sanitizer_args = {'step': 'delete-tags'}\r
 \r
         name, address = PlaceSanitizer([sanitizer_args],\r
-                                    self.config).process_names(place)\r
-\r
-        return {\r
-                'name': sorted([(p.name, p.kind, p.suffix or '') for p in name]),\r
-                'address': sorted([(p.name, p.kind, p.suffix or '') for p in address])\r
-            }\r
+                                       self.config).process_names(place)\r
 \r
 \r
+        return {'name': sorted([(p.name, p.kind, p.suffix or '') for p in name]),\r
+                'address': sorted([(p.name, p.kind, p.suffix or '') for p in address])}\r
 \r
     def test_on_name(self):\r
         res = self.run_sanitizer_on('name', name='foo', ref='bar', ref_abc='baz')\r
 \r
     def test_on_name(self):\r
         res = self.run_sanitizer_on('name', name='foo', ref='bar', ref_abc='baz')\r
@@ -44,7 +41,7 @@ class TestWithDefault:
         res = self.run_sanitizer_on('address', name='foo', ref='bar', ref_abc='baz')\r
 \r
         assert res.get('address') == [('bar', 'ref', ''), ('baz', 'ref', 'abc'),\r
         res = self.run_sanitizer_on('address', name='foo', ref='bar', ref_abc='baz')\r
 \r
         assert res.get('address') == [('bar', 'ref', ''), ('baz', 'ref', 'abc'),\r
-                                        ('foo', 'name', '')]\r
+                                      ('foo', 'name', '')]\r
 \r
 \r
 class TestTypeField:\r
 \r
 \r
 class TestTypeField:\r
@@ -56,15 +53,13 @@ class TestTypeField:
     def run_sanitizer_on(self, type, **kwargs):\r
 \r
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},\r
     def run_sanitizer_on(self, type, **kwargs):\r
 \r
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},\r
-                            'country_code': 'de', 'rank_address': 30})\r
+                           'country_code': 'de', 'rank_address': 30})\r
 \r
 \r
-        sanitizer_args = {\r
-                        'step': 'delete-tags',\r
-                        'type': type,\r
-                    }\r
+        sanitizer_args = {'step': 'delete-tags',\r
+                          'type': type}\r
 \r
         name, _ = PlaceSanitizer([sanitizer_args],\r
 \r
         name, _ = PlaceSanitizer([sanitizer_args],\r
-                                    self.config).process_names(place)\r
+                                 self.config).process_names(place)\r
 \r
         return sorted([(p.name, p.kind, p.suffix or '') for p in name])\r
 \r
 \r
         return sorted([(p.name, p.kind, p.suffix or '') for p in name])\r
 \r
@@ -77,7 +72,8 @@ class TestTypeField:
         res = self.run_sanitizer_on('address', name='foo', ref='bar', ref_abc='baz')\r
 \r
         assert res == [('bar', 'ref', ''), ('baz', 'ref', 'abc'),\r
         res = self.run_sanitizer_on('address', name='foo', ref='bar', ref_abc='baz')\r
 \r
         assert res == [('bar', 'ref', ''), ('baz', 'ref', 'abc'),\r
-                        ('foo', 'name', '')]\r
+                       ('foo', 'name', '')]\r
+\r
 \r
 class TestFilterKind:\r
 \r
 \r
 class TestFilterKind:\r
 \r
@@ -88,15 +84,13 @@ class TestFilterKind:
     def run_sanitizer_on(self, filt, **kwargs):\r
 \r
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},\r
     def run_sanitizer_on(self, filt, **kwargs):\r
 \r
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},\r
-                            'country_code': 'de', 'rank_address': 30})\r
+                           'country_code': 'de', 'rank_address': 30})\r
 \r
 \r
-        sanitizer_args = {\r
-                        'step': 'delete-tags',\r
-                        'filter-kind': filt,\r
-                    }\r
+        sanitizer_args = {'step': 'delete-tags',\r
+                          'filter-kind': filt}\r
 \r
         name, _ = PlaceSanitizer([sanitizer_args],\r
 \r
         name, _ = PlaceSanitizer([sanitizer_args],\r
-                                    self.config).process_names(place)\r
+                                 self.config).process_names(place)\r
 \r
         return sorted([(p.name, p.kind, p.suffix or '') for p in name])\r
 \r
 \r
         return sorted([(p.name, p.kind, p.suffix or '') for p in name])\r
 \r
@@ -106,7 +100,6 @@ class TestFilterKind:
 \r
         assert res == [('bar', 'ref', 'abc'), ('foo', 'ref', '')]\r
 \r
 \r
         assert res == [('bar', 'ref', 'abc'), ('foo', 'ref', '')]\r
 \r
-\r
     def test_single_pattern(self):\r
         res = self.run_sanitizer_on(['.*name'],\r
                                     name_fr='foo', ref_fr='foo', namexx_fr='bar',\r
     def test_single_pattern(self):\r
         res = self.run_sanitizer_on(['.*name'],\r
                                     name_fr='foo', ref_fr='foo', namexx_fr='bar',\r
@@ -114,7 +107,6 @@ class TestFilterKind:
 \r
         assert res == [('bar', 'namexx', 'fr'), ('foo', 'ref', 'fr')]\r
 \r
 \r
         assert res == [('bar', 'namexx', 'fr'), ('foo', 'ref', 'fr')]\r
 \r
-\r
     def test_multiple_patterns(self):\r
         res = self.run_sanitizer_on(['.*name', 'ref'],\r
                                     name_fr='foo', ref_fr='foo', oldref_fr='foo',\r
     def test_multiple_patterns(self):\r
         res = self.run_sanitizer_on(['.*name', 'ref'],\r
                                     name_fr='foo', ref_fr='foo', oldref_fr='foo',\r
@@ -132,19 +124,16 @@ class TestRankAddress:
     def run_sanitizer_on(self, rank_addr, **kwargs):\r
 \r
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},\r
     def run_sanitizer_on(self, rank_addr, **kwargs):\r
 \r
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},\r
-                            'country_code': 'de', 'rank_address': 30})\r
+                           'country_code': 'de', 'rank_address': 30})\r
 \r
 \r
-        sanitizer_args = {\r
-                        'step': 'delete-tags',\r
-                        'rank_address': rank_addr\r
-                    }\r
+        sanitizer_args = {'step': 'delete-tags',\r
+                          'rank_address': rank_addr}\r
 \r
         name, _ = PlaceSanitizer([sanitizer_args],\r
 \r
         name, _ = PlaceSanitizer([sanitizer_args],\r
-                                    self.config).process_names(place)\r
+                                 self.config).process_names(place)\r
 \r
         return sorted([(p.name, p.kind, p.suffix or '') for p in name])\r
 \r
 \r
         return sorted([(p.name, p.kind, p.suffix or '') for p in name])\r
 \r
-\r
     def test_single_rank(self):\r
         res = self.run_sanitizer_on('30', name='foo', ref='bar')\r
 \r
     def test_single_rank(self):\r
         res = self.run_sanitizer_on('30', name='foo', ref='bar')\r
 \r
@@ -185,33 +174,29 @@ class TestSuffix:
     def run_sanitizer_on(self, suffix, **kwargs):\r
 \r
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},\r
     def run_sanitizer_on(self, suffix, **kwargs):\r
 \r
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},\r
-                            'country_code': 'de', 'rank_address': 30})\r
+                           'country_code': 'de', 'rank_address': 30})\r
 \r
 \r
-        sanitizer_args = {\r
-                        'step': 'delete-tags',\r
-                        'suffix': suffix,\r
-                    }\r
+        sanitizer_args = {'step': 'delete-tags',\r
+                          'suffix': suffix}\r
 \r
         name, _ = PlaceSanitizer([sanitizer_args],\r
 \r
         name, _ = PlaceSanitizer([sanitizer_args],\r
-                                    self.config).process_names(place)\r
+                                 self.config).process_names(place)\r
 \r
         return sorted([(p.name, p.kind, p.suffix or '') for p in name])\r
 \r
 \r
         return sorted([(p.name, p.kind, p.suffix or '') for p in name])\r
 \r
-\r
     def test_single_suffix(self):\r
         res = self.run_sanitizer_on('abc', name='foo', name_abc='foo',\r
     def test_single_suffix(self):\r
         res = self.run_sanitizer_on('abc', name='foo', name_abc='foo',\r
-                                 name_pqr='bar', ref='bar', ref_abc='baz')\r
+                                    name_pqr='bar', ref='bar', ref_abc='baz')\r
 \r
         assert res == [('bar', 'name', 'pqr'), ('bar', 'ref', ''), ('foo', 'name', '')]\r
 \r
     def test_multiple_suffix(self):\r
         res = self.run_sanitizer_on(['abc.*', 'pqr'], name='foo', name_abcxx='foo',\r
 \r
         assert res == [('bar', 'name', 'pqr'), ('bar', 'ref', ''), ('foo', 'name', '')]\r
 \r
     def test_multiple_suffix(self):\r
         res = self.run_sanitizer_on(['abc.*', 'pqr'], name='foo', name_abcxx='foo',\r
-                                 ref_pqr='bar', name_pqrxx='baz')\r
+                                    ref_pqr='bar', name_pqrxx='baz')\r
 \r
         assert res == [('baz', 'name', 'pqrxx'), ('foo', 'name', '')]\r
 \r
 \r
 \r
         assert res == [('baz', 'name', 'pqrxx'), ('foo', 'name', '')]\r
 \r
 \r
-\r
 class TestCountryCodes:\r
 \r
     @pytest.fixture(autouse=True)\r
 class TestCountryCodes:\r
 \r
     @pytest.fixture(autouse=True)\r
@@ -221,19 +206,16 @@ class TestCountryCodes:
     def run_sanitizer_on(self, country_code, **kwargs):\r
 \r
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},\r
     def run_sanitizer_on(self, country_code, **kwargs):\r
 \r
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},\r
-                            'country_code': 'de', 'rank_address': 30})\r
+                           'country_code': 'de', 'rank_address': 30})\r
 \r
 \r
-        sanitizer_args = {\r
-                        'step': 'delete-tags',\r
-                        'country_code': country_code,\r
-                    }\r
+        sanitizer_args = {'step': 'delete-tags',\r
+                          'country_code': country_code}\r
 \r
         name, _ = PlaceSanitizer([sanitizer_args],\r
 \r
         name, _ = PlaceSanitizer([sanitizer_args],\r
-                                    self.config).process_names(place)\r
+                                 self.config).process_names(place)\r
 \r
         return sorted([(p.name, p.kind) for p in name])\r
 \r
 \r
         return sorted([(p.name, p.kind) for p in name])\r
 \r
-\r
     def test_single_country_code_pass(self):\r
         res = self.run_sanitizer_on('de', name='foo', ref='bar')\r
 \r
     def test_single_country_code_pass(self):\r
         res = self.run_sanitizer_on('de', name='foo', ref='bar')\r
 \r
@@ -259,6 +241,7 @@ class TestCountryCodes:
 \r
         assert res == [('bar', 'ref'), ('foo', 'name')]\r
 \r
 \r
         assert res == [('bar', 'ref'), ('foo', 'name')]\r
 \r
+\r
 class TestAllParameters:\r
 \r
     @pytest.fixture(autouse=True)\r
 class TestAllParameters:\r
 \r
     @pytest.fixture(autouse=True)\r
@@ -268,7 +251,7 @@ class TestAllParameters:
     def run_sanitizer_on(self, country_code, rank_addr, suffix, **kwargs):\r
 \r
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},\r
     def run_sanitizer_on(self, country_code, rank_addr, suffix, **kwargs):\r
 \r
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},\r
-                            'country_code': 'de', 'rank_address': 30})\r
+                           'country_code': 'de', 'rank_address': 30})\r
 \r
         sanitizer_args = {\r
                         'step': 'delete-tags',\r
 \r
         sanitizer_args = {\r
                         'step': 'delete-tags',\r
@@ -281,11 +264,10 @@ class TestAllParameters:
                     }\r
 \r
         name, _ = PlaceSanitizer([sanitizer_args],\r
                     }\r
 \r
         name, _ = PlaceSanitizer([sanitizer_args],\r
-                                    self.config).process_names(place)\r
+                                 self.config).process_names(place)\r
 \r
         return sorted([(p.name, p.kind, p.suffix or '') for p in name])\r
 \r
 \r
         return sorted([(p.name, p.kind, p.suffix or '') for p in name])\r
 \r
-\r
     def test_string_arguments_pass(self):\r
         res = self.run_sanitizer_on('de', '25-30', r'[\s\S]*',\r
                                     name='foo', ref='foo', name_abc='bar', ref_abc='baz')\r
     def test_string_arguments_pass(self):\r
         res = self.run_sanitizer_on('de', '25-30', r'[\s\S]*',\r
                                     name='foo', ref='foo', name_abc='bar', ref_abc='baz')\r
index 0497f21df70e9907348730b21ce22c5700c984d3..5dd2ec034ac441fbc512ea49e4e506337a8e3aee 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for sanitizer configuration helper functions.
 # For a full list of authors see the git log.
 """
 Tests for sanitizer configuration helper functions.
@@ -12,6 +12,7 @@ import pytest
 from nominatim_db.errors import UsageError
 from nominatim_db.tokenizer.sanitizers.config import SanitizerConfig
 
 from nominatim_db.errors import UsageError
 from nominatim_db.tokenizer.sanitizers.config import SanitizerConfig
 
+
 def test_string_list_default_empty():
     assert SanitizerConfig().get_string_list('op') == []
 
 def test_string_list_default_empty():
     assert SanitizerConfig().get_string_list('op') == []
 
@@ -53,7 +54,7 @@ def test_create_split_regex_no_params_unsplit(inp):
                                       ('ying;;yang', ['ying', 'yang']),
                                       (';a; ;c;d,', ['', 'a', '', 'c', 'd', '']),
                                       ('1,  3  ,5', ['1', '3', '5'])
                                       ('ying;;yang', ['ying', 'yang']),
                                       (';a; ;c;d,', ['', 'a', '', 'c', 'd', '']),
                                       ('1,  3  ,5', ['1', '3', '5'])
-                                     ])
+                                      ])
 def test_create_split_regex_no_params_split(inp, outp):
     regex = SanitizerConfig().get_delimiter()
 
 def test_create_split_regex_no_params_split(inp, outp):
     regex = SanitizerConfig().get_delimiter()
 
@@ -70,7 +71,7 @@ def test_create_split_regex_custom(delimiter):
 
 def test_create_split_regex_empty_delimiter():
     with pytest.raises(UsageError):
 
 def test_create_split_regex_empty_delimiter():
     with pytest.raises(UsageError):
-        regex = SanitizerConfig({'delimiters': ''}).get_delimiter()
+        SanitizerConfig({'delimiters': ''}).get_delimiter()
 
 
 @pytest.mark.parametrize('inp', ('name', 'name:de', 'na\\me', '.*', ''))
 
 
 @pytest.mark.parametrize('inp', ('name', 'name:de', 'na\\me', '.*', ''))
@@ -96,12 +97,12 @@ def test_create_name_filter_no_param_default_fail_all(inp):
 
 def test_create_name_filter_no_param_default_invalid_string():
     with pytest.raises(ValueError):
 
 def test_create_name_filter_no_param_default_invalid_string():
     with pytest.raises(ValueError):
-        filt = SanitizerConfig().get_filter('name', 'abc')
+        SanitizerConfig().get_filter('name', 'abc')
 
 
 def test_create_name_filter_no_param_default_empty_list():
     with pytest.raises(ValueError):
 
 
 def test_create_name_filter_no_param_default_empty_list():
     with pytest.raises(ValueError):
-        filt = SanitizerConfig().get_filter('name', [])
+        SanitizerConfig().get_filter('name', [])
 
 
 @pytest.mark.parametrize('kind', ('de', 'name:de', 'ende'))
 
 
 @pytest.mark.parametrize('kind', ('de', 'name:de', 'ende'))
@@ -121,7 +122,7 @@ def test_create_kind_filter_default_negetive(kind):
 @pytest.mark.parametrize('kind', ('lang', 'lang:de', 'langxx'))
 def test_create_kind_filter_custom_regex_positive(kind):
     filt = SanitizerConfig({'filter-kind': 'lang.*'}
 @pytest.mark.parametrize('kind', ('lang', 'lang:de', 'langxx'))
 def test_create_kind_filter_custom_regex_positive(kind):
     filt = SanitizerConfig({'filter-kind': 'lang.*'}
-    ).get_filter('filter-kind', ['.*fr'])
+                           ).get_filter('filter-kind', ['.*fr'])
 
     assert filt(kind)
 
 
     assert filt(kind)
 
@@ -136,7 +137,7 @@ def test_create_kind_filter_custom_regex_negative(kind):
 @pytest.mark.parametrize('kind', ('name', 'fr', 'name:fr', 'frfr', '34'))
 def test_create_kind_filter_many_positive(kind):
     filt = SanitizerConfig({'filter-kind': ['.*fr', 'name', r'\d+']}
 @pytest.mark.parametrize('kind', ('name', 'fr', 'name:fr', 'frfr', '34'))
 def test_create_kind_filter_many_positive(kind):
     filt = SanitizerConfig({'filter-kind': ['.*fr', 'name', r'\d+']}
-    ).get_filter('filter-kind')
+                           ).get_filter('filter-kind')
 
     assert filt(kind)
 
 
     assert filt(kind)
 
@@ -144,6 +145,6 @@ def test_create_kind_filter_many_positive(kind):
 @pytest.mark.parametrize('kind', ('name:de', 'fridge', 'a34', '.*', '\\'))
 def test_create_kind_filter_many_negative(kind):
     filt = SanitizerConfig({'filter-kind': ['.*fr', 'name', r'\d+']}
 @pytest.mark.parametrize('kind', ('name:de', 'fridge', 'a34', '.*', '\\'))
 def test_create_kind_filter_many_negative(kind):
     filt = SanitizerConfig({'filter-kind': ['.*fr', 'name', r'\d+']}
-    ).get_filter('filter-kind')
+                           ).get_filter('filter-kind')
 
     assert not filt(kind)
 
     assert not filt(kind)
index fbfd72da514e974b2523c7fc869ed3625af44f7f..ec4869b3495c3f56127a8e22c6f1db3050ada38d 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for the sanitizer that splits multivalue lists.
 # For a full list of authors see the git log.
 """
 Tests for the sanitizer that splits multivalue lists.
@@ -14,20 +14,19 @@ from nominatim_db.data.place_info import PlaceInfo
 
 from nominatim_db.errors import UsageError
 
 
 from nominatim_db.errors import UsageError
 
+
 class TestSplitName:
 
     @pytest.fixture(autouse=True)
     def setup_country(self, def_config):
         self.config = def_config
 
 class TestSplitName:
 
     @pytest.fixture(autouse=True)
     def setup_country(self, def_config):
         self.config = def_config
 
-
     def run_sanitizer_on(self, **kwargs):
         place = PlaceInfo({'name': kwargs})
         name, _ = PlaceSanitizer([{'step': 'split-name-list'}], self.config).process_names(place)
 
         return sorted([(p.name, p.kind, p.suffix) for p in name])
 
     def run_sanitizer_on(self, **kwargs):
         place = PlaceInfo({'name': kwargs})
         name, _ = PlaceSanitizer([{'step': 'split-name-list'}], self.config).process_names(place)
 
         return sorted([(p.name, p.kind, p.suffix) for p in name])
 
-
     def sanitize_with_delimiter(self, delimiter, name):
         place = PlaceInfo({'name': {'name': name}})
         san = PlaceSanitizer([{'step': 'split-name-list', 'delimiters': delimiter}],
     def sanitize_with_delimiter(self, delimiter, name):
         place = PlaceInfo({'name': {'name': name}})
         san = PlaceSanitizer([{'step': 'split-name-list', 'delimiters': delimiter}],
@@ -36,12 +35,10 @@ class TestSplitName:
 
         return sorted([p.name for p in name])
 
 
         return sorted([p.name for p in name])
 
-
     def test_simple(self):
         assert self.run_sanitizer_on(name='ABC') == [('ABC', 'name', None)]
         assert self.run_sanitizer_on(name='') == [('', 'name', None)]
 
     def test_simple(self):
         assert self.run_sanitizer_on(name='ABC') == [('ABC', 'name', None)]
         assert self.run_sanitizer_on(name='') == [('', 'name', None)]
 
-
     def test_splits(self):
         assert self.run_sanitizer_on(name='A;B;C') == [('A', 'name', None),
                                                        ('B', 'name', None),
     def test_splits(self):
         assert self.run_sanitizer_on(name='A;B;C') == [('A', 'name', None),
                                                        ('B', 'name', None),
@@ -49,7 +46,6 @@ class TestSplitName:
         assert self.run_sanitizer_on(short_name=' House, boat ') == [('House', 'short_name', None),
                                                                      ('boat', 'short_name', None)]
 
         assert self.run_sanitizer_on(short_name=' House, boat ') == [('House', 'short_name', None),
                                                                      ('boat', 'short_name', None)]
 
-
     def test_empty_fields(self):
         assert self.run_sanitizer_on(name='A;;B') == [('A', 'name', None),
                                                       ('B', 'name', None)]
     def test_empty_fields(self):
         assert self.run_sanitizer_on(name='A;;B') == [('A', 'name', None),
                                                       ('B', 'name', None)]
@@ -58,14 +54,12 @@ class TestSplitName:
         assert self.run_sanitizer_on(name=' ;B') == [('B', 'name', None)]
         assert self.run_sanitizer_on(name='B,') == [('B', 'name', None)]
 
         assert self.run_sanitizer_on(name=' ;B') == [('B', 'name', None)]
         assert self.run_sanitizer_on(name='B,') == [('B', 'name', None)]
 
-
     def test_custom_delimiters(self):
         assert self.sanitize_with_delimiter(':', '12:45,3') == ['12', '45,3']
         assert self.sanitize_with_delimiter('\\', 'a;\\b!#@ \\') == ['a;', 'b!#@']
         assert self.sanitize_with_delimiter('[]', 'foo[to]be') == ['be', 'foo', 'to']
         assert self.sanitize_with_delimiter(' ', 'morning  sun') == ['morning', 'sun']
 
     def test_custom_delimiters(self):
         assert self.sanitize_with_delimiter(':', '12:45,3') == ['12', '45,3']
         assert self.sanitize_with_delimiter('\\', 'a;\\b!#@ \\') == ['a;', 'b!#@']
         assert self.sanitize_with_delimiter('[]', 'foo[to]be') == ['be', 'foo', 'to']
         assert self.sanitize_with_delimiter(' ', 'morning  sun') == ['morning', 'sun']
 
-
     def test_empty_delimiter_set(self):
         with pytest.raises(UsageError):
             self.sanitize_with_delimiter('', 'abc')
     def test_empty_delimiter_set(self):
         with pytest.raises(UsageError):
             self.sanitize_with_delimiter('', 'abc')
index 6a4cffcf3039d564b431bc0128ddf6f61697d416..6e891f9eb0ef29f27b64ca512657e3baf5b46f5e 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for the sanitizer that handles braced suffixes.
 # For a full list of authors see the git log.
 """
 Tests for the sanitizer that handles braced suffixes.
@@ -12,6 +12,7 @@ import pytest
 from nominatim_db.tokenizer.place_sanitizer import PlaceSanitizer
 from nominatim_db.data.place_info import PlaceInfo
 
 from nominatim_db.tokenizer.place_sanitizer import PlaceSanitizer
 from nominatim_db.data.place_info import PlaceInfo
 
+
 class TestStripBrace:
 
     @pytest.fixture(autouse=True)
 class TestStripBrace:
 
     @pytest.fixture(autouse=True)
@@ -24,23 +25,19 @@ class TestStripBrace:
 
         return sorted([(p.name, p.kind, p.suffix) for p in name])
 
 
         return sorted([(p.name, p.kind, p.suffix) for p in name])
 
-
     def test_no_braces(self):
         assert self.run_sanitizer_on(name='foo', ref='23') == [('23', 'ref', None),
                                                                ('foo', 'name', None)]
 
     def test_no_braces(self):
         assert self.run_sanitizer_on(name='foo', ref='23') == [('23', 'ref', None),
                                                                ('foo', 'name', None)]
 
-
     def test_simple_braces(self):
     def test_simple_braces(self):
-        assert self.run_sanitizer_on(name='Halle (Saale)', ref='3')\
-          == [('3', 'ref', None), ('Halle', 'name', None), ('Halle (Saale)', 'name', None)]
-        assert self.run_sanitizer_on(name='ack ( bar')\
-          == [('ack', 'name', None), ('ack ( bar', 'name', None)]
-
+        assert self.run_sanitizer_on(name='Halle (Saale)', ref='3') \
+            == [('3', 'ref', None), ('Halle', 'name', None), ('Halle (Saale)', 'name', None)]
+        assert self.run_sanitizer_on(name='ack ( bar') \
+            == [('ack', 'name', None), ('ack ( bar', 'name', None)]
 
     def test_only_braces(self):
         assert self.run_sanitizer_on(name='(maybe)') == [('(maybe)', 'name', None)]
 
 
     def test_only_braces(self):
         assert self.run_sanitizer_on(name='(maybe)') == [('(maybe)', 'name', None)]
 
-
     def test_double_braces(self):
         assert self.run_sanitizer_on(name='a((b))') == [('a', 'name', None),
                                                         ('a((b))', 'name', None)]
     def test_double_braces(self):
         assert self.run_sanitizer_on(name='a((b))') == [('a', 'name', None),
                                                         ('a((b))', 'name', None)]
index 2022e41002e1b58ffd4d7b1f4ce1447ee33ab4dd..8f1d05401f2f7b1382c11606dd04047008c2b115 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for the sanitizer that enables language-dependent analyzers.
 # For a full list of authors see the git log.
 """
 Tests for the sanitizer that enables language-dependent analyzers.
@@ -13,13 +13,13 @@ from nominatim_db.data.place_info import PlaceInfo
 from nominatim_db.tokenizer.place_sanitizer import PlaceSanitizer
 from nominatim_db.data.country_info import setup_country_config
 
 from nominatim_db.tokenizer.place_sanitizer import PlaceSanitizer
 from nominatim_db.data.country_info import setup_country_config
 
+
 class TestWithDefaults:
 
     @pytest.fixture(autouse=True)
     def setup_country(self, def_config):
         self.config = def_config
 
 class TestWithDefaults:
 
     @pytest.fixture(autouse=True)
     def setup_country(self, def_config):
         self.config = def_config
 
-
     def run_sanitizer_on(self, country, **kwargs):
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},
                            'country_code': country})
     def run_sanitizer_on(self, country, **kwargs):
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},
                            'country_code': country})
@@ -28,19 +28,16 @@ class TestWithDefaults:
 
         return sorted([(p.name, p.kind, p.suffix, p.attr) for p in name])
 
 
         return sorted([(p.name, p.kind, p.suffix, p.attr) for p in name])
 
-
     def test_no_names(self):
         assert self.run_sanitizer_on('de') == []
 
     def test_no_names(self):
         assert self.run_sanitizer_on('de') == []
 
-
     def test_simple(self):
     def test_simple(self):
-        res = self.run_sanitizer_on('fr', name='Foo',name_de='Zoo', ref_abc='M')
+        res = self.run_sanitizer_on('fr', name='Foo', name_de='Zoo', ref_abc='M')
 
         assert res == [('Foo', 'name', None, {}),
                        ('M', 'ref', 'abc', {'analyzer': 'abc'}),
                        ('Zoo', 'name', 'de', {'analyzer': 'de'})]
 
 
         assert res == [('Foo', 'name', None, {}),
                        ('M', 'ref', 'abc', {'analyzer': 'abc'}),
                        ('Zoo', 'name', 'de', {'analyzer': 'de'})]
 
-
     @pytest.mark.parametrize('suffix', ['DE', 'asbc'])
     def test_illegal_suffix(self, suffix):
         assert self.run_sanitizer_on('fr', **{'name_' + suffix: 'Foo'}) \
     @pytest.mark.parametrize('suffix', ['DE', 'asbc'])
     def test_illegal_suffix(self, suffix):
         assert self.run_sanitizer_on('fr', **{'name_' + suffix: 'Foo'}) \
@@ -53,7 +50,6 @@ class TestFilterKind:
     def setup_country(self, def_config):
         self.config = def_config
 
     def setup_country(self, def_config):
         self.config = def_config
 
-
     def run_sanitizer_on(self, filt, **kwargs):
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},
                            'country_code': 'de'})
     def run_sanitizer_on(self, filt, **kwargs):
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},
                            'country_code': 'de'})
@@ -63,17 +59,15 @@ class TestFilterKind:
 
         return sorted([(p.name, p.kind, p.suffix, p.attr) for p in name])
 
 
         return sorted([(p.name, p.kind, p.suffix, p.attr) for p in name])
 
-
     def test_single_exact_name(self):
         res = self.run_sanitizer_on(['name'], name_fr='A', ref_fr='12',
     def test_single_exact_name(self):
         res = self.run_sanitizer_on(['name'], name_fr='A', ref_fr='12',
-                                              shortname_fr='C', name='D')
+                                    shortname_fr='C', name='D')
 
         assert res == [('12', 'ref',  'fr', {}),
                        ('A',  'name', 'fr', {'analyzer': 'fr'}),
                        ('C',  'shortname', 'fr', {}),
                        ('D',  'name', None, {})]
 
 
         assert res == [('12', 'ref',  'fr', {}),
                        ('A',  'name', 'fr', {'analyzer': 'fr'}),
                        ('C',  'shortname', 'fr', {}),
                        ('D',  'name', None, {})]
 
-
     def test_single_pattern(self):
         res = self.run_sanitizer_on(['.*name'],
                                     name_fr='A', ref_fr='12', namexx_fr='B',
     def test_single_pattern(self):
         res = self.run_sanitizer_on(['.*name'],
                                     name_fr='A', ref_fr='12', namexx_fr='B',
@@ -85,7 +79,6 @@ class TestFilterKind:
                        ('C',  'shortname', 'fr', {'analyzer': 'fr'}),
                        ('D',  'name', None, {})]
 
                        ('C',  'shortname', 'fr', {'analyzer': 'fr'}),
                        ('D',  'name', None, {})]
 
-
     def test_multiple_patterns(self):
         res = self.run_sanitizer_on(['.*name', 'ref'],
                                     name_fr='A', ref_fr='12', oldref_fr='X',
     def test_multiple_patterns(self):
         res = self.run_sanitizer_on(['.*name', 'ref'],
                                     name_fr='A', ref_fr='12', oldref_fr='X',
@@ -106,7 +99,6 @@ class TestDefaultCountry:
         setup_country_config(def_config)
         self.config = def_config
 
         setup_country_config(def_config)
         self.config = def_config
 
-
     def run_sanitizer_append(self, mode,  country, **kwargs):
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},
                            'country_code': country})
     def run_sanitizer_append(self, mode,  country, **kwargs):
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},
                            'country_code': country})
@@ -122,7 +114,6 @@ class TestDefaultCountry:
 
         return sorted([(p.name, p.attr.get('analyzer', '')) for p in name])
 
 
         return sorted([(p.name, p.attr.get('analyzer', '')) for p in name])
 
-
     def run_sanitizer_replace(self, mode,  country, **kwargs):
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},
                            'country_code': country})
     def run_sanitizer_replace(self, mode,  country, **kwargs):
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},
                            'country_code': country})
@@ -138,7 +129,6 @@ class TestDefaultCountry:
 
         return sorted([(p.name, p.attr.get('analyzer', '')) for p in name])
 
 
         return sorted([(p.name, p.attr.get('analyzer', '')) for p in name])
 
-
     def test_missing_country(self):
         place = PlaceInfo({'name': {'name': 'something'}})
         name, _ = PlaceSanitizer([{'step': 'tag-analyzer-by-language',
     def test_missing_country(self):
         place = PlaceInfo({'name': {'name': 'something'}})
         name, _ = PlaceSanitizer([{'step': 'tag-analyzer-by-language',
@@ -151,59 +141,50 @@ class TestDefaultCountry:
         assert name[0].suffix is None
         assert 'analyzer' not in name[0].attr
 
         assert name[0].suffix is None
         assert 'analyzer' not in name[0].attr
 
-
     def test_mono_unknown_country(self):
         expect = [('XX', '')]
 
         assert self.run_sanitizer_replace('mono', 'xx', name='XX') == expect
         assert self.run_sanitizer_append('mono', 'xx', name='XX') == expect
 
     def test_mono_unknown_country(self):
         expect = [('XX', '')]
 
         assert self.run_sanitizer_replace('mono', 'xx', name='XX') == expect
         assert self.run_sanitizer_append('mono', 'xx', name='XX') == expect
 
-
     def test_mono_monoling_replace(self):
         res = self.run_sanitizer_replace('mono', 'de', name='Foo')
 
         assert res == [('Foo', 'de')]
 
     def test_mono_monoling_replace(self):
         res = self.run_sanitizer_replace('mono', 'de', name='Foo')
 
         assert res == [('Foo', 'de')]
 
-
     def test_mono_monoling_append(self):
         res = self.run_sanitizer_append('mono', 'de', name='Foo')
 
         assert res == [('Foo', ''), ('Foo', 'de')]
 
     def test_mono_monoling_append(self):
         res = self.run_sanitizer_append('mono', 'de', name='Foo')
 
         assert res == [('Foo', ''), ('Foo', 'de')]
 
-
     def test_mono_multiling(self):
         expect = [('XX', '')]
 
         assert self.run_sanitizer_replace('mono', 'ch', name='XX') == expect
         assert self.run_sanitizer_append('mono', 'ch', name='XX') == expect
 
     def test_mono_multiling(self):
         expect = [('XX', '')]
 
         assert self.run_sanitizer_replace('mono', 'ch', name='XX') == expect
         assert self.run_sanitizer_append('mono', 'ch', name='XX') == expect
 
-
     def test_all_unknown_country(self):
         expect = [('XX', '')]
 
         assert self.run_sanitizer_replace('all', 'xx', name='XX') == expect
         assert self.run_sanitizer_append('all', 'xx', name='XX') == expect
 
     def test_all_unknown_country(self):
         expect = [('XX', '')]
 
         assert self.run_sanitizer_replace('all', 'xx', name='XX') == expect
         assert self.run_sanitizer_append('all', 'xx', name='XX') == expect
 
-
     def test_all_monoling_replace(self):
         res = self.run_sanitizer_replace('all', 'de', name='Foo')
 
         assert res == [('Foo', 'de')]
 
     def test_all_monoling_replace(self):
         res = self.run_sanitizer_replace('all', 'de', name='Foo')
 
         assert res == [('Foo', 'de')]
 
-
     def test_all_monoling_append(self):
         res = self.run_sanitizer_append('all', 'de', name='Foo')
 
         assert res == [('Foo', ''), ('Foo', 'de')]
 
     def test_all_monoling_append(self):
         res = self.run_sanitizer_append('all', 'de', name='Foo')
 
         assert res == [('Foo', ''), ('Foo', 'de')]
 
-
     def test_all_multiling_append(self):
         res = self.run_sanitizer_append('all', 'ch', name='XX')
 
         assert res == [('XX', ''),
                        ('XX', 'de'), ('XX', 'fr'), ('XX', 'it'), ('XX', 'rm')]
 
     def test_all_multiling_append(self):
         res = self.run_sanitizer_append('all', 'ch', name='XX')
 
         assert res == [('XX', ''),
                        ('XX', 'de'), ('XX', 'fr'), ('XX', 'it'), ('XX', 'rm')]
 
-
     def test_all_multiling_replace(self):
         res = self.run_sanitizer_replace('all', 'ch', name='XX')
 
     def test_all_multiling_replace(self):
         res = self.run_sanitizer_replace('all', 'ch', name='XX')
 
@@ -216,7 +197,6 @@ class TestCountryWithWhitelist:
     def setup_country(self, def_config):
         self.config = def_config
 
     def setup_country(self, def_config):
         self.config = def_config
 
-
     def run_sanitizer_on(self, mode,  country, **kwargs):
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},
                            'country_code': country})
     def run_sanitizer_on(self, mode,  country, **kwargs):
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},
                            'country_code': country})
@@ -233,21 +213,17 @@ class TestCountryWithWhitelist:
 
         return sorted([(p.name, p.attr.get('analyzer', '')) for p in name])
 
 
         return sorted([(p.name, p.attr.get('analyzer', '')) for p in name])
 
-
     def test_mono_monoling(self):
         assert self.run_sanitizer_on('mono', 'de', name='Foo') == [('Foo', 'de')]
         assert self.run_sanitizer_on('mono', 'pt', name='Foo') == [('Foo', '')]
 
     def test_mono_monoling(self):
         assert self.run_sanitizer_on('mono', 'de', name='Foo') == [('Foo', 'de')]
         assert self.run_sanitizer_on('mono', 'pt', name='Foo') == [('Foo', '')]
 
-
     def test_mono_multiling(self):
         assert self.run_sanitizer_on('mono', 'ca', name='Foo') == [('Foo', '')]
 
     def test_mono_multiling(self):
         assert self.run_sanitizer_on('mono', 'ca', name='Foo') == [('Foo', '')]
 
-
     def test_all_monoling(self):
         assert self.run_sanitizer_on('all', 'de', name='Foo') == [('Foo', 'de')]
         assert self.run_sanitizer_on('all', 'pt', name='Foo') == [('Foo', '')]
 
     def test_all_monoling(self):
         assert self.run_sanitizer_on('all', 'de', name='Foo') == [('Foo', 'de')]
         assert self.run_sanitizer_on('all', 'pt', name='Foo') == [('Foo', '')]
 
-
     def test_all_multiling(self):
         assert self.run_sanitizer_on('all', 'ca', name='Foo') == [('Foo', 'fr')]
         assert self.run_sanitizer_on('all', 'ch', name='Foo') \
     def test_all_multiling(self):
         assert self.run_sanitizer_on('all', 'ca', name='Foo') == [('Foo', 'fr')]
         assert self.run_sanitizer_on('all', 'ch', name='Foo') \
@@ -260,7 +236,6 @@ class TestWhiteList:
     def setup_country(self, def_config):
         self.config = def_config
 
     def setup_country(self, def_config):
         self.config = def_config
 
-
     def run_sanitizer_on(self, whitelist, **kwargs):
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()}})
         name, _ = PlaceSanitizer([{'step': 'tag-analyzer-by-language',
     def run_sanitizer_on(self, whitelist, **kwargs):
         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()}})
         name, _ = PlaceSanitizer([{'step': 'tag-analyzer-by-language',
@@ -275,14 +250,11 @@ class TestWhiteList:
 
         return sorted([(p.name, p.attr.get('analyzer', '')) for p in name])
 
 
         return sorted([(p.name, p.attr.get('analyzer', '')) for p in name])
 
-
     def test_in_whitelist(self):
         assert self.run_sanitizer_on(['de', 'xx'], ref_xx='123') == [('123', 'xx')]
 
     def test_in_whitelist(self):
         assert self.run_sanitizer_on(['de', 'xx'], ref_xx='123') == [('123', 'xx')]
 
-
     def test_not_in_whitelist(self):
         assert self.run_sanitizer_on(['de', 'xx'], ref_yy='123') == [('123', '')]
 
     def test_not_in_whitelist(self):
         assert self.run_sanitizer_on(['de', 'xx'], ref_yy='123') == [('123', '')]
 
-
     def test_empty_whitelist(self):
         assert self.run_sanitizer_on([], ref_yy='123') == [('123', '')]
     def test_empty_whitelist(self):
         assert self.run_sanitizer_on([], ref_yy='123') == [('123', '')]
index 08edbb564462a1ea9556b14616586220b2f748f0..6db7a3c35329c3b241f9a5a85c2e392d3cdc07c0 100644 (file)
@@ -2,86 +2,86 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 # For a full list of authors see the git log.
-from typing import Mapping, Optional, List
 import pytest
 
 from nominatim_db.data.place_info import PlaceInfo
 import pytest
 
 from nominatim_db.data.place_info import PlaceInfo
-from nominatim_db.data.place_name import PlaceName
 from nominatim_db.tokenizer.place_sanitizer import PlaceSanitizer
 
 from nominatim_db.tokenizer.place_sanitizer import PlaceSanitizer
 
+
 class TestTagJapanese:
     @pytest.fixture(autouse=True)
     def setup_country(self, def_config):
         self.config = def_config
 
 class TestTagJapanese:
     @pytest.fixture(autouse=True)
     def setup_country(self, def_config):
         self.config = def_config
 
-    def run_sanitizer_on(self,type, **kwargs):
+    def run_sanitizer_on(self, type, **kwargs):
         place = PlaceInfo({
             'address': kwargs,
             'country_code': 'jp'
         })
         sanitizer_args = {'step': 'tag-japanese'}
         _, address = PlaceSanitizer([sanitizer_args], self.config).process_names(place)
         place = PlaceInfo({
             'address': kwargs,
             'country_code': 'jp'
         })
         sanitizer_args = {'step': 'tag-japanese'}
         _, address = PlaceSanitizer([sanitizer_args], self.config).process_names(place)
-        tmp_list = [(p.name,p.kind) for p in address]
+        tmp_list = [(p.name, p.kind) for p in address]
         return sorted(tmp_list)
 
     def test_on_address(self):
         res = self.run_sanitizer_on('address', name='foo', ref='bar', ref_abc='baz')
         return sorted(tmp_list)
 
     def test_on_address(self):
         res = self.run_sanitizer_on('address', name='foo', ref='bar', ref_abc='baz')
-        assert res == [('bar','ref'),('baz','ref_abc'),('foo','name')]
+        assert res == [('bar', 'ref'), ('baz', 'ref_abc'), ('foo', 'name')]
 
     def test_housenumber(self):
         res = self.run_sanitizer_on('address', housenumber='2')
 
     def test_housenumber(self):
         res = self.run_sanitizer_on('address', housenumber='2')
-        assert res == [('2','housenumber')]
+        assert res == [('2', 'housenumber')]
 
     def test_blocknumber(self):
         res = self.run_sanitizer_on('address', block_number='6')
 
     def test_blocknumber(self):
         res = self.run_sanitizer_on('address', block_number='6')
-        assert res == [('6','housenumber')]
+        assert res == [('6', 'housenumber')]
 
     def test_neighbourhood(self):
         res = self.run_sanitizer_on('address', neighbourhood='8')
 
     def test_neighbourhood(self):
         res = self.run_sanitizer_on('address', neighbourhood='8')
-        assert res == [('8','place')]
+        assert res == [('8', 'place')]
 
     def test_quarter(self):
         res = self.run_sanitizer_on('address', quarter='kase')
 
     def test_quarter(self):
         res = self.run_sanitizer_on('address', quarter='kase')
-        assert res==[('kase','place')]
+        assert res == [('kase', 'place')]
 
     def test_housenumber_blocknumber(self):
         res = self.run_sanitizer_on('address', housenumber='2', block_number='6')
 
     def test_housenumber_blocknumber(self):
         res = self.run_sanitizer_on('address', housenumber='2', block_number='6')
-        assert res == [('6-2','housenumber')]
+        assert res == [('6-2', 'housenumber')]
 
     def test_quarter_neighbourhood(self):
         res = self.run_sanitizer_on('address', quarter='kase', neighbourhood='8')
 
     def test_quarter_neighbourhood(self):
         res = self.run_sanitizer_on('address', quarter='kase', neighbourhood='8')
-        assert res == [('kase8','place')]
+        assert res == [('kase8', 'place')]
 
     def test_blocknumber_housenumber_quarter(self):
         res = self.run_sanitizer_on('address', block_number='6', housenumber='2', quarter='kase')
 
     def test_blocknumber_housenumber_quarter(self):
         res = self.run_sanitizer_on('address', block_number='6', housenumber='2', quarter='kase')
-        assert res == [('6-2','housenumber'),('kase','place')]
+        assert res == [('6-2', 'housenumber'), ('kase', 'place')]
 
     def test_blocknumber_housenumber_quarter_neighbourhood(self):
         res = self.run_sanitizer_on('address', block_number='6', housenumber='2', neighbourhood='8')
 
     def test_blocknumber_housenumber_quarter_neighbourhood(self):
         res = self.run_sanitizer_on('address', block_number='6', housenumber='2', neighbourhood='8')
-        assert res == [('6-2','housenumber'),('8','place')]
+        assert res == [('6-2', 'housenumber'), ('8', 'place')]
 
     def test_blocknumber_quarter_neighbourhood(self):
 
     def test_blocknumber_quarter_neighbourhood(self):
-        res = self.run_sanitizer_on('address',block_number='6', quarter='kase', neighbourhood='8')
-        assert res == [('6','housenumber'),('kase8','place')]
+        res = self.run_sanitizer_on('address', block_number='6', quarter='kase', neighbourhood='8')
+        assert res == [('6', 'housenumber'), ('kase8', 'place')]
 
     def test_blocknumber_quarter(self):
 
     def test_blocknumber_quarter(self):
-        res = self.run_sanitizer_on('address',block_number='6', quarter='kase')
-        assert res == [('6','housenumber'),('kase','place')]
+        res = self.run_sanitizer_on('address', block_number='6', quarter='kase')
+        assert res == [('6', 'housenumber'), ('kase', 'place')]
 
     def test_blocknumber_neighbourhood(self):
 
     def test_blocknumber_neighbourhood(self):
-        res = self.run_sanitizer_on('address',block_number='6', neighbourhood='8')
-        assert res == [('6','housenumber'),('8','place')]
+        res = self.run_sanitizer_on('address', block_number='6', neighbourhood='8')
+        assert res == [('6', 'housenumber'), ('8', 'place')]
 
     def test_housenumber_quarter_neighbourhood(self):
 
     def test_housenumber_quarter_neighbourhood(self):
-        res = self.run_sanitizer_on('address',housenumber='2', quarter='kase', neighbourhood='8')
-        assert res == [('2','housenumber'),('kase8','place')]
+        res = self.run_sanitizer_on('address', housenumber='2', quarter='kase', neighbourhood='8')
+        assert res == [('2', 'housenumber'), ('kase8', 'place')]
 
     def test_housenumber_quarter(self):
 
     def test_housenumber_quarter(self):
-        res = self.run_sanitizer_on('address',housenumber='2', quarter='kase')
-        assert res == [('2','housenumber'),('kase','place')]
+        res = self.run_sanitizer_on('address', housenumber='2', quarter='kase')
+        assert res == [('2', 'housenumber'), ('kase', 'place')]
 
     def test_housenumber_blocknumber_neighbourhood_quarter(self):
 
     def test_housenumber_blocknumber_neighbourhood_quarter(self):
-        res = self.run_sanitizer_on('address', block_number='6', housenumber='2', quarter='kase', neighbourhood='8')
-        assert res == [('6-2','housenumber'),('kase8','place')]
+        res = self.run_sanitizer_on('address', block_number='6', housenumber='2',
+                                    quarter='kase', neighbourhood='8')
+        assert res == [('6-2', 'housenumber'), ('kase8', 'place')]
index 632dea88f831561fe711f26a9e535e27b6310c05..4f8d2cfecf69f2a74f67e3bb3205d59d8a2cce3d 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for creating new tokenizers.
 # For a full list of authors see the git log.
 """
 Tests for creating new tokenizers.
@@ -27,7 +27,6 @@ class TestFactory:
     def init_env(self, project_env, property_table, tokenizer_mock):
         self.config = project_env
 
     def init_env(self, project_env, property_table, tokenizer_mock):
         self.config = project_env
 
-
     def test_setup_dummy_tokenizer(self, temp_db_conn):
         tokenizer = factory.create_tokenizer(self.config)
 
     def test_setup_dummy_tokenizer(self, temp_db_conn):
         tokenizer = factory.create_tokenizer(self.config)
 
@@ -37,7 +36,6 @@ class TestFactory:
 
         assert properties.get_property(temp_db_conn, 'tokenizer') == 'dummy'
 
 
         assert properties.get_property(temp_db_conn, 'tokenizer') == 'dummy'
 
-
     def test_setup_tokenizer_dir_exists(self):
         (self.config.project_dir / 'tokenizer').mkdir()
 
     def test_setup_tokenizer_dir_exists(self):
         (self.config.project_dir / 'tokenizer').mkdir()
 
@@ -46,14 +44,12 @@ class TestFactory:
         assert isinstance(tokenizer, DummyTokenizer)
         assert tokenizer.init_state == "new"
 
         assert isinstance(tokenizer, DummyTokenizer)
         assert tokenizer.init_state == "new"
 
-
     def test_setup_tokenizer_dir_failure(self):
         (self.config.project_dir / 'tokenizer').write_text("foo")
 
         with pytest.raises(UsageError):
             factory.create_tokenizer(self.config)
 
     def test_setup_tokenizer_dir_failure(self):
         (self.config.project_dir / 'tokenizer').write_text("foo")
 
         with pytest.raises(UsageError):
             factory.create_tokenizer(self.config)
 
-
     def test_load_tokenizer(self):
         factory.create_tokenizer(self.config)
 
     def test_load_tokenizer(self):
         factory.create_tokenizer(self.config)
 
@@ -62,7 +58,6 @@ class TestFactory:
         assert isinstance(tokenizer, DummyTokenizer)
         assert tokenizer.init_state == "loaded"
 
         assert isinstance(tokenizer, DummyTokenizer)
         assert tokenizer.init_state == "loaded"
 
-
     def test_load_repopulate_tokenizer_dir(self):
         factory.create_tokenizer(self.config)
 
     def test_load_repopulate_tokenizer_dir(self):
         factory.create_tokenizer(self.config)
 
@@ -71,7 +66,6 @@ class TestFactory:
         factory.get_tokenizer_for_db(self.config)
         assert (self.config.project_dir / 'tokenizer').exists()
 
         factory.get_tokenizer_for_db(self.config)
         assert (self.config.project_dir / 'tokenizer').exists()
 
-
     def test_load_missing_property(self, temp_db_cursor):
         factory.create_tokenizer(self.config)
 
     def test_load_missing_property(self, temp_db_cursor):
         factory.create_tokenizer(self.config)
 
index 06a3cd6ce7b81a3697c3d2006089e0f79126ae35..ce00281cff7e09e850fb4d5ee957fb687f65d809 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for ICU tokenizer.
 # For a full list of authors see the git log.
 """
 Tests for ICU tokenizer.
@@ -20,6 +20,7 @@ from nominatim_db.data.place_info import PlaceInfo
 
 from mock_icu_word_table import MockIcuWordTable
 
 
 from mock_icu_word_table import MockIcuWordTable
 
+
 @pytest.fixture
 def word_table(temp_db_conn):
     return MockIcuWordTable(temp_db_conn)
 @pytest.fixture
 def word_table(temp_db_conn):
     return MockIcuWordTable(temp_db_conn)
@@ -89,6 +90,7 @@ def analyzer(tokenizer_factory, test_config, monkeypatch,
 
     return _mk_analyser
 
 
     return _mk_analyser
 
+
 @pytest.fixture
 def sql_functions(temp_db_conn, def_config, src_dir):
     orig_sql = def_config.lib_dir.sql
 @pytest.fixture
 def sql_functions(temp_db_conn, def_config, src_dir):
     orig_sql = def_config.lib_dir.sql
@@ -152,19 +154,19 @@ LANGUAGE plpgsql;
                               """)
 
 
                               """)
 
 
-
 def test_init_new(tokenizer_factory, test_config, db_prop):
     tok = tokenizer_factory()
     tok.init_new_db(test_config)
 
 def test_init_new(tokenizer_factory, test_config, db_prop):
     tok = tokenizer_factory()
     tok.init_new_db(test_config)
 
-    assert db_prop(nominatim_db.tokenizer.icu_rule_loader.DBCFG_IMPORT_NORM_RULES) \
-            .startswith(':: lower ();')
+    prop = db_prop(nominatim_db.tokenizer.icu_rule_loader.DBCFG_IMPORT_NORM_RULES)
+
+    assert prop.startswith(':: lower ();')
 
 
 def test_init_word_table(tokenizer_factory, test_config, place_row, temp_db_cursor):
 
 
 def test_init_word_table(tokenizer_factory, test_config, place_row, temp_db_cursor):
-    place_row(names={'name' : 'Test Area', 'ref' : '52'})
-    place_row(names={'name' : 'No Area'})
-    place_row(names={'name' : 'Holzstrasse'})
+    place_row(names={'name': 'Test Area', 'ref': '52'})
+    place_row(names={'name': 'No Area'})
+    place_row(names={'name': 'Holzstrasse'})
 
     tok = tokenizer_factory()
     tok.init_new_db(test_config)
 
     tok = tokenizer_factory()
     tok.init_new_db(test_config)
@@ -259,12 +261,10 @@ class TestPostcodes:
             self.analyzer = anl
             yield anl
 
             self.analyzer = anl
             yield anl
 
-
     def process_postcode(self, cc, postcode):
         return self.analyzer.process_place(PlaceInfo({'country_code': cc,
                                                       'address': {'postcode': postcode}}))
 
     def process_postcode(self, cc, postcode):
         return self.analyzer.process_place(PlaceInfo({'country_code': cc,
                                                       'address': {'postcode': postcode}}))
 
-
     def test_update_postcodes_deleted(self, word_table):
         word_table.add_postcode(' 1234', '1234')
         word_table.add_postcode(' 5678', '5678')
     def test_update_postcodes_deleted(self, word_table):
         word_table.add_postcode(' 1234', '1234')
         word_table.add_postcode(' 5678', '5678')
@@ -273,20 +273,17 @@ class TestPostcodes:
 
         assert word_table.count() == 0
 
 
         assert word_table.count() == 0
 
-
     def test_process_place_postcode_simple(self, word_table):
         info = self.process_postcode('de', '12345')
 
         assert info['postcode'] == '12345'
 
     def test_process_place_postcode_simple(self, word_table):
         info = self.process_postcode('de', '12345')
 
         assert info['postcode'] == '12345'
 
-
     def test_process_place_postcode_with_space(self, word_table):
         info = self.process_postcode('in', '123 567')
 
         assert info['postcode'] == '123567'
 
 
     def test_process_place_postcode_with_space(self, word_table):
         info = self.process_postcode('in', '123 567')
 
         assert info['postcode'] == '123567'
 
 
-
 def test_update_special_phrase_empty_table(analyzer, word_table):
     with analyzer() as anl:
         anl.update_special_phrases([
 def test_update_special_phrase_empty_table(analyzer, word_table):
     with analyzer() as anl:
         anl.update_special_phrases([
@@ -296,9 +293,9 @@ def test_update_special_phrase_empty_table(analyzer, word_table):
         ], True)
 
     assert word_table.get_special() \
         ], True)
 
     assert word_table.get_special() \
-               == {('KÖNIG BEI', 'König bei', 'amenity', 'royal', 'near'),
-                   ('KÖNIGE', 'Könige', 'amenity', 'royal', None),
-                   ('STREET', 'street', 'highway', 'primary', 'in')}
+        == {('KÖNIG BEI', 'König bei', 'amenity', 'royal', 'near'),
+            ('KÖNIGE', 'Könige', 'amenity', 'royal', None),
+            ('STREET', 'street', 'highway', 'primary', 'in')}
 
 
 def test_update_special_phrase_delete_all(analyzer, word_table):
 
 
 def test_update_special_phrase_delete_all(analyzer, word_table):
@@ -339,9 +336,9 @@ def test_update_special_phrase_modify(analyzer, word_table):
         ], True)
 
     assert word_table.get_special() \
         ], True)
 
     assert word_table.get_special() \
-               == {('PRISON', 'prison', 'amenity', 'prison', 'in'),
-                   ('BAR', 'bar', 'highway', 'road', None),
-                   ('GARDEN', 'garden', 'leisure', 'garden', 'near')}
+        == {('PRISON', 'prison', 'amenity', 'prison', 'in'),
+            ('BAR', 'bar', 'highway', 'road', None),
+            ('GARDEN', 'garden', 'leisure', 'garden', 'near')}
 
 
 def test_add_country_names_new(analyzer, word_table):
 
 
 def test_add_country_names_new(analyzer, word_table):
@@ -370,7 +367,6 @@ class TestPlaceNames:
             self.analyzer = anl
             yield anl
 
             self.analyzer = anl
             yield anl
 
-
     def expect_name_terms(self, info, *expected_terms):
         tokens = self.analyzer.get_word_token_info(expected_terms)
         for token in tokens:
     def expect_name_terms(self, info, *expected_terms):
         tokens = self.analyzer.get_word_token_info(expected_terms)
         for token in tokens:
@@ -378,34 +374,29 @@ class TestPlaceNames:
 
         assert eval(info['names']) == set((t[2] for t in tokens))
 
 
         assert eval(info['names']) == set((t[2] for t in tokens))
 
-
     def process_named_place(self, names):
         return self.analyzer.process_place(PlaceInfo({'name': names}))
 
     def process_named_place(self, names):
         return self.analyzer.process_place(PlaceInfo({'name': names}))
 
-
     def test_simple_names(self):
         info = self.process_named_place({'name': 'Soft bAr', 'ref': '34'})
 
         self.expect_name_terms(info, '#Soft bAr', '#34', 'Soft', 'bAr', '34')
 
     def test_simple_names(self):
         info = self.process_named_place({'name': 'Soft bAr', 'ref': '34'})
 
         self.expect_name_terms(info, '#Soft bAr', '#34', 'Soft', 'bAr', '34')
 
-
-    @pytest.mark.parametrize('sep', [',' , ';'])
+    @pytest.mark.parametrize('sep', [',', ';'])
     def test_names_with_separator(self, sep):
         info = self.process_named_place({'name': sep.join(('New York', 'Big Apple'))})
 
         self.expect_name_terms(info, '#New York', '#Big Apple',
                                      'new', 'york', 'big', 'apple')
 
     def test_names_with_separator(self, sep):
         info = self.process_named_place({'name': sep.join(('New York', 'Big Apple'))})
 
         self.expect_name_terms(info, '#New York', '#Big Apple',
                                      'new', 'york', 'big', 'apple')
 
-
     def test_full_names_with_bracket(self):
         info = self.process_named_place({'name': 'Houseboat (left)'})
 
         self.expect_name_terms(info, '#Houseboat (left)', '#Houseboat',
                                      'houseboat', 'left')
 
     def test_full_names_with_bracket(self):
         info = self.process_named_place({'name': 'Houseboat (left)'})
 
         self.expect_name_terms(info, '#Houseboat (left)', '#Houseboat',
                                      'houseboat', 'left')
 
-
     def test_country_name(self, word_table):
     def test_country_name(self, word_table):
-        place = PlaceInfo({'name' : {'name': 'Norge'},
+        place = PlaceInfo({'name': {'name': 'Norge'},
                            'country_code': 'no',
                            'rank_address': 4,
                            'class': 'boundary',
                            'country_code': 'no',
                            'rank_address': 4,
                            'class': 'boundary',
@@ -427,18 +418,15 @@ class TestPlaceAddress:
             self.analyzer = anl
             yield anl
 
             self.analyzer = anl
             yield anl
 
-
     @pytest.fixture
     def getorcreate_hnr_id(self, temp_db_cursor):
         temp_db_cursor.execute("""CREATE OR REPLACE FUNCTION getorcreate_hnr_id(lookup_term TEXT)
                                   RETURNS INTEGER AS $$
                                     SELECT -nextval('seq_word')::INTEGER; $$ LANGUAGE SQL""")
 
     @pytest.fixture
     def getorcreate_hnr_id(self, temp_db_cursor):
         temp_db_cursor.execute("""CREATE OR REPLACE FUNCTION getorcreate_hnr_id(lookup_term TEXT)
                                   RETURNS INTEGER AS $$
                                     SELECT -nextval('seq_word')::INTEGER; $$ LANGUAGE SQL""")
 
-
     def process_address(self, **kwargs):
         return self.analyzer.process_place(PlaceInfo({'address': kwargs}))
 
     def process_address(self, **kwargs):
         return self.analyzer.process_place(PlaceInfo({'address': kwargs}))
 
-
     def name_token_set(self, *expected_terms):
         tokens = self.analyzer.get_word_token_info(expected_terms)
         for token in tokens:
     def name_token_set(self, *expected_terms):
         tokens = self.analyzer.get_word_token_info(expected_terms)
         for token in tokens:
@@ -446,14 +434,12 @@ class TestPlaceAddress:
 
         return set((t[2] for t in tokens))
 
 
         return set((t[2] for t in tokens))
 
-
     @pytest.mark.parametrize('pcode', ['12345', 'AB 123', '34-345'])
     def test_process_place_postcode(self, word_table, pcode):
         info = self.process_address(postcode=pcode)
 
         assert info['postcode'] == pcode
 
     @pytest.mark.parametrize('pcode', ['12345', 'AB 123', '34-345'])
     def test_process_place_postcode(self, word_table, pcode):
         info = self.process_address(postcode=pcode)
 
         assert info['postcode'] == pcode
 
-
     @pytest.mark.parametrize('hnr', ['123a', '1', '101'])
     def test_process_place_housenumbers_simple(self, hnr, getorcreate_hnr_id):
         info = self.process_address(housenumber=hnr)
     @pytest.mark.parametrize('hnr', ['123a', '1', '101'])
     def test_process_place_housenumbers_simple(self, hnr, getorcreate_hnr_id):
         info = self.process_address(housenumber=hnr)
@@ -461,7 +447,6 @@ class TestPlaceAddress:
         assert info['hnr'] == hnr.upper()
         assert info['hnr_tokens'] == "{-1}"
 
         assert info['hnr'] == hnr.upper()
         assert info['hnr_tokens'] == "{-1}"
 
-
     def test_process_place_housenumbers_duplicates(self, getorcreate_hnr_id):
         info = self.process_address(housenumber='134',
                                     conscriptionnumber='134',
     def test_process_place_housenumbers_duplicates(self, getorcreate_hnr_id):
         info = self.process_address(housenumber='134',
                                     conscriptionnumber='134',
@@ -470,7 +455,6 @@ class TestPlaceAddress:
         assert set(info['hnr'].split(';')) == set(('134', '99A'))
         assert info['hnr_tokens'] == "{-1,-2}"
 
         assert set(info['hnr'].split(';')) == set(('134', '99A'))
         assert info['hnr_tokens'] == "{-1,-2}"
 
-
     def test_process_place_housenumbers_cached(self, getorcreate_hnr_id):
         info = self.process_address(housenumber="45")
         assert info['hnr_tokens'] == "{-1}"
     def test_process_place_housenumbers_cached(self, getorcreate_hnr_id):
         info = self.process_address(housenumber="45")
         assert info['hnr_tokens'] == "{-1}"
@@ -484,37 +468,32 @@ class TestPlaceAddress:
         info = self.process_address(housenumber="41")
         assert eval(info['hnr_tokens']) == {-3}
 
         info = self.process_address(housenumber="41")
         assert eval(info['hnr_tokens']) == {-3}
 
-
     def test_process_place_street(self):
     def test_process_place_street(self):
-        self.analyzer.process_place(PlaceInfo({'name': {'name' : 'Grand Road'}}))
+        self.analyzer.process_place(PlaceInfo({'name': {'name': 'Grand Road'}}))
         info = self.process_address(street='Grand Road')
 
         assert eval(info['street']) == self.name_token_set('#Grand Road')
 
         info = self.process_address(street='Grand Road')
 
         assert eval(info['street']) == self.name_token_set('#Grand Road')
 
-
     def test_process_place_nonexisting_street(self):
         info = self.process_address(street='Grand Road')
 
         assert info['street'] == '{}'
 
     def test_process_place_nonexisting_street(self):
         info = self.process_address(street='Grand Road')
 
         assert info['street'] == '{}'
 
-
     def test_process_place_multiple_street_tags(self):
     def test_process_place_multiple_street_tags(self):
-        self.analyzer.process_place(PlaceInfo({'name': {'name' : 'Grand Road',
+        self.analyzer.process_place(PlaceInfo({'name': {'name': 'Grand Road',
                                                         'ref': '05989'}}))
         info = self.process_address(**{'street': 'Grand Road',
                                                         'ref': '05989'}}))
         info = self.process_address(**{'street': 'Grand Road',
-                                      'street:sym_ul': '05989'})
+                                       'street:sym_ul': '05989'})
 
         assert eval(info['street']) == self.name_token_set('#Grand Road', '#05989')
 
 
         assert eval(info['street']) == self.name_token_set('#Grand Road', '#05989')
 
-
     def test_process_place_street_empty(self):
         info = self.process_address(street='🜵')
 
         assert info['street'] == '{}'
 
     def test_process_place_street_empty(self):
         info = self.process_address(street='🜵')
 
         assert info['street'] == '{}'
 
-
     def test_process_place_street_from_cache(self):
     def test_process_place_street_from_cache(self):
-        self.analyzer.process_place(PlaceInfo({'name': {'name' : 'Grand Road'}}))
+        self.analyzer.process_place(PlaceInfo({'name': {'name': 'Grand Road'}}))
         self.process_address(street='Grand Road')
 
         # request address again
         self.process_address(street='Grand Road')
 
         # request address again
@@ -522,25 +501,21 @@ class TestPlaceAddress:
 
         assert eval(info['street']) == self.name_token_set('#Grand Road')
 
 
         assert eval(info['street']) == self.name_token_set('#Grand Road')
 
-
     def test_process_place_place(self):
         info = self.process_address(place='Honu Lulu')
 
         assert eval(info['place']) == self.name_token_set('HONU', 'LULU', '#HONU LULU')
 
     def test_process_place_place(self):
         info = self.process_address(place='Honu Lulu')
 
         assert eval(info['place']) == self.name_token_set('HONU', 'LULU', '#HONU LULU')
 
-
     def test_process_place_place_extra(self):
         info = self.process_address(**{'place:en': 'Honu Lulu'})
 
         assert 'place' not in info
 
     def test_process_place_place_extra(self):
         info = self.process_address(**{'place:en': 'Honu Lulu'})
 
         assert 'place' not in info
 
-
     def test_process_place_place_empty(self):
         info = self.process_address(place='🜵')
 
         assert 'place' not in info
 
     def test_process_place_place_empty(self):
         info = self.process_address(place='🜵')
 
         assert 'place' not in info
 
-
     def test_process_place_address_terms(self):
         info = self.process_address(country='de', city='Zwickau', state='Sachsen',
                                     suburb='Zwickau', street='Hauptstr',
     def test_process_place_address_terms(self):
         info = self.process_address(country='de', city='Zwickau', state='Sachsen',
                                     suburb='Zwickau', street='Hauptstr',
@@ -549,19 +524,17 @@ class TestPlaceAddress:
         city = self.name_token_set('ZWICKAU', '#ZWICKAU')
         state = self.name_token_set('SACHSEN', '#SACHSEN')
 
         city = self.name_token_set('ZWICKAU', '#ZWICKAU')
         state = self.name_token_set('SACHSEN', '#SACHSEN')
 
-        result = {k: eval(v) for k,v in info['addr'].items()}
+        result = {k: eval(v) for k, v in info['addr'].items()}
 
         assert result == {'city': city, 'suburb': city, 'state': state}
 
 
         assert result == {'city': city, 'suburb': city, 'state': state}
 
-
     def test_process_place_multiple_address_terms(self):
         info = self.process_address(**{'city': 'Bruxelles', 'city:de': 'Brüssel'})
 
     def test_process_place_multiple_address_terms(self):
         info = self.process_address(**{'city': 'Bruxelles', 'city:de': 'Brüssel'})
 
-        result = {k: eval(v) for k,v in info['addr'].items()}
+        result = {k: eval(v) for k, v in info['addr'].items()}
 
         assert result == {'city': self.name_token_set('Bruxelles', '#Bruxelles')}
 
 
         assert result == {'city': self.name_token_set('Bruxelles', '#Bruxelles')}
 
-
     def test_process_place_address_terms_empty(self):
         info = self.process_address(country='de', city=' ', street='Hauptstr',
                                     full='right behind the church')
     def test_process_place_address_terms_empty(self):
         info = self.process_address(country='de', city=' ', street='Hauptstr',
                                     full='right behind the church')
@@ -575,22 +548,21 @@ class TestPlaceHousenumberWithAnalyser:
     def setup(self, analyzer, sql_functions):
         hnr = {'step': 'clean-housenumbers',
                'filter-kind': ['housenumber', 'conscriptionnumber', 'streetnumber']}
     def setup(self, analyzer, sql_functions):
         hnr = {'step': 'clean-housenumbers',
                'filter-kind': ['housenumber', 'conscriptionnumber', 'streetnumber']}
-        with analyzer(trans=(":: upper()", "'🜵' > ' '"), sanitizers=[hnr], with_housenumber=True) as anl:
+        with analyzer(trans=(":: upper()", "'🜵' > ' '"), sanitizers=[hnr],
+                      with_housenumber=True) as anl:
             self.analyzer = anl
             yield anl
 
             self.analyzer = anl
             yield anl
 
-
     @pytest.fixture
     def getorcreate_hnr_id(self, temp_db_cursor):
     @pytest.fixture
     def getorcreate_hnr_id(self, temp_db_cursor):
-        temp_db_cursor.execute("""CREATE OR REPLACE FUNCTION create_analyzed_hnr_id(norm_term TEXT, lookup_terms TEXT[])
-                                  RETURNS INTEGER AS $$
-                                    SELECT -nextval('seq_word')::INTEGER; $$ LANGUAGE SQL""")
-
+        temp_db_cursor.execute("""
+            CREATE OR REPLACE FUNCTION create_analyzed_hnr_id(norm_term TEXT, lookup_terms TEXT[])
+            RETURNS INTEGER AS $$
+                SELECT -nextval('seq_word')::INTEGER; $$ LANGUAGE SQL""")
 
     def process_address(self, **kwargs):
         return self.analyzer.process_place(PlaceInfo({'address': kwargs}))
 
 
     def process_address(self, **kwargs):
         return self.analyzer.process_place(PlaceInfo({'address': kwargs}))
 
-
     def name_token_set(self, *expected_terms):
         tokens = self.analyzer.get_word_token_info(expected_terms)
         for token in tokens:
     def name_token_set(self, *expected_terms):
         tokens = self.analyzer.get_word_token_info(expected_terms)
         for token in tokens:
@@ -598,7 +570,6 @@ class TestPlaceHousenumberWithAnalyser:
 
         return set((t[2] for t in tokens))
 
 
         return set((t[2] for t in tokens))
 
-
     @pytest.mark.parametrize('hnr', ['123 a', '1', '101'])
     def test_process_place_housenumbers_simple(self, hnr, getorcreate_hnr_id):
         info = self.process_address(housenumber=hnr)
     @pytest.mark.parametrize('hnr', ['123 a', '1', '101'])
     def test_process_place_housenumbers_simple(self, hnr, getorcreate_hnr_id):
         info = self.process_address(housenumber=hnr)
@@ -606,7 +577,6 @@ class TestPlaceHousenumberWithAnalyser:
         assert info['hnr'] == hnr.upper()
         assert info['hnr_tokens'] == "{-1}"
 
         assert info['hnr'] == hnr.upper()
         assert info['hnr_tokens'] == "{-1}"
 
-
     def test_process_place_housenumbers_duplicates(self, getorcreate_hnr_id):
         info = self.process_address(housenumber='134',
                                     conscriptionnumber='134',
     def test_process_place_housenumbers_duplicates(self, getorcreate_hnr_id):
         info = self.process_address(housenumber='134',
                                     conscriptionnumber='134',
@@ -615,7 +585,6 @@ class TestPlaceHousenumberWithAnalyser:
         assert set(info['hnr'].split(';')) == set(('134', '99 A'))
         assert info['hnr_tokens'] == "{-1,-2}"
 
         assert set(info['hnr'].split(';')) == set(('134', '99 A'))
         assert info['hnr_tokens'] == "{-1,-2}"
 
-
     def test_process_place_housenumbers_cached(self, getorcreate_hnr_id):
         info = self.process_address(housenumber="45")
         assert info['hnr_tokens'] == "{-1}"
     def test_process_place_housenumbers_cached(self, getorcreate_hnr_id):
         info = self.process_address(housenumber="45")
         assert info['hnr_tokens'] == "{-1}"
@@ -637,7 +606,6 @@ class TestUpdateWordTokens:
         table_factory('search_name', 'place_id BIGINT, name_vector INT[]')
         self.tok = tokenizer_factory()
 
         table_factory('search_name', 'place_id BIGINT, name_vector INT[]')
         self.tok = tokenizer_factory()
 
-
     @pytest.fixture
     def search_entry(self, temp_db_cursor):
         place_id = itertools.count(1000)
     @pytest.fixture
     def search_entry(self, temp_db_cursor):
         place_id = itertools.count(1000)
@@ -648,7 +616,6 @@ class TestUpdateWordTokens:
 
         return _insert
 
 
         return _insert
 
-
     @pytest.fixture(params=['simple', 'analyzed'])
     def add_housenumber(self, request, word_table):
         if request.param == 'simple':
     @pytest.fixture(params=['simple', 'analyzed'])
     def add_housenumber(self, request, word_table):
         if request.param == 'simple':
@@ -660,7 +627,6 @@ class TestUpdateWordTokens:
 
         return _make
 
 
         return _make
 
-
     @pytest.mark.parametrize('hnr', ('1a', '1234567', '34 5'))
     def test_remove_unused_housenumbers(self, add_housenumber, word_table, hnr):
         word_table.add_housenumber(1000, hnr)
     @pytest.mark.parametrize('hnr', ('1a', '1234567', '34 5'))
     def test_remove_unused_housenumbers(self, add_housenumber, word_table, hnr):
         word_table.add_housenumber(1000, hnr)
@@ -669,7 +635,6 @@ class TestUpdateWordTokens:
         self.tok.update_word_tokens()
         assert word_table.count_housenumbers() == 0
 
         self.tok.update_word_tokens()
         assert word_table.count_housenumbers() == 0
 
-
     def test_keep_unused_numeral_housenumbers(self, add_housenumber, word_table):
         add_housenumber(1000, '5432')
 
     def test_keep_unused_numeral_housenumbers(self, add_housenumber, word_table):
         add_housenumber(1000, '5432')
 
@@ -677,8 +642,8 @@ class TestUpdateWordTokens:
         self.tok.update_word_tokens()
         assert word_table.count_housenumbers() == 1
 
         self.tok.update_word_tokens()
         assert word_table.count_housenumbers() == 1
 
-
-    def test_keep_housenumbers_from_search_name_table(self, add_housenumber, word_table, search_entry):
+    def test_keep_housenumbers_from_search_name_table(self, add_housenumber,
+                                                      word_table, search_entry):
         add_housenumber(9999, '5432a')
         add_housenumber(9991, '9 a')
         search_entry(123, 9999, 34)
         add_housenumber(9999, '5432a')
         add_housenumber(9991, '9 a')
         search_entry(123, 9999, 34)
@@ -687,8 +652,8 @@ class TestUpdateWordTokens:
         self.tok.update_word_tokens()
         assert word_table.count_housenumbers() == 1
 
         self.tok.update_word_tokens()
         assert word_table.count_housenumbers() == 1
 
-
-    def test_keep_housenumbers_from_placex_table(self, add_housenumber, word_table, placex_table):
+    def test_keep_housenumbers_from_placex_table(self, add_housenumber, word_table,
+                                                 placex_table):
         add_housenumber(9999, '5432a')
         add_housenumber(9990, '34z')
         placex_table.add(housenumber='34z')
         add_housenumber(9999, '5432a')
         add_housenumber(9990, '34z')
         placex_table.add(housenumber='34z')
@@ -698,8 +663,8 @@ class TestUpdateWordTokens:
         self.tok.update_word_tokens()
         assert word_table.count_housenumbers() == 1
 
         self.tok.update_word_tokens()
         assert word_table.count_housenumbers() == 1
 
-
-    def test_keep_housenumbers_from_placex_table_hnr_list(self, add_housenumber, word_table, placex_table):
+    def test_keep_housenumbers_from_placex_table_hnr_list(self, add_housenumber,
+                                                          word_table, placex_table):
         add_housenumber(9991, '9 b')
         add_housenumber(9990, '34z')
         placex_table.add(housenumber='9 a;9 b;9 c')
         add_housenumber(9991, '9 b')
         add_housenumber(9990, '34z')
         placex_table.add(housenumber='9 a;9 b;9 c')
index a3fae75815d4a1d0dad629b00a547c7d77efc1bb..f26b84c26fbac32ccd02b491b03c6c1e2a86a865 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for converting a config file to ICU rules.
 # For a full list of authors see the git log.
 """
 Tests for converting a config file to ICU rules.
@@ -19,17 +19,16 @@ from icu import Transliterator
 
 CONFIG_SECTIONS = ('normalization', 'transliteration', 'token-analysis')
 
 
 CONFIG_SECTIONS = ('normalization', 'transliteration', 'token-analysis')
 
+
 class TestIcuRuleLoader:
 
     @pytest.fixture(autouse=True)
     def init_env(self, project_env):
         self.project_env = project_env
 
 class TestIcuRuleLoader:
 
     @pytest.fixture(autouse=True)
     def init_env(self, project_env):
         self.project_env = project_env
 
-
     def write_config(self, content):
         (self.project_env.project_dir / 'icu_tokenizer.yaml').write_text(dedent(content))
 
     def write_config(self, content):
         (self.project_env.project_dir / 'icu_tokenizer.yaml').write_text(dedent(content))
 
-
     def config_rules(self, *variants):
         content = dedent("""\
         normalization:
     def config_rules(self, *variants):
         content = dedent("""\
         normalization:
@@ -49,14 +48,12 @@ class TestIcuRuleLoader:
         content += '\n'.join(("             - " + s for s in variants)) + '\n'
         self.write_config(content)
 
         content += '\n'.join(("             - " + s for s in variants)) + '\n'
         self.write_config(content)
 
-
     def get_replacements(self, *variants):
         self.config_rules(*variants)
         loader = ICURuleLoader(self.project_env)
         rules = loader.analysis[None].config['replacements']
 
     def get_replacements(self, *variants):
         self.config_rules(*variants)
         loader = ICURuleLoader(self.project_env)
         rules = loader.analysis[None].config['replacements']
 
-        return sorted((k, sorted(v)) for k,v in rules)
-
+        return sorted((k, sorted(v)) for k, v in rules)
 
     def test_empty_rule_set(self):
         self.write_config("""\
 
     def test_empty_rule_set(self):
         self.write_config("""\
@@ -72,16 +69,14 @@ class TestIcuRuleLoader:
         assert rules.get_normalization_rules() == ''
         assert rules.get_transliteration_rules() == ''
 
         assert rules.get_normalization_rules() == ''
         assert rules.get_transliteration_rules() == ''
 
-
     @pytest.mark.parametrize("section", CONFIG_SECTIONS)
     def test_missing_section(self, section):
     @pytest.mark.parametrize("section", CONFIG_SECTIONS)
     def test_missing_section(self, section):
-        rule_cfg = { s: [] for s in CONFIG_SECTIONS if s != section}
+        rule_cfg = {s: [] for s in CONFIG_SECTIONS if s != section}
         self.write_config(yaml.dump(rule_cfg))
 
         with pytest.raises(UsageError):
             ICURuleLoader(self.project_env)
 
         self.write_config(yaml.dump(rule_cfg))
 
         with pytest.raises(UsageError):
             ICURuleLoader(self.project_env)
 
-
     def test_get_search_rules(self):
         self.config_rules()
         loader = ICURuleLoader(self.project_env)
     def test_get_search_rules(self):
         self.config_rules()
         loader = ICURuleLoader(self.project_env)
@@ -97,7 +92,6 @@ class TestIcuRuleLoader:
         assert trans.transliterate(" Αθήνα ") == " athēna "
         assert trans.transliterate(" проспект ") == " prospekt "
 
         assert trans.transliterate(" Αθήνα ") == " athēna "
         assert trans.transliterate(" проспект ") == " prospekt "
 
-
     def test_get_normalization_rules(self):
         self.config_rules()
         loader = ICURuleLoader(self.project_env)
     def test_get_normalization_rules(self):
         self.config_rules()
         loader = ICURuleLoader(self.project_env)
@@ -106,7 +100,6 @@ class TestIcuRuleLoader:
 
         assert trans.transliterate(" проспект-Prospekt ") == " проспект prospekt "
 
 
         assert trans.transliterate(" проспект-Prospekt ") == " проспект prospekt "
 
-
     def test_get_transliteration_rules(self):
         self.config_rules()
         loader = ICURuleLoader(self.project_env)
     def test_get_transliteration_rules(self):
         self.config_rules()
         loader = ICURuleLoader(self.project_env)
@@ -115,7 +108,6 @@ class TestIcuRuleLoader:
 
         assert trans.transliterate(" проспект-Prospekt ") == " prospekt Prospekt "
 
 
         assert trans.transliterate(" проспект-Prospekt ") == " prospekt Prospekt "
 
-
     def test_transliteration_rules_from_file(self):
         self.write_config("""\
             normalization:
     def test_transliteration_rules_from_file(self):
         self.write_config("""\
             normalization:
@@ -135,7 +127,6 @@ class TestIcuRuleLoader:
 
         assert trans.transliterate(" axxt ") == " byt "
 
 
         assert trans.transliterate(" axxt ") == " byt "
 
-
     def test_search_rules(self):
         self.config_rules('~street => s,st', 'master => mstr')
         proc = ICURuleLoader(self.project_env).make_token_analysis()
     def test_search_rules(self):
         self.config_rules('~street => s,st', 'master => mstr')
         proc = ICURuleLoader(self.project_env).make_token_analysis()
@@ -144,7 +135,6 @@ class TestIcuRuleLoader:
         assert proc.search.transliterate('Earnes St').strip() == 'earnes st'
         assert proc.search.transliterate('Nostreet').strip() == 'nostreet'
 
         assert proc.search.transliterate('Earnes St').strip() == 'earnes st'
         assert proc.search.transliterate('Nostreet').strip() == 'nostreet'
 
-
     @pytest.mark.parametrize("variant", ['foo > bar', 'foo -> bar -> bar',
                                          '~foo~ -> bar', 'fo~ o -> bar'])
     def test_invalid_variant_description(self, variant):
     @pytest.mark.parametrize("variant", ['foo > bar', 'foo -> bar -> bar',
                                          '~foo~ -> bar', 'fo~ o -> bar'])
     def test_invalid_variant_description(self, variant):
@@ -157,25 +147,21 @@ class TestIcuRuleLoader:
 
         assert repl == [(' foo ', [' bar', ' foo'])]
 
 
         assert repl == [(' foo ', [' bar', ' foo'])]
 
-
     def test_replace_full(self):
         repl = self.get_replacements("foo => bar")
 
         assert repl == [(' foo ', [' bar'])]
 
     def test_replace_full(self):
         repl = self.get_replacements("foo => bar")
 
         assert repl == [(' foo ', [' bar'])]
 
-
     def test_add_suffix_no_decompose(self):
         repl = self.get_replacements("~berg |-> bg")
 
         assert repl == [(' berg ', [' berg', ' bg']),
                         ('berg ', ['berg', 'bg'])]
 
     def test_add_suffix_no_decompose(self):
         repl = self.get_replacements("~berg |-> bg")
 
         assert repl == [(' berg ', [' berg', ' bg']),
                         ('berg ', ['berg', 'bg'])]
 
-
     def test_replace_suffix_no_decompose(self):
         repl = self.get_replacements("~berg |=> bg")
 
     def test_replace_suffix_no_decompose(self):
         repl = self.get_replacements("~berg |=> bg")
 
-        assert repl == [(' berg ', [' bg']),('berg ', ['bg'])]
-
+        assert repl == [(' berg ', [' bg']), ('berg ', ['bg'])]
 
     def test_add_suffix_decompose(self):
         repl = self.get_replacements("~berg -> bg")
 
     def test_add_suffix_decompose(self):
         repl = self.get_replacements("~berg -> bg")
@@ -183,26 +169,22 @@ class TestIcuRuleLoader:
         assert repl == [(' berg ', [' berg', ' bg', 'berg', 'bg']),
                         ('berg ', [' berg', ' bg', 'berg', 'bg'])]
 
         assert repl == [(' berg ', [' berg', ' bg', 'berg', 'bg']),
                         ('berg ', [' berg', ' bg', 'berg', 'bg'])]
 
-
     def test_replace_suffix_decompose(self):
         repl = self.get_replacements("~berg => bg")
 
         assert repl == [(' berg ', [' bg', 'bg']),
                         ('berg ', [' bg', 'bg'])]
 
     def test_replace_suffix_decompose(self):
         repl = self.get_replacements("~berg => bg")
 
         assert repl == [(' berg ', [' bg', 'bg']),
                         ('berg ', [' bg', 'bg'])]
 
-
     def test_add_prefix_no_compose(self):
         repl = self.get_replacements("hinter~ |-> hnt")
 
         assert repl == [(' hinter', [' hinter', ' hnt']),
                         (' hinter ', [' hinter', ' hnt'])]
 
     def test_add_prefix_no_compose(self):
         repl = self.get_replacements("hinter~ |-> hnt")
 
         assert repl == [(' hinter', [' hinter', ' hnt']),
                         (' hinter ', [' hinter', ' hnt'])]
 
-
     def test_replace_prefix_no_compose(self):
         repl = self.get_replacements("hinter~ |=> hnt")
 
     def test_replace_prefix_no_compose(self):
         repl = self.get_replacements("hinter~ |=> hnt")
 
-        assert repl ==  [(' hinter', [' hnt']), (' hinter ', [' hnt'])]
-
+        assert repl == [(' hinter', [' hnt']), (' hinter ', [' hnt'])]
 
     def test_add_prefix_compose(self):
         repl = self.get_replacements("hinter~-> h")
 
     def test_add_prefix_compose(self):
         repl = self.get_replacements("hinter~-> h")
@@ -210,45 +192,38 @@ class TestIcuRuleLoader:
         assert repl == [(' hinter', [' h', ' h ', ' hinter', ' hinter ']),
                         (' hinter ', [' h', ' h', ' hinter', ' hinter'])]
 
         assert repl == [(' hinter', [' h', ' h ', ' hinter', ' hinter ']),
                         (' hinter ', [' h', ' h', ' hinter', ' hinter'])]
 
-
     def test_replace_prefix_compose(self):
         repl = self.get_replacements("hinter~=> h")
 
         assert repl == [(' hinter', [' h', ' h ']),
                         (' hinter ', [' h', ' h'])]
 
     def test_replace_prefix_compose(self):
         repl = self.get_replacements("hinter~=> h")
 
         assert repl == [(' hinter', [' h', ' h ']),
                         (' hinter ', [' h', ' h'])]
 
-
     def test_add_beginning_only(self):
         repl = self.get_replacements("^Premier -> Pr")
 
         assert repl == [('^ premier ', ['^ pr', '^ premier'])]
 
     def test_add_beginning_only(self):
         repl = self.get_replacements("^Premier -> Pr")
 
         assert repl == [('^ premier ', ['^ pr', '^ premier'])]
 
-
     def test_replace_beginning_only(self):
         repl = self.get_replacements("^Premier => Pr")
 
         assert repl == [('^ premier ', ['^ pr'])]
 
     def test_replace_beginning_only(self):
         repl = self.get_replacements("^Premier => Pr")
 
         assert repl == [('^ premier ', ['^ pr'])]
 
-
     def test_add_final_only(self):
         repl = self.get_replacements("road$ -> rd")
 
         assert repl == [(' road ^', [' rd ^', ' road ^'])]
 
     def test_add_final_only(self):
         repl = self.get_replacements("road$ -> rd")
 
         assert repl == [(' road ^', [' rd ^', ' road ^'])]
 
-
     def test_replace_final_only(self):
         repl = self.get_replacements("road$ => rd")
 
         assert repl == [(' road ^', [' rd ^'])]
 
     def test_replace_final_only(self):
         repl = self.get_replacements("road$ => rd")
 
         assert repl == [(' road ^', [' rd ^'])]
 
-
     def test_decompose_only(self):
         repl = self.get_replacements("~foo -> foo")
 
         assert repl == [(' foo ', [' foo', 'foo']),
                         ('foo ', [' foo', 'foo'])]
 
     def test_decompose_only(self):
         repl = self.get_replacements("~foo -> foo")
 
         assert repl == [(' foo ', [' foo', 'foo']),
                         ('foo ', [' foo', 'foo'])]
 
-
     def test_add_suffix_decompose_end_only(self):
         repl = self.get_replacements("~berg |-> bg", "~berg$ -> bg")
 
     def test_add_suffix_decompose_end_only(self):
         repl = self.get_replacements("~berg |-> bg", "~berg$ -> bg")
 
@@ -257,7 +232,6 @@ class TestIcuRuleLoader:
                         ('berg ', ['berg', 'bg']),
                         ('berg ^', [' berg ^', ' bg ^', 'berg ^', 'bg ^'])]
 
                         ('berg ', ['berg', 'bg']),
                         ('berg ^', [' berg ^', ' bg ^', 'berg ^', 'bg ^'])]
 
-
     def test_replace_suffix_decompose_end_only(self):
         repl = self.get_replacements("~berg |=> bg", "~berg$ => bg")
 
     def test_replace_suffix_decompose_end_only(self):
         repl = self.get_replacements("~berg |=> bg", "~berg$ => bg")
 
@@ -266,7 +240,6 @@ class TestIcuRuleLoader:
                         ('berg ', ['bg']),
                         ('berg ^', [' bg ^', 'bg ^'])]
 
                         ('berg ', ['bg']),
                         ('berg ^', [' bg ^', 'bg ^'])]
 
-
     def test_add_multiple_suffix(self):
         repl = self.get_replacements("~berg,~burg -> bg")
 
     def test_add_multiple_suffix(self):
         repl = self.get_replacements("~berg,~burg -> bg")
 
index 25844459f907f2801432e8eec1e0111fb676d894..fcf02bd3fe6fda4d584e32b0d15a78dea8097f05 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for execution of the sanitztion step.
 # For a full list of authors see the git log.
 """
 Tests for execution of the sanitztion step.
@@ -50,13 +50,13 @@ def test_placeinfo_has_attr():
 def test_sanitizer_default(def_config):
     san = sanitizer.PlaceSanitizer([{'step': 'split-name-list'}], def_config)
 
 def test_sanitizer_default(def_config):
     san = sanitizer.PlaceSanitizer([{'step': 'split-name-list'}], def_config)
 
-    name, address =  san.process_names(PlaceInfo({'name': {'name:de:de': '1;2;3'},
-                                                  'address': {'street': 'Bald'}}))
+    name, address = san.process_names(PlaceInfo({'name': {'name:de:de': '1;2;3'},
+                                                 'address': {'street': 'Bald'}}))
 
     assert len(name) == 3
     assert all(isinstance(n, sanitizer.PlaceName) for n in name)
 
     assert len(name) == 3
     assert all(isinstance(n, sanitizer.PlaceName) for n in name)
-    assert all(n.kind == 'name'  for n in name)
-    assert all(n.suffix == 'de:de'  for n in name)
+    assert all(n.kind == 'name' for n in name)
+    assert all(n.suffix == 'de:de' for n in name)
 
     assert len(address) == 1
     assert all(isinstance(n, sanitizer.PlaceName) for n in address)
 
     assert len(address) == 1
     assert all(isinstance(n, sanitizer.PlaceName) for n in address)
@@ -66,7 +66,7 @@ def test_sanitizer_default(def_config):
 def test_sanitizer_empty_list(def_config, rules):
     san = sanitizer.PlaceSanitizer(rules, def_config)
 
 def test_sanitizer_empty_list(def_config, rules):
     san = sanitizer.PlaceSanitizer(rules, def_config)
 
-    name, address =  san.process_names(PlaceInfo({'name': {'name:de:de': '1;2;3'}}))
+    name, address = san.process_names(PlaceInfo({'name': {'name:de:de': '1;2;3'}}))
 
     assert len(name) == 1
     assert all(isinstance(n, sanitizer.PlaceName) for n in name)
 
     assert len(name) == 1
     assert all(isinstance(n, sanitizer.PlaceName) for n in name)
@@ -74,4 +74,4 @@ def test_sanitizer_empty_list(def_config, rules):
 
 def test_sanitizer_missing_step_definition(def_config):
     with pytest.raises(UsageError):
 
 def test_sanitizer_missing_step_definition(def_config):
     with pytest.raises(UsageError):
-        san = sanitizer.PlaceSanitizer([{'id': 'split-name-list'}], def_config)
+        sanitizer.PlaceSanitizer([{'id': 'split-name-list'}], def_config)
index 870c8a5d76f81346d291a2cd348f4431e65fbb6f..1eb15a50d98c0d86f9e1171ca02edad761d4b7f2 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for special postcode analysis and variant generation.
 # For a full list of authors see the git log.
 """
 Tests for special postcode analysis and variant generation.
@@ -13,7 +13,6 @@ from icu import Transliterator
 
 import nominatim_db.tokenizer.token_analysis.postcodes as module
 from nominatim_db.data.place_name import PlaceName
 
 import nominatim_db.tokenizer.token_analysis.postcodes as module
 from nominatim_db.data.place_name import PlaceName
-from nominatim_db.errors import UsageError
 
 DEFAULT_NORMALIZATION = """ :: NFD ();
                             '🜳' > ' ';
 
 DEFAULT_NORMALIZATION = """ :: NFD ();
                             '🜳' > ' ';
@@ -27,9 +26,10 @@ DEFAULT_TRANSLITERATION = """ ::  Latin ();
                               '🜵' > ' ';
                           """
 
                               '🜵' > ' ';
                           """
 
+
 @pytest.fixture
 def analyser():
 @pytest.fixture
 def analyser():
-    rules = { 'analyzer': 'postcodes'}
+    rules = {'analyzer': 'postcodes'}
     config = module.configure(rules, DEFAULT_NORMALIZATION)
 
     trans = Transliterator.createFromRules("test_trans", DEFAULT_TRANSLITERATION)
     config = module.configure(rules, DEFAULT_NORMALIZATION)
 
     trans = Transliterator.createFromRules("test_trans", DEFAULT_TRANSLITERATION)
index 191f551f86debcef7d011a102b5adf60803030f6..02870f2445e7b798a7bc29ffa5aa794d2dd1a9a1 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for import name normalisation and variant generation.
 # For a full list of authors see the git log.
 """
 Tests for import name normalisation and variant generation.
@@ -26,8 +26,9 @@ DEFAULT_TRANSLITERATION = """ ::  Latin ();
                               '🜵' > ' ';
                           """
 
                               '🜵' > ' ';
                           """
 
+
 def make_analyser(*variants, variant_only=False):
 def make_analyser(*variants, variant_only=False):
-    rules = { 'analyzer': 'generic', 'variants': [{'words': variants}]}
+    rules = {'analyzer': 'generic', 'variants': [{'words': variants}]}
     if variant_only:
         rules['mode'] = 'variant-only'
     trans = Transliterator.createFromRules("test_trans", DEFAULT_TRANSLITERATION)
     if variant_only:
         rules['mode'] = 'variant-only'
     trans = Transliterator.createFromRules("test_trans", DEFAULT_TRANSLITERATION)
@@ -43,7 +44,7 @@ def get_normalized_variants(proc, name):
 
 
 def test_no_variants():
 
 
 def test_no_variants():
-    rules = { 'analyzer': 'generic' }
+    rules = {'analyzer': 'generic'}
     trans = Transliterator.createFromRules("test_trans", DEFAULT_TRANSLITERATION)
     norm = Transliterator.createFromRules("test_norm", DEFAULT_NORMALIZATION)
     config = module.configure(rules, norm, trans)
     trans = Transliterator.createFromRules("test_trans", DEFAULT_TRANSLITERATION)
     norm = Transliterator.createFromRules("test_norm", DEFAULT_NORMALIZATION)
     config = module.configure(rules, norm, trans)
@@ -62,35 +63,36 @@ def test_variants_empty():
 
 
 VARIANT_TESTS = [
 
 
 VARIANT_TESTS = [
-(('~strasse,~straße -> str', '~weg => weg'), "hallo", {'hallo'}),
-(('weg => wg',), "holzweg", {'holzweg'}),
-(('weg -> wg',), "holzweg", {'holzweg'}),
-(('~weg => weg',), "holzweg", {'holz weg', 'holzweg'}),
-(('~weg -> weg',), "holzweg",  {'holz weg', 'holzweg'}),
-(('~weg => w',), "holzweg", {'holz w', 'holzw'}),
-(('~weg -> w',), "holzweg",  {'holz weg', 'holzweg', 'holz w', 'holzw'}),
-(('~weg => weg',), "Meier Weg", {'meier weg', 'meierweg'}),
-(('~weg -> weg',), "Meier Weg", {'meier weg', 'meierweg'}),
-(('~weg => w',), "Meier Weg", {'meier w', 'meierw'}),
-(('~weg -> w',), "Meier Weg", {'meier weg', 'meierweg', 'meier w', 'meierw'}),
-(('weg => wg',), "Meier Weg", {'meier wg'}),
-(('weg -> wg',), "Meier Weg", {'meier weg', 'meier wg'}),
-(('~strasse,~straße -> str', '~weg => weg'), "Bauwegstraße",
+    (('~strasse,~straße -> str', '~weg => weg'), "hallo", {'hallo'}),
+    (('weg => wg',), "holzweg", {'holzweg'}),
+    (('weg -> wg',), "holzweg", {'holzweg'}),
+    (('~weg => weg',), "holzweg", {'holz weg', 'holzweg'}),
+    (('~weg -> weg',), "holzweg",  {'holz weg', 'holzweg'}),
+    (('~weg => w',), "holzweg", {'holz w', 'holzw'}),
+    (('~weg -> w',), "holzweg",  {'holz weg', 'holzweg', 'holz w', 'holzw'}),
+    (('~weg => weg',), "Meier Weg", {'meier weg', 'meierweg'}),
+    (('~weg -> weg',), "Meier Weg", {'meier weg', 'meierweg'}),
+    (('~weg => w',), "Meier Weg", {'meier w', 'meierw'}),
+    (('~weg -> w',), "Meier Weg", {'meier weg', 'meierweg', 'meier w', 'meierw'}),
+    (('weg => wg',), "Meier Weg", {'meier wg'}),
+    (('weg -> wg',), "Meier Weg", {'meier weg', 'meier wg'}),
+    (('~strasse,~straße -> str', '~weg => weg'), "Bauwegstraße",
      {'bauweg straße', 'bauweg str', 'bauwegstraße', 'bauwegstr'}),
      {'bauweg straße', 'bauweg str', 'bauwegstraße', 'bauwegstr'}),
-(('am => a', 'bach => b'), "am bach", {'a b'}),
-(('am => a', '~bach => b'), "am bach", {'a b'}),
-(('am -> a', '~bach -> b'), "am bach", {'am bach', 'a bach', 'am b', 'a b'}),
-(('am -> a', '~bach -> b'), "ambach", {'ambach', 'am bach', 'amb', 'am b'}),
-(('saint -> s,st', 'street -> st'), "Saint Johns Street",
+    (('am => a', 'bach => b'), "am bach", {'a b'}),
+    (('am => a', '~bach => b'), "am bach", {'a b'}),
+    (('am -> a', '~bach -> b'), "am bach", {'am bach', 'a bach', 'am b', 'a b'}),
+    (('am -> a', '~bach -> b'), "ambach", {'ambach', 'am bach', 'amb', 'am b'}),
+    (('saint -> s,st', 'street -> st'), "Saint Johns Street",
      {'saint johns street', 's johns street', 'st johns street',
       'saint johns st', 's johns st', 'st johns st'}),
      {'saint johns street', 's johns street', 'st johns street',
       'saint johns st', 's johns st', 'st johns st'}),
-(('river$ -> r',), "River Bend Road", {'river bend road'}),
-(('river$ -> r',), "Bent River", {'bent river', 'bent r'}),
-(('^north => n',), "North 2nd Street", {'n 2nd street'}),
-(('^north => n',), "Airport North", {'airport north'}),
-(('am -> a',), "am am am am am am am am", {'am am am am am am am am'}),
-(('am => a',), "am am am am am am am am", {'a a a a a a a a'})
-]
+    (('river$ -> r',), "River Bend Road", {'river bend road'}),
+    (('river$ -> r',), "Bent River", {'bent river', 'bent r'}),
+    (('^north => n',), "North 2nd Street", {'n 2nd street'}),
+    (('^north => n',), "Airport North", {'airport north'}),
+    (('am -> a',), "am am am am am am am am", {'am am am am am am am am'}),
+    (('am => a',), "am am am am am am am am", {'a a a a a a a a'})
+    ]
+
 
 @pytest.mark.parametrize("rules,name,variants", VARIANT_TESTS)
 def test_variants(rules, name, variants):
 
 @pytest.mark.parametrize("rules,name,variants", VARIANT_TESTS)
 def test_variants(rules, name, variants):
@@ -103,10 +105,11 @@ def test_variants(rules, name, variants):
 
 
 VARIANT_ONLY_TESTS = [
 
 
 VARIANT_ONLY_TESTS = [
-(('weg => wg',), "hallo", set()),
-(('weg => wg',), "Meier Weg", {'meier wg'}),
-(('weg -> wg',), "Meier Weg", {'meier wg'}),
-]
+    (('weg => wg',), "hallo", set()),
+    (('weg => wg',), "Meier Weg", {'meier wg'}),
+    (('weg -> wg',), "Meier Weg", {'meier wg'}),
+    ]
+
 
 @pytest.mark.parametrize("rules,name,variants", VARIANT_ONLY_TESTS)
 def test_variants_only(rules, name, variants):
 
 @pytest.mark.parametrize("rules,name,variants", VARIANT_ONLY_TESTS)
 def test_variants_only(rules, name, variants):
@@ -122,17 +125,15 @@ class TestGetReplacements:
 
     @staticmethod
     def configure_rules(*variants):
 
     @staticmethod
     def configure_rules(*variants):
-        rules = { 'analyzer': 'generic', 'variants': [{'words': variants}]}
+        rules = {'analyzer': 'generic', 'variants': [{'words': variants}]}
         trans = Transliterator.createFromRules("test_trans", DEFAULT_TRANSLITERATION)
         norm = Transliterator.createFromRules("test_norm", DEFAULT_NORMALIZATION)
         return module.configure(rules, norm, trans)
 
         trans = Transliterator.createFromRules("test_trans", DEFAULT_TRANSLITERATION)
         norm = Transliterator.createFromRules("test_norm", DEFAULT_NORMALIZATION)
         return module.configure(rules, norm, trans)
 
-
     def get_replacements(self, *variants):
         config = self.configure_rules(*variants)
 
     def get_replacements(self, *variants):
         config = self.configure_rules(*variants)
 
-        return sorted((k, sorted(v)) for k,v in config['replacements'])
-
+        return sorted((k, sorted(v)) for k, v in config['replacements'])
 
     @pytest.mark.parametrize("variant", ['foo > bar', 'foo -> bar -> bar',
                                          '~foo~ -> bar', 'fo~ o -> bar'])
 
     @pytest.mark.parametrize("variant", ['foo > bar', 'foo -> bar -> bar',
                                          '~foo~ -> bar', 'fo~ o -> bar'])
@@ -140,38 +141,32 @@ class TestGetReplacements:
         with pytest.raises(UsageError):
             self.configure_rules(variant)
 
         with pytest.raises(UsageError):
             self.configure_rules(variant)
 
-
     @pytest.mark.parametrize("rule", ["!!! -> bar", "bar => !!!"])
     def test_ignore_unnormalizable_terms(self, rule):
         repl = self.get_replacements(rule)
 
         assert repl == []
 
     @pytest.mark.parametrize("rule", ["!!! -> bar", "bar => !!!"])
     def test_ignore_unnormalizable_terms(self, rule):
         repl = self.get_replacements(rule)
 
         assert repl == []
 
-
     def test_add_full(self):
         repl = self.get_replacements("foo -> bar")
 
         assert repl == [(' foo ', [' bar', ' foo'])]
 
     def test_add_full(self):
         repl = self.get_replacements("foo -> bar")
 
         assert repl == [(' foo ', [' bar', ' foo'])]
 
-
     def test_replace_full(self):
         repl = self.get_replacements("foo => bar")
 
         assert repl == [(' foo ', [' bar'])]
 
     def test_replace_full(self):
         repl = self.get_replacements("foo => bar")
 
         assert repl == [(' foo ', [' bar'])]
 
-
     def test_add_suffix_no_decompose(self):
         repl = self.get_replacements("~berg |-> bg")
 
         assert repl == [(' berg ', [' berg', ' bg']),
                         ('berg ', ['berg', 'bg'])]
 
     def test_add_suffix_no_decompose(self):
         repl = self.get_replacements("~berg |-> bg")
 
         assert repl == [(' berg ', [' berg', ' bg']),
                         ('berg ', ['berg', 'bg'])]
 
-
     def test_replace_suffix_no_decompose(self):
         repl = self.get_replacements("~berg |=> bg")
 
     def test_replace_suffix_no_decompose(self):
         repl = self.get_replacements("~berg |=> bg")
 
-        assert repl == [(' berg ', [' bg']),('berg ', ['bg'])]
-
+        assert repl == [(' berg ', [' bg']), ('berg ', ['bg'])]
 
     def test_add_suffix_decompose(self):
         repl = self.get_replacements("~berg -> bg")
 
     def test_add_suffix_decompose(self):
         repl = self.get_replacements("~berg -> bg")
@@ -179,26 +174,22 @@ class TestGetReplacements:
         assert repl == [(' berg ', [' berg', ' bg', 'berg', 'bg']),
                         ('berg ', [' berg', ' bg', 'berg', 'bg'])]
 
         assert repl == [(' berg ', [' berg', ' bg', 'berg', 'bg']),
                         ('berg ', [' berg', ' bg', 'berg', 'bg'])]
 
-
     def test_replace_suffix_decompose(self):
         repl = self.get_replacements("~berg => bg")
 
         assert repl == [(' berg ', [' bg', 'bg']),
                         ('berg ', [' bg', 'bg'])]
 
     def test_replace_suffix_decompose(self):
         repl = self.get_replacements("~berg => bg")
 
         assert repl == [(' berg ', [' bg', 'bg']),
                         ('berg ', [' bg', 'bg'])]
 
-
     def test_add_prefix_no_compose(self):
         repl = self.get_replacements("hinter~ |-> hnt")
 
         assert repl == [(' hinter', [' hinter', ' hnt']),
                         (' hinter ', [' hinter', ' hnt'])]
 
     def test_add_prefix_no_compose(self):
         repl = self.get_replacements("hinter~ |-> hnt")
 
         assert repl == [(' hinter', [' hinter', ' hnt']),
                         (' hinter ', [' hinter', ' hnt'])]
 
-
     def test_replace_prefix_no_compose(self):
         repl = self.get_replacements("hinter~ |=> hnt")
 
     def test_replace_prefix_no_compose(self):
         repl = self.get_replacements("hinter~ |=> hnt")
 
-        assert repl ==  [(' hinter', [' hnt']), (' hinter ', [' hnt'])]
-
+        assert repl == [(' hinter', [' hnt']), (' hinter ', [' hnt'])]
 
     def test_add_prefix_compose(self):
         repl = self.get_replacements("hinter~-> h")
 
     def test_add_prefix_compose(self):
         repl = self.get_replacements("hinter~-> h")
@@ -206,45 +197,38 @@ class TestGetReplacements:
         assert repl == [(' hinter', [' h', ' h ', ' hinter', ' hinter ']),
                         (' hinter ', [' h', ' h', ' hinter', ' hinter'])]
 
         assert repl == [(' hinter', [' h', ' h ', ' hinter', ' hinter ']),
                         (' hinter ', [' h', ' h', ' hinter', ' hinter'])]
 
-
     def test_replace_prefix_compose(self):
         repl = self.get_replacements("hinter~=> h")
 
         assert repl == [(' hinter', [' h', ' h ']),
                         (' hinter ', [' h', ' h'])]
 
     def test_replace_prefix_compose(self):
         repl = self.get_replacements("hinter~=> h")
 
         assert repl == [(' hinter', [' h', ' h ']),
                         (' hinter ', [' h', ' h'])]
 
-
     def test_add_beginning_only(self):
         repl = self.get_replacements("^Premier -> Pr")
 
         assert repl == [('^ premier ', ['^ pr', '^ premier'])]
 
     def test_add_beginning_only(self):
         repl = self.get_replacements("^Premier -> Pr")
 
         assert repl == [('^ premier ', ['^ pr', '^ premier'])]
 
-
     def test_replace_beginning_only(self):
         repl = self.get_replacements("^Premier => Pr")
 
         assert repl == [('^ premier ', ['^ pr'])]
 
     def test_replace_beginning_only(self):
         repl = self.get_replacements("^Premier => Pr")
 
         assert repl == [('^ premier ', ['^ pr'])]
 
-
     def test_add_final_only(self):
         repl = self.get_replacements("road$ -> rd")
 
         assert repl == [(' road ^', [' rd ^', ' road ^'])]
 
     def test_add_final_only(self):
         repl = self.get_replacements("road$ -> rd")
 
         assert repl == [(' road ^', [' rd ^', ' road ^'])]
 
-
     def test_replace_final_only(self):
         repl = self.get_replacements("road$ => rd")
 
         assert repl == [(' road ^', [' rd ^'])]
 
     def test_replace_final_only(self):
         repl = self.get_replacements("road$ => rd")
 
         assert repl == [(' road ^', [' rd ^'])]
 
-
     def test_decompose_only(self):
         repl = self.get_replacements("~foo -> foo")
 
         assert repl == [(' foo ', [' foo', 'foo']),
                         ('foo ', [' foo', 'foo'])]
 
     def test_decompose_only(self):
         repl = self.get_replacements("~foo -> foo")
 
         assert repl == [(' foo ', [' foo', 'foo']),
                         ('foo ', [' foo', 'foo'])]
 
-
     def test_add_suffix_decompose_end_only(self):
         repl = self.get_replacements("~berg |-> bg", "~berg$ -> bg")
 
     def test_add_suffix_decompose_end_only(self):
         repl = self.get_replacements("~berg |-> bg", "~berg$ -> bg")
 
@@ -253,7 +237,6 @@ class TestGetReplacements:
                         ('berg ', ['berg', 'bg']),
                         ('berg ^', [' berg ^', ' bg ^', 'berg ^', 'bg ^'])]
 
                         ('berg ', ['berg', 'bg']),
                         ('berg ^', [' berg ^', ' bg ^', 'berg ^', 'bg ^'])]
 
-
     def test_replace_suffix_decompose_end_only(self):
         repl = self.get_replacements("~berg |=> bg", "~berg$ => bg")
 
     def test_replace_suffix_decompose_end_only(self):
         repl = self.get_replacements("~berg |=> bg", "~berg$ => bg")
 
@@ -262,7 +245,6 @@ class TestGetReplacements:
                         ('berg ', ['bg']),
                         ('berg ^', [' bg ^', 'bg ^'])]
 
                         ('berg ', ['bg']),
                         ('berg ^', [' bg ^', 'bg ^'])]
 
-
     @pytest.mark.parametrize('rule', ["~berg,~burg -> bg",
                                       "~berg, ~burg -> bg",
                                       "~berg,,~burg -> bg"])
     @pytest.mark.parametrize('rule', ["~berg,~burg -> bg",
                                       "~berg, ~burg -> bg",
                                       "~berg,,~burg -> bg"])
index 7d0db9258246cea0017dec0ada0418d9c508fd74..2ce2236a3c490762c965c42a75cdcc4344661c54 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for generic token analysis, mutation part.
 # For a full list of authors see the git log.
 """
 Tests for generic token analysis, mutation part.
@@ -24,37 +24,34 @@ DEFAULT_TRANSLITERATION = """ ::  Latin ();
                               '🜵' > ' ';
                           """
 
                               '🜵' > ' ';
                           """
 
+
 class TestMutationNoVariants:
 
     def make_analyser(self, *mutations):
 class TestMutationNoVariants:
 
     def make_analyser(self, *mutations):
-        rules = { 'analyzer': 'generic',
-                  'mutations': [ {'pattern': m[0], 'replacements': m[1]}
-                                 for m in mutations]
-                }
+        rules = {'analyzer': 'generic',
+                 'mutations': [{'pattern': m[0], 'replacements': m[1]}
+                               for m in mutations]
+                 }
         trans = Transliterator.createFromRules("test_trans", DEFAULT_TRANSLITERATION)
         norm = Transliterator.createFromRules("test_norm", DEFAULT_NORMALIZATION)
         config = module.configure(rules, norm, trans)
 
         self.analysis = module.create(norm, trans, config)
 
         trans = Transliterator.createFromRules("test_trans", DEFAULT_TRANSLITERATION)
         norm = Transliterator.createFromRules("test_norm", DEFAULT_NORMALIZATION)
         config = module.configure(rules, norm, trans)
 
         self.analysis = module.create(norm, trans, config)
 
-
     def variants(self, name):
         norm = Transliterator.createFromRules("test_norm", DEFAULT_NORMALIZATION)
         return set(self.analysis.compute_variants(norm.transliterate(name).strip()))
 
     def variants(self, name):
         norm = Transliterator.createFromRules("test_norm", DEFAULT_NORMALIZATION)
         return set(self.analysis.compute_variants(norm.transliterate(name).strip()))
 
-
     @pytest.mark.parametrize('pattern', ('(capture)', ['a list']))
     def test_bad_pattern(self, pattern):
         with pytest.raises(UsageError):
             self.make_analyser((pattern, ['b']))
 
     @pytest.mark.parametrize('pattern', ('(capture)', ['a list']))
     def test_bad_pattern(self, pattern):
         with pytest.raises(UsageError):
             self.make_analyser((pattern, ['b']))
 
-
     @pytest.mark.parametrize('replacements', (None, 'a string'))
     def test_bad_replacement(self, replacements):
         with pytest.raises(UsageError):
             self.make_analyser(('a', replacements))
 
     @pytest.mark.parametrize('replacements', (None, 'a string'))
     def test_bad_replacement(self, replacements):
         with pytest.raises(UsageError):
             self.make_analyser(('a', replacements))
 
-
     def test_simple_replacement(self):
         self.make_analyser(('a', ['b']))
 
     def test_simple_replacement(self):
         self.make_analyser(('a', ['b']))
 
@@ -62,27 +59,23 @@ class TestMutationNoVariants:
         assert self.variants('abba') == {'bbbb'}
         assert self.variants('2 aar') == {'2 bbr'}
 
         assert self.variants('abba') == {'bbbb'}
         assert self.variants('2 aar') == {'2 bbr'}
 
-
     def test_multichar_replacement(self):
         self.make_analyser(('1 1', ['1 1 1']))
 
         assert self.variants('1 1456') == {'1 1 1456'}
         assert self.variants('1 1 1') == {'1 1 1 1'}
 
     def test_multichar_replacement(self):
         self.make_analyser(('1 1', ['1 1 1']))
 
         assert self.variants('1 1456') == {'1 1 1456'}
         assert self.variants('1 1 1') == {'1 1 1 1'}
 
-
     def test_removement_replacement(self):
         self.make_analyser((' ', [' ', '']))
 
         assert self.variants('A 345') == {'a 345', 'a345'}
         assert self.variants('a g b') == {'a g b', 'ag b', 'a gb', 'agb'}
 
     def test_removement_replacement(self):
         self.make_analyser((' ', [' ', '']))
 
         assert self.variants('A 345') == {'a 345', 'a345'}
         assert self.variants('a g b') == {'a g b', 'ag b', 'a gb', 'agb'}
 
-
     def test_regex_pattern(self):
         self.make_analyser(('[^a-z]+', ['XXX', ' ']))
 
         assert self.variants('a-34n12') == {'aXXXnXXX', 'aXXXn', 'a nXXX', 'a n'}
 
     def test_regex_pattern(self):
         self.make_analyser(('[^a-z]+', ['XXX', ' ']))
 
         assert self.variants('a-34n12') == {'aXXXnXXX', 'aXXXn', 'a nXXX', 'a n'}
 
-
     def test_multiple_mutations(self):
         self.make_analyser(('ä', ['ä', 'ae']), ('ö', ['ö', 'oe']))
 
     def test_multiple_mutations(self):
         self.make_analyser(('ä', ['ä', 'ae']), ('ö', ['ö', 'oe']))
 
index 0384a4567ad26d6074c0b84a898b5e252dcdab9c..6ce665802c0a6426d020251f317652fb49638809 100644 (file)
@@ -10,6 +10,7 @@ Tests for simplified trie structure.
 
 from nominatim_db.tokenizer.token_analysis.simple_trie import SimpleTrie
 
 
 from nominatim_db.tokenizer.token_analysis.simple_trie import SimpleTrie
 
+
 def test_single_item_trie():
     t = SimpleTrie([('foob', 42)])
 
 def test_single_item_trie():
     t = SimpleTrie([('foob', 42)])
 
@@ -18,6 +19,7 @@ def test_single_item_trie():
     assert t.longest_prefix('foob') == (42, 4)
     assert t.longest_prefix('123foofoo', 3) == (None, 3)
 
     assert t.longest_prefix('foob') == (42, 4)
     assert t.longest_prefix('123foofoo', 3) == (None, 3)
 
+
 def test_complex_item_tree():
     t = SimpleTrie([('a', 1),
                     ('b', 2),
 def test_complex_item_tree():
     t = SimpleTrie([('a', 1),
                     ('b', 2),
index 0098747e52537d97eb33c889fcbb0f600fb2967e..dc9346c8fbcb06e33db50afd3c49e8cc92a90edd 100644 (file)
@@ -2,10 +2,11 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 import pytest
 
 # For a full list of authors see the git log.
 import pytest
 
+
 @pytest.fixture
 def osm2pgsql_options(temp_db, tmp_path):
     """ A standard set of options for osm2pgsql
 @pytest.fixture
 def osm2pgsql_options(temp_db, tmp_path):
     """ A standard set of options for osm2pgsql
index c5aaaaae9f9c77ee4a614f6de51b610702929b8e..38cf87c4b5c642c230a280e5f0aefd4be9876527 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for functions to add additional data to the database.
 # For a full list of authors see the git log.
 """
 Tests for functions to add additional data to the database.
@@ -13,6 +13,7 @@ import pytest
 
 from nominatim_db.tools import add_osm_data
 
 
 from nominatim_db.tools import add_osm_data
 
+
 class CaptureGetUrl:
 
     def __init__(self, monkeypatch):
 class CaptureGetUrl:
 
     def __init__(self, monkeypatch):
@@ -29,6 +30,7 @@ def setup_delete_postprocessing(temp_db_cursor):
     temp_db_cursor.execute("""CREATE OR REPLACE FUNCTION flush_deleted_places()
                               RETURNS INTEGER AS $$ SELECT 1 $$ LANGUAGE SQL""")
 
     temp_db_cursor.execute("""CREATE OR REPLACE FUNCTION flush_deleted_places()
                               RETURNS INTEGER AS $$ SELECT 1 $$ LANGUAGE SQL""")
 
+
 def test_import_osm_file_simple(dsn, table_factory, osm2pgsql_options, capfd):
 
     assert add_osm_data.add_data_from_file(dsn, Path('change.osm'), osm2pgsql_options) == 0
 def test_import_osm_file_simple(dsn, table_factory, osm2pgsql_options, capfd):
 
     assert add_osm_data.add_data_from_file(dsn, Path('change.osm'), osm2pgsql_options) == 0
index 1e1f0e294736c23826f94adbda5a380a8a12c8a8..e758bca2e3e28d4aa38d9422684aa5ace0e48ae2 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for maintenance and analysis functions.
 # For a full list of authors see the git log.
 """
 Tests for maintenance and analysis functions.
@@ -14,6 +14,7 @@ from nominatim_db.tools import admin
 from nominatim_db.tokenizer import factory
 from nominatim_db.db.sql_preprocessor import SQLPreprocessor
 
 from nominatim_db.tokenizer import factory
 from nominatim_db.db.sql_preprocessor import SQLPreprocessor
 
+
 @pytest.fixture(autouse=True)
 def create_placex_table(project_env, tokenizer_mock, temp_db_cursor, placex_table):
     """ All tests in this module require the placex table to be set up.
 @pytest.fixture(autouse=True)
 def create_placex_table(project_env, tokenizer_mock, temp_db_cursor, placex_table):
     """ All tests in this module require the placex table to be set up.
@@ -76,7 +77,8 @@ def test_analyse_indexing_with_osm_id(project_env, temp_db_cursor):
 class TestAdminCleanDeleted:
 
     @pytest.fixture(autouse=True)
 class TestAdminCleanDeleted:
 
     @pytest.fixture(autouse=True)
-    def setup_polygon_delete(self, project_env, table_factory, place_table, osmline_table, temp_db_cursor, temp_db_conn, def_config, src_dir):
+    def setup_polygon_delete(self, project_env, table_factory, place_table,
+                             osmline_table, temp_db_cursor, temp_db_conn, def_config, src_dir):
         """ Set up place_force_delete function and related tables
         """
         self.project_env = project_env
         """ Set up place_force_delete function and related tables
         """
         self.project_env = project_env
@@ -87,12 +89,14 @@ class TestAdminCleanDeleted:
                       class TEXT NOT NULL,
                       type TEXT NOT NULL""",
                       ((100, 'N', 'boundary', 'administrative'),
                       class TEXT NOT NULL,
                       type TEXT NOT NULL""",
                       ((100, 'N', 'boundary', 'administrative'),
-                      (145, 'N', 'boundary', 'administrative'),
-                      (175, 'R', 'landcover', 'grass')))
-        temp_db_cursor.execute("""INSERT INTO placex (place_id, osm_id, osm_type, class, type, indexed_date, indexed_status)
-                              VALUES(1, 100, 'N', 'boundary', 'administrative', current_date - INTERVAL '1 month', 1),
-                               (2, 145, 'N', 'boundary', 'administrative', current_date - INTERVAL '3 month', 1),
-                               (3, 175, 'R', 'landcover', 'grass', current_date - INTERVAL '3 months', 1)""")
+                       (145, 'N', 'boundary', 'administrative'),
+                       (175, 'R', 'landcover', 'grass')))
+        temp_db_cursor.execute("""
+            INSERT INTO placex (place_id, osm_id, osm_type, class, type,
+                                indexed_date, indexed_status)
+            VALUES(1, 100, 'N', 'boundary', 'administrative', current_date - INTERVAL '1 month', 1),
+                  (2, 145, 'N', 'boundary', 'administrative', current_date - INTERVAL '3 month', 1),
+                  (3, 175, 'R', 'landcover', 'grass', current_date - INTERVAL '3 months', 1)""")
         # set up tables and triggers for utils function
         table_factory('place_to_be_deleted',
                       """osm_id BIGINT,
         # set up tables and triggers for utils function
         table_factory('place_to_be_deleted',
                       """osm_id BIGINT,
@@ -116,33 +120,42 @@ class TestAdminCleanDeleted:
         sqlproc = SQLPreprocessor(temp_db_conn, def_config)
         sqlproc.run_sql_file(temp_db_conn, 'functions/utils.sql')
         def_config.lib_dir.sql = orig_sql
         sqlproc = SQLPreprocessor(temp_db_conn, def_config)
         sqlproc.run_sql_file(temp_db_conn, 'functions/utils.sql')
         def_config.lib_dir.sql = orig_sql
-        
 
     def test_admin_clean_deleted_no_records(self):
         admin.clean_deleted_relations(self.project_env, age='1 year')
 
     def test_admin_clean_deleted_no_records(self):
         admin.clean_deleted_relations(self.project_env, age='1 year')
-        assert self.temp_db_cursor.row_set('SELECT osm_id, osm_type, class, type, indexed_status FROM placex') == {(100, 'N', 'boundary', 'administrative', 1),
-                                                                                                                   (145, 'N', 'boundary', 'administrative', 1),
-                                                                                                                   (175, 'R', 'landcover', 'grass', 1)}
-        assert self.temp_db_cursor.table_rows('import_polygon_delete') == 3
 
 
+        rowset = self.temp_db_cursor.row_set(
+            'SELECT osm_id, osm_type, class, type, indexed_status FROM placex')
+
+        assert rowset == {(100, 'N', 'boundary', 'administrative', 1),
+                          (145, 'N', 'boundary', 'administrative', 1),
+                          (175, 'R', 'landcover', 'grass', 1)}
+        assert self.temp_db_cursor.table_rows('import_polygon_delete') == 3
 
     @pytest.mark.parametrize('test_age', ['T week', '1 welk', 'P1E'])
     def test_admin_clean_deleted_bad_age(self, test_age):
         with pytest.raises(UsageError):
 
     @pytest.mark.parametrize('test_age', ['T week', '1 welk', 'P1E'])
     def test_admin_clean_deleted_bad_age(self, test_age):
         with pytest.raises(UsageError):
-            admin.clean_deleted_relations(self.project_env, age = test_age)
-
+            admin.clean_deleted_relations(self.project_env, age=test_age)
 
     def test_admin_clean_deleted_partial(self):
 
     def test_admin_clean_deleted_partial(self):
-        admin.clean_deleted_relations(self.project_env, age = '2 months')
-        assert self.temp_db_cursor.row_set('SELECT osm_id, osm_type, class, type, indexed_status FROM placex') == {(100, 'N', 'boundary', 'administrative', 1),
-                                                                                                                   (145, 'N', 'boundary', 'administrative', 100),
-                                                                                                                   (175, 'R', 'landcover', 'grass', 100)}
+        admin.clean_deleted_relations(self.project_env, age='2 months')
+
+        rowset = self.temp_db_cursor.row_set(
+            'SELECT osm_id, osm_type, class, type, indexed_status FROM placex')
+
+        assert rowset == {(100, 'N', 'boundary', 'administrative', 1),
+                          (145, 'N', 'boundary', 'administrative', 100),
+                          (175, 'R', 'landcover', 'grass', 100)}
         assert self.temp_db_cursor.table_rows('import_polygon_delete') == 1
 
     @pytest.mark.parametrize('test_age', ['1 week', 'P3D', '5 hours'])
     def test_admin_clean_deleted(self, test_age):
         assert self.temp_db_cursor.table_rows('import_polygon_delete') == 1
 
     @pytest.mark.parametrize('test_age', ['1 week', 'P3D', '5 hours'])
     def test_admin_clean_deleted(self, test_age):
-        admin.clean_deleted_relations(self.project_env, age = test_age)
-        assert self.temp_db_cursor.row_set('SELECT osm_id, osm_type, class, type, indexed_status FROM placex') == {(100, 'N', 'boundary', 'administrative', 100),
-                                                                                                                   (145, 'N', 'boundary', 'administrative', 100),
-                                                                                                                   (175, 'R', 'landcover', 'grass', 100)}
+        admin.clean_deleted_relations(self.project_env, age=test_age)
+
+        rowset = self.temp_db_cursor.row_set(
+            'SELECT osm_id, osm_type, class, type, indexed_status FROM placex')
+
+        assert rowset == {(100, 'N', 'boundary', 'administrative', 100),
+                          (145, 'N', 'boundary', 'administrative', 100),
+                          (175, 'R', 'landcover', 'grass', 100)}
         assert self.temp_db_cursor.table_rows('import_polygon_delete') == 0
         assert self.temp_db_cursor.table_rows('import_polygon_delete') == 0
index 886bd75b72842216d7e1173e2cf57f53cac6c400..66506f561e42ab432ca2e84a21ab97e71c64f4e7 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for database integrity checks.
 # For a full list of authors see the git log.
 """
 Tests for database integrity checks.
@@ -12,6 +12,7 @@ import pytest
 from nominatim_db.tools import check_database as chkdb
 import nominatim_db.version
 
 from nominatim_db.tools import check_database as chkdb
 import nominatim_db.version
 
+
 def test_check_database_unknown_db(def_config, monkeypatch):
     monkeypatch.setenv('NOMINATIM_DATABASE_DSN', 'pgsql:dbname=fjgkhughwgh2423gsags')
     assert chkdb.check_database(def_config) == 1
 def test_check_database_unknown_db(def_config, monkeypatch):
     monkeypatch.setenv('NOMINATIM_DATABASE_DSN', 'pgsql:dbname=fjgkhughwgh2423gsags')
     assert chkdb.check_database(def_config) == 1
@@ -35,6 +36,7 @@ def test_check_database_version_good(property_table, temp_db_conn, def_config):
                        str(nominatim_db.version.NOMINATIM_VERSION))
     assert chkdb.check_database_version(temp_db_conn, def_config) == chkdb.CheckState.OK
 
                        str(nominatim_db.version.NOMINATIM_VERSION))
     assert chkdb.check_database_version(temp_db_conn, def_config) == chkdb.CheckState.OK
 
+
 def test_check_database_version_bad(property_table, temp_db_conn, def_config):
     property_table.set('database_version', '3.9.9-9')
     assert chkdb.check_database_version(temp_db_conn, def_config) == chkdb.CheckState.FATAL
 def test_check_database_version_bad(property_table, temp_db_conn, def_config):
     property_table.set('database_version', '3.9.9-9')
     assert chkdb.check_database_version(temp_db_conn, def_config) == chkdb.CheckState.FATAL
index df2042982c98f090dc24174e38064873c15b09b3..f8cea2cce8267dc64ddd5c1e19c612acb667ad5d 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for functions to import a new database.
 # For a full list of authors see the git log.
 """
 Tests for functions to import a new database.
@@ -10,13 +10,14 @@ Tests for functions to import a new database.
 from pathlib import Path
 
 import pytest
 from pathlib import Path
 
 import pytest
-import pytest_asyncio
+import pytest_asyncio  # noqa
 import psycopg
 from psycopg import sql as pysql
 
 from nominatim_db.tools import database_import
 from nominatim_db.errors import UsageError
 
 import psycopg
 from psycopg import sql as pysql
 
 from nominatim_db.tools import database_import
 from nominatim_db.errors import UsageError
 
+
 class TestDatabaseSetup:
     DBNAME = 'test_nominatim_python_unittest'
 
 class TestDatabaseSetup:
     DBNAME = 'test_nominatim_python_unittest'
 
@@ -31,18 +32,15 @@ class TestDatabaseSetup:
             with conn.cursor() as cur:
                 cur.execute(f'DROP DATABASE IF EXISTS {self.DBNAME}')
 
             with conn.cursor() as cur:
                 cur.execute(f'DROP DATABASE IF EXISTS {self.DBNAME}')
 
-
     @pytest.fixture
     def cursor(self):
         with psycopg.connect(dbname=self.DBNAME) as conn:
             with conn.cursor() as cur:
                 yield cur
 
     @pytest.fixture
     def cursor(self):
         with psycopg.connect(dbname=self.DBNAME) as conn:
             with conn.cursor() as cur:
                 yield cur
 
-
     def conn(self):
         return psycopg.connect(dbname=self.DBNAME)
 
     def conn(self):
         return psycopg.connect(dbname=self.DBNAME)
 
-
     def test_setup_skeleton(self):
         database_import.setup_database_skeleton(f'dbname={self.DBNAME}')
 
     def test_setup_skeleton(self):
         database_import.setup_database_skeleton(f'dbname={self.DBNAME}')
 
@@ -51,25 +49,21 @@ class TestDatabaseSetup:
             with conn.cursor() as cur:
                 cur.execute('CREATE TABLE t (h HSTORE, geom GEOMETRY(Geometry, 4326))')
 
             with conn.cursor() as cur:
                 cur.execute('CREATE TABLE t (h HSTORE, geom GEOMETRY(Geometry, 4326))')
 
-
     def test_unsupported_pg_version(self, monkeypatch):
         monkeypatch.setattr(database_import, 'POSTGRESQL_REQUIRED_VERSION', (100, 4))
 
         with pytest.raises(UsageError, match='PostgreSQL server is too old.'):
             database_import.setup_database_skeleton(f'dbname={self.DBNAME}')
 
     def test_unsupported_pg_version(self, monkeypatch):
         monkeypatch.setattr(database_import, 'POSTGRESQL_REQUIRED_VERSION', (100, 4))
 
         with pytest.raises(UsageError, match='PostgreSQL server is too old.'):
             database_import.setup_database_skeleton(f'dbname={self.DBNAME}')
 
-
     def test_create_db_explicit_ro_user(self):
         database_import.setup_database_skeleton(f'dbname={self.DBNAME}',
                                                 rouser='postgres')
 
     def test_create_db_explicit_ro_user(self):
         database_import.setup_database_skeleton(f'dbname={self.DBNAME}',
                                                 rouser='postgres')
 
-
     def test_create_db_missing_ro_user(self):
         with pytest.raises(UsageError, match='Missing read-only user.'):
             database_import.setup_database_skeleton(f'dbname={self.DBNAME}',
                                                     rouser='sdfwkjkjgdugu2;jgsafkljas;')
 
     def test_create_db_missing_ro_user(self):
         with pytest.raises(UsageError, match='Missing read-only user.'):
             database_import.setup_database_skeleton(f'dbname={self.DBNAME}',
                                                     rouser='sdfwkjkjgdugu2;jgsafkljas;')
 
-
     def test_setup_extensions_old_postgis(self, monkeypatch):
         monkeypatch.setattr(database_import, 'POSTGIS_REQUIRED_VERSION', (50, 50))
 
     def test_setup_extensions_old_postgis(self, monkeypatch):
         monkeypatch.setattr(database_import, 'POSTGIS_REQUIRED_VERSION', (50, 50))
 
@@ -173,7 +167,7 @@ def test_truncate_database_tables(temp_db_conn, temp_db_cursor, table_factory, w
 @pytest.mark.parametrize("threads", (1, 5))
 @pytest.mark.asyncio
 async def test_load_data(dsn, place_row, placex_table, osmline_table,
 @pytest.mark.parametrize("threads", (1, 5))
 @pytest.mark.asyncio
 async def test_load_data(dsn, place_row, placex_table, osmline_table,
-                   temp_db_cursor, threads):
+                         temp_db_cursor, threads):
     for func in ('precompute_words', 'getorcreate_housenumber_id', 'make_standard_name'):
         temp_db_cursor.execute(pysql.SQL("""CREATE FUNCTION {} (src TEXT)
                                             RETURNS TEXT AS $$ SELECT 'a'::TEXT $$ LANGUAGE SQL
     for func in ('precompute_words', 'getorcreate_housenumber_id', 'make_standard_name'):
         temp_db_cursor.execute(pysql.SQL("""CREATE FUNCTION {} (src TEXT)
                                             RETURNS TEXT AS $$ SELECT 'a'::TEXT $$ LANGUAGE SQL
@@ -198,11 +192,9 @@ class TestSetupSQL:
 
         self.config = def_config
 
 
         self.config = def_config
 
-
     def write_sql(self, fname, content):
         (self.config.lib_dir.sql / fname).write_text(content)
 
     def write_sql(self, fname, content):
         (self.config.lib_dir.sql / fname).write_text(content)
 
-
     @pytest.mark.parametrize("reverse", [True, False])
     def test_create_tables(self, temp_db_conn, temp_db_cursor, reverse):
         self.write_sql('tables.sql',
     @pytest.mark.parametrize("reverse", [True, False])
     def test_create_tables(self, temp_db_conn, temp_db_cursor, reverse):
         self.write_sql('tables.sql',
@@ -213,7 +205,6 @@ class TestSetupSQL:
 
         temp_db_cursor.scalar('SELECT test()') == reverse
 
 
         temp_db_cursor.scalar('SELECT test()') == reverse
 
-
     def test_create_table_triggers(self, temp_db_conn, temp_db_cursor):
         self.write_sql('table-triggers.sql',
                        """CREATE FUNCTION test() RETURNS TEXT
     def test_create_table_triggers(self, temp_db_conn, temp_db_cursor):
         self.write_sql('table-triggers.sql',
                        """CREATE FUNCTION test() RETURNS TEXT
@@ -223,7 +214,6 @@ class TestSetupSQL:
 
         temp_db_cursor.scalar('SELECT test()') == 'a'
 
 
         temp_db_cursor.scalar('SELECT test()') == 'a'
 
-
     def test_create_partition_tables(self, temp_db_conn, temp_db_cursor):
         self.write_sql('partition-tables.src.sql',
                        """CREATE FUNCTION test() RETURNS TEXT
     def test_create_partition_tables(self, temp_db_conn, temp_db_cursor):
         self.write_sql('partition-tables.src.sql',
                        """CREATE FUNCTION test() RETURNS TEXT
@@ -233,7 +223,6 @@ class TestSetupSQL:
 
         temp_db_cursor.scalar('SELECT test()') == 'b'
 
 
         temp_db_cursor.scalar('SELECT test()') == 'b'
 
-
     @pytest.mark.parametrize("drop", [True, False])
     @pytest.mark.asyncio
     async def test_create_search_indices(self, temp_db_conn, temp_db_cursor, drop):
     @pytest.mark.parametrize("drop", [True, False])
     @pytest.mark.asyncio
     async def test_create_search_indices(self, temp_db_conn, temp_db_cursor, drop):
index 666ef0b8b65e74d1418bd6d3c8807b2217306f35..216f1a40774f0ba7242f2f58d6ad6b913f135454 100644 (file)
@@ -2,19 +2,14 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for tools.exec_utils module.
 """
 # For a full list of authors see the git log.
 """
 Tests for tools.exec_utils module.
 """
-from pathlib import Path
-import subprocess
-
-import pytest
-
-from nominatim_db.config import Configuration
 import nominatim_db.tools.exec_utils as exec_utils
 
 import nominatim_db.tools.exec_utils as exec_utils
 
+
 def test_run_osm2pgsql(osm2pgsql_options):
     osm2pgsql_options['append'] = False
     osm2pgsql_options['import_file'] = 'foo.bar'
 def test_run_osm2pgsql(osm2pgsql_options):
     osm2pgsql_options['append'] = False
     osm2pgsql_options['import_file'] = 'foo.bar'
index f64850fb2e99312aade36ebbd404c4f23020a132..21e49b8dc63054fd2cd8a46d5131215b52ff5ce5 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for freeze functions (removing unused database parts).
 # For a full list of authors see the git log.
 """
 Tests for freeze functions (removing unused database parts).
@@ -26,6 +26,7 @@ NOMINATIM_DROP_TABLES = [
     'wikipedia_article', 'wikipedia_redirect'
 ]
 
     'wikipedia_article', 'wikipedia_redirect'
 ]
 
+
 def test_drop_tables(temp_db_conn, temp_db_cursor, table_factory):
     for table in NOMINATIM_RUNTIME_TABLES + NOMINATIM_DROP_TABLES:
         table_factory(table)
 def test_drop_tables(temp_db_conn, temp_db_cursor, table_factory):
     for table in NOMINATIM_RUNTIME_TABLES + NOMINATIM_DROP_TABLES:
         table_factory(table)
@@ -42,6 +43,7 @@ def test_drop_tables(temp_db_conn, temp_db_cursor, table_factory):
 
     assert freeze.is_frozen(temp_db_conn)
 
 
     assert freeze.is_frozen(temp_db_conn)
 
+
 def test_drop_flatnode_file_no_file():
     freeze.drop_flatnode_file(None)
 
 def test_drop_flatnode_file_no_file():
     freeze.drop_flatnode_file(None)
 
index 0d33e6e0f30e4a0ab47bfb02a4cd63f2ad4c55a9..d8fe8946c9173ed12485fc12163862869056ec7c 100644 (file)
@@ -2,20 +2,17 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
     Tests for import special phrases methods
     of the class SPImporter.
 """
 # For a full list of authors see the git log.
 """
     Tests for import special phrases methods
     of the class SPImporter.
 """
-from shutil import copyfile
 import pytest
 from nominatim_db.tools.special_phrases.sp_importer import SPImporter
 from nominatim_db.tools.special_phrases.sp_wiki_loader import SPWikiLoader
 from nominatim_db.tools.special_phrases.special_phrase import SpecialPhrase
 import pytest
 from nominatim_db.tools.special_phrases.sp_importer import SPImporter
 from nominatim_db.tools.special_phrases.sp_wiki_loader import SPWikiLoader
 from nominatim_db.tools.special_phrases.special_phrase import SpecialPhrase
-from nominatim_db.errors import UsageError
 
 
-from cursor import CursorForTesting
 
 @pytest.fixture
 def sp_importer(temp_db_conn, def_config, monkeypatch):
 
 @pytest.fixture
 def sp_importer(temp_db_conn, def_config, monkeypatch):
@@ -53,6 +50,7 @@ def test_fetch_existing_place_classtype_tables(sp_importer, table_factory):
     contained_table = sp_importer.table_phrases_to_delete.pop()
     assert contained_table == 'place_classtype_testclasstypetable'
 
     contained_table = sp_importer.table_phrases_to_delete.pop()
     assert contained_table == 'place_classtype_testclasstypetable'
 
+
 def test_check_sanity_class(sp_importer):
     """
         Check for _check_sanity() method.
 def test_check_sanity_class(sp_importer):
     """
         Check for _check_sanity() method.
@@ -65,6 +63,7 @@ def test_check_sanity_class(sp_importer):
 
     assert sp_importer._check_sanity(SpecialPhrase('en', 'class', 'type', ''))
 
 
     assert sp_importer._check_sanity(SpecialPhrase('en', 'class', 'type', ''))
 
+
 def test_load_white_and_black_lists(sp_importer):
     """
         Test that _load_white_and_black_lists() well return
 def test_load_white_and_black_lists(sp_importer):
     """
         Test that _load_white_and_black_lists() well return
@@ -93,6 +92,7 @@ def test_create_place_classtype_indexes(temp_db_with_extensions,
 
     assert check_placeid_and_centroid_indexes(temp_db_cursor, phrase_class, phrase_type)
 
 
     assert check_placeid_and_centroid_indexes(temp_db_cursor, phrase_class, phrase_type)
 
+
 def test_create_place_classtype_table(temp_db_conn, temp_db_cursor, placex_table, sp_importer):
     """
         Test that _create_place_classtype_table() create
 def test_create_place_classtype_table(temp_db_conn, temp_db_cursor, placex_table, sp_importer):
     """
         Test that _create_place_classtype_table() create
@@ -105,6 +105,7 @@ def test_create_place_classtype_table(temp_db_conn, temp_db_cursor, placex_table
 
     assert check_table_exist(temp_db_cursor, phrase_class, phrase_type)
 
 
     assert check_table_exist(temp_db_cursor, phrase_class, phrase_type)
 
+
 def test_grant_access_to_web_user(temp_db_conn, temp_db_cursor, table_factory,
                                   def_config, sp_importer):
     """
 def test_grant_access_to_web_user(temp_db_conn, temp_db_cursor, table_factory,
                                   def_config, sp_importer):
     """
@@ -120,7 +121,9 @@ def test_grant_access_to_web_user(temp_db_conn, temp_db_cursor, table_factory,
     sp_importer._grant_access_to_webuser(phrase_class, phrase_type)
     temp_db_conn.commit()
 
     sp_importer._grant_access_to_webuser(phrase_class, phrase_type)
     temp_db_conn.commit()
 
-    assert check_grant_access(temp_db_cursor, def_config.DATABASE_WEBUSER, phrase_class, phrase_type)
+    assert check_grant_access(temp_db_cursor, def_config.DATABASE_WEBUSER,
+                              phrase_class, phrase_type)
+
 
 def test_create_place_classtype_table_and_indexes(
         temp_db_cursor, def_config, placex_table,
 
 def test_create_place_classtype_table_and_indexes(
         temp_db_cursor, def_config, placex_table,
@@ -141,6 +144,7 @@ def test_create_place_classtype_table_and_indexes(
         assert check_placeid_and_centroid_indexes(temp_db_cursor, pair[0], pair[1])
         assert check_grant_access(temp_db_cursor, def_config.DATABASE_WEBUSER, pair[0], pair[1])
 
         assert check_placeid_and_centroid_indexes(temp_db_cursor, pair[0], pair[1])
         assert check_grant_access(temp_db_cursor, def_config.DATABASE_WEBUSER, pair[0], pair[1])
 
+
 def test_remove_non_existent_tables_from_db(sp_importer, default_phrases,
                                             temp_db_conn, temp_db_cursor):
     """
 def test_remove_non_existent_tables_from_db(sp_importer, default_phrases,
                                             temp_db_conn, temp_db_cursor):
     """
@@ -168,7 +172,7 @@ def test_remove_non_existent_tables_from_db(sp_importer, default_phrases,
     temp_db_conn.commit()
 
     assert temp_db_cursor.row_set(query_tables) \
     temp_db_conn.commit()
 
     assert temp_db_cursor.row_set(query_tables) \
-                 == {('place_classtype_testclasstypetable_to_keep', )}
+        == {('place_classtype_testclasstypetable_to_keep', )}
 
 
 @pytest.mark.parametrize("should_replace", [(True), (False)])
 
 
 @pytest.mark.parametrize("should_replace", [(True), (False)])
@@ -182,8 +186,8 @@ def test_import_phrases(monkeypatch, temp_db_cursor, def_config, sp_importer,
         It should also update the database well by deleting or preserving existing entries
         of the database.
     """
         It should also update the database well by deleting or preserving existing entries
         of the database.
     """
-    #Add some data to the database before execution in order to test
-    #what is deleted and what is preserved.
+    # Add some data to the database before execution in order to test
+    # what is deleted and what is preserved.
     table_factory('place_classtype_amenity_animal_shelter')
     table_factory('place_classtype_wrongclass_wrongtype')
 
     table_factory('place_classtype_amenity_animal_shelter')
     table_factory('place_classtype_wrongclass_wrongtype')
 
@@ -209,6 +213,7 @@ def test_import_phrases(monkeypatch, temp_db_cursor, def_config, sp_importer,
     if should_replace:
         assert not temp_db_cursor.table_exists('place_classtype_wrongclass_wrongtype')
 
     if should_replace:
         assert not temp_db_cursor.table_exists('place_classtype_wrongclass_wrongtype')
 
+
 def check_table_exist(temp_db_cursor, phrase_class, phrase_type):
     """
         Verify that the place_classtype table exists for the given
 def check_table_exist(temp_db_cursor, phrase_class, phrase_type):
     """
         Verify that the place_classtype table exists for the given
@@ -231,6 +236,7 @@ def check_grant_access(temp_db_cursor, user, phrase_class, phrase_type):
             AND privilege_type='SELECT'""".format(table_name, user))
     return temp_db_cursor.fetchone()
 
             AND privilege_type='SELECT'""".format(table_name, user))
     return temp_db_cursor.fetchone()
 
+
 def check_placeid_and_centroid_indexes(temp_db_cursor, phrase_class, phrase_type):
     """
         Check that the place_id index and centroid index exist for the
 def check_placeid_and_centroid_indexes(temp_db_cursor, phrase_class, phrase_type):
     """
         Check that the place_id index and centroid index exist for the
index 0b4d2ec6e18585afd6ee233dfa5c31eb06086d04..00f6a7d7ad11a749c00b106cca815f956645b09f 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for migration functions
 # For a full list of authors see the git log.
 """
 Tests for migration functions
@@ -11,9 +11,9 @@ import pytest
 
 from nominatim_db.tools import migration
 from nominatim_db.errors import UsageError
 
 from nominatim_db.tools import migration
 from nominatim_db.errors import UsageError
-from nominatim_db.db.connection import server_version_tuple
 import nominatim_db.version
 
 import nominatim_db.version
 
+
 class DummyTokenizer:
 
     def update_sql_functions(self, config):
 class DummyTokenizer:
 
     def update_sql_functions(self, config):
@@ -49,6 +49,7 @@ def test_run_single_migration(temp_db_with_extensions, def_config, temp_db_curso
                        str(nominatim_db.version.NominatimVersion(*oldversion)))
 
     done = {'old': False, 'new': False}
                        str(nominatim_db.version.NominatimVersion(*oldversion)))
 
     done = {'old': False, 'new': False}
+
     def _migration(**_):
         """ Dummy migration"""
         done['new'] = True
     def _migration(**_):
         """ Dummy migration"""
         done['new'] = True
@@ -69,7 +70,7 @@ def test_run_single_migration(temp_db_with_extensions, def_config, temp_db_curso
     assert property_table.get('database_version') == str(nominatim_db.version.NOMINATIM_VERSION)
 
 
     assert property_table.get('database_version') == str(nominatim_db.version.NOMINATIM_VERSION)
 
 
-###### Tests for specific migrations
+# Tests for specific migrations
 #
 # Each migration should come with two tests:
 #  1. Test that migration from old to new state works as expected.
 #
 # Each migration should come with two tests:
 #  1. Test that migration from old to new state works as expected.
index f035bb19affa5c1195cb8999f61897cdd68c00de..b03c9748441a69537859b404dc125db55411ff18 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for functions to maintain the artificial postcode table.
 # For a full list of authors see the git log.
 """
 Tests for functions to maintain the artificial postcode table.
@@ -15,6 +15,7 @@ from nominatim_db.tools import postcodes
 from nominatim_db.data import country_info
 import dummy_tokenizer
 
 from nominatim_db.data import country_info
 import dummy_tokenizer
 
+
 class MockPostcodeTable:
     """ A location_postcode table for testing.
     """
 class MockPostcodeTable:
     """ A location_postcode table for testing.
     """
@@ -35,7 +36,7 @@ class MockPostcodeTable:
                            RETURNS TEXT AS $$ BEGIN RETURN postcode; END; $$ LANGUAGE plpgsql;
 
                            CREATE OR REPLACE FUNCTION get_country_code(place geometry)
                            RETURNS TEXT AS $$ BEGIN RETURN postcode; END; $$ LANGUAGE plpgsql;
 
                            CREATE OR REPLACE FUNCTION get_country_code(place geometry)
-                           RETURNS TEXT AS $$ BEGIN 
+                           RETURNS TEXT AS $$ BEGIN
                            RETURN null;
                            END; $$ LANGUAGE plpgsql;
                         """)
                            RETURN null;
                            END; $$ LANGUAGE plpgsql;
                         """)
@@ -51,7 +52,6 @@ class MockPostcodeTable:
                         (country, postcode, x, y))
         self.conn.commit()
 
                         (country, postcode, x, y))
         self.conn.commit()
 
-
     @property
     def row_set(self):
         with self.conn.cursor() as cur:
     @property
     def row_set(self):
         with self.conn.cursor() as cur:
@@ -180,7 +180,7 @@ def test_postcodes_extern(dsn, postcode_table, tmp_path,
                                       ('xx', 'CD 4511', -10, -5)}
 
 
                                       ('xx', 'CD 4511', -10, -5)}
 
 
-def test_postcodes_extern_bad_column(dsn, postcode_table, tmp_path, 
+def test_postcodes_extern_bad_column(dsn, postcode_table, tmp_path,
                                      insert_implicit_postcode, tokenizer):
     insert_implicit_postcode(1, 'xx', 'POINT(10 12)', dict(postcode='AB 4511'))
 
                                      insert_implicit_postcode, tokenizer):
     insert_implicit_postcode(1, 'xx', 'POINT(10 12)', dict(postcode='AB 4511'))
 
@@ -204,6 +204,7 @@ def test_postcodes_extern_bad_number(dsn, insert_implicit_postcode,
     assert postcode_table.row_set == {('xx', 'AB 4511', 10, 12),
                                       ('xx', 'CD 4511', -10, -5)}
 
     assert postcode_table.row_set == {('xx', 'AB 4511', 10, 12),
                                       ('xx', 'CD 4511', -10, -5)}
 
+
 def test_can_compute(dsn, table_factory):
     assert not postcodes.can_compute(dsn)
     table_factory('place')
 def test_can_compute(dsn, table_factory):
     assert not postcodes.can_compute(dsn)
     table_factory('place')
@@ -211,10 +212,10 @@ def test_can_compute(dsn, table_factory):
 
 
 def test_no_placex_entry(dsn, tmp_path, temp_db_cursor, place_row, postcode_table, tokenizer):
 
 
 def test_no_placex_entry(dsn, tmp_path, temp_db_cursor, place_row, postcode_table, tokenizer):
-    #Rewrite the get_country_code function to verify its execution.
+    # Rewrite the get_country_code function to verify its execution.
     temp_db_cursor.execute("""
         CREATE OR REPLACE FUNCTION get_country_code(place geometry)
     temp_db_cursor.execute("""
         CREATE OR REPLACE FUNCTION get_country_code(place geometry)
-        RETURNS TEXT AS $$ BEGIN 
+        RETURNS TEXT AS $$ BEGIN
         RETURN 'yy';
         END; $$ LANGUAGE plpgsql;
     """)
         RETURN 'yy';
         END; $$ LANGUAGE plpgsql;
     """)
@@ -224,11 +225,12 @@ def test_no_placex_entry(dsn, tmp_path, temp_db_cursor, place_row, postcode_tabl
     assert postcode_table.row_set == {('yy', 'AB 4511', 10, 12)}
 
 
     assert postcode_table.row_set == {('yy', 'AB 4511', 10, 12)}
 
 
-def test_discard_badly_formatted_postcodes(dsn, tmp_path, temp_db_cursor, place_row, postcode_table, tokenizer):
-    #Rewrite the get_country_code function to verify its execution.
+def test_discard_badly_formatted_postcodes(dsn, tmp_path, temp_db_cursor, place_row,
+                                           postcode_table, tokenizer):
+    # Rewrite the get_country_code function to verify its execution.
     temp_db_cursor.execute("""
         CREATE OR REPLACE FUNCTION get_country_code(place geometry)
     temp_db_cursor.execute("""
         CREATE OR REPLACE FUNCTION get_country_code(place geometry)
-        RETURNS TEXT AS $$ BEGIN 
+        RETURNS TEXT AS $$ BEGIN
         RETURN 'fr';
         END; $$ LANGUAGE plpgsql;
     """)
         RETURN 'fr';
         END; $$ LANGUAGE plpgsql;
     """)
index 8f73518000b966690c60959f7de119283532fcfe..95feef0de04e7c6e34b57e3296b82ac48cb05e09 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Test for various refresh functions.
 # For a full list of authors see the git log.
 """
 Test for various refresh functions.
@@ -12,7 +12,7 @@ from pathlib import Path
 import pytest
 
 from nominatim_db.tools import refresh
 import pytest
 
 from nominatim_db.tools import refresh
-from nominatim_db.db.connection import postgis_version_tuple
+
 
 def test_refresh_import_wikipedia_not_existing(dsn):
     assert refresh.import_wikipedia_articles(dsn, Path('.')) == 1
 
 def test_refresh_import_wikipedia_not_existing(dsn):
     assert refresh.import_wikipedia_articles(dsn, Path('.')) == 1
@@ -21,6 +21,7 @@ def test_refresh_import_wikipedia_not_existing(dsn):
 def test_refresh_import_secondary_importance_non_existing(dsn):
     assert refresh.import_secondary_importance(dsn, Path('.')) == 1
 
 def test_refresh_import_secondary_importance_non_existing(dsn):
     assert refresh.import_secondary_importance(dsn, Path('.')) == 1
 
+
 def test_refresh_import_secondary_importance_testdb(dsn, src_dir, temp_db_conn, temp_db_cursor):
     temp_db_cursor.execute('CREATE EXTENSION postgis')
     temp_db_cursor.execute('CREATE EXTENSION postgis_raster')
 def test_refresh_import_secondary_importance_testdb(dsn, src_dir, temp_db_conn, temp_db_cursor):
     temp_db_cursor.execute('CREATE EXTENSION postgis')
     temp_db_cursor.execute('CREATE EXTENSION postgis_raster')
index 6e094cdc1c0e03ad5e138bffc18412039acfd07a..f2bfdea6c4da47a68d5f38362d88069dc691fbe4 100644 (file)
@@ -2,23 +2,24 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for function for importing address ranks.
 """
 import json
 # For a full list of authors see the git log.
 """
 Tests for function for importing address ranks.
 """
 import json
-from pathlib import Path
 
 import pytest
 
 from nominatim_db.tools.refresh import load_address_levels, load_address_levels_from_config
 
 
 import pytest
 
 from nominatim_db.tools.refresh import load_address_levels, load_address_levels_from_config
 
+
 def test_load_ranks_def_config(temp_db_conn, temp_db_cursor, def_config):
     load_address_levels_from_config(temp_db_conn, def_config)
 
     assert temp_db_cursor.table_rows('address_levels') > 0
 
 def test_load_ranks_def_config(temp_db_conn, temp_db_cursor, def_config):
     load_address_levels_from_config(temp_db_conn, def_config)
 
     assert temp_db_cursor.table_rows('address_levels') > 0
 
+
 def test_load_ranks_from_project_dir(project_env, temp_db_conn, temp_db_cursor):
     test_file = project_env.project_dir / 'address-levels.json'
     test_file.write_text('[{"tags":{"place":{"sea":2}}}]')
 def test_load_ranks_from_project_dir(project_env, temp_db_conn, temp_db_cursor):
     test_file = project_env.project_dir / 'address-levels.json'
     test_file.write_text('[{"tags":{"place":{"sea":2}}}]')
@@ -43,14 +44,14 @@ def test_load_ranks_country(temp_db_conn, temp_db_cursor):
                           "tags": {"place": {"village": 15}}},
                          {"countries": ['uk', 'us'],
                           "tags": {"place": {"village": 16}}}
                           "tags": {"place": {"village": 15}}},
                          {"countries": ['uk', 'us'],
                           "tags": {"place": {"village": 16}}}
-                        ])
+                         ])
 
     assert temp_db_cursor.row_set('SELECT * FROM levels') == \
            set([(None, 'place', 'village', 14, 14),
                 ('de', 'place', 'village', 15, 15),
                 ('uk', 'place', 'village', 16, 16),
                 ('us', 'place', 'village', 16, 16),
 
     assert temp_db_cursor.row_set('SELECT * FROM levels') == \
            set([(None, 'place', 'village', 14, 14),
                 ('de', 'place', 'village', 15, 15),
                 ('uk', 'place', 'village', 16, 16),
                 ('us', 'place', 'village', 16, 16),
-               ])
+                ])
 
 
 def test_load_ranks_default_value(temp_db_conn, temp_db_cursor):
 
 
 def test_load_ranks_default_value(temp_db_conn, temp_db_cursor):
@@ -58,33 +59,33 @@ def test_load_ranks_default_value(temp_db_conn, temp_db_cursor):
                         [{"tags": {"boundary": {"": 28}}},
                          {"countries": ['hu'],
                           "tags": {"boundary": {"": 29}}}
                         [{"tags": {"boundary": {"": 28}}},
                          {"countries": ['hu'],
                           "tags": {"boundary": {"": 29}}}
-                        ])
+                         ])
 
     assert temp_db_cursor.row_set('SELECT * FROM levels') == \
            set([(None, 'boundary', None, 28, 28),
                 ('hu', 'boundary', None, 29, 29),
 
     assert temp_db_cursor.row_set('SELECT * FROM levels') == \
            set([(None, 'boundary', None, 28, 28),
                 ('hu', 'boundary', None, 29, 29),
-               ])
+                ])
 
 
 def test_load_ranks_multiple_keys(temp_db_conn, temp_db_cursor):
     load_address_levels(temp_db_conn, 'levels',
                         [{"tags": {"place": {"city": 14},
 
 
 def test_load_ranks_multiple_keys(temp_db_conn, temp_db_cursor):
     load_address_levels(temp_db_conn, 'levels',
                         [{"tags": {"place": {"city": 14},
-                                   "boundary": {"administrative2" : 4}}
-                         }])
+                                   "boundary": {"administrative2": 4}}
+                          }])
 
     assert temp_db_cursor.row_set('SELECT * FROM levels') == \
            set([(None, 'place', 'city', 14, 14),
                 (None, 'boundary', 'administrative2', 4, 4),
 
     assert temp_db_cursor.row_set('SELECT * FROM levels') == \
            set([(None, 'place', 'city', 14, 14),
                 (None, 'boundary', 'administrative2', 4, 4),
-               ])
+                ])
 
 
 def test_load_ranks_address(temp_db_conn, temp_db_cursor):
     load_address_levels(temp_db_conn, 'levels',
                         [{"tags": {"place": {"city": 14,
 
 
 def test_load_ranks_address(temp_db_conn, temp_db_cursor):
     load_address_levels(temp_db_conn, 'levels',
                         [{"tags": {"place": {"city": 14,
-                                             "town" : [14, 13]}}
-                         }])
+                                             "town": [14, 13]}}
+                          }])
 
     assert temp_db_cursor.row_set('SELECT * FROM levels') == \
            set([(None, 'place', 'city', 14, 14),
                 (None, 'place', 'town', 14, 13),
 
     assert temp_db_cursor.row_set('SELECT * FROM levels') == \
            set([(None, 'place', 'city', 14, 14),
                 (None, 'place', 'town', 14, 13),
-               ])
+                ])
index 984a161016fecd8f594a00d8a0b7b80010b708a5..bd8724d60138787eec910724642e78f88aea307a 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for creating PL/pgSQL functions for Nominatim.
 # For a full list of authors see the git log.
 """
 Tests for creating PL/pgSQL functions for Nominatim.
@@ -11,6 +11,7 @@ import pytest
 
 from nominatim_db.tools.refresh import create_functions
 
 
 from nominatim_db.tools.refresh import create_functions
 
+
 class TestCreateFunctions:
     @pytest.fixture(autouse=True)
     def init_env(self, sql_preprocessor, temp_db_conn, def_config, tmp_path):
 class TestCreateFunctions:
     @pytest.fixture(autouse=True)
     def init_env(self, sql_preprocessor, temp_db_conn, def_config, tmp_path):
@@ -18,12 +19,10 @@ class TestCreateFunctions:
         self.config = def_config
         def_config.lib_dir.sql = tmp_path
 
         self.config = def_config
         def_config.lib_dir.sql = tmp_path
 
-
     def write_functions(self, content):
         sqlfile = self.config.lib_dir.sql / 'functions.sql'
         sqlfile.write_text(content)
 
     def write_functions(self, content):
         sqlfile = self.config.lib_dir.sql / 'functions.sql'
         sqlfile.write_text(content)
 
-
     def test_create_functions(self, temp_db_cursor):
         self.write_functions("""CREATE OR REPLACE FUNCTION test() RETURNS INTEGER
                               AS $$
     def test_create_functions(self, temp_db_cursor):
         self.write_functions("""CREATE OR REPLACE FUNCTION test() RETURNS INTEGER
                               AS $$
@@ -37,7 +36,6 @@ class TestCreateFunctions:
 
         assert temp_db_cursor.scalar('SELECT test()') == 43
 
 
         assert temp_db_cursor.scalar('SELECT test()') == 43
 
-
     @pytest.mark.parametrize("dbg,ret", ((True, 43), (False, 22)))
     def test_create_functions_with_template(self, temp_db_cursor, dbg, ret):
         self.write_functions("""CREATE OR REPLACE FUNCTION test() RETURNS INTEGER
     @pytest.mark.parametrize("dbg,ret", ((True, 43), (False, 22)))
     def test_create_functions_with_template(self, temp_db_cursor, dbg, ret):
         self.write_functions("""CREATE OR REPLACE FUNCTION test() RETURNS INTEGER
index 997ba04dc43562938266a2b4809cb9647bda7b0c..046e91919e3a3f7e826df94ef0b254216971a4e7 100644 (file)
@@ -12,7 +12,10 @@ import csv
 
 import pytest
 
 
 import pytest
 
-from nominatim_db.tools.refresh import import_wikipedia_articles, recompute_importance, create_functions
+from nominatim_db.tools.refresh import (import_wikipedia_articles,
+                                        recompute_importance,
+                                        create_functions)
+
 
 @pytest.fixture
 def wiki_csv(tmp_path, sql_preprocessor):
 
 @pytest.fixture
 def wiki_csv(tmp_path, sql_preprocessor):
@@ -25,7 +28,7 @@ def wiki_csv(tmp_path, sql_preprocessor):
             for lang, title, importance, wd in data:
                 writer.writerow({'language': lang, 'type': 'a',
                                  'title': title, 'importance': str(importance),
             for lang, title, importance, wd in data:
                 writer.writerow({'language': lang, 'type': 'a',
                                  'title': title, 'importance': str(importance),
-                                 'wikidata_id' : wd})
+                                 'wikidata_id': wd})
         return tmp_path
 
     return _import
         return tmp_path
 
     return _import
index 392ea0750b6f50c11c5006e4ef6eb09ceb7763f3..347899bdb0fc4f97c448c0d064ae0638f027f1dc 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for replication functionality.
 # For a full list of authors see the git log.
 """
 Tests for replication functionality.
@@ -22,13 +22,15 @@ OSM_NODE_DATA = """\
 <node id="100" visible="true" version="1" changeset="2047" timestamp="2006-01-27T22:09:10Z" user="Foo" uid="111" lat="48.7586670" lon="8.1343060">
 </node>
 </osm>
 <node id="100" visible="true" version="1" changeset="2047" timestamp="2006-01-27T22:09:10Z" user="Foo" uid="111" lat="48.7586670" lon="8.1343060">
 </node>
 </osm>
-"""
+"""  # noqa
+
 
 @pytest.fixture(autouse=True)
 def setup_status_table(status_table):
     pass
 
 
 @pytest.fixture(autouse=True)
 def setup_status_table(status_table):
     pass
 
-### init replication
+
+# init replication
 
 def test_init_replication_bad_base_url(monkeypatch, place_row, temp_db_conn):
     place_row(osm_type='N', osm_id=100)
 
 def test_init_replication_bad_base_url(monkeypatch, place_row, temp_db_conn):
     place_row(osm_type='N', osm_id=100)
@@ -50,13 +52,13 @@ def test_init_replication_success(monkeypatch, place_row, temp_db_conn, temp_db_
     nominatim_db.tools.replication.init_replication(temp_db_conn, 'https://test.io')
 
     expected_date = dt.datetime.strptime('2006-01-27T19:09:10', status.ISODATE_FORMAT)\
     nominatim_db.tools.replication.init_replication(temp_db_conn, 'https://test.io')
 
     expected_date = dt.datetime.strptime('2006-01-27T19:09:10', status.ISODATE_FORMAT)\
-                        .replace(tzinfo=dt.timezone.utc)
+                      .replace(tzinfo=dt.timezone.utc)
 
     assert temp_db_cursor.row_set("SELECT * FROM import_status") \
 
     assert temp_db_cursor.row_set("SELECT * FROM import_status") \
-             == {(expected_date, 234, True)}
+        == {(expected_date, 234, True)}
 
 
 
 
-### checking for updates
+# checking for updates
 
 def test_check_for_updates_empty_status_table(temp_db_conn):
     assert nominatim_db.tools.replication.check_for_updates(temp_db_conn, 'https://test.io') == 254
 
 def test_check_for_updates_empty_status_table(temp_db_conn):
     assert nominatim_db.tools.replication.check_for_updates(temp_db_conn, 'https://test.io') == 254
@@ -87,10 +89,11 @@ def test_check_for_updates_no_new_data(monkeypatch, temp_db_conn,
                         "get_state_info",
                         lambda self: OsmosisState(server_sequence, date))
 
                         "get_state_info",
                         lambda self: OsmosisState(server_sequence, date))
 
-    assert nominatim_db.tools.replication.check_for_updates(temp_db_conn, 'https://test.io') == result
+    assert result == \
+        nominatim_db.tools.replication.check_for_updates(temp_db_conn, 'https://test.io')
 
 
 
 
-### updating
+# updating
 
 @pytest.fixture
 def update_options(tmpdir):
 
 @pytest.fixture
 def update_options(tmpdir):
@@ -100,6 +103,7 @@ def update_options(tmpdir):
                 import_file=tmpdir / 'foo.osm',
                 max_diff_size=1)
 
                 import_file=tmpdir / 'foo.osm',
                 max_diff_size=1)
 
+
 def test_update_empty_status_table(dsn):
     with pytest.raises(UsageError):
         nominatim_db.tools.replication.update(dsn, {})
 def test_update_empty_status_table(dsn):
     with pytest.raises(UsageError):
         nominatim_db.tools.replication.update(dsn, {})
@@ -109,7 +113,7 @@ def test_update_already_indexed(temp_db_conn, dsn):
     status.set_status(temp_db_conn, dt.datetime.now(dt.timezone.utc), seq=34, indexed=False)
 
     assert nominatim_db.tools.replication.update(dsn, dict(indexed_only=True)) \
     status.set_status(temp_db_conn, dt.datetime.now(dt.timezone.utc), seq=34, indexed=False)
 
     assert nominatim_db.tools.replication.update(dsn, dict(indexed_only=True)) \
-             == nominatim_db.tools.replication.UpdateState.MORE_PENDING
+        == nominatim_db.tools.replication.UpdateState.MORE_PENDING
 
 
 def test_update_no_data_no_sleep(monkeypatch, temp_db_conn, dsn, update_options):
 
 
 def test_update_no_data_no_sleep(monkeypatch, temp_db_conn, dsn, update_options):
@@ -124,7 +128,7 @@ def test_update_no_data_no_sleep(monkeypatch, temp_db_conn, dsn, update_options)
     monkeypatch.setattr(time, 'sleep', sleeptime.append)
 
     assert nominatim_db.tools.replication.update(dsn, update_options) \
     monkeypatch.setattr(time, 'sleep', sleeptime.append)
 
     assert nominatim_db.tools.replication.update(dsn, update_options) \
-             == nominatim_db.tools.replication.UpdateState.NO_CHANGES
+        == nominatim_db.tools.replication.UpdateState.NO_CHANGES
 
     assert not sleeptime
 
 
     assert not sleeptime
 
@@ -141,7 +145,7 @@ def test_update_no_data_sleep(monkeypatch, temp_db_conn, dsn, update_options):
     monkeypatch.setattr(time, 'sleep', sleeptime.append)
 
     assert nominatim_db.tools.replication.update(dsn, update_options) \
     monkeypatch.setattr(time, 'sleep', sleeptime.append)
 
     assert nominatim_db.tools.replication.update(dsn, update_options) \
-             == nominatim_db.tools.replication.UpdateState.NO_CHANGES
+        == nominatim_db.tools.replication.UpdateState.NO_CHANGES
 
     assert len(sleeptime) == 1
     assert sleeptime[0] < 3600
 
     assert len(sleeptime) == 1
     assert sleeptime[0] < 3600
index 9d0ad9cc8e81c8782819fa2c54cd1bffdd0082fb..67d6eed575cdb50f5bddfd95fe01d72de5fe1eab 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
     Tests for methods of the SPCsvLoader class.
 # For a full list of authors see the git log.
 """
     Tests for methods of the SPCsvLoader class.
@@ -13,6 +13,7 @@ from nominatim_db.errors import UsageError
 from nominatim_db.tools.special_phrases.sp_csv_loader import SPCsvLoader
 from nominatim_db.tools.special_phrases.special_phrase import SpecialPhrase
 
 from nominatim_db.tools.special_phrases.sp_csv_loader import SPCsvLoader
 from nominatim_db.tools.special_phrases.special_phrase import SpecialPhrase
 
+
 @pytest.fixture
 def sp_csv_loader(src_dir):
     """
 @pytest.fixture
 def sp_csv_loader(src_dir):
     """
index 5c37c32f42eb2eec91c3043096bf255c5db3ce58..b8e41cbe2f6c87cc9713a79ea3d0d5dc5c3559ff 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
     Tests for methods of the SPWikiLoader class.
 # For a full list of authors see the git log.
 """
     Tests for methods of the SPWikiLoader class.
@@ -36,22 +36,22 @@ def test_generate_phrases(sp_wiki_loader):
     """
     phrases = list(sp_wiki_loader.generate_phrases())
 
     """
     phrases = list(sp_wiki_loader.generate_phrases())
 
-    assert set((p.p_label, p.p_class, p.p_type, p.p_operator) for p in phrases) ==\
-              {('Zip Line', 'aerialway', 'zip_line', '-'),
-               ('Zip Lines', 'aerialway', 'zip_line', '-'),
-               ('Zip Line in', 'aerialway', 'zip_line', 'in'),
-               ('Zip Lines in', 'aerialway', 'zip_line', 'in'),
-               ('Zip Line near', 'aerialway', 'zip_line', 'near'),
-               ('Animal shelter', 'amenity', 'animal_shelter', '-'),
-               ('Animal shelters', 'amenity', 'animal_shelter', '-'),
-               ('Animal shelter in', 'amenity', 'animal_shelter', 'in'),
-               ('Animal shelters in', 'amenity', 'animal_shelter', 'in'),
-               ('Animal shelter near', 'amenity', 'animal_shelter', 'near'),
-               ('Animal shelters near', 'amenity', 'animal_shelter', 'near'),
-               ('Drinking Water near', 'amenity', 'drinking_water', 'near'),
-               ('Water', 'amenity', 'drinking_water', '-'),
-               ('Water in', 'amenity', 'drinking_water', 'in'),
-               ('Water near', 'amenity', 'drinking_water', 'near'),
-               ('Embassy', 'amenity', 'embassy', '-'),
-               ('Embassys', 'amenity', 'embassy', '-'),
-               ('Embassies', 'amenity', 'embassy', '-')}
+    assert set((p.p_label, p.p_class, p.p_type, p.p_operator) for p in phrases) == \
+        {('Zip Line', 'aerialway', 'zip_line', '-'),
+         ('Zip Lines', 'aerialway', 'zip_line', '-'),
+         ('Zip Line in', 'aerialway', 'zip_line', 'in'),
+         ('Zip Lines in', 'aerialway', 'zip_line', 'in'),
+         ('Zip Line near', 'aerialway', 'zip_line', 'near'),
+         ('Animal shelter', 'amenity', 'animal_shelter', '-'),
+         ('Animal shelters', 'amenity', 'animal_shelter', '-'),
+         ('Animal shelter in', 'amenity', 'animal_shelter', 'in'),
+         ('Animal shelters in', 'amenity', 'animal_shelter', 'in'),
+         ('Animal shelter near', 'amenity', 'animal_shelter', 'near'),
+         ('Animal shelters near', 'amenity', 'animal_shelter', 'near'),
+         ('Drinking Water near', 'amenity', 'drinking_water', 'near'),
+         ('Water', 'amenity', 'drinking_water', '-'),
+         ('Water in', 'amenity', 'drinking_water', 'in'),
+         ('Water near', 'amenity', 'drinking_water', 'near'),
+         ('Embassy', 'amenity', 'embassy', '-'),
+         ('Embassys', 'amenity', 'embassy', '-'),
+         ('Embassies', 'amenity', 'embassy', '-')}
index 5d65fafb3b5c4d272472269ece832ea7bb220be6..f7dfe32e6be4052cee2d4f4539a0ceba045f381f 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Test for tiger data function
 # For a full list of authors see the git log.
 """
 Test for tiger data function
@@ -11,12 +11,13 @@ import tarfile
 from textwrap import dedent
 
 import pytest
 from textwrap import dedent
 
 import pytest
-import pytest_asyncio
+import pytest_asyncio  # noqa: F401
 
 from nominatim_db.db.connection import execute_scalar
 from nominatim_db.tools import tiger_data, freeze
 from nominatim_db.errors import UsageError
 
 
 from nominatim_db.db.connection import execute_scalar
 from nominatim_db.tools import tiger_data, freeze
 from nominatim_db.errors import UsageError
 
+
 class MockTigerTable:
 
     def __init__(self, conn):
 class MockTigerTable:
 
     def __init__(self, conn):
@@ -40,6 +41,7 @@ class MockTigerTable:
             cur.execute("SELECT * FROM tiger LIMIT 1")
             return cur.fetchone()
 
             cur.execute("SELECT * FROM tiger LIMIT 1")
             return cur.fetchone()
 
+
 @pytest.fixture
 def tiger_table(def_config, temp_db_conn, sql_preprocessor,
                 temp_db_with_extensions, tmp_path):
 @pytest.fixture
 def tiger_table(def_config, temp_db_conn, sql_preprocessor,
                 temp_db_with_extensions, tmp_path):
@@ -87,7 +89,7 @@ async def test_add_tiger_data(def_config, src_dir, tiger_table, tokenizer_mock,
 
 @pytest.mark.asyncio
 async def test_add_tiger_data_database_frozen(def_config, temp_db_conn, tiger_table, tokenizer_mock,
 
 @pytest.mark.asyncio
 async def test_add_tiger_data_database_frozen(def_config, temp_db_conn, tiger_table, tokenizer_mock,
-                                 tmp_path):
+                                              tmp_path):
     freeze.drop_update_tables(temp_db_conn)
 
     with pytest.raises(UsageError) as excinfo:
     freeze.drop_update_tables(temp_db_conn)
 
     with pytest.raises(UsageError) as excinfo:
@@ -100,7 +102,7 @@ async def test_add_tiger_data_database_frozen(def_config, temp_db_conn, tiger_ta
 
 @pytest.mark.asyncio
 async def test_add_tiger_data_no_files(def_config, tiger_table, tokenizer_mock,
 
 @pytest.mark.asyncio
 async def test_add_tiger_data_no_files(def_config, tiger_table, tokenizer_mock,
-                                 tmp_path):
+                                       tmp_path):
     await tiger_data.add_tiger_data(str(tmp_path), def_config, 1, tokenizer_mock())
 
     assert tiger_table.count() == 0
     await tiger_data.add_tiger_data(str(tmp_path), def_config, 1, tokenizer_mock())
 
     assert tiger_table.count() == 0
@@ -108,7 +110,7 @@ async def test_add_tiger_data_no_files(def_config, tiger_table, tokenizer_mock,
 
 @pytest.mark.asyncio
 async def test_add_tiger_data_bad_file(def_config, tiger_table, tokenizer_mock,
 
 @pytest.mark.asyncio
 async def test_add_tiger_data_bad_file(def_config, tiger_table, tokenizer_mock,
-                                 tmp_path):
+                                       tmp_path):
     sqlfile = tmp_path / '1010.csv'
     sqlfile.write_text("""Random text""")
 
     sqlfile = tmp_path / '1010.csv'
     sqlfile.write_text("""Random text""")
 
@@ -119,7 +121,7 @@ async def test_add_tiger_data_bad_file(def_config, tiger_table, tokenizer_mock,
 
 @pytest.mark.asyncio
 async def test_add_tiger_data_hnr_nan(def_config, tiger_table, tokenizer_mock,
 
 @pytest.mark.asyncio
 async def test_add_tiger_data_hnr_nan(def_config, tiger_table, tokenizer_mock,
-                                csv_factory, tmp_path):
+                                      csv_factory, tmp_path):
     csv_factory('file1', hnr_from=99)
     csv_factory('file2', hnr_from='L12')
     csv_factory('file3', hnr_to='12.4')
     csv_factory('file1', hnr_from=99)
     csv_factory('file2', hnr_from='L12')
     csv_factory('file3', hnr_to='12.4')
@@ -133,7 +135,7 @@ async def test_add_tiger_data_hnr_nan(def_config, tiger_table, tokenizer_mock,
 @pytest.mark.parametrize("threads", (1, 5))
 @pytest.mark.asyncio
 async def test_add_tiger_data_tarfile(def_config, tiger_table, tokenizer_mock,
 @pytest.mark.parametrize("threads", (1, 5))
 @pytest.mark.asyncio
 async def test_add_tiger_data_tarfile(def_config, tiger_table, tokenizer_mock,
-                                tmp_path, src_dir, threads):
+                                      tmp_path, src_dir, threads):
     tar = tarfile.open(str(tmp_path / 'sample.tar.gz'), "w:gz")
     tar.add(str(src_dir / 'test' / 'testdb' / 'tiger' / '01001.csv'))
     tar.close()
     tar = tarfile.open(str(tmp_path / 'sample.tar.gz'), "w:gz")
     tar.add(str(src_dir / 'test' / 'testdb' / 'tiger' / '01001.csv'))
     tar.close()
@@ -146,7 +148,7 @@ async def test_add_tiger_data_tarfile(def_config, tiger_table, tokenizer_mock,
 
 @pytest.mark.asyncio
 async def test_add_tiger_data_bad_tarfile(def_config, tiger_table, tokenizer_mock,
 
 @pytest.mark.asyncio
 async def test_add_tiger_data_bad_tarfile(def_config, tiger_table, tokenizer_mock,
-                                    tmp_path):
+                                          tmp_path):
     tarfile = tmp_path / 'sample.tar.gz'
     tarfile.write_text("""Random text""")
 
     tarfile = tmp_path / 'sample.tar.gz'
     tarfile.write_text("""Random text""")
 
@@ -156,7 +158,7 @@ async def test_add_tiger_data_bad_tarfile(def_config, tiger_table, tokenizer_moc
 
 @pytest.mark.asyncio
 async def test_add_tiger_data_empty_tarfile(def_config, tiger_table, tokenizer_mock,
 
 @pytest.mark.asyncio
 async def test_add_tiger_data_empty_tarfile(def_config, tiger_table, tokenizer_mock,
-                                      tmp_path):
+                                            tmp_path):
     tar = tarfile.open(str(tmp_path / 'sample.tar.gz'), "w:gz")
     tar.add(__file__)
     tar.close()
     tar = tarfile.open(str(tmp_path / 'sample.tar.gz'), "w:gz")
     tar.add(__file__)
     tar.close()
index bac0edb3c406fd9ab45b74fb4d0e410ddfc982b2..664d5cd7a7f7d39438ce5a387a60ab06db8bb43e 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for centroid computation.
 # For a full list of authors see the git log.
 """
 Tests for centroid computation.
@@ -11,6 +11,7 @@ import pytest
 
 from nominatim_db.utils.centroid import PointsCentroid
 
 
 from nominatim_db.utils.centroid import PointsCentroid
 
+
 def test_empty_set():
     c = PointsCentroid()
 
 def test_empty_set():
     c = PointsCentroid()
 
@@ -18,7 +19,7 @@ def test_empty_set():
         c.centroid()
 
 
         c.centroid()
 
 
-@pytest.mark.parametrize("centroid", [(0,0), (-1, 3), [0.0000032, 88.4938]])
+@pytest.mark.parametrize("centroid", [(0, 0), (-1, 3), [0.0000032, 88.4938]])
 def test_one_point_centroid(centroid):
     c = PointsCentroid()
 
 def test_one_point_centroid(centroid):
     c = PointsCentroid()
 
index 53e3f4d3073ca01bcc1ad0bdc89f90c4a8c92234..c0946f010c97f6507c429bca9d4a244efbdec0c6 100644 (file)
@@ -2,7 +2,7 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2024 by the Nominatim developer community.
+# Copyright (C) 2025 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Tests for the streaming JSON writer.
 # For a full list of authors see the git log.
 """
 Tests for the streaming JSON writer.
@@ -13,6 +13,7 @@ import pytest
 
 from nominatim_api.utils.json_writer import JsonWriter
 
 
 from nominatim_api.utils.json_writer import JsonWriter
 
+
 @pytest.mark.parametrize("inval,outstr", [(None, 'null'),
                                           (True, 'true'), (False, 'false'),
                                           (23, '23'), (0, '0'), (-1.3, '-1.3'),
 @pytest.mark.parametrize("inval,outstr", [(None, 'null'),
                                           (True, 'true'), (False, 'false'),
                                           (23, '23'), (0, '0'), (-1.3, '-1.3'),
@@ -71,6 +72,7 @@ def test_object_single_entry():
     assert writer() == '{"something":5}'
     json.loads(writer())
 
     assert writer() == '{"something":5}'
     json.loads(writer())
 
+
 def test_object_many_values():
     writer = JsonWriter()\
                 .start_object()\
 def test_object_many_values():
     writer = JsonWriter()\
                 .start_object()\
@@ -82,6 +84,7 @@ def test_object_many_values():
     assert writer() == '{"foo":null,"bar":{},"baz":"b\\taz"}'
     json.loads(writer())
 
     assert writer() == '{"foo":null,"bar":{},"baz":"b\\taz"}'
     json.loads(writer())
 
+
 def test_object_many_values_without_none():
     writer = JsonWriter()\
                 .start_object()\
 def test_object_many_values_without_none():
     writer = JsonWriter()\
                 .start_object()\
@@ -89,7 +92,7 @@ def test_object_many_values_without_none():
                     .keyval_not_none('bar', None)\
                     .keyval_not_none('baz', '')\
                     .keyval_not_none('eve', False,
                     .keyval_not_none('bar', None)\
                     .keyval_not_none('baz', '')\
                     .keyval_not_none('eve', False,
-                                     transform = lambda v: 'yes' if v else 'no')\
+                                     transform=lambda v: 'yes' if v else 'no')\
                 .end_object()
 
     assert writer() == '{"foo":0,"baz":"","eve":"no"}'
                 .end_object()
 
     assert writer() == '{"foo":0,"baz":"","eve":"no"}'