]> git.openstreetmap.org Git - nominatim.git/commitdiff
fix style issue found by flake8
authorSarah Hoffmann <lonvia@denofr.de>
Sun, 10 Nov 2024 21:47:14 +0000 (22:47 +0100)
committerSarah Hoffmann <lonvia@denofr.de>
Sun, 10 Nov 2024 21:47:14 +0000 (22:47 +0100)
112 files changed:
.pylintrc [deleted file]
src/nominatim_api/config.py
src/nominatim_api/connection.py
src/nominatim_api/core.py
src/nominatim_api/errors.py
src/nominatim_api/localization.py
src/nominatim_api/logging.py
src/nominatim_api/lookup.py
src/nominatim_api/result_formatting.py
src/nominatim_api/results.py
src/nominatim_api/reverse.py
src/nominatim_api/search/db_search_builder.py
src/nominatim_api/search/db_search_fields.py
src/nominatim_api/search/db_search_lookups.py
src/nominatim_api/search/db_searches.py
src/nominatim_api/search/geocoder.py
src/nominatim_api/search/icu_tokenizer.py
src/nominatim_api/search/query.py
src/nominatim_api/search/query_analyzer_factory.py
src/nominatim_api/search/token_assignment.py
src/nominatim_api/server/asgi_adaptor.py
src/nominatim_api/server/falcon/server.py
src/nominatim_api/server/starlette/server.py
src/nominatim_api/sql/async_core_library.py
src/nominatim_api/sql/sqlalchemy_functions.py
src/nominatim_api/sql/sqlalchemy_schema.py
src/nominatim_api/sql/sqlalchemy_types/geometry.py
src/nominatim_api/sql/sqlalchemy_types/int_array.py
src/nominatim_api/sql/sqlalchemy_types/json.py
src/nominatim_api/sql/sqlalchemy_types/key_value.py
src/nominatim_api/sql/sqlite_functions.py
src/nominatim_api/status.py
src/nominatim_api/types.py
src/nominatim_api/typing.py
src/nominatim_api/utils/json_writer.py
src/nominatim_api/v1/__init__.py
src/nominatim_api/v1/classtypes.py
src/nominatim_api/v1/format.py
src/nominatim_api/v1/format_json.py
src/nominatim_api/v1/format_xml.py
src/nominatim_api/v1/helpers.py
src/nominatim_api/v1/server_glue.py
src/nominatim_db/cli.py
src/nominatim_db/clicmd/add_data.py
src/nominatim_db/clicmd/admin.py
src/nominatim_db/clicmd/api.py
src/nominatim_db/clicmd/args.py
src/nominatim_db/clicmd/convert.py
src/nominatim_db/clicmd/export.py
src/nominatim_db/clicmd/freeze.py
src/nominatim_db/clicmd/index.py
src/nominatim_db/clicmd/refresh.py
src/nominatim_db/clicmd/replication.py
src/nominatim_db/clicmd/setup.py
src/nominatim_db/clicmd/special_phrases.py
src/nominatim_db/config.py
src/nominatim_db/data/country_info.py
src/nominatim_db/data/place_info.py
src/nominatim_db/data/place_name.py
src/nominatim_db/data/postcode_format.py
src/nominatim_db/db/connection.py
src/nominatim_db/db/properties.py
src/nominatim_db/db/query_pool.py
src/nominatim_db/db/sql_preprocessor.py
src/nominatim_db/db/utils.py
src/nominatim_db/errors.py
src/nominatim_db/indexer/indexer.py
src/nominatim_db/indexer/progress.py
src/nominatim_db/indexer/runners.py
src/nominatim_db/tokenizer/base.py
src/nominatim_db/tokenizer/factory.py
src/nominatim_db/tokenizer/icu_rule_loader.py
src/nominatim_db/tokenizer/icu_token_analysis.py
src/nominatim_db/tokenizer/icu_tokenizer.py
src/nominatim_db/tokenizer/place_sanitizer.py
src/nominatim_db/tokenizer/sanitizers/base.py
src/nominatim_db/tokenizer/sanitizers/clean_housenumbers.py
src/nominatim_db/tokenizer/sanitizers/clean_postcodes.py
src/nominatim_db/tokenizer/sanitizers/clean_tiger_tags.py
src/nominatim_db/tokenizer/sanitizers/config.py
src/nominatim_db/tokenizer/sanitizers/delete_tags.py
src/nominatim_db/tokenizer/sanitizers/split_name_list.py
src/nominatim_db/tokenizer/sanitizers/tag_analyzer_by_language.py
src/nominatim_db/tokenizer/sanitizers/tag_japanese.py
src/nominatim_db/tokenizer/token_analysis/base.py
src/nominatim_db/tokenizer/token_analysis/config_variants.py
src/nominatim_db/tokenizer/token_analysis/generic.py
src/nominatim_db/tokenizer/token_analysis/generic_mutation.py
src/nominatim_db/tokenizer/token_analysis/housenumbers.py
src/nominatim_db/tokenizer/token_analysis/postcodes.py
src/nominatim_db/tools/add_osm_data.py
src/nominatim_db/tools/admin.py
src/nominatim_db/tools/check_database.py
src/nominatim_db/tools/collect_os_info.py
src/nominatim_db/tools/convert_sqlite.py
src/nominatim_db/tools/database_import.py
src/nominatim_db/tools/exec_utils.py
src/nominatim_db/tools/freeze.py
src/nominatim_db/tools/migration.py
src/nominatim_db/tools/postcodes.py
src/nominatim_db/tools/refresh.py
src/nominatim_db/tools/replication.py
src/nominatim_db/tools/special_phrases/importer_statistics.py
src/nominatim_db/tools/special_phrases/sp_csv_loader.py
src/nominatim_db/tools/special_phrases/sp_importer.py
src/nominatim_db/tools/special_phrases/sp_wiki_loader.py
src/nominatim_db/tools/special_phrases/special_phrase.py
src/nominatim_db/tools/tiger_data.py
src/nominatim_db/typing.py
src/nominatim_db/utils/centroid.py
src/nominatim_db/utils/url_utils.py
src/nominatim_db/version.py

diff --git a/.pylintrc b/.pylintrc
deleted file mode 100644 (file)
index e562055..0000000
--- a/.pylintrc
+++ /dev/null
@@ -1,22 +0,0 @@
-[MASTER]
-
-extension-pkg-whitelist=osmium,falcon
-ignored-modules=icu,datrie
-
-[MESSAGES CONTROL]
-
-[TYPECHECK]
-
-# closing added here because it sometimes triggers a false positive with
-# 'with' statements.
-ignored-classes=NominatimArgs,closing
-# 'too-many-ancestors' is triggered already by deriving from UserDict
-# 'not-context-manager' disabled because it causes false positives once
-#   typed Python is enabled. See also https://github.com/PyCQA/pylint/issues/5273
-disable=too-few-public-methods,duplicate-code,too-many-ancestors,bad-option-value,no-self-use,not-context-manager,use-dict-literal,chained-comparison,attribute-defined-outside-init,too-many-boolean-expressions,contextmanager-generator-missing-cleanup,too-many-positional-arguments
-
-good-names=i,j,x,y,m,t,fd,db,cc,x1,x2,y1,y2,pt,k,v,nr
-
-[DESIGN]
-
-max-returns=7
index 18afda66879f6adfa5bf28dfb4ebcf9cc8e579ee..94f3bb5d0e3456ba54bffdd5ed99b3e7d9e2d96e 100644 (file)
@@ -8,5 +8,5 @@
 # This file is just a placeholder to make the config module available
 # during development. It will be replaced by nominatim_db/config.py on
 # installation.
 # This file is just a placeholder to make the config module available
 # during development. It will be replaced by nominatim_db/config.py on
 # installation.
-# pylint: skip-file
+# flake8: noqa
 from nominatim_db.config import *
 from nominatim_db.config import *
index 167ffaa45492e9943d2f755ce3509331ebf9dd42..e104745ebe784de098b97bb6a9d70f9a5a7a0d52 100644 (file)
@@ -21,6 +21,7 @@ from .logging import log
 
 T = TypeVar('T')
 
 
 T = TypeVar('T')
 
+
 class SearchConnection:
     """ An extended SQLAlchemy connection class, that also contains
         the table definitions. The underlying asynchronous SQLAlchemy
 class SearchConnection:
     """ An extended SQLAlchemy connection class, that also contains
         the table definitions. The underlying asynchronous SQLAlchemy
@@ -32,37 +33,32 @@ class SearchConnection:
                  tables: SearchTables,
                  properties: Dict[str, Any]) -> None:
         self.connection = conn
                  tables: SearchTables,
                  properties: Dict[str, Any]) -> None:
         self.connection = conn
-        self.t = tables # pylint: disable=invalid-name
+        self.t = tables
         self._property_cache = properties
         self._classtables: Optional[Set[str]] = None
         self.query_timeout: Optional[int] = None
 
         self._property_cache = properties
         self._classtables: Optional[Set[str]] = None
         self.query_timeout: Optional[int] = None
 
-
     def set_query_timeout(self, timeout: Optional[int]) -> None:
         """ Set the timeout after which a query over this connection
             is cancelled.
         """
         self.query_timeout = timeout
 
     def set_query_timeout(self, timeout: Optional[int]) -> None:
         """ Set the timeout after which a query over this connection
             is cancelled.
         """
         self.query_timeout = timeout
 
-
     async def scalar(self, sql: sa.sql.base.Executable,
     async def scalar(self, sql: sa.sql.base.Executable,
-                     params: Union[Mapping[str, Any], None] = None
-                    ) -> Any:
+                     params: Union[Mapping[str, Any], None] = None) -> Any:
         """ Execute a 'scalar()' query on the connection.
         """
         log().sql(self.connection, sql, params)
         return await asyncio.wait_for(self.connection.scalar(sql, params), self.query_timeout)
 
         """ Execute a 'scalar()' query on the connection.
         """
         log().sql(self.connection, sql, params)
         return await asyncio.wait_for(self.connection.scalar(sql, params), self.query_timeout)
 
-
     async def execute(self, sql: 'sa.Executable',
                       params: Union[Mapping[str, Any], Sequence[Mapping[str, Any]], None] = None
     async def execute(self, sql: 'sa.Executable',
                       params: Union[Mapping[str, Any], Sequence[Mapping[str, Any]], None] = None
-                     ) -> 'sa.Result[Any]':
+                      ) -> 'sa.Result[Any]':
         """ Execute a 'execute()' query on the connection.
         """
         log().sql(self.connection, sql, params)
         return await asyncio.wait_for(self.connection.execute(sql, params), self.query_timeout)
 
         """ Execute a 'execute()' query on the connection.
         """
         log().sql(self.connection, sql, params)
         return await asyncio.wait_for(self.connection.execute(sql, params), self.query_timeout)
 
-
     async def get_property(self, name: str, cached: bool = True) -> str:
         """ Get a property from Nominatim's property table.
 
     async def get_property(self, name: str, cached: bool = True) -> str:
         """ Get a property from Nominatim's property table.
 
@@ -89,7 +85,6 @@ class SearchConnection:
 
         return cast(str, value)
 
 
         return cast(str, value)
 
-
     async def get_db_property(self, name: str) -> Any:
         """ Get a setting from the database. At the moment, only
             'server_version', the version of the database software, can
     async def get_db_property(self, name: str) -> Any:
         """ Get a setting from the database. At the moment, only
             'server_version', the version of the database software, can
@@ -102,7 +97,6 @@ class SearchConnection:
 
         return self._property_cache['DB:server_version']
 
 
         return self._property_cache['DB:server_version']
 
-
     async def get_cached_value(self, group: str, name: str,
                                factory: Callable[[], Awaitable[T]]) -> T:
         """ Access the cache for this Nominatim instance.
     async def get_cached_value(self, group: str, name: str,
                                factory: Callable[[], Awaitable[T]]) -> T:
         """ Access the cache for this Nominatim instance.
@@ -125,7 +119,6 @@ class SearchConnection:
 
         return value
 
 
         return value
 
-
     async def get_class_table(self, cls: str, typ: str) -> Optional[SaFromClause]:
         """ Lookup up if there is a classtype table for the given category
             and return a SQLAlchemy table for it, if it exists.
     async def get_class_table(self, cls: str, typ: str) -> Optional[SaFromClause]:
         """ Lookup up if there is a classtype table for the given category
             and return a SQLAlchemy table for it, if it exists.
index ff0db39f820b51585abd3fd4723ee886a455027b..3f4652bff27874c47f3788323561ce9a93b3b4ef 100644 (file)
@@ -7,7 +7,7 @@
 """
 Implementation of classes for API access via libraries.
 """
 """
 Implementation of classes for API access via libraries.
 """
-from typing import Mapping, Optional, Any, AsyncIterator, Dict, Sequence, List,\
+from typing import Mapping, Optional, Any, AsyncIterator, Dict, Sequence, List, \
                    Union, Tuple, cast
 import asyncio
 import sys
                    Union, Tuple, cast
 import asyncio
 import sys
@@ -21,7 +21,7 @@ from .errors import UsageError
 from .sql.sqlalchemy_schema import SearchTables
 from .sql.async_core_library import PGCORE_LIB, PGCORE_ERROR
 from .config import Configuration
 from .sql.sqlalchemy_schema import SearchTables
 from .sql.async_core_library import PGCORE_LIB, PGCORE_ERROR
 from .config import Configuration
-from .sql import sqlite_functions, sqlalchemy_functions #pylint: disable=unused-import
+from .sql import sqlite_functions, sqlalchemy_functions  # noqa
 from .connection import SearchConnection
 from .status import get_status, StatusResult
 from .lookup import get_detailed_place, get_simple_place
 from .connection import SearchConnection
 from .status import get_status, StatusResult
 from .lookup import get_detailed_place, get_simple_place
@@ -31,7 +31,7 @@ from . import types as ntyp
 from .results import DetailedResult, ReverseResult, SearchResults
 
 
 from .results import DetailedResult, ReverseResult, SearchResults
 
 
-class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
+class NominatimAPIAsync:
     """ The main frontend to the Nominatim database implements the
         functions for lookup, forward and reverse geocoding using
         asynchronous functions.
     """ The main frontend to the Nominatim database implements the
         functions for lookup, forward and reverse geocoding using
         asynchronous functions.
@@ -61,19 +61,18 @@ class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
         """
         self.config = Configuration(project_dir, environ)
         self.query_timeout = self.config.get_int('QUERY_TIMEOUT') \
         """
         self.config = Configuration(project_dir, environ)
         self.query_timeout = self.config.get_int('QUERY_TIMEOUT') \
-                             if self.config.QUERY_TIMEOUT else None
+            if self.config.QUERY_TIMEOUT else None
         self.reverse_restrict_to_country_area = self.config.get_bool('SEARCH_WITHIN_COUNTRIES')
         self.server_version = 0
 
         if sys.version_info >= (3, 10):
             self._engine_lock = asyncio.Lock()
         else:
         self.reverse_restrict_to_country_area = self.config.get_bool('SEARCH_WITHIN_COUNTRIES')
         self.server_version = 0
 
         if sys.version_info >= (3, 10):
             self._engine_lock = asyncio.Lock()
         else:
-            self._engine_lock = asyncio.Lock(loop=loop) # pylint: disable=unexpected-keyword-arg
+            self._engine_lock = asyncio.Lock(loop=loop)
         self._engine: Optional[sa_asyncio.AsyncEngine] = None
         self._tables: Optional[SearchTables] = None
         self._property_cache: Dict[str, Any] = {'DB:server_version': 0}
 
         self._engine: Optional[sa_asyncio.AsyncEngine] = None
         self._tables: Optional[SearchTables] = None
         self._property_cache: Dict[str, Any] = {'DB:server_version': 0}
 
-
     async def setup_database(self) -> None:
         """ Set up the SQL engine and connections.
 
     async def setup_database(self) -> None:
         """ Set up the SQL engine and connections.
 
@@ -95,7 +94,6 @@ class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
                 extra_args['max_overflow'] = 0
                 extra_args['pool_size'] = self.config.get_int('API_POOL_SIZE')
 
                 extra_args['max_overflow'] = 0
                 extra_args['pool_size'] = self.config.get_int('API_POOL_SIZE')
 
-
             is_sqlite = self.config.DATABASE_DSN.startswith('sqlite:')
 
             if is_sqlite:
             is_sqlite = self.config.DATABASE_DSN.startswith('sqlite:')
 
             if is_sqlite:
@@ -156,10 +154,9 @@ class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
 
             self._property_cache['DB:server_version'] = server_version
 
 
             self._property_cache['DB:server_version'] = server_version
 
-            self._tables = SearchTables(sa.MetaData()) # pylint: disable=no-member
+            self._tables = SearchTables(sa.MetaData())
             self._engine = engine
 
             self._engine = engine
 
-
     async def close(self) -> None:
         """ Close all active connections to the database. The NominatimAPIAsync
             object remains usable after closing. If a new API functions is
     async def close(self) -> None:
         """ Close all active connections to the database. The NominatimAPIAsync
             object remains usable after closing. If a new API functions is
@@ -168,15 +165,12 @@ class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
         if self._engine is not None:
             await self._engine.dispose()
 
         if self._engine is not None:
             await self._engine.dispose()
 
-
     async def __aenter__(self) -> 'NominatimAPIAsync':
         return self
 
     async def __aenter__(self) -> 'NominatimAPIAsync':
         return self
 
-
     async def __aexit__(self, *_: Any) -> None:
         await self.close()
 
     async def __aexit__(self, *_: Any) -> None:
         await self.close()
 
-
     @contextlib.asynccontextmanager
     async def begin(self) -> AsyncIterator[SearchConnection]:
         """ Create a new connection with automatic transaction handling.
     @contextlib.asynccontextmanager
     async def begin(self) -> AsyncIterator[SearchConnection]:
         """ Create a new connection with automatic transaction handling.
@@ -194,7 +188,6 @@ class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
         async with self._engine.begin() as conn:
             yield SearchConnection(conn, self._tables, self._property_cache)
 
         async with self._engine.begin() as conn:
             yield SearchConnection(conn, self._tables, self._property_cache)
 
-
     async def status(self) -> StatusResult:
         """ Return the status of the database.
         """
     async def status(self) -> StatusResult:
         """ Return the status of the database.
         """
@@ -207,7 +200,6 @@ class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
 
         return status
 
 
         return status
 
-
     async def details(self, place: ntyp.PlaceRef, **params: Any) -> Optional[DetailedResult]:
         """ Get detailed information about a place in the database.
 
     async def details(self, place: ntyp.PlaceRef, **params: Any) -> Optional[DetailedResult]:
         """ Get detailed information about a place in the database.
 
@@ -220,7 +212,6 @@ class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
                 await make_query_analyzer(conn)
             return await get_detailed_place(conn, place, details)
 
                 await make_query_analyzer(conn)
             return await get_detailed_place(conn, place, details)
 
-
     async def lookup(self, places: Sequence[ntyp.PlaceRef], **params: Any) -> SearchResults:
         """ Get simple information about a list of places.
 
     async def lookup(self, places: Sequence[ntyp.PlaceRef], **params: Any) -> SearchResults:
         """ Get simple information about a list of places.
 
@@ -234,7 +225,6 @@ class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
             return SearchResults(filter(None,
                                         [await get_simple_place(conn, p, details) for p in places]))
 
             return SearchResults(filter(None,
                                         [await get_simple_place(conn, p, details) for p in places]))
 
-
     async def reverse(self, coord: ntyp.AnyPoint, **params: Any) -> Optional[ReverseResult]:
         """ Find a place by its coordinates. Also known as reverse geocoding.
 
     async def reverse(self, coord: ntyp.AnyPoint, **params: Any) -> Optional[ReverseResult]:
         """ Find a place by its coordinates. Also known as reverse geocoding.
 
@@ -255,7 +245,6 @@ class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
                                        self.reverse_restrict_to_country_area)
             return await geocoder.lookup(coord)
 
                                        self.reverse_restrict_to_country_area)
             return await geocoder.lookup(coord)
 
-
     async def search(self, query: str, **params: Any) -> SearchResults:
         """ Find a place by free-text search. Also known as forward geocoding.
         """
     async def search(self, query: str, **params: Any) -> SearchResults:
         """ Find a place by free-text search. Also known as forward geocoding.
         """
@@ -266,13 +255,11 @@ class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
         async with self.begin() as conn:
             conn.set_query_timeout(self.query_timeout)
             geocoder = ForwardGeocoder(conn, ntyp.SearchDetails.from_kwargs(params),
         async with self.begin() as conn:
             conn.set_query_timeout(self.query_timeout)
             geocoder = ForwardGeocoder(conn, ntyp.SearchDetails.from_kwargs(params),
-                                       self.config.get_int('REQUEST_TIMEOUT') \
-                                         if self.config.REQUEST_TIMEOUT else None)
+                                       self.config.get_int('REQUEST_TIMEOUT')
+                                       if self.config.REQUEST_TIMEOUT else None)
             phrases = [Phrase(PhraseType.NONE, p.strip()) for p in query.split(',')]
             return await geocoder.lookup(phrases)
 
             phrases = [Phrase(PhraseType.NONE, p.strip()) for p in query.split(',')]
             return await geocoder.lookup(phrases)
 
-
-    # pylint: disable=too-many-arguments,too-many-branches
     async def search_address(self, amenity: Optional[str] = None,
                              street: Optional[str] = None,
                              city: Optional[str] = None,
     async def search_address(self, amenity: Optional[str] = None,
                              street: Optional[str] = None,
                              city: Optional[str] = None,
@@ -326,11 +313,10 @@ class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
                     details.layers |= ntyp.DataLayer.POI
 
             geocoder = ForwardGeocoder(conn, details,
                     details.layers |= ntyp.DataLayer.POI
 
             geocoder = ForwardGeocoder(conn, details,
-                                       self.config.get_int('REQUEST_TIMEOUT') \
-                                         if self.config.REQUEST_TIMEOUT else None)
+                                       self.config.get_int('REQUEST_TIMEOUT')
+                                       if self.config.REQUEST_TIMEOUT else None)
             return await geocoder.lookup(phrases)
 
             return await geocoder.lookup(phrases)
 
-
     async def search_category(self, categories: List[Tuple[str, str]],
                               near_query: Optional[str] = None,
                               **params: Any) -> SearchResults:
     async def search_category(self, categories: List[Tuple[str, str]],
                               near_query: Optional[str] = None,
                               **params: Any) -> SearchResults:
@@ -352,12 +338,11 @@ class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
                     await make_query_analyzer(conn)
 
             geocoder = ForwardGeocoder(conn, details,
                     await make_query_analyzer(conn)
 
             geocoder = ForwardGeocoder(conn, details,
-                                       self.config.get_int('REQUEST_TIMEOUT') \
-                                         if self.config.REQUEST_TIMEOUT else None)
+                                       self.config.get_int('REQUEST_TIMEOUT')
+                                       if self.config.REQUEST_TIMEOUT else None)
             return await geocoder.lookup_pois(categories, phrases)
 
 
             return await geocoder.lookup_pois(categories, phrases)
 
 
-
 class NominatimAPI:
     """ This class provides a thin synchronous wrapper around the asynchronous
         Nominatim functions. It creates its own event loop and runs each
 class NominatimAPI:
     """ This class provides a thin synchronous wrapper around the asynchronous
         Nominatim functions. It creates its own event loop and runs each
@@ -382,7 +367,6 @@ class NominatimAPI:
         self._loop = asyncio.new_event_loop()
         self._async_api = NominatimAPIAsync(project_dir, environ, loop=self._loop)
 
         self._loop = asyncio.new_event_loop()
         self._async_api = NominatimAPIAsync(project_dir, environ, loop=self._loop)
 
-
     def close(self) -> None:
         """ Close all active connections to the database.
 
     def close(self) -> None:
         """ Close all active connections to the database.
 
@@ -393,15 +377,12 @@ class NominatimAPI:
             self._loop.run_until_complete(self._async_api.close())
             self._loop.close()
 
             self._loop.run_until_complete(self._async_api.close())
             self._loop.close()
 
-
     def __enter__(self) -> 'NominatimAPI':
         return self
 
     def __enter__(self) -> 'NominatimAPI':
         return self
 
-
     def __exit__(self, *_: Any) -> None:
         self.close()
 
     def __exit__(self, *_: Any) -> None:
         self.close()
 
-
     @property
     def config(self) -> Configuration:
         """ Provide read-only access to the [configuration](Configuration.md)
     @property
     def config(self) -> Configuration:
         """ Provide read-only access to the [configuration](Configuration.md)
@@ -427,7 +408,6 @@ class NominatimAPI:
         """
         return self._loop.run_until_complete(self._async_api.status())
 
         """
         return self._loop.run_until_complete(self._async_api.status())
 
-
     def details(self, place: ntyp.PlaceRef, **params: Any) -> Optional[DetailedResult]:
         """ Get detailed information about a place in the database.
 
     def details(self, place: ntyp.PlaceRef, **params: Any) -> Optional[DetailedResult]:
         """ Get detailed information about a place in the database.
 
@@ -510,7 +490,6 @@ class NominatimAPI:
         """
         return self._loop.run_until_complete(self._async_api.details(place, **params))
 
         """
         return self._loop.run_until_complete(self._async_api.details(place, **params))
 
-
     def lookup(self, places: Sequence[ntyp.PlaceRef], **params: Any) -> SearchResults:
         """ Get simple information about a list of places.
 
     def lookup(self, places: Sequence[ntyp.PlaceRef], **params: Any) -> SearchResults:
         """ Get simple information about a list of places.
 
@@ -587,7 +566,6 @@ class NominatimAPI:
         """
         return self._loop.run_until_complete(self._async_api.lookup(places, **params))
 
         """
         return self._loop.run_until_complete(self._async_api.lookup(places, **params))
 
-
     def reverse(self, coord: ntyp.AnyPoint, **params: Any) -> Optional[ReverseResult]:
         """ Find a place by its coordinates. Also known as reverse geocoding.
 
     def reverse(self, coord: ntyp.AnyPoint, **params: Any) -> Optional[ReverseResult]:
         """ Find a place by its coordinates. Also known as reverse geocoding.
 
@@ -669,7 +647,6 @@ class NominatimAPI:
         """
         return self._loop.run_until_complete(self._async_api.reverse(coord, **params))
 
         """
         return self._loop.run_until_complete(self._async_api.reverse(coord, **params))
 
-
     def search(self, query: str, **params: Any) -> SearchResults:
         """ Find a place by free-text search. Also known as forward geocoding.
 
     def search(self, query: str, **params: Any) -> SearchResults:
         """ Find a place by free-text search. Also known as forward geocoding.
 
@@ -769,8 +746,6 @@ class NominatimAPI:
         return self._loop.run_until_complete(
                    self._async_api.search(query, **params))
 
         return self._loop.run_until_complete(
                    self._async_api.search(query, **params))
 
-
-    # pylint: disable=too-many-arguments
     def search_address(self, amenity: Optional[str] = None,
                        street: Optional[str] = None,
                        city: Optional[str] = None,
     def search_address(self, amenity: Optional[str] = None,
                        street: Optional[str] = None,
                        city: Optional[str] = None,
@@ -888,7 +863,6 @@ class NominatimAPI:
                    self._async_api.search_address(amenity, street, city, county,
                                                   state, country, postalcode, **params))
 
                    self._async_api.search_address(amenity, street, city, county,
                                                   state, country, postalcode, **params))
 
-
     def search_category(self, categories: List[Tuple[str, str]],
                         near_query: Optional[str] = None,
                         **params: Any) -> SearchResults:
     def search_category(self, categories: List[Tuple[str, str]],
                         near_query: Optional[str] = None,
                         **params: Any) -> SearchResults:
index c7331a89f7519d06f85ac34a8d4f61ad1299d6e7..98fe693d12b51dfba2865f52c7ab6181861c52ca 100644 (file)
@@ -8,6 +8,7 @@
 Custom exception and error classes for Nominatim.
 """
 
 Custom exception and error classes for Nominatim.
 """
 
+
 class UsageError(Exception):
     """ An error raised because of bad user input. This error will usually
         not cause a stack trace to be printed unless debugging is enabled.
 class UsageError(Exception):
     """ An error raised because of bad user input. This error will usually
         not cause a stack trace to be printed unless debugging is enabled.
index 5964bbee8d1084af8291da8a52184c776e814b3b..bbf9225bb22fdac08fd6217dd84b14959aa21604 100644 (file)
@@ -11,6 +11,7 @@ from typing import Mapping, List, Optional
 
 import re
 
 
 import re
 
+
 class Locales:
     """ Helper class for localization of names.
 
 class Locales:
     """ Helper class for localization of names.
 
@@ -28,24 +29,20 @@ class Locales:
         self._add_lang_tags('official_name', 'short_name')
         self._add_tags('official_name', 'short_name', 'ref')
 
         self._add_lang_tags('official_name', 'short_name')
         self._add_tags('official_name', 'short_name', 'ref')
 
-
     def __bool__(self) -> bool:
         return len(self.languages) > 0
 
     def __bool__(self) -> bool:
         return len(self.languages) > 0
 
-
     def _add_tags(self, *tags: str) -> None:
         for tag in tags:
             self.name_tags.append(tag)
             self.name_tags.append(f"_place_{tag}")
 
     def _add_tags(self, *tags: str) -> None:
         for tag in tags:
             self.name_tags.append(tag)
             self.name_tags.append(f"_place_{tag}")
 
-
     def _add_lang_tags(self, *tags: str) -> None:
         for tag in tags:
             for lang in self.languages:
                 self.name_tags.append(f"{tag}:{lang}")
                 self.name_tags.append(f"_place_{tag}:{lang}")
 
     def _add_lang_tags(self, *tags: str) -> None:
         for tag in tags:
             for lang in self.languages:
                 self.name_tags.append(f"{tag}:{lang}")
                 self.name_tags.append(f"_place_{tag}:{lang}")
 
-
     def display_name(self, names: Optional[Mapping[str, str]]) -> str:
         """ Return the best matching name from a dictionary of names
             containing different name variants.
     def display_name(self, names: Optional[Mapping[str, str]]) -> str:
         """ Return the best matching name from a dictionary of names
             containing different name variants.
@@ -64,7 +61,6 @@ class Locales:
         # Nothing? Return any of the other names as a default.
         return next(iter(names.values()))
 
         # Nothing? Return any of the other names as a default.
         return next(iter(names.values()))
 
-
     @staticmethod
     def from_accept_languages(langstr: str) -> 'Locales':
         """ Create a localization object from a language list in the
     @staticmethod
     def from_accept_languages(langstr: str) -> 'Locales':
         """ Create a localization object from a language list in the
index 7df36ec12f21e0717497272743ff7c22d0b71a02..1a6aef9b52a009c6398605491e269dd50c76862b 100644 (file)
@@ -49,41 +49,35 @@ class BaseLogger:
         """ Start a new debug chapter for the given function and its parameters.
         """
 
         """ Start a new debug chapter for the given function and its parameters.
         """
 
-
     def section(self, heading: str) -> None:
         """ Start a new section with the given title.
         """
 
     def section(self, heading: str) -> None:
         """ Start a new section with the given title.
         """
 
-
     def comment(self, text: str) -> None:
         """ Add a simple comment to the debug output.
         """
 
     def comment(self, text: str) -> None:
         """ Add a simple comment to the debug output.
         """
 
-
     def var_dump(self, heading: str, var: Any) -> None:
         """ Print the content of the variable to the debug output prefixed by
             the given heading.
         """
 
     def var_dump(self, heading: str, var: Any) -> None:
         """ Print the content of the variable to the debug output prefixed by
             the given heading.
         """
 
-
     def table_dump(self, heading: str, rows: Iterator[Optional[List[Any]]]) -> None:
         """ Print the table generated by the generator function.
         """
 
     def table_dump(self, heading: str, rows: Iterator[Optional[List[Any]]]) -> None:
         """ Print the table generated by the generator function.
         """
 
-
     def result_dump(self, heading: str, results: Iterator[Tuple[Any, Any]]) -> None:
         """ Print a list of search results generated by the generator function.
         """
 
     def result_dump(self, heading: str, results: Iterator[Tuple[Any, Any]]) -> None:
         """ Print a list of search results generated by the generator function.
         """
 
-
     def sql(self, conn: AsyncConnection, statement: 'sa.Executable',
             params: Union[Mapping[str, Any], Sequence[Mapping[str, Any]], None]) -> None:
         """ Print the SQL for the given statement.
         """
 
     def format_sql(self, conn: AsyncConnection, statement: 'sa.Executable',
     def sql(self, conn: AsyncConnection, statement: 'sa.Executable',
             params: Union[Mapping[str, Any], Sequence[Mapping[str, Any]], None]) -> None:
         """ Print the SQL for the given statement.
         """
 
     def format_sql(self, conn: AsyncConnection, statement: 'sa.Executable',
-                   extra_params: Union[Mapping[str, Any],
-                                 Sequence[Mapping[str, Any]], None]) -> str:
+                   extra_params: Union[Mapping[str, Any], Sequence[Mapping[str, Any]], None]
+                   ) -> str:
         """ Return the compiled version of the statement.
         """
         compiled = cast('sa.ClauseElement', statement).compile(conn.sync_engine)
         """ Return the compiled version of the statement.
         """
         compiled = cast('sa.ClauseElement', statement).compile(conn.sync_engine)
@@ -108,7 +102,7 @@ class BaseLogger:
                 try:
                     sqlstr = re.sub(r'__\[POSTCOMPILE_[^]]*\]', '%s', sqlstr)
                     return sqlstr % tuple((repr(params.get(name, None))
                 try:
                     sqlstr = re.sub(r'__\[POSTCOMPILE_[^]]*\]', '%s', sqlstr)
                     return sqlstr % tuple((repr(params.get(name, None))
-                                          for name in compiled.positiontup)) # type: ignore
+                                          for name in compiled.positiontup))  # type: ignore
                 except TypeError:
                     return sqlstr
 
                 except TypeError:
                     return sqlstr
 
@@ -121,28 +115,26 @@ class BaseLogger:
         assert conn.dialect.name == 'sqlite'
 
         # params in positional order
         assert conn.dialect.name == 'sqlite'
 
         # params in positional order
-        pparams = (repr(params.get(name, None)) for name in compiled.positiontup) # type: ignore
+        pparams = (repr(params.get(name, None)) for name in compiled.positiontup)  # type: ignore
 
         sqlstr = re.sub(r'__\[POSTCOMPILE_([^]]*)\]', '?', sqlstr)
         sqlstr = re.sub(r"\?", lambda m: next(pparams), sqlstr)
 
         return sqlstr
 
 
         sqlstr = re.sub(r'__\[POSTCOMPILE_([^]]*)\]', '?', sqlstr)
         sqlstr = re.sub(r"\?", lambda m: next(pparams), sqlstr)
 
         return sqlstr
 
+
 class HTMLLogger(BaseLogger):
     """ Logger that formats messages in HTML.
     """
     def __init__(self) -> None:
         self.buffer = io.StringIO()
 
 class HTMLLogger(BaseLogger):
     """ Logger that formats messages in HTML.
     """
     def __init__(self) -> None:
         self.buffer = io.StringIO()
 
-
     def _timestamp(self) -> None:
         self._write(f'<p class="timestamp">[{dt.datetime.now()}]</p>')
 
     def _timestamp(self) -> None:
         self._write(f'<p class="timestamp">[{dt.datetime.now()}]</p>')
 
-
     def get_buffer(self) -> str:
         return HTML_HEADER + self.buffer.getvalue() + HTML_FOOTER
 
     def get_buffer(self) -> str:
         return HTML_HEADER + self.buffer.getvalue() + HTML_FOOTER
 
-
     def function(self, func: str, **kwargs: Any) -> None:
         self._timestamp()
         self._write(f"<h1>Debug output for {func}()</h1>\n<p>Parameters:<dl>")
     def function(self, func: str, **kwargs: Any) -> None:
         self._timestamp()
         self._write(f"<h1>Debug output for {func}()</h1>\n<p>Parameters:<dl>")
@@ -150,17 +142,14 @@ class HTMLLogger(BaseLogger):
             self._write(f'<dt>{name}</dt><dd>{self._python_var(value)}</dd>')
         self._write('</dl></p>')
 
             self._write(f'<dt>{name}</dt><dd>{self._python_var(value)}</dd>')
         self._write('</dl></p>')
 
-
     def section(self, heading: str) -> None:
         self._timestamp()
         self._write(f"<h2>{heading}</h2>")
 
     def section(self, heading: str) -> None:
         self._timestamp()
         self._write(f"<h2>{heading}</h2>")
 
-
     def comment(self, text: str) -> None:
         self._timestamp()
         self._write(f"<p>{text}</p>")
 
     def comment(self, text: str) -> None:
         self._timestamp()
         self._write(f"<p>{text}</p>")
 
-
     def var_dump(self, heading: str, var: Any) -> None:
         self._timestamp()
         if callable(var):
     def var_dump(self, heading: str, var: Any) -> None:
         self._timestamp()
         if callable(var):
@@ -168,7 +157,6 @@ class HTMLLogger(BaseLogger):
 
         self._write(f'<h5>{heading}</h5>{self._python_var(var)}')
 
 
         self._write(f'<h5>{heading}</h5>{self._python_var(var)}')
 
-
     def table_dump(self, heading: str, rows: Iterator[Optional[List[Any]]]) -> None:
         self._timestamp()
         head = next(rows)
     def table_dump(self, heading: str, rows: Iterator[Optional[List[Any]]]) -> None:
         self._timestamp()
         head = next(rows)
@@ -185,11 +173,11 @@ class HTMLLogger(BaseLogger):
                 self._write('</tr>')
         self._write('</tbody></table>')
 
                 self._write('</tr>')
         self._write('</tbody></table>')
 
-
     def result_dump(self, heading: str, results: Iterator[Tuple[Any, Any]]) -> None:
         """ Print a list of search results generated by the generator function.
         """
         self._timestamp()
     def result_dump(self, heading: str, results: Iterator[Tuple[Any, Any]]) -> None:
         """ Print a list of search results generated by the generator function.
         """
         self._timestamp()
+
         def format_osm(osm_object: Optional[Tuple[str, int]]) -> str:
             if not osm_object:
                 return '-'
         def format_osm(osm_object: Optional[Tuple[str, int]]) -> str:
             if not osm_object:
                 return '-'
@@ -218,7 +206,6 @@ class HTMLLogger(BaseLogger):
             total += 1
         self._write(f'</dl><b>TOTAL:</b> {total}</p>')
 
             total += 1
         self._write(f'</dl><b>TOTAL:</b> {total}</p>')
 
-
     def sql(self, conn: AsyncConnection, statement: 'sa.Executable',
             params: Union[Mapping[str, Any], Sequence[Mapping[str, Any]], None]) -> None:
         self._timestamp()
     def sql(self, conn: AsyncConnection, statement: 'sa.Executable',
             params: Union[Mapping[str, Any], Sequence[Mapping[str, Any]], None]) -> None:
         self._timestamp()
@@ -230,7 +217,6 @@ class HTMLLogger(BaseLogger):
         else:
             self._write(f'<code class="lang-sql">{html.escape(sqlstr)}</code>')
 
         else:
             self._write(f'<code class="lang-sql">{html.escape(sqlstr)}</code>')
 
-
     def _python_var(self, var: Any) -> str:
         if CODE_HIGHLIGHT:
             fmt = highlight(str(var), PythonLexer(), HtmlFormatter(nowrap=True))
     def _python_var(self, var: Any) -> str:
         if CODE_HIGHLIGHT:
             fmt = highlight(str(var), PythonLexer(), HtmlFormatter(nowrap=True))
@@ -238,7 +224,6 @@ class HTMLLogger(BaseLogger):
 
         return f'<code class="lang-python">{html.escape(str(var))}</code>'
 
 
         return f'<code class="lang-python">{html.escape(str(var))}</code>'
 
-
     def _write(self, text: str) -> None:
         """ Add the raw text to the debug output.
         """
     def _write(self, text: str) -> None:
         """ Add the raw text to the debug output.
         """
@@ -251,38 +236,31 @@ class TextLogger(BaseLogger):
     def __init__(self) -> None:
         self.buffer = io.StringIO()
 
     def __init__(self) -> None:
         self.buffer = io.StringIO()
 
-
     def _timestamp(self) -> None:
         self._write(f'[{dt.datetime.now()}]\n')
 
     def _timestamp(self) -> None:
         self._write(f'[{dt.datetime.now()}]\n')
 
-
     def get_buffer(self) -> str:
         return self.buffer.getvalue()
 
     def get_buffer(self) -> str:
         return self.buffer.getvalue()
 
-
     def function(self, func: str, **kwargs: Any) -> None:
         self._write(f"#### Debug output for {func}()\n\nParameters:\n")
         for name, value in kwargs.items():
             self._write(f'  {name}: {self._python_var(value)}\n')
         self._write('\n')
 
     def function(self, func: str, **kwargs: Any) -> None:
         self._write(f"#### Debug output for {func}()\n\nParameters:\n")
         for name, value in kwargs.items():
             self._write(f'  {name}: {self._python_var(value)}\n')
         self._write('\n')
 
-
     def section(self, heading: str) -> None:
         self._timestamp()
         self._write(f"\n# {heading}\n\n")
 
     def section(self, heading: str) -> None:
         self._timestamp()
         self._write(f"\n# {heading}\n\n")
 
-
     def comment(self, text: str) -> None:
         self._write(f"{text}\n")
 
     def comment(self, text: str) -> None:
         self._write(f"{text}\n")
 
-
     def var_dump(self, heading: str, var: Any) -> None:
         if callable(var):
             var = var()
 
         self._write(f'{heading}:\n  {self._python_var(var)}\n\n')
 
     def var_dump(self, heading: str, var: Any) -> None:
         if callable(var):
             var = var()
 
         self._write(f'{heading}:\n  {self._python_var(var)}\n\n')
 
-
     def table_dump(self, heading: str, rows: Iterator[Optional[List[Any]]]) -> None:
         self._write(f'{heading}:\n')
         data = [list(map(self._python_var, row)) if row else None for row in rows]
     def table_dump(self, heading: str, rows: Iterator[Optional[List[Any]]]) -> None:
         self._write(f'{heading}:\n')
         data = [list(map(self._python_var, row)) if row else None for row in rows]
@@ -291,7 +269,7 @@ class TextLogger(BaseLogger):
 
         maxlens = [max(len(d[i]) for d in data if d) for i in range(num_cols)]
         tablewidth = sum(maxlens) + 3 * num_cols + 1
 
         maxlens = [max(len(d[i]) for d in data if d) for i in range(num_cols)]
         tablewidth = sum(maxlens) + 3 * num_cols + 1
-        row_format = '| ' +' | '.join(f'{{:<{l}}}' for l in maxlens) + ' |\n'
+        row_format = '| ' + ' | '.join(f'{{:<{ln}}}' for ln in maxlens) + ' |\n'
         self._write('-'*tablewidth + '\n')
         self._write(row_format.format(*data[0]))
         self._write('-'*tablewidth + '\n')
         self._write('-'*tablewidth + '\n')
         self._write(row_format.format(*data[0]))
         self._write('-'*tablewidth + '\n')
@@ -303,7 +281,6 @@ class TextLogger(BaseLogger):
         if data[-1]:
             self._write('-'*tablewidth + '\n')
 
         if data[-1]:
             self._write('-'*tablewidth + '\n')
 
-
     def result_dump(self, heading: str, results: Iterator[Tuple[Any, Any]]) -> None:
         self._timestamp()
         self._write(f'{heading}:\n')
     def result_dump(self, heading: str, results: Iterator[Tuple[Any, Any]]) -> None:
         self._timestamp()
         self._write(f'{heading}:\n')
@@ -318,18 +295,15 @@ class TextLogger(BaseLogger):
             total += 1
         self._write(f'TOTAL: {total}\n\n')
 
             total += 1
         self._write(f'TOTAL: {total}\n\n')
 
-
     def sql(self, conn: AsyncConnection, statement: 'sa.Executable',
             params: Union[Mapping[str, Any], Sequence[Mapping[str, Any]], None]) -> None:
         self._timestamp()
         sqlstr = '\n| '.join(textwrap.wrap(self.format_sql(conn, statement, params), width=78))
         self._write(f"| {sqlstr}\n\n")
 
     def sql(self, conn: AsyncConnection, statement: 'sa.Executable',
             params: Union[Mapping[str, Any], Sequence[Mapping[str, Any]], None]) -> None:
         self._timestamp()
         sqlstr = '\n| '.join(textwrap.wrap(self.format_sql(conn, statement, params), width=78))
         self._write(f"| {sqlstr}\n\n")
 
-
     def _python_var(self, var: Any) -> str:
         return str(var)
 
     def _python_var(self, var: Any) -> str:
         return str(var)
 
-
     def _write(self, text: str) -> None:
         self.buffer.write(text)
 
     def _write(self, text: str) -> None:
         self.buffer.write(text)
 
@@ -368,8 +342,8 @@ HTML_HEADER: str = """<!DOCTYPE html>
   <title>Nominatim - Debug</title>
   <style>
 """ + \
   <title>Nominatim - Debug</title>
   <style>
 """ + \
-(HtmlFormatter(nobackground=True).get_style_defs('.highlight') if CODE_HIGHLIGHT else '') +\
-"""
+    (HtmlFormatter(nobackground=True).get_style_defs('.highlight') if CODE_HIGHLIGHT else '') + \
+    """
     h2 { font-size: x-large }
 
     dl {
     h2 { font-size: x-large }
 
     dl {
index 34739171d81c4ed1df37ce3c9d6a406897462b4b..89a0258e46372ac96656ec6906d093cfbfeab5bd 100644 (file)
@@ -127,7 +127,7 @@ async def find_in_postcode(conn: SearchConnection, place: ntyp.PlaceRef,
 
 async def find_in_all_tables(conn: SearchConnection, place: ntyp.PlaceRef,
                              add_geometries: GeomFunc
 
 async def find_in_all_tables(conn: SearchConnection, place: ntyp.PlaceRef,
                              add_geometries: GeomFunc
-                            ) -> Tuple[Optional[SaRow], RowFunc[nres.BaseResultT]]:
+                             ) -> Tuple[Optional[SaRow], RowFunc[nres.BaseResultT]]:
     """ Search for the given place in all data tables
         and return the base information.
     """
     """ Search for the given place in all data tables
         and return the base information.
     """
@@ -219,7 +219,6 @@ async def get_simple_place(conn: SearchConnection, place: ntyp.PlaceRef,
 
         return sql.add_columns(*out)
 
 
         return sql.add_columns(*out)
 
-
     row_func: RowFunc[nres.SearchResult]
     row, row_func = await find_in_all_tables(conn, place, _add_geometry)
 
     row_func: RowFunc[nres.SearchResult]
     row, row_func = await find_in_all_tables(conn, place, _add_geometry)
 
index 50f086f3fb281fbf89108c40241e809dd216a747..b6d26c31736afd0d8158b9e5436f914174013fc9 100644 (file)
@@ -14,7 +14,7 @@ import importlib
 
 from .server.content_types import CONTENT_JSON
 
 
 from .server.content_types import CONTENT_JSON
 
-T = TypeVar('T') # pylint: disable=invalid-name
+T = TypeVar('T')  # pylint: disable=invalid-name
 FormatFunc = Callable[[T, Mapping[str, Any]], str]
 ErrorFormatFunc = Callable[[str, str, int], str]
 
 FormatFunc = Callable[[T, Mapping[str, Any]], str]
 ErrorFormatFunc = Callable[[str, str, int], str]
 
@@ -31,7 +31,6 @@ class FormatDispatcher:
             self.content_types.update(content_types)
         self.format_functions: Dict[Type[Any], Dict[str, FormatFunc[Any]]] = defaultdict(dict)
 
             self.content_types.update(content_types)
         self.format_functions: Dict[Type[Any], Dict[str, FormatFunc[Any]]] = defaultdict(dict)
 
-
     def format_func(self, result_class: Type[T],
                     fmt: str) -> Callable[[FormatFunc[T]], FormatFunc[T]]:
         """ Decorator for a function that formats a given type of result into the
     def format_func(self, result_class: Type[T],
                     fmt: str) -> Callable[[FormatFunc[T]], FormatFunc[T]]:
         """ Decorator for a function that formats a given type of result into the
@@ -43,7 +42,6 @@ class FormatDispatcher:
 
         return decorator
 
 
         return decorator
 
-
     def error_format_func(self, func: ErrorFormatFunc) -> ErrorFormatFunc:
         """ Decorator for a function that formats error messges.
             There is only one error formatter per dispatcher. Using
     def error_format_func(self, func: ErrorFormatFunc) -> ErrorFormatFunc:
         """ Decorator for a function that formats error messges.
             There is only one error formatter per dispatcher. Using
@@ -52,19 +50,16 @@ class FormatDispatcher:
         self.error_handler = func
         return func
 
         self.error_handler = func
         return func
 
-
     def list_formats(self, result_type: Type[Any]) -> List[str]:
         """ Return a list of formats supported by this formatter.
         """
         return list(self.format_functions[result_type].keys())
 
     def list_formats(self, result_type: Type[Any]) -> List[str]:
         """ Return a list of formats supported by this formatter.
         """
         return list(self.format_functions[result_type].keys())
 
-
     def supports_format(self, result_type: Type[Any], fmt: str) -> bool:
         """ Check if the given format is supported by this formatter.
         """
         return fmt in self.format_functions[result_type]
 
     def supports_format(self, result_type: Type[Any], fmt: str) -> bool:
         """ Check if the given format is supported by this formatter.
         """
         return fmt in self.format_functions[result_type]
 
-
     def format_result(self, result: Any, fmt: str, options: Mapping[str, Any]) -> str:
         """ Convert the given result into a string using the given format.
 
     def format_result(self, result: Any, fmt: str, options: Mapping[str, Any]) -> str:
         """ Convert the given result into a string using the given format.
 
@@ -73,7 +68,6 @@ class FormatDispatcher:
         """
         return self.format_functions[type(result)][fmt](result, options)
 
         """
         return self.format_functions[type(result)][fmt](result, options)
 
-
     def format_error(self, content_type: str, msg: str, status: int) -> str:
         """ Convert the given error message into a response string
             taking the requested content_type into account.
     def format_error(self, content_type: str, msg: str, status: int) -> str:
         """ Convert the given error message into a response string
             taking the requested content_type into account.
@@ -82,7 +76,6 @@ class FormatDispatcher:
         """
         return self.error_handler(content_type, msg, status)
 
         """
         return self.error_handler(content_type, msg, status)
 
-
     def set_content_type(self, fmt: str, content_type: str) -> None:
         """ Set the content type for the given format. This is the string
             that will be returned in the Content-Type header of the HTML
     def set_content_type(self, fmt: str, content_type: str) -> None:
         """ Set the content type for the given format. This is the string
             that will be returned in the Content-Type header of the HTML
@@ -90,7 +83,6 @@ class FormatDispatcher:
         """
         self.content_types[fmt] = content_type
 
         """
         self.content_types[fmt] = content_type
 
-
     def get_content_type(self, fmt: str) -> str:
         """ Return the content type for the given format.
 
     def get_content_type(self, fmt: str) -> str:
         """ Return the content type for the given format.
 
index 28c0fc1a4bf4a3d2e747d30c0d6032ea3ea0722e..1a4dc8ae01d87a2d853e74ad5fc002d4ea5e8535 100644 (file)
@@ -26,7 +26,7 @@ from .logging import log
 from .localization import Locales
 
 # This file defines complex result data classes.
 from .localization import Locales
 
 # This file defines complex result data classes.
-# pylint: disable=too-many-instance-attributes
+
 
 def _mingle_name_tags(names: Optional[Dict[str, str]]) -> Optional[Dict[str, str]]:
     """ Mix-in names from linked places, so that they show up
 
 def _mingle_name_tags(names: Optional[Dict[str, str]]) -> Optional[Dict[str, str]]:
     """ Mix-in names from linked places, so that they show up
@@ -153,7 +153,6 @@ class AddressLines(List[AddressLine]):
         return label_parts
 
 
         return label_parts
 
 
-
 @dataclasses.dataclass
 class WordInfo:
     """ Each entry in the list of search terms contains the
 @dataclasses.dataclass
 class WordInfo:
     """ Each entry in the list of search terms contains the
@@ -183,7 +182,7 @@ class BaseResult:
     category: Tuple[str, str]
     centroid: Point
 
     category: Tuple[str, str]
     centroid: Point
 
-    place_id : Optional[int] = None
+    place_id: Optional[int] = None
     osm_object: Optional[Tuple[str, int]] = None
     parent_place_id: Optional[int] = None
     linked_place_id: Optional[int] = None
     osm_object: Optional[Tuple[str, int]] = None
     parent_place_id: Optional[int] = None
     linked_place_id: Optional[int] = None
@@ -220,14 +219,12 @@ class BaseResult:
         """
         return self.centroid[1]
 
         """
         return self.centroid[1]
 
-
     @property
     def lon(self) -> float:
         """ Get the longitude (or x) of the center point of the place.
         """
         return self.centroid[0]
 
     @property
     def lon(self) -> float:
         """ Get the longitude (or x) of the center point of the place.
         """
         return self.centroid[0]
 
-
     def calculated_importance(self) -> float:
         """ Get a valid importance value. This is either the stored importance
             of the value or an artificial value computed from the place's
     def calculated_importance(self) -> float:
         """ Get a valid importance value. This is either the stored importance
             of the value or an artificial value computed from the place's
@@ -235,7 +232,6 @@ class BaseResult:
         """
         return self.importance or (0.40001 - (self.rank_search/75.0))
 
         """
         return self.importance or (0.40001 - (self.rank_search/75.0))
 
-
     def localize(self, locales: Locales) -> None:
         """ Fill the locale_name and the display_name field for the
             place and, if available, its address information.
     def localize(self, locales: Locales) -> None:
         """ Fill the locale_name and the display_name field for the
             place and, if available, its address information.
@@ -247,9 +243,9 @@ class BaseResult:
             self.display_name = self.locale_name
 
 
             self.display_name = self.locale_name
 
 
-
 BaseResultT = TypeVar('BaseResultT', bound=BaseResult)
 
 BaseResultT = TypeVar('BaseResultT', bound=BaseResult)
 
+
 @dataclasses.dataclass
 class DetailedResult(BaseResult):
     """ A search result with more internal information from the database
 @dataclasses.dataclass
 class DetailedResult(BaseResult):
     """ A search result with more internal information from the database
@@ -279,13 +275,12 @@ class SearchResult(BaseResult):
     bbox: Optional[Bbox] = None
     accuracy: float = 0.0
 
     bbox: Optional[Bbox] = None
     accuracy: float = 0.0
 
-
     @property
     def ranking(self) -> float:
         """ Return the ranking, a combined measure of accuracy and importance.
         """
         return (self.accuracy if self.accuracy is not None else 1) \
     @property
     def ranking(self) -> float:
         """ Return the ranking, a combined measure of accuracy and importance.
         """
         return (self.accuracy if self.accuracy is not None else 1) \
-               - self.calculated_importance()
+            - self.calculated_importance()
 
 
 class SearchResults(List[SearchResult]):
 
 
 class SearchResults(List[SearchResult]):
@@ -295,7 +290,7 @@ class SearchResults(List[SearchResult]):
 
 
 def _filter_geometries(row: SaRow) -> Dict[str, str]:
 
 
 def _filter_geometries(row: SaRow) -> Dict[str, str]:
-    return {k[9:]: v for k, v in row._mapping.items() # pylint: disable=W0212
+    return {k[9:]: v for k, v in row._mapping.items()
             if k.startswith('geometry_')}
 
 
             if k.startswith('geometry_')}
 
 
@@ -312,9 +307,9 @@ def create_from_placex_row(row: Optional[SaRow],
                       place_id=row.place_id,
                       osm_object=(row.osm_type, row.osm_id),
                       category=(row.class_, row.type),
                       place_id=row.place_id,
                       osm_object=(row.osm_type, row.osm_id),
                       category=(row.class_, row.type),
-                      parent_place_id = row.parent_place_id,
-                      linked_place_id = getattr(row, 'linked_place_id', None),
-                      admin_level = getattr(row, 'admin_level', 15),
+                      parent_place_id=row.parent_place_id,
+                      linked_place_id=getattr(row, 'linked_place_id', None),
+                      admin_level=getattr(row, 'admin_level', 15),
                       names=_mingle_name_tags(row.name),
                       address=row.address,
                       extratags=row.extratags,
                       names=_mingle_name_tags(row.name),
                       address=row.address,
                       extratags=row.extratags,
@@ -345,7 +340,7 @@ def create_from_osmline_row(row: Optional[SaRow],
 
     res = class_type(source_table=SourceTable.OSMLINE,
                      place_id=row.place_id,
 
     res = class_type(source_table=SourceTable.OSMLINE,
                      place_id=row.place_id,
-                     parent_place_id = row.parent_place_id,
+                     parent_place_id=row.parent_place_id,
                      osm_object=('W', row.osm_id),
                      category=('place', 'houses' if hnr is None else 'house'),
                      address=row.address,
                      osm_object=('W', row.osm_id),
                      category=('place', 'houses' if hnr is None else 'house'),
                      address=row.address,
@@ -382,7 +377,7 @@ def create_from_tiger_row(row: Optional[SaRow],
 
     res = class_type(source_table=SourceTable.TIGER,
                      place_id=row.place_id,
 
     res = class_type(source_table=SourceTable.TIGER,
                      place_id=row.place_id,
-                     parent_place_id = row.parent_place_id,
+                     parent_place_id=row.parent_place_id,
                      osm_object=(osm_type or row.osm_type, osm_id or row.osm_id),
                      category=('place', 'houses' if hnr is None else 'house'),
                      postcode=row.postcode,
                      osm_object=(osm_type or row.osm_type, osm_id or row.osm_id),
                      category=('place', 'houses' if hnr is None else 'house'),
                      postcode=row.postcode,
@@ -401,7 +396,7 @@ def create_from_tiger_row(row: Optional[SaRow],
 
 
 def create_from_postcode_row(row: Optional[SaRow],
 
 
 def create_from_postcode_row(row: Optional[SaRow],
-                          class_type: Type[BaseResultT]) -> Optional[BaseResultT]:
+                             class_type: Type[BaseResultT]) -> Optional[BaseResultT]:
     """ Construct a new result and add the data from the result row
         from the postcode table. 'class_type' defines
         the type of result to return. Returns None if the row is None.
     """ Construct a new result and add the data from the result row
         from the postcode table. 'class_type' defines
         the type of result to return. Returns None if the row is None.
@@ -411,7 +406,7 @@ def create_from_postcode_row(row: Optional[SaRow],
 
     return class_type(source_table=SourceTable.POSTCODE,
                       place_id=row.place_id,
 
     return class_type(source_table=SourceTable.POSTCODE,
                       place_id=row.place_id,
-                      parent_place_id = row.parent_place_id,
+                      parent_place_id=row.parent_place_id,
                       category=('place', 'postcode'),
                       names={'ref': row.postcode},
                       rank_search=row.rank_search,
                       category=('place', 'postcode'),
                       names={'ref': row.postcode},
                       rank_search=row.rank_search,
@@ -422,7 +417,7 @@ def create_from_postcode_row(row: Optional[SaRow],
 
 
 def create_from_country_row(row: Optional[SaRow],
 
 
 def create_from_country_row(row: Optional[SaRow],
-                        class_type: Type[BaseResultT]) -> Optional[BaseResultT]:
+                            class_type: Type[BaseResultT]) -> Optional[BaseResultT]:
     """ Construct a new result and add the data from the result row
         from the fallback country tables. 'class_type' defines
         the type of result to return. Returns None if the row is None.
     """ Construct a new result and add the data from the result row
         from the fallback country tables. 'class_type' defines
         the type of result to return. Returns None if the row is None.
@@ -535,7 +530,7 @@ async def _finalize_entry(conn: SearchConnection, result: BaseResultT) -> None:
                 distance=0.0))
         result.address_rows.append(AddressLine(
             category=('place', 'country_code'),
                 distance=0.0))
         result.address_rows.append(AddressLine(
             category=('place', 'country_code'),
-            names={'ref': result.country_code}, extratags = {},
+            names={'ref': result.country_code}, extratags={},
             fromarea=True, isaddress=False, rank_address=4,
             distance=0.0))
 
             fromarea=True, isaddress=False, rank_address=4,
             distance=0.0))
 
@@ -580,12 +575,12 @@ async def complete_address_details(conn: SearchConnection, results: List[BaseRes
     for result in results:
         _setup_address_details(result)
 
     for result in results:
         _setup_address_details(result)
 
-    ### Lookup entries from place_address line
+    # Lookup entries from place_address line
 
     lookup_ids = [{'pid': r.place_id,
                    'lid': _get_address_lookup_id(r),
                    'names': list(r.address.values()) if r.address else [],
 
     lookup_ids = [{'pid': r.place_id,
                    'lid': _get_address_lookup_id(r),
                    'names': list(r.address.values()) if r.address else [],
-                   'c': ('SRID=4326;' + r.centroid.to_wkt()) if r.centroid else '' }
+                   'c': ('SRID=4326;' + r.centroid.to_wkt()) if r.centroid else ''}
                   for r in results if r.place_id]
 
     if not lookup_ids:
                   for r in results if r.place_id]
 
     if not lookup_ids:
@@ -621,7 +616,6 @@ async def complete_address_details(conn: SearchConnection, results: List[BaseRes
             .order_by(taddr.c.distance.desc())\
             .order_by(t.c.rank_search.desc())
 
             .order_by(taddr.c.distance.desc())\
             .order_by(t.c.rank_search.desc())
 
-
     current_result = None
     current_rank_address = -1
     for row in await conn.execute(sql):
     current_result = None
     current_rank_address = -1
     for row in await conn.execute(sql):
@@ -649,8 +643,7 @@ async def complete_address_details(conn: SearchConnection, results: List[BaseRes
     for result in results:
         await _finalize_entry(conn, result)
 
     for result in results:
         await _finalize_entry(conn, result)
 
-
-    ### Finally add the record for the parent entry where necessary.
+    # Finally add the record for the parent entry where necessary.
 
     parent_lookup_ids = list(filter(lambda e: e['pid'] != e['lid'], lookup_ids))
     if parent_lookup_ids:
 
     parent_lookup_ids = list(filter(lambda e: e['pid'] != e['lid'], lookup_ids))
     if parent_lookup_ids:
@@ -661,7 +654,7 @@ async def complete_address_details(conn: SearchConnection, results: List[BaseRes
                         t.c.class_, t.c.type, t.c.extratags,
                         t.c.admin_level,
                         t.c.rank_address)\
                         t.c.class_, t.c.type, t.c.extratags,
                         t.c.admin_level,
                         t.c.rank_address)\
-                 .where(t.c.place_id == ltab.c.value['lid'].as_integer())
+                .where(t.c.place_id == ltab.c.value['lid'].as_integer())
 
         for row in await conn.execute(sql):
             current_result = next((r for r in results if r.place_id == row.src_place_id), None)
 
         for row in await conn.execute(sql):
             current_result = next((r for r in results if r.place_id == row.src_place_id), None)
@@ -677,7 +670,7 @@ async def complete_address_details(conn: SearchConnection, results: List[BaseRes
                     fromarea=True, isaddress=True,
                     rank_address=row.rank_address, distance=0.0))
 
                     fromarea=True, isaddress=True,
                     rank_address=row.rank_address, distance=0.0))
 
-    ### Now sort everything
+    # Now sort everything
     def mk_sort_key(place_id: Optional[int]) -> Callable[[AddressLine], Tuple[bool, int, bool]]:
         return lambda a: (a.place_id != place_id, -a.rank_address, a.isaddress)
 
     def mk_sort_key(place_id: Optional[int]) -> Callable[[AddressLine], Tuple[bool, int, bool]]:
         return lambda a: (a.place_id != place_id, -a.rank_address, a.isaddress)
 
@@ -706,7 +699,7 @@ async def complete_linked_places(conn: SearchConnection, result: BaseResult) ->
         return
 
     sql = _placex_select_address_row(conn, result.centroid)\
         return
 
     sql = _placex_select_address_row(conn, result.centroid)\
-            .where(conn.t.placex.c.linked_place_id == result.place_id)
+        .where(conn.t.placex.c.linked_place_id == result.place_id)
 
     for row in await conn.execute(sql):
         result.linked_rows.append(_result_row_to_address_row(row))
 
     for row in await conn.execute(sql):
         result.linked_rows.append(_result_row_to_address_row(row))
@@ -745,8 +738,8 @@ async def complete_parented_places(conn: SearchConnection, result: BaseResult) -
         return
 
     sql = _placex_select_address_row(conn, result.centroid)\
         return
 
     sql = _placex_select_address_row(conn, result.centroid)\
-            .where(conn.t.placex.c.parent_place_id == result.place_id)\
-            .where(conn.t.placex.c.rank_search == 30)
+        .where(conn.t.placex.c.parent_place_id == result.place_id)\
+        .where(conn.t.placex.c.rank_search == 30)
 
     for row in await conn.execute(sql):
         result.parented_rows.append(_result_row_to_address_row(row))
 
     for row in await conn.execute(sql):
         result.parented_rows.append(_result_row_to_address_row(row))
index 20270656f949944a2a8fca6dc0b8590a8c3ec8d3..e0c1d11831ec2776bc076cc8205d6e867d014a6c 100644 (file)
@@ -12,7 +12,7 @@ import functools
 
 import sqlalchemy as sa
 
 
 import sqlalchemy as sa
 
-from .typing import SaColumn, SaSelect, SaFromClause, SaLabel, SaRow,\
+from .typing import SaColumn, SaSelect, SaFromClause, SaLabel, SaRow, \
                     SaBind, SaLambdaSelect
 from .sql.sqlalchemy_types import Geometry
 from .connection import SearchConnection
                     SaBind, SaLambdaSelect
 from .sql.sqlalchemy_types import Geometry
 from .connection import SearchConnection
@@ -29,11 +29,12 @@ RowFunc = Callable[[Optional[SaRow], Type[nres.ReverseResult]], Optional[nres.Re
 WKT_PARAM: SaBind = sa.bindparam('wkt', type_=Geometry)
 MAX_RANK_PARAM: SaBind = sa.bindparam('max_rank')
 
 WKT_PARAM: SaBind = sa.bindparam('wkt', type_=Geometry)
 MAX_RANK_PARAM: SaBind = sa.bindparam('max_rank')
 
+
 def no_index(expr: SaColumn) -> SaColumn:
     """ Wrap the given expression, so that the query planner will
         refrain from using the expression for index lookup.
     """
 def no_index(expr: SaColumn) -> SaColumn:
     """ Wrap the given expression, so that the query planner will
         refrain from using the expression for index lookup.
     """
-    return sa.func.coalesce(sa.null(), expr) # pylint: disable=not-callable
+    return sa.func.coalesce(sa.null(), expr)
 
 
 def _select_from_placex(t: SaFromClause, use_wkt: bool = True) -> SaSelect:
 
 
 def _select_from_placex(t: SaFromClause, use_wkt: bool = True) -> SaSelect:
@@ -48,7 +49,6 @@ def _select_from_placex(t: SaFromClause, use_wkt: bool = True) -> SaSelect:
         centroid = sa.case((t.c.geometry.is_line_like(), t.c.geometry.ST_ClosestPoint(WKT_PARAM)),
                            else_=t.c.centroid).label('centroid')
 
         centroid = sa.case((t.c.geometry.is_line_like(), t.c.geometry.ST_ClosestPoint(WKT_PARAM)),
                            else_=t.c.centroid).label('centroid')
 
-
     return sa.select(t.c.place_id, t.c.osm_type, t.c.osm_id, t.c.name,
                      t.c.class_, t.c.type,
                      t.c.address, t.c.extratags,
     return sa.select(t.c.place_id, t.c.osm_type, t.c.osm_id, t.c.name,
                      t.c.class_, t.c.type,
                      t.c.address, t.c.extratags,
@@ -63,8 +63,8 @@ def _select_from_placex(t: SaFromClause, use_wkt: bool = True) -> SaSelect:
 
 def _interpolated_housenumber(table: SaFromClause) -> SaLabel:
     return sa.cast(table.c.startnumber
 
 def _interpolated_housenumber(table: SaFromClause) -> SaLabel:
     return sa.cast(table.c.startnumber
-                    + sa.func.round(((table.c.endnumber - table.c.startnumber) * table.c.position)
-                                    / table.c.step) * table.c.step,
+                   + sa.func.round(((table.c.endnumber - table.c.startnumber) * table.c.position)
+                                   / table.c.step) * table.c.step,
                    sa.Integer).label('housenumber')
 
 
                    sa.Integer).label('housenumber')
 
 
@@ -72,8 +72,8 @@ def _interpolated_position(table: SaFromClause) -> SaLabel:
     fac = sa.cast(table.c.step, sa.Float) / (table.c.endnumber - table.c.startnumber)
     rounded_pos = sa.func.round(table.c.position / fac) * fac
     return sa.case(
     fac = sa.cast(table.c.step, sa.Float) / (table.c.endnumber - table.c.startnumber)
     rounded_pos = sa.func.round(table.c.position / fac) * fac
     return sa.case(
-             (table.c.endnumber == table.c.startnumber, table.c.linegeo.ST_Centroid()),
-              else_=table.c.linegeo.ST_LineInterpolatePoint(rounded_pos)).label('centroid')
+        (table.c.endnumber == table.c.startnumber, table.c.linegeo.ST_Centroid()),
+        else_=table.c.linegeo.ST_LineInterpolatePoint(rounded_pos)).label('centroid')
 
 
 def _locate_interpolation(table: SaFromClause) -> SaLabel:
 
 
 def _locate_interpolation(table: SaFromClause) -> SaLabel:
@@ -101,38 +101,32 @@ class ReverseGeocoder:
 
         self.bind_params: Dict[str, Any] = {'max_rank': params.max_rank}
 
 
         self.bind_params: Dict[str, Any] = {'max_rank': params.max_rank}
 
-
     @property
     def max_rank(self) -> int:
         """ Return the maximum configured rank.
         """
         return self.params.max_rank
 
     @property
     def max_rank(self) -> int:
         """ Return the maximum configured rank.
         """
         return self.params.max_rank
 
-
     def has_geometries(self) -> bool:
         """ Check if any geometries are requested.
         """
         return bool(self.params.geometry_output)
 
     def has_geometries(self) -> bool:
         """ Check if any geometries are requested.
         """
         return bool(self.params.geometry_output)
 
-
     def layer_enabled(self, *layer: DataLayer) -> bool:
         """ Return true when any of the given layer types are requested.
         """
     def layer_enabled(self, *layer: DataLayer) -> bool:
         """ Return true when any of the given layer types are requested.
         """
-        return any(self.params.layers & l for l in layer)
-
+        return any(self.params.layers & ly for ly in layer)
 
     def layer_disabled(self, *layer: DataLayer) -> bool:
         """ Return true when none of the given layer types is requested.
         """
 
     def layer_disabled(self, *layer: DataLayer) -> bool:
         """ Return true when none of the given layer types is requested.
         """
-        return not any(self.params.layers & l for l in layer)
-
+        return not any(self.params.layers & ly for ly in layer)
 
     def has_feature_layers(self) -> bool:
         """ Return true if any layer other than ADDRESS or POI is requested.
         """
         return self.layer_enabled(DataLayer.RAILWAY, DataLayer.MANMADE, DataLayer.NATURAL)
 
 
     def has_feature_layers(self) -> bool:
         """ Return true if any layer other than ADDRESS or POI is requested.
         """
         return self.layer_enabled(DataLayer.RAILWAY, DataLayer.MANMADE, DataLayer.NATURAL)
 
-
     def _add_geometry_columns(self, sql: SaLambdaSelect, col: SaColumn) -> SaSelect:
         out = []
 
     def _add_geometry_columns(self, sql: SaLambdaSelect, col: SaColumn) -> SaSelect:
         out = []
 
@@ -150,7 +144,6 @@ class ReverseGeocoder:
 
         return sql.add_columns(*out)
 
 
         return sql.add_columns(*out)
 
-
     def _filter_by_layer(self, table: SaFromClause) -> SaColumn:
         if self.layer_enabled(DataLayer.MANMADE):
             exclude = []
     def _filter_by_layer(self, table: SaFromClause) -> SaColumn:
         if self.layer_enabled(DataLayer.MANMADE):
             exclude = []
@@ -167,7 +160,6 @@ class ReverseGeocoder:
             include.extend(('natural', 'water', 'waterway'))
         return table.c.class_.in_(tuple(include))
 
             include.extend(('natural', 'water', 'waterway'))
         return table.c.class_.in_(tuple(include))
 
-
     async def _find_closest_street_or_poi(self, distance: float) -> Optional[SaRow]:
         """ Look up the closest rank 26+ place in the database, which
             is closer than the given distance.
     async def _find_closest_street_or_poi(self, distance: float) -> Optional[SaRow]:
         """ Look up the closest rank 26+ place in the database, which
             is closer than the given distance.
@@ -179,14 +171,15 @@ class ReverseGeocoder:
         # when used with prepared statements
         diststr = sa.text(f"{distance}")
 
         # when used with prepared statements
         diststr = sa.text(f"{distance}")
 
-        sql: SaLambdaSelect = sa.lambda_stmt(lambda: _select_from_placex(t)
-                .where(t.c.geometry.within_distance(WKT_PARAM, diststr))
-                .where(t.c.indexed_status == 0)
-                .where(t.c.linked_place_id == None)
-                .where(sa.or_(sa.not_(t.c.geometry.is_area()),
-                              t.c.centroid.ST_Distance(WKT_PARAM) < diststr))
-                .order_by('distance')
-                .limit(2))
+        sql: SaLambdaSelect = sa.lambda_stmt(
+            lambda: _select_from_placex(t)
+            .where(t.c.geometry.within_distance(WKT_PARAM, diststr))
+            .where(t.c.indexed_status == 0)
+            .where(t.c.linked_place_id == None)
+            .where(sa.or_(sa.not_(t.c.geometry.is_area()),
+                          t.c.centroid.ST_Distance(WKT_PARAM) < diststr))
+            .order_by('distance')
+            .limit(2))
 
         if self.has_geometries():
             sql = self._add_geometry_columns(sql, t.c.geometry)
 
         if self.has_geometries():
             sql = self._add_geometry_columns(sql, t.c.geometry)
@@ -227,7 +220,6 @@ class ReverseGeocoder:
 
         return prev_row
 
 
         return prev_row
 
-
     async def _find_housenumber_for_street(self, parent_place_id: int) -> Optional[SaRow]:
         t = self.conn.t.placex
 
     async def _find_housenumber_for_street(self, parent_place_id: int) -> Optional[SaRow]:
         t = self.conn.t.placex
 
@@ -249,7 +241,6 @@ class ReverseGeocoder:
 
         return (await self.conn.execute(sql, self.bind_params)).one_or_none()
 
 
         return (await self.conn.execute(sql, self.bind_params)).one_or_none()
 
-
     async def _find_interpolation_for_street(self, parent_place_id: Optional[int],
                                              distance: float) -> Optional[SaRow]:
         t = self.conn.t.osmline
     async def _find_interpolation_for_street(self, parent_place_id: Optional[int],
                                              distance: float) -> Optional[SaRow]:
         t = self.conn.t.osmline
@@ -268,11 +259,11 @@ class ReverseGeocoder:
         inner = sql.subquery('ipol')
 
         sql = sa.select(inner.c.place_id, inner.c.osm_id,
         inner = sql.subquery('ipol')
 
         sql = sa.select(inner.c.place_id, inner.c.osm_id,
-                             inner.c.parent_place_id, inner.c.address,
-                             _interpolated_housenumber(inner),
-                             _interpolated_position(inner),
-                             inner.c.postcode, inner.c.country_code,
-                             inner.c.distance)
+                        inner.c.parent_place_id, inner.c.address,
+                        _interpolated_housenumber(inner),
+                        _interpolated_position(inner),
+                        inner.c.postcode, inner.c.country_code,
+                        inner.c.distance)
 
         if self.has_geometries():
             sub = sql.subquery('geom')
 
         if self.has_geometries():
             sub = sql.subquery('geom')
@@ -280,7 +271,6 @@ class ReverseGeocoder:
 
         return (await self.conn.execute(sql, self.bind_params)).one_or_none()
 
 
         return (await self.conn.execute(sql, self.bind_params)).one_or_none()
 
-
     async def _find_tiger_number_for_street(self, parent_place_id: int) -> Optional[SaRow]:
         t = self.conn.t.tiger
 
     async def _find_tiger_number_for_street(self, parent_place_id: int) -> Optional[SaRow]:
         t = self.conn.t.tiger
 
@@ -310,7 +300,6 @@ class ReverseGeocoder:
 
         return (await self.conn.execute(sql, self.bind_params)).one_or_none()
 
 
         return (await self.conn.execute(sql, self.bind_params)).one_or_none()
 
-
     async def lookup_street_poi(self) -> Tuple[Optional[SaRow], RowFunc]:
         """ Find a street or POI/address for the given WKT point.
         """
     async def lookup_street_poi(self) -> Tuple[Optional[SaRow], RowFunc]:
         """ Find a street or POI/address for the given WKT point.
         """
@@ -365,7 +354,6 @@ class ReverseGeocoder:
 
         return row, row_func
 
 
         return row, row_func
 
-
     async def _lookup_area_address(self) -> Optional[SaRow]:
         """ Lookup large addressable areas for the given WKT point.
         """
     async def _lookup_area_address(self) -> Optional[SaRow]:
         """ Lookup large addressable areas for the given WKT point.
         """
@@ -384,9 +372,9 @@ class ReverseGeocoder:
                       .subquery('area')
 
             return _select_from_placex(inner, False)\
                       .subquery('area')
 
             return _select_from_placex(inner, False)\
-                      .where(inner.c.geometry.ST_Contains(WKT_PARAM))\
-                      .order_by(sa.desc(inner.c.rank_search))\
-                      .limit(1)
+                .where(inner.c.geometry.ST_Contains(WKT_PARAM))\
+                .order_by(sa.desc(inner.c.rank_search))\
+                .limit(1)
 
         sql: SaLambdaSelect = sa.lambda_stmt(_base_query)
         if self.has_geometries():
 
         sql: SaLambdaSelect = sa.lambda_stmt(_base_query)
         if self.has_geometries():
@@ -403,15 +391,14 @@ class ReverseGeocoder:
 
             def _place_inside_area_query() -> SaSelect:
                 inner = \
 
             def _place_inside_area_query() -> SaSelect:
                 inner = \
-                    sa.select(t,
-                              t.c.geometry.ST_Distance(WKT_PARAM).label('distance'))\
-                      .where(t.c.rank_search > address_rank)\
-                      .where(t.c.rank_search <= MAX_RANK_PARAM)\
-                      .where(t.c.indexed_status == 0)\
-                      .where(sa.func.IntersectsReverseDistance(t, WKT_PARAM))\
-                      .order_by(sa.desc(t.c.rank_search))\
-                      .limit(50)\
-                      .subquery('places')
+                    sa.select(t, t.c.geometry.ST_Distance(WKT_PARAM).label('distance'))\
+                    .where(t.c.rank_search > address_rank)\
+                    .where(t.c.rank_search <= MAX_RANK_PARAM)\
+                    .where(t.c.indexed_status == 0)\
+                    .where(sa.func.IntersectsReverseDistance(t, WKT_PARAM))\
+                    .order_by(sa.desc(t.c.rank_search))\
+                    .limit(50)\
+                    .subquery('places')
 
                 touter = t.alias('outer')
                 return _select_from_placex(inner, False)\
 
                 touter = t.alias('outer')
                 return _select_from_placex(inner, False)\
@@ -435,7 +422,6 @@ class ReverseGeocoder:
 
         return address_row
 
 
         return address_row
 
-
     async def _lookup_area_others(self) -> Optional[SaRow]:
         t = self.conn.t.placex
 
     async def _lookup_area_others(self) -> Optional[SaRow]:
         t = self.conn.t.placex
 
@@ -453,10 +439,10 @@ class ReverseGeocoder:
                   .subquery()
 
         sql = _select_from_placex(inner, False)\
                   .subquery()
 
         sql = _select_from_placex(inner, False)\
-                  .where(sa.or_(sa.not_(inner.c.geometry.is_area()),
-                                inner.c.geometry.ST_Contains(WKT_PARAM)))\
-                  .order_by(sa.desc(inner.c.rank_search), inner.c.distance)\
-                  .limit(1)
+            .where(sa.or_(sa.not_(inner.c.geometry.is_area()),
+                          inner.c.geometry.ST_Contains(WKT_PARAM)))\
+            .order_by(sa.desc(inner.c.rank_search), inner.c.distance)\
+            .limit(1)
 
         if self.has_geometries():
             sql = self._add_geometry_columns(sql, inner.c.geometry)
 
         if self.has_geometries():
             sql = self._add_geometry_columns(sql, inner.c.geometry)
@@ -466,7 +452,6 @@ class ReverseGeocoder:
 
         return row
 
 
         return row
 
-
     async def lookup_area(self) -> Optional[SaRow]:
         """ Lookup large areas for the current search.
         """
     async def lookup_area(self) -> Optional[SaRow]:
         """ Lookup large areas for the current search.
         """
@@ -484,7 +469,6 @@ class ReverseGeocoder:
 
         return _get_closest(address_row, other_row)
 
 
         return _get_closest(address_row, other_row)
 
-
     async def lookup_country_codes(self) -> List[str]:
         """ Lookup the country for the current search.
         """
     async def lookup_country_codes(self) -> List[str]:
         """ Lookup the country for the current search.
         """
@@ -497,7 +481,6 @@ class ReverseGeocoder:
         log().var_dump('Country codes', ccodes)
         return ccodes
 
         log().var_dump('Country codes', ccodes)
         return ccodes
 
-
     async def lookup_country(self, ccodes: List[str]) -> Optional[SaRow]:
         """ Lookup the country for the current search.
         """
     async def lookup_country(self, ccodes: List[str]) -> Optional[SaRow]:
         """ Lookup the country for the current search.
         """
@@ -512,17 +495,15 @@ class ReverseGeocoder:
             log().comment('Search for place nodes in country')
 
             def _base_query() -> SaSelect:
             log().comment('Search for place nodes in country')
 
             def _base_query() -> SaSelect:
-                inner = \
-                    sa.select(t,
-                              t.c.geometry.ST_Distance(WKT_PARAM).label('distance'))\
-                      .where(t.c.rank_search > 4)\
-                      .where(t.c.rank_search <= MAX_RANK_PARAM)\
-                      .where(t.c.indexed_status == 0)\
-                      .where(t.c.country_code.in_(ccodes))\
-                      .where(sa.func.IntersectsReverseDistance(t, WKT_PARAM))\
-                      .order_by(sa.desc(t.c.rank_search))\
-                      .limit(50)\
-                      .subquery('area')
+                inner = sa.select(t, t.c.geometry.ST_Distance(WKT_PARAM).label('distance'))\
+                          .where(t.c.rank_search > 4)\
+                          .where(t.c.rank_search <= MAX_RANK_PARAM)\
+                          .where(t.c.indexed_status == 0)\
+                          .where(t.c.country_code.in_(ccodes))\
+                          .where(sa.func.IntersectsReverseDistance(t, WKT_PARAM))\
+                          .order_by(sa.desc(t.c.rank_search))\
+                          .limit(50)\
+                          .subquery('area')
 
                 return _select_from_placex(inner, False)\
                     .where(sa.func.IsBelowReverseDistance(inner.c.distance, inner.c.rank_search))\
 
                 return _select_from_placex(inner, False)\
                     .where(sa.func.IsBelowReverseDistance(inner.c.distance, inner.c.rank_search))\
@@ -561,14 +542,12 @@ class ReverseGeocoder:
 
         return address_row
 
 
         return address_row
 
-
     async def lookup(self, coord: AnyPoint) -> Optional[nres.ReverseResult]:
         """ Look up a single coordinate. Returns the place information,
             if a place was found near the coordinates or None otherwise.
         """
         log().function('reverse_lookup', coord=coord, params=self.params)
 
     async def lookup(self, coord: AnyPoint) -> Optional[nres.ReverseResult]:
         """ Look up a single coordinate. Returns the place information,
             if a place was found near the coordinates or None otherwise.
         """
         log().function('reverse_lookup', coord=coord, params=self.params)
 
-
         self.bind_params['wkt'] = f'POINT({coord[0]} {coord[1]})'
 
         row: Optional[SaRow] = None
         self.bind_params['wkt'] = f'POINT({coord[0]} {coord[1]})'
 
         row: Optional[SaRow] = None
index 1ac6db2b2a96d5ebc5095d81bd936b0002194600..632270ef04176f394a10e29d9397141bdeb5a457 100644 (file)
@@ -42,7 +42,7 @@ def build_poi_search(category: List[Tuple[str, str]],
     class _PoiData(dbf.SearchData):
         penalty = 0.0
         qualifiers = dbf.WeightedCategories(category, [0.0] * len(category))
     class _PoiData(dbf.SearchData):
         penalty = 0.0
         qualifiers = dbf.WeightedCategories(category, [0.0] * len(category))
-        countries=ccs
+        countries = ccs
 
     return dbs.PoiSearch(_PoiData())
 
 
     return dbs.PoiSearch(_PoiData())
 
@@ -55,15 +55,13 @@ class SearchBuilder:
         self.query = query
         self.details = details
 
         self.query = query
         self.details = details
 
-
     @property
     def configured_for_country(self) -> bool:
         """ Return true if the search details are configured to
             allow countries in the result.
         """
         return self.details.min_rank <= 4 and self.details.max_rank >= 4 \
     @property
     def configured_for_country(self) -> bool:
         """ Return true if the search details are configured to
             allow countries in the result.
         """
         return self.details.min_rank <= 4 and self.details.max_rank >= 4 \
-               and self.details.layer_enabled(DataLayer.ADDRESS)
-
+            and self.details.layer_enabled(DataLayer.ADDRESS)
 
     @property
     def configured_for_postcode(self) -> bool:
 
     @property
     def configured_for_postcode(self) -> bool:
@@ -71,8 +69,7 @@ class SearchBuilder:
             allow postcodes in the result.
         """
         return self.details.min_rank <= 5 and self.details.max_rank >= 11\
             allow postcodes in the result.
         """
         return self.details.min_rank <= 5 and self.details.max_rank >= 11\
-               and self.details.layer_enabled(DataLayer.ADDRESS)
-
+            and self.details.layer_enabled(DataLayer.ADDRESS)
 
     @property
     def configured_for_housenumbers(self) -> bool:
 
     @property
     def configured_for_housenumbers(self) -> bool:
@@ -80,8 +77,7 @@ class SearchBuilder:
             allow addresses in the result.
         """
         return self.details.max_rank >= 30 \
             allow addresses in the result.
         """
         return self.details.max_rank >= 30 \
-               and self.details.layer_enabled(DataLayer.ADDRESS)
-
+            and self.details.layer_enabled(DataLayer.ADDRESS)
 
     def build(self, assignment: TokenAssignment) -> Iterator[dbs.AbstractSearch]:
         """ Yield all possible abstract searches for the given token assignment.
 
     def build(self, assignment: TokenAssignment) -> Iterator[dbs.AbstractSearch]:
         """ Yield all possible abstract searches for the given token assignment.
@@ -92,7 +88,7 @@ class SearchBuilder:
 
         near_items = self.get_near_items(assignment)
         if near_items is not None and not near_items:
 
         near_items = self.get_near_items(assignment)
         if near_items is not None and not near_items:
-            return # impossible compbination of near items and category parameter
+            return  # impossible combination of near items and category parameter
 
         if assignment.name is None:
             if near_items and not sdata.postcodes:
 
         if assignment.name is None:
             if near_items and not sdata.postcodes:
@@ -123,7 +119,6 @@ class SearchBuilder:
                 search.penalty += assignment.penalty
                 yield search
 
                 search.penalty += assignment.penalty
                 yield search
 
-
     def build_poi_search(self, sdata: dbf.SearchData) -> Iterator[dbs.AbstractSearch]:
         """ Build abstract search query for a simple category search.
             This kind of search requires an additional geographic constraint.
     def build_poi_search(self, sdata: dbf.SearchData) -> Iterator[dbs.AbstractSearch]:
         """ Build abstract search query for a simple category search.
             This kind of search requires an additional geographic constraint.
@@ -132,7 +127,6 @@ class SearchBuilder:
            and ((self.details.viewbox and self.details.bounded_viewbox) or self.details.near):
             yield dbs.PoiSearch(sdata)
 
            and ((self.details.viewbox and self.details.bounded_viewbox) or self.details.near):
             yield dbs.PoiSearch(sdata)
 
-
     def build_special_search(self, sdata: dbf.SearchData,
                              address: List[TokenRange],
                              is_category: bool) -> Iterator[dbs.AbstractSearch]:
     def build_special_search(self, sdata: dbf.SearchData,
                              address: List[TokenRange],
                              is_category: bool) -> Iterator[dbs.AbstractSearch]:
@@ -157,7 +151,6 @@ class SearchBuilder:
                 penalty += 0.2
             yield dbs.PostcodeSearch(penalty, sdata)
 
                 penalty += 0.2
             yield dbs.PostcodeSearch(penalty, sdata)
 
-
     def build_housenumber_search(self, sdata: dbf.SearchData, hnrs: List[Token],
                                  address: List[TokenRange]) -> Iterator[dbs.AbstractSearch]:
         """ Build a simple address search for special entries where the
     def build_housenumber_search(self, sdata: dbf.SearchData, hnrs: List[Token],
                                  address: List[TokenRange]) -> Iterator[dbs.AbstractSearch]:
         """ Build a simple address search for special entries where the
@@ -167,7 +160,7 @@ class SearchBuilder:
         expected_count = sum(t.count for t in hnrs)
 
         partials = {t.token: t.addr_count for trange in address
         expected_count = sum(t.count for t in hnrs)
 
         partials = {t.token: t.addr_count for trange in address
-                       for t in self.query.get_partials_list(trange)}
+                    for t in self.query.get_partials_list(trange)}
 
         if not partials:
             # can happen when none of the partials is indexed
 
         if not partials:
             # can happen when none of the partials is indexed
@@ -190,7 +183,6 @@ class SearchBuilder:
         sdata.housenumbers = dbf.WeightedStrings([], [])
         yield dbs.PlaceSearch(0.05, sdata, expected_count)
 
         sdata.housenumbers = dbf.WeightedStrings([], [])
         yield dbs.PlaceSearch(0.05, sdata, expected_count)
 
-
     def build_name_search(self, sdata: dbf.SearchData,
                           name: TokenRange, address: List[TokenRange],
                           is_category: bool) -> Iterator[dbs.AbstractSearch]:
     def build_name_search(self, sdata: dbf.SearchData,
                           name: TokenRange, address: List[TokenRange],
                           is_category: bool) -> Iterator[dbs.AbstractSearch]:
@@ -205,14 +197,13 @@ class SearchBuilder:
                 sdata.lookups = lookup
                 yield dbs.PlaceSearch(penalty + name_penalty, sdata, count)
 
                 sdata.lookups = lookup
                 yield dbs.PlaceSearch(penalty + name_penalty, sdata, count)
 
-
-    def yield_lookups(self, name: TokenRange, address: List[TokenRange])\
-                          -> Iterator[Tuple[float, int, List[dbf.FieldLookup]]]:
+    def yield_lookups(self, name: TokenRange, address: List[TokenRange]
+                      ) -> Iterator[Tuple[float, int, List[dbf.FieldLookup]]]:
         """ Yield all variants how the given name and address should best
             be searched for. This takes into account how frequent the terms
             are and tries to find a lookup that optimizes index use.
         """
         """ Yield all variants how the given name and address should best
             be searched for. This takes into account how frequent the terms
             are and tries to find a lookup that optimizes index use.
         """
-        penalty = 0.0 # extra penalty
+        penalty = 0.0  # extra penalty
         name_partials = {t.token: t for t in self.query.get_partials_list(name)}
 
         addr_partials = [t for r in address for t in self.query.get_partials_list(r)]
         name_partials = {t.token: t for t in self.query.get_partials_list(name)}
 
         addr_partials = [t for r in address for t in self.query.get_partials_list(r)]
@@ -231,7 +222,7 @@ class SearchBuilder:
             fulls_count = sum(t.count for t in name_fulls)
 
             if fulls_count < 50000 or addr_count < 30000:
             fulls_count = sum(t.count for t in name_fulls)
 
             if fulls_count < 50000 or addr_count < 30000:
-                yield penalty,fulls_count / (2**len(addr_tokens)), \
+                yield penalty, fulls_count / (2**len(addr_tokens)), \
                     self.get_full_name_ranking(name_fulls, addr_partials,
                                                fulls_count > 30000 / max(1, len(addr_tokens)))
 
                     self.get_full_name_ranking(name_fulls, addr_partials,
                                                fulls_count > 30000 / max(1, len(addr_tokens)))
 
@@ -241,9 +232,8 @@ class SearchBuilder:
         if exp_count < 10000 and addr_count < 20000:
             penalty += 0.35 * max(1 if name_fulls else 0.1,
                                   5 - len(name_partials) - len(addr_tokens))
         if exp_count < 10000 and addr_count < 20000:
             penalty += 0.35 * max(1 if name_fulls else 0.1,
                                   5 - len(name_partials) - len(addr_tokens))
-            yield penalty, exp_count,\
-                  self.get_name_address_ranking(list(name_partials.keys()), addr_partials)
-
+            yield penalty, exp_count, \
+                self.get_name_address_ranking(list(name_partials.keys()), addr_partials)
 
     def get_name_address_ranking(self, name_tokens: List[int],
                                  addr_partials: List[Token]) -> List[dbf.FieldLookup]:
 
     def get_name_address_ranking(self, name_tokens: List[int],
                                  addr_partials: List[Token]) -> List[dbf.FieldLookup]:
@@ -268,7 +258,6 @@ class SearchBuilder:
 
         return lookup
 
 
         return lookup
 
-
     def get_full_name_ranking(self, name_fulls: List[Token], addr_partials: List[Token],
                               use_lookup: bool) -> List[dbf.FieldLookup]:
         """ Create a ranking expression with full name terms and
     def get_full_name_ranking(self, name_fulls: List[Token], addr_partials: List[Token],
                               use_lookup: bool) -> List[dbf.FieldLookup]:
         """ Create a ranking expression with full name terms and
@@ -293,7 +282,6 @@ class SearchBuilder:
         return dbf.lookup_by_any_name([t.token for t in name_fulls],
                                       addr_restrict_tokens, addr_lookup_tokens)
 
         return dbf.lookup_by_any_name([t.token for t in name_fulls],
                                       addr_restrict_tokens, addr_lookup_tokens)
 
-
     def get_name_ranking(self, trange: TokenRange,
                          db_field: str = 'name_vector') -> dbf.FieldRanking:
         """ Create a ranking expression for a name term in the given range.
     def get_name_ranking(self, trange: TokenRange,
                          db_field: str = 'name_vector') -> dbf.FieldRanking:
         """ Create a ranking expression for a name term in the given range.
@@ -306,7 +294,6 @@ class SearchBuilder:
         default = sum(t.penalty for t in name_partials) + 0.2
         return dbf.FieldRanking(db_field, default, ranks)
 
         default = sum(t.penalty for t in name_partials) + 0.2
         return dbf.FieldRanking(db_field, default, ranks)
 
-
     def get_addr_ranking(self, trange: TokenRange) -> dbf.FieldRanking:
         """ Create a list of ranking expressions for an address term
             for the given ranges.
     def get_addr_ranking(self, trange: TokenRange) -> dbf.FieldRanking:
         """ Create a list of ranking expressions for an address term
             for the given ranges.
@@ -315,7 +302,7 @@ class SearchBuilder:
         heapq.heappush(todo, (0, trange.start, dbf.RankedTokens(0.0, [])))
         ranks: List[dbf.RankedTokens] = []
 
         heapq.heappush(todo, (0, trange.start, dbf.RankedTokens(0.0, [])))
         ranks: List[dbf.RankedTokens] = []
 
-        while todo: # pylint: disable=too-many-nested-blocks
+        while todo:
             neglen, pos, rank = heapq.heappop(todo)
             for tlist in self.query.nodes[pos].starting:
                 if tlist.ttype in (TokenType.PARTIAL, TokenType.WORD):
             neglen, pos, rank = heapq.heappop(todo)
             for tlist in self.query.nodes[pos].starting:
                 if tlist.ttype in (TokenType.PARTIAL, TokenType.WORD):
@@ -354,7 +341,6 @@ class SearchBuilder:
 
         return dbf.FieldRanking('nameaddress_vector', default, ranks)
 
 
         return dbf.FieldRanking('nameaddress_vector', default, ranks)
 
-
     def get_search_data(self, assignment: TokenAssignment) -> Optional[dbf.SearchData]:
         """ Collect the tokens for the non-name search fields in the
             assignment.
     def get_search_data(self, assignment: TokenAssignment) -> Optional[dbf.SearchData]:
         """ Collect the tokens for the non-name search fields in the
             assignment.
@@ -401,7 +387,6 @@ class SearchBuilder:
 
         return sdata
 
 
         return sdata
 
-
     def get_country_tokens(self, trange: TokenRange) -> List[Token]:
         """ Return the list of country tokens for the given range,
             optionally filtered by the country list from the details
     def get_country_tokens(self, trange: TokenRange) -> List[Token]:
         """ Return the list of country tokens for the given range,
             optionally filtered by the country list from the details
@@ -413,7 +398,6 @@ class SearchBuilder:
 
         return tokens
 
 
         return tokens
 
-
     def get_qualifier_tokens(self, trange: TokenRange) -> List[Token]:
         """ Return the list of qualifier tokens for the given range,
             optionally filtered by the qualifier list from the details
     def get_qualifier_tokens(self, trange: TokenRange) -> List[Token]:
         """ Return the list of qualifier tokens for the given range,
             optionally filtered by the qualifier list from the details
@@ -425,7 +409,6 @@ class SearchBuilder:
 
         return tokens
 
 
         return tokens
 
-
     def get_near_items(self, assignment: TokenAssignment) -> Optional[dbf.WeightedCategories]:
         """ Collect tokens for near items search or use the categories
             requested per parameter.
     def get_near_items(self, assignment: TokenAssignment) -> Optional[dbf.WeightedCategories]:
         """ Collect tokens for near items search or use the categories
             requested per parameter.
index 95b2b4a7d8921b3daf1540db72072535c0488719..6bd330944318e06026ddfc18f031686e3623ba88 100644 (file)
@@ -28,11 +28,9 @@ class WeightedStrings:
     def __bool__(self) -> bool:
         return bool(self.values)
 
     def __bool__(self) -> bool:
         return bool(self.values)
 
-
     def __iter__(self) -> Iterator[Tuple[str, float]]:
         return iter(zip(self.values, self.penalties))
 
     def __iter__(self) -> Iterator[Tuple[str, float]]:
         return iter(zip(self.values, self.penalties))
 
-
     def get_penalty(self, value: str, default: float = 1000.0) -> float:
         """ Get the penalty for the given value. Returns the given default
             if the value does not exist.
     def get_penalty(self, value: str, default: float = 1000.0) -> float:
         """ Get the penalty for the given value. Returns the given default
             if the value does not exist.
@@ -54,11 +52,9 @@ class WeightedCategories:
     def __bool__(self) -> bool:
         return bool(self.values)
 
     def __bool__(self) -> bool:
         return bool(self.values)
 
-
     def __iter__(self) -> Iterator[Tuple[Tuple[str, str], float]]:
         return iter(zip(self.values, self.penalties))
 
     def __iter__(self) -> Iterator[Tuple[Tuple[str, str], float]]:
         return iter(zip(self.values, self.penalties))
 
-
     def get_penalty(self, value: Tuple[str, str], default: float = 1000.0) -> float:
         """ Get the penalty for the given value. Returns the given default
             if the value does not exist.
     def get_penalty(self, value: Tuple[str, str], default: float = 1000.0) -> float:
         """ Get the penalty for the given value. Returns the given default
             if the value does not exist.
@@ -69,7 +65,6 @@ class WeightedCategories:
             pass
         return default
 
             pass
         return default
 
-
     def sql_restrict(self, table: SaFromClause) -> SaExpression:
         """ Return an SQLAlcheny expression that restricts the
             class and type columns of the given table to the values
     def sql_restrict(self, table: SaFromClause) -> SaExpression:
         """ Return an SQLAlcheny expression that restricts the
             class and type columns of the given table to the values
@@ -125,7 +120,6 @@ class FieldRanking:
                 ranking.penalty -= min_penalty
         return min_penalty
 
                 ranking.penalty -= min_penalty
         return min_penalty
 
-
     def sql_penalty(self, table: SaFromClause) -> SaColumn:
         """ Create an SQL expression for the rankings.
         """
     def sql_penalty(self, table: SaFromClause) -> SaColumn:
         """ Create an SQL expression for the rankings.
         """
@@ -177,7 +171,6 @@ class SearchData:
 
     qualifiers: WeightedCategories = WeightedCategories([], [])
 
 
     qualifiers: WeightedCategories = WeightedCategories([], [])
 
-
     def set_strings(self, field: str, tokens: List[Token]) -> None:
         """ Set on of the WeightedStrings properties from the given
             token list. Adapt the global penalty, so that the
     def set_strings(self, field: str, tokens: List[Token]) -> None:
         """ Set on of the WeightedStrings properties from the given
             token list. Adapt the global penalty, so that the
@@ -191,7 +184,6 @@ class SearchData:
 
             setattr(self, field, wstrs)
 
 
             setattr(self, field, wstrs)
 
-
     def set_qualifiers(self, tokens: List[Token]) -> None:
         """ Set the qulaifier field from the given tokens.
         """
     def set_qualifiers(self, tokens: List[Token]) -> None:
         """ Set the qulaifier field from the given tokens.
         """
@@ -207,7 +199,6 @@ class SearchData:
             self.qualifiers = WeightedCategories(list(categories.keys()),
                                                  list(categories.values()))
 
             self.qualifiers = WeightedCategories(list(categories.keys()),
                                                  list(categories.values()))
 
-
     def set_ranking(self, rankings: List[FieldRanking]) -> None:
         """ Set the list of rankings and normalize the ranking.
         """
     def set_ranking(self, rankings: List[FieldRanking]) -> None:
         """ Set the list of rankings and normalize the ranking.
         """
index 4a21d51f0f8c1c3e9a5cafa60d5195621e911026..8e411c25b310816c30a3cf353d2c3fa9c60bf5d3 100644 (file)
@@ -15,10 +15,10 @@ from sqlalchemy.ext.compiler import compiles
 from ..typing import SaFromClause
 from ..sql.sqlalchemy_types import IntArray
 
 from ..typing import SaFromClause
 from ..sql.sqlalchemy_types import IntArray
 
-# pylint: disable=consider-using-f-string
 
 LookupType = sa.sql.expression.FunctionElement[Any]
 
 
 LookupType = sa.sql.expression.FunctionElement[Any]
 
+
 class LookupAll(LookupType):
     """ Find all entries in search_name table that contain all of
         a given list of tokens using an index for the search.
 class LookupAll(LookupType):
     """ Find all entries in search_name table that contain all of
         a given list of tokens using an index for the search.
@@ -40,7 +40,7 @@ def _default_lookup_all(element: LookupAll,
 
 @compiles(LookupAll, 'sqlite')
 def _sqlite_lookup_all(element: LookupAll,
 
 @compiles(LookupAll, 'sqlite')
 def _sqlite_lookup_all(element: LookupAll,
-                        compiler: 'sa.Compiled', **kw: Any) -> str:
+                       compiler: 'sa.Compiled', **kw: Any) -> str:
     place, col, colname, tokens = list(element.clauses)
     return "(%s IN (SELECT CAST(value as bigint) FROM"\
            " (SELECT array_intersect_fuzzy(places) as p FROM"\
     place, col, colname, tokens = list(element.clauses)
     return "(%s IN (SELECT CAST(value as bigint) FROM"\
            " (SELECT array_intersect_fuzzy(places) as p FROM"\
@@ -50,13 +50,11 @@ def _sqlite_lookup_all(element: LookupAll,
            "   ORDER BY length(places)) as x) as u,"\
            " json_each('[' || u.p || ']'))"\
            " AND array_contains(%s, %s))"\
            "   ORDER BY length(places)) as x) as u,"\
            " json_each('[' || u.p || ']'))"\
            " AND array_contains(%s, %s))"\
-             % (compiler.process(place, **kw),
-                compiler.process(tokens, **kw),
-                compiler.process(colname, **kw),
-                compiler.process(col, **kw),
-                compiler.process(tokens, **kw)
-                )
-
+        % (compiler.process(place, **kw),
+           compiler.process(tokens, **kw),
+           compiler.process(colname, **kw),
+           compiler.process(col, **kw),
+           compiler.process(tokens, **kw))
 
 
 class LookupAny(LookupType):
 
 
 class LookupAny(LookupType):
@@ -69,6 +67,7 @@ class LookupAny(LookupType):
         super().__init__(table.c.place_id, getattr(table.c, column), column,
                          sa.type_coerce(tokens, IntArray))
 
         super().__init__(table.c.place_id, getattr(table.c, column), column,
                          sa.type_coerce(tokens, IntArray))
 
+
 @compiles(LookupAny)
 def _default_lookup_any(element: LookupAny,
                         compiler: 'sa.Compiled', **kw: Any) -> str:
 @compiles(LookupAny)
 def _default_lookup_any(element: LookupAny,
                         compiler: 'sa.Compiled', **kw: Any) -> str:
@@ -76,9 +75,10 @@ def _default_lookup_any(element: LookupAny,
     return "(%s && %s)" % (compiler.process(col, **kw),
                            compiler.process(tokens, **kw))
 
     return "(%s && %s)" % (compiler.process(col, **kw),
                            compiler.process(tokens, **kw))
 
+
 @compiles(LookupAny, 'sqlite')
 def _sqlite_lookup_any(element: LookupAny,
 @compiles(LookupAny, 'sqlite')
 def _sqlite_lookup_any(element: LookupAny,
-                        compiler: 'sa.Compiled', **kw: Any) -> str:
+                       compiler: 'sa.Compiled', **kw: Any) -> str:
     place, _, colname, tokens = list(element.clauses)
     return "%s IN (SELECT CAST(value as bigint) FROM"\
            " (SELECT array_union(places) as p FROM reverse_search_name"\
     place, _, colname, tokens = list(element.clauses)
     return "%s IN (SELECT CAST(value as bigint) FROM"\
            " (SELECT array_union(places) as p FROM reverse_search_name"\
@@ -89,7 +89,6 @@ def _sqlite_lookup_any(element: LookupAny,
                                                compiler.process(colname, **kw))
 
 
                                                compiler.process(colname, **kw))
 
 
-
 class Restrict(LookupType):
     """ Find all entries that contain all of the given tokens.
         Do not use an index for the search.
 class Restrict(LookupType):
     """ Find all entries that contain all of the given tokens.
         Do not use an index for the search.
@@ -103,12 +102,13 @@ class Restrict(LookupType):
 
 @compiles(Restrict)
 def _default_restrict(element: Restrict,
 
 @compiles(Restrict)
 def _default_restrict(element: Restrict,
-                        compiler: 'sa.Compiled', **kw: Any) -> str:
+                      compiler: 'sa.Compiled', **kw: Any) -> str:
     arg1, arg2 = list(element.clauses)
     return "(coalesce(null, %s) @> %s)" % (compiler.process(arg1, **kw),
                                            compiler.process(arg2, **kw))
 
     arg1, arg2 = list(element.clauses)
     return "(coalesce(null, %s) @> %s)" % (compiler.process(arg1, **kw),
                                            compiler.process(arg2, **kw))
 
+
 @compiles(Restrict, 'sqlite')
 def _sqlite_restrict(element: Restrict,
 @compiles(Restrict, 'sqlite')
 def _sqlite_restrict(element: Restrict,
-                        compiler: 'sa.Compiled', **kw: Any) -> str:
+                     compiler: 'sa.Compiled', **kw: Any) -> str:
     return "array_contains(%s)" % compiler.process(element.clauses, **kw)
     return "array_contains(%s)" % compiler.process(element.clauses, **kw)
index d2202b2ccfb827d737f19af6aae574ecdb69e622..3a4c826fd871c0a60725d62188066e0bbd9ae7d9 100644 (file)
@@ -20,14 +20,12 @@ from ..types import SearchDetails, DataLayer, GeometryFormat, Bbox
 from .. import results as nres
 from .db_search_fields import SearchData, WeightedCategories
 
 from .. import results as nres
 from .db_search_fields import SearchData, WeightedCategories
 
-#pylint: disable=singleton-comparison,not-callable
-#pylint: disable=too-many-branches,too-many-arguments,too-many-locals,too-many-statements
 
 def no_index(expr: SaColumn) -> SaColumn:
     """ Wrap the given expression, so that the query planner will
         refrain from using the expression for index lookup.
     """
 
 def no_index(expr: SaColumn) -> SaColumn:
     """ Wrap the given expression, so that the query planner will
         refrain from using the expression for index lookup.
     """
-    return sa.func.coalesce(sa.null(), expr) # pylint: disable=not-callable
+    return sa.func.coalesce(sa.null(), expr)
 
 
 def _details_to_bind_params(details: SearchDetails) -> Dict[str, Any]:
 
 
 def _details_to_bind_params(details: SearchDetails) -> Dict[str, Any]:
@@ -68,7 +66,7 @@ def filter_by_area(sql: SaSelect, t: SaFromClause,
     if details.viewbox is not None and details.bounded_viewbox:
         sql = sql.where(t.c.geometry.intersects(VIEWBOX_PARAM,
                                                 use_index=not avoid_index and
     if details.viewbox is not None and details.bounded_viewbox:
         sql = sql.where(t.c.geometry.intersects(VIEWBOX_PARAM,
                                                 use_index=not avoid_index and
-                                                          details.viewbox.area < 0.2))
+                                                details.viewbox.area < 0.2))
 
     return sql
 
 
     return sql
 
@@ -190,7 +188,7 @@ def _int_list_to_subquery(inp: List[int]) -> 'sa.Subquery':
         as rows in the column 'nr'.
     """
     vtab = sa.func.JsonArrayEach(sa.type_coerce(inp, sa.JSON))\
         as rows in the column 'nr'.
     """
     vtab = sa.func.JsonArrayEach(sa.type_coerce(inp, sa.JSON))\
-               .table_valued(sa.column('value', type_=sa.JSON))
+             .table_valued(sa.column('value', type_=sa.JSON))
     return sa.select(sa.cast(sa.cast(vtab.c.value, sa.Text), sa.Integer).label('nr')).subquery()
 
 
     return sa.select(sa.cast(sa.cast(vtab.c.value, sa.Text), sa.Integer).label('nr')).subquery()
 
 
@@ -266,7 +264,6 @@ class NearSearch(AbstractSearch):
         self.search = search
         self.categories = categories
 
         self.search = search
         self.categories = categories
 
-
     async def lookup(self, conn: SearchConnection,
                      details: SearchDetails) -> nres.SearchResults:
         """ Find results for the search in the database.
     async def lookup(self, conn: SearchConnection,
                      details: SearchDetails) -> nres.SearchResults:
         """ Find results for the search in the database.
@@ -288,11 +285,12 @@ class NearSearch(AbstractSearch):
         else:
             min_rank = 26
             max_rank = 30
         else:
             min_rank = 26
             max_rank = 30
-        base = nres.SearchResults(r for r in base if r.source_table == nres.SourceTable.PLACEX
-                                                     and r.accuracy <= max_accuracy
-                                                     and r.bbox and r.bbox.area < 20
-                                                     and r.rank_address >= min_rank
-                                                     and r.rank_address <= max_rank)
+        base = nres.SearchResults(r for r in base
+                                  if (r.source_table == nres.SourceTable.PLACEX
+                                      and r.accuracy <= max_accuracy
+                                      and r.bbox and r.bbox.area < 20
+                                      and r.rank_address >= min_rank
+                                      and r.rank_address <= max_rank))
 
         if base:
             baseids = [b.place_id for b in base[:5] if b.place_id]
 
         if base:
             baseids = [b.place_id for b in base[:5] if b.place_id]
@@ -304,7 +302,6 @@ class NearSearch(AbstractSearch):
 
         return results
 
 
         return results
 
-
     async def lookup_category(self, results: nres.SearchResults,
                               conn: SearchConnection, ids: List[int],
                               category: Tuple[str, str], penalty: float,
     async def lookup_category(self, results: nres.SearchResults,
                               conn: SearchConnection, ids: List[int],
                               category: Tuple[str, str], penalty: float,
@@ -334,9 +331,9 @@ class NearSearch(AbstractSearch):
                     .join(tgeom,
                           table.c.centroid.ST_CoveredBy(
                               sa.case((sa.and_(tgeom.c.rank_address > 9,
                     .join(tgeom,
                           table.c.centroid.ST_CoveredBy(
                               sa.case((sa.and_(tgeom.c.rank_address > 9,
-                                                tgeom.c.geometry.is_area()),
+                                               tgeom.c.geometry.is_area()),
                                        tgeom.c.geometry),
                                        tgeom.c.geometry),
-                                      else_ = tgeom.c.centroid.ST_Expand(0.05))))
+                                      else_=tgeom.c.centroid.ST_Expand(0.05))))
 
         inner = sql.where(tgeom.c.place_id.in_(ids))\
                    .group_by(table.c.place_id).subquery()
 
         inner = sql.where(tgeom.c.place_id.in_(ids))\
                    .group_by(table.c.place_id).subquery()
@@ -363,7 +360,6 @@ class NearSearch(AbstractSearch):
             results.append(result)
 
 
             results.append(result)
 
 
-
 class PoiSearch(AbstractSearch):
     """ Category search in a geographic area.
     """
 class PoiSearch(AbstractSearch):
     """ Category search in a geographic area.
     """
@@ -372,7 +368,6 @@ class PoiSearch(AbstractSearch):
         self.qualifiers = sdata.qualifiers
         self.countries = sdata.countries
 
         self.qualifiers = sdata.qualifiers
         self.countries = sdata.countries
 
-
     async def lookup(self, conn: SearchConnection,
                      details: SearchDetails) -> nres.SearchResults:
         """ Find results for the search in the database.
     async def lookup(self, conn: SearchConnection,
                      details: SearchDetails) -> nres.SearchResults:
         """ Find results for the search in the database.
@@ -387,7 +382,7 @@ class PoiSearch(AbstractSearch):
             def _base_query() -> SaSelect:
                 return _select_placex(t) \
                            .add_columns((-t.c.centroid.ST_Distance(NEAR_PARAM))
             def _base_query() -> SaSelect:
                 return _select_placex(t) \
                            .add_columns((-t.c.centroid.ST_Distance(NEAR_PARAM))
-                                         .label('importance'))\
+                                        .label('importance'))\
                            .where(t.c.linked_place_id == None) \
                            .where(t.c.geometry.within_distance(NEAR_PARAM, NEAR_RADIUS_PARAM)) \
                            .order_by(t.c.centroid.ST_Distance(NEAR_PARAM)) \
                            .where(t.c.linked_place_id == None) \
                            .where(t.c.geometry.within_distance(NEAR_PARAM, NEAR_RADIUS_PARAM)) \
                            .order_by(t.c.centroid.ST_Distance(NEAR_PARAM)) \
@@ -396,9 +391,9 @@ class PoiSearch(AbstractSearch):
             classtype = self.qualifiers.values
             if len(classtype) == 1:
                 cclass, ctype = classtype[0]
             classtype = self.qualifiers.values
             if len(classtype) == 1:
                 cclass, ctype = classtype[0]
-                sql: SaLambdaSelect = sa.lambda_stmt(lambda: _base_query()
-                                                 .where(t.c.class_ == cclass)
-                                                 .where(t.c.type == ctype))
+                sql: SaLambdaSelect = sa.lambda_stmt(
+                    lambda: _base_query().where(t.c.class_ == cclass)
+                                         .where(t.c.type == ctype))
             else:
                 sql = _base_query().where(sa.or_(*(sa.and_(t.c.class_ == cls, t.c.type == typ)
                                                    for cls, typ in classtype)))
             else:
                 sql = _base_query().where(sa.or_(*(sa.and_(t.c.class_ == cls, t.c.type == typ)
                                                    for cls, typ in classtype)))
@@ -455,7 +450,6 @@ class CountrySearch(AbstractSearch):
         super().__init__(sdata.penalty)
         self.countries = sdata.countries
 
         super().__init__(sdata.penalty)
         self.countries = sdata.countries
 
-
     async def lookup(self, conn: SearchConnection,
                      details: SearchDetails) -> nres.SearchResults:
         """ Find results for the search in the database.
     async def lookup(self, conn: SearchConnection,
                      details: SearchDetails) -> nres.SearchResults:
         """ Find results for the search in the database.
@@ -464,9 +458,9 @@ class CountrySearch(AbstractSearch):
 
         ccodes = self.countries.values
         sql = _select_placex(t)\
 
         ccodes = self.countries.values
         sql = _select_placex(t)\
-                .add_columns(t.c.importance)\
-                .where(t.c.country_code.in_(ccodes))\
-                .where(t.c.rank_address == 4)
+            .add_columns(t.c.importance)\
+            .where(t.c.country_code.in_(ccodes))\
+            .where(t.c.rank_address == 4)
 
         if details.geometry_output:
             sql = _add_geometry_columns(sql, t.c.geometry, details)
 
         if details.geometry_output:
             sql = _add_geometry_columns(sql, t.c.geometry, details)
@@ -493,7 +487,6 @@ class CountrySearch(AbstractSearch):
 
         return results
 
 
         return results
 
-
     async def lookup_in_country_table(self, conn: SearchConnection,
                                       details: SearchDetails) -> nres.SearchResults:
         """ Look up the country in the fallback country tables.
     async def lookup_in_country_table(self, conn: SearchConnection,
                                       details: SearchDetails) -> nres.SearchResults:
         """ Look up the country in the fallback country tables.
@@ -509,7 +502,7 @@ class CountrySearch(AbstractSearch):
 
         sql = sa.select(tgrid.c.country_code,
                         tgrid.c.geometry.ST_Centroid().ST_Collect().ST_Centroid()
 
         sql = sa.select(tgrid.c.country_code,
                         tgrid.c.geometry.ST_Centroid().ST_Collect().ST_Centroid()
-                              .label('centroid'),
+                             .label('centroid'),
                         tgrid.c.geometry.ST_Collect().ST_Expand(0).label('bbox'))\
                 .where(tgrid.c.country_code.in_(self.countries.values))\
                 .group_by(tgrid.c.country_code)
                         tgrid.c.geometry.ST_Collect().ST_Expand(0).label('bbox'))\
                 .where(tgrid.c.country_code.in_(self.countries.values))\
                 .group_by(tgrid.c.country_code)
@@ -537,7 +530,6 @@ class CountrySearch(AbstractSearch):
         return results
 
 
         return results
 
 
-
 class PostcodeSearch(AbstractSearch):
     """ Search for a postcode.
     """
 class PostcodeSearch(AbstractSearch):
     """ Search for a postcode.
     """
@@ -548,7 +540,6 @@ class PostcodeSearch(AbstractSearch):
         self.lookups = sdata.lookups
         self.rankings = sdata.rankings
 
         self.lookups = sdata.lookups
         self.rankings = sdata.rankings
 
-
     async def lookup(self, conn: SearchConnection,
                      details: SearchDetails) -> nres.SearchResults:
         """ Find results for the search in the database.
     async def lookup(self, conn: SearchConnection,
                      details: SearchDetails) -> nres.SearchResults:
         """ Find results for the search in the database.
@@ -588,14 +579,13 @@ class PostcodeSearch(AbstractSearch):
             tsearch = conn.t.search_name
             sql = sql.where(tsearch.c.place_id == t.c.parent_place_id)\
                      .where((tsearch.c.name_vector + tsearch.c.nameaddress_vector)
             tsearch = conn.t.search_name
             sql = sql.where(tsearch.c.place_id == t.c.parent_place_id)\
                      .where((tsearch.c.name_vector + tsearch.c.nameaddress_vector)
-                                     .contains(sa.type_coerce(self.lookups[0].tokens,
-                                                              IntArray)))
+                            .contains(sa.type_coerce(self.lookups[0].tokens,
+                                                     IntArray)))
 
         for ranking in self.rankings:
             penalty += ranking.sql_penalty(conn.t.search_name)
         penalty += sa.case(*((t.c.postcode == v, p) for v, p in self.postcodes),
 
         for ranking in self.rankings:
             penalty += ranking.sql_penalty(conn.t.search_name)
         penalty += sa.case(*((t.c.postcode == v, p) for v, p in self.postcodes),
-                       else_=1.0)
-
+                           else_=1.0)
 
         sql = sql.add_columns(penalty.label('accuracy'))
         sql = sql.order_by('accuracy').limit(LIMIT_PARAM)
 
         sql = sql.add_columns(penalty.label('accuracy'))
         sql = sql.order_by('accuracy').limit(LIMIT_PARAM)
@@ -603,13 +593,14 @@ class PostcodeSearch(AbstractSearch):
         results = nres.SearchResults()
         for row in await conn.execute(sql, _details_to_bind_params(details)):
             p = conn.t.placex
         results = nres.SearchResults()
         for row in await conn.execute(sql, _details_to_bind_params(details)):
             p = conn.t.placex
-            placex_sql = _select_placex(p).add_columns(p.c.importance)\
-                             .where(sa.text("""class = 'boundary'
-                                               AND type = 'postal_code'
-                                               AND osm_type = 'R'"""))\
-                             .where(p.c.country_code == row.country_code)\
-                             .where(p.c.postcode == row.postcode)\
-                             .limit(1)
+            placex_sql = _select_placex(p)\
+                .add_columns(p.c.importance)\
+                .where(sa.text("""class = 'boundary'
+                                  AND type = 'postal_code'
+                                  AND osm_type = 'R'"""))\
+                .where(p.c.country_code == row.country_code)\
+                .where(p.c.postcode == row.postcode)\
+                .limit(1)
 
             if details.geometry_output:
                 placex_sql = _add_geometry_columns(placex_sql, p.c.geometry, details)
 
             if details.geometry_output:
                 placex_sql = _add_geometry_columns(placex_sql, p.c.geometry, details)
@@ -630,7 +621,6 @@ class PostcodeSearch(AbstractSearch):
         return results
 
 
         return results
 
 
-
 class PlaceSearch(AbstractSearch):
     """ Generic search for an address or named place.
     """
 class PlaceSearch(AbstractSearch):
     """ Generic search for an address or named place.
     """
@@ -646,7 +636,6 @@ class PlaceSearch(AbstractSearch):
         self.rankings = sdata.rankings
         self.expected_count = expected_count
 
         self.rankings = sdata.rankings
         self.expected_count = expected_count
 
-
     def _inner_search_name_cte(self, conn: SearchConnection,
                                details: SearchDetails) -> 'sa.CTE':
         """ Create a subquery that preselects the rows in the search_name
     def _inner_search_name_cte(self, conn: SearchConnection,
                                details: SearchDetails) -> 'sa.CTE':
         """ Create a subquery that preselects the rows in the search_name
@@ -699,7 +688,7 @@ class PlaceSearch(AbstractSearch):
                                                              NEAR_RADIUS_PARAM))
             else:
                 sql = sql.where(t.c.centroid
                                                              NEAR_RADIUS_PARAM))
             else:
                 sql = sql.where(t.c.centroid
-                                   .ST_Distance(NEAR_PARAM) <  NEAR_RADIUS_PARAM)
+                                 .ST_Distance(NEAR_PARAM) < NEAR_RADIUS_PARAM)
 
         if self.housenumbers:
             sql = sql.where(t.c.address_rank.between(16, 30))
 
         if self.housenumbers:
             sql = sql.where(t.c.address_rank.between(16, 30))
@@ -727,8 +716,8 @@ class PlaceSearch(AbstractSearch):
            and (details.near is None or details.near_radius is not None)\
            and not self.qualifiers:
             sql = sql.add_columns(sa.func.first_value(inner.c.penalty - inner.c.importance)
            and (details.near is None or details.near_radius is not None)\
            and not self.qualifiers:
             sql = sql.add_columns(sa.func.first_value(inner.c.penalty - inner.c.importance)
-                                       .over(order_by=inner.c.penalty - inner.c.importance)
-                                       .label('min_penalty'))
+                                    .over(order_by=inner.c.penalty - inner.c.importance)
+                                    .label('min_penalty'))
 
             inner = sql.subquery()
 
 
             inner = sql.subquery()
 
@@ -739,7 +728,6 @@ class PlaceSearch(AbstractSearch):
 
         return sql.cte('searches')
 
 
         return sql.cte('searches')
 
-
     async def lookup(self, conn: SearchConnection,
                      details: SearchDetails) -> nres.SearchResults:
         """ Find results for the search in the database.
     async def lookup(self, conn: SearchConnection,
                      details: SearchDetails) -> nres.SearchResults:
         """ Find results for the search in the database.
@@ -759,8 +747,8 @@ class PlaceSearch(AbstractSearch):
             pcs = self.postcodes.values
 
             pc_near = sa.select(sa.func.min(tpc.c.geometry.ST_Distance(t.c.centroid)))\
             pcs = self.postcodes.values
 
             pc_near = sa.select(sa.func.min(tpc.c.geometry.ST_Distance(t.c.centroid)))\
-                      .where(tpc.c.postcode.in_(pcs))\
-                      .scalar_subquery()
+                        .where(tpc.c.postcode.in_(pcs))\
+                        .scalar_subquery()
             penalty += sa.case((t.c.postcode.in_(pcs), 0.0),
                                else_=sa.func.coalesce(pc_near, cast(SaColumn, 2.0)))
 
             penalty += sa.case((t.c.postcode.in_(pcs), 0.0),
                                else_=sa.func.coalesce(pc_near, cast(SaColumn, 2.0)))
 
@@ -771,13 +759,12 @@ class PlaceSearch(AbstractSearch):
 
         if details.near is not None:
             sql = sql.add_columns((-tsearch.c.centroid.ST_Distance(NEAR_PARAM))
 
         if details.near is not None:
             sql = sql.add_columns((-tsearch.c.centroid.ST_Distance(NEAR_PARAM))
-                                      .label('importance'))
+                                  .label('importance'))
             sql = sql.order_by(sa.desc(sa.text('importance')))
         else:
             sql = sql.order_by(penalty - tsearch.c.importance)
             sql = sql.add_columns(tsearch.c.importance)
 
             sql = sql.order_by(sa.desc(sa.text('importance')))
         else:
             sql = sql.order_by(penalty - tsearch.c.importance)
             sql = sql.add_columns(tsearch.c.importance)
 
-
         sql = sql.add_columns(penalty.label('accuracy'))\
                  .order_by(sa.text('accuracy'))
 
         sql = sql.add_columns(penalty.label('accuracy'))\
                  .order_by(sa.text('accuracy'))
 
@@ -814,7 +801,7 @@ class PlaceSearch(AbstractSearch):
                 tiger_sql = sa.case((inner.c.country_code == 'us',
                                      _make_interpolation_subquery(conn.t.tiger, inner,
                                                                   numerals, details)
                 tiger_sql = sa.case((inner.c.country_code == 'us',
                                      _make_interpolation_subquery(conn.t.tiger, inner,
                                                                   numerals, details)
-                                    ), else_=None)
+                                     ), else_=None)
             else:
                 interpol_sql = sa.null()
                 tiger_sql = sa.null()
             else:
                 interpol_sql = sa.null()
                 tiger_sql = sa.null()
@@ -868,7 +855,7 @@ class PlaceSearch(AbstractSearch):
                 if (not details.excluded or result.place_id not in details.excluded)\
                    and (not self.qualifiers or result.category in self.qualifiers.values)\
                    and result.rank_address >= details.min_rank:
                 if (not details.excluded or result.place_id not in details.excluded)\
                    and (not self.qualifiers or result.category in self.qualifiers.values)\
                    and result.rank_address >= details.min_rank:
-                    result.accuracy += 1.0 # penalty for missing housenumber
+                    result.accuracy += 1.0  # penalty for missing housenumber
                     results.append(result)
             else:
                 results.append(result)
                     results.append(result)
             else:
                 results.append(result)
index b5fd1f002e8483ed070dcad714351e04cdeefb64..195dd513ebc103b462d85bed236b4dccde858f72 100644 (file)
@@ -23,6 +23,7 @@ from .db_searches import AbstractSearch
 from .query_analyzer_factory import make_query_analyzer, AbstractQueryAnalyzer
 from .query import Phrase, QueryStruct
 
 from .query_analyzer_factory import make_query_analyzer, AbstractQueryAnalyzer
 from .query import Phrase, QueryStruct
 
+
 class ForwardGeocoder:
     """ Main class responsible for place search.
     """
 class ForwardGeocoder:
     """ Main class responsible for place search.
     """
@@ -34,14 +35,12 @@ class ForwardGeocoder:
         self.timeout = dt.timedelta(seconds=timeout or 1000000)
         self.query_analyzer: Optional[AbstractQueryAnalyzer] = None
 
         self.timeout = dt.timedelta(seconds=timeout or 1000000)
         self.query_analyzer: Optional[AbstractQueryAnalyzer] = None
 
-
     @property
     def limit(self) -> int:
         """ Return the configured maximum number of search results.
         """
         return self.params.max_results
 
     @property
     def limit(self) -> int:
         """ Return the configured maximum number of search results.
         """
         return self.params.max_results
 
-
     async def build_searches(self,
                              phrases: List[Phrase]) -> Tuple[QueryStruct, List[AbstractSearch]]:
         """ Analyse the query and return the tokenized query and list of
     async def build_searches(self,
                              phrases: List[Phrase]) -> Tuple[QueryStruct, List[AbstractSearch]]:
         """ Analyse the query and return the tokenized query and list of
@@ -68,7 +67,6 @@ class ForwardGeocoder:
 
         return query, searches
 
 
         return query, searches
 
-
     async def execute_searches(self, query: QueryStruct,
                                searches: List[AbstractSearch]) -> SearchResults:
         """ Run the abstract searches against the database until a result
     async def execute_searches(self, query: QueryStruct,
                                searches: List[AbstractSearch]) -> SearchResults:
         """ Run the abstract searches against the database until a result
@@ -103,7 +101,6 @@ class ForwardGeocoder:
 
         return SearchResults(results.values())
 
 
         return SearchResults(results.values())
 
-
     def pre_filter_results(self, results: SearchResults) -> SearchResults:
         """ Remove results that are significantly worse than the
             best match.
     def pre_filter_results(self, results: SearchResults) -> SearchResults:
         """ Remove results that are significantly worse than the
             best match.
@@ -114,7 +111,6 @@ class ForwardGeocoder:
 
         return results
 
 
         return results
 
-
     def sort_and_cut_results(self, results: SearchResults) -> SearchResults:
         """ Remove badly matching results, sort by ranking and
             limit to the configured number of results.
     def sort_and_cut_results(self, results: SearchResults) -> SearchResults:
         """ Remove badly matching results, sort by ranking and
             limit to the configured number of results.
@@ -124,21 +120,20 @@ class ForwardGeocoder:
             min_rank = results[0].rank_search
             min_ranking = results[0].ranking
             results = SearchResults(r for r in results
             min_rank = results[0].rank_search
             min_ranking = results[0].ranking
             results = SearchResults(r for r in results
-                                    if r.ranking + 0.03 * (r.rank_search - min_rank)
-                                       < min_ranking + 0.5)
+                                    if (r.ranking + 0.03 * (r.rank_search - min_rank)
+                                        < min_ranking + 0.5))
 
             results = SearchResults(results[:self.limit])
 
         return results
 
 
             results = SearchResults(results[:self.limit])
 
         return results
 
-
     def rerank_by_query(self, query: QueryStruct, results: SearchResults) -> None:
         """ Adjust the accuracy of the localized result according to how well
             they match the original query.
         """
         assert self.query_analyzer is not None
         qwords = [word for phrase in query.source
     def rerank_by_query(self, query: QueryStruct, results: SearchResults) -> None:
         """ Adjust the accuracy of the localized result according to how well
             they match the original query.
         """
         assert self.query_analyzer is not None
         qwords = [word for phrase in query.source
-                       for word in re.split('[, ]+', phrase.text) if word]
+                  for word in re.split('[, ]+', phrase.text) if word]
         if not qwords:
             return
 
         if not qwords:
             return
 
@@ -167,7 +162,6 @@ class ForwardGeocoder:
                 distance *= 2
             result.accuracy += distance * 0.4 / sum(len(w) for w in qwords)
 
                 distance *= 2
             result.accuracy += distance * 0.4 / sum(len(w) for w in qwords)
 
-
     async def lookup_pois(self, categories: List[Tuple[str, str]],
                           phrases: List[Phrase]) -> SearchResults:
         """ Look up places by category. If phrase is given, a place search
     async def lookup_pois(self, categories: List[Tuple[str, str]],
                           phrases: List[Phrase]) -> SearchResults:
         """ Look up places by category. If phrase is given, a place search
@@ -197,7 +191,6 @@ class ForwardGeocoder:
 
         return results
 
 
         return results
 
-
     async def lookup(self, phrases: List[Phrase]) -> SearchResults:
         """ Look up a single free-text query.
         """
     async def lookup(self, phrases: List[Phrase]) -> SearchResults:
         """ Look up a single free-text query.
         """
@@ -223,7 +216,6 @@ class ForwardGeocoder:
         return results
 
 
         return results
 
 
-# pylint: disable=invalid-name,too-many-locals
 def _dump_searches(searches: List[AbstractSearch], query: QueryStruct,
                    start: int = 0) -> Iterator[Optional[List[Any]]]:
     yield ['Penalty', 'Lookups', 'Housenr', 'Postcode', 'Countries',
 def _dump_searches(searches: List[AbstractSearch], query: QueryStruct,
                    start: int = 0) -> Iterator[Optional[List[Any]]]:
     yield ['Penalty', 'Lookups', 'Housenr', 'Postcode', 'Countries',
@@ -242,12 +234,11 @@ def _dump_searches(searches: List[AbstractSearch], query: QueryStruct,
             ranks = ranks[:100] + '...'
         return f"{f.column}({ranks},def={f.default:.3g})"
 
             ranks = ranks[:100] + '...'
         return f"{f.column}({ranks},def={f.default:.3g})"
 
-    def fmt_lookup(l: Any) -> str:
-        if not l:
+    def fmt_lookup(lk: Any) -> str:
+        if not lk:
             return ''
 
             return ''
 
-        return f"{l.lookup_type}({l.column}{tk(l.tokens)})"
-
+        return f"{lk.lookup_type}({lk.column}{tk(lk.tokens)})"
 
     def fmt_cstr(c: Any) -> str:
         if not c:
 
     def fmt_cstr(c: Any) -> str:
         if not c:
index 1aadc97e80170181fad8c35a1d70f7eb6464696d..fa14531aed0d6c07cf79c277255324495b1b063d 100644 (file)
@@ -48,6 +48,7 @@ class QueryPart(NamedTuple):
 QueryParts = List[QueryPart]
 WordDict = Dict[str, List[qmod.TokenRange]]
 
 QueryParts = List[QueryPart]
 WordDict = Dict[str, List[qmod.TokenRange]]
 
+
 def yield_words(terms: List[QueryPart], start: int) -> Iterator[Tuple[str, qmod.TokenRange]]:
     """ Return all combinations of words in the terms list after the
         given position.
 def yield_words(terms: List[QueryPart], start: int) -> Iterator[Tuple[str, qmod.TokenRange]]:
     """ Return all combinations of words in the terms list after the
         given position.
@@ -72,7 +73,6 @@ class ICUToken(qmod.Token):
         assert self.info
         return self.info.get('class', ''), self.info.get('type', '')
 
         assert self.info
         return self.info.get('class', ''), self.info.get('type', '')
 
-
     def rematch(self, norm: str) -> None:
         """ Check how well the token matches the given normalized string
             and add a penalty, if necessary.
     def rematch(self, norm: str) -> None:
         """ Check how well the token matches the given normalized string
             and add a penalty, if necessary.
@@ -91,7 +91,6 @@ class ICUToken(qmod.Token):
                 distance += abs((ato-afrom) - (bto-bfrom))
         self.penalty += (distance/len(self.lookup_word))
 
                 distance += abs((ato-afrom) - (bto-bfrom))
         self.penalty += (distance/len(self.lookup_word))
 
-
     @staticmethod
     def from_db_row(row: SaRow) -> 'ICUToken':
         """ Create a ICUToken from the row of the word table.
     @staticmethod
     def from_db_row(row: SaRow) -> 'ICUToken':
         """ Create a ICUToken from the row of the word table.
@@ -128,16 +127,13 @@ class ICUToken(qmod.Token):
                         addr_count=max(1, addr_count))
 
 
                         addr_count=max(1, addr_count))
 
 
-
 class ICUQueryAnalyzer(AbstractQueryAnalyzer):
     """ Converter for query strings into a tokenized query
         using the tokens created by a ICU tokenizer.
     """
 class ICUQueryAnalyzer(AbstractQueryAnalyzer):
     """ Converter for query strings into a tokenized query
         using the tokens created by a ICU tokenizer.
     """
-
     def __init__(self, conn: SearchConnection) -> None:
         self.conn = conn
 
     def __init__(self, conn: SearchConnection) -> None:
         self.conn = conn
 
-
     async def setup(self) -> None:
         """ Set up static data structures needed for the analysis.
         """
     async def setup(self) -> None:
         """ Set up static data structures needed for the analysis.
         """
@@ -163,7 +159,6 @@ class ICUQueryAnalyzer(AbstractQueryAnalyzer):
                      sa.Column('word', sa.Text),
                      sa.Column('info', Json))
 
                      sa.Column('word', sa.Text),
                      sa.Column('info', Json))
 
-
     async def analyze_query(self, phrases: List[qmod.Phrase]) -> qmod.QueryStruct:
         """ Analyze the given list of phrases and return the
             tokenized query.
     async def analyze_query(self, phrases: List[qmod.Phrase]) -> qmod.QueryStruct:
         """ Analyze the given list of phrases and return the
             tokenized query.
@@ -202,7 +197,6 @@ class ICUQueryAnalyzer(AbstractQueryAnalyzer):
 
         return query
 
 
         return query
 
-
     def normalize_text(self, text: str) -> str:
         """ Bring the given text into a normalized form. That is the
             standardized form search will work with. All information removed
     def normalize_text(self, text: str) -> str:
         """ Bring the given text into a normalized form. That is the
             standardized form search will work with. All information removed
@@ -210,7 +204,6 @@ class ICUQueryAnalyzer(AbstractQueryAnalyzer):
         """
         return cast(str, self.normalizer.transliterate(text))
 
         """
         return cast(str, self.normalizer.transliterate(text))
 
-
     def split_query(self, query: qmod.QueryStruct) -> Tuple[QueryParts, WordDict]:
         """ Transliterate the phrases and split them into tokens.
 
     def split_query(self, query: qmod.QueryStruct) -> Tuple[QueryParts, WordDict]:
         """ Transliterate the phrases and split them into tokens.
 
@@ -243,7 +236,6 @@ class ICUQueryAnalyzer(AbstractQueryAnalyzer):
 
         return parts, words
 
 
         return parts, words
 
-
     async def lookup_in_db(self, words: List[str]) -> 'sa.Result[Any]':
         """ Return the token information from the database for the
             given word tokens.
     async def lookup_in_db(self, words: List[str]) -> 'sa.Result[Any]':
         """ Return the token information from the database for the
             given word tokens.
@@ -251,7 +243,6 @@ class ICUQueryAnalyzer(AbstractQueryAnalyzer):
         t = self.conn.t.meta.tables['word']
         return await self.conn.execute(t.select().where(t.c.word_token.in_(words)))
 
         t = self.conn.t.meta.tables['word']
         return await self.conn.execute(t.select().where(t.c.word_token.in_(words)))
 
-
     def add_extra_tokens(self, query: qmod.QueryStruct, parts: QueryParts) -> None:
         """ Add tokens to query that are not saved in the database.
         """
     def add_extra_tokens(self, query: qmod.QueryStruct, parts: QueryParts) -> None:
         """ Add tokens to query that are not saved in the database.
         """
@@ -263,7 +254,6 @@ class ICUQueryAnalyzer(AbstractQueryAnalyzer):
                                          count=1, addr_count=1, lookup_word=part.token,
                                          word_token=part.token, info=None))
 
                                          count=1, addr_count=1, lookup_word=part.token,
                                          word_token=part.token, info=None))
 
-
     def rerank_tokens(self, query: qmod.QueryStruct, parts: QueryParts) -> None:
         """ Add penalties to tokens that depend on presence of other token.
         """
     def rerank_tokens(self, query: qmod.QueryStruct, parts: QueryParts) -> None:
         """ Add penalties to tokens that depend on presence of other token.
         """
@@ -274,8 +264,8 @@ class ICUQueryAnalyzer(AbstractQueryAnalyzer):
                        and (repl.ttype != qmod.TokenType.HOUSENUMBER
                             or len(tlist.tokens[0].lookup_word) > 4):
                         repl.add_penalty(0.39)
                        and (repl.ttype != qmod.TokenType.HOUSENUMBER
                             or len(tlist.tokens[0].lookup_word) > 4):
                         repl.add_penalty(0.39)
-            elif tlist.ttype == qmod.TokenType.HOUSENUMBER \
-                 and len(tlist.tokens[0].lookup_word) <= 3:
+            elif (tlist.ttype == qmod.TokenType.HOUSENUMBER
+                  and len(tlist.tokens[0].lookup_word) <= 3):
                 if any(c.isdigit() for c in tlist.tokens[0].lookup_word):
                     for repl in node.starting:
                         if repl.end == tlist.end and repl.ttype != qmod.TokenType.HOUSENUMBER:
                 if any(c.isdigit() for c in tlist.tokens[0].lookup_word):
                     for repl in node.starting:
                         if repl.end == tlist.end and repl.ttype != qmod.TokenType.HOUSENUMBER:
index 53482df84a11d228ec5c771b71dfc739f9258b1e..02ebbb5b9d7b6f690af9bdcba466151d57117d1a 100644 (file)
@@ -12,6 +12,7 @@ from abc import ABC, abstractmethod
 import dataclasses
 import enum
 
 import dataclasses
 import enum
 
+
 class BreakType(enum.Enum):
     """ Type of break between tokens.
     """
 class BreakType(enum.Enum):
     """ Type of break between tokens.
     """
@@ -102,13 +103,13 @@ class Token(ABC):
     addr_count: int
     lookup_word: str
 
     addr_count: int
     lookup_word: str
 
-
     @abstractmethod
     def get_category(self) -> Tuple[str, str]:
         """ Return the category restriction for qualifier terms and
             category objects.
         """
 
     @abstractmethod
     def get_category(self) -> Tuple[str, str]:
         """ Return the category restriction for qualifier terms and
             category objects.
         """
 
+
 @dataclasses.dataclass
 class TokenRange:
     """ Indexes of query nodes over which a token spans.
 @dataclasses.dataclass
 class TokenRange:
     """ Indexes of query nodes over which a token spans.
@@ -119,31 +120,25 @@ class TokenRange:
     def __lt__(self, other: 'TokenRange') -> bool:
         return self.end <= other.start
 
     def __lt__(self, other: 'TokenRange') -> bool:
         return self.end <= other.start
 
-
     def __le__(self, other: 'TokenRange') -> bool:
         return NotImplemented
 
     def __le__(self, other: 'TokenRange') -> bool:
         return NotImplemented
 
-
     def __gt__(self, other: 'TokenRange') -> bool:
         return self.start >= other.end
 
     def __gt__(self, other: 'TokenRange') -> bool:
         return self.start >= other.end
 
-
     def __ge__(self, other: 'TokenRange') -> bool:
         return NotImplemented
 
     def __ge__(self, other: 'TokenRange') -> bool:
         return NotImplemented
 
-
     def replace_start(self, new_start: int) -> 'TokenRange':
         """ Return a new token range with the new start.
         """
         return TokenRange(new_start, self.end)
 
     def replace_start(self, new_start: int) -> 'TokenRange':
         """ Return a new token range with the new start.
         """
         return TokenRange(new_start, self.end)
 
-
     def replace_end(self, new_end: int) -> 'TokenRange':
         """ Return a new token range with the new end.
         """
         return TokenRange(self.start, new_end)
 
     def replace_end(self, new_end: int) -> 'TokenRange':
         """ Return a new token range with the new end.
         """
         return TokenRange(self.start, new_end)
 
-
     def split(self, index: int) -> Tuple['TokenRange', 'TokenRange']:
         """ Split the span into two spans at the given index.
             The index must be within the span.
     def split(self, index: int) -> Tuple['TokenRange', 'TokenRange']:
         """ Split the span into two spans at the given index.
             The index must be within the span.
@@ -159,7 +154,6 @@ class TokenList:
     ttype: TokenType
     tokens: List[Token]
 
     ttype: TokenType
     tokens: List[Token]
 
-
     def add_penalty(self, penalty: float) -> None:
         """ Add the given penalty to all tokens in the list.
         """
     def add_penalty(self, penalty: float) -> None:
         """ Add the given penalty to all tokens in the list.
         """
@@ -181,7 +175,6 @@ class QueryNode:
         """
         return any(tl.end == end and tl.ttype in ttypes for tl in self.starting)
 
         """
         return any(tl.end == end and tl.ttype in ttypes for tl in self.starting)
 
-
     def get_tokens(self, end: int, ttype: TokenType) -> Optional[List[Token]]:
         """ Get the list of tokens of the given type starting at this node
             and ending at the node 'end'. Returns 'None' if no such
     def get_tokens(self, end: int, ttype: TokenType) -> Optional[List[Token]]:
         """ Get the list of tokens of the given type starting at this node
             and ending at the node 'end'. Returns 'None' if no such
@@ -220,13 +213,11 @@ class QueryStruct:
         self.nodes: List[QueryNode] = \
             [QueryNode(BreakType.START, source[0].ptype if source else PhraseType.NONE)]
 
         self.nodes: List[QueryNode] = \
             [QueryNode(BreakType.START, source[0].ptype if source else PhraseType.NONE)]
 
-
     def num_token_slots(self) -> int:
         """ Return the length of the query in vertice steps.
         """
         return len(self.nodes) - 1
 
     def num_token_slots(self) -> int:
         """ Return the length of the query in vertice steps.
         """
         return len(self.nodes) - 1
 
-
     def add_node(self, btype: BreakType, ptype: PhraseType) -> None:
         """ Append a new break node with the given break type.
             The phrase type denotes the type for any tokens starting
     def add_node(self, btype: BreakType, ptype: PhraseType) -> None:
         """ Append a new break node with the given break type.
             The phrase type denotes the type for any tokens starting
@@ -234,7 +225,6 @@ class QueryStruct:
         """
         self.nodes.append(QueryNode(btype, ptype))
 
         """
         self.nodes.append(QueryNode(btype, ptype))
 
-
     def add_token(self, trange: TokenRange, ttype: TokenType, token: Token) -> None:
         """ Add a token to the query. 'start' and 'end' are the indexes of the
             nodes from which to which the token spans. The indexes must exist
     def add_token(self, trange: TokenRange, ttype: TokenType, token: Token) -> None:
         """ Add a token to the query. 'start' and 'end' are the indexes of the
             nodes from which to which the token spans. The indexes must exist
@@ -247,7 +237,7 @@ class QueryStruct:
         """
         snode = self.nodes[trange.start]
         full_phrase = snode.btype in (BreakType.START, BreakType.PHRASE)\
         """
         snode = self.nodes[trange.start]
         full_phrase = snode.btype in (BreakType.START, BreakType.PHRASE)\
-                      and self.nodes[trange.end].btype in (BreakType.PHRASE, BreakType.END)
+            and self.nodes[trange.end].btype in (BreakType.PHRASE, BreakType.END)
         if snode.ptype.compatible_with(ttype, full_phrase):
             tlist = snode.get_tokens(trange.end, ttype)
             if tlist is None:
         if snode.ptype.compatible_with(ttype, full_phrase):
             tlist = snode.get_tokens(trange.end, ttype)
             if tlist is None:
@@ -255,7 +245,6 @@ class QueryStruct:
             else:
                 tlist.append(token)
 
             else:
                 tlist.append(token)
 
-
     def get_tokens(self, trange: TokenRange, ttype: TokenType) -> List[Token]:
         """ Get the list of tokens of a given type, spanning the given
             nodes. The nodes must exist. If no tokens exist, an
     def get_tokens(self, trange: TokenRange, ttype: TokenType) -> List[Token]:
         """ Get the list of tokens of a given type, spanning the given
             nodes. The nodes must exist. If no tokens exist, an
@@ -263,7 +252,6 @@ class QueryStruct:
         """
         return self.nodes[trange.start].get_tokens(trange.end, ttype) or []
 
         """
         return self.nodes[trange.start].get_tokens(trange.end, ttype) or []
 
-
     def get_partials_list(self, trange: TokenRange) -> List[Token]:
         """ Create a list of partial tokens between the given nodes.
             The list is composed of the first token of type PARTIAL
     def get_partials_list(self, trange: TokenRange) -> List[Token]:
         """ Create a list of partial tokens between the given nodes.
             The list is composed of the first token of type PARTIAL
@@ -271,8 +259,7 @@ class QueryStruct:
             assumed to exist.
         """
         return [next(iter(self.get_tokens(TokenRange(i, i+1), TokenType.PARTIAL)))
             assumed to exist.
         """
         return [next(iter(self.get_tokens(TokenRange(i, i+1), TokenType.PARTIAL)))
-                          for i in range(trange.start, trange.end)]
-
+                for i in range(trange.start, trange.end)]
 
     def iter_token_lists(self) -> Iterator[Tuple[int, QueryNode, TokenList]]:
         """ Iterator over all token lists in the query.
 
     def iter_token_lists(self) -> Iterator[Tuple[int, QueryNode, TokenList]]:
         """ Iterator over all token lists in the query.
@@ -281,7 +268,6 @@ class QueryStruct:
             for tlist in node.starting:
                 yield i, node, tlist
 
             for tlist in node.starting:
                 yield i, node, tlist
 
-
     def find_lookup_word_by_id(self, token: int) -> str:
         """ Find the first token with the given token ID and return
             its lookup word. Returns 'None' if no such token exists.
     def find_lookup_word_by_id(self, token: int) -> str:
         """ Find the first token with the given token ID and return
             its lookup word. Returns 'None' if no such token exists.
index 06443090ab52eef92368c8da48a7bc3b2f35dc38..ca25ccb5fe4eb9f6f1f4c8153dc4d6264f9490b3 100644 (file)
@@ -18,6 +18,7 @@ from ..connection import SearchConnection
 if TYPE_CHECKING:
     from .query import Phrase, QueryStruct
 
 if TYPE_CHECKING:
     from .query import Phrase, QueryStruct
 
+
 class AbstractQueryAnalyzer(ABC):
     """ Class for analysing incoming queries.
 
 class AbstractQueryAnalyzer(ABC):
     """ Class for analysing incoming queries.
 
@@ -29,7 +30,6 @@ class AbstractQueryAnalyzer(ABC):
         """ Analyze the given phrases and return the tokenized query.
         """
 
         """ Analyze the given phrases and return the tokenized query.
         """
 
-
     @abstractmethod
     def normalize_text(self, text: str) -> str:
         """ Bring the given text into a normalized form. That is the
     @abstractmethod
     def normalize_text(self, text: str) -> str:
         """ Bring the given text into a normalized form. That is the
@@ -38,7 +38,6 @@ class AbstractQueryAnalyzer(ABC):
         """
 
 
         """
 
 
-
 async def make_query_analyzer(conn: SearchConnection) -> AbstractQueryAnalyzer:
     """ Create a query analyzer for the tokenizer used by the database.
     """
 async def make_query_analyzer(conn: SearchConnection) -> AbstractQueryAnalyzer:
     """ Create a query analyzer for the tokenizer used by the database.
     """
index 5ac63d6f844e013cbfc94e50eae7e830cd68f262..a2e1804c732d737096d4e6416a858515c640b058 100644 (file)
@@ -14,7 +14,6 @@ import dataclasses
 from ..logging import log
 from . import query as qmod
 
 from ..logging import log
 from . import query as qmod
 
-# pylint: disable=too-many-return-statements,too-many-branches
 
 @dataclasses.dataclass
 class TypedRange:
 
 @dataclasses.dataclass
 class TypedRange:
@@ -35,8 +34,9 @@ PENALTY_TOKENCHANGE = {
 
 TypedRangeSeq = List[TypedRange]
 
 
 TypedRangeSeq = List[TypedRange]
 
+
 @dataclasses.dataclass
 @dataclasses.dataclass
-class TokenAssignment: # pylint: disable=too-many-instance-attributes
+class TokenAssignment:
     """ Representation of a possible assignment of token types
         to the tokens in a tokenized query.
     """
     """ Representation of a possible assignment of token types
         to the tokens in a tokenized query.
     """
@@ -49,7 +49,6 @@ class TokenAssignment: # pylint: disable=too-many-instance-attributes
     near_item: Optional[qmod.TokenRange] = None
     qualifier: Optional[qmod.TokenRange] = None
 
     near_item: Optional[qmod.TokenRange] = None
     qualifier: Optional[qmod.TokenRange] = None
 
-
     @staticmethod
     def from_ranges(ranges: TypedRangeSeq) -> 'TokenAssignment':
         """ Create a new token assignment from a sequence of typed spans.
     @staticmethod
     def from_ranges(ranges: TypedRangeSeq) -> 'TokenAssignment':
         """ Create a new token assignment from a sequence of typed spans.
@@ -83,34 +82,29 @@ class _TokenSequence:
         self.direction = direction
         self.penalty = penalty
 
         self.direction = direction
         self.penalty = penalty
 
-
     def __str__(self) -> str:
         seq = ''.join(f'[{r.trange.start} - {r.trange.end}: {r.ttype.name}]' for r in self.seq)
         return f'{seq} (dir: {self.direction}, penalty: {self.penalty})'
 
     def __str__(self) -> str:
         seq = ''.join(f'[{r.trange.start} - {r.trange.end}: {r.ttype.name}]' for r in self.seq)
         return f'{seq} (dir: {self.direction}, penalty: {self.penalty})'
 
-
     @property
     def end_pos(self) -> int:
         """ Return the index of the global end of the current sequence.
         """
         return self.seq[-1].trange.end if self.seq else 0
 
     @property
     def end_pos(self) -> int:
         """ Return the index of the global end of the current sequence.
         """
         return self.seq[-1].trange.end if self.seq else 0
 
-
     def has_types(self, *ttypes: qmod.TokenType) -> bool:
         """ Check if the current sequence contains any typed ranges of
             the given types.
         """
         return any(s.ttype in ttypes for s in self.seq)
 
     def has_types(self, *ttypes: qmod.TokenType) -> bool:
         """ Check if the current sequence contains any typed ranges of
             the given types.
         """
         return any(s.ttype in ttypes for s in self.seq)
 
-
     def is_final(self) -> bool:
         """ Return true when the sequence cannot be extended by any
             form of token anymore.
         """
         # Country and category must be the final term for left-to-right
         return len(self.seq) > 1 and \
     def is_final(self) -> bool:
         """ Return true when the sequence cannot be extended by any
             form of token anymore.
         """
         # Country and category must be the final term for left-to-right
         return len(self.seq) > 1 and \
-               self.seq[-1].ttype in (qmod.TokenType.COUNTRY, qmod.TokenType.NEAR_ITEM)
-
+            self.seq[-1].ttype in (qmod.TokenType.COUNTRY, qmod.TokenType.NEAR_ITEM)
 
     def appendable(self, ttype: qmod.TokenType) -> Optional[int]:
         """ Check if the give token type is appendable to the existing sequence.
 
     def appendable(self, ttype: qmod.TokenType) -> Optional[int]:
         """ Check if the give token type is appendable to the existing sequence.
@@ -149,10 +143,10 @@ class _TokenSequence:
                     return None
                 if len(self.seq) > 2 \
                    or self.has_types(qmod.TokenType.POSTCODE, qmod.TokenType.COUNTRY):
                     return None
                 if len(self.seq) > 2 \
                    or self.has_types(qmod.TokenType.POSTCODE, qmod.TokenType.COUNTRY):
-                    return None # direction left-to-right: housenumber must come before anything
-            elif self.direction == -1 \
-                 or self.has_types(qmod.TokenType.POSTCODE, qmod.TokenType.COUNTRY):
-                return -1 # force direction right-to-left if after other terms
+                    return None  # direction left-to-right: housenumber must come before anything
+            elif (self.direction == -1
+                  or self.has_types(qmod.TokenType.POSTCODE, qmod.TokenType.COUNTRY)):
+                return -1  # force direction right-to-left if after other terms
 
             return self.direction
 
 
             return self.direction
 
@@ -196,7 +190,6 @@ class _TokenSequence:
 
         return None
 
 
         return None
 
-
     def advance(self, ttype: qmod.TokenType, end_pos: int,
                 btype: qmod.BreakType) -> Optional['_TokenSequence']:
         """ Return a new token sequence state with the given token type
     def advance(self, ttype: qmod.TokenType, end_pos: int,
                 btype: qmod.BreakType) -> Optional['_TokenSequence']:
         """ Return a new token sequence state with the given token type
@@ -223,7 +216,6 @@ class _TokenSequence:
 
         return _TokenSequence(newseq, newdir, self.penalty + new_penalty)
 
 
         return _TokenSequence(newseq, newdir, self.penalty + new_penalty)
 
-
     def _adapt_penalty_from_priors(self, priors: int, new_dir: int) -> bool:
         if priors >= 2:
             if self.direction == 0:
     def _adapt_penalty_from_priors(self, priors: int, new_dir: int) -> bool:
         if priors >= 2:
             if self.direction == 0:
@@ -236,7 +228,6 @@ class _TokenSequence:
 
         return True
 
 
         return True
 
-
     def recheck_sequence(self) -> bool:
         """ Check that the sequence is a fully valid token assignment
             and adapt direction and penalties further if necessary.
     def recheck_sequence(self) -> bool:
         """ Check that the sequence is a fully valid token assignment
             and adapt direction and penalties further if necessary.
@@ -264,9 +255,8 @@ class _TokenSequence:
 
         return True
 
 
         return True
 
-
     def _get_assignments_postcode(self, base: TokenAssignment,
     def _get_assignments_postcode(self, base: TokenAssignment,
-                                  query_len: int)  -> Iterator[TokenAssignment]:
+                                  query_len: int) -> Iterator[TokenAssignment]:
         """ Yield possible assignments of Postcode searches with an
             address component.
         """
         """ Yield possible assignments of Postcode searches with an
             address component.
         """
@@ -278,13 +268,12 @@ class _TokenSequence:
             # <address>,<postcode> should give preference to address search
             if base.postcode.start == 0:
                 penalty = self.penalty
             # <address>,<postcode> should give preference to address search
             if base.postcode.start == 0:
                 penalty = self.penalty
-                self.direction = -1 # name searches are only possible backwards
+                self.direction = -1  # name searches are only possible backwards
             else:
                 penalty = self.penalty + 0.1
             else:
                 penalty = self.penalty + 0.1
-                self.direction = 1 # name searches are only possible forwards
+                self.direction = 1  # name searches are only possible forwards
             yield dataclasses.replace(base, penalty=penalty)
 
             yield dataclasses.replace(base, penalty=penalty)
 
-
     def _get_assignments_address_forward(self, base: TokenAssignment,
                                          query: qmod.QueryStruct) -> Iterator[TokenAssignment]:
         """ Yield possible assignments of address searches with
     def _get_assignments_address_forward(self, base: TokenAssignment,
                                          query: qmod.QueryStruct) -> Iterator[TokenAssignment]:
         """ Yield possible assignments of address searches with
@@ -320,7 +309,6 @@ class _TokenSequence:
             yield dataclasses.replace(base, name=name, address=[addr] + base.address[1:],
                                       penalty=penalty + PENALTY_TOKENCHANGE[query.nodes[i].btype])
 
             yield dataclasses.replace(base, name=name, address=[addr] + base.address[1:],
                                       penalty=penalty + PENALTY_TOKENCHANGE[query.nodes[i].btype])
 
-
     def _get_assignments_address_backward(self, base: TokenAssignment,
                                           query: qmod.QueryStruct) -> Iterator[TokenAssignment]:
         """ Yield possible assignments of address searches with
     def _get_assignments_address_backward(self, base: TokenAssignment,
                                           query: qmod.QueryStruct) -> Iterator[TokenAssignment]:
         """ Yield possible assignments of address searches with
@@ -355,7 +343,6 @@ class _TokenSequence:
             yield dataclasses.replace(base, name=name, address=base.address[:-1] + [addr],
                                       penalty=penalty + PENALTY_TOKENCHANGE[query.nodes[i].btype])
 
             yield dataclasses.replace(base, name=name, address=base.address[:-1] + [addr],
                                       penalty=penalty + PENALTY_TOKENCHANGE[query.nodes[i].btype])
 
-
     def get_assignments(self, query: qmod.QueryStruct) -> Iterator[TokenAssignment]:
         """ Yield possible assignments for the current sequence.
 
     def get_assignments(self, query: qmod.QueryStruct) -> Iterator[TokenAssignment]:
         """ Yield possible assignments for the current sequence.
 
index 49fe288f5137245b0fd5626903c7eb3bac573335..77c50f31b9b59ecc142e788964875de9c5fc87c9 100644 (file)
@@ -16,13 +16,13 @@ from ..core import NominatimAPIAsync
 from ..result_formatting import FormatDispatcher
 from .content_types import CONTENT_TEXT
 
 from ..result_formatting import FormatDispatcher
 from .content_types import CONTENT_TEXT
 
+
 class ASGIAdaptor(abc.ABC):
     """ Adapter class for the different ASGI frameworks.
         Wraps functionality over concrete requests and responses.
     """
     content_type: str = CONTENT_TEXT
 
 class ASGIAdaptor(abc.ABC):
     """ Adapter class for the different ASGI frameworks.
         Wraps functionality over concrete requests and responses.
     """
     content_type: str = CONTENT_TEXT
 
-
     @abc.abstractmethod
     def get(self, name: str, default: Optional[str] = None) -> Optional[str]:
         """ Return an input parameter as a string. If the parameter was
     @abc.abstractmethod
     def get(self, name: str, default: Optional[str] = None) -> Optional[str]:
         """ Return an input parameter as a string. If the parameter was
@@ -35,14 +35,12 @@ class ASGIAdaptor(abc.ABC):
             not provided, return the 'default' value.
         """
 
             not provided, return the 'default' value.
         """
 
-
     @abc.abstractmethod
     def error(self, msg: str, status: int = 400) -> Exception:
         """ Construct an appropriate exception from the given error message.
             The exception must result in a HTTP error with the given status.
         """
 
     @abc.abstractmethod
     def error(self, msg: str, status: int = 400) -> Exception:
         """ Construct an appropriate exception from the given error message.
             The exception must result in a HTTP error with the given status.
         """
 
-
     @abc.abstractmethod
     def create_response(self, status: int, output: str, num_results: int) -> Any:
         """ Create a response from the given parameters. The result will
     @abc.abstractmethod
     def create_response(self, status: int, output: str, num_results: int) -> Any:
         """ Create a response from the given parameters. The result will
@@ -55,25 +53,21 @@ class ASGIAdaptor(abc.ABC):
             body of the response to 'output'.
         """
 
             body of the response to 'output'.
         """
 
-
     @abc.abstractmethod
     def base_uri(self) -> str:
         """ Return the URI of the original request.
         """
 
     @abc.abstractmethod
     def base_uri(self) -> str:
         """ Return the URI of the original request.
         """
 
-
     @abc.abstractmethod
     def config(self) -> Configuration:
         """ Return the current configuration object.
         """
 
     @abc.abstractmethod
     def config(self) -> Configuration:
         """ Return the current configuration object.
         """
 
-
     @abc.abstractmethod
     def formatting(self) -> FormatDispatcher:
         """ Return the formatting object to use.
         """
 
     @abc.abstractmethod
     def formatting(self) -> FormatDispatcher:
         """ Return the formatting object to use.
         """
 
-
     def get_int(self, name: str, default: Optional[int] = None) -> int:
         """ Return an input parameter as an int. Raises an exception if
             the parameter is given but not in an integer format.
     def get_int(self, name: str, default: Optional[int] = None) -> int:
         """ Return an input parameter as an int. Raises an exception if
             the parameter is given but not in an integer format.
@@ -97,7 +91,6 @@ class ASGIAdaptor(abc.ABC):
 
         return intval
 
 
         return intval
 
-
     def get_float(self, name: str, default: Optional[float] = None) -> float:
         """ Return an input parameter as a flaoting-point number. Raises an
             exception if the parameter is given but not in an float format.
     def get_float(self, name: str, default: Optional[float] = None) -> float:
         """ Return an input parameter as a flaoting-point number. Raises an
             exception if the parameter is given but not in an float format.
@@ -124,7 +117,6 @@ class ASGIAdaptor(abc.ABC):
 
         return fval
 
 
         return fval
 
-
     def get_bool(self, name: str, default: Optional[bool] = None) -> bool:
         """ Return an input parameter as bool. Only '0' is accepted as
             an input for 'false' all other inputs will be interpreted as 'true'.
     def get_bool(self, name: str, default: Optional[bool] = None) -> bool:
         """ Return an input parameter as bool. Only '0' is accepted as
             an input for 'false' all other inputs will be interpreted as 'true'.
@@ -143,7 +135,6 @@ class ASGIAdaptor(abc.ABC):
 
         return value != '0'
 
 
         return value != '0'
 
-
     def raise_error(self, msg: str, status: int = 400) -> NoReturn:
         """ Raise an exception resulting in the given HTTP status and
             message. The message will be formatted according to the
     def raise_error(self, msg: str, status: int = 400) -> NoReturn:
         """ Raise an exception resulting in the given HTTP status and
             message. The message will be formatted according to the
index 558ff94338dba0c5f43d9deae9afa4ef57cbbb34..b58c1cfa830c5a863a8fc46445f3c62b02bdea06 100644 (file)
@@ -21,6 +21,7 @@ from ...result_formatting import FormatDispatcher, load_format_dispatcher
 from ... import logging as loglib
 from ..asgi_adaptor import ASGIAdaptor, EndpointFunc
 
 from ... import logging as loglib
 from ..asgi_adaptor import ASGIAdaptor, EndpointFunc
 
+
 class HTTPNominatimError(Exception):
     """ A special exception class for errors raised during processing.
     """
 class HTTPNominatimError(Exception):
     """ A special exception class for errors raised during processing.
     """
@@ -30,7 +31,7 @@ class HTTPNominatimError(Exception):
         self.content_type = content_type
 
 
         self.content_type = content_type
 
 
-async def nominatim_error_handler(req: Request, resp: Response, #pylint: disable=unused-argument
+async def nominatim_error_handler(req: Request, resp: Response,
                                   exception: HTTPNominatimError,
                                   _: Any) -> None:
     """ Special error handler that passes message and content type as
                                   exception: HTTPNominatimError,
                                   _: Any) -> None:
     """ Special error handler that passes message and content type as
@@ -41,8 +42,8 @@ async def nominatim_error_handler(req: Request, resp: Response, #pylint: disable
     resp.content_type = exception.content_type
 
 
     resp.content_type = exception.content_type
 
 
-async def timeout_error_handler(req: Request, resp: Response, #pylint: disable=unused-argument
-                                exception: TimeoutError, #pylint: disable=unused-argument
+async def timeout_error_handler(req: Request, resp: Response,
+                                exception: TimeoutError,
                                 _: Any) -> None:
     """ Special error handler that passes message and content type as
         per exception info.
                                 _: Any) -> None:
     """ Special error handler that passes message and content type as
         per exception info.
@@ -70,26 +71,21 @@ class ParamWrapper(ASGIAdaptor):
         self._config = config
         self._formatter = formatter
 
         self._config = config
         self._formatter = formatter
 
-
     def get(self, name: str, default: Optional[str] = None) -> Optional[str]:
         return self.request.get_param(name, default=default)
 
     def get(self, name: str, default: Optional[str] = None) -> Optional[str]:
         return self.request.get_param(name, default=default)
 
-
     def get_header(self, name: str, default: Optional[str] = None) -> Optional[str]:
         return self.request.get_header(name, default=default)
 
     def get_header(self, name: str, default: Optional[str] = None) -> Optional[str]:
         return self.request.get_header(name, default=default)
 
-
     def error(self, msg: str, status: int = 400) -> HTTPNominatimError:
         return HTTPNominatimError(msg, status, self.content_type)
 
     def error(self, msg: str, status: int = 400) -> HTTPNominatimError:
         return HTTPNominatimError(msg, status, self.content_type)
 
-
     def create_response(self, status: int, output: str, num_results: int) -> None:
         self.response.context.num_results = num_results
         self.response.status = status
         self.response.text = output
         self.response.content_type = self.content_type
 
     def create_response(self, status: int, output: str, num_results: int) -> None:
         self.response.context.num_results = num_results
         self.response.status = status
         self.response.text = output
         self.response.content_type = self.content_type
 
-
     def base_uri(self) -> str:
         return self.request.forwarded_prefix
 
     def base_uri(self) -> str:
         return self.request.forwarded_prefix
 
@@ -111,7 +107,6 @@ class EndpointWrapper:
         self.api = api
         self.formatter = formatter
 
         self.api = api
         self.formatter = formatter
 
-
     async def on_get(self, req: Request, resp: Response) -> None:
         """ Implementation of the endpoint.
         """
     async def on_get(self, req: Request, resp: Response) -> None:
         """ Implementation of the endpoint.
         """
@@ -124,15 +119,13 @@ class FileLoggingMiddleware:
     """
 
     def __init__(self, file_name: str):
     """
 
     def __init__(self, file_name: str):
-        self.fd = open(file_name, 'a', buffering=1, encoding='utf8') # pylint: disable=R1732
-
+        self.fd = open(file_name, 'a', buffering=1, encoding='utf8')
 
     async def process_request(self, req: Request, _: Response) -> None:
         """ Callback before the request starts timing.
         """
         req.context.start = dt.datetime.now(tz=dt.timezone.utc)
 
 
     async def process_request(self, req: Request, _: Response) -> None:
         """ Callback before the request starts timing.
         """
         req.context.start = dt.datetime.now(tz=dt.timezone.utc)
 
-
     async def process_response(self, req: Request, resp: Response,
                                resource: Optional[EndpointWrapper],
                                req_succeeded: bool) -> None:
     async def process_response(self, req: Request, resp: Response,
                                resource: Optional[EndpointWrapper],
                                req_succeeded: bool) -> None:
@@ -140,7 +133,7 @@ class FileLoggingMiddleware:
             writes logs for successful requests for search, reverse and lookup.
         """
         if not req_succeeded or resource is None or resp.status != 200\
             writes logs for successful requests for search, reverse and lookup.
         """
         if not req_succeeded or resource is None or resp.status != 200\
-            or resource.name not in ('reverse', 'search', 'lookup', 'details'):
+           or resource.name not in ('reverse', 'search', 'lookup', 'details'):
             return
 
         finish = dt.datetime.now(tz=dt.timezone.utc)
             return
 
         finish = dt.datetime.now(tz=dt.timezone.utc)
@@ -183,7 +176,7 @@ def get_application(project_dir: Path,
     app.add_error_handler(HTTPNominatimError, nominatim_error_handler)
     app.add_error_handler(TimeoutError, timeout_error_handler)
     # different from TimeoutError in Python <= 3.10
     app.add_error_handler(HTTPNominatimError, nominatim_error_handler)
     app.add_error_handler(TimeoutError, timeout_error_handler)
     # different from TimeoutError in Python <= 3.10
-    app.add_error_handler(asyncio.TimeoutError, timeout_error_handler) # type: ignore[arg-type]
+    app.add_error_handler(asyncio.TimeoutError, timeout_error_handler)  # type: ignore[arg-type]
 
     legacy_urls = api.config.get_bool('SERVE_LEGACY_URLS')
     formatter = load_format_dispatcher('v1', project_dir)
 
     legacy_urls = api.config.get_bool('SERVE_LEGACY_URLS')
     formatter = load_format_dispatcher('v1', project_dir)
index 3bfabc10dd285c611ea5bcd4a95232aa72e8557a..48f0207ac7b2f21e07a16ca83ad627d984b74200 100644 (file)
@@ -28,6 +28,7 @@ from ...result_formatting import FormatDispatcher, load_format_dispatcher
 from ..asgi_adaptor import ASGIAdaptor, EndpointFunc
 from ... import logging as loglib
 
 from ..asgi_adaptor import ASGIAdaptor, EndpointFunc
 from ... import logging as loglib
 
+
 class ParamWrapper(ASGIAdaptor):
     """ Adaptor class for server glue to Starlette framework.
     """
 class ParamWrapper(ASGIAdaptor):
     """ Adaptor class for server glue to Starlette framework.
     """
@@ -35,25 +36,20 @@ class ParamWrapper(ASGIAdaptor):
     def __init__(self, request: Request) -> None:
         self.request = request
 
     def __init__(self, request: Request) -> None:
         self.request = request
 
-
     def get(self, name: str, default: Optional[str] = None) -> Optional[str]:
         return self.request.query_params.get(name, default=default)
 
     def get(self, name: str, default: Optional[str] = None) -> Optional[str]:
         return self.request.query_params.get(name, default=default)
 
-
     def get_header(self, name: str, default: Optional[str] = None) -> Optional[str]:
         return self.request.headers.get(name, default)
 
     def get_header(self, name: str, default: Optional[str] = None) -> Optional[str]:
         return self.request.headers.get(name, default)
 
-
     def error(self, msg: str, status: int = 400) -> HTTPException:
         return HTTPException(status, detail=msg,
                              headers={'content-type': self.content_type})
 
     def error(self, msg: str, status: int = 400) -> HTTPException:
         return HTTPException(status, detail=msg,
                              headers={'content-type': self.content_type})
 
-
     def create_response(self, status: int, output: str, num_results: int) -> Response:
         self.request.state.num_results = num_results
         return Response(output, status_code=status, media_type=self.content_type)
 
     def create_response(self, status: int, output: str, num_results: int) -> Response:
         self.request.state.num_results = num_results
         return Response(output, status_code=status, media_type=self.content_type)
 
-
     def base_uri(self) -> str:
         scheme = self.request.url.scheme
         host = self.request.url.hostname
     def base_uri(self) -> str:
         scheme = self.request.url.scheme
         host = self.request.url.hostname
@@ -66,11 +62,9 @@ class ParamWrapper(ASGIAdaptor):
 
         return f"{scheme}://{host}{root}"
 
 
         return f"{scheme}://{host}{root}"
 
-
     def config(self) -> Configuration:
         return cast(Configuration, self.request.app.state.API.config)
 
     def config(self) -> Configuration:
         return cast(Configuration, self.request.app.state.API.config)
 
-
     def formatting(self) -> FormatDispatcher:
         return cast(FormatDispatcher, self.request.app.state.API.formatter)
 
     def formatting(self) -> FormatDispatcher:
         return cast(FormatDispatcher, self.request.app.state.API.formatter)
 
@@ -89,7 +83,7 @@ class FileLoggingMiddleware(BaseHTTPMiddleware):
 
     def __init__(self, app: Starlette, file_name: str = ''):
         super().__init__(app)
 
     def __init__(self, app: Starlette, file_name: str = ''):
         super().__init__(app)
-        self.fd = open(file_name, 'a', buffering=1, encoding='utf8') # pylint: disable=R1732
+        self.fd = open(file_name, 'a', buffering=1, encoding='utf8')
 
     async def dispatch(self, request: Request,
                        call_next: RequestResponseEndpoint) -> Response:
 
     async def dispatch(self, request: Request,
                        call_next: RequestResponseEndpoint) -> Response:
@@ -118,7 +112,7 @@ class FileLoggingMiddleware(BaseHTTPMiddleware):
         return response
 
 
         return response
 
 
-async def timeout_error(request: Request, #pylint: disable=unused-argument
+async def timeout_error(request: Request,
                         _: Exception) -> Response:
     """ Error handler for query timeouts.
     """
                         _: Exception) -> Response:
     """ Error handler for query timeouts.
     """
index f8e29749984d2bc4844fc736d595cc75ebe03a35..973163d5621f32153c6721c23125cf48a31d8b64 100644 (file)
@@ -7,10 +7,10 @@
 """
 Import the base library to use with asynchronous SQLAlchemy.
 """
 """
 Import the base library to use with asynchronous SQLAlchemy.
 """
-# pylint: disable=invalid-name, ungrouped-imports, unused-import
-
 from typing import Any
 
 from typing import Any
 
+# flake8: noqa
+
 try:
     import sqlalchemy.dialects.postgresql.psycopg
     import psycopg
 try:
     import sqlalchemy.dialects.postgresql.psycopg
     import psycopg
index 094c33dc2995be898f98669b252474276c3a2bd9..81fc83d6c4ddd875b2616a44cb88480796cf244f 100644 (file)
@@ -15,7 +15,6 @@ from sqlalchemy.ext.compiler import compiles
 
 from ..typing import SaColumn
 
 
 from ..typing import SaColumn
 
-# pylint: disable=all
 
 class PlacexGeometryReverseLookuppolygon(sa.sql.functions.GenericFunction[Any]):
     """ Check for conditions that allow partial index use on
 
 class PlacexGeometryReverseLookuppolygon(sa.sql.functions.GenericFunction[Any]):
     """ Check for conditions that allow partial index use on
@@ -69,8 +68,8 @@ def default_reverse_place_diameter(element: IntersectsReverseDistance,
            f" AND {table}.name is not null"\
            f" AND {table}.linked_place_id is null"\
            f" AND {table}.osm_type = 'N'" + \
            f" AND {table}.name is not null"\
            f" AND {table}.linked_place_id is null"\
            f" AND {table}.osm_type = 'N'" + \
-           " AND ST_Buffer(%s, reverse_place_diameter(%s)) && %s)" \
-               tuple(map(lambda c: compiler.process(c, **kw), element.clauses))
+           " AND ST_Buffer(%s, reverse_place_diameter(%s)) && %s)" \
+        % tuple(map(lambda c: compiler.process(c, **kw), element.clauses))
 
 
 @compiles(IntersectsReverseDistance, 'sqlite')
 
 
 @compiles(IntersectsReverseDistance, 'sqlite')
@@ -79,17 +78,17 @@ def sqlite_reverse_place_diameter(element: IntersectsReverseDistance,
     geom1, rank, geom2 = list(element.clauses)
     table = element.tablename
 
     geom1, rank, geom2 = list(element.clauses)
     table = element.tablename
 
-    return (f"({table}.rank_address between 4 and 25"\
-            f" AND {table}.type != 'postcode'"\
-            f" AND {table}.name is not null"\
-            f" AND {table}.linked_place_id is null"\
-            f" AND {table}.osm_type = 'N'"\
-             " AND MbrIntersects(%s, ST_Expand(%s, 14.0 * exp(-0.2 * %s) - 0.03))"\
-            f" AND {table}.place_id IN"\
-             " (SELECT place_id FROM placex_place_node_areas"\
-             "  WHERE ROWID IN (SELECT ROWID FROM SpatialIndex"\
-             "  WHERE f_table_name = 'placex_place_node_areas'"\
-             "  AND search_frame = %s)))") % (
+    return (f"({table}.rank_address between 4 and 25"
+            f" AND {table}.type != 'postcode'"
+            f" AND {table}.name is not null"
+            f" AND {table}.linked_place_id is null"
+            f" AND {table}.osm_type = 'N'"
+            "  AND MbrIntersects(%s, ST_Expand(%s, 14.0 * exp(-0.2 * %s) - 0.03))"
+            f" AND {table}.place_id IN"
+            "  (SELECT place_id FROM placex_place_node_areas"
+            "   WHERE ROWID IN (SELECT ROWID FROM SpatialIndex"
+            "   WHERE f_table_name = 'placex_place_node_areas'"
+              AND search_frame = %s)))") % (
                 compiler.process(geom1, **kw),
                 compiler.process(geom2, **kw),
                 compiler.process(rank, **kw),
                 compiler.process(geom1, **kw),
                 compiler.process(geom2, **kw),
                 compiler.process(rank, **kw),
@@ -153,6 +152,7 @@ class CrosscheckNames(sa.sql.functions.GenericFunction[Any]):
     name = 'CrosscheckNames'
     inherit_cache = True
 
     name = 'CrosscheckNames'
     inherit_cache = True
 
+
 @compiles(CrosscheckNames)
 def compile_crosscheck_names(element: CrosscheckNames,
                              compiler: 'sa.Compiled', **kw: Any) -> str:
 @compiles(CrosscheckNames)
 def compile_crosscheck_names(element: CrosscheckNames,
                              compiler: 'sa.Compiled', **kw: Any) -> str:
@@ -188,7 +188,6 @@ def sqlite_json_array_each(element: JsonArrayEach, compiler: 'sa.Compiled', **kw
     return "json_each(%s)" % compiler.process(element.clauses, **kw)
 
 
     return "json_each(%s)" % compiler.process(element.clauses, **kw)
 
 
-
 class Greatest(sa.sql.functions.GenericFunction[Any]):
     """ Function to compute maximum of all its input parameters.
     """
 class Greatest(sa.sql.functions.GenericFunction[Any]):
     """ Function to compute maximum of all its input parameters.
     """
@@ -201,7 +200,6 @@ def sqlite_greatest(element: Greatest, compiler: 'sa.Compiled', **kw: Any) -> st
     return "max(%s)" % compiler.process(element.clauses, **kw)
 
 
     return "max(%s)" % compiler.process(element.clauses, **kw)
 
 
-
 class RegexpWord(sa.sql.functions.GenericFunction[Any]):
     """ Check if a full word is in a given string.
     """
 class RegexpWord(sa.sql.functions.GenericFunction[Any]):
     """ Check if a full word is in a given string.
     """
@@ -212,10 +210,12 @@ class RegexpWord(sa.sql.functions.GenericFunction[Any]):
 @compiles(RegexpWord, 'postgresql')
 def postgres_regexp_nocase(element: RegexpWord, compiler: 'sa.Compiled', **kw: Any) -> str:
     arg1, arg2 = list(element.clauses)
 @compiles(RegexpWord, 'postgresql')
 def postgres_regexp_nocase(element: RegexpWord, compiler: 'sa.Compiled', **kw: Any) -> str:
     arg1, arg2 = list(element.clauses)
-    return "%s ~* ('\\m(' || %s  || ')\\M')::text" % (compiler.process(arg2, **kw), compiler.process(arg1, **kw))
+    return "%s ~* ('\\m(' || %s  || ')\\M')::text" \
+        % (compiler.process(arg2, **kw), compiler.process(arg1, **kw))
 
 
 @compiles(RegexpWord, 'sqlite')
 def sqlite_regexp_nocase(element: RegexpWord, compiler: 'sa.Compiled', **kw: Any) -> str:
     arg1, arg2 = list(element.clauses)
 
 
 @compiles(RegexpWord, 'sqlite')
 def sqlite_regexp_nocase(element: RegexpWord, compiler: 'sa.Compiled', **kw: Any) -> str:
     arg1, arg2 = list(element.clauses)
-    return "regexp('\\b(' || %s  || ')\\b', %s)" % (compiler.process(arg1, **kw), compiler.process(arg2, **kw))
+    return "regexp('\\b(' || %s  || ')\\b', %s)"\
+        % (compiler.process(arg1, **kw), compiler.process(arg2, **kw))
index 0dfb63e7b83ad4ce09f371aa00a1aaede883d688..a8989c4c8495fa93ffcb753aa82b76fc8d711034 100644 (file)
@@ -11,7 +11,7 @@ import sqlalchemy as sa
 
 from .sqlalchemy_types import Geometry, KeyValueStore, IntArray
 
 
 from .sqlalchemy_types import Geometry, KeyValueStore, IntArray
 
-#pylint: disable=too-many-instance-attributes
+
 class SearchTables:
     """ Data class that holds the tables of the Nominatim database.
 
 class SearchTables:
     """ Data class that holds the tables of the Nominatim database.
 
@@ -22,16 +22,19 @@ class SearchTables:
     def __init__(self, meta: sa.MetaData) -> None:
         self.meta = meta
 
     def __init__(self, meta: sa.MetaData) -> None:
         self.meta = meta
 
-        self.import_status = sa.Table('import_status', meta,
+        self.import_status = sa.Table(
+            'import_status', meta,
             sa.Column('lastimportdate', sa.DateTime(True), nullable=False),
             sa.Column('sequence_id', sa.Integer),
             sa.Column('indexed', sa.Boolean))
 
             sa.Column('lastimportdate', sa.DateTime(True), nullable=False),
             sa.Column('sequence_id', sa.Integer),
             sa.Column('indexed', sa.Boolean))
 
-        self.properties = sa.Table('nominatim_properties', meta,
+        self.properties = sa.Table(
+            'nominatim_properties', meta,
             sa.Column('property', sa.Text, nullable=False),
             sa.Column('value', sa.Text))
 
             sa.Column('property', sa.Text, nullable=False),
             sa.Column('value', sa.Text))
 
-        self.placex = sa.Table('placex', meta,
+        self.placex = sa.Table(
+            'placex', meta,
             sa.Column('place_id', sa.BigInteger, nullable=False),
             sa.Column('parent_place_id', sa.BigInteger),
             sa.Column('linked_place_id', sa.BigInteger),
             sa.Column('place_id', sa.BigInteger, nullable=False),
             sa.Column('parent_place_id', sa.BigInteger),
             sa.Column('linked_place_id', sa.BigInteger),
@@ -55,14 +58,16 @@ class SearchTables:
             sa.Column('postcode', sa.Text),
             sa.Column('centroid', Geometry))
 
             sa.Column('postcode', sa.Text),
             sa.Column('centroid', Geometry))
 
-        self.addressline = sa.Table('place_addressline', meta,
+        self.addressline = sa.Table(
+            'place_addressline', meta,
             sa.Column('place_id', sa.BigInteger),
             sa.Column('address_place_id', sa.BigInteger),
             sa.Column('distance', sa.Float),
             sa.Column('fromarea', sa.Boolean),
             sa.Column('isaddress', sa.Boolean))
 
             sa.Column('place_id', sa.BigInteger),
             sa.Column('address_place_id', sa.BigInteger),
             sa.Column('distance', sa.Float),
             sa.Column('fromarea', sa.Boolean),
             sa.Column('isaddress', sa.Boolean))
 
-        self.postcode = sa.Table('location_postcode', meta,
+        self.postcode = sa.Table(
+            'location_postcode', meta,
             sa.Column('place_id', sa.BigInteger),
             sa.Column('parent_place_id', sa.BigInteger),
             sa.Column('rank_search', sa.SmallInteger),
             sa.Column('place_id', sa.BigInteger),
             sa.Column('parent_place_id', sa.BigInteger),
             sa.Column('rank_search', sa.SmallInteger),
@@ -73,7 +78,8 @@ class SearchTables:
             sa.Column('postcode', sa.Text),
             sa.Column('geometry', Geometry))
 
             sa.Column('postcode', sa.Text),
             sa.Column('geometry', Geometry))
 
-        self.osmline = sa.Table('location_property_osmline', meta,
+        self.osmline = sa.Table(
+            'location_property_osmline', meta,
             sa.Column('place_id', sa.BigInteger, nullable=False),
             sa.Column('osm_id', sa.BigInteger),
             sa.Column('parent_place_id', sa.BigInteger),
             sa.Column('place_id', sa.BigInteger, nullable=False),
             sa.Column('osm_id', sa.BigInteger),
             sa.Column('parent_place_id', sa.BigInteger),
@@ -87,19 +93,22 @@ class SearchTables:
             sa.Column('postcode', sa.Text),
             sa.Column('country_code', sa.String(2)))
 
             sa.Column('postcode', sa.Text),
             sa.Column('country_code', sa.String(2)))
 
-        self.country_name = sa.Table('country_name', meta,
+        self.country_name = sa.Table(
+            'country_name', meta,
             sa.Column('country_code', sa.String(2)),
             sa.Column('name', KeyValueStore),
             sa.Column('derived_name', KeyValueStore),
             sa.Column('partition', sa.Integer))
 
             sa.Column('country_code', sa.String(2)),
             sa.Column('name', KeyValueStore),
             sa.Column('derived_name', KeyValueStore),
             sa.Column('partition', sa.Integer))
 
-        self.country_grid = sa.Table('country_osm_grid', meta,
+        self.country_grid = sa.Table(
+            'country_osm_grid', meta,
             sa.Column('country_code', sa.String(2)),
             sa.Column('area', sa.Float),
             sa.Column('geometry', Geometry))
 
         # The following tables are not necessarily present.
             sa.Column('country_code', sa.String(2)),
             sa.Column('area', sa.Float),
             sa.Column('geometry', Geometry))
 
         # The following tables are not necessarily present.
-        self.search_name = sa.Table('search_name', meta,
+        self.search_name = sa.Table(
+            'search_name', meta,
             sa.Column('place_id', sa.BigInteger),
             sa.Column('importance', sa.Float),
             sa.Column('search_rank', sa.SmallInteger),
             sa.Column('place_id', sa.BigInteger),
             sa.Column('importance', sa.Float),
             sa.Column('search_rank', sa.SmallInteger),
@@ -109,7 +118,8 @@ class SearchTables:
             sa.Column('country_code', sa.String(2)),
             sa.Column('centroid', Geometry))
 
             sa.Column('country_code', sa.String(2)),
             sa.Column('centroid', Geometry))
 
-        self.tiger = sa.Table('location_property_tiger', meta,
+        self.tiger = sa.Table(
+            'location_property_tiger', meta,
             sa.Column('place_id', sa.BigInteger),
             sa.Column('parent_place_id', sa.BigInteger),
             sa.Column('startnumber', sa.Integer),
             sa.Column('place_id', sa.BigInteger),
             sa.Column('parent_place_id', sa.BigInteger),
             sa.Column('startnumber', sa.Integer),
index 15b79a231ac8ff83d59a1bbf87ef0c90892c7354..90adcce850ec6c7d82c1b41c8a32065e7a3b49e7 100644 (file)
@@ -9,7 +9,6 @@ Custom types for SQLAlchemy.
 """
 from __future__ import annotations
 from typing import Callable, Any, cast
 """
 from __future__ import annotations
 from typing import Callable, Any, cast
-import sys
 
 import sqlalchemy as sa
 from sqlalchemy.ext.compiler import compiles
 
 import sqlalchemy as sa
 from sqlalchemy.ext.compiler import compiles
@@ -17,7 +16,6 @@ from sqlalchemy import types
 
 from ...typing import SaColumn, SaBind
 
 
 from ...typing import SaColumn, SaBind
 
-#pylint: disable=all
 
 class Geometry_DistanceSpheroid(sa.sql.expression.FunctionElement[float]):
     """ Function to compute the spherical distance in meters.
 
 class Geometry_DistanceSpheroid(sa.sql.expression.FunctionElement[float]):
     """ Function to compute the spherical distance in meters.
@@ -126,12 +124,12 @@ def spatialite_intersects_column(element: Geometry_ColumnIntersectsBbox,
     arg1, arg2 = list(element.clauses)
     return "MbrIntersects(%s, %s) = 1 and "\
            "%s.ROWID IN (SELECT ROWID FROM SpatialIndex "\
     arg1, arg2 = list(element.clauses)
     return "MbrIntersects(%s, %s) = 1 and "\
            "%s.ROWID IN (SELECT ROWID FROM SpatialIndex "\
-                        "WHERE f_table_name = '%s' AND f_geometry_column = '%s' "\
-                        "AND search_frame = %s)" %(
-              compiler.process(arg1, **kw),
-              compiler.process(arg2, **kw),
-              arg1.table.name, arg1.table.name, arg1.name,
-              compiler.process(arg2, **kw))
+           "             WHERE f_table_name = '%s' AND f_geometry_column = '%s' "\
+           "             AND search_frame = %s)"\
+        % (compiler.process(arg1, **kw),
+           compiler.process(arg2, **kw),
+           arg1.table.name, arg1.table.name, arg1.name,
+           compiler.process(arg2, **kw))
 
 
 class Geometry_ColumnDWithin(sa.sql.expression.FunctionElement[Any]):
 
 
 class Geometry_ColumnDWithin(sa.sql.expression.FunctionElement[Any]):
@@ -149,23 +147,24 @@ def default_dwithin_column(element: Geometry_ColumnDWithin,
                            compiler: 'sa.Compiled', **kw: Any) -> str:
     return "ST_DWithin(%s)" % compiler.process(element.clauses, **kw)
 
                            compiler: 'sa.Compiled', **kw: Any) -> str:
     return "ST_DWithin(%s)" % compiler.process(element.clauses, **kw)
 
+
 @compiles(Geometry_ColumnDWithin, 'sqlite')
 def spatialite_dwithin_column(element: Geometry_ColumnDWithin,
                               compiler: 'sa.Compiled', **kw: Any) -> str:
     geom1, geom2, dist = list(element.clauses)
     return "ST_Distance(%s, %s) < %s and "\
            "%s.ROWID IN (SELECT ROWID FROM SpatialIndex "\
 @compiles(Geometry_ColumnDWithin, 'sqlite')
 def spatialite_dwithin_column(element: Geometry_ColumnDWithin,
                               compiler: 'sa.Compiled', **kw: Any) -> str:
     geom1, geom2, dist = list(element.clauses)
     return "ST_Distance(%s, %s) < %s and "\
            "%s.ROWID IN (SELECT ROWID FROM SpatialIndex "\
-                        "WHERE f_table_name = '%s' AND f_geometry_column = '%s' "\
-                        "AND search_frame = ST_Expand(%s, %s))" %(
-              compiler.process(geom1, **kw),
-              compiler.process(geom2, **kw),
-              compiler.process(dist, **kw),
-              geom1.table.name, geom1.table.name, geom1.name,
-              compiler.process(geom2, **kw),
-              compiler.process(dist, **kw))
+           "             WHERE f_table_name = '%s' AND f_geometry_column = '%s' "\
+           "             AND search_frame = ST_Expand(%s, %s))"\
+        % (compiler.process(geom1, **kw),
+           compiler.process(geom2, **kw),
+           compiler.process(dist, **kw),
+           geom1.table.name, geom1.table.name, geom1.name,
+           compiler.process(geom2, **kw),
+           compiler.process(dist, **kw))
 
 
 
 
-class Geometry(types.UserDefinedType): # type: ignore[type-arg]
+class Geometry(types.UserDefinedType):  # type: ignore[type-arg]
     """ Simplified type decorator for PostGIS geometry. This type
         only supports geometries in 4326 projection.
     """
     """ Simplified type decorator for PostGIS geometry. This type
         only supports geometries in 4326 projection.
     """
@@ -174,11 +173,9 @@ class Geometry(types.UserDefinedType): # type: ignore[type-arg]
     def __init__(self, subtype: str = 'Geometry'):
         self.subtype = subtype
 
     def __init__(self, subtype: str = 'Geometry'):
         self.subtype = subtype
 
-
     def get_col_spec(self) -> str:
         return f'GEOMETRY({self.subtype}, 4326)'
 
     def get_col_spec(self) -> str:
         return f'GEOMETRY({self.subtype}, 4326)'
 
-
     def bind_processor(self, dialect: 'sa.Dialect') -> Callable[[Any], str]:
         def process(value: Any) -> str:
             if isinstance(value, str):
     def bind_processor(self, dialect: 'sa.Dialect') -> Callable[[Any], str]:
         def process(value: Any) -> str:
             if isinstance(value, str):
@@ -187,23 +184,19 @@ class Geometry(types.UserDefinedType): # type: ignore[type-arg]
             return cast(str, value.to_wkt())
         return process
 
             return cast(str, value.to_wkt())
         return process
 
-
     def result_processor(self, dialect: 'sa.Dialect', coltype: object) -> Callable[[Any], str]:
         def process(value: Any) -> str:
             assert isinstance(value, str)
             return value
         return process
 
     def result_processor(self, dialect: 'sa.Dialect', coltype: object) -> Callable[[Any], str]:
         def process(value: Any) -> str:
             assert isinstance(value, str)
             return value
         return process
 
-
     def column_expression(self, col: SaColumn) -> SaColumn:
         return sa.func.ST_AsEWKB(col)
 
     def column_expression(self, col: SaColumn) -> SaColumn:
         return sa.func.ST_AsEWKB(col)
 
-
     def bind_expression(self, bindvalue: SaBind) -> SaColumn:
         return sa.func.ST_GeomFromText(bindvalue, sa.text('4326'), type_=self)
 
     def bind_expression(self, bindvalue: SaBind) -> SaColumn:
         return sa.func.ST_GeomFromText(bindvalue, sa.text('4326'), type_=self)
 
-
-    class comparator_factory(types.UserDefinedType.Comparator): # type: ignore[type-arg]
+    class comparator_factory(types.UserDefinedType.Comparator):  # type: ignore[type-arg]
 
         def intersects(self, other: SaColumn, use_index: bool = True) -> 'sa.Operators':
             if not use_index:
 
         def intersects(self, other: SaColumn, use_index: bool = True) -> 'sa.Operators':
             if not use_index:
@@ -214,69 +207,55 @@ class Geometry(types.UserDefinedType): # type: ignore[type-arg]
 
             return Geometry_IntersectsBbox(self.expr, other)
 
 
             return Geometry_IntersectsBbox(self.expr, other)
 
-
         def is_line_like(self) -> SaColumn:
             return Geometry_IsLineLike(self)
 
         def is_line_like(self) -> SaColumn:
             return Geometry_IsLineLike(self)
 
-
         def is_area(self) -> SaColumn:
             return Geometry_IsAreaLike(self)
 
         def is_area(self) -> SaColumn:
             return Geometry_IsAreaLike(self)
 
-
         def within_distance(self, other: SaColumn, distance: SaColumn) -> SaColumn:
             if isinstance(self.expr, sa.Column):
                 return Geometry_ColumnDWithin(self.expr, other, distance)
 
             return self.ST_Distance(other) < distance
 
         def within_distance(self, other: SaColumn, distance: SaColumn) -> SaColumn:
             if isinstance(self.expr, sa.Column):
                 return Geometry_ColumnDWithin(self.expr, other, distance)
 
             return self.ST_Distance(other) < distance
 
-
         def ST_Distance(self, other: SaColumn) -> SaColumn:
             return sa.func.ST_Distance(self, other, type_=sa.Float)
 
         def ST_Distance(self, other: SaColumn) -> SaColumn:
             return sa.func.ST_Distance(self, other, type_=sa.Float)
 
-
         def ST_Contains(self, other: SaColumn) -> SaColumn:
             return sa.func.ST_Contains(self, other, type_=sa.Boolean)
 
         def ST_Contains(self, other: SaColumn) -> SaColumn:
             return sa.func.ST_Contains(self, other, type_=sa.Boolean)
 
-
         def ST_CoveredBy(self, other: SaColumn) -> SaColumn:
             return sa.func.ST_CoveredBy(self, other, type_=sa.Boolean)
 
         def ST_CoveredBy(self, other: SaColumn) -> SaColumn:
             return sa.func.ST_CoveredBy(self, other, type_=sa.Boolean)
 
-
         def ST_ClosestPoint(self, other: SaColumn) -> SaColumn:
             return sa.func.coalesce(sa.func.ST_ClosestPoint(self, other, type_=Geometry),
                                     other)
 
         def ST_ClosestPoint(self, other: SaColumn) -> SaColumn:
             return sa.func.coalesce(sa.func.ST_ClosestPoint(self, other, type_=Geometry),
                                     other)
 
-
         def ST_Buffer(self, other: SaColumn) -> SaColumn:
             return sa.func.ST_Buffer(self, other, type_=Geometry)
 
         def ST_Buffer(self, other: SaColumn) -> SaColumn:
             return sa.func.ST_Buffer(self, other, type_=Geometry)
 
-
         def ST_Expand(self, other: SaColumn) -> SaColumn:
             return sa.func.ST_Expand(self, other, type_=Geometry)
 
         def ST_Expand(self, other: SaColumn) -> SaColumn:
             return sa.func.ST_Expand(self, other, type_=Geometry)
 
-
         def ST_Collect(self) -> SaColumn:
             return sa.func.ST_Collect(self, type_=Geometry)
 
         def ST_Collect(self) -> SaColumn:
             return sa.func.ST_Collect(self, type_=Geometry)
 
-
         def ST_Centroid(self) -> SaColumn:
             return sa.func.ST_Centroid(self, type_=Geometry)
 
         def ST_Centroid(self) -> SaColumn:
             return sa.func.ST_Centroid(self, type_=Geometry)
 
-
         def ST_LineInterpolatePoint(self, other: SaColumn) -> SaColumn:
             return sa.func.ST_LineInterpolatePoint(self, other, type_=Geometry)
 
         def ST_LineInterpolatePoint(self, other: SaColumn) -> SaColumn:
             return sa.func.ST_LineInterpolatePoint(self, other, type_=Geometry)
 
-
         def ST_LineLocatePoint(self, other: SaColumn) -> SaColumn:
             return sa.func.ST_LineLocatePoint(self, other, type_=sa.Float)
 
         def ST_LineLocatePoint(self, other: SaColumn) -> SaColumn:
             return sa.func.ST_LineLocatePoint(self, other, type_=sa.Float)
 
-
         def distance_spheroid(self, other: SaColumn) -> SaColumn:
             return Geometry_DistanceSpheroid(self, other)
 
 
 @compiles(Geometry, 'sqlite')
         def distance_spheroid(self, other: SaColumn) -> SaColumn:
             return Geometry_DistanceSpheroid(self, other)
 
 
 @compiles(Geometry, 'sqlite')
-def get_col_spec(self, *args, **kwargs): # type: ignore[no-untyped-def]
+def get_col_spec(self, *args, **kwargs):  # type: ignore[no-untyped-def]
     return 'GEOMETRY'
 
 
     return 'GEOMETRY'
 
 
@@ -290,6 +269,7 @@ SQLITE_FUNCTION_ALIAS = (
     ('ST_LineInterpolatePoint', sa.Float, 'ST_Line_Interpolate_Point'),
 )
 
     ('ST_LineInterpolatePoint', sa.Float, 'ST_Line_Interpolate_Point'),
 )
 
+
 def _add_function_alias(func: str, ftype: type, alias: str) -> None:
     _FuncDef = type(func, (sa.sql.functions.GenericFunction, ), {
         "type": ftype(),
 def _add_function_alias(func: str, ftype: type, alias: str) -> None:
     _FuncDef = type(func, (sa.sql.functions.GenericFunction, ), {
         "type": ftype(),
@@ -304,5 +284,6 @@ def _add_function_alias(func: str, ftype: type, alias: str) -> None:
 
     compiles(_FuncDef, 'sqlite')(_sqlite_impl)
 
 
     compiles(_FuncDef, 'sqlite')(_sqlite_impl)
 
+
 for alias in SQLITE_FUNCTION_ALIAS:
     _add_function_alias(*alias)
 for alias in SQLITE_FUNCTION_ALIAS:
     _add_function_alias(*alias)
index e53f8bfdd7439ee027950b46b86ca7b13fb51c62..0926d2b7bc2212e92cc69ca77a625f84d4629593 100644 (file)
@@ -7,7 +7,7 @@
 """
 Custom type for an array of integers.
 """
 """
 Custom type for an array of integers.
 """
-from typing import Any, List, cast, Optional
+from typing import Any, List, Optional
 
 import sqlalchemy as sa
 from sqlalchemy.ext.compiler import compiles
 
 import sqlalchemy as sa
 from sqlalchemy.ext.compiler import compiles
@@ -15,7 +15,6 @@ from sqlalchemy.dialects.postgresql import ARRAY
 
 from ...typing import SaDialect, SaColumn
 
 
 from ...typing import SaDialect, SaColumn
 
-# pylint: disable=all
 
 class IntList(sa.types.TypeDecorator[Any]):
     """ A list of integers saved as a text of comma-separated numbers.
 
 class IntList(sa.types.TypeDecorator[Any]):
     """ A list of integers saved as a text of comma-separated numbers.
@@ -46,12 +45,11 @@ class IntArray(sa.types.TypeDecorator[Any]):
 
     def load_dialect_impl(self, dialect: SaDialect) -> sa.types.TypeEngine[Any]:
         if dialect.name == 'postgresql':
 
     def load_dialect_impl(self, dialect: SaDialect) -> sa.types.TypeEngine[Any]:
         if dialect.name == 'postgresql':
-            return ARRAY(sa.Integer()) #pylint: disable=invalid-name
+            return ARRAY(sa.Integer())
 
         return IntList()
 
 
         return IntList()
 
-
-    class comparator_factory(sa.types.UserDefinedType.Comparator): # type: ignore[type-arg]
+    class comparator_factory(sa.types.UserDefinedType.Comparator):  # type: ignore[type-arg]
 
         def __add__(self, other: SaColumn) -> 'sa.ColumnOperators':
             """ Concate the array with the given array. If one of the
 
         def __add__(self, other: SaColumn) -> 'sa.ColumnOperators':
             """ Concate the array with the given array. If one of the
@@ -59,7 +57,6 @@ class IntArray(sa.types.TypeDecorator[Any]):
             """
             return ArrayCat(self.expr, other)
 
             """
             return ArrayCat(self.expr, other)
 
-
         def contains(self, other: SaColumn, **kwargs: Any) -> 'sa.ColumnOperators':
             """ Return true if the array contains all the value of the argument
                 array.
         def contains(self, other: SaColumn, **kwargs: Any) -> 'sa.ColumnOperators':
             """ Return true if the array contains all the value of the argument
                 array.
@@ -67,7 +64,6 @@ class IntArray(sa.types.TypeDecorator[Any]):
             return ArrayContains(self.expr, other)
 
 
             return ArrayContains(self.expr, other)
 
 
-
 class ArrayAgg(sa.sql.functions.GenericFunction[Any]):
     """ Aggregate function to collect elements in an array.
     """
 class ArrayAgg(sa.sql.functions.GenericFunction[Any]):
     """ Aggregate function to collect elements in an array.
     """
@@ -82,7 +78,6 @@ def sqlite_array_agg(element: ArrayAgg, compiler: 'sa.Compiled', **kw: Any) -> s
     return "group_concat(%s, ',')" % compiler.process(element.clauses, **kw)
 
 
     return "group_concat(%s, ',')" % compiler.process(element.clauses, **kw)
 
 
-
 class ArrayContains(sa.sql.expression.FunctionElement[Any]):
     """ Function to check if an array is fully contained in another.
     """
 class ArrayContains(sa.sql.expression.FunctionElement[Any]):
     """ Function to check if an array is fully contained in another.
     """
@@ -102,7 +97,6 @@ def sqlite_array_contains(element: ArrayContains, compiler: 'sa.Compiled', **kw:
     return "array_contains(%s)" % compiler.process(element.clauses, **kw)
 
 
     return "array_contains(%s)" % compiler.process(element.clauses, **kw)
 
 
-
 class ArrayCat(sa.sql.expression.FunctionElement[Any]):
     """ Function to check if an array is fully contained in another.
     """
 class ArrayCat(sa.sql.expression.FunctionElement[Any]):
     """ Function to check if an array is fully contained in another.
     """
@@ -120,4 +114,3 @@ def generic_array_cat(element: ArrayCat, compiler: 'sa.Compiled', **kw: Any) ->
 def sqlite_array_cat(element: ArrayCat, compiler: 'sa.Compiled', **kw: Any) -> str:
     arg1, arg2 = list(element.clauses)
     return "(%s || ',' || %s)" % (compiler.process(arg1, **kw), compiler.process(arg2, **kw))
 def sqlite_array_cat(element: ArrayCat, compiler: 'sa.Compiled', **kw: Any) -> str:
     arg1, arg2 = list(element.clauses)
     return "(%s || ',' || %s)" % (compiler.process(arg1, **kw), compiler.process(arg2, **kw))
-
index 825fd1f2f6f57296c51ba7ff85915d3318d3e47b..1c8f9f7b7ec812f449036cf6a71624247f314a79 100644 (file)
@@ -15,7 +15,6 @@ from sqlalchemy.dialects.sqlite import JSON as sqlite_json
 
 from ...typing import SaDialect
 
 
 from ...typing import SaDialect
 
-# pylint: disable=all
 
 class Json(sa.types.TypeDecorator[Any]):
     """ Dialect-independent type for JSON.
 
 class Json(sa.types.TypeDecorator[Any]):
     """ Dialect-independent type for JSON.
@@ -25,6 +24,6 @@ class Json(sa.types.TypeDecorator[Any]):
 
     def load_dialect_impl(self, dialect: SaDialect) -> sa.types.TypeEngine[Any]:
         if dialect.name == 'postgresql':
 
     def load_dialect_impl(self, dialect: SaDialect) -> sa.types.TypeEngine[Any]:
         if dialect.name == 'postgresql':
-            return JSONB(none_as_null=True) # type: ignore[no-untyped-call]
+            return JSONB(none_as_null=True)  # type: ignore[no-untyped-call]
 
         return sqlite_json(none_as_null=True)
 
         return sqlite_json(none_as_null=True)
index e8296d38001243f664d8e90eb96c24c7c27683eb..bcedc977318ffd6599147a276bdc80f6a1faa679 100644 (file)
@@ -16,7 +16,6 @@ from sqlalchemy.dialects.sqlite import JSON as sqlite_json
 
 from ...typing import SaDialect, SaColumn
 
 
 from ...typing import SaDialect, SaColumn
 
-# pylint: disable=all
 
 class KeyValueStore(sa.types.TypeDecorator[Any]):
     """ Dialect-independent type of a simple key-value store of strings.
 
 class KeyValueStore(sa.types.TypeDecorator[Any]):
     """ Dialect-independent type of a simple key-value store of strings.
@@ -26,12 +25,11 @@ class KeyValueStore(sa.types.TypeDecorator[Any]):
 
     def load_dialect_impl(self, dialect: SaDialect) -> sa.types.TypeEngine[Any]:
         if dialect.name == 'postgresql':
 
     def load_dialect_impl(self, dialect: SaDialect) -> sa.types.TypeEngine[Any]:
         if dialect.name == 'postgresql':
-            return HSTORE() # type: ignore[no-untyped-call]
+            return HSTORE()  # type: ignore[no-untyped-call]
 
         return sqlite_json(none_as_null=True)
 
 
         return sqlite_json(none_as_null=True)
 
-
-    class comparator_factory(sa.types.UserDefinedType.Comparator): # type: ignore[type-arg]
+    class comparator_factory(sa.types.UserDefinedType.Comparator):  # type: ignore[type-arg]
 
         def merge(self, other: SaColumn) -> 'sa.Operators':
             """ Merge the values from the given KeyValueStore into this
 
         def merge(self, other: SaColumn) -> 'sa.Operators':
             """ Merge the values from the given KeyValueStore into this
@@ -48,15 +46,16 @@ class KeyValueConcat(sa.sql.expression.FunctionElement[Any]):
     name = 'JsonConcat'
     inherit_cache = True
 
     name = 'JsonConcat'
     inherit_cache = True
 
+
 @compiles(KeyValueConcat)
 def default_json_concat(element: KeyValueConcat, compiler: 'sa.Compiled', **kw: Any) -> str:
     arg1, arg2 = list(element.clauses)
 @compiles(KeyValueConcat)
 def default_json_concat(element: KeyValueConcat, compiler: 'sa.Compiled', **kw: Any) -> str:
     arg1, arg2 = list(element.clauses)
-    return "(%s || coalesce(%s, ''::hstore))" % (compiler.process(arg1, **kw), compiler.process(arg2, **kw))
+    return "(%s || coalesce(%s, ''::hstore))"\
+        % (compiler.process(arg1, **kw), compiler.process(arg2, **kw))
+
 
 @compiles(KeyValueConcat, 'sqlite')
 def sqlite_json_concat(element: KeyValueConcat, compiler: 'sa.Compiled', **kw: Any) -> str:
     arg1, arg2 = list(element.clauses)
 
 @compiles(KeyValueConcat, 'sqlite')
 def sqlite_json_concat(element: KeyValueConcat, compiler: 'sa.Compiled', **kw: Any) -> str:
     arg1, arg2 = list(element.clauses)
-    return "json_patch(%s, coalesce(%s, '{}'))" % (compiler.process(arg1, **kw), compiler.process(arg2, **kw))
-
-
-
+    return "json_patch(%s, coalesce(%s, '{}'))"\
+        % (compiler.process(arg1, **kw), compiler.process(arg2, **kw))
index 43865e951ef0e4d26361d5476830da0d5016fd1a..ef46bec36740b2b7a6f8a2fb8d02ac3b575acd7f 100644 (file)
@@ -10,7 +10,6 @@ Custom functions for SQLite.
 from typing import cast, Optional, Set, Any
 import json
 
 from typing import cast, Optional, Set, Any
 import json
 
-# pylint: disable=protected-access
 
 def weigh_search(search_vector: Optional[str], rankings: str, default: float) -> float:
     """ Custom weight function for search results.
 
 def weigh_search(search_vector: Optional[str], rankings: str, default: float) -> float:
     """ Custom weight function for search results.
@@ -118,5 +117,5 @@ async def _make_aggregate(aioconn: Any, *args: Any) -> None:
 def _create_aggregate(conn: Any, name: str, nargs: int, aggregate: Any) -> None:
     try:
         conn.await_(_make_aggregate(conn._connection, name, nargs, aggregate))
 def _create_aggregate(conn: Any, name: str, nargs: int, aggregate: Any) -> None:
     try:
         conn.await_(_make_aggregate(conn._connection, name, nargs, aggregate))
-    except Exception as error: # pylint: disable=broad-exception-caught
+    except Exception as error:
         conn._handle_exception(error)
         conn._handle_exception(error)
index ea88a467d08b0646a0c3a1226309a9284326d2f1..f9a9a8eb7d45c3a7b2ed7e44aca066fdf07861ac 100644 (file)
@@ -16,6 +16,7 @@ import sqlalchemy as sa
 from .connection import SearchConnection
 from .version import NOMINATIM_API_VERSION
 
 from .connection import SearchConnection
 from .version import NOMINATIM_API_VERSION
 
+
 @dataclasses.dataclass
 class StatusResult:
     """ Result of a call to the status API.
 @dataclasses.dataclass
 class StatusResult:
     """ Result of a call to the status API.
index 0dea1d1bc7127c664350e10b5fd2efe6fb30dc3f..5f3309d9498f901fd89072e0005bd14c2161f0fa 100644 (file)
@@ -19,7 +19,6 @@ from binascii import unhexlify
 from .errors import UsageError
 from .localization import Locales
 
 from .errors import UsageError
 from .localization import Locales
 
-# pylint: disable=no-member,too-many-boolean-expressions,too-many-instance-attributes
 
 @dataclasses.dataclass
 class PlaceID:
 
 @dataclasses.dataclass
 class PlaceID:
@@ -72,27 +71,23 @@ class Point(NamedTuple):
     x: float
     y: float
 
     x: float
     y: float
 
-
     @property
     def lat(self) -> float:
         """ Return the latitude of the point.
         """
         return self.y
 
     @property
     def lat(self) -> float:
         """ Return the latitude of the point.
         """
         return self.y
 
-
     @property
     def lon(self) -> float:
         """ Return the longitude of the point.
         """
         return self.x
 
     @property
     def lon(self) -> float:
         """ Return the longitude of the point.
         """
         return self.x
 
-
     def to_geojson(self) -> str:
         """ Return the point in GeoJSON format.
         """
         return f'{{"type": "Point","coordinates": [{self.x}, {self.y}]}}'
 
     def to_geojson(self) -> str:
         """ Return the point in GeoJSON format.
         """
         return f'{{"type": "Point","coordinates": [{self.x}, {self.y}]}}'
 
-
     @staticmethod
     def from_wkb(wkb: Union[str, bytes]) -> 'Point':
         """ Create a point from EWKB as returned from the database.
     @staticmethod
     def from_wkb(wkb: Union[str, bytes]) -> 'Point':
         """ Create a point from EWKB as returned from the database.
@@ -115,7 +110,6 @@ class Point(NamedTuple):
 
         return Point(x, y)
 
 
         return Point(x, y)
 
-
     @staticmethod
     def from_param(inp: Any) -> 'Point':
         """ Create a point from an input parameter. The parameter
     @staticmethod
     def from_param(inp: Any) -> 'Point':
         """ Create a point from an input parameter. The parameter
@@ -144,19 +138,18 @@ class Point(NamedTuple):
 
         return Point(x, y)
 
 
         return Point(x, y)
 
-
     def to_wkt(self) -> str:
         """ Return the WKT representation of the point.
         """
         return f'POINT({self.x} {self.y})'
 
 
     def to_wkt(self) -> str:
         """ Return the WKT representation of the point.
         """
         return f'POINT({self.x} {self.y})'
 
 
-
 AnyPoint = Union[Point, Tuple[float, float]]
 
 WKB_BBOX_HEADER_LE = b'\x01\x03\x00\x00\x20\xE6\x10\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00'
 WKB_BBOX_HEADER_BE = b'\x00\x20\x00\x00\x03\x00\x00\x10\xe6\x00\x00\x00\x01\x00\x00\x00\x05'
 
 AnyPoint = Union[Point, Tuple[float, float]]
 
 WKB_BBOX_HEADER_LE = b'\x01\x03\x00\x00\x20\xE6\x10\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00'
 WKB_BBOX_HEADER_BE = b'\x00\x20\x00\x00\x03\x00\x00\x10\xe6\x00\x00\x00\x01\x00\x00\x00\x05'
 
+
 class Bbox:
     """ A bounding box in WGS84 projection.
 
 class Bbox:
     """ A bounding box in WGS84 projection.
 
@@ -169,56 +162,48 @@ class Bbox:
         """
         self.coords = (minx, miny, maxx, maxy)
 
         """
         self.coords = (minx, miny, maxx, maxy)
 
-
     @property
     def minlat(self) -> float:
         """ Southern-most latitude, corresponding to the minimum y coordinate.
         """
         return self.coords[1]
 
     @property
     def minlat(self) -> float:
         """ Southern-most latitude, corresponding to the minimum y coordinate.
         """
         return self.coords[1]
 
-
     @property
     def maxlat(self) -> float:
         """ Northern-most latitude, corresponding to the maximum y coordinate.
         """
         return self.coords[3]
 
     @property
     def maxlat(self) -> float:
         """ Northern-most latitude, corresponding to the maximum y coordinate.
         """
         return self.coords[3]
 
-
     @property
     def minlon(self) -> float:
         """ Western-most longitude, corresponding to the minimum x coordinate.
         """
         return self.coords[0]
 
     @property
     def minlon(self) -> float:
         """ Western-most longitude, corresponding to the minimum x coordinate.
         """
         return self.coords[0]
 
-
     @property
     def maxlon(self) -> float:
         """ Eastern-most longitude, corresponding to the maximum x coordinate.
         """
         return self.coords[2]
 
     @property
     def maxlon(self) -> float:
         """ Eastern-most longitude, corresponding to the maximum x coordinate.
         """
         return self.coords[2]
 
-
     @property
     def area(self) -> float:
         """ Return the area of the box in WGS84.
         """
         return (self.coords[2] - self.coords[0]) * (self.coords[3] - self.coords[1])
 
     @property
     def area(self) -> float:
         """ Return the area of the box in WGS84.
         """
         return (self.coords[2] - self.coords[0]) * (self.coords[3] - self.coords[1])
 
-
     def contains(self, pt: Point) -> bool:
         """ Check if the point is inside or on the boundary of the box.
         """
         return self.coords[0] <= pt[0] and self.coords[1] <= pt[1]\
     def contains(self, pt: Point) -> bool:
         """ Check if the point is inside or on the boundary of the box.
         """
         return self.coords[0] <= pt[0] and self.coords[1] <= pt[1]\
-               and self.coords[2] >= pt[0] and self.coords[3] >= pt[1]
-
+            and self.coords[2] >= pt[0] and self.coords[3] >= pt[1]
 
     def to_wkt(self) -> str:
         """ Return the WKT representation of the Bbox. This
             is a simple polygon with four points.
         """
         return 'POLYGON(({0} {1},{0} {3},{2} {3},{2} {1},{0} {1}))'\
 
     def to_wkt(self) -> str:
         """ Return the WKT representation of the Bbox. This
             is a simple polygon with four points.
         """
         return 'POLYGON(({0} {1},{0} {3},{2} {3},{2} {1},{0} {1}))'\
-                  .format(*self.coords) # pylint: disable=consider-using-f-string
-
+            .format(*self.coords)
 
     @staticmethod
     def from_wkb(wkb: Union[None, str, bytes]) -> 'Optional[Bbox]':
 
     @staticmethod
     def from_wkb(wkb: Union[None, str, bytes]) -> 'Optional[Bbox]':
@@ -242,7 +227,6 @@ class Bbox:
 
         return Bbox(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2))
 
 
         return Bbox(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2))
 
-
     @staticmethod
     def from_point(pt: Point, buffer: float) -> 'Bbox':
         """ Return a Bbox around the point with the buffer added to all sides.
     @staticmethod
     def from_point(pt: Point, buffer: float) -> 'Bbox':
         """ Return a Bbox around the point with the buffer added to all sides.
@@ -250,7 +234,6 @@ class Bbox:
         return Bbox(pt[0] - buffer, pt[1] - buffer,
                     pt[0] + buffer, pt[1] + buffer)
 
         return Bbox(pt[0] - buffer, pt[1] - buffer,
                     pt[0] + buffer, pt[1] + buffer)
 
-
     @staticmethod
     def from_param(inp: Any) -> 'Bbox':
         """ Return a Bbox from an input parameter. The box may be
     @staticmethod
     def from_param(inp: Any) -> 'Bbox':
         """ Return a Bbox from an input parameter. The box may be
@@ -383,7 +366,9 @@ def format_categories(categories: List[Tuple[str, str]]) -> List[Tuple[str, str]
     """
     return categories
 
     """
     return categories
 
-TParam = TypeVar('TParam', bound='LookupDetails') # pylint: disable=invalid-name
+
+TParam = TypeVar('TParam', bound='LookupDetails')
+
 
 @dataclasses.dataclass
 class LookupDetails:
 
 @dataclasses.dataclass
 class LookupDetails:
@@ -434,7 +419,7 @@ class LookupDetails:
                        else field.default
             if field.metadata and 'transform' in field.metadata:
                 return field.metadata['transform'](v)
                        else field.default
             if field.metadata and 'transform' in field.metadata:
                 return field.metadata['transform'](v)
-            if not isinstance(v, field.type): # type: ignore[arg-type]
+            if not isinstance(v, field.type):  # type: ignore[arg-type]
                 raise UsageError(f"Parameter '{field.name}' needs to be of {field.type!s}.")
             return v
 
                 raise UsageError(f"Parameter '{field.name}' needs to be of {field.type!s}.")
             return v
 
@@ -446,15 +431,17 @@ class LookupDetails:
 class ReverseDetails(LookupDetails):
     """ Collection of parameters for the reverse call.
     """
 class ReverseDetails(LookupDetails):
     """ Collection of parameters for the reverse call.
     """
+
     max_rank: int = dataclasses.field(default=30,
     max_rank: int = dataclasses.field(default=30,
-                                      metadata={'transform': lambda v: max(0, min(v, 30))}
-                                     )
+                                      metadata={'transform': lambda v: max(0, min(v, 30))})
     """ Highest address rank to return.
     """
     """ Highest address rank to return.
     """
+
     layers: DataLayer = DataLayer.ADDRESS | DataLayer.POI
     """ Filter which kind of data to include.
     """
 
     layers: DataLayer = DataLayer.ADDRESS | DataLayer.POI
     """ Filter which kind of data to include.
     """
 
+
 @dataclasses.dataclass
 class SearchDetails(LookupDetails):
     """ Collection of parameters for the search call.
 @dataclasses.dataclass
 class SearchDetails(LookupDetails):
     """ Collection of parameters for the search call.
@@ -463,54 +450,63 @@ class SearchDetails(LookupDetails):
     """ Maximum number of results to be returned. The actual number of results
         may be less.
     """
     """ Maximum number of results to be returned. The actual number of results
         may be less.
     """
+
     min_rank: int = dataclasses.field(default=0,
     min_rank: int = dataclasses.field(default=0,
-                                      metadata={'transform': lambda v: max(0, min(v, 30))}
-                                     )
+                                      metadata={'transform': lambda v: max(0, min(v, 30))})
     """ Lowest address rank to return.
     """
     """ Lowest address rank to return.
     """
+
     max_rank: int = dataclasses.field(default=30,
     max_rank: int = dataclasses.field(default=30,
-                                      metadata={'transform': lambda v: max(0, min(v, 30))}
-                                     )
+                                      metadata={'transform': lambda v: max(0, min(v, 30))})
     """ Highest address rank to return.
     """
     """ Highest address rank to return.
     """
+
     layers: Optional[DataLayer] = dataclasses.field(default=None,
     layers: Optional[DataLayer] = dataclasses.field(default=None,
-                                                    metadata={'transform': lambda r : r})
+                                                    metadata={'transform': lambda r: r})
     """ Filter which kind of data to include. When 'None' (the default) then
         filtering by layers is disabled.
     """
     """ Filter which kind of data to include. When 'None' (the default) then
         filtering by layers is disabled.
     """
+
     countries: List[str] = dataclasses.field(default_factory=list,
                                              metadata={'transform': format_country})
     """ Restrict search results to the given countries. An empty list (the
         default) will disable this filter.
     """
     countries: List[str] = dataclasses.field(default_factory=list,
                                              metadata={'transform': format_country})
     """ Restrict search results to the given countries. An empty list (the
         default) will disable this filter.
     """
+
     excluded: List[int] = dataclasses.field(default_factory=list,
                                             metadata={'transform': format_excluded})
     """ List of OSM objects to exclude from the results. Currently only
         works when the internal place ID is given.
         An empty list (the default) will disable this filter.
     """
     excluded: List[int] = dataclasses.field(default_factory=list,
                                             metadata={'transform': format_excluded})
     """ List of OSM objects to exclude from the results. Currently only
         works when the internal place ID is given.
         An empty list (the default) will disable this filter.
     """
+
     viewbox: Optional[Bbox] = dataclasses.field(default=None,
                                                 metadata={'transform': Bbox.from_param})
     """ Focus the search on a given map area.
     """
     viewbox: Optional[Bbox] = dataclasses.field(default=None,
                                                 metadata={'transform': Bbox.from_param})
     """ Focus the search on a given map area.
     """
+
     bounded_viewbox: bool = False
     """ Use 'viewbox' as a filter and restrict results to places within the
         given area.
     """
     bounded_viewbox: bool = False
     """ Use 'viewbox' as a filter and restrict results to places within the
         given area.
     """
+
     near: Optional[Point] = dataclasses.field(default=None,
                                               metadata={'transform': Point.from_param})
     """ Order results by distance to the given point.
     """
     near: Optional[Point] = dataclasses.field(default=None,
                                               metadata={'transform': Point.from_param})
     """ Order results by distance to the given point.
     """
+
     near_radius: Optional[float] = dataclasses.field(default=None,
     near_radius: Optional[float] = dataclasses.field(default=None,
-                                              metadata={'transform': lambda r : r})
+                                                     metadata={'transform': lambda r: r})
     """ Use near point as a filter and drop results outside the given
         radius. Radius is given in degrees WSG84.
     """
     """ Use near point as a filter and drop results outside the given
         radius. Radius is given in degrees WSG84.
     """
+
     categories: List[Tuple[str, str]] = dataclasses.field(default_factory=list,
                                                           metadata={'transform': format_categories})
     """ Restrict search to places with one of the given class/type categories.
         An empty list (the default) will disable this filter.
     """
     categories: List[Tuple[str, str]] = dataclasses.field(default_factory=list,
                                                           metadata={'transform': format_categories})
     """ Restrict search to places with one of the given class/type categories.
         An empty list (the default) will disable this filter.
     """
+
     viewbox_x2: Optional[Bbox] = None
 
     def __post_init__(self) -> None:
     viewbox_x2: Optional[Bbox] = None
 
     def __post_init__(self) -> None:
@@ -520,7 +516,6 @@ class SearchDetails(LookupDetails):
             self.viewbox_x2 = Bbox(self.viewbox.minlon - xext, self.viewbox.minlat - yext,
                                    self.viewbox.maxlon + xext, self.viewbox.maxlat + yext)
 
             self.viewbox_x2 = Bbox(self.viewbox.minlon - xext, self.viewbox.minlat - yext,
                                    self.viewbox.maxlon + xext, self.viewbox.maxlat + yext)
 
-
     def restrict_min_max_rank(self, new_min: int, new_max: int) -> None:
         """ Change the min_rank and max_rank fields to respect the
             given boundaries.
     def restrict_min_max_rank(self, new_min: int, new_max: int) -> None:
         """ Change the min_rank and max_rank fields to respect the
             given boundaries.
@@ -529,7 +524,6 @@ class SearchDetails(LookupDetails):
         self.min_rank = max(self.min_rank, new_min)
         self.max_rank = min(self.max_rank, new_max)
 
         self.min_rank = max(self.min_rank, new_min)
         self.max_rank = min(self.max_rank, new_max)
 
-
     def is_impossible(self) -> bool:
         """ Check if the parameter configuration is contradictionary and
             cannot yield any results.
     def is_impossible(self) -> bool:
         """ Check if the parameter configuration is contradictionary and
             cannot yield any results.
@@ -542,7 +536,6 @@ class SearchDetails(LookupDetails):
                 or (self.max_rank <= 4 and
                     self.layers is not None and not self.layers & DataLayer.ADDRESS))
 
                 or (self.max_rank <= 4 and
                     self.layers is not None and not self.layers & DataLayer.ADDRESS))
 
-
     def layer_enabled(self, layer: DataLayer) -> bool:
         """ Check if the given layer has been chosen. Also returns
             true when layer restriction has been disabled completely.
     def layer_enabled(self, layer: DataLayer) -> bool:
         """ Check if the given layer has been chosen. Also returns
             true when layer restriction has been disabled completely.
index ba0d95bf08248110875c550550fd2ec62035dce0..89aa44285f622e00020a5debb58b439be95f70c8 100644 (file)
@@ -11,7 +11,7 @@ Complex type definitions are moved here, to keep the source files readable.
 """
 from typing import Union, TYPE_CHECKING
 
 """
 from typing import Union, TYPE_CHECKING
 
-# pylint: disable=missing-class-docstring,useless-import-alias
+# flake8: noqa
 
 # SQLAlchemy introduced generic types in version 2.0 making typing
 # incompatible with older versions. Add wrappers here so we don't have
 
 # SQLAlchemy introduced generic types in version 2.0 making typing
 # incompatible with older versions. Add wrappers here so we don't have
index c3d17a841db859c1a3817f69c664cb4590890b00..eddc441deaf8ea2e2ca054d3170b4dd2165fca07 100644 (file)
@@ -12,9 +12,10 @@ import io
 try:
     import ujson as json
 except ModuleNotFoundError:
 try:
     import ujson as json
 except ModuleNotFoundError:
-    import json # type: ignore[no-redef]
+    import json  # type: ignore[no-redef]
+
+T = TypeVar('T')
 
 
-T = TypeVar('T') # pylint: disable=invalid-name
 
 class JsonWriter:
     """ JSON encoder that renders the output directly into an output
 
 class JsonWriter:
     """ JSON encoder that renders the output directly into an output
@@ -33,7 +34,6 @@ class JsonWriter:
         self.data = io.StringIO()
         self.pending = ''
 
         self.data = io.StringIO()
         self.pending = ''
 
-
     def __call__(self) -> str:
         """ Return the rendered JSON content as a string.
             The writer remains usable after calling this function.
     def __call__(self) -> str:
         """ Return the rendered JSON content as a string.
             The writer remains usable after calling this function.
@@ -44,7 +44,6 @@ class JsonWriter:
             self.pending = ''
         return self.data.getvalue()
 
             self.pending = ''
         return self.data.getvalue()
 
-
     def start_object(self) -> 'JsonWriter':
         """ Write the open bracket of a JSON object.
         """
     def start_object(self) -> 'JsonWriter':
         """ Write the open bracket of a JSON object.
         """
@@ -53,7 +52,6 @@ class JsonWriter:
         self.pending = '{'
         return self
 
         self.pending = '{'
         return self
 
-
     def end_object(self) -> 'JsonWriter':
         """ Write the closing bracket of a JSON object.
         """
     def end_object(self) -> 'JsonWriter':
         """ Write the closing bracket of a JSON object.
         """
@@ -63,7 +61,6 @@ class JsonWriter:
         self.pending = '}'
         return self
 
         self.pending = '}'
         return self
 
-
     def start_array(self) -> 'JsonWriter':
         """ Write the opening bracket of a JSON array.
         """
     def start_array(self) -> 'JsonWriter':
         """ Write the opening bracket of a JSON array.
         """
@@ -72,7 +69,6 @@ class JsonWriter:
         self.pending = '['
         return self
 
         self.pending = '['
         return self
 
-
     def end_array(self) -> 'JsonWriter':
         """ Write the closing bracket of a JSON array.
         """
     def end_array(self) -> 'JsonWriter':
         """ Write the closing bracket of a JSON array.
         """
@@ -82,7 +78,6 @@ class JsonWriter:
         self.pending = ']'
         return self
 
         self.pending = ']'
         return self
 
-
     def key(self, name: str) -> 'JsonWriter':
         """ Write the key string of a JSON object.
         """
     def key(self, name: str) -> 'JsonWriter':
         """ Write the key string of a JSON object.
         """
@@ -92,7 +87,6 @@ class JsonWriter:
         self.pending = ':'
         return self
 
         self.pending = ':'
         return self
 
-
     def value(self, value: Any) -> 'JsonWriter':
         """ Write out a value as JSON. The function uses the json.dumps()
             function for encoding the JSON. Thus any value that can be
     def value(self, value: Any) -> 'JsonWriter':
         """ Write out a value as JSON. The function uses the json.dumps()
             function for encoding the JSON. Thus any value that can be
@@ -100,7 +94,6 @@ class JsonWriter:
         """
         return self.raw(json.dumps(value, ensure_ascii=False))
 
         """
         return self.raw(json.dumps(value, ensure_ascii=False))
 
-
     def float(self, value: float, precision: int) -> 'JsonWriter':
         """ Write out a float value with the given precision.
         """
     def float(self, value: float, precision: int) -> 'JsonWriter':
         """ Write out a float value with the given precision.
         """
@@ -114,7 +107,6 @@ class JsonWriter:
         self.pending = ','
         return self
 
         self.pending = ','
         return self
 
-
     def raw(self, raw_json: str) -> 'JsonWriter':
         """ Write out the given value as is. This function is useful if
             a value is already available in JSON format.
     def raw(self, raw_json: str) -> 'JsonWriter':
         """ Write out the given value as is. This function is useful if
             a value is already available in JSON format.
@@ -125,7 +117,6 @@ class JsonWriter:
         self.data.write(raw_json)
         return self
 
         self.data.write(raw_json)
         return self
 
-
     def keyval(self, key: str, value: Any) -> 'JsonWriter':
         """ Write out an object element with the given key and value.
             This is a shortcut for calling 'key()', 'value()' and 'next()'.
     def keyval(self, key: str, value: Any) -> 'JsonWriter':
         """ Write out an object element with the given key and value.
             This is a shortcut for calling 'key()', 'value()' and 'next()'.
@@ -134,7 +125,6 @@ class JsonWriter:
         self.value(value)
         return self.next()
 
         self.value(value)
         return self.next()
 
-
     def keyval_not_none(self, key: str, value: Optional[T],
                         transform: Optional[Callable[[T], Any]] = None) -> 'JsonWriter':
         """ Write out an object element only if the value is not None.
     def keyval_not_none(self, key: str, value: Optional[T],
                         transform: Optional[Callable[[T], Any]] = None) -> 'JsonWriter':
         """ Write out an object element only if the value is not None.
index 4f684a91782ae1cdc55e128c712dc8a2e7e6cae4..f49de2a2968c3131f0f4388ea6e02c9e8ea3e07b 100644 (file)
@@ -8,6 +8,4 @@
 Implementation of API version v1 (aka the legacy version).
 """
 
 Implementation of API version v1 (aka the legacy version).
 """
 
-#pylint: disable=useless-import-alias
-
 from .server_glue import ROUTES as ROUTES
 from .server_glue import ROUTES as ROUTES
index 9e78c83b5a634eeb171c8396df6227403b8837df..3224232c4f85da30cc07ceb3b84d6cfdb37fb61d 100644 (file)
@@ -15,6 +15,7 @@ from typing import Tuple, Optional, Mapping, Union
 from ..results import ReverseResult, SearchResult
 from ..types import Bbox
 
 from ..results import ReverseResult, SearchResult
 from ..types import Bbox
 
+
 def get_label_tag(category: Tuple[str, str], extratags: Optional[Mapping[str, str]],
                   rank: int, country: Optional[str]) -> str:
     """ Create a label tag for the given place that can be used as an XML name.
 def get_label_tag(category: Tuple[str, str], extratags: Optional[Mapping[str, str]],
                   rank: int, country: Optional[str]) -> str:
     """ Create a label tag for the given place that can be used as an XML name.
@@ -33,8 +34,8 @@ def get_label_tag(category: Tuple[str, str], extratags: Optional[Mapping[str, st
         label = category[1] if category[1] != 'yes' else category[0]
     elif rank < 28:
         label = 'road'
         label = category[1] if category[1] != 'yes' else category[0]
     elif rank < 28:
         label = 'road'
-    elif category[0] == 'place'\
-         and category[1] in ('house_number', 'house_name', 'country_code'):
+    elif (category[0] == 'place'
+          and category[1] in ('house_number', 'house_name', 'country_code')):
         label = category[1]
     else:
         label = category[0]
         label = category[1]
     else:
         label = category[0]
index 478c7207f7aa9b612f81c934f0450848c76e575e..2657d3698b81bdba83661031219e85b341d9694b 100644 (file)
@@ -22,14 +22,17 @@ from . import format_json, format_xml
 from .. import logging as loglib
 from ..server import content_types as ct
 
 from .. import logging as loglib
 from ..server import content_types as ct
 
+
 class RawDataList(List[Dict[str, Any]]):
     """ Data type for formatting raw data lists 'as is' in json.
     """
 
 class RawDataList(List[Dict[str, Any]]):
     """ Data type for formatting raw data lists 'as is' in json.
     """
 
+
 dispatch = FormatDispatcher({'text': ct.CONTENT_TEXT,
                              'xml': ct.CONTENT_XML,
                              'debug': ct.CONTENT_HTML})
 
 dispatch = FormatDispatcher({'text': ct.CONTENT_TEXT,
                              'xml': ct.CONTENT_XML,
                              'debug': ct.CONTENT_HTML})
 
+
 @dispatch.error_format_func
 def _format_error(content_type: str, msg: str, status: int) -> str:
     if content_type == ct.CONTENT_XML:
 @dispatch.error_format_func
 def _format_error(content_type: str, msg: str, status: int) -> str:
     if content_type == ct.CONTENT_XML:
@@ -65,13 +68,13 @@ def _format_status_json(result: StatusResult, _: Mapping[str, Any]) -> str:
     out = JsonWriter()
 
     out.start_object()\
     out = JsonWriter()
 
     out.start_object()\
-         .keyval('status', result.status)\
-         .keyval('message', result.message)\
-         .keyval_not_none('data_updated', result.data_updated,
-                          lambda v: v.isoformat())\
-         .keyval('software_version', str(result.software_version))\
-         .keyval_not_none('database_version', result.database_version, str)\
-       .end_object()
+        .keyval('status', result.status)\
+        .keyval('message', result.message)\
+        .keyval_not_none('data_updated', result.data_updated,
+                         lambda v: v.isoformat())\
+        .keyval('software_version', str(result.software_version))\
+        .keyval_not_none('database_version', result.database_version, str)\
+        .end_object()
 
     return out()
 
 
     return out()
 
@@ -119,7 +122,7 @@ def _add_parent_rows_grouped(writer: JsonWriter, rows: AddressLines,
     writer.key('hierarchy').start_object()
     for group, grouped in data.items():
         writer.key(group).start_array()
     writer.key('hierarchy').start_object()
     for group, grouped in data.items():
         writer.key(group).start_array()
-        grouped.sort() # sorts alphabetically by local name
+        grouped.sort()  # sorts alphabetically by local name
         for line in grouped:
             writer.raw(line).next()
         writer.end_array().next()
         for line in grouped:
             writer.raw(line).next()
         writer.end_array().next()
@@ -135,32 +138,32 @@ def _format_details_json(result: DetailedResult, options: Mapping[str, Any]) ->
 
     out = JsonWriter()
     out.start_object()\
 
     out = JsonWriter()
     out.start_object()\
-         .keyval_not_none('place_id', result.place_id)\
-         .keyval_not_none('parent_place_id', result.parent_place_id)
+        .keyval_not_none('place_id', result.place_id)\
+        .keyval_not_none('parent_place_id', result.parent_place_id)
 
     if result.osm_object is not None:
         out.keyval('osm_type', result.osm_object[0])\
            .keyval('osm_id', result.osm_object[1])
 
     out.keyval('category', result.category[0])\
 
     if result.osm_object is not None:
         out.keyval('osm_type', result.osm_object[0])\
            .keyval('osm_id', result.osm_object[1])
 
     out.keyval('category', result.category[0])\
-         .keyval('type', result.category[1])\
-         .keyval('admin_level', result.admin_level)\
-         .keyval('localname', result.locale_name or '')\
-         .keyval('names', result.names or {})\
-         .keyval('addresstags', result.address or {})\
-         .keyval_not_none('housenumber', result.housenumber)\
-         .keyval_not_none('calculated_postcode', result.postcode)\
-         .keyval_not_none('country_code', result.country_code)\
-         .keyval_not_none('indexed_date', result.indexed_date, lambda v: v.isoformat())\
-         .keyval_not_none('importance', result.importance)\
-         .keyval('calculated_importance', result.calculated_importance())\
-         .keyval('extratags', result.extratags or {})\
-         .keyval_not_none('calculated_wikipedia', result.wikipedia)\
-         .keyval('rank_address', result.rank_address)\
-         .keyval('rank_search', result.rank_search)\
-         .keyval('isarea', 'Polygon' in (geom or result.geometry.get('type') or ''))\
-         .key('centroid').raw(centroid).next()\
-         .key('geometry').raw(geom or centroid).next()
+       .keyval('type', result.category[1])\
+       .keyval('admin_level', result.admin_level)\
+       .keyval('localname', result.locale_name or '')\
+       .keyval('names', result.names or {})\
+       .keyval('addresstags', result.address or {})\
+       .keyval_not_none('housenumber', result.housenumber)\
+       .keyval_not_none('calculated_postcode', result.postcode)\
+       .keyval_not_none('country_code', result.country_code)\
+       .keyval_not_none('indexed_date', result.indexed_date, lambda v: v.isoformat())\
+       .keyval_not_none('importance', result.importance)\
+       .keyval('calculated_importance', result.calculated_importance())\
+       .keyval('extratags', result.extratags or {})\
+       .keyval_not_none('calculated_wikipedia', result.wikipedia)\
+       .keyval('rank_address', result.rank_address)\
+       .keyval('rank_search', result.rank_search)\
+       .keyval('isarea', 'Polygon' in (geom or result.geometry.get('type') or ''))\
+       .key('centroid').raw(centroid).next()\
+       .key('geometry').raw(geom or centroid).next()
 
     if options.get('icon_base_url', None):
         icon = ICONS.get(result.category)
 
     if options.get('icon_base_url', None):
         icon = ICONS.get(result.category)
@@ -241,32 +244,32 @@ def _format_search_xml(results: SearchResults, options: Mapping[str, Any]) -> st
                                       extra)
 
 
                                       extra)
 
 
-
 @dispatch.format_func(SearchResults, 'geojson')
 def _format_search_geojson(results: SearchResults,
 @dispatch.format_func(SearchResults, 'geojson')
 def _format_search_geojson(results: SearchResults,
-                            options: Mapping[str, Any]) -> str:
+                           options: Mapping[str, Any]) -> str:
     return format_json.format_base_geojson(results, options, False)
 
 
 @dispatch.format_func(SearchResults, 'geocodejson')
 def _format_search_geocodejson(results: SearchResults,
     return format_json.format_base_geojson(results, options, False)
 
 
 @dispatch.format_func(SearchResults, 'geocodejson')
 def _format_search_geocodejson(results: SearchResults,
-                                options: Mapping[str, Any]) -> str:
+                               options: Mapping[str, Any]) -> str:
     return format_json.format_base_geocodejson(results, options, False)
 
 
 @dispatch.format_func(SearchResults, 'json')
 def _format_search_json(results: SearchResults,
     return format_json.format_base_geocodejson(results, options, False)
 
 
 @dispatch.format_func(SearchResults, 'json')
 def _format_search_json(results: SearchResults,
-                         options: Mapping[str, Any]) -> str:
+                        options: Mapping[str, Any]) -> str:
     return format_json.format_base_json(results, options, False,
                                         class_label='class')
 
 
 @dispatch.format_func(SearchResults, 'jsonv2')
 def _format_search_jsonv2(results: SearchResults,
     return format_json.format_base_json(results, options, False,
                                         class_label='class')
 
 
 @dispatch.format_func(SearchResults, 'jsonv2')
 def _format_search_jsonv2(results: SearchResults,
-                           options: Mapping[str, Any]) -> str:
+                          options: Mapping[str, Any]) -> str:
     return format_json.format_base_json(results, options, False,
                                         class_label='category')
 
     return format_json.format_base_json(results, options, False,
                                         class_label='category')
 
+
 @dispatch.format_func(RawDataList, 'json')
 def _format_raw_data_json(results: RawDataList,  _: Mapping[str, Any]) -> str:
     out = JsonWriter()
 @dispatch.format_func(RawDataList, 'json')
 def _format_raw_data_json(results: RawDataList,  _: Mapping[str, Any]) -> str:
     out = JsonWriter()
@@ -275,7 +278,7 @@ def _format_raw_data_json(results: RawDataList,  _: Mapping[str, Any]) -> str:
         out.start_object()
         for k, v in res.items():
             if isinstance(v, dt.datetime):
         out.start_object()
         for k, v in res.items():
             if isinstance(v, dt.datetime):
-                out.keyval(k, v.isoformat(sep= ' ', timespec='seconds'))
+                out.keyval(k, v.isoformat(sep=' ', timespec='seconds'))
             else:
                 out.keyval(k, v)
         out.end_object().next()
             else:
                 out.keyval(k, v)
         out.end_object().next()
index 34bb777a2f206de64c55ca36c07dbb94819ed26f..b397e702cec09ec5a791762dba0fdd4422ec918e 100644 (file)
@@ -13,7 +13,6 @@ from ..utils.json_writer import JsonWriter
 from ..results import AddressLines, ReverseResults, SearchResults
 from . import classtypes as cl
 
 from ..results import AddressLines, ReverseResults, SearchResults
 from . import classtypes as cl
 
-#pylint: disable=too-many-branches
 
 def _write_osm_id(out: JsonWriter, osm_object: Optional[Tuple[str, int]]) -> None:
     if osm_object is not None:
 
 def _write_osm_id(out: JsonWriter, osm_object: Optional[Tuple[str, int]]) -> None:
     if osm_object is not None:
@@ -22,7 +21,7 @@ def _write_osm_id(out: JsonWriter, osm_object: Optional[Tuple[str, int]]) -> Non
 
 
 def _write_typed_address(out: JsonWriter, address: Optional[AddressLines],
 
 
 def _write_typed_address(out: JsonWriter, address: Optional[AddressLines],
-                               country_code: Optional[str]) -> None:
+                         country_code: Optional[str]) -> None:
     parts = {}
     for line in (address or []):
         if line.isaddress:
     parts = {}
     for line in (address or []):
         if line.isaddress:
@@ -52,13 +51,12 @@ def _write_geocodejson_address(out: JsonWriter,
                 out.keyval('postcode', line.local_name)
             elif line.category[1] == 'house_number':
                 out.keyval('housenumber', line.local_name)
                 out.keyval('postcode', line.local_name)
             elif line.category[1] == 'house_number':
                 out.keyval('housenumber', line.local_name)
-            elif (obj_place_id is None or obj_place_id != line.place_id) \
-                 and line.rank_address >= 4 and line.rank_address < 28:
+            elif ((obj_place_id is None or obj_place_id != line.place_id)
+                  and line.rank_address >= 4 and line.rank_address < 28):
                 rank_name = GEOCODEJSON_RANKS[line.rank_address]
                 if rank_name not in extra:
                     extra[rank_name] = line.local_name
 
                 rank_name = GEOCODEJSON_RANKS[line.rank_address]
                 if rank_name not in extra:
                     extra[rank_name] = line.local_name
 
-
     for k, v in extra.items():
         out.keyval(k, v)
 
     for k, v in extra.items():
         out.keyval(k, v)
 
@@ -87,17 +85,16 @@ def format_base_json(results: Union[ReverseResults, SearchResults],
         _write_osm_id(out, result.osm_object)
 
         out.keyval('lat', f"{result.centroid.lat}")\
         _write_osm_id(out, result.osm_object)
 
         out.keyval('lat', f"{result.centroid.lat}")\
-             .keyval('lon', f"{result.centroid.lon}")\
-             .keyval(class_label, result.category[0])\
-             .keyval('type', result.category[1])\
-             .keyval('place_rank', result.rank_search)\
-             .keyval('importance', result.calculated_importance())\
-             .keyval('addresstype', cl.get_label_tag(result.category, result.extratags,
-                                                     result.rank_address,
-                                                     result.country_code))\
-             .keyval('name', result.locale_name or '')\
-             .keyval('display_name', result.display_name or '')
-
+           .keyval('lon', f"{result.centroid.lon}")\
+           .keyval(class_label, result.category[0])\
+           .keyval('type', result.category[1])\
+           .keyval('place_rank', result.rank_search)\
+           .keyval('importance', result.calculated_importance())\
+           .keyval('addresstype', cl.get_label_tag(result.category, result.extratags,
+                                                   result.rank_address,
+                                                   result.country_code))\
+           .keyval('name', result.locale_name or '')\
+           .keyval('display_name', result.display_name or '')
 
         if options.get('icon_base_url', None):
             icon = cl.ICONS.get(result.category)
 
         if options.get('icon_base_url', None):
             icon = cl.ICONS.get(result.category)
@@ -117,10 +114,10 @@ def format_base_json(results: Union[ReverseResults, SearchResults],
 
         bbox = cl.bbox_from_result(result)
         out.key('boundingbox').start_array()\
 
         bbox = cl.bbox_from_result(result)
         out.key('boundingbox').start_array()\
-             .value(f"{bbox.minlat:0.7f}").next()\
-             .value(f"{bbox.maxlat:0.7f}").next()\
-             .value(f"{bbox.minlon:0.7f}").next()\
-             .value(f"{bbox.maxlon:0.7f}").next()\
+           .value(f"{bbox.minlat:0.7f}").next()\
+           .value(f"{bbox.maxlat:0.7f}").next()\
+           .value(f"{bbox.minlon:0.7f}").next()\
+           .value(f"{bbox.maxlon:0.7f}").next()\
            .end_array().next()
 
         if result.geometry:
            .end_array().next()
 
         if result.geometry:
@@ -153,9 +150,9 @@ def format_base_geojson(results: Union[ReverseResults, SearchResults],
     out = JsonWriter()
 
     out.start_object()\
     out = JsonWriter()
 
     out.start_object()\
-         .keyval('type', 'FeatureCollection')\
-         .keyval('licence', cl.OSM_ATTRIBUTION)\
-         .key('features').start_array()
+       .keyval('type', 'FeatureCollection')\
+       .keyval('licence', cl.OSM_ATTRIBUTION)\
+       .key('features').start_array()
 
     for result in results:
         out.start_object()\
 
     for result in results:
         out.start_object()\
@@ -187,7 +184,7 @@ def format_base_geojson(results: Union[ReverseResults, SearchResults],
         if options.get('namedetails', False):
             out.keyval('namedetails', result.names)
 
         if options.get('namedetails', False):
             out.keyval('namedetails', result.names)
 
-        out.end_object().next() # properties
+        out.end_object().next()  # properties
 
         out.key('bbox').start_array()
         for coord in cl.bbox_from_result(result).coords:
 
         out.key('bbox').start_array()
         for coord in cl.bbox_from_result(result).coords:
@@ -214,20 +211,20 @@ def format_base_geocodejson(results: Union[ReverseResults, SearchResults],
     out = JsonWriter()
 
     out.start_object()\
     out = JsonWriter()
 
     out.start_object()\
-         .keyval('type', 'FeatureCollection')\
-         .key('geocoding').start_object()\
-           .keyval('version', '0.1.0')\
-           .keyval('attribution', cl.OSM_ATTRIBUTION)\
-           .keyval('licence', 'ODbL')\
-           .keyval_not_none('query', options.get('query'))\
-           .end_object().next()\
-         .key('features').start_array()
+       .keyval('type', 'FeatureCollection')\
+       .key('geocoding').start_object()\
+                        .keyval('version', '0.1.0')\
+                        .keyval('attribution', cl.OSM_ATTRIBUTION)\
+                        .keyval('licence', 'ODbL')\
+                        .keyval_not_none('query', options.get('query'))\
+                        .end_object().next()\
+       .key('features').start_array()
 
     for result in results:
         out.start_object()\
              .keyval('type', 'Feature')\
              .key('properties').start_object()\
 
     for result in results:
         out.start_object()\
              .keyval('type', 'Feature')\
              .key('properties').start_object()\
-               .key('geocoding').start_object()
+                               .key('geocoding').start_object()
 
         out.keyval_not_none('place_id', result.place_id)
 
 
         out.keyval_not_none('place_id', result.place_id)
 
index aafaec35ab9502e3686a51274e3896d62f1fd88e..b3f0e562271c023e65ead3f786d873519f6a4ff3 100644 (file)
@@ -15,7 +15,6 @@ from ..results import AddressLines, ReverseResult, ReverseResults, \
                       SearchResult, SearchResults
 from . import classtypes as cl
 
                       SearchResult, SearchResults
 from . import classtypes as cl
 
-#pylint: disable=too-many-branches
 
 def _write_xml_address(root: ET.Element, address: AddressLines,
                        country_code: Optional[str]) -> None:
 
 def _write_xml_address(root: ET.Element, address: AddressLines,
                        country_code: Optional[str]) -> None:
@@ -30,7 +29,7 @@ def _write_xml_address(root: ET.Element, address: AddressLines,
             if line.names and 'ISO3166-2' in line.names and line.admin_level:
                 parts[f"ISO3166-2-lvl{line.admin_level}"] = line.names['ISO3166-2']
 
             if line.names and 'ISO3166-2' in line.names and line.admin_level:
                 parts[f"ISO3166-2-lvl{line.admin_level}"] = line.names['ISO3166-2']
 
-    for k,v in parts.items():
+    for k, v in parts.items():
         ET.SubElement(root, k).text = v
 
     if country_code:
         ET.SubElement(root, k).text = v
 
     if country_code:
@@ -120,7 +119,7 @@ def format_base_xml(results: Union[ReverseResults, SearchResults],
         if options.get('namedetails', False):
             eroot = ET.SubElement(root if simple else place, 'namedetails')
             if result.names:
         if options.get('namedetails', False):
             eroot = ET.SubElement(root if simple else place, 'namedetails')
             if result.names:
-                for k,v in result.names.items():
+                for k, v in result.names.items():
                     ET.SubElement(eroot, 'name', attrib={'desc': k}).text = v
 
     return '<?xml version="1.0" encoding="UTF-8" ?>\n' + ET.tostring(root, encoding='unicode')
                     ET.SubElement(eroot, 'name', attrib={'desc': k}).text = v
 
     return '<?xml version="1.0" encoding="UTF-8" ?>\n' + ET.tostring(root, encoding='unicode')
index 4e1e4e5577d38ebf067b69d4ed1b83bf4809aa2e..2c6ddc99943b570bbb82126defedf5e10597b131 100644 (file)
@@ -15,6 +15,7 @@ import re
 from ..results import SearchResult, SearchResults, SourceTable
 from ..types import SearchDetails, GeometryFormat
 
 from ..results import SearchResult, SearchResults, SourceTable
 from ..types import SearchDetails, GeometryFormat
 
+
 REVERSE_MAX_RANKS = [2, 2, 2,   # 0-2   Continent/Sea
                      4, 4,      # 3-4   Country
                      8,         # 5     State
 REVERSE_MAX_RANKS = [2, 2, 2,   # 0-2   Continent/Sea
                      4, 4,      # 3-4   Country
                      8,         # 5     State
@@ -28,7 +29,7 @@ REVERSE_MAX_RANKS = [2, 2, 2,   # 0-2   Continent/Sea
                      26,        # 16    Major Streets
                      27,        # 17    Minor Streets
                      30         # 18    Building
                      26,        # 16    Major Streets
                      27,        # 17    Minor Streets
                      30         # 18    Building
-                    ]
+                     ]
 
 
 def zoom_to_rank(zoom: int) -> int:
 
 
 def zoom_to_rank(zoom: int) -> int:
@@ -52,7 +53,6 @@ def feature_type_to_rank(feature_type: Optional[str]) -> Tuple[int, int]:
     return FEATURE_TYPE_TO_RANK.get(feature_type, (0, 30))
 
 
     return FEATURE_TYPE_TO_RANK.get(feature_type, (0, 30))
 
 
-#pylint: disable=too-many-arguments,too-many-branches
 def extend_query_parts(queryparts: Dict[str, Any], details: Dict[str, Any],
                        feature_type: Optional[str],
                        namedetails: bool, extratags: bool,
 def extend_query_parts(queryparts: Dict[str, Any], details: Dict[str, Any],
                        feature_type: Optional[str],
                        namedetails: bool, extratags: bool,
@@ -135,15 +135,18 @@ def _is_postcode_relation_for(result: SearchResult, postcode: str) -> bool:
            and result.names.get('ref') == postcode
 
 
            and result.names.get('ref') == postcode
 
 
-def _deg(axis:str) -> str:
+def _deg(axis: str) -> str:
     return f"(?P<{axis}_deg>\\d+\\.\\d+)°?"
 
     return f"(?P<{axis}_deg>\\d+\\.\\d+)°?"
 
+
 def _deg_min(axis: str) -> str:
     return f"(?P<{axis}_deg>\\d+)[°\\s]+(?P<{axis}_min>[\\d.]+)[′']*"
 
 def _deg_min(axis: str) -> str:
     return f"(?P<{axis}_deg>\\d+)[°\\s]+(?P<{axis}_min>[\\d.]+)[′']*"
 
+
 def _deg_min_sec(axis: str) -> str:
     return f"(?P<{axis}_deg>\\d+)[°\\s]+(?P<{axis}_min>\\d+)[′'\\s]+(?P<{axis}_sec>[\\d.]+)[\"″]*"
 
 def _deg_min_sec(axis: str) -> str:
     return f"(?P<{axis}_deg>\\d+)[°\\s]+(?P<{axis}_min>\\d+)[′'\\s]+(?P<{axis}_sec>[\\d.]+)[\"″]*"
 
+
 COORD_REGEX = [re.compile(r'(?:(?P<pre>.*?)\s+)??' + r + r'(?:\s+(?P<post>.*))?') for r in (
     r"(?P<ns>[NS])\s*" + _deg('lat') + r"[\s,]+" + r"(?P<ew>[EW])\s*" + _deg('lon'),
     _deg('lat') + r"\s*(?P<ns>[NS])[\s,]+" + _deg('lon') + r"\s*(?P<ew>[EW])",
 COORD_REGEX = [re.compile(r'(?:(?P<pre>.*?)\s+)??' + r + r'(?:\s+(?P<post>.*))?') for r in (
     r"(?P<ns>[NS])\s*" + _deg('lat') + r"[\s,]+" + r"(?P<ew>[EW])\s*" + _deg('lon'),
     _deg('lat') + r"\s*(?P<ns>[NS])[\s,]+" + _deg('lon') + r"\s*(?P<ew>[EW])",
@@ -154,6 +157,7 @@ COORD_REGEX = [re.compile(r'(?:(?P<pre>.*?)\s+)??' + r + r'(?:\s+(?P<post>.*))?'
     r"\[?(?P<lat_deg>[+-]?\d+\.\d+)[\s,]+(?P<lon_deg>[+-]?\d+\.\d+)\]?"
 )]
 
     r"\[?(?P<lat_deg>[+-]?\d+\.\d+)[\s,]+(?P<lon_deg>[+-]?\d+\.\d+)\]?"
 )]
 
+
 def extract_coords_from_query(query: str) -> Tuple[str, Optional[float], Optional[float]]:
     """ Look for something that is formatted like a coordinate at the
         beginning or end of the query. If found, extract the coordinate and
 def extract_coords_from_query(query: str) -> Tuple[str, Optional[float], Optional[float]]:
     """ Look for something that is formatted like a coordinate at the
         beginning or end of the query. If found, extract the coordinate and
@@ -185,6 +189,7 @@ def extract_coords_from_query(query: str) -> Tuple[str, Optional[float], Optiona
 
 CATEGORY_REGEX = re.compile(r'(?P<pre>.*?)\[(?P<cls>[a-zA-Z_]+)=(?P<typ>[a-zA-Z_]+)\](?P<post>.*)')
 
 
 CATEGORY_REGEX = re.compile(r'(?P<pre>.*?)\[(?P<cls>[a-zA-Z_]+)=(?P<typ>[a-zA-Z_]+)\](?P<post>.*)')
 
+
 def extract_category_from_query(query: str) -> Tuple[str, Optional[str], Optional[str]]:
     """ Extract a hidden category specification of the form '[key=value]' from
         the query. If found, extract key and value  and
 def extract_category_from_query(query: str) -> Tuple[str, Optional[str], Optional[str]]:
     """ Extract a hidden category specification of the form '[key=value]' from
         the query. If found, extract key and value  and
index a9d30842fb960e2ec85ad3adbcbf97fd7a552817..ee502d8b6382c62f1cea5dabd7fdcb21df874def 100644 (file)
@@ -27,6 +27,7 @@ from . import helpers
 from ..server import content_types as ct
 from ..server.asgi_adaptor import ASGIAdaptor
 
 from ..server import content_types as ct
 from ..server.asgi_adaptor import ASGIAdaptor
 
+
 def build_response(adaptor: ASGIAdaptor, output: str, status: int = 200,
                    num_results: int = 0) -> Any:
     """ Create a response from the given output. Wraps a JSONP function
 def build_response(adaptor: ASGIAdaptor, output: str, status: int = 200,
                    num_results: int = 0) -> Any:
     """ Create a response from the given output. Wraps a JSONP function
@@ -47,8 +48,8 @@ def get_accepted_languages(adaptor: ASGIAdaptor) -> str:
     """ Return the accepted languages.
     """
     return adaptor.get('accept-language')\
     """ Return the accepted languages.
     """
     return adaptor.get('accept-language')\
-           or adaptor.get_header('accept-language')\
-           or adaptor.config().DEFAULT_LANGUAGE
+        or adaptor.get_header('accept-language')\
+        or adaptor.config().DEFAULT_LANGUAGE
 
 
 def setup_debugging(adaptor: ASGIAdaptor) -> bool:
 
 
 def setup_debugging(adaptor: ASGIAdaptor) -> bool:
@@ -88,7 +89,7 @@ def parse_format(adaptor: ASGIAdaptor, result_type: Type[Any], default: str) ->
 
     if not formatting.supports_format(result_type, fmt):
         adaptor.raise_error("Parameter 'format' must be one of: " +
 
     if not formatting.supports_format(result_type, fmt):
         adaptor.raise_error("Parameter 'format' must be one of: " +
-                          ', '.join(formatting.list_formats(result_type)))
+                            ', '.join(formatting.list_formats(result_type)))
 
     adaptor.content_type = formatting.get_content_type(fmt)
     return fmt
 
     adaptor.content_type = formatting.get_content_type(fmt)
     return fmt
@@ -119,7 +120,7 @@ def parse_geometry_details(adaptor: ASGIAdaptor, fmt: str) -> Dict[str, Any]:
     return {'address_details': True,
             'geometry_simplification': adaptor.get_float('polygon_threshold', 0.0),
             'geometry_output': output
     return {'address_details': True,
             'geometry_simplification': adaptor.get_float('polygon_threshold', 0.0),
             'geometry_output': output
-           }
+            }
 
 
 async def status_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
 
 
 async def status_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
@@ -135,7 +136,7 @@ async def status_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
         status_code = 200
 
     return build_response(params, params.formatting().format_result(result, fmt, {}),
         status_code = 200
 
     return build_response(params, params.formatting().format_result(result, fmt, {}),
-                                 status=status_code)
+                          status=status_code)
 
 
 async def details_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
 
 
 async def details_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
@@ -161,11 +162,11 @@ async def details_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
                                linked_places=params.get_bool('linkedplaces', True),
                                parented_places=params.get_bool('hierarchy', False),
                                keywords=params.get_bool('keywords', False),
                                linked_places=params.get_bool('linkedplaces', True),
                                parented_places=params.get_bool('hierarchy', False),
                                keywords=params.get_bool('keywords', False),
-                               geometry_output = GeometryFormat.GEOJSON
-                                                 if params.get_bool('polygon_geojson', False)
-                                                 else GeometryFormat.NONE,
+                               geometry_output=(GeometryFormat.GEOJSON
+                                                if params.get_bool('polygon_geojson', False)
+                                                else GeometryFormat.NONE),
                                locales=locales
                                locales=locales
-                              )
+                               )
 
     if debug:
         return build_response(params, loglib.get_and_disable())
 
     if debug:
         return build_response(params, loglib.get_and_disable())
@@ -173,10 +174,11 @@ async def details_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
     if result is None:
         params.raise_error('No place with that OSM ID found.', status=404)
 
     if result is None:
         params.raise_error('No place with that OSM ID found.', status=404)
 
-    output = params.formatting().format_result(result, fmt,
-                 {'locales': locales,
-                  'group_hierarchy': params.get_bool('group_hierarchy', False),
-                  'icon_base_url': params.config().MAPICON_URL})
+    output = params.formatting().format_result(
+        result, fmt,
+        {'locales': locales,
+         'group_hierarchy': params.get_bool('group_hierarchy', False),
+         'icon_base_url': params.config().MAPICON_URL})
 
     return build_response(params, output, num_results=1)
 
 
     return build_response(params, output, num_results=1)
 
@@ -253,7 +255,7 @@ async def lookup_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
 
 
 async def _unstructured_search(query: str, api: NominatimAPIAsync,
 
 
 async def _unstructured_search(query: str, api: NominatimAPIAsync,
-                              details: Dict[str, Any]) -> SearchResults:
+                               details: Dict[str, Any]) -> SearchResults:
     if not query:
         return SearchResults()
 
     if not query:
         return SearchResults()
 
@@ -290,15 +292,15 @@ async def search_endpoint(api: NominatimAPIAsync, params: ASGIAdaptor) -> Any:
     debug = setup_debugging(params)
     details = parse_geometry_details(params, fmt)
 
     debug = setup_debugging(params)
     details = parse_geometry_details(params, fmt)
 
-    details['countries']  = params.get('countrycodes', None)
+    details['countries'] = params.get('countrycodes', None)
     details['excluded'] = params.get('exclude_place_ids', None)
     details['viewbox'] = params.get('viewbox', None) or params.get('viewboxlbrt', None)
     details['bounded_viewbox'] = params.get_bool('bounded', False)
     details['dedupe'] = params.get_bool('dedupe', True)
 
     max_results = max(1, min(50, params.get_int('limit', 10)))
     details['excluded'] = params.get('exclude_place_ids', None)
     details['viewbox'] = params.get('viewbox', None) or params.get('viewboxlbrt', None)
     details['bounded_viewbox'] = params.get_bool('bounded', False)
     details['dedupe'] = params.get_bool('dedupe', True)
 
     max_results = max(1, min(50, params.get_int('limit', 10)))
-    details['max_results'] = max_results + min(10, max_results) \
-                             if details['dedupe'] else max_results
+    details['max_results'] = (max_results + min(10, max_results)
+                              if details['dedupe'] else max_results)
 
     details['min_rank'], details['max_rank'] = \
         helpers.feature_type_to_rank(params.get('featureType', ''))
 
     details['min_rank'], details['max_rank'] = \
         helpers.feature_type_to_rank(params.get('featureType', ''))
index 8d8a07f7ab2a61d201a83999744b468dee424ee9..f5f74208d3c7ba64eb01d5ed367e17738d6d63db 100644 (file)
@@ -25,6 +25,7 @@ from .clicmd.args import NominatimArgs, Subcommand
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 class CommandlineParser:
     """ Wraps some of the common functions for parsing the command line
         and setting up subcommands.
 class CommandlineParser:
     """ Wraps some of the common functions for parsing the command line
         and setting up subcommands.
@@ -57,7 +58,6 @@ class CommandlineParser:
         group.add_argument('-j', '--threads', metavar='NUM', type=int,
                            help='Number of parallel threads to use')
 
         group.add_argument('-j', '--threads', metavar='NUM', type=int,
                            help='Number of parallel threads to use')
 
-
     def nominatim_version_text(self) -> str:
         """ Program name and version number as string
         """
     def nominatim_version_text(self) -> str:
         """ Program name and version number as string
         """
@@ -66,7 +66,6 @@ class CommandlineParser:
             text += f' ({version.GIT_COMMIT_HASH})'
         return text
 
             text += f' ({version.GIT_COMMIT_HASH})'
         return text
 
-
     def add_subcommand(self, name: str, cmd: Subcommand) -> None:
         """ Add a subcommand to the parser. The subcommand must be a class
             with a function add_args() that adds the parameters for the
     def add_subcommand(self, name: str, cmd: Subcommand) -> None:
         """ Add a subcommand to the parser. The subcommand must be a class
             with a function add_args() that adds the parameters for the
@@ -82,7 +81,6 @@ class CommandlineParser:
         parser.set_defaults(command=cmd)
         cmd.add_args(parser)
 
         parser.set_defaults(command=cmd)
         cmd.add_args(parser)
 
-
     def run(self, **kwargs: Any) -> int:
         """ Parse the command line arguments of the program and execute the
             appropriate subcommand.
     def run(self, **kwargs: Any) -> int:
         """ Parse the command line arguments of the program and execute the
             appropriate subcommand.
@@ -122,7 +120,7 @@ class CommandlineParser:
             return ret
         except UsageError as exception:
             if log.isEnabledFor(logging.DEBUG):
             return ret
         except UsageError as exception:
             if log.isEnabledFor(logging.DEBUG):
-                raise # use Python's exception printing
+                raise  # use Python's exception printing
             log.fatal('FATAL: %s', exception)
 
         # If we get here, then execution has failed in some way.
             log.fatal('FATAL: %s', exception)
 
         # If we get here, then execution has failed in some way.
@@ -139,7 +137,6 @@ class CommandlineParser:
 # a subcommand.
 #
 # No need to document the functions each time.
 # a subcommand.
 #
 # No need to document the functions each time.
-# pylint: disable=C0111
 class AdminServe:
     """\
     Start a simple web server for serving the API.
 class AdminServe:
     """\
     Start a simple web server for serving the API.
@@ -164,15 +161,13 @@ class AdminServe:
                            choices=('falcon', 'starlette'),
                            help='Webserver framework to run. (default: falcon)')
 
                            choices=('falcon', 'starlette'),
                            help='Webserver framework to run. (default: falcon)')
 
-
     def run(self, args: NominatimArgs) -> int:
         asyncio.run(self.run_uvicorn(args))
 
         return 0
 
     def run(self, args: NominatimArgs) -> int:
         asyncio.run(self.run_uvicorn(args))
 
         return 0
 
-
     async def run_uvicorn(self, args: NominatimArgs) -> None:
     async def run_uvicorn(self, args: NominatimArgs) -> None:
-        import uvicorn # pylint: disable=import-outside-toplevel
+        import uvicorn
 
         server_info = args.server.split(':', 1)
         host = server_info[0]
 
         server_info = args.server.split(':', 1)
         host = server_info[0]
@@ -226,7 +221,7 @@ def get_set_parser() -> CommandlineParser:
         parser.add_subcommand('details', apicmd.APIDetails())
         parser.add_subcommand('status', apicmd.APIStatus())
     except ModuleNotFoundError as ex:
         parser.add_subcommand('details', apicmd.APIDetails())
         parser.add_subcommand('status', apicmd.APIStatus())
     except ModuleNotFoundError as ex:
-        if not ex.name or 'nominatim_api' not in ex.name: # pylint: disable=E1135
+        if not ex.name or 'nominatim_api' not in ex.name:
             raise ex
 
         parser.parser.epilog = \
             raise ex
 
         parser.parser.epilog = \
@@ -235,7 +230,6 @@ def get_set_parser() -> CommandlineParser:
             '\n    export, convert, serve, search, reverse, lookup, details, status'\
             "\n\nRun 'pip install nominatim-api' to install the package."
 
             '\n    export, convert, serve, search, reverse, lookup, details, status'\
             "\n\nRun 'pip install nominatim-api' to install the package."
 
-
     return parser
 
 
     return parser
 
 
index e2058b74099e4ad69a26945341c6eb35815eeded..580740f1897d8e64c4f6f8598f281816850b2159 100644 (file)
@@ -18,13 +18,10 @@ from .args import NominatimArgs
 from ..db.connection import connect
 from ..tools.freeze import is_frozen
 
 from ..db.connection import connect
 from ..tools.freeze import is_frozen
 
-# Do not repeat documentation of subcommand classes.
-# pylint: disable=C0111
-# Using non-top-level imports to avoid eventually unused imports.
-# pylint: disable=E0012,C0415
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 class UpdateAddData:
     """\
     Add additional data from a file or an online source.
 class UpdateAddData:
     """\
     Add additional data from a file or an online source.
@@ -65,7 +62,6 @@ class UpdateAddData:
         group2.add_argument('--socket-timeout', dest='socket_timeout', type=int, default=60,
                             help='Set timeout for file downloads')
 
         group2.add_argument('--socket-timeout', dest='socket_timeout', type=int, default=60,
                             help='Set timeout for file downloads')
 
-
     def run(self, args: NominatimArgs) -> int:
         from ..tools import add_osm_data
 
     def run(self, args: NominatimArgs) -> int:
         from ..tools import add_osm_data
 
@@ -103,7 +99,6 @@ class UpdateAddData:
 
         return 0
 
 
         return 0
 
-
     async def _add_tiger_data(self, args: NominatimArgs) -> int:
         from ..tokenizer import factory as tokenizer_factory
         from ..tools import tiger_data
     async def _add_tiger_data(self, args: NominatimArgs) -> int:
         from ..tokenizer import factory as tokenizer_factory
         from ..tools import tiger_data
@@ -113,5 +108,5 @@ class UpdateAddData:
         tokenizer = tokenizer_factory.get_tokenizer_for_db(args.config)
         return await tiger_data.add_tiger_data(args.tiger_data,
                                                args.config,
         tokenizer = tokenizer_factory.get_tokenizer_for_db(args.config)
         return await tiger_data.add_tiger_data(args.tiger_data,
                                                args.config,
-                                               args.threads or psutil.cpu_count()  or 1,
+                                               args.threads or psutil.cpu_count() or 1,
                                                tokenizer)
                                                tokenizer)
index 1edff174dc37ad251de9d9d048736098d717d2f0..ba0b0458ab6978f52d47e6715c5598492f808bf3 100644 (file)
@@ -57,7 +57,6 @@ class AdminFuncs:
         mgroup.add_argument('--place-id', type=int,
                             help='Analyse indexing of the given Nominatim object')
 
         mgroup.add_argument('--place-id', type=int,
                             help='Analyse indexing of the given Nominatim object')
 
-
     def run(self, args: NominatimArgs) -> int:
         # pylint: disable=too-many-return-statements
         if args.warm:
     def run(self, args: NominatimArgs) -> int:
         # pylint: disable=too-many-return-statements
         if args.warm:
@@ -93,7 +92,6 @@ class AdminFuncs:
 
         return 1
 
 
         return 1
 
-
     def _warm(self, args: NominatimArgs) -> int:
         try:
             import nominatim_api as napi
     def _warm(self, args: NominatimArgs) -> int:
         try:
             import nominatim_api as napi
index 000a603296d5f7c6e95e21e288d34a62ec3639c6..a922dc89fedb3231738d1235323fc1ce1d8bbea2 100644 (file)
@@ -22,11 +22,10 @@ import nominatim_api.logging as loglib
 from ..errors import UsageError
 from .args import NominatimArgs
 
 from ..errors import UsageError
 from .args import NominatimArgs
 
-# Do not repeat documentation of subcommand classes.
-# pylint: disable=C0111
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 STRUCTURED_QUERY = (
     ('amenity', 'name and/or type of POI'),
     ('street', 'housenumber and street'),
 STRUCTURED_QUERY = (
     ('amenity', 'name and/or type of POI'),
     ('street', 'housenumber and street'),
@@ -37,6 +36,7 @@ STRUCTURED_QUERY = (
     ('postalcode', 'postcode')
 )
 
     ('postalcode', 'postcode')
 )
 
+
 EXTRADATA_PARAMS = (
     ('addressdetails', 'Include a breakdown of the address into elements'),
     ('extratags', ("Include additional information if available "
 EXTRADATA_PARAMS = (
     ('addressdetails', 'Include a breakdown of the address into elements'),
     ('extratags', ("Include additional information if available "
@@ -44,6 +44,7 @@ EXTRADATA_PARAMS = (
     ('namedetails', 'Include a list of alternative names')
 )
 
     ('namedetails', 'Include a list of alternative names')
 )
 
+
 def _add_list_format(parser: argparse.ArgumentParser) -> None:
     group = parser.add_argument_group('Other options')
     group.add_argument('--list-formats', action='store_true',
 def _add_list_format(parser: argparse.ArgumentParser) -> None:
     group = parser.add_argument_group('Other options')
     group.add_argument('--list-formats', action='store_true',
@@ -62,7 +63,7 @@ def _add_api_output_arguments(parser: argparse.ArgumentParser) -> None:
     group.add_argument('--polygon-output',
                        choices=['geojson', 'kml', 'svg', 'text'],
                        help='Output geometry of results as a GeoJSON, KML, SVG or WKT')
     group.add_argument('--polygon-output',
                        choices=['geojson', 'kml', 'svg', 'text'],
                        help='Output geometry of results as a GeoJSON, KML, SVG or WKT')
-    group.add_argument('--polygon-threshold', type=float, default = 0.0,
+    group.add_argument('--polygon-threshold', type=float, default=0.0,
                        metavar='TOLERANCE',
                        help=("Simplify output geometry."
                              "Parameter is difference tolerance in degrees."))
                        metavar='TOLERANCE',
                        help=("Simplify output geometry."
                              "Parameter is difference tolerance in degrees."))
@@ -173,7 +174,6 @@ class APISearch:
                            help='Do not remove duplicates from the result list')
         _add_list_format(parser)
 
                            help='Do not remove duplicates from the result list')
         _add_list_format(parser)
 
-
     def run(self, args: NominatimArgs) -> int:
         formatter = napi.load_format_dispatcher('v1', args.project_dir)
 
     def run(self, args: NominatimArgs) -> int:
         formatter = napi.load_format_dispatcher('v1', args.project_dir)
 
@@ -189,7 +189,7 @@ class APISearch:
         try:
             with napi.NominatimAPI(args.project_dir) as api:
                 params: Dict[str, Any] = {'max_results': args.limit + min(args.limit, 10),
         try:
             with napi.NominatimAPI(args.project_dir) as api:
                 params: Dict[str, Any] = {'max_results': args.limit + min(args.limit, 10),
-                                          'address_details': True, # needed for display name
+                                          'address_details': True,  # needed for display name
                                           'geometry_output': _get_geometry_output(args),
                                           'geometry_simplification': args.polygon_threshold,
                                           'countries': args.countrycodes,
                                           'geometry_output': _get_geometry_output(args),
                                           'geometry_simplification': args.polygon_threshold,
                                           'countries': args.countrycodes,
@@ -197,7 +197,7 @@ class APISearch:
                                           'viewbox': args.viewbox,
                                           'bounded_viewbox': args.bounded,
                                           'locales': _get_locales(args, api.config.DEFAULT_LANGUAGE)
                                           'viewbox': args.viewbox,
                                           'bounded_viewbox': args.bounded,
                                           'locales': _get_locales(args, api.config.DEFAULT_LANGUAGE)
-                                         }
+                                          }
 
                 if args.query:
                     results = api.search(args.query, **params)
 
                 if args.query:
                     results = api.search(args.query, **params)
@@ -253,7 +253,6 @@ class APIReverse:
         _add_api_output_arguments(parser)
         _add_list_format(parser)
 
         _add_api_output_arguments(parser)
         _add_list_format(parser)
 
-
     def run(self, args: NominatimArgs) -> int:
         formatter = napi.load_format_dispatcher('v1', args.project_dir)
 
     def run(self, args: NominatimArgs) -> int:
         formatter = napi.load_format_dispatcher('v1', args.project_dir)
 
@@ -276,7 +275,7 @@ class APIReverse:
                 result = api.reverse(napi.Point(args.lon, args.lat),
                                      max_rank=zoom_to_rank(args.zoom or 18),
                                      layers=layers,
                 result = api.reverse(napi.Point(args.lon, args.lat),
                                      max_rank=zoom_to_rank(args.zoom or 18),
                                      layers=layers,
-                                     address_details=True, # needed for display name
+                                     address_details=True,  # needed for display name
                                      geometry_output=_get_geometry_output(args),
                                      geometry_simplification=args.polygon_threshold,
                                      locales=_get_locales(args, api.config.DEFAULT_LANGUAGE))
                                      geometry_output=_get_geometry_output(args),
                                      geometry_simplification=args.polygon_threshold,
                                      locales=_get_locales(args, api.config.DEFAULT_LANGUAGE))
@@ -299,7 +298,6 @@ class APIReverse:
         return 42
 
 
         return 42
 
 
-
 class APILookup:
     """\
     Execute API lookup query.
 class APILookup:
     """\
     Execute API lookup query.
@@ -319,7 +317,6 @@ class APILookup:
         _add_api_output_arguments(parser)
         _add_list_format(parser)
 
         _add_api_output_arguments(parser)
         _add_list_format(parser)
 
-
     def run(self, args: NominatimArgs) -> int:
         formatter = napi.load_format_dispatcher('v1', args.project_dir)
 
     def run(self, args: NominatimArgs) -> int:
         formatter = napi.load_format_dispatcher('v1', args.project_dir)
 
@@ -340,7 +337,7 @@ class APILookup:
         try:
             with napi.NominatimAPI(args.project_dir) as api:
                 results = api.lookup(places,
         try:
             with napi.NominatimAPI(args.project_dir) as api:
                 results = api.lookup(places,
-                                     address_details=True, # needed for display name
+                                     address_details=True,  # needed for display name
                                      geometry_output=_get_geometry_output(args),
                                      geometry_simplification=args.polygon_threshold or 0.0,
                                      locales=_get_locales(args, api.config.DEFAULT_LANGUAGE))
                                      geometry_output=_get_geometry_output(args),
                                      geometry_simplification=args.polygon_threshold or 0.0,
                                      locales=_get_locales(args, api.config.DEFAULT_LANGUAGE))
@@ -401,7 +398,6 @@ class APIDetails:
                            help='Preferred language order for presenting search results')
         _add_list_format(parser)
 
                            help='Preferred language order for presenting search results')
         _add_list_format(parser)
 
-
     def run(self, args: NominatimArgs) -> int:
         formatter = napi.load_format_dispatcher('v1', args.project_dir)
 
     def run(self, args: NominatimArgs) -> int:
         formatter = napi.load_format_dispatcher('v1', args.project_dir)
 
@@ -421,7 +417,7 @@ class APIDetails:
             place = napi.OsmID('W', args.way, args.object_class)
         elif args.relation:
             place = napi.OsmID('R', args.relation, args.object_class)
             place = napi.OsmID('W', args.way, args.object_class)
         elif args.relation:
             place = napi.OsmID('R', args.relation, args.object_class)
-        elif  args.place_id is not None:
+        elif args.place_id is not None:
             place = napi.PlaceID(args.place_id)
         else:
             raise UsageError('One of the arguments --node/-n --way/-w '
             place = napi.PlaceID(args.place_id)
         else:
             raise UsageError('One of the arguments --node/-n --way/-w '
@@ -435,10 +431,10 @@ class APIDetails:
                                      linked_places=args.linkedplaces,
                                      parented_places=args.hierarchy,
                                      keywords=args.keywords,
                                      linked_places=args.linkedplaces,
                                      parented_places=args.hierarchy,
                                      keywords=args.keywords,
-                                     geometry_output=napi.GeometryFormat.GEOJSON
-                                                     if args.polygon_geojson
-                                                     else napi.GeometryFormat.NONE,
-                                    locales=locales)
+                                     geometry_output=(napi.GeometryFormat.GEOJSON
+                                                      if args.polygon_geojson
+                                                      else napi.GeometryFormat.NONE),
+                                     locales=locales)
         except napi.UsageError as ex:
             raise UsageError(ex) from ex
 
         except napi.UsageError as ex:
             raise UsageError(ex) from ex
 
@@ -472,7 +468,6 @@ class APIStatus:
                            help='Format of result (use --list-formats to see supported formats)')
         _add_list_format(parser)
 
                            help='Format of result (use --list-formats to see supported formats)')
         _add_list_format(parser)
 
-
     def run(self, args: NominatimArgs) -> int:
         formatter = napi.load_format_dispatcher('v1', args.project_dir)
 
     def run(self, args: NominatimArgs) -> int:
         formatter = napi.load_format_dispatcher('v1', args.project_dir)
 
index c74bca6245a40baf3b920a7311c2228d31fa043d..488ecd184adbe48f5f320659f7ec78cd93d27be2 100644 (file)
@@ -16,8 +16,10 @@ from ..errors import UsageError
 from ..config import Configuration
 from ..typing import Protocol
 
 from ..config import Configuration
 from ..typing import Protocol
 
+
 LOG = logging.getLogger()
 
 LOG = logging.getLogger()
 
+
 class Subcommand(Protocol):
     """
     Interface to be implemented by classes implementing a CLI subcommand.
 class Subcommand(Protocol):
     """
     Interface to be implemented by classes implementing a CLI subcommand.
@@ -178,7 +180,6 @@ class NominatimArgs:
     polygon_geojson: bool
     group_hierarchy: bool
 
     polygon_geojson: bool
     group_hierarchy: bool
 
-
     def osm2pgsql_options(self, default_cache: int,
                           default_threads: int) -> Dict[str, Any]:
         """ Return the standard osm2pgsql options that can be derived
     def osm2pgsql_options(self, default_cache: int,
                           default_threads: int) -> Dict[str, Any]:
         """ Return the standard osm2pgsql options that can be derived
@@ -196,9 +197,8 @@ class NominatimArgs:
                                      slim_index=self.config.TABLESPACE_OSM_INDEX,
                                      main_data=self.config.TABLESPACE_PLACE_DATA,
                                      main_index=self.config.TABLESPACE_PLACE_INDEX
                                      slim_index=self.config.TABLESPACE_OSM_INDEX,
                                      main_data=self.config.TABLESPACE_PLACE_DATA,
                                      main_index=self.config.TABLESPACE_PLACE_INDEX
-                                    )
-                   )
-
+                                     )
+                    )
 
     def get_osm_file_list(self) -> Optional[List[Path]]:
         """ Return the --osm-file argument as a list of Paths or None
 
     def get_osm_file_list(self) -> Optional[List[Path]]:
         """ Return the --osm-file argument as a list of Paths or None
index 1468b7829f560356736c9fe3687c133e2edb7b17..275dda3dcd7d1863c8a3421c660de5729a3dac1f 100644 (file)
@@ -15,10 +15,6 @@ from pathlib import Path
 from ..errors import UsageError
 from .args import NominatimArgs
 
 from ..errors import UsageError
 from .args import NominatimArgs
 
-# Do not repeat documentation of subcommand classes.
-# pylint: disable=C0111
-# Using non-top-level imports to avoid eventually unused imports.
-# pylint: disable=E0012,C0415
 
 class WithAction(argparse.Action):
     """ Special action that saves a list of flags, given on the command-line
 
 class WithAction(argparse.Action):
     """ Special action that saves a list of flags, given on the command-line
@@ -43,7 +39,6 @@ class WithAction(argparse.Action):
 
         super().__init__(full_option_strings, argparse.SUPPRESS, nargs=0, **kwargs)
 
 
         super().__init__(full_option_strings, argparse.SUPPRESS, nargs=0, **kwargs)
 
-
     def __call__(self, parser: argparse.ArgumentParser, namespace: argparse.Namespace,
                  values: Union[str, Sequence[Any], None],
                  option_string: Optional[str] = None) -> None:
     def __call__(self, parser: argparse.ArgumentParser, namespace: argparse.Namespace,
                  values: Union[str, Sequence[Any], None],
                  option_string: Optional[str] = None) -> None:
@@ -81,7 +76,6 @@ class ConvertDB:
         group.add_argument('--details', action=WithAction, dest_set=self.options, default=True,
                            help='Enable/disable support for details API (default: enabled)')
 
         group.add_argument('--details', action=WithAction, dest_set=self.options, default=True,
                            help='Enable/disable support for details API (default: enabled)')
 
-
     def run(self, args: NominatimArgs) -> int:
         if args.output.exists():
             raise UsageError(f"File '{args.output}' already exists. Refusing to overwrite.")
     def run(self, args: NominatimArgs) -> int:
         if args.output.exists():
             raise UsageError(f"File '{args.output}' already exists. Refusing to overwrite.")
index 93f63980b9dec111a99fd4d9c29b65b4642c0dca..c6a100b239fe54881cb25858466d264f0d731e09 100644 (file)
@@ -18,20 +18,15 @@ import nominatim_api as napi
 from nominatim_api.results import create_from_placex_row, ReverseResult, add_result_details
 from nominatim_api.types import LookupDetails
 
 from nominatim_api.results import create_from_placex_row, ReverseResult, add_result_details
 from nominatim_api.types import LookupDetails
 
-import sqlalchemy as sa # pylint: disable=C0411
+import sqlalchemy as sa
 
 from ..errors import UsageError
 from .args import NominatimArgs
 
 
 from ..errors import UsageError
 from .args import NominatimArgs
 
-# Do not repeat documentation of subcommand classes.
-# pylint: disable=C0111
-# Using non-top-level imports to avoid eventually unused imports.
-# pylint: disable=E0012,C0415
-# Needed for SQLAlchemy
-# pylint: disable=singleton-comparison
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 RANK_RANGE_MAP = {
   'country': (4, 4),
   'state': (5, 9),
 RANK_RANGE_MAP = {
   'country': (4, 4),
   'state': (5, 9),
@@ -42,6 +37,7 @@ RANK_RANGE_MAP = {
   'path': (27, 27)
 }
 
   'path': (27, 27)
 }
 
+
 RANK_TO_OUTPUT_MAP = {
     4: 'country',
     5: 'state', 6: 'state', 7: 'state', 8: 'state', 9: 'state',
 RANK_TO_OUTPUT_MAP = {
     4: 'country',
     5: 'state', 6: 'state', 7: 'state', 8: 'state', 9: 'state',
@@ -50,6 +46,7 @@ RANK_TO_OUTPUT_MAP = {
     17: 'suburb', 18: 'suburb', 19: 'suburb', 20: 'suburb', 21: 'suburb',
     26: 'street', 27: 'path'}
 
     17: 'suburb', 18: 'suburb', 19: 'suburb', 20: 'suburb', 21: 'suburb',
     26: 'street', 27: 'path'}
 
+
 class QueryExport:
     """\
     Export places as CSV file from the database.
 class QueryExport:
     """\
     Export places as CSV file from the database.
@@ -84,7 +81,6 @@ class QueryExport:
                            dest='relation',
                            help='Export only children of this OSM relation')
 
                            dest='relation',
                            help='Export only children of this OSM relation')
 
-
     def run(self, args: NominatimArgs) -> int:
         return asyncio.run(export(args))
 
     def run(self, args: NominatimArgs) -> int:
         return asyncio.run(export(args))
 
@@ -104,15 +100,15 @@ async def export(args: NominatimArgs) -> int:
             t = conn.t.placex
 
             sql = sa.select(t.c.place_id, t.c.parent_place_id,
             t = conn.t.placex
 
             sql = sa.select(t.c.place_id, t.c.parent_place_id,
-                        t.c.osm_type, t.c.osm_id, t.c.name,
-                        t.c.class_, t.c.type, t.c.admin_level,
-                        t.c.address, t.c.extratags,
-                        t.c.housenumber, t.c.postcode, t.c.country_code,
-                        t.c.importance, t.c.wikipedia, t.c.indexed_date,
-                        t.c.rank_address, t.c.rank_search,
-                        t.c.centroid)\
-                     .where(t.c.linked_place_id == None)\
-                     .where(t.c.rank_address.between(*output_range))
+                            t.c.osm_type, t.c.osm_id, t.c.name,
+                            t.c.class_, t.c.type, t.c.admin_level,
+                            t.c.address, t.c.extratags,
+                            t.c.housenumber, t.c.postcode, t.c.country_code,
+                            t.c.importance, t.c.wikipedia, t.c.indexed_date,
+                            t.c.rank_address, t.c.rank_search,
+                            t.c.centroid)\
+                    .where(t.c.linked_place_id == None)\
+                    .where(t.c.rank_address.between(*output_range))
 
             parent_place_id = await get_parent_id(conn, args.node, args.way, args.relation)
             if parent_place_id:
 
             parent_place_id = await get_parent_id(conn, args.node, args.way, args.relation)
             if parent_place_id:
@@ -159,7 +155,6 @@ async def dump_results(conn: napi.SearchConnection,
     await add_result_details(conn, results,
                              LookupDetails(address_details=True, locales=locale))
 
     await add_result_details(conn, results,
                              LookupDetails(address_details=True, locales=locale))
 
-
     for result in results:
         data = {'placeid': result.place_id,
                 'postcode': result.postcode}
     for result in results:
         data = {'placeid': result.place_id,
                 'postcode': result.postcode}
index 27562ccc81802efbecfcd75131321b7bf4fde50f..4b0b1489f54ee2db42ce5da53638aad903e86bb5 100644 (file)
@@ -12,10 +12,6 @@ import argparse
 from ..db.connection import connect
 from .args import NominatimArgs
 
 from ..db.connection import connect
 from .args import NominatimArgs
 
-# Do not repeat documentation of subcommand classes.
-# pylint: disable=C0111
-# Using non-top-level imports to avoid eventually unused imports.
-# pylint: disable=E0012,C0415
 
 class SetupFreeze:
     """\
 
 class SetupFreeze:
     """\
@@ -30,8 +26,7 @@ class SetupFreeze:
     """
 
     def add_args(self, parser: argparse.ArgumentParser) -> None:
     """
 
     def add_args(self, parser: argparse.ArgumentParser) -> None:
-        pass # No options
-
+        pass  # No options
 
     def run(self, args: NominatimArgs) -> int:
         from ..tools import freeze
 
     def run(self, args: NominatimArgs) -> int:
         from ..tools import freeze
index c0619f34db410e7ffc618a06dea12130782ff684..f1890a657a1fa6f23f3e3bc4209fc1c4a37082c5 100644 (file)
@@ -16,11 +16,6 @@ from ..db import status
 from ..db.connection import connect
 from .args import NominatimArgs
 
 from ..db.connection import connect
 from .args import NominatimArgs
 
-# Do not repeat documentation of subcommand classes.
-# pylint: disable=C0111
-# Using non-top-level imports to avoid eventually unused imports.
-# pylint: disable=E0012,C0415
-
 
 class UpdateIndex:
     """\
 
 class UpdateIndex:
     """\
@@ -43,7 +38,6 @@ class UpdateIndex:
         group.add_argument('--maxrank', '-R', type=int, metavar='RANK', default=30,
                            help='Maximum/finishing rank')
 
         group.add_argument('--maxrank', '-R', type=int, metavar='RANK', default=30,
                            help='Maximum/finishing rank')
 
-
     def run(self, args: NominatimArgs) -> int:
         asyncio.run(self._do_index(args))
 
     def run(self, args: NominatimArgs) -> int:
         asyncio.run(self._do_index(args))
 
@@ -54,7 +48,6 @@ class UpdateIndex:
 
         return 0
 
 
         return 0
 
-
     async def _do_index(self, args: NominatimArgs) -> None:
         from ..tokenizer import factory as tokenizer_factory
 
     async def _do_index(self, args: NominatimArgs) -> None:
         from ..tokenizer import factory as tokenizer_factory
 
@@ -64,7 +57,7 @@ class UpdateIndex:
         indexer = Indexer(args.config.get_libpq_dsn(), tokenizer,
                           args.threads or psutil.cpu_count() or 1)
 
         indexer = Indexer(args.config.get_libpq_dsn(), tokenizer,
                           args.threads or psutil.cpu_count() or 1)
 
-        has_pending = True # run at least once
+        has_pending = True  # run at least once
         while has_pending:
             if not args.no_boundaries:
                 await indexer.index_boundaries(args.minrank, args.maxrank)
         while has_pending:
             if not args.no_boundaries:
                 await indexer.index_boundaries(args.minrank, args.maxrank)
index 741411658e6977ee5dc4552a9f93b5b07d28d3b6..1d1977d22329320b47b1ba0552d7e55e5025d283 100644 (file)
@@ -18,13 +18,10 @@ from ..db.connection import connect, table_exists
 from ..tokenizer.base import AbstractTokenizer
 from .args import NominatimArgs
 
 from ..tokenizer.base import AbstractTokenizer
 from .args import NominatimArgs
 
-# Do not repeat documentation of subcommand classes.
-# pylint: disable=C0111
-# Using non-top-level imports to avoid eventually unused imports.
-# pylint: disable=E0012,C0415
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 def _parse_osm_object(obj: str) -> Tuple[str, int]:
     """ Parse the given argument into a tuple of OSM type and ID.
         Raises an ArgumentError if the format is not recognized.
 def _parse_osm_object(obj: str) -> Tuple[str, int]:
     """ Parse the given argument into a tuple of OSM type and ID.
         Raises an ArgumentError if the format is not recognized.
@@ -86,8 +83,7 @@ class UpdateRefresh:
         group.add_argument('--enable-debug-statements', action='store_true',
                            help='Enable debug warning statements in functions')
 
         group.add_argument('--enable-debug-statements', action='store_true',
                            help='Enable debug warning statements in functions')
 
-
-    def run(self, args: NominatimArgs) -> int: #pylint: disable=too-many-branches, too-many-statements
+    def run(self, args: NominatimArgs) -> int:
         from ..tools import refresh, postcodes
         from ..indexer.indexer import Indexer
 
         from ..tools import refresh, postcodes
         from ..indexer.indexer import Indexer
 
@@ -131,7 +127,7 @@ class UpdateRefresh:
 
             LOG.warning('Import secondary importance raster data from %s', args.project_dir)
             if refresh.import_secondary_importance(args.config.get_libpq_dsn(),
 
             LOG.warning('Import secondary importance raster data from %s', args.project_dir)
             if refresh.import_secondary_importance(args.config.get_libpq_dsn(),
-                                                args.project_dir) > 0:
+                                                   args.project_dir) > 0:
                 LOG.fatal('FATAL: Cannot update secondary importance raster data')
                 return 1
             need_function_refresh = True
                 LOG.fatal('FATAL: Cannot update secondary importance raster data')
                 return 1
             need_function_refresh = True
@@ -173,7 +169,6 @@ class UpdateRefresh:
 
         return 0
 
 
         return 0
 
-
     def _get_tokenizer(self, config: Configuration) -> AbstractTokenizer:
         if self.tokenizer is None:
             from ..tokenizer import factory as tokenizer_factory
     def _get_tokenizer(self, config: Configuration) -> AbstractTokenizer:
         if self.tokenizer is None:
             from ..tokenizer import factory as tokenizer_factory
index ba4c7730b44a6ef6782bd651a25b53abb56748fa..ec85cc8bc682143704bdbdf47da34b28bc7a06fc 100644 (file)
@@ -22,10 +22,6 @@ from .args import NominatimArgs
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
-# Do not repeat documentation of subcommand classes.
-# pylint: disable=C0111
-# Using non-top-level imports to make pyosmium optional for replication only.
-# pylint: disable=C0415
 
 class UpdateReplication:
     """\
 
 class UpdateReplication:
     """\
@@ -71,7 +67,6 @@ class UpdateReplication:
         group.add_argument('--socket-timeout', dest='socket_timeout', type=int, default=60,
                            help='Set timeout for file downloads')
 
         group.add_argument('--socket-timeout', dest='socket_timeout', type=int, default=60,
                            help='Set timeout for file downloads')
 
-
     def _init_replication(self, args: NominatimArgs) -> int:
         from ..tools import replication, refresh
 
     def _init_replication(self, args: NominatimArgs) -> int:
         from ..tools import replication, refresh
 
@@ -84,7 +79,6 @@ class UpdateReplication:
                 refresh.create_functions(conn, args.config, True, False)
         return 0
 
                 refresh.create_functions(conn, args.config, True, False)
         return 0
 
-
     def _check_for_updates(self, args: NominatimArgs) -> int:
         from ..tools import replication
 
     def _check_for_updates(self, args: NominatimArgs) -> int:
         from ..tools import replication
 
@@ -92,7 +86,6 @@ class UpdateReplication:
             return replication.check_for_updates(conn, base_url=args.config.REPLICATION_URL,
                                                  socket_timeout=args.socket_timeout)
 
             return replication.check_for_updates(conn, base_url=args.config.REPLICATION_URL,
                                                  socket_timeout=args.socket_timeout)
 
-
     def _report_update(self, batchdate: dt.datetime,
                        start_import: dt.datetime,
                        start_index: Optional[dt.datetime]) -> None:
     def _report_update(self, batchdate: dt.datetime,
                        start_import: dt.datetime,
                        start_index: Optional[dt.datetime]) -> None:
@@ -106,7 +99,6 @@ class UpdateReplication:
                     round_time(end - start_import),
                     round_time(end - batchdate))
 
                     round_time(end - start_import),
                     round_time(end - batchdate))
 
-
     def _compute_update_interval(self, args: NominatimArgs) -> int:
         if args.catch_up:
             return 0
     def _compute_update_interval(self, args: NominatimArgs) -> int:
         if args.catch_up:
             return 0
@@ -123,7 +115,6 @@ class UpdateReplication:
 
         return update_interval
 
 
         return update_interval
 
-
     async def _update(self, args: NominatimArgs) -> None:
         # pylint: disable=too-many-locals
         from ..tools import replication
     async def _update(self, args: NominatimArgs) -> None:
         # pylint: disable=too-many-locals
         from ..tools import replication
@@ -186,7 +177,6 @@ class UpdateReplication:
                 LOG.warning("No new changes. Sleeping for %d sec.", recheck_interval)
                 time.sleep(recheck_interval)
 
                 LOG.warning("No new changes. Sleeping for %d sec.", recheck_interval)
                 time.sleep(recheck_interval)
 
-
     def run(self, args: NominatimArgs) -> int:
         socket.setdefaulttimeout(args.socket_timeout)
 
     def run(self, args: NominatimArgs) -> int:
         socket.setdefaulttimeout(args.socket_timeout)
 
index a7066ff2c4ccc29cba943d5bfea3fac760b7a7aa..39cbe65a8b931dfdebfbacd11c28e7b5699d4dde 100644 (file)
@@ -23,13 +23,10 @@ from ..tokenizer.base import AbstractTokenizer
 from ..version import NOMINATIM_VERSION
 from .args import NominatimArgs
 
 from ..version import NOMINATIM_VERSION
 from .args import NominatimArgs
 
-# Do not repeat documentation of subcommand classes.
-# pylint: disable=C0111
-# Using non-top-level imports to avoid eventually unused imports.
-# pylint: disable=C0415
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 class SetupAll:
     """\
     Create a new Nominatim database from an OSM file.
 class SetupAll:
     """\
     Create a new Nominatim database from an OSM file.
@@ -42,36 +39,35 @@ class SetupAll:
     def add_args(self, parser: argparse.ArgumentParser) -> None:
         group1 = parser.add_argument_group('Required arguments')
         group1.add_argument('--osm-file', metavar='FILE', action='append',
     def add_args(self, parser: argparse.ArgumentParser) -> None:
         group1 = parser.add_argument_group('Required arguments')
         group1.add_argument('--osm-file', metavar='FILE', action='append',
-                           help='OSM file to be imported'
-                                ' (repeat for importing multiple files)',
-                                default=None)
+                            help='OSM file to be imported'
+                                 ' (repeat for importing multiple files)',
+                            default=None)
         group1.add_argument('--continue', dest='continue_at',
         group1.add_argument('--continue', dest='continue_at',
-                           choices=['import-from-file', 'load-data', 'indexing', 'db-postprocess'],
-                           help='Continue an import that was interrupted',
-                           default=None)
+                            choices=['import-from-file', 'load-data', 'indexing', 'db-postprocess'],
+                            help='Continue an import that was interrupted',
+                            default=None)
         group2 = parser.add_argument_group('Optional arguments')
         group2.add_argument('--osm2pgsql-cache', metavar='SIZE', type=int,
         group2 = parser.add_argument_group('Optional arguments')
         group2.add_argument('--osm2pgsql-cache', metavar='SIZE', type=int,
-                           help='Size of cache to be used by osm2pgsql (in MB)')
+                            help='Size of cache to be used by osm2pgsql (in MB)')
         group2.add_argument('--reverse-only', action='store_true',
         group2.add_argument('--reverse-only', action='store_true',
-                           help='Do not create tables and indexes for searching')
+                            help='Do not create tables and indexes for searching')
         group2.add_argument('--no-partitions', action='store_true',
         group2.add_argument('--no-partitions', action='store_true',
-                           help=("Do not partition search indices "
-                                 "(speeds up import of single country extracts)"))
+                            help="Do not partition search indices "
+                                 "(speeds up import of single country extracts)")
         group2.add_argument('--no-updates', action='store_true',
         group2.add_argument('--no-updates', action='store_true',
-                           help="Do not keep tables that are only needed for "
-                                "updating the database later")
+                            help="Do not keep tables that are only needed for "
+                                 "updating the database later")
         group2.add_argument('--offline', action='store_true',
                             help="Do not attempt to load any additional data from the internet")
         group3 = parser.add_argument_group('Expert options')
         group3.add_argument('--ignore-errors', action='store_true',
         group2.add_argument('--offline', action='store_true',
                             help="Do not attempt to load any additional data from the internet")
         group3 = parser.add_argument_group('Expert options')
         group3.add_argument('--ignore-errors', action='store_true',
-                           help='Continue import even when errors in SQL are present')
+                            help='Continue import even when errors in SQL are present')
         group3.add_argument('--index-noanalyse', action='store_true',
         group3.add_argument('--index-noanalyse', action='store_true',
-                           help='Do not perform analyse operations during index (expert only)')
+                            help='Do not perform analyse operations during index (expert only)')
         group3.add_argument('--prepare-database', action='store_true',
                             help='Create the database but do not import any data')
 
         group3.add_argument('--prepare-database', action='store_true',
                             help='Create the database but do not import any data')
 
-
-    def run(self, args: NominatimArgs) -> int: # pylint: disable=too-many-statements, too-many-branches
+    def run(self, args: NominatimArgs) -> int:
         if args.osm_file is None and args.continue_at is None and not args.prepare_database:
             raise UsageError("No input files (use --osm-file).")
 
         if args.osm_file is None and args.continue_at is None and not args.prepare_database:
             raise UsageError("No input files (use --osm-file).")
 
@@ -85,7 +81,6 @@ class SetupAll:
 
         return asyncio.run(self.async_run(args))
 
 
         return asyncio.run(self.async_run(args))
 
-
     async def async_run(self, args: NominatimArgs) -> int:
         from ..data import country_info
         from ..tools import database_import, postcodes, freeze
     async def async_run(self, args: NominatimArgs) -> int:
         from ..data import country_info
         from ..tools import database_import, postcodes, freeze
@@ -97,7 +92,7 @@ class SetupAll:
         if args.prepare_database or args.continue_at is None:
             LOG.warning('Creating database')
             database_import.setup_database_skeleton(args.config.get_libpq_dsn(),
         if args.prepare_database or args.continue_at is None:
             LOG.warning('Creating database')
             database_import.setup_database_skeleton(args.config.get_libpq_dsn(),
-                                                        rouser=args.config.DATABASE_WEBUSER)
+                                                    rouser=args.config.DATABASE_WEBUSER)
             if args.prepare_database:
                 return 0
 
             if args.prepare_database:
                 return 0
 
@@ -120,8 +115,7 @@ class SetupAll:
             postcodes.update_postcodes(args.config.get_libpq_dsn(),
                                        args.project_dir, tokenizer)
 
             postcodes.update_postcodes(args.config.get_libpq_dsn(),
                                        args.project_dir, tokenizer)
 
-        if args.continue_at in \
-            ('import-from-file', 'load-data', 'indexing', None):
+        if args.continue_at in ('import-from-file', 'load-data', 'indexing', None):
             LOG.warning('Indexing places')
             indexer = Indexer(args.config.get_libpq_dsn(), tokenizer, num_threads)
             await indexer.index_full(analyse=not args.index_noanalyse)
             LOG.warning('Indexing places')
             indexer = Indexer(args.config.get_libpq_dsn(), tokenizer, num_threads)
             await indexer.index_full(analyse=not args.index_noanalyse)
@@ -145,7 +139,6 @@ class SetupAll:
 
         return 0
 
 
         return 0
 
-
     def _base_import(self, args: NominatimArgs) -> None:
         from ..tools import database_import, refresh
         from ..data import country_info
     def _base_import(self, args: NominatimArgs) -> None:
         from ..tools import database_import, refresh
         from ..data import country_info
@@ -159,8 +152,8 @@ class SetupAll:
             database_import.check_existing_database_plugins(args.config.get_libpq_dsn())
             LOG.warning('Setting up country tables')
             country_info.setup_country_tables(args.config.get_libpq_dsn(),
             database_import.check_existing_database_plugins(args.config.get_libpq_dsn())
             LOG.warning('Setting up country tables')
             country_info.setup_country_tables(args.config.get_libpq_dsn(),
-                                            args.config.lib_dir.data,
-                                            args.no_partitions)
+                                              args.config.lib_dir.data,
+                                              args.no_partitions)
 
             LOG.warning('Importing OSM data file')
             database_import.import_osm_data(files,
 
             LOG.warning('Importing OSM data file')
             database_import.import_osm_data(files,
@@ -171,20 +164,19 @@ class SetupAll:
             LOG.warning('Importing wikipedia importance data')
             data_path = Path(args.config.WIKIPEDIA_DATA_PATH or args.project_dir)
             if refresh.import_wikipedia_articles(args.config.get_libpq_dsn(),
             LOG.warning('Importing wikipedia importance data')
             data_path = Path(args.config.WIKIPEDIA_DATA_PATH or args.project_dir)
             if refresh.import_wikipedia_articles(args.config.get_libpq_dsn(),
-                                                data_path) > 0:
+                                                 data_path) > 0:
                 LOG.error('Wikipedia importance dump file not found. '
                 LOG.error('Wikipedia importance dump file not found. '
-                        'Calculating importance values of locations will not '
-                        'use Wikipedia importance data.')
+                          'Calculating importance values of locations will not '
+                          'use Wikipedia importance data.')
 
             LOG.warning('Importing secondary importance raster data')
             if refresh.import_secondary_importance(args.config.get_libpq_dsn(),
 
             LOG.warning('Importing secondary importance raster data')
             if refresh.import_secondary_importance(args.config.get_libpq_dsn(),
-                                                args.project_dir) != 0:
+                                                   args.project_dir) != 0:
                 LOG.error('Secondary importance file not imported. '
                 LOG.error('Secondary importance file not imported. '
-                        'Falling back to default ranking.')
+                          'Falling back to default ranking.')
 
             self._setup_tables(args.config, args.reverse_only)
 
 
             self._setup_tables(args.config, args.reverse_only)
 
-
     def _setup_tables(self, config: Configuration, reverse_only: bool) -> None:
         """ Set up the basic database layout: tables, indexes and functions.
         """
     def _setup_tables(self, config: Configuration, reverse_only: bool) -> None:
         """ Set up the basic database layout: tables, indexes and functions.
         """
@@ -205,7 +197,6 @@ class SetupAll:
             LOG.warning('Create functions (3rd pass)')
             refresh.create_functions(conn, config, False, False)
 
             LOG.warning('Create functions (3rd pass)')
             refresh.create_functions(conn, config, False, False)
 
-
     def _get_tokenizer(self, continue_at: Optional[str],
                        config: Configuration) -> AbstractTokenizer:
         """ Set up a new tokenizer or load an already initialised one.
     def _get_tokenizer(self, continue_at: Optional[str],
                        config: Configuration) -> AbstractTokenizer:
         """ Set up a new tokenizer or load an already initialised one.
@@ -219,7 +210,6 @@ class SetupAll:
         # just load the tokenizer
         return tokenizer_factory.get_tokenizer_for_db(config)
 
         # just load the tokenizer
         return tokenizer_factory.get_tokenizer_for_db(config)
 
-
     def _finalize_database(self, dsn: str, offline: bool) -> None:
         """ Determine the database date and set the status accordingly.
         """
     def _finalize_database(self, dsn: str, offline: bool) -> None:
         """ Determine the database date and set the status accordingly.
         """
@@ -230,5 +220,5 @@ class SetupAll:
                 dbdate = status.compute_database_date(conn, offline)
                 status.set_status(conn, dbdate)
                 LOG.info('Database is at %s.', dbdate)
                 dbdate = status.compute_database_date(conn, offline)
                 status.set_status(conn, dbdate)
                 LOG.info('Database is at %s.', dbdate)
-            except Exception as exc: # pylint: disable=broad-except
+            except Exception as exc:
                 LOG.error('Cannot determine date of database: %s', exc)
                 LOG.error('Cannot determine date of database: %s', exc)
index 660859421b28ba000a4ae977afda6bd60bd6d61b..9ba751a02a5ea5f4a1d01e49c4a5c85e9952000d 100644 (file)
@@ -18,12 +18,9 @@ from ..tools.special_phrases.sp_wiki_loader import SPWikiLoader
 from ..tools.special_phrases.sp_csv_loader import SPCsvLoader
 from .args import NominatimArgs
 
 from ..tools.special_phrases.sp_csv_loader import SPCsvLoader
 from .args import NominatimArgs
 
+
 LOG = logging.getLogger()
 
 LOG = logging.getLogger()
 
-# Do not repeat documentation of subcommand classes.
-# pylint: disable=C0111
-# Using non-top-level imports to avoid eventually unused imports.
-# pylint: disable=E0012,C0415
 
 class ImportSpecialPhrases:
     """\
 
 class ImportSpecialPhrases:
     """\
@@ -62,7 +59,6 @@ class ImportSpecialPhrases:
         group.add_argument('--no-replace', action='store_true',
                            help='Keep the old phrases and only add the new ones')
 
         group.add_argument('--no-replace', action='store_true',
                            help='Keep the old phrases and only add the new ones')
 
-
     def run(self, args: NominatimArgs) -> int:
 
         if args.import_from_wiki:
     def run(self, args: NominatimArgs) -> int:
 
         if args.import_from_wiki:
@@ -77,7 +73,6 @@ class ImportSpecialPhrases:
 
         return 0
 
 
         return 0
 
-
     def start_import(self, args: NominatimArgs, loader: SpecialPhraseLoader) -> None:
         """
             Create the SPImporter object containing the right
     def start_import(self, args: NominatimArgs, loader: SpecialPhraseLoader) -> None:
         """
             Create the SPImporter object containing the right
index b220b5c7844ab7ef20756d68c9e8e0033e47ec72..ad54ab3d3f195e42bd09449eaa58bef64194d5d9 100644 (file)
@@ -25,7 +25,8 @@ from .errors import UsageError
 from . import paths
 
 LOG = logging.getLogger()
 from . import paths
 
 LOG = logging.getLogger()
-CONFIG_CACHE : Dict[str, Any] = {}
+CONFIG_CACHE: Dict[str, Any] = {}
+
 
 def flatten_config_list(content: Any, section: str = '') -> List[Any]:
     """ Flatten YAML configuration lists that contain include sections
 
 def flatten_config_list(content: Any, section: str = '') -> List[Any]:
     """ Flatten YAML configuration lists that contain include sections
@@ -79,14 +80,12 @@ class Configuration:
         self.lib_dir = _LibDirs()
         self._private_plugins: Dict[str, object] = {}
 
         self.lib_dir = _LibDirs()
         self._private_plugins: Dict[str, object] = {}
 
-
     def set_libdirs(self, **kwargs: StrPath) -> None:
         """ Set paths to library functions and data.
         """
         for key, value in kwargs.items():
             setattr(self.lib_dir, key, None if value is None else Path(value))
 
     def set_libdirs(self, **kwargs: StrPath) -> None:
         """ Set paths to library functions and data.
         """
         for key, value in kwargs.items():
             setattr(self.lib_dir, key, None if value is None else Path(value))
 
-
     def __getattr__(self, name: str) -> str:
         name = 'NOMINATIM_' + name
 
     def __getattr__(self, name: str) -> str:
         name = 'NOMINATIM_' + name
 
@@ -95,7 +94,6 @@ class Configuration:
 
         return self._config[name] or ''
 
 
         return self._config[name] or ''
 
-
     def get_bool(self, name: str) -> bool:
         """ Return the given configuration parameter as a boolean.
 
     def get_bool(self, name: str) -> bool:
         """ Return the given configuration parameter as a boolean.
 
@@ -108,7 +106,6 @@ class Configuration:
         """
         return getattr(self, name).lower() in ('1', 'yes', 'true')
 
         """
         return getattr(self, name).lower() in ('1', 'yes', 'true')
 
-
     def get_int(self, name: str) -> int:
         """ Return the given configuration parameter as an int.
 
     def get_int(self, name: str) -> int:
         """ Return the given configuration parameter as an int.
 
@@ -128,11 +125,10 @@ class Configuration:
             LOG.fatal("Invalid setting NOMINATIM_%s. Needs to be a number.", name)
             raise UsageError("Configuration error.") from exp
 
             LOG.fatal("Invalid setting NOMINATIM_%s. Needs to be a number.", name)
             raise UsageError("Configuration error.") from exp
 
-
     def get_str_list(self, name: str) -> Optional[List[str]]:
         """ Return the given configuration parameter as a list of strings.
             The values are assumed to be given as a comma-sparated list and
     def get_str_list(self, name: str) -> Optional[List[str]]:
         """ Return the given configuration parameter as a list of strings.
             The values are assumed to be given as a comma-sparated list and
-            will be stripped before returning them. 
+            will be stripped before returning them.
 
             Parameters:
               name: Name of the configuration parameter with the NOMINATIM_
 
             Parameters:
               name: Name of the configuration parameter with the NOMINATIM_
@@ -148,7 +144,6 @@ class Configuration:
 
         return [v.strip() for v in raw.split(',')] if raw else None
 
 
         return [v.strip() for v in raw.split(',')] if raw else None
 
-
     def get_path(self, name: str) -> Optional[Path]:
         """ Return the given configuration parameter as a Path.
 
     def get_path(self, name: str) -> Optional[Path]:
         """ Return the given configuration parameter as a Path.
 
@@ -174,7 +169,6 @@ class Configuration:
 
         return cfgpath.resolve()
 
 
         return cfgpath.resolve()
 
-
     def get_libpq_dsn(self) -> str:
         """ Get configured database DSN converted into the key/value format
             understood by libpq and psycopg.
     def get_libpq_dsn(self) -> str:
         """ Get configured database DSN converted into the key/value format
             understood by libpq and psycopg.
@@ -194,7 +188,6 @@ class Configuration:
 
         return dsn
 
 
         return dsn
 
-
     def get_database_params(self) -> Mapping[str, Union[str, int, None]]:
         """ Get the configured parameters for the database connection
             as a mapping.
     def get_database_params(self) -> Mapping[str, Union[str, int, None]]:
         """ Get the configured parameters for the database connection
             as a mapping.
@@ -206,7 +199,6 @@ class Configuration:
 
         return conninfo_to_dict(dsn)
 
 
         return conninfo_to_dict(dsn)
 
-
     def get_import_style_file(self) -> Path:
         """ Return the import style file as a path object. Translates the
             name of the standard styles automatically into a file in the
     def get_import_style_file(self) -> Path:
         """ Return the import style file as a path object. Translates the
             name of the standard styles automatically into a file in the
@@ -219,7 +211,6 @@ class Configuration:
 
         return self.find_config_file('', 'IMPORT_STYLE')
 
 
         return self.find_config_file('', 'IMPORT_STYLE')
 
-
     def get_os_env(self) -> Dict[str, str]:
         """ Return a copy of the OS environment with the Nominatim configuration
             merged in.
     def get_os_env(self) -> Dict[str, str]:
         """ Return a copy of the OS environment with the Nominatim configuration
             merged in.
@@ -229,7 +220,6 @@ class Configuration:
 
         return env
 
 
         return env
 
-
     def load_sub_configuration(self, filename: StrPath,
                                config: Optional[str] = None) -> Any:
         """ Load additional configuration from a file. `filename` is the name
     def load_sub_configuration(self, filename: StrPath,
                                config: Optional[str] = None) -> Any:
         """ Load additional configuration from a file. `filename` is the name
@@ -267,7 +257,6 @@ class Configuration:
         CONFIG_CACHE[str(configfile)] = result
         return result
 
         CONFIG_CACHE[str(configfile)] = result
         return result
 
-
     def load_plugin_module(self, module_name: str, internal_path: str) -> Any:
         """ Load a Python module as a plugin.
 
     def load_plugin_module(self, module_name: str, internal_path: str) -> Any:
         """ Load a Python module as a plugin.
 
@@ -310,7 +299,6 @@ class Configuration:
 
         return sys.modules.get(module_name) or importlib.import_module(module_name)
 
 
         return sys.modules.get(module_name) or importlib.import_module(module_name)
 
-
     def find_config_file(self, filename: StrPath,
                          config: Optional[str] = None) -> Path:
         """ Resolve the location of a configuration file given a filename and
     def find_config_file(self, filename: StrPath,
                          config: Optional[str] = None) -> Path:
         """ Resolve the location of a configuration file given a filename and
@@ -334,7 +322,6 @@ class Configuration:
 
                 filename = cfg_filename
 
 
                 filename = cfg_filename
 
-
         search_paths = [self.project_dir, self.config_dir]
         for path in search_paths:
             if path is not None and (path / filename).is_file():
         search_paths = [self.project_dir, self.config_dir]
         for path in search_paths:
             if path is not None and (path / filename).is_file():
@@ -344,7 +331,6 @@ class Configuration:
                   filename, search_paths)
         raise UsageError("Config file not found.")
 
                   filename, search_paths)
         raise UsageError("Config file not found.")
 
-
     def _load_from_yaml(self, cfgfile: Path) -> Any:
         """ Load a YAML configuration file. This installs a special handler that
             allows to include other YAML files using the '!include' operator.
     def _load_from_yaml(self, cfgfile: Path) -> Any:
         """ Load a YAML configuration file. This installs a special handler that
             allows to include other YAML files using the '!include' operator.
@@ -353,7 +339,6 @@ class Configuration:
                              Loader=yaml.SafeLoader)
         return yaml.safe_load(cfgfile.read_text(encoding='utf-8'))
 
                              Loader=yaml.SafeLoader)
         return yaml.safe_load(cfgfile.read_text(encoding='utf-8'))
 
-
     def _yaml_include_representer(self, loader: Any, node: yaml.Node) -> Any:
         """ Handler for the '!include' operator in YAML files.
 
     def _yaml_include_representer(self, loader: Any, node: yaml.Node) -> Any:
         """ Handler for the '!include' operator in YAML files.
 
index 9b71405993f35f855e57465564a2b1eebd29ee9e..bc3f20f598b68155f787a7feb5bdcd3a006fa3f4 100644 (file)
@@ -16,6 +16,7 @@ from ..errors import UsageError
 from ..config import Configuration
 from ..tokenizer.base import AbstractTokenizer
 
 from ..config import Configuration
 from ..tokenizer.base import AbstractTokenizer
 
+
 def _flatten_name_list(names: Any) -> Dict[str, str]:
     if names is None:
         return {}
 def _flatten_name_list(names: Any) -> Dict[str, str]:
     if names is None:
         return {}
@@ -39,7 +40,6 @@ def _flatten_name_list(names: Any) -> Dict[str, str]:
     return flat
 
 
     return flat
 
 
-
 class _CountryInfo:
     """ Caches country-specific properties from the configuration file.
     """
 class _CountryInfo:
     """ Caches country-specific properties from the configuration file.
     """
@@ -47,7 +47,6 @@ class _CountryInfo:
     def __init__(self) -> None:
         self._info: Dict[str, Dict[str, Any]] = {}
 
     def __init__(self) -> None:
         self._info: Dict[str, Dict[str, Any]] = {}
 
-
     def load(self, config: Configuration) -> None:
         """ Load the country properties from the configuration files,
             if they are not loaded yet.
     def load(self, config: Configuration) -> None:
         """ Load the country properties from the configuration files,
             if they are not loaded yet.
@@ -63,7 +62,6 @@ class _CountryInfo:
                                          for x in prop['languages'].split(',')]
                 prop['names'] = _flatten_name_list(prop.get('names'))
 
                                          for x in prop['languages'].split(',')]
                 prop['names'] = _flatten_name_list(prop.get('names'))
 
-
     def items(self) -> Iterable[Tuple[str, Dict[str, Any]]]:
         """ Return tuples of (country_code, property dict) as iterable.
         """
     def items(self) -> Iterable[Tuple[str, Dict[str, Any]]]:
         """ Return tuples of (country_code, property dict) as iterable.
         """
@@ -75,7 +73,6 @@ class _CountryInfo:
         return self._info.get(country_code, {})
 
 
         return self._info.get(country_code, {})
 
 
-
 _COUNTRY_INFO = _CountryInfo()
 
 
 _COUNTRY_INFO = _CountryInfo()
 
 
@@ -86,14 +83,17 @@ def setup_country_config(config: Configuration) -> None:
     """
     _COUNTRY_INFO.load(config)
 
     """
     _COUNTRY_INFO.load(config)
 
+
 @overload
 def iterate() -> Iterable[Tuple[str, Dict[str, Any]]]:
     ...
 
 @overload
 def iterate() -> Iterable[Tuple[str, Dict[str, Any]]]:
     ...
 
+
 @overload
 def iterate(prop: str) -> Iterable[Tuple[str, Any]]:
     ...
 
 @overload
 def iterate(prop: str) -> Iterable[Tuple[str, Any]]:
     ...
 
+
 def iterate(prop: Optional[str] = None) -> Iterable[Tuple[str, Dict[str, Any]]]:
     """ Iterate over country code and properties.
 
 def iterate(prop: Optional[str] = None) -> Iterable[Tuple[str, Dict[str, Any]]]:
     """ Iterate over country code and properties.
 
@@ -168,7 +168,7 @@ def create_country_names(conn: Connection, tokenizer: AbstractTokenizer,
 
                 # country names (only in languages as provided)
                 if name:
 
                 # country names (only in languages as provided)
                 if name:
-                    names.update({k : v for k, v in name.items() if _include_key(k)})
+                    names.update({k: v for k, v in name.items() if _include_key(k)})
 
                 analyzer.add_country_names(code, names)
 
 
                 analyzer.add_country_names(code, names)
 
index 5b5ef57f91bccb72e031059b73797a9579b0696e..5fc6a48a6d81eea2a86c9272fe748e9fdd659be9 100644 (file)
@@ -10,6 +10,7 @@ the tokenizer.
 """
 from typing import Optional, Mapping, Any, Tuple
 
 """
 from typing import Optional, Mapping, Any, Tuple
 
+
 class PlaceInfo:
     """ This data class contains all information the tokenizer can access
         about a place.
 class PlaceInfo:
     """ This data class contains all information the tokenizer can access
         about a place.
@@ -18,7 +19,6 @@ class PlaceInfo:
     def __init__(self, info: Mapping[str, Any]) -> None:
         self._info = info
 
     def __init__(self, info: Mapping[str, Any]) -> None:
         self._info = info
 
-
     @property
     def name(self) -> Optional[Mapping[str, str]]:
         """ A dictionary with the names of the place. Keys and values represent
     @property
     def name(self) -> Optional[Mapping[str, str]]:
         """ A dictionary with the names of the place. Keys and values represent
@@ -28,7 +28,6 @@ class PlaceInfo:
         """
         return self._info.get('name')
 
         """
         return self._info.get('name')
 
-
     @property
     def address(self) -> Optional[Mapping[str, str]]:
         """ A dictionary with the address elements of the place. They key
     @property
     def address(self) -> Optional[Mapping[str, str]]:
         """ A dictionary with the address elements of the place. They key
@@ -43,7 +42,6 @@ class PlaceInfo:
         """
         return self._info.get('address')
 
         """
         return self._info.get('address')
 
-
     @property
     def country_code(self) -> Optional[str]:
         """ The country code of the country the place is in. Guaranteed
     @property
     def country_code(self) -> Optional[str]:
         """ The country code of the country the place is in. Guaranteed
@@ -52,7 +50,6 @@ class PlaceInfo:
         """
         return self._info.get('country_code')
 
         """
         return self._info.get('country_code')
 
-
     @property
     def rank_address(self) -> int:
         """ The [rank address][1] before any rank correction is applied.
     @property
     def rank_address(self) -> int:
         """ The [rank address][1] before any rank correction is applied.
@@ -61,7 +58,6 @@ class PlaceInfo:
         """
         return self._info.get('rank_address', 0)
 
         """
         return self._info.get('rank_address', 0)
 
-
     @property
     def centroid(self) -> Optional[Tuple[float, float]]:
         """ A center point of the place in WGS84. May be None when the
     @property
     def centroid(self) -> Optional[Tuple[float, float]]:
         """ A center point of the place in WGS84. May be None when the
@@ -70,17 +66,15 @@ class PlaceInfo:
         x, y = self._info.get('centroid_x'), self._info.get('centroid_y')
         return None if x is None or y is None else (x, y)
 
         x, y = self._info.get('centroid_x'), self._info.get('centroid_y')
         return None if x is None or y is None else (x, y)
 
-
     def is_a(self, key: str, value: str) -> bool:
         """ Set to True when the place's primary tag corresponds to the given
             key and value.
         """
         return self._info.get('class') == key and self._info.get('type') == value
 
     def is_a(self, key: str, value: str) -> bool:
         """ Set to True when the place's primary tag corresponds to the given
             key and value.
         """
         return self._info.get('class') == key and self._info.get('type') == value
 
-
     def is_country(self) -> bool:
         """ Set to True when the place is a valid country boundary.
         """
         return self.rank_address == 4 \
     def is_country(self) -> bool:
         """ Set to True when the place is a valid country boundary.
         """
         return self.rank_address == 4 \
-               and self.is_a('boundary', 'administrative') \
-               and self.country_code is not None
+            and self.is_a('boundary', 'administrative') \
+            and self.country_code is not None
index cb1705e9794a789d21678122f69a262df99e4067..600d31583d2d7ff157c255229cb1d931c6b400b6 100644 (file)
@@ -9,6 +9,7 @@ Data class for a single name of a place.
 """
 from typing import Optional, Dict, Mapping
 
 """
 from typing import Optional, Dict, Mapping
 
+
 class PlaceName:
     """ Each name and address part of a place is encapsulated in an object of
         this class. It saves not only the name proper but also describes the
 class PlaceName:
     """ Each name and address part of a place is encapsulated in an object of
         this class. It saves not only the name proper but also describes the
@@ -32,11 +33,9 @@ class PlaceName:
         self.suffix = suffix
         self.attr: Dict[str, str] = {}
 
         self.suffix = suffix
         self.attr: Dict[str, str] = {}
 
-
     def __repr__(self) -> str:
         return f"PlaceName(name={self.name!r},kind={self.kind!r},suffix={self.suffix!r})"
 
     def __repr__(self) -> str:
         return f"PlaceName(name={self.name!r},kind={self.kind!r},suffix={self.suffix!r})"
 
-
     def clone(self, name: Optional[str] = None,
               kind: Optional[str] = None,
               suffix: Optional[str] = None,
     def clone(self, name: Optional[str] = None,
               kind: Optional[str] = None,
               suffix: Optional[str] = None,
@@ -57,21 +56,18 @@ class PlaceName:
 
         return newobj
 
 
         return newobj
 
-
     def set_attr(self, key: str, value: str) -> None:
         """ Add the given property to the name. If the property was already
             set, then the value is overwritten.
         """
         self.attr[key] = value
 
     def set_attr(self, key: str, value: str) -> None:
         """ Add the given property to the name. If the property was already
             set, then the value is overwritten.
         """
         self.attr[key] = value
 
-
     def get_attr(self, key: str, default: Optional[str] = None) -> Optional[str]:
         """ Return the given property or the value of 'default' if it
             is not set.
         """
         return self.attr.get(key, default)
 
     def get_attr(self, key: str, default: Optional[str] = None) -> Optional[str]:
         """ Return the given property or the value of 'default' if it
             is not set.
         """
         return self.attr.get(key, default)
 
-
     def has_attr(self, key: str) -> bool:
         """ Check if the given attribute is set.
         """
     def has_attr(self, key: str) -> bool:
         """ Check if the given attribute is set.
         """
index 0d04826d944692992b84bbdde260a27a31bf168f..0e6635f94217b23e5e1e1968688381a088569956 100644 (file)
@@ -14,6 +14,7 @@ import re
 from ..errors import UsageError
 from . import country_info
 
 from ..errors import UsageError
 from . import country_info
 
+
 class CountryPostcodeMatcher:
     """ Matches and formats a postcode according to a format definition
         of the given country.
 class CountryPostcodeMatcher:
     """ Matches and formats a postcode according to a format definition
         of the given country.
@@ -30,7 +31,6 @@ class CountryPostcodeMatcher:
 
         self.output = config.get('output', r'\g<0>')
 
 
         self.output = config.get('output', r'\g<0>')
 
-
     def match(self, postcode: str) -> Optional[Match[str]]:
         """ Match the given postcode against the postcode pattern for this
             matcher. Returns a `re.Match` object if the match was successful
     def match(self, postcode: str) -> Optional[Match[str]]:
         """ Match the given postcode against the postcode pattern for this
             matcher. Returns a `re.Match` object if the match was successful
@@ -44,7 +44,6 @@ class CountryPostcodeMatcher:
 
         return None
 
 
         return None
 
-
     def normalize(self, match: Match[str]) -> str:
         """ Return the default format of the postcode for the given match.
             `match` must be a `re.Match` object previously returned by
     def normalize(self, match: Match[str]) -> str:
         """ Return the default format of the postcode for the given match.
             `match` must be a `re.Match` object previously returned by
@@ -71,14 +70,12 @@ class PostcodeFormatter:
             else:
                 raise UsageError(f"Invalid entry 'postcode' for country '{ccode}'")
 
             else:
                 raise UsageError(f"Invalid entry 'postcode' for country '{ccode}'")
 
-
     def set_default_pattern(self, pattern: str) -> None:
         """ Set the postcode match pattern to use, when a country does not
             have a specific pattern.
         """
         self.default_matcher = CountryPostcodeMatcher('', {'pattern': pattern})
 
     def set_default_pattern(self, pattern: str) -> None:
         """ Set the postcode match pattern to use, when a country does not
             have a specific pattern.
         """
         self.default_matcher = CountryPostcodeMatcher('', {'pattern': pattern})
 
-
     def get_matcher(self, country_code: Optional[str]) -> Optional[CountryPostcodeMatcher]:
         """ Return the CountryPostcodeMatcher for the given country.
             Returns None if the country doesn't have a postcode and the
     def get_matcher(self, country_code: Optional[str]) -> Optional[CountryPostcodeMatcher]:
         """ Return the CountryPostcodeMatcher for the given country.
             Returns None if the country doesn't have a postcode and the
@@ -92,7 +89,6 @@ class PostcodeFormatter:
 
         return self.country_matcher.get(country_code, self.default_matcher)
 
 
         return self.country_matcher.get(country_code, self.default_matcher)
 
-
     def match(self, country_code: Optional[str], postcode: str) -> Optional[Match[str]]:
         """ Match the given postcode against the postcode pattern for this
             matcher. Returns a `re.Match` object if the country has a pattern
     def match(self, country_code: Optional[str], postcode: str) -> Optional[Match[str]]:
         """ Match the given postcode against the postcode pattern for this
             matcher. Returns a `re.Match` object if the country has a pattern
@@ -105,7 +101,6 @@ class PostcodeFormatter:
 
         return self.country_matcher.get(country_code, self.default_matcher).match(postcode)
 
 
         return self.country_matcher.get(country_code, self.default_matcher).match(postcode)
 
-
     def normalize(self, country_code: str, match: Match[str]) -> str:
         """ Return the default format of the postcode for the given match.
             `match` must be a `re.Match` object previously returned by
     def normalize(self, country_code: str, match: Match[str]) -> str:
         """ Return the default format of the postcode for the given match.
             `match` must be a `re.Match` object previously returned by
index 6c7e843fdd34dddfdb6fdf4db9decbd00ec8b145..e960a3fa8a1186450a67b749754155975e8327b8 100644 (file)
@@ -23,6 +23,7 @@ LOG = logging.getLogger()
 Cursor = psycopg.Cursor[Any]
 Connection = psycopg.Connection[Any]
 
 Cursor = psycopg.Cursor[Any]
 Connection = psycopg.Connection[Any]
 
+
 def execute_scalar(conn: Connection, sql: psycopg.abc.Query, args: Any = None) -> Any:
     """ Execute query that returns a single value. The value is returned.
         If the query yields more than one row, a ValueError is raised.
 def execute_scalar(conn: Connection, sql: psycopg.abc.Query, args: Any = None) -> Any:
     """ Execute query that returns a single value. The value is returned.
         If the query yields more than one row, a ValueError is raised.
@@ -42,9 +43,10 @@ def execute_scalar(conn: Connection, sql: psycopg.abc.Query, args: Any = None) -
 def table_exists(conn: Connection, table: str) -> bool:
     """ Check that a table with the given name exists in the database.
     """
 def table_exists(conn: Connection, table: str) -> bool:
     """ Check that a table with the given name exists in the database.
     """
-    num = execute_scalar(conn,
-            """SELECT count(*) FROM pg_tables
-               WHERE tablename = %s and schemaname = 'public'""", (table, ))
+    num = execute_scalar(
+        conn,
+        """SELECT count(*) FROM pg_tables
+           WHERE tablename = %s and schemaname = 'public'""", (table, ))
     return num == 1 if isinstance(num, int) else False
 
 
     return num == 1 if isinstance(num, int) else False
 
 
@@ -52,9 +54,9 @@ def table_has_column(conn: Connection, table: str, column: str) -> bool:
     """ Check if the table 'table' exists and has a column with name 'column'.
     """
     has_column = execute_scalar(conn,
     """ Check if the table 'table' exists and has a column with name 'column'.
     """
     has_column = execute_scalar(conn,
-                    """SELECT count(*) FROM information_schema.columns
-                       WHERE table_name = %s and column_name = %s""",
-                    (table, column))
+                                """SELECT count(*) FROM information_schema.columns
+                                   WHERE table_name = %s and column_name = %s""",
+                                (table, column))
     return has_column > 0 if isinstance(has_column, int) else False
 
 
     return has_column > 0 if isinstance(has_column, int) else False
 
 
@@ -77,8 +79,9 @@ def index_exists(conn: Connection, index: str, table: Optional[str] = None) -> b
 
     return True
 
 
     return True
 
+
 def drop_tables(conn: Connection, *names: str,
 def drop_tables(conn: Connection, *names: str,
-               if_exists: bool = True, cascade: bool = False) -> None:
+                if_exists: bool = True, cascade: bool = False) -> None:
     """ Drop one or more tables with the given names.
         Set `if_exists` to False if a non-existent table should raise
         an exception instead of just being ignored. `cascade` will cause
     """ Drop one or more tables with the given names.
         Set `if_exists` to False if a non-existent table should raise
         an exception instead of just being ignored. `cascade` will cause
index 0e017ead900c0c2f6fa236e65d3ae927498e059b..37d9e6564810333427a0961de074f1adedf8849a 100644 (file)
@@ -11,6 +11,7 @@ from typing import Optional, cast
 
 from .connection import Connection, table_exists
 
 
 from .connection import Connection, table_exists
 
+
 def set_property(conn: Connection, name: str, value: str) -> None:
     """ Add or replace the property with the given name.
     """
 def set_property(conn: Connection, name: str, value: str) -> None:
     """ Add or replace the property with the given name.
     """
index 2828937f9f61317d07ec93981cd022b7eb6d2cae..08a920482d58f1a64dd71d3a52d904b7725e6e63 100644 (file)
@@ -18,6 +18,7 @@ LOG = logging.getLogger()
 
 QueueItem = Optional[Tuple[psycopg.abc.Query, Any]]
 
 
 QueueItem = Optional[Tuple[psycopg.abc.Query, Any]]
 
+
 class QueryPool:
     """ Pool to run SQL queries in parallel asynchronous execution.
 
 class QueryPool:
     """ Pool to run SQL queries in parallel asynchronous execution.
 
@@ -32,7 +33,6 @@ class QueryPool:
         self.pool = [asyncio.create_task(self._worker_loop(dsn, **conn_args))
                      for _ in range(pool_size)]
 
         self.pool = [asyncio.create_task(self._worker_loop(dsn, **conn_args))
                      for _ in range(pool_size)]
 
-
     async def put_query(self, query: psycopg.abc.Query, params: Any) -> None:
         """ Schedule a query for execution.
         """
     async def put_query(self, query: psycopg.abc.Query, params: Any) -> None:
         """ Schedule a query for execution.
         """
@@ -41,7 +41,6 @@ class QueryPool:
         self.wait_time += time.time() - tstart
         await asyncio.sleep(0)
 
         self.wait_time += time.time() - tstart
         await asyncio.sleep(0)
 
-
     async def finish(self) -> None:
         """ Wait for all queries to finish and close the pool.
         """
     async def finish(self) -> None:
         """ Wait for all queries to finish and close the pool.
         """
@@ -57,7 +56,6 @@ class QueryPool:
             if excp is not None:
                 raise excp
 
             if excp is not None:
                 raise excp
 
-
     async def _worker_loop(self, dsn: str, **conn_args: Any) -> None:
         conn_args['autocommit'] = True
         aconn = await psycopg.AsyncConnection.connect(dsn, **conn_args)
     async def _worker_loop(self, dsn: str, **conn_args: Any) -> None:
         conn_args['autocommit'] = True
         aconn = await psycopg.AsyncConnection.connect(dsn, **conn_args)
@@ -78,10 +76,8 @@ class QueryPool:
                                  str(item[0]), str(item[1]))
                         # item is still valid here, causing a retry
 
                                  str(item[0]), str(item[1]))
                         # item is still valid here, causing a retry
 
-
     async def __aenter__(self) -> 'QueryPool':
         return self
 
     async def __aenter__(self) -> 'QueryPool':
         return self
 
-
     async def __aexit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
         await self.finish()
     async def __aexit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
         await self.finish()
index 25faead4d7fcb75a1bd12fd866f96a82e88db76e..85dbaabc97bc582fa92a1126d812d7dc5ebe01fb 100644 (file)
@@ -15,6 +15,7 @@ from .connection import Connection, server_version_tuple, postgis_version_tuple
 from ..config import Configuration
 from ..db.query_pool import QueryPool
 
 from ..config import Configuration
 from ..db.query_pool import QueryPool
 
+
 def _get_partitions(conn: Connection) -> Set[int]:
     """ Get the set of partitions currently in use.
     """
 def _get_partitions(conn: Connection) -> Set[int]:
     """ Get the set of partitions currently in use.
     """
@@ -35,6 +36,7 @@ def _get_tables(conn: Connection) -> Set[str]:
 
         return set((row[0] for row in list(cur)))
 
 
         return set((row[0] for row in list(cur)))
 
+
 def _get_middle_db_format(conn: Connection, tables: Set[str]) -> str:
     """ Returns the version of the slim middle tables.
     """
 def _get_middle_db_format(conn: Connection, tables: Set[str]) -> str:
     """ Returns the version of the slim middle tables.
     """
@@ -73,9 +75,10 @@ def _setup_postgresql_features(conn: Connection) -> Dict[str, Any]:
     ps3 = postgis_version >= (3, 0)
     return {
         'has_index_non_key_column': pg11plus,
     ps3 = postgis_version >= (3, 0)
     return {
         'has_index_non_key_column': pg11plus,
-        'spgist_geom' : 'SPGIST' if pg11plus and ps3 else 'GIST'
+        'spgist_geom': 'SPGIST' if pg11plus and ps3 else 'GIST'
     }
 
     }
 
+
 class SQLPreprocessor:
     """ A environment for preprocessing SQL files from the
         lib-sql directory.
 class SQLPreprocessor:
     """ A environment for preprocessing SQL files from the
         lib-sql directory.
@@ -102,7 +105,6 @@ class SQLPreprocessor:
         self.env.globals['db'] = db_info
         self.env.globals['postgres'] = _setup_postgresql_features(conn)
 
         self.env.globals['db'] = db_info
         self.env.globals['postgres'] = _setup_postgresql_features(conn)
 
-
     def run_string(self, conn: Connection, template: str, **kwargs: Any) -> None:
         """ Execute the given SQL template string on the connection.
             The keyword arguments may supply additional parameters
     def run_string(self, conn: Connection, template: str, **kwargs: Any) -> None:
         """ Execute the given SQL template string on the connection.
             The keyword arguments may supply additional parameters
@@ -114,7 +116,6 @@ class SQLPreprocessor:
             cur.execute(sql)
         conn.commit()
 
             cur.execute(sql)
         conn.commit()
 
-
     def run_sql_file(self, conn: Connection, name: str, **kwargs: Any) -> None:
         """ Execute the given SQL file on the connection. The keyword arguments
             may supply additional parameters for preprocessing.
     def run_sql_file(self, conn: Connection, name: str, **kwargs: Any) -> None:
         """ Execute the given SQL file on the connection. The keyword arguments
             may supply additional parameters for preprocessing.
@@ -125,7 +126,6 @@ class SQLPreprocessor:
             cur.execute(sql)
         conn.commit()
 
             cur.execute(sql)
         conn.commit()
 
-
     async def run_parallel_sql_file(self, dsn: str, name: str, num_threads: int = 1,
                                     **kwargs: Any) -> None:
         """ Execute the given SQL files using parallel asynchronous connections.
     async def run_parallel_sql_file(self, dsn: str, name: str, num_threads: int = 1,
                                     **kwargs: Any) -> None:
         """ Execute the given SQL files using parallel asynchronous connections.
index 02e5bd2d35ed825c322d07c203e64795de308f5b..63eba72cfc5a29f26ba51a24342b066a530654f5 100644 (file)
@@ -18,6 +18,7 @@ from ..errors import UsageError
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 def _pipe_to_proc(proc: 'subprocess.Popen[bytes]',
                   fdesc: Union[IO[bytes], gzip.GzipFile]) -> int:
     assert proc.stdin is not None
 def _pipe_to_proc(proc: 'subprocess.Popen[bytes]',
                   fdesc: Union[IO[bytes], gzip.GzipFile]) -> int:
     assert proc.stdin is not None
@@ -31,6 +32,7 @@ def _pipe_to_proc(proc: 'subprocess.Popen[bytes]',
 
     return len(chunk)
 
 
     return len(chunk)
 
+
 def execute_file(dsn: str, fname: Path,
                  ignore_errors: bool = False,
                  pre_code: Optional[str] = None,
 def execute_file(dsn: str, fname: Path,
                  ignore_errors: bool = False,
                  pre_code: Optional[str] = None,
index c7331a89f7519d06f85ac34a8d4f61ad1299d6e7..98fe693d12b51dfba2865f52c7ab6181861c52ca 100644 (file)
@@ -8,6 +8,7 @@
 Custom exception and error classes for Nominatim.
 """
 
 Custom exception and error classes for Nominatim.
 """
 
+
 class UsageError(Exception):
     """ An error raised because of bad user input. This error will usually
         not cause a stack trace to be printed unless debugging is enabled.
 class UsageError(Exception):
     """ An error raised because of bad user input. This error will usually
         not cause a stack trace to be printed unless debugging is enabled.
index 9d42922b8e4f09372bc395dbcf209b41e7890030..d467efbd6e27b7dbaa207ee042d2ea3ac2cadcf9 100644 (file)
@@ -21,6 +21,7 @@ from . import runners
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 class Indexer:
     """ Main indexing routine.
     """
 class Indexer:
     """ Main indexing routine.
     """
@@ -30,7 +31,6 @@ class Indexer:
         self.tokenizer = tokenizer
         self.num_threads = num_threads
 
         self.tokenizer = tokenizer
         self.num_threads = num_threads
 
-
     def has_pending(self) -> bool:
         """ Check if any data still needs indexing.
             This function must only be used after the import has finished.
     def has_pending(self) -> bool:
         """ Check if any data still needs indexing.
             This function must only be used after the import has finished.
@@ -41,7 +41,6 @@ class Indexer:
                 cur.execute("SELECT 'a' FROM placex WHERE indexed_status > 0 LIMIT 1")
                 return cur.rowcount > 0
 
                 cur.execute("SELECT 'a' FROM placex WHERE indexed_status > 0 LIMIT 1")
                 return cur.rowcount > 0
 
-
     async def index_full(self, analyse: bool = True) -> None:
         """ Index the complete database. This will first index boundaries
             followed by all other objects. When `analyse` is True, then the
     async def index_full(self, analyse: bool = True) -> None:
         """ Index the complete database. This will first index boundaries
             followed by all other objects. When `analyse` is True, then the
@@ -75,7 +74,6 @@ class Indexer:
                 if not self.has_pending():
                     break
 
                 if not self.has_pending():
                     break
 
-
     async def index_boundaries(self, minrank: int, maxrank: int) -> int:
         """ Index only administrative boundaries within the given rank range.
         """
     async def index_boundaries(self, minrank: int, maxrank: int) -> int:
         """ Index only administrative boundaries within the given rank range.
         """
@@ -138,7 +136,6 @@ class Indexer:
                                    (minrank, maxrank))
                 total_tuples = {row.rank_address: row.count for row in cur}
 
                                    (minrank, maxrank))
                 total_tuples = {row.rank_address: row.count for row in cur}
 
-
         with self.tokenizer.name_analyzer() as analyzer:
             for rank in range(max(1, minrank), maxrank + 1):
                 if rank >= 30:
         with self.tokenizer.name_analyzer() as analyzer:
             for rank in range(max(1, minrank), maxrank + 1):
                 if rank >= 30:
@@ -156,7 +153,6 @@ class Indexer:
 
         return total
 
 
         return total
 
-
     async def index_postcodes(self) -> int:
         """Index the entries of the location_postcode table.
         """
     async def index_postcodes(self) -> int:
         """Index the entries of the location_postcode table.
         """
@@ -164,7 +160,6 @@ class Indexer:
 
         return await self._index(runners.PostcodeRunner(), batch=20)
 
 
         return await self._index(runners.PostcodeRunner(), batch=20)
 
-
     def update_status_table(self) -> None:
         """ Update the status in the status table to 'indexed'.
         """
     def update_status_table(self) -> None:
         """ Update the status in the status table to 'indexed'.
         """
@@ -193,7 +188,7 @@ class Indexer:
 
         if total_tuples > 0:
             async with await psycopg.AsyncConnection.connect(
 
         if total_tuples > 0:
             async with await psycopg.AsyncConnection.connect(
-                                 self.dsn, row_factory=psycopg.rows.dict_row) as aconn,\
+                                 self.dsn, row_factory=psycopg.rows.dict_row) as aconn, \
                        QueryPool(self.dsn, self.num_threads, autocommit=True) as pool:
                 fetcher_time = 0.0
                 tstart = time.time()
                        QueryPool(self.dsn, self.num_threads, autocommit=True) as pool:
                 fetcher_time = 0.0
                 tstart = time.time()
@@ -224,7 +219,6 @@ class Indexer:
 
         return progress.done()
 
 
         return progress.done()
 
-
     def _prepare_indexing(self, runner: runners.Runner) -> int:
         with connect(self.dsn) as conn:
             hstore_info = psycopg.types.TypeInfo.fetch(conn, "hstore")
     def _prepare_indexing(self, runner: runners.Runner) -> int:
         with connect(self.dsn) as conn:
             hstore_info = psycopg.types.TypeInfo.fetch(conn, "hstore")
index 668dbd59f2ac068bb07eb82208556e6401cefc15..66c35f062c72d27061f193bff300e39760283e24 100644 (file)
@@ -14,6 +14,7 @@ LOG = logging.getLogger()
 
 INITIAL_PROGRESS = 10
 
 
 INITIAL_PROGRESS = 10
 
+
 class ProgressLogger:
     """ Tracks and prints progress for the indexing process.
         `name` is the name of the indexing step being tracked.
 class ProgressLogger:
     """ Tracks and prints progress for the indexing process.
         `name` is the name of the indexing step being tracked.
index d7737c07230c3d7df4b1579c986ba68d046333df..e20cf20dfcdd044f9ff546128c1c6a0a668e0f54 100644 (file)
@@ -19,11 +19,11 @@ from ..typing import Protocol
 from ..data.place_info import PlaceInfo
 from ..tokenizer.base import AbstractAnalyzer
 
 from ..data.place_info import PlaceInfo
 from ..tokenizer.base import AbstractAnalyzer
 
-# pylint: disable=C0111
 
 def _mk_valuelist(template: str, num: int) -> pysql.Composed:
     return pysql.SQL(',').join([pysql.SQL(template)] * num)
 
 
 def _mk_valuelist(template: str, num: int) -> pysql.Composed:
     return pysql.SQL(',').join([pysql.SQL(template)] * num)
 
+
 def _analyze_place(place: DictRow, analyzer: AbstractAnalyzer) -> Json:
     return Json(analyzer.process_place(PlaceInfo(place)))
 
 def _analyze_place(place: DictRow, analyzer: AbstractAnalyzer) -> Json:
     return Json(analyzer.process_place(PlaceInfo(place)))
 
@@ -41,6 +41,7 @@ SELECT_SQL = pysql.SQL("""SELECT place_id, extra.*
                           LATERAL placex_indexing_prepare(px) as extra """)
 UPDATE_LINE = "(%s, %s::hstore, %s::hstore, %s::int, %s::jsonb)"
 
                           LATERAL placex_indexing_prepare(px) as extra """)
 UPDATE_LINE = "(%s, %s::hstore, %s::hstore, %s::int, %s::jsonb)"
 
+
 class AbstractPlacexRunner:
     """ Returns SQL commands for indexing of the placex table.
     """
 class AbstractPlacexRunner:
     """ Returns SQL commands for indexing of the placex table.
     """
@@ -49,7 +50,6 @@ class AbstractPlacexRunner:
         self.rank = rank
         self.analyzer = analyzer
 
         self.rank = rank
         self.analyzer = analyzer
 
-
     def index_places_query(self, batch_size: int) -> Query:
         return pysql.SQL(
             """ UPDATE placex
     def index_places_query(self, batch_size: int) -> Query:
         return pysql.SQL(
             """ UPDATE placex
@@ -59,7 +59,6 @@ class AbstractPlacexRunner:
                 WHERE place_id = v.id
             """).format(_mk_valuelist(UPDATE_LINE, batch_size))
 
                 WHERE place_id = v.id
             """).format(_mk_valuelist(UPDATE_LINE, batch_size))
 
-
     def index_places_params(self, place: DictRow) -> Sequence[Any]:
         return (place['place_id'],
                 place['name'],
     def index_places_params(self, place: DictRow) -> Sequence[Any]:
         return (place['place_id'],
                 place['name'],
@@ -118,7 +117,6 @@ class InterpolationRunner:
     def __init__(self, analyzer: AbstractAnalyzer) -> None:
         self.analyzer = analyzer
 
     def __init__(self, analyzer: AbstractAnalyzer) -> None:
         self.analyzer = analyzer
 
-
     def name(self) -> str:
         return "interpolation lines (location_property_osmline)"
 
     def name(self) -> str:
         return "interpolation lines (location_property_osmline)"
 
@@ -126,14 +124,12 @@ class InterpolationRunner:
         return """SELECT count(*) FROM location_property_osmline
                   WHERE indexed_status > 0"""
 
         return """SELECT count(*) FROM location_property_osmline
                   WHERE indexed_status > 0"""
 
-
     def sql_get_objects(self) -> Query:
         return """SELECT place_id, get_interpolation_address(address, osm_id) as address
                   FROM location_property_osmline
                   WHERE indexed_status > 0
                   ORDER BY geometry_sector"""
 
     def sql_get_objects(self) -> Query:
         return """SELECT place_id, get_interpolation_address(address, osm_id) as address
                   FROM location_property_osmline
                   WHERE indexed_status > 0
                   ORDER BY geometry_sector"""
 
-
     def index_places_query(self, batch_size: int) -> Query:
         return pysql.SQL("""UPDATE location_property_osmline
                             SET indexed_status = 0, address = v.addr, token_info = v.ti
     def index_places_query(self, batch_size: int) -> Query:
         return pysql.SQL("""UPDATE location_property_osmline
                             SET indexed_status = 0, address = v.addr, token_info = v.ti
@@ -141,13 +137,11 @@ class InterpolationRunner:
                             WHERE place_id = v.id
                          """).format(_mk_valuelist("(%s, %s::hstore, %s::jsonb)", batch_size))
 
                             WHERE place_id = v.id
                          """).format(_mk_valuelist("(%s, %s::hstore, %s::jsonb)", batch_size))
 
-
     def index_places_params(self, place: DictRow) -> Sequence[Any]:
         return (place['place_id'], place['address'],
                 _analyze_place(place, self.analyzer))
 
 
     def index_places_params(self, place: DictRow) -> Sequence[Any]:
         return (place['place_id'], place['address'],
                 _analyze_place(place, self.analyzer))
 
 
-
 class PostcodeRunner(Runner):
     """ Provides the SQL commands for indexing the location_postcode table.
     """
 class PostcodeRunner(Runner):
     """ Provides the SQL commands for indexing the location_postcode table.
     """
@@ -155,22 +149,18 @@ class PostcodeRunner(Runner):
     def name(self) -> str:
         return "postcodes (location_postcode)"
 
     def name(self) -> str:
         return "postcodes (location_postcode)"
 
-
     def sql_count_objects(self) -> Query:
         return 'SELECT count(*) FROM location_postcode WHERE indexed_status > 0'
 
     def sql_count_objects(self) -> Query:
         return 'SELECT count(*) FROM location_postcode WHERE indexed_status > 0'
 
-
     def sql_get_objects(self) -> Query:
         return """SELECT place_id FROM location_postcode
                   WHERE indexed_status > 0
                   ORDER BY country_code, postcode"""
 
     def sql_get_objects(self) -> Query:
         return """SELECT place_id FROM location_postcode
                   WHERE indexed_status > 0
                   ORDER BY country_code, postcode"""
 
-
     def index_places_query(self, batch_size: int) -> Query:
         return pysql.SQL("""UPDATE location_postcode SET indexed_status = 0
                                     WHERE place_id IN ({})""")\
                     .format(pysql.SQL(',').join((pysql.Placeholder() for _ in range(batch_size))))
 
     def index_places_query(self, batch_size: int) -> Query:
         return pysql.SQL("""UPDATE location_postcode SET indexed_status = 0
                                     WHERE place_id IN ({})""")\
                     .format(pysql.SQL(',').join((pysql.Placeholder() for _ in range(batch_size))))
 
-
     def index_places_params(self, place: DictRow) -> Sequence[Any]:
         return (place['place_id'], )
     def index_places_params(self, place: DictRow) -> Sequence[Any]:
         return (place['place_id'], )
index d3aeeacac628afd19fdd5cff9e6bc3dbb61419a9..4b96cb235e10ccf80326f38ea8455cc75080d1dc 100644 (file)
@@ -17,6 +17,7 @@ from ..config import Configuration
 from ..db.connection import Connection
 from ..data.place_info import PlaceInfo
 
 from ..db.connection import Connection
 from ..data.place_info import PlaceInfo
 
+
 class AbstractAnalyzer(ABC):
     """ The analyzer provides the functions for analysing names and building
         the token database.
 class AbstractAnalyzer(ABC):
     """ The analyzer provides the functions for analysing names and building
         the token database.
@@ -28,17 +29,14 @@ class AbstractAnalyzer(ABC):
     def __enter__(self) -> 'AbstractAnalyzer':
         return self
 
     def __enter__(self) -> 'AbstractAnalyzer':
         return self
 
-
     def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
         self.close()
 
     def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
         self.close()
 
-
     @abstractmethod
     def close(self) -> None:
         """ Free all resources used by the analyzer.
         """
 
     @abstractmethod
     def close(self) -> None:
         """ Free all resources used by the analyzer.
         """
 
-
     @abstractmethod
     def get_word_token_info(self, words: List[str]) -> List[Tuple[str, str, int]]:
         """ Return token information for the given list of words.
     @abstractmethod
     def get_word_token_info(self, words: List[str]) -> List[Tuple[str, str, int]]:
         """ Return token information for the given list of words.
@@ -57,7 +55,6 @@ class AbstractAnalyzer(ABC):
                     (original word, word token, word id).
         """
 
                     (original word, word token, word id).
         """
 
-
     @abstractmethod
     def normalize_postcode(self, postcode: str) -> str:
         """ Convert the postcode to its standardized form.
     @abstractmethod
     def normalize_postcode(self, postcode: str) -> str:
         """ Convert the postcode to its standardized form.
@@ -72,14 +69,12 @@ class AbstractAnalyzer(ABC):
                 The given postcode after normalization.
         """
 
                 The given postcode after normalization.
         """
 
-
     @abstractmethod
     def update_postcodes_from_db(self) -> None:
         """ Update the tokenizer's postcode tokens from the current content
             of the `location_postcode` table.
         """
 
     @abstractmethod
     def update_postcodes_from_db(self) -> None:
         """ Update the tokenizer's postcode tokens from the current content
             of the `location_postcode` table.
         """
 
-
     @abstractmethod
     def update_special_phrases(self,
                                phrases: Iterable[Tuple[str, str, str, str]],
     @abstractmethod
     def update_special_phrases(self,
                                phrases: Iterable[Tuple[str, str, str, str]],
@@ -95,7 +90,6 @@ class AbstractAnalyzer(ABC):
                                 ones that already exist.
         """
 
                                 ones that already exist.
         """
 
-
     @abstractmethod
     def add_country_names(self, country_code: str, names: Dict[str, str]) -> None:
         """ Add the given names to the tokenizer's list of country tokens.
     @abstractmethod
     def add_country_names(self, country_code: str, names: Dict[str, str]) -> None:
         """ Add the given names to the tokenizer's list of country tokens.
@@ -106,7 +100,6 @@ class AbstractAnalyzer(ABC):
                 names: Dictionary of name type to name.
         """
 
                 names: Dictionary of name type to name.
         """
 
-
     @abstractmethod
     def process_place(self, place: PlaceInfo) -> Any:
         """ Extract tokens for the given place and compute the
     @abstractmethod
     def process_place(self, place: PlaceInfo) -> Any:
         """ Extract tokens for the given place and compute the
@@ -122,7 +115,6 @@ class AbstractAnalyzer(ABC):
         """
 
 
         """
 
 
-
 class AbstractTokenizer(ABC):
     """ The tokenizer instance is the central instance of the tokenizer in
         the system. There will only be a single instance of the tokenizer
 class AbstractTokenizer(ABC):
     """ The tokenizer instance is the central instance of the tokenizer in
         the system. There will only be a single instance of the tokenizer
@@ -146,7 +138,6 @@ class AbstractTokenizer(ABC):
                 tokenizers.
         """
 
                 tokenizers.
         """
 
-
     @abstractmethod
     def init_from_project(self, config: Configuration) -> None:
         """ Initialise the tokenizer from an existing database setup.
     @abstractmethod
     def init_from_project(self, config: Configuration) -> None:
         """ Initialise the tokenizer from an existing database setup.
@@ -158,7 +149,6 @@ class AbstractTokenizer(ABC):
               config: Read-only object with configuration options.
         """
 
               config: Read-only object with configuration options.
         """
 
-
     @abstractmethod
     def finalize_import(self, config: Configuration) -> None:
         """ This function is called at the very end of an import when all
     @abstractmethod
     def finalize_import(self, config: Configuration) -> None:
         """ This function is called at the very end of an import when all
@@ -170,7 +160,6 @@ class AbstractTokenizer(ABC):
               config: Read-only object with configuration options.
         """
 
               config: Read-only object with configuration options.
         """
 
-
     @abstractmethod
     def update_sql_functions(self, config: Configuration) -> None:
         """ Update the SQL part of the tokenizer. This function is called
     @abstractmethod
     def update_sql_functions(self, config: Configuration) -> None:
         """ Update the SQL part of the tokenizer. This function is called
@@ -184,7 +173,6 @@ class AbstractTokenizer(ABC):
               config: Read-only object with configuration options.
         """
 
               config: Read-only object with configuration options.
         """
 
-
     @abstractmethod
     def check_database(self, config: Configuration) -> Optional[str]:
         """ Check that the database is set up correctly and ready for being
     @abstractmethod
     def check_database(self, config: Configuration) -> Optional[str]:
         """ Check that the database is set up correctly and ready for being
@@ -199,7 +187,6 @@ class AbstractTokenizer(ABC):
                   how to resolve the issue. If everything is okay, return `None`.
         """
 
                   how to resolve the issue. If everything is okay, return `None`.
         """
 
-
     @abstractmethod
     def update_statistics(self, config: Configuration, threads: int = 1) -> None:
         """ Recompute any tokenizer statistics necessary for efficient lookup.
     @abstractmethod
     def update_statistics(self, config: Configuration, threads: int = 1) -> None:
         """ Recompute any tokenizer statistics necessary for efficient lookup.
@@ -208,14 +195,12 @@ class AbstractTokenizer(ABC):
             it to be called in order to work.
         """
 
             it to be called in order to work.
         """
 
-
     @abstractmethod
     def update_word_tokens(self) -> None:
         """ Do house-keeping on the tokenizers internal data structures.
             Remove unused word tokens, resort data etc.
         """
 
     @abstractmethod
     def update_word_tokens(self) -> None:
         """ Do house-keeping on the tokenizers internal data structures.
             Remove unused word tokens, resort data etc.
         """
 
-
     @abstractmethod
     def name_analyzer(self) -> AbstractAnalyzer:
         """ Create a new analyzer for tokenizing names and queries
     @abstractmethod
     def name_analyzer(self) -> AbstractAnalyzer:
         """ Create a new analyzer for tokenizing names and queries
@@ -231,7 +216,6 @@ class AbstractTokenizer(ABC):
             call the close() function before destructing the analyzer.
         """
 
             call the close() function before destructing the analyzer.
         """
 
-
     @abstractmethod
     def most_frequent_words(self, conn: Connection, num: int) -> List[str]:
         """ Return a list of the most frequent full words in the database.
     @abstractmethod
     def most_frequent_words(self, conn: Connection, num: int) -> List[str]:
         """ Return a list of the most frequent full words in the database.
index 5003c322e3764bfb49e1b01c71fbb20112d33543..70b2b0beed0b7718e9dfd19582540b2302cb75b0 100644 (file)
@@ -29,6 +29,7 @@ from ..tokenizer.base import AbstractTokenizer, TokenizerModule
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 def _import_tokenizer(name: str) -> TokenizerModule:
     """ Load the tokenizer.py module from project directory.
     """
 def _import_tokenizer(name: str) -> TokenizerModule:
     """ Load the tokenizer.py module from project directory.
     """
index 0aca2921b966848d87a9e30146592fbe1f104a42..978739c351c1483661ce69fc6e4a4fd8f76ef1ad 100644 (file)
@@ -61,7 +61,6 @@ class ICURuleLoader:
         # Load optional sanitizer rule set.
         self.sanitizer_rules = rules.get('sanitizers', [])
 
         # Load optional sanitizer rule set.
         self.sanitizer_rules = rules.get('sanitizers', [])
 
-
     def load_config_from_db(self, conn: Connection) -> None:
         """ Get previously saved parts of the configuration from the
             database.
     def load_config_from_db(self, conn: Connection) -> None:
         """ Get previously saved parts of the configuration from the
             database.
@@ -81,7 +80,6 @@ class ICURuleLoader:
             self.analysis_rules = []
         self._setup_analysis()
 
             self.analysis_rules = []
         self._setup_analysis()
 
-
     def save_config_to_db(self, conn: Connection) -> None:
         """ Save the part of the configuration that cannot be changed into
             the database.
     def save_config_to_db(self, conn: Connection) -> None:
         """ Save the part of the configuration that cannot be changed into
             the database.
@@ -90,20 +88,17 @@ class ICURuleLoader:
         set_property(conn, DBCFG_IMPORT_TRANS_RULES, self.transliteration_rules)
         set_property(conn, DBCFG_IMPORT_ANALYSIS_RULES, json.dumps(self.analysis_rules))
 
         set_property(conn, DBCFG_IMPORT_TRANS_RULES, self.transliteration_rules)
         set_property(conn, DBCFG_IMPORT_ANALYSIS_RULES, json.dumps(self.analysis_rules))
 
-
     def make_sanitizer(self) -> PlaceSanitizer:
         """ Create a place sanitizer from the configured rules.
         """
         return PlaceSanitizer(self.sanitizer_rules, self.config)
 
     def make_sanitizer(self) -> PlaceSanitizer:
         """ Create a place sanitizer from the configured rules.
         """
         return PlaceSanitizer(self.sanitizer_rules, self.config)
 
-
     def make_token_analysis(self) -> ICUTokenAnalysis:
         """ Create a token analyser from the reviouly loaded rules.
         """
         return ICUTokenAnalysis(self.normalization_rules,
                                 self.transliteration_rules, self.analysis)
 
     def make_token_analysis(self) -> ICUTokenAnalysis:
         """ Create a token analyser from the reviouly loaded rules.
         """
         return ICUTokenAnalysis(self.normalization_rules,
                                 self.transliteration_rules, self.analysis)
 
-
     def get_search_rules(self) -> str:
         """ Return the ICU rules to be used during search.
             The rules combine normalization and transliteration.
     def get_search_rules(self) -> str:
         """ Return the ICU rules to be used during search.
             The rules combine normalization and transliteration.
@@ -116,23 +111,20 @@ class ICURuleLoader:
         rules.write(self.transliteration_rules)
         return rules.getvalue()
 
         rules.write(self.transliteration_rules)
         return rules.getvalue()
 
-
     def get_normalization_rules(self) -> str:
         """ Return rules for normalisation of a term.
         """
         return self.normalization_rules
 
     def get_normalization_rules(self) -> str:
         """ Return rules for normalisation of a term.
         """
         return self.normalization_rules
 
-
     def get_transliteration_rules(self) -> str:
         """ Return the rules for converting a string into its asciii representation.
         """
         return self.transliteration_rules
 
     def get_transliteration_rules(self) -> str:
         """ Return the rules for converting a string into its asciii representation.
         """
         return self.transliteration_rules
 
-
     def _setup_analysis(self) -> None:
         """ Process the rules used for creating the various token analyzers.
         """
     def _setup_analysis(self) -> None:
         """ Process the rules used for creating the various token analyzers.
         """
-        self.analysis: Dict[Optional[str], TokenAnalyzerRule]  = {}
+        self.analysis: Dict[Optional[str], TokenAnalyzerRule] = {}
 
         if not isinstance(self.analysis_rules, list):
             raise UsageError("Configuration section 'token-analysis' must be a list.")
 
         if not isinstance(self.analysis_rules, list):
             raise UsageError("Configuration section 'token-analysis' must be a list.")
@@ -140,7 +132,7 @@ class ICURuleLoader:
         norm = Transliterator.createFromRules("rule_loader_normalization",
                                               self.normalization_rules)
         trans = Transliterator.createFromRules("rule_loader_transliteration",
         norm = Transliterator.createFromRules("rule_loader_normalization",
                                               self.normalization_rules)
         trans = Transliterator.createFromRules("rule_loader_transliteration",
-                                              self.transliteration_rules)
+                                               self.transliteration_rules)
 
         for section in self.analysis_rules:
             name = section.get('id', None)
 
         for section in self.analysis_rules:
             name = section.get('id', None)
@@ -154,7 +146,6 @@ class ICURuleLoader:
             self.analysis[name] = TokenAnalyzerRule(section, norm, trans,
                                                     self.config)
 
             self.analysis[name] = TokenAnalyzerRule(section, norm, trans,
                                                     self.config)
 
-
     @staticmethod
     def _cfg_to_icu_rules(rules: Mapping[str, Any], section: str) -> str:
         """ Load an ICU ruleset from the given section. If the section is a
     @staticmethod
     def _cfg_to_icu_rules(rules: Mapping[str, Any], section: str) -> str:
         """ Load an ICU ruleset from the given section. If the section is a
@@ -189,7 +180,6 @@ class TokenAnalyzerRule:
         self.config = self._analysis_mod.configure(rules, normalizer,
                                                    transliterator)
 
         self.config = self._analysis_mod.configure(rules, normalizer,
                                                    transliterator)
 
-
     def create(self, normalizer: Any, transliterator: Any) -> Analyzer:
         """ Create a new analyser instance for the given rule.
         """
     def create(self, normalizer: Any, transliterator: Any) -> Analyzer:
         """ Create a new analyser instance for the given rule.
         """
index fe6704d4249158526ababae3b4910da1f013cd30..a3cdcb7afdb9a008ee4c19f642b18542da369ac0 100644 (file)
@@ -14,8 +14,9 @@ from icu import Transliterator
 from .token_analysis.base import Analyzer
 
 if TYPE_CHECKING:
 from .token_analysis.base import Analyzer
 
 if TYPE_CHECKING:
-    from typing import Any
-    from .icu_rule_loader import TokenAnalyzerRule # pylint: disable=cyclic-import
+    from typing import Any  # noqa
+    from .icu_rule_loader import TokenAnalyzerRule
+
 
 class ICUTokenAnalysis:
     """ Container class collecting the transliterators and token analysis
 
 class ICUTokenAnalysis:
     """ Container class collecting the transliterators and token analysis
@@ -35,7 +36,6 @@ class ICUTokenAnalysis:
         self.analysis = {name: arules.create(self.normalizer, self.to_ascii)
                          for name, arules in analysis_rules.items()}
 
         self.analysis = {name: arules.create(self.normalizer, self.to_ascii)
                          for name, arules in analysis_rules.items()}
 
-
     def get_analyzer(self, name: Optional[str]) -> Analyzer:
         """ Return the given named analyzer. If no analyzer with that
             name exists, return the default analyzer.
     def get_analyzer(self, name: Optional[str]) -> Analyzer:
         """ Return the given named analyzer. If no analyzer with that
             name exists, return the default analyzer.
index 1b95a90174841f00f552e8023c6ab4ffaef25280..83928644a9c3a9964e26af05c81ef061b8cfeb05 100644 (file)
@@ -17,7 +17,7 @@ from pathlib import Path
 from psycopg.types.json import Jsonb
 from psycopg import sql as pysql
 
 from psycopg.types.json import Jsonb
 from psycopg import sql as pysql
 
-from ..db.connection import connect, Connection, Cursor, server_version_tuple,\
+from ..db.connection import connect, Connection, Cursor, server_version_tuple, \
                             drop_tables, table_exists, execute_scalar
 from ..config import Configuration
 from ..db.sql_preprocessor import SQLPreprocessor
                             drop_tables, table_exists, execute_scalar
 from ..config import Configuration
 from ..db.sql_preprocessor import SQLPreprocessor
@@ -32,10 +32,11 @@ DBCFG_TERM_NORMALIZATION = "tokenizer_term_normalization"
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
-WORD_TYPES =(('country_names', 'C'),
-             ('postcodes', 'P'),
-             ('full_word', 'W'),
-             ('housenumbers', 'H'))
+WORD_TYPES = (('country_names', 'C'),
+              ('postcodes', 'P'),
+              ('full_word', 'W'),
+              ('housenumbers', 'H'))
+
 
 def create(dsn: str, data_dir: Path) -> 'ICUTokenizer':
     """ Create a new instance of the tokenizer provided by this module.
 
 def create(dsn: str, data_dir: Path) -> 'ICUTokenizer':
     """ Create a new instance of the tokenizer provided by this module.
@@ -54,7 +55,6 @@ class ICUTokenizer(AbstractTokenizer):
         self.data_dir = data_dir
         self.loader: Optional[ICURuleLoader] = None
 
         self.data_dir = data_dir
         self.loader: Optional[ICURuleLoader] = None
 
-
     def init_new_db(self, config: Configuration, init_db: bool = True) -> None:
         """ Set up a new tokenizer for the database.
 
     def init_new_db(self, config: Configuration, init_db: bool = True) -> None:
         """ Set up a new tokenizer for the database.
 
@@ -70,7 +70,6 @@ class ICUTokenizer(AbstractTokenizer):
             self._setup_db_tables(config)
             self._create_base_indices(config, 'word')
 
             self._setup_db_tables(config)
             self._create_base_indices(config, 'word')
 
-
     def init_from_project(self, config: Configuration) -> None:
         """ Initialise the tokenizer from the project directory.
         """
     def init_from_project(self, config: Configuration) -> None:
         """ Initialise the tokenizer from the project directory.
         """
@@ -79,14 +78,12 @@ class ICUTokenizer(AbstractTokenizer):
         with connect(self.dsn) as conn:
             self.loader.load_config_from_db(conn)
 
         with connect(self.dsn) as conn:
             self.loader.load_config_from_db(conn)
 
-
     def finalize_import(self, config: Configuration) -> None:
         """ Do any required postprocessing to make the tokenizer data ready
             for use.
         """
         self._create_lookup_indices(config, 'word')
 
     def finalize_import(self, config: Configuration) -> None:
         """ Do any required postprocessing to make the tokenizer data ready
             for use.
         """
         self._create_lookup_indices(config, 'word')
 
-
     def update_sql_functions(self, config: Configuration) -> None:
         """ Reimport the SQL functions for this tokenizer.
         """
     def update_sql_functions(self, config: Configuration) -> None:
         """ Reimport the SQL functions for this tokenizer.
         """
@@ -94,14 +91,12 @@ class ICUTokenizer(AbstractTokenizer):
             sqlp = SQLPreprocessor(conn, config)
             sqlp.run_sql_file(conn, 'tokenizer/icu_tokenizer.sql')
 
             sqlp = SQLPreprocessor(conn, config)
             sqlp.run_sql_file(conn, 'tokenizer/icu_tokenizer.sql')
 
-
     def check_database(self, config: Configuration) -> None:
         """ Check that the tokenizer is set up correctly.
         """
         # Will throw an error if there is an issue.
         self.init_from_project(config)
 
     def check_database(self, config: Configuration) -> None:
         """ Check that the tokenizer is set up correctly.
         """
         # Will throw an error if there is an issue.
         self.init_from_project(config)
 
-
     def update_statistics(self, config: Configuration, threads: int = 2) -> None:
         """ Recompute frequencies for all name words.
         """
     def update_statistics(self, config: Configuration, threads: int = 2) -> None:
         """ Recompute frequencies for all name words.
         """
@@ -126,28 +121,29 @@ class ICUTokenizer(AbstractTokenizer):
                                      SELECT unnest(nameaddress_vector) as id, count(*)
                                      FROM search_name GROUP BY id""")
                     cur.execute('CREATE INDEX ON addressword_frequencies(id)')
                                      SELECT unnest(nameaddress_vector) as id, count(*)
                                      FROM search_name GROUP BY id""")
                     cur.execute('CREATE INDEX ON addressword_frequencies(id)')
-                    cur.execute("""CREATE OR REPLACE FUNCTION word_freq_update(wid INTEGER,
-                                                                               INOUT info JSONB)
-                                   AS $$
-                                   DECLARE rec RECORD;
-                                   BEGIN
-                                   IF info is null THEN
-                                     info = '{}'::jsonb;
-                                   END IF;
-                                   FOR rec IN SELECT count FROM word_frequencies WHERE id = wid
-                                   LOOP
-                                     info = info || jsonb_build_object('count', rec.count);
-                                   END LOOP;
-                                   FOR rec IN SELECT count FROM addressword_frequencies WHERE id = wid
-                                   LOOP
-                                     info = info || jsonb_build_object('addr_count', rec.count);
-                                   END LOOP;
-                                   IF info = '{}'::jsonb THEN
-                                     info = null;
-                                   END IF;
-                                   END;
-                                   $$ LANGUAGE plpgsql IMMUTABLE;
-                                """)
+                    cur.execute("""
+                        CREATE OR REPLACE FUNCTION word_freq_update(wid INTEGER,
+                                                                    INOUT info JSONB)
+                        AS $$
+                        DECLARE rec RECORD;
+                        BEGIN
+                        IF info is null THEN
+                          info = '{}'::jsonb;
+                        END IF;
+                        FOR rec IN SELECT count FROM word_frequencies WHERE id = wid
+                        LOOP
+                          info = info || jsonb_build_object('count', rec.count);
+                        END LOOP;
+                        FOR rec IN SELECT count FROM addressword_frequencies WHERE id = wid
+                        LOOP
+                          info = info || jsonb_build_object('addr_count', rec.count);
+                        END LOOP;
+                        IF info = '{}'::jsonb THEN
+                          info = null;
+                        END IF;
+                        END;
+                        $$ LANGUAGE plpgsql IMMUTABLE;
+                        """)
                     LOG.info('Update word table with recomputed frequencies')
                     drop_tables(conn, 'tmp_word')
                     cur.execute("""CREATE TABLE tmp_word AS
                     LOG.info('Update word table with recomputed frequencies')
                     drop_tables(conn, 'tmp_word')
                     cur.execute("""CREATE TABLE tmp_word AS
@@ -200,8 +196,6 @@ class ICUTokenizer(AbstractTokenizer):
         self._create_lookup_indices(config, 'tmp_word')
         self._move_temporary_word_table('tmp_word')
 
         self._create_lookup_indices(config, 'tmp_word')
         self._move_temporary_word_table('tmp_word')
 
-
-
     def _cleanup_housenumbers(self) -> None:
         """ Remove unused house numbers.
         """
     def _cleanup_housenumbers(self) -> None:
         """ Remove unused house numbers.
         """
@@ -235,8 +229,6 @@ class ICUTokenizer(AbstractTokenizer):
                                 (list(candidates.values()), ))
                 conn.commit()
 
                                 (list(candidates.values()), ))
                 conn.commit()
 
-
-
     def update_word_tokens(self) -> None:
         """ Remove unused tokens.
         """
     def update_word_tokens(self) -> None:
         """ Remove unused tokens.
         """
@@ -244,7 +236,6 @@ class ICUTokenizer(AbstractTokenizer):
         self._cleanup_housenumbers()
         LOG.warning("Tokenizer house-keeping done.")
 
         self._cleanup_housenumbers()
         LOG.warning("Tokenizer house-keeping done.")
 
-
     def name_analyzer(self) -> 'ICUNameAnalyzer':
         """ Create a new analyzer for tokenizing names and queries
             using this tokinzer. Analyzers are context managers and should
     def name_analyzer(self) -> 'ICUNameAnalyzer':
         """ Create a new analyzer for tokenizing names and queries
             using this tokinzer. Analyzers are context managers and should
@@ -264,7 +255,6 @@ class ICUTokenizer(AbstractTokenizer):
         return ICUNameAnalyzer(self.dsn, self.loader.make_sanitizer(),
                                self.loader.make_token_analysis())
 
         return ICUNameAnalyzer(self.dsn, self.loader.make_sanitizer(),
                                self.loader.make_token_analysis())
 
-
     def most_frequent_words(self, conn: Connection, num: int) -> List[str]:
         """ Return a list of the `num` most frequent full words
             in the database.
     def most_frequent_words(self, conn: Connection, num: int) -> List[str]:
         """ Return a list of the `num` most frequent full words
             in the database.
@@ -276,7 +266,6 @@ class ICUTokenizer(AbstractTokenizer):
                              ORDER BY count DESC LIMIT %s""", (num,))
             return list(s[0].split('@')[0] for s in cur)
 
                              ORDER BY count DESC LIMIT %s""", (num,))
             return list(s[0].split('@')[0] for s in cur)
 
-
     def _save_config(self) -> None:
         """ Save the configuration that needs to remain stable for the given
             database as database properties.
     def _save_config(self) -> None:
         """ Save the configuration that needs to remain stable for the given
             database as database properties.
@@ -285,7 +274,6 @@ class ICUTokenizer(AbstractTokenizer):
         with connect(self.dsn) as conn:
             self.loader.save_config_to_db(conn)
 
         with connect(self.dsn) as conn:
             self.loader.save_config_to_db(conn)
 
-
     def _setup_db_tables(self, config: Configuration) -> None:
         """ Set up the word table and fill it with pre-computed word
             frequencies.
     def _setup_db_tables(self, config: Configuration) -> None:
         """ Set up the word table and fill it with pre-computed word
             frequencies.
@@ -309,7 +297,6 @@ class ICUTokenizer(AbstractTokenizer):
             """)
             conn.commit()
 
             """)
             conn.commit()
 
-
     def _create_base_indices(self, config: Configuration, table_name: str) -> None:
         """ Set up the word table and fill it with pre-computed word
             frequencies.
     def _create_base_indices(self, config: Configuration, table_name: str) -> None:
         """ Set up the word table and fill it with pre-computed word
             frequencies.
@@ -330,21 +317,21 @@ class ICUTokenizer(AbstractTokenizer):
                                 column_type=ctype)
             conn.commit()
 
                                 column_type=ctype)
             conn.commit()
 
-
     def _create_lookup_indices(self, config: Configuration, table_name: str) -> None:
         """ Create additional indexes used when running the API.
         """
         with connect(self.dsn) as conn:
             sqlp = SQLPreprocessor(conn, config)
             # Index required for details lookup.
     def _create_lookup_indices(self, config: Configuration, table_name: str) -> None:
         """ Create additional indexes used when running the API.
         """
         with connect(self.dsn) as conn:
             sqlp = SQLPreprocessor(conn, config)
             # Index required for details lookup.
-            sqlp.run_string(conn, """
+            sqlp.run_string(
+                conn,
+                """
                 CREATE INDEX IF NOT EXISTS idx_{{table_name}}_word_id
                   ON {{table_name}} USING BTREE (word_id) {{db.tablespace.search_index}}
                 CREATE INDEX IF NOT EXISTS idx_{{table_name}}_word_id
                   ON {{table_name}} USING BTREE (word_id) {{db.tablespace.search_index}}
-            """,
-            table_name=table_name)
+                """,
+                table_name=table_name)
             conn.commit()
 
             conn.commit()
 
-
     def _move_temporary_word_table(self, old: str) -> None:
         """ Rename all tables and indexes used by the tokenizer.
         """
     def _move_temporary_word_table(self, old: str) -> None:
         """ Rename all tables and indexes used by the tokenizer.
         """
@@ -361,8 +348,6 @@ class ICUTokenizer(AbstractTokenizer):
             conn.commit()
 
 
             conn.commit()
 
 
-
-
 class ICUNameAnalyzer(AbstractAnalyzer):
     """ The ICU analyzer uses the ICU library for splitting names.
 
 class ICUNameAnalyzer(AbstractAnalyzer):
     """ The ICU analyzer uses the ICU library for splitting names.
 
@@ -379,7 +364,6 @@ class ICUNameAnalyzer(AbstractAnalyzer):
 
         self._cache = _TokenCache()
 
 
         self._cache = _TokenCache()
 
-
     def close(self) -> None:
         """ Free all resources used by the analyzer.
         """
     def close(self) -> None:
         """ Free all resources used by the analyzer.
         """
@@ -387,20 +371,17 @@ class ICUNameAnalyzer(AbstractAnalyzer):
             self.conn.close()
             self.conn = None
 
             self.conn.close()
             self.conn = None
 
-
     def _search_normalized(self, name: str) -> str:
         """ Return the search token transliteration of the given name.
         """
         return cast(str, self.token_analysis.search.transliterate(name)).strip()
 
     def _search_normalized(self, name: str) -> str:
         """ Return the search token transliteration of the given name.
         """
         return cast(str, self.token_analysis.search.transliterate(name)).strip()
 
-
     def _normalized(self, name: str) -> str:
         """ Return the normalized version of the given name with all
             non-relevant information removed.
         """
         return cast(str, self.token_analysis.normalizer.transliterate(name)).strip()
 
     def _normalized(self, name: str) -> str:
         """ Return the normalized version of the given name with all
             non-relevant information removed.
         """
         return cast(str, self.token_analysis.normalizer.transliterate(name)).strip()
 
-
     def get_word_token_info(self, words: Sequence[str]) -> List[Tuple[str, str, int]]:
         """ Return token information for the given list of words.
             If a word starts with # it is assumed to be a full name
     def get_word_token_info(self, words: Sequence[str]) -> List[Tuple[str, str, int]]:
         """ Return token information for the given list of words.
             If a word starts with # it is assumed to be a full name
@@ -432,8 +413,7 @@ class ICUNameAnalyzer(AbstractAnalyzer):
             part_ids = {r[0]: r[1] for r in cur}
 
         return [(k, v, full_ids.get(v, None)) for k, v in full_tokens.items()] \
             part_ids = {r[0]: r[1] for r in cur}
 
         return [(k, v, full_ids.get(v, None)) for k, v in full_tokens.items()] \
-               + [(k, v, part_ids.get(v, None)) for k, v in partial_tokens.items()]
-
+            + [(k, v, part_ids.get(v, None)) for k, v in partial_tokens.items()]
 
     def normalize_postcode(self, postcode: str) -> str:
         """ Convert the postcode to a standardized form.
 
     def normalize_postcode(self, postcode: str) -> str:
         """ Convert the postcode to a standardized form.
@@ -443,7 +423,6 @@ class ICUNameAnalyzer(AbstractAnalyzer):
         """
         return postcode.strip().upper()
 
         """
         return postcode.strip().upper()
 
-
     def update_postcodes_from_db(self) -> None:
         """ Update postcode tokens in the word table from the location_postcode
             table.
     def update_postcodes_from_db(self) -> None:
         """ Update postcode tokens in the word table from the location_postcode
             table.
@@ -516,9 +495,6 @@ class ICUNameAnalyzer(AbstractAnalyzer):
             with self.conn.cursor() as cur:
                 cur.executemany("""SELECT create_postcode_word(%s, %s)""", terms)
 
             with self.conn.cursor() as cur:
                 cur.executemany("""SELECT create_postcode_word(%s, %s)""", terms)
 
-
-
-
     def update_special_phrases(self, phrases: Iterable[Tuple[str, str, str, str]],
                                should_replace: bool) -> None:
         """ Replace the search index for special phrases with the new phrases.
     def update_special_phrases(self, phrases: Iterable[Tuple[str, str, str, str]],
                                should_replace: bool) -> None:
         """ Replace the search index for special phrases with the new phrases.
@@ -548,7 +524,6 @@ class ICUNameAnalyzer(AbstractAnalyzer):
         LOG.info("Total phrases: %s. Added: %s. Deleted: %s",
                  len(norm_phrases), added, deleted)
 
         LOG.info("Total phrases: %s. Added: %s. Deleted: %s",
                  len(norm_phrases), added, deleted)
 
-
     def _add_special_phrases(self, cursor: Cursor,
                              new_phrases: Set[Tuple[str, str, str, str]],
                              existing_phrases: Set[Tuple[str, str, str, str]]) -> int:
     def _add_special_phrases(self, cursor: Cursor,
                              new_phrases: Set[Tuple[str, str, str, str]],
                              existing_phrases: Set[Tuple[str, str, str, str]]) -> int:
@@ -568,10 +543,9 @@ class ICUNameAnalyzer(AbstractAnalyzer):
 
         return added
 
 
         return added
 
-
     def _remove_special_phrases(self, cursor: Cursor,
     def _remove_special_phrases(self, cursor: Cursor,
-                             new_phrases: Set[Tuple[str, str, str, str]],
-                             existing_phrases: Set[Tuple[str, str, str, str]]) -> int:
+                                new_phrases: Set[Tuple[str, str, str, str]],
+                                existing_phrases: Set[Tuple[str, str, str, str]]) -> int:
         """ Remove all phrases from the database that are no longer in the
             new phrase list.
         """
         """ Remove all phrases from the database that are no longer in the
             new phrase list.
         """
@@ -587,7 +561,6 @@ class ICUNameAnalyzer(AbstractAnalyzer):
 
         return len(to_delete)
 
 
         return len(to_delete)
 
-
     def add_country_names(self, country_code: str, names: Mapping[str, str]) -> None:
         """ Add default names for the given country to the search index.
         """
     def add_country_names(self, country_code: str, names: Mapping[str, str]) -> None:
         """ Add default names for the given country to the search index.
         """
@@ -599,7 +572,6 @@ class ICUNameAnalyzer(AbstractAnalyzer):
                                      self.sanitizer.process_names(info)[0],
                                      internal=True)
 
                                      self.sanitizer.process_names(info)[0],
                                      internal=True)
 
-
     def _add_country_full_names(self, country_code: str, names: Sequence[PlaceName],
                                 internal: bool = False) -> None:
         """ Add names for the given country from an already sanitized
     def _add_country_full_names(self, country_code: str, names: Sequence[PlaceName],
                                 internal: bool = False) -> None:
         """ Add names for the given country from an already sanitized
@@ -651,7 +623,6 @@ class ICUNameAnalyzer(AbstractAnalyzer):
                           """
                 cur.execute(sql, (country_code, list(new_tokens)))
 
                           """
                 cur.execute(sql, (country_code, list(new_tokens)))
 
-
     def process_place(self, place: PlaceInfo) -> Mapping[str, Any]:
         """ Determine tokenizer information about the given place.
 
     def process_place(self, place: PlaceInfo) -> Mapping[str, Any]:
         """ Determine tokenizer information about the given place.
 
@@ -674,7 +645,6 @@ class ICUNameAnalyzer(AbstractAnalyzer):
 
         return token_info.to_dict()
 
 
         return token_info.to_dict()
 
-
     def _process_place_address(self, token_info: '_TokenInfo',
                                address: Sequence[PlaceName]) -> None:
         for item in address:
     def _process_place_address(self, token_info: '_TokenInfo',
                                address: Sequence[PlaceName]) -> None:
         for item in address:
@@ -687,12 +657,11 @@ class ICUNameAnalyzer(AbstractAnalyzer):
             elif item.kind == 'place':
                 if not item.suffix:
                     token_info.add_place(itertools.chain(*self._compute_name_tokens([item])))
             elif item.kind == 'place':
                 if not item.suffix:
                     token_info.add_place(itertools.chain(*self._compute_name_tokens([item])))
-            elif not item.kind.startswith('_') and not item.suffix and \
-                 item.kind not in ('country', 'full', 'inclusion'):
+            elif (not item.kind.startswith('_') and not item.suffix and
+                  item.kind not in ('country', 'full', 'inclusion')):
                 token_info.add_address_term(item.kind,
                                             itertools.chain(*self._compute_name_tokens([item])))
 
                 token_info.add_address_term(item.kind,
                                             itertools.chain(*self._compute_name_tokens([item])))
 
-
     def _compute_housenumber_token(self, hnr: PlaceName) -> Tuple[Optional[int], Optional[str]]:
         """ Normalize the housenumber and return the word token and the
             canonical form.
     def _compute_housenumber_token(self, hnr: PlaceName) -> Tuple[Optional[int], Optional[str]]:
         """ Normalize the housenumber and return the word token and the
             canonical form.
@@ -728,7 +697,6 @@ class ICUNameAnalyzer(AbstractAnalyzer):
 
         return result
 
 
         return result
 
-
     def _retrieve_full_tokens(self, name: str) -> List[int]:
         """ Get the full name token for the given name, if it exists.
             The name is only retrieved for the standard analyser.
     def _retrieve_full_tokens(self, name: str) -> List[int]:
         """ Get the full name token for the given name, if it exists.
             The name is only retrieved for the standard analyser.
@@ -749,7 +717,6 @@ class ICUNameAnalyzer(AbstractAnalyzer):
 
         return full
 
 
         return full
 
-
     def _compute_name_tokens(self, names: Sequence[PlaceName]) -> Tuple[Set[int], Set[int]]:
         """ Computes the full name and partial name tokens for the given
             dictionary of names.
     def _compute_name_tokens(self, names: Sequence[PlaceName]) -> Tuple[Set[int], Set[int]]:
         """ Computes the full name and partial name tokens for the given
             dictionary of names.
@@ -787,7 +754,6 @@ class ICUNameAnalyzer(AbstractAnalyzer):
 
         return full_tokens, partial_tokens
 
 
         return full_tokens, partial_tokens
 
-
     def _add_postcode(self, item: PlaceName) -> Optional[str]:
         """ Make sure the normalized postcode is present in the word table.
         """
     def _add_postcode(self, item: PlaceName) -> Optional[str]:
         """ Make sure the normalized postcode is present in the word table.
         """
@@ -835,11 +801,9 @@ class _TokenInfo:
         self.address_tokens: Dict[str, str] = {}
         self.postcode: Optional[str] = None
 
         self.address_tokens: Dict[str, str] = {}
         self.postcode: Optional[str] = None
 
-
     def _mk_array(self, tokens: Iterable[Any]) -> str:
         return f"{{{','.join((str(s) for s in tokens))}}}"
 
     def _mk_array(self, tokens: Iterable[Any]) -> str:
         return f"{{{','.join((str(s) for s in tokens))}}}"
 
-
     def to_dict(self) -> Dict[str, Any]:
         """ Return the token information in database importable format.
         """
     def to_dict(self) -> Dict[str, Any]:
         """ Return the token information in database importable format.
         """
@@ -866,13 +830,11 @@ class _TokenInfo:
 
         return out
 
 
         return out
 
-
     def set_names(self, fulls: Iterable[int], partials: Iterable[int]) -> None:
         """ Adds token information for the normalised names.
         """
         self.names = self._mk_array(itertools.chain(fulls, partials))
 
     def set_names(self, fulls: Iterable[int], partials: Iterable[int]) -> None:
         """ Adds token information for the normalised names.
         """
         self.names = self._mk_array(itertools.chain(fulls, partials))
 
-
     def add_housenumber(self, token: Optional[int], hnr: Optional[str]) -> None:
         """ Extract housenumber information from a list of normalised
             housenumbers.
     def add_housenumber(self, token: Optional[int], hnr: Optional[str]) -> None:
         """ Extract housenumber information from a list of normalised
             housenumbers.
@@ -882,7 +844,6 @@ class _TokenInfo:
             self.housenumbers.add(hnr)
             self.housenumber_tokens.add(token)
 
             self.housenumbers.add(hnr)
             self.housenumber_tokens.add(token)
 
-
     def add_street(self, tokens: Iterable[int]) -> None:
         """ Add addr:street match terms.
         """
     def add_street(self, tokens: Iterable[int]) -> None:
         """ Add addr:street match terms.
         """
@@ -890,13 +851,11 @@ class _TokenInfo:
             self.street_tokens = set()
         self.street_tokens.update(tokens)
 
             self.street_tokens = set()
         self.street_tokens.update(tokens)
 
-
     def add_place(self, tokens: Iterable[int]) -> None:
         """ Add addr:place search and match terms.
         """
         self.place_tokens.update(tokens)
 
     def add_place(self, tokens: Iterable[int]) -> None:
         """ Add addr:place search and match terms.
         """
         self.place_tokens.update(tokens)
 
-
     def add_address_term(self, key: str, partials: Iterable[int]) -> None:
         """ Add additional address terms.
         """
     def add_address_term(self, key: str, partials: Iterable[int]) -> None:
         """ Add additional address terms.
         """
index 68322f9fd5cdf5c488d0f2dca322d31d7ba1c5f6..55e4a459d5b0ffee8cba938a7d3c73cc1d355c2a 100644 (file)
@@ -39,7 +39,6 @@ class PlaceSanitizer:
 
                 self.handlers.append(module.create(SanitizerConfig(func)))
 
 
                 self.handlers.append(module.create(SanitizerConfig(func)))
 
-
     def process_names(self, place: PlaceInfo) -> Tuple[List[PlaceName], List[PlaceName]]:
         """ Extract a sanitized list of names and address parts from the
             given place. The function returns a tuple
     def process_names(self, place: PlaceInfo) -> Tuple[List[PlaceName], List[PlaceName]]:
         """ Extract a sanitized list of names and address parts from the
             given place. The function returns a tuple
index 2dbc4482556f75b0df691b819675ae5540a23c35..177302990ebb8b8d97e11a840debe950ac5823e5 100644 (file)
@@ -27,7 +27,6 @@ class ProcessInfo:
         self.names = self._convert_name_dict(place.name)
         self.address = self._convert_name_dict(place.address)
 
         self.names = self._convert_name_dict(place.name)
         self.address = self._convert_name_dict(place.address)
 
-
     @staticmethod
     def _convert_name_dict(names: Optional[Mapping[str, str]]) -> List[PlaceName]:
         """ Convert a dictionary of names into a list of PlaceNames.
     @staticmethod
     def _convert_name_dict(names: Optional[Mapping[str, str]]) -> List[PlaceName]:
         """ Convert a dictionary of names into a list of PlaceNames.
index 20443616a70540ab520e372f400857ceb840f485..a74ca2499403620d07d9a0786555a5ab0659c14e 100644 (file)
@@ -30,6 +30,7 @@ from ...data.place_name import PlaceName
 from .base import ProcessInfo
 from .config import SanitizerConfig
 
 from .base import ProcessInfo
 from .config import SanitizerConfig
 
+
 class _HousenumberSanitizer:
 
     def __init__(self, config: SanitizerConfig) -> None:
 class _HousenumberSanitizer:
 
     def __init__(self, config: SanitizerConfig) -> None:
@@ -38,7 +39,6 @@ class _HousenumberSanitizer:
 
         self.filter_name = config.get_filter('convert-to-name', 'FAIL_ALL')
 
 
         self.filter_name = config.get_filter('convert-to-name', 'FAIL_ALL')
 
-
     def __call__(self, obj: ProcessInfo) -> None:
         if not obj.address:
             return
     def __call__(self, obj: ProcessInfo) -> None:
         if not obj.address:
             return
@@ -57,7 +57,6 @@ class _HousenumberSanitizer:
 
         obj.address = new_address
 
 
         obj.address = new_address
 
-
     def sanitize(self, value: str) -> Iterator[str]:
         """ Extract housenumbers in a regularized format from an OSM value.
 
     def sanitize(self, value: str) -> Iterator[str]:
         """ Extract housenumbers in a regularized format from an OSM value.
 
@@ -68,7 +67,6 @@ class _HousenumberSanitizer:
             if hnr:
                 yield from self._regularize(hnr)
 
             if hnr:
                 yield from self._regularize(hnr)
 
-
     def _regularize(self, hnr: str) -> Iterator[str]:
         yield hnr
 
     def _regularize(self, hnr: str) -> Iterator[str]:
         yield hnr
 
index 5340dc8ce26aaba436832abf11a9c7cfc672edd4..9bdf363c5b313d7e5d59a26098163c958e346677 100644 (file)
@@ -26,6 +26,7 @@ from ...data.postcode_format import PostcodeFormatter
 from .base import ProcessInfo
 from .config import SanitizerConfig
 
 from .base import ProcessInfo
 from .config import SanitizerConfig
 
+
 class _PostcodeSanitizer:
 
     def __init__(self, config: SanitizerConfig) -> None:
 class _PostcodeSanitizer:
 
     def __init__(self, config: SanitizerConfig) -> None:
@@ -36,7 +37,6 @@ class _PostcodeSanitizer:
         if default_pattern is not None and isinstance(default_pattern, str):
             self.matcher.set_default_pattern(default_pattern)
 
         if default_pattern is not None and isinstance(default_pattern, str):
             self.matcher.set_default_pattern(default_pattern)
 
-
     def __call__(self, obj: ProcessInfo) -> None:
         if not obj.address:
             return
     def __call__(self, obj: ProcessInfo) -> None:
         if not obj.address:
             return
@@ -55,7 +55,6 @@ class _PostcodeSanitizer:
                 postcode.name = formatted[0]
                 postcode.set_attr('variant', formatted[1])
 
                 postcode.name = formatted[0]
                 postcode.set_attr('variant', formatted[1])
 
-
     def scan(self, postcode: str, country: Optional[str]) -> Optional[Tuple[str, str]]:
         """ Check the postcode for correct formatting and return the
             normalized version. Returns None if the postcode does not
     def scan(self, postcode: str, country: Optional[str]) -> Optional[Tuple[str, str]]:
         """ Check the postcode for correct formatting and return the
             normalized version. Returns None if the postcode does not
@@ -67,10 +66,8 @@ class _PostcodeSanitizer:
 
         assert country is not None
 
 
         assert country is not None
 
-        return self.matcher.normalize(country, match),\
-               ' '.join(filter(lambda p: p is not None, match.groups()))
-
-
+        return self.matcher.normalize(country, match), \
+            ' '.join(filter(lambda p: p is not None, match.groups()))
 
 
 def create(config: SanitizerConfig) -> Callable[[ProcessInfo], None]:
 
 
 def create(config: SanitizerConfig) -> Callable[[ProcessInfo], None]:
index 714a9256bd5cdf015771c6d23d0fcb6739b76cd2..87038f99ebefa0fa858c643885ddfd89b3171b8b 100644 (file)
@@ -19,6 +19,7 @@ from .config import SanitizerConfig
 
 COUNTY_MATCH = re.compile('(.*), [A-Z][A-Z]')
 
 
 COUNTY_MATCH = re.compile('(.*), [A-Z][A-Z]')
 
+
 def _clean_tiger_county(obj: ProcessInfo) -> None:
     """ Remove the state reference from tiger:county tags.
 
 def _clean_tiger_county(obj: ProcessInfo) -> None:
     """ Remove the state reference from tiger:county tags.
 
index 034d0791ed56ef6e22c6b72f99ce23bc3953b1b5..1e624b09b6fde4d0f3113cad3f981ae778c0e454 100644 (file)
@@ -20,6 +20,7 @@ if TYPE_CHECKING:
 else:
     _BaseUserDict = UserDict
 
 else:
     _BaseUserDict = UserDict
 
+
 class SanitizerConfig(_BaseUserDict):
     """ The `SanitizerConfig` class is a read-only dictionary
         with configuration options for the sanitizer.
 class SanitizerConfig(_BaseUserDict):
     """ The `SanitizerConfig` class is a read-only dictionary
         with configuration options for the sanitizer.
@@ -61,7 +62,6 @@ class SanitizerConfig(_BaseUserDict):
 
         return values
 
 
         return values
 
-
     def get_bool(self, param: str, default: Optional[bool] = None) -> bool:
         """ Extract a configuration parameter as a boolean.
 
     def get_bool(self, param: str, default: Optional[bool] = None) -> bool:
         """ Extract a configuration parameter as a boolean.
 
@@ -82,7 +82,6 @@ class SanitizerConfig(_BaseUserDict):
 
         return value
 
 
         return value
 
-
     def get_delimiter(self, default: str = ',;') -> Pattern[str]:
         """ Return the 'delimiters' parameter in the configuration as a
             compiled regular expression that can be used to split strings on
     def get_delimiter(self, default: str = ',;') -> Pattern[str]:
         """ Return the 'delimiters' parameter in the configuration as a
             compiled regular expression that can be used to split strings on
@@ -105,7 +104,6 @@ class SanitizerConfig(_BaseUserDict):
 
         return re.compile('\\s*[{}]+\\s*'.format(''.join('\\' + d for d in delimiter_set)))
 
 
         return re.compile('\\s*[{}]+\\s*'.format(''.join('\\' + d for d in delimiter_set)))
 
-
     def get_filter(self, param: str, default: Union[str, Sequence[str]] = 'PASS_ALL'
                    ) -> Callable[[str], bool]:
         """ Returns a filter function for the given parameter of the sanitizer
     def get_filter(self, param: str, default: Union[str, Sequence[str]] = 'PASS_ALL'
                    ) -> Callable[[str], bool]:
         """ Returns a filter function for the given parameter of the sanitizer
index 7856862c67488ab1d34400a89dad8026a84e20cc..6c905cfe4bdf624ee48fbaac2a647e3dad3ae8c5 100644 (file)
@@ -60,6 +60,7 @@ from ...data.place_name import PlaceName
 from .base import ProcessInfo\r
 from .config import SanitizerConfig\r
 \r
 from .base import ProcessInfo\r
 from .config import SanitizerConfig\r
 \r
+\r
 class _TagSanitizer:\r
 \r
     def __init__(self, config: SanitizerConfig) -> None:\r
 class _TagSanitizer:\r
 \r
     def __init__(self, config: SanitizerConfig) -> None:\r
@@ -74,7 +75,6 @@ class _TagSanitizer:
 \r
         self.has_country_code = config.get('country_code', None) is not None\r
 \r
 \r
         self.has_country_code = config.get('country_code', None) is not None\r
 \r
-\r
     def __call__(self, obj: ProcessInfo) -> None:\r
         tags = obj.names if self.type == 'name' else obj.address\r
 \r
     def __call__(self, obj: ProcessInfo) -> None:\r
         tags = obj.names if self.type == 'name' else obj.address\r
 \r
@@ -93,13 +93,11 @@ class _TagSanitizer:
                or not self.filter_name(tag.name):\r
                 filtered_tags.append(tag)\r
 \r
                or not self.filter_name(tag.name):\r
                 filtered_tags.append(tag)\r
 \r
-\r
         if self.type == 'name':\r
             obj.names = filtered_tags\r
         else:\r
             obj.address = filtered_tags\r
 \r
         if self.type == 'name':\r
             obj.names = filtered_tags\r
         else:\r
             obj.address = filtered_tags\r
 \r
-\r
     def _set_allowed_ranks(self, ranks: Sequence[str]) -> Tuple[bool, ...]:\r
         """ Returns a tuple of 31 boolean values corresponding to the\r
             address ranks 0-30. Value at index 'i' is True if rank 'i'\r
     def _set_allowed_ranks(self, ranks: Sequence[str]) -> Tuple[bool, ...]:\r
         """ Returns a tuple of 31 boolean values corresponding to the\r
             address ranks 0-30. Value at index 'i' is True if rank 'i'\r
@@ -117,7 +115,6 @@ class _TagSanitizer:
             for i in range(start, end + 1):\r
                 allowed_ranks[i] = True\r
 \r
             for i in range(start, end + 1):\r
                 allowed_ranks[i] = True\r
 \r
-\r
         return tuple(allowed_ranks)\r
 \r
 \r
         return tuple(allowed_ranks)\r
 \r
 \r
index bb261359ce097a12b52d341586e07462be157115..f4aab24269d687f5baf1dc3ab7a17641dae2d7e9 100644 (file)
@@ -16,6 +16,7 @@ from typing import Callable
 from .base import ProcessInfo
 from .config import SanitizerConfig
 
 from .base import ProcessInfo
 from .config import SanitizerConfig
 
+
 def create(config: SanitizerConfig) -> Callable[[ProcessInfo], None]:
     """ Create a name processing function that splits name values with
         multiple values into their components.
 def create(config: SanitizerConfig) -> Callable[[ProcessInfo], None]:
     """ Create a name processing function that splits name values with
         multiple values into their components.
index db585a50f4887dd921c8e57484c1ac3874e89c49..7bf6c6a73ae43ee6be32bd00f9aaa399b9adaf39 100644 (file)
@@ -36,6 +36,7 @@ from ...data import country_info
 from .base import ProcessInfo
 from .config import SanitizerConfig
 
 from .base import ProcessInfo
 from .config import SanitizerConfig
 
+
 class _AnalyzerByLanguage:
     """ Processor for tagging the language of names in a place.
     """
 class _AnalyzerByLanguage:
     """ Processor for tagging the language of names in a place.
     """
@@ -47,7 +48,6 @@ class _AnalyzerByLanguage:
 
         self._compute_default_languages(config.get('use-defaults', 'no'))
 
 
         self._compute_default_languages(config.get('use-defaults', 'no'))
 
-
     def _compute_default_languages(self, use_defaults: str) -> None:
         self.deflangs: Dict[Optional[str], List[str]] = {}
 
     def _compute_default_languages(self, use_defaults: str) -> None:
         self.deflangs: Dict[Optional[str], List[str]] = {}
 
@@ -55,18 +55,16 @@ class _AnalyzerByLanguage:
             for ccode, clangs in country_info.iterate('languages'):
                 if len(clangs) == 1 or use_defaults == 'all':
                     if self.whitelist:
             for ccode, clangs in country_info.iterate('languages'):
                 if len(clangs) == 1 or use_defaults == 'all':
                     if self.whitelist:
-                        self.deflangs[ccode] = [l for l in clangs if l in self.whitelist]
+                        self.deflangs[ccode] = [cl for cl in clangs if cl in self.whitelist]
                     else:
                         self.deflangs[ccode] = clangs
 
                     else:
                         self.deflangs[ccode] = clangs
 
-
     def _suffix_matches(self, suffix: str) -> bool:
         if self.whitelist is None:
             return len(suffix) in (2, 3) and suffix.islower()
 
         return suffix in self.whitelist
 
     def _suffix_matches(self, suffix: str) -> bool:
         if self.whitelist is None:
             return len(suffix) in (2, 3) and suffix.islower()
 
         return suffix in self.whitelist
 
-
     def __call__(self, obj: ProcessInfo) -> None:
         if not obj.names:
             return
     def __call__(self, obj: ProcessInfo) -> None:
         if not obj.names:
             return
@@ -80,14 +78,13 @@ class _AnalyzerByLanguage:
             else:
                 langs = self.deflangs.get(obj.place.country_code)
 
             else:
                 langs = self.deflangs.get(obj.place.country_code)
 
-
             if langs:
                 if self.replace:
                     name.set_attr('analyzer', langs[0])
                 else:
                     more_names.append(name.clone(attr={'analyzer': langs[0]}))
 
             if langs:
                 if self.replace:
                     name.set_attr('analyzer', langs[0])
                 else:
                     more_names.append(name.clone(attr={'analyzer': langs[0]}))
 
-                more_names.extend(name.clone(attr={'analyzer': l}) for l in langs[1:])
+                more_names.extend(name.clone(attr={'analyzer': lg}) for lg in langs[1:])
 
         obj.names.extend(more_names)
 
 
         obj.names.extend(more_names)
 
index c4dc1c1b12a0bf4c0018b454d6ee921e05eddd4c..3fc3e19630ecc68bffb60f72810d9a7889c90eb1 100644 (file)
@@ -18,11 +18,13 @@ from .base import ProcessInfo
 from .config import SanitizerConfig
 from ...data.place_name import PlaceName
 
 from .config import SanitizerConfig
 from ...data.place_name import PlaceName
 
+
 def create(_: SanitizerConfig) -> Callable[[ProcessInfo], None]:
     """Set up the sanitizer
     """
     return tag_japanese
 
 def create(_: SanitizerConfig) -> Callable[[ProcessInfo], None]:
     """Set up the sanitizer
     """
     return tag_japanese
 
+
 def reconbine_housenumber(
     new_address: List[PlaceName],
     tmp_housenumber: Optional[str],
 def reconbine_housenumber(
     new_address: List[PlaceName],
     tmp_housenumber: Optional[str],
@@ -56,6 +58,7 @@ def reconbine_housenumber(
         )
     return new_address
 
         )
     return new_address
 
+
 def reconbine_place(
     new_address: List[PlaceName],
     tmp_neighbourhood: Optional[str],
 def reconbine_place(
     new_address: List[PlaceName],
     tmp_neighbourhood: Optional[str],
@@ -88,6 +91,8 @@ def reconbine_place(
             )
         )
     return new_address
             )
         )
     return new_address
+
+
 def tag_japanese(obj: ProcessInfo) -> None:
     """Recombine kind of address
     """
 def tag_japanese(obj: ProcessInfo) -> None:
     """Recombine kind of address
     """
index 9435edb3b562442a6c5369888390453137bdd828..52ee801343fb6c29d2425dd356c0b9df495a745b 100644 (file)
@@ -12,6 +12,7 @@ from typing import Mapping, List, Any
 from ...typing import Protocol
 from ...data.place_name import PlaceName
 
 from ...typing import Protocol
 from ...data.place_name import PlaceName
 
+
 class Analyzer(Protocol):
     """ The `create()` function of an analysis module needs to return an
         object that implements the following functions.
 class Analyzer(Protocol):
     """ The `create()` function of an analysis module needs to return an
         object that implements the following functions.
index aff360afa62f917d80afadb7786cf1f55d2441eb..7e181479f61d2fb4a772b5a11396ce7acad4bae4 100644 (file)
@@ -15,6 +15,7 @@ import re
 from ...config import flatten_config_list
 from ...errors import UsageError
 
 from ...config import flatten_config_list
 from ...errors import UsageError
 
+
 class ICUVariant(NamedTuple):
     """ A single replacement rule for variant creation.
     """
 class ICUVariant(NamedTuple):
     """ A single replacement rule for variant creation.
     """
@@ -64,7 +65,6 @@ class _VariantMaker:
     def __init__(self, normalizer: Any) -> None:
         self.norm = normalizer
 
     def __init__(self, normalizer: Any) -> None:
         self.norm = normalizer
 
-
     def compute(self, rule: Any) -> Iterator[ICUVariant]:
         """ Generator for all ICUVariant tuples from a single variant rule.
         """
     def compute(self, rule: Any) -> Iterator[ICUVariant]:
         """ Generator for all ICUVariant tuples from a single variant rule.
         """
@@ -88,7 +88,6 @@ class _VariantMaker:
                 for froms, tos in _create_variants(*src, repl, decompose):
                     yield ICUVariant(froms, tos)
 
                 for froms, tos in _create_variants(*src, repl, decompose):
                     yield ICUVariant(froms, tos)
 
-
     def _parse_variant_word(self, name: str) -> Optional[Tuple[str, str, str]]:
         name = name.strip()
         match = re.fullmatch(r'([~^]?)([^~$^]*)([~$]?)', name)
     def _parse_variant_word(self, name: str) -> Optional[Tuple[str, str, str]]:
         name = name.strip()
         match = re.fullmatch(r'([~^]?)([^~$^]*)([~$]?)', name)
index 30f1944e569bc732bcdb282012ee0dda4042a846..4aa84de76ba8945fd18e412abb974dbce8cfe6a0 100644 (file)
@@ -17,7 +17,8 @@ from ...data.place_name import PlaceName
 from .config_variants import get_variant_config
 from .generic_mutation import MutationVariantGenerator
 
 from .config_variants import get_variant_config
 from .generic_mutation import MutationVariantGenerator
 
-### Configuration section
+# Configuration section
+
 
 def configure(rules: Mapping[str, Any], normalizer: Any, _: Any) -> Dict[str, Any]:
     """ Extract and preprocess the configuration for this module.
 
 def configure(rules: Mapping[str, Any], normalizer: Any, _: Any) -> Dict[str, Any]:
     """ Extract and preprocess the configuration for this module.
@@ -47,7 +48,7 @@ def configure(rules: Mapping[str, Any], normalizer: Any, _: Any) -> Dict[str, An
     return config
 
 
     return config
 
 
-### Analysis section
+# Analysis section
 
 def create(normalizer: Any, transliterator: Any,
            config: Mapping[str, Any]) -> 'GenericTokenAnalysis':
 
 def create(normalizer: Any, transliterator: Any,
            config: Mapping[str, Any]) -> 'GenericTokenAnalysis':
@@ -77,14 +78,12 @@ class GenericTokenAnalysis:
         # set up mutation rules
         self.mutations = [MutationVariantGenerator(*cfg) for cfg in config['mutations']]
 
         # set up mutation rules
         self.mutations = [MutationVariantGenerator(*cfg) for cfg in config['mutations']]
 
-
     def get_canonical_id(self, name: PlaceName) -> str:
         """ Return the normalized form of the name. This is the standard form
             from which possible variants for the name can be derived.
         """
         return cast(str, self.norm.transliterate(name.name)).strip()
 
     def get_canonical_id(self, name: PlaceName) -> str:
         """ Return the normalized form of the name. This is the standard form
             from which possible variants for the name can be derived.
         """
         return cast(str, self.norm.transliterate(name.name)).strip()
 
-
     def compute_variants(self, norm_name: str) -> List[str]:
         """ Compute the spelling variants for the given normalized name
             and transliterate the result.
     def compute_variants(self, norm_name: str) -> List[str]:
         """ Compute the spelling variants for the given normalized name
             and transliterate the result.
@@ -96,7 +95,6 @@ class GenericTokenAnalysis:
 
         return [name for name in self._transliterate_unique_list(norm_name, variants) if name]
 
 
         return [name for name in self._transliterate_unique_list(norm_name, variants) if name]
 
-
     def _transliterate_unique_list(self, norm_name: str,
                                    iterable: Iterable[str]) -> Iterator[Optional[str]]:
         seen = set()
     def _transliterate_unique_list(self, norm_name: str,
                                    iterable: Iterable[str]) -> Iterator[Optional[str]]:
         seen = set()
@@ -108,7 +106,6 @@ class GenericTokenAnalysis:
                 seen.add(variant)
                 yield self.to_ascii.transliterate(variant).strip()
 
                 seen.add(variant)
                 yield self.to_ascii.transliterate(variant).strip()
 
-
     def _generate_word_variants(self, norm_name: str) -> Iterable[str]:
         baseform = '^ ' + norm_name + ' ^'
         baselen = len(baseform)
     def _generate_word_variants(self, norm_name: str) -> Iterable[str]:
         baseform = '^ ' + norm_name + ' ^'
         baselen = len(baseform)
index be70b49dcd89841a86e9f3ac6f001309d7554a37..718cc468886af3b329a40a146f79e6435ac6597e 100644 (file)
@@ -16,6 +16,7 @@ from ...errors import UsageError
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 def _zigzag(outer: Iterable[str], inner: Iterable[str]) -> Iterator[str]:
     return itertools.chain.from_iterable(itertools.zip_longest(outer, inner, fillvalue=''))
 
 def _zigzag(outer: Iterable[str], inner: Iterable[str]) -> Iterator[str]:
     return itertools.chain.from_iterable(itertools.zip_longest(outer, inner, fillvalue=''))
 
@@ -36,7 +37,6 @@ class MutationVariantGenerator:
                       "This is not allowed.", pattern)
             raise UsageError("Bad mutation pattern in configuration.")
 
                       "This is not allowed.", pattern)
             raise UsageError("Bad mutation pattern in configuration.")
 
-
     def generate(self, names: Iterable[str]) -> Iterator[str]:
         """ Generator function for the name variants. 'names' is an iterable
             over a set of names for which the variants are to be generated.
     def generate(self, names: Iterable[str]) -> Iterator[str]:
         """ Generator function for the name variants. 'names' is an iterable
             over a set of names for which the variants are to be generated.
@@ -49,7 +49,6 @@ class MutationVariantGenerator:
                 for seps in self._fillers(len(parts)):
                     yield ''.join(_zigzag(parts, seps))
 
                 for seps in self._fillers(len(parts)):
                     yield ''.join(_zigzag(parts, seps))
 
-
     def _fillers(self, num_parts: int) -> Iterator[Tuple[str, ...]]:
         """ Returns a generator for strings to join the given number of string
             parts in all possible combinations.
     def _fillers(self, num_parts: int) -> Iterator[Tuple[str, ...]]:
         """ Returns a generator for strings to join the given number of string
             parts in all possible combinations.
index 5b1236f7433ef5dc4881ff0158ed4b6de0627ff5..f676fba751af73c229e869721f20484c5033f5c8 100644 (file)
@@ -19,16 +19,18 @@ RE_DIGIT_ALPHA = re.compile(r'(\d)\s*([^\d\s␣])')
 RE_ALPHA_DIGIT = re.compile(r'([^\s\d␣])\s*(\d)')
 RE_NAMED_PART = re.compile(r'[a-z]{4}')
 
 RE_ALPHA_DIGIT = re.compile(r'([^\s\d␣])\s*(\d)')
 RE_NAMED_PART = re.compile(r'[a-z]{4}')
 
-### Configuration section
+# Configuration section
+
 
 def configure(*_: Any) -> None:
     """ All behaviour is currently hard-coded.
     """
     return None
 
 
 def configure(*_: Any) -> None:
     """ All behaviour is currently hard-coded.
     """
     return None
 
-### Analysis section
+# Analysis section
+
 
 
-def create(normalizer: Any, transliterator: Any, config: None) -> 'HousenumberTokenAnalysis': # pylint: disable=W0613
+def create(normalizer: Any, transliterator: Any, config: None) -> 'HousenumberTokenAnalysis':
     """ Create a new token analysis instance for this module.
     """
     return HousenumberTokenAnalysis(normalizer, transliterator)
     """ Create a new token analysis instance for this module.
     """
     return HousenumberTokenAnalysis(normalizer, transliterator)
index 17c4e2a6e81a83a9bfaecc24d1e4072e693feb99..641ad7fdf8a77ab9b71103854fc760e66ec450bc 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) 2022 by the Nominatim developer community.
+# Copyright (C) 2024 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Specialized processor for postcodes. Supports a 'lookup' variant of the
 # For a full list of authors see the git log.
 """
 Specialized processor for postcodes. Supports a 'lookup' variant of the
@@ -13,16 +13,18 @@ from typing import Any, List
 from ...data.place_name import PlaceName
 from .generic_mutation import MutationVariantGenerator
 
 from ...data.place_name import PlaceName
 from .generic_mutation import MutationVariantGenerator
 
-### Configuration section
+# Configuration section
+
 
 def configure(*_: Any) -> None:
     """ All behaviour is currently hard-coded.
     """
     return None
 
 
 def configure(*_: Any) -> None:
     """ All behaviour is currently hard-coded.
     """
     return None
 
-### Analysis section
+# Analysis section
+
 
 
-def create(normalizer: Any, transliterator: Any, config: None) -> 'PostcodeTokenAnalysis': # pylint: disable=W0613
+def create(normalizer: Any, transliterator: Any, config: None) -> 'PostcodeTokenAnalysis':
     """ Create a new token analysis instance for this module.
     """
     return PostcodeTokenAnalysis(normalizer, transliterator)
     """ Create a new token analysis instance for this module.
     """
     return PostcodeTokenAnalysis(normalizer, transliterator)
@@ -44,13 +46,11 @@ class PostcodeTokenAnalysis:
 
         self.mutator = MutationVariantGenerator(' ', (' ', ''))
 
 
         self.mutator = MutationVariantGenerator(' ', (' ', ''))
 
-
     def get_canonical_id(self, name: PlaceName) -> str:
         """ Return the standard form of the postcode.
         """
         return name.name.strip().upper()
 
     def get_canonical_id(self, name: PlaceName) -> str:
         """ Return the standard form of the postcode.
         """
         return name.name.strip().upper()
 
-
     def compute_variants(self, norm_name: str) -> List[str]:
         """ Compute the spelling variants for the given normalized postcode.
 
     def compute_variants(self, norm_name: str) -> List[str]:
         """ Compute the spelling variants for the given normalized postcode.
 
index f9e2e6486f400814a2553aa40942fae49a22f061..c7f2efe226cb6e4fabddb4e694dc512b18099bae 100644 (file)
@@ -18,6 +18,7 @@ from .exec_utils import run_osm2pgsql
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 def _run_osm2pgsql(dsn: str, options: MutableMapping[str, Any]) -> None:
     run_osm2pgsql(options)
 
 def _run_osm2pgsql(dsn: str, options: MutableMapping[str, Any]) -> None:
     run_osm2pgsql(options)
 
index e70a7e50508abb8b5fcba78e5b147338e1205e51..b8e3cb5687161ca7e8a27e307c3b4c4e509d08ff 100644 (file)
@@ -22,6 +22,7 @@ from ..data.place_info import PlaceInfo
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 def _get_place_info(cursor: Cursor, osm_id: Optional[str],
                     place_id: Optional[int]) -> DictCursorResult:
     sql = """SELECT place_id, extra.*
 def _get_place_info(cursor: Cursor, osm_id: Optional[str],
                     place_id: Optional[int]) -> DictCursorResult:
     sql = """SELECT place_id, extra.*
index bad7fb9ee5620615e6cb7c02f7d60600be4beed8..79770142494821fc23bee2c63b72940911e43300 100644 (file)
@@ -12,7 +12,7 @@ from enum import Enum
 from textwrap import dedent
 
 from ..config import Configuration
 from textwrap import dedent
 
 from ..config import Configuration
-from ..db.connection import connect, Connection, server_version_tuple,\
+from ..db.connection import connect, Connection, server_version_tuple, \
                             index_exists, table_exists, execute_scalar
 from ..db import properties
 from ..errors import UsageError
                             index_exists, table_exists, execute_scalar
 from ..db import properties
 from ..errors import UsageError
@@ -22,6 +22,7 @@ from ..version import NOMINATIM_VERSION, parse_version
 
 CHECKLIST = []
 
 
 CHECKLIST = []
 
+
 class CheckState(Enum):
     """ Possible states of a check. FATAL stops check execution entirely.
     """
 class CheckState(Enum):
     """ Possible states of a check. FATAL stops check execution entirely.
     """
@@ -31,9 +32,11 @@ class CheckState(Enum):
     NOT_APPLICABLE = 3
     WARN = 4
 
     NOT_APPLICABLE = 3
     WARN = 4
 
+
 CheckResult = Union[CheckState, Tuple[CheckState, Mapping[str, Any]]]
 CheckFunc = Callable[[Connection, Configuration], CheckResult]
 
 CheckResult = Union[CheckState, Tuple[CheckState, Mapping[str, Any]]]
 CheckFunc = Callable[[Connection, Configuration], CheckResult]
 
+
 def _check(hint: Optional[str] = None) -> Callable[[CheckFunc], CheckFunc]:
     """ Decorator for checks. It adds the function to the list of
         checks to execute and adds the code for printing progress messages.
 def _check(hint: Optional[str] = None) -> Callable[[CheckFunc], CheckFunc]:
     """ Decorator for checks. It adds the function to the list of
         checks to execute and adds the code for printing progress messages.
@@ -68,6 +71,7 @@ def _check(hint: Optional[str] = None) -> Callable[[CheckFunc], CheckFunc]:
 
     return decorator
 
 
     return decorator
 
+
 class _BadConnection:
 
     def __init__(self, msg: str) -> None:
 class _BadConnection:
 
     def __init__(self, msg: str) -> None:
@@ -77,13 +81,14 @@ class _BadConnection:
         """ Dummy function to provide the implementation.
         """
 
         """ Dummy function to provide the implementation.
         """
 
+
 def check_database(config: Configuration) -> int:
     """ Run a number of checks on the database and return the status.
     """
     try:
         conn = connect(config.get_libpq_dsn())
     except UsageError as err:
 def check_database(config: Configuration) -> int:
     """ Run a number of checks on the database and return the status.
     """
     try:
         conn = connect(config.get_libpq_dsn())
     except UsageError as err:
-        conn = _BadConnection(str(err)) # type: ignore[assignment]
+        conn = _BadConnection(str(err))  # type: ignore[assignment]
 
     overall_result = 0
     for check in CHECKLIST:
 
     overall_result = 0
     for check in CHECKLIST:
@@ -110,7 +115,7 @@ def _get_indexes(conn: Connection) -> List[str]:
                'idx_osmline_parent_osm_id',
                'idx_postcode_id',
                'idx_postcode_postcode'
                'idx_osmline_parent_osm_id',
                'idx_postcode_id',
                'idx_postcode_postcode'
-              ]
+               ]
 
     # These won't exist if --reverse-only import was used
     if table_exists(conn, 'search_name'):
 
     # These won't exist if --reverse-only import was used
     if table_exists(conn, 'search_name'):
@@ -154,6 +159,7 @@ def check_connection(conn: Any, config: Configuration) -> CheckResult:
 
     return CheckState.OK
 
 
     return CheckState.OK
 
+
 @_check(hint="""\
              Database version ({db_version}) doesn't match Nominatim version ({nom_version})
 
 @_check(hint="""\
              Database version ({db_version}) doesn't match Nominatim version ({nom_version})
 
@@ -195,6 +201,7 @@ def check_database_version(conn: Connection, config: Configuration) -> CheckResu
                                   instruction=instruction,
                                   config=config)
 
                                   instruction=instruction,
                                   config=config)
 
+
 @_check(hint="""\
              placex table not found
 
 @_check(hint="""\
              placex table not found
 
@@ -274,7 +281,7 @@ def check_indexing(conn: Connection, _: Configuration) -> CheckResult:
         return CheckState.OK
 
     if freeze.is_frozen(conn):
         return CheckState.OK
 
     if freeze.is_frozen(conn):
-        index_cmd="""\
+        index_cmd = """\
             Database is marked frozen, it cannot be updated.
             Low counts of unindexed places are fine."""
         return CheckState.WARN, dict(count=cnt, index_cmd=index_cmd)
             Database is marked frozen, it cannot be updated.
             Low counts of unindexed places are fine."""
         return CheckState.WARN, dict(count=cnt, index_cmd=index_cmd)
index c5616c67c59f9d1d25b7215cabbadac5f3753eb5..fc921b207e84ef4eb5f57b76337eacd3882ed467 100644 (file)
@@ -132,8 +132,8 @@ def report_system_information(config: Configuration) -> None:
     - PostgreSQL version: {postgresql_ver}
     - PostGIS version: {postgis_ver}
     - OS: {os_name_info()}
     - PostgreSQL version: {postgresql_ver}
     - PostGIS version: {postgis_ver}
     - OS: {os_name_info()}
-    
-    
+
+
     **Hardware Configuration:**
     - RAM: {friendly_memory_string(psutil.virtual_memory().total)}
     - number of CPUs: {psutil.cpu_count(logical=False)}
     **Hardware Configuration:**
     - RAM: {friendly_memory_string(psutil.virtual_memory().total)}
     - number of CPUs: {psutil.cpu_count(logical=False)}
@@ -144,13 +144,13 @@ def report_system_information(config: Configuration) -> None:
     ```
     {run_command(["df", "-h"])}
     ```
     ```
     {run_command(["df", "-h"])}
     ```
-    
+
     **lsblk - list block devices: **
     ```
     {run_command("lsblk")}
     ```
     **lsblk - list block devices: **
     ```
     {run_command("lsblk")}
     ```
-    
-    
+
+
     **Postgresql Configuration:**
     ```
     {postgresql_config}
     **Postgresql Configuration:**
     ```
     {postgresql_config}
index d53527d181f4f670e9028b0cf27869751e3a9bfa..e3dae900be9c592253ab88ce40807ce2258932ef 100644 (file)
@@ -21,6 +21,7 @@ from nominatim_api.sql.sqlalchemy_types import Geometry, IntArray
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 async def convert(project_dir: Optional[Union[str, Path]],
                   outfile: Path, options: Set[str]) -> None:
     """ Export an existing database to sqlite. The resulting database
 async def convert(project_dir: Optional[Union[str, Path]],
                   outfile: Path, options: Set[str]) -> None:
     """ Export an existing database to sqlite. The resulting database
@@ -53,7 +54,6 @@ class SqliteWriter:
         self.dest = dest
         self.options = options
 
         self.dest = dest
         self.options = options
 
-
     async def write(self) -> None:
         """ Create the database structure and copy the data from
             the source database to the destination.
     async def write(self) -> None:
         """ Create the database structure and copy the data from
             the source database to the destination.
@@ -67,7 +67,6 @@ class SqliteWriter:
             await self.create_word_table()
         await self.create_indexes()
 
             await self.create_word_table()
         await self.create_indexes()
 
-
     async def create_tables(self) -> None:
         """ Set up the database tables.
         """
     async def create_tables(self) -> None:
         """ Set up the database tables.
         """
@@ -87,7 +86,6 @@ class SqliteWriter:
                         sa.func.RecoverGeometryColumn(table.name, col.name, 4326,
                                                       col.type.subtype.upper(), 'XY')))
 
                         sa.func.RecoverGeometryColumn(table.name, col.name, 4326,
                                                       col.type.subtype.upper(), 'XY')))
 
-
     async def create_class_tables(self) -> None:
         """ Set up the table that serve class/type-specific geometries.
         """
     async def create_class_tables(self) -> None:
         """ Set up the table that serve class/type-specific geometries.
         """
@@ -99,7 +97,6 @@ class SqliteWriter:
                          sa.Column('place_id', sa.BigInteger),
                          sa.Column('centroid', Geometry))
 
                          sa.Column('place_id', sa.BigInteger),
                          sa.Column('centroid', Geometry))
 
-
     async def create_word_table(self) -> None:
         """ Create the word table.
             This table needs the property information to determine the
     async def create_word_table(self) -> None:
         """ Create the word table.
             This table needs the property information to determine the
@@ -122,7 +119,6 @@ class SqliteWriter:
 
         await self.dest.connection.run_sync(sa.Index('idx_word_woken', dest.c.word_token).create)
 
 
         await self.dest.connection.run_sync(sa.Index('idx_word_woken', dest.c.word_token).create)
 
-
     async def copy_data(self) -> None:
         """ Copy data for all registered tables.
         """
     async def copy_data(self) -> None:
         """ Copy data for all registered tables.
         """
@@ -151,7 +147,6 @@ class SqliteWriter:
         data = [{'tablename': t} for t in self.dest.t.meta.tables]
         await self.dest.execute(pg_tables.insert().values(data))
 
         data = [{'tablename': t} for t in self.dest.t.meta.tables]
         await self.dest.execute(pg_tables.insert().values(data))
 
-
     async def create_indexes(self) -> None:
         """ Add indexes necessary for the frontend.
         """
     async def create_indexes(self) -> None:
         """ Add indexes necessary for the frontend.
         """
@@ -197,14 +192,12 @@ class SqliteWriter:
                     await self.dest.execute(sa.select(
                       sa.func.CreateSpatialIndex(t, 'centroid')))
 
                     await self.dest.execute(sa.select(
                       sa.func.CreateSpatialIndex(t, 'centroid')))
 
-
     async def create_spatial_index(self, table: str, column: str) -> None:
         """ Create a spatial index on the given table and column.
         """
         await self.dest.execute(sa.select(
                   sa.func.CreateSpatialIndex(getattr(self.dest.t, table).name, column)))
 
     async def create_spatial_index(self, table: str, column: str) -> None:
         """ Create a spatial index on the given table and column.
         """
         await self.dest.execute(sa.select(
                   sa.func.CreateSpatialIndex(getattr(self.dest.t, table).name, column)))
 
-
     async def create_index(self, table_name: str, column: str) -> None:
         """ Create a simple index on the given table and column.
         """
     async def create_index(self, table_name: str, column: str) -> None:
         """ Create a simple index on the given table and column.
         """
@@ -212,7 +205,6 @@ class SqliteWriter:
         await self.dest.connection.run_sync(
             sa.Index(f"idx_{table}_{column}", getattr(table.c, column)).create)
 
         await self.dest.connection.run_sync(
             sa.Index(f"idx_{table}_{column}", getattr(table.c, column)).create)
 
-
     async def create_search_index(self) -> None:
         """ Create the tables and indexes needed for word lookup.
         """
     async def create_search_index(self) -> None:
         """ Create the tables and indexes needed for word lookup.
         """
@@ -242,7 +234,6 @@ class SqliteWriter:
         await self.dest.connection.run_sync(
             sa.Index('idx_reverse_search_name_word', rsn.c.word).create)
 
         await self.dest.connection.run_sync(
             sa.Index('idx_reverse_search_name_word', rsn.c.word).create)
 
-
     def select_from(self, table: str) -> SaSelect:
         """ Create the SQL statement to select the source columns and rows.
         """
     def select_from(self, table: str) -> SaSelect:
         """ Create the SQL statement to select the source columns and rows.
         """
@@ -258,9 +249,9 @@ class SqliteWriter:
                                         columns.geometry),
                                        else_=sa.func.ST_SimplifyPreserveTopology(
                                                 columns.geometry, 0.0001)
                                         columns.geometry),
                                        else_=sa.func.ST_SimplifyPreserveTopology(
                                                 columns.geometry, 0.0001)
-                                )).label('geometry'))
+                                       )).label('geometry'))
 
         sql = sa.select(*(sa.func.ST_AsText(c).label(c.name)
 
         sql = sa.select(*(sa.func.ST_AsText(c).label(c.name)
-                             if isinstance(c.type, Geometry) else c for c in columns))
+                        if isinstance(c.type, Geometry) else c for c in columns))
 
         return sql
 
         return sql
index e96954ddd2df605e59618fd23e204c955649ef66..415e9d249f3277ce95bc048c9c8858b684cfd1c3 100644 (file)
@@ -20,7 +20,7 @@ from psycopg import sql as pysql
 
 from ..errors import UsageError
 from ..config import Configuration
 
 from ..errors import UsageError
 from ..config import Configuration
-from ..db.connection import connect, get_pg_env, Connection, server_version_tuple,\
+from ..db.connection import connect, get_pg_env, Connection, server_version_tuple, \
                             postgis_version_tuple, drop_tables, table_exists, execute_scalar
 from ..db.sql_preprocessor import SQLPreprocessor
 from ..db.query_pool import QueryPool
                             postgis_version_tuple, drop_tables, table_exists, execute_scalar
 from ..db.sql_preprocessor import SQLPreprocessor
 from ..db.query_pool import QueryPool
@@ -29,6 +29,7 @@ from ..version import POSTGRESQL_REQUIRED_VERSION, POSTGIS_REQUIRED_VERSION
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 def _require_version(module: str, actual: Tuple[int, int], expected: Tuple[int, int]) -> None:
     """ Compares the version for the given module and raises an exception
         if the actual version is too old.
 def _require_version(module: str, actual: Tuple[int, int], expected: Tuple[int, int]) -> None:
     """ Compares the version for the given module and raises an exception
         if the actual version is too old.
@@ -251,7 +252,7 @@ async def _progress_print() -> None:
 
 
 async def create_search_indices(conn: Connection, config: Configuration,
 
 
 async def create_search_indices(conn: Connection, config: Configuration,
-                          drop: bool = False, threads: int = 1) -> None:
+                                drop: bool = False, threads: int = 1) -> None:
     """ Create tables that have explicit partitioning.
     """
 
     """ Create tables that have explicit partitioning.
     """
 
index 4cbbf95d9b650c2e8d11f6c2b36b4d5c32e78c60..fc3a7465f9555bbb9013f77bc171ef40efc5c859 100644 (file)
@@ -35,7 +35,7 @@ def run_osm2pgsql(options: Mapping[str, Any]) -> None:
            '--number-processes', '1' if options['append'] else str(options['threads']),
            '--cache', str(options['osm2pgsql_cache']),
            '--style', str(options['osm2pgsql_style'])
            '--number-processes', '1' if options['append'] else str(options['threads']),
            '--cache', str(options['osm2pgsql_cache']),
            '--style', str(options['osm2pgsql_style'])
-          ]
+           ]
 
     if str(options['osm2pgsql_style']).endswith('.lua'):
         env['LUA_PATH'] = ';'.join((str(options['osm2pgsql_style_path'] / '?.lua'),
 
     if str(options['osm2pgsql_style']).endswith('.lua'):
         env['LUA_PATH'] = ';'.join((str(options['osm2pgsql_style_path'] / '?.lua'),
@@ -50,7 +50,6 @@ def run_osm2pgsql(options: Mapping[str, Any]) -> None:
         cmd.extend(('--output', 'gazetteer', '--hstore', '--latlon'))
         cmd.extend(_mk_tablespace_options('main', options))
 
         cmd.extend(('--output', 'gazetteer', '--hstore', '--latlon'))
         cmd.extend(_mk_tablespace_options('main', options))
 
-
     if options['flatnode_file']:
         cmd.extend(('--flat-nodes', options['flatnode_file']))
 
     if options['flatnode_file']:
         cmd.extend(('--flat-nodes', options['flatnode_file']))
 
index c4eedb43262029424b120072576de0e061b32d86..a308d0eb4572c936e8566bc00d43e52c39968f6e 100644 (file)
@@ -28,6 +28,7 @@ UPDATE_TABLES = [
     'wikipedia_%'
 ]
 
     'wikipedia_%'
 ]
 
+
 def drop_update_tables(conn: Connection) -> None:
     """ Drop all tables only necessary for updating the database from
         OSM replication data.
 def drop_update_tables(conn: Connection) -> None:
     """ Drop all tables only necessary for updating the database from
         OSM replication data.
@@ -49,8 +50,8 @@ def drop_flatnode_file(fpath: Optional[Path]) -> None:
     if fpath and fpath.exists():
         fpath.unlink()
 
     if fpath and fpath.exists():
         fpath.unlink()
 
+
 def is_frozen(conn: Connection) -> bool:
     """ Returns true if database is in a frozen state
     """
 def is_frozen(conn: Connection) -> bool:
     """ Returns true if database is in a frozen state
     """
-
     return table_exists(conn, 'place') is False
     return table_exists(conn, 'place') is False
index 12abe7fea5d3365ba28d4eb9380c6e0585825bda..80df29321af4d6d4b6a6d85d1264e7526d3f5a41 100644 (file)
@@ -13,7 +13,7 @@ import logging
 from ..errors import UsageError
 from ..config import Configuration
 from ..db import properties
 from ..errors import UsageError
 from ..config import Configuration
 from ..db import properties
-from ..db.connection import connect, Connection,\
+from ..db.connection import connect, Connection, \
                             table_exists, register_hstore
 from ..version import NominatimVersion, NOMINATIM_VERSION, parse_version
 from ..tokenizer import factory as tokenizer_factory
                             table_exists, register_hstore
 from ..version import NominatimVersion, NOMINATIM_VERSION, parse_version
 from ..tokenizer import factory as tokenizer_factory
@@ -21,7 +21,8 @@ from . import refresh
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
-_MIGRATION_FUNCTIONS : List[Tuple[NominatimVersion, Callable[..., None]]] = []
+_MIGRATION_FUNCTIONS: List[Tuple[NominatimVersion, Callable[..., None]]] = []
+
 
 def migrate(config: Configuration, paths: Any) -> int:
     """ Check for the current database version and execute migrations,
 
 def migrate(config: Configuration, paths: Any) -> int:
     """ Check for the current database version and execute migrations,
index 357b2bae027bef4be2917fe5952e03ca01b2ab75..4763aa03388062b2171dc14652c39bae00aa7b94 100644 (file)
@@ -25,6 +25,7 @@ from ..tokenizer.base import AbstractAnalyzer, AbstractTokenizer
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 def _to_float(numstr: str, max_value: float) -> float:
     """ Convert the number in string into a float. The number is expected
         to be in the range of [-max_value, max_value]. Otherwise rises a
 def _to_float(numstr: str, max_value: float) -> float:
     """ Convert the number in string into a float. The number is expected
         to be in the range of [-max_value, max_value]. Otherwise rises a
@@ -36,6 +37,7 @@ def _to_float(numstr: str, max_value: float) -> float:
 
     return num
 
 
     return num
 
+
 class _PostcodeCollector:
     """ Collector for postcodes of a single country.
     """
 class _PostcodeCollector:
     """ Collector for postcodes of a single country.
     """
@@ -46,7 +48,6 @@ class _PostcodeCollector:
         self.collected: Dict[str, PointsCentroid] = defaultdict(PointsCentroid)
         self.normalization_cache: Optional[Tuple[str, Optional[str]]] = None
 
         self.collected: Dict[str, PointsCentroid] = defaultdict(PointsCentroid)
         self.normalization_cache: Optional[Tuple[str, Optional[str]]] = None
 
-
     def add(self, postcode: str, x: float, y: float) -> None:
         """ Add the given postcode to the collection cache. If the postcode
             already existed, it is overwritten with the new centroid.
     def add(self, postcode: str, x: float, y: float) -> None:
         """ Add the given postcode to the collection cache. If the postcode
             already existed, it is overwritten with the new centroid.
@@ -63,7 +64,6 @@ class _PostcodeCollector:
             if normalized:
                 self.collected[normalized] += (x, y)
 
             if normalized:
                 self.collected[normalized] += (x, y)
 
-
     def commit(self, conn: Connection, analyzer: AbstractAnalyzer, project_dir: Path) -> None:
         """ Update postcodes for the country from the postcodes selected so far
             as well as any externally supplied postcodes.
     def commit(self, conn: Connection, analyzer: AbstractAnalyzer, project_dir: Path) -> None:
         """ Update postcodes for the country from the postcodes selected so far
             as well as any externally supplied postcodes.
@@ -97,9 +97,9 @@ class _PostcodeCollector:
                               """).format(pysql.Literal(self.country)),
                     to_update)
 
                               """).format(pysql.Literal(self.country)),
                     to_update)
 
-
-    def _compute_changes(self, conn: Connection) \
-          -> Tuple[List[Tuple[str, float, float]], List[str], List[Tuple[float, float, str]]]:
+    def _compute_changes(
+            self, conn: Connection
+            ) -> Tuple[List[Tuple[str, float, float]], List[str], List[Tuple[float, float, str]]]:
         """ Compute which postcodes from the collected postcodes have to be
             added or modified and which from the location_postcode table
             have to be deleted.
         """ Compute which postcodes from the collected postcodes have to be
             added or modified and which from the location_postcode table
             have to be deleted.
@@ -125,7 +125,6 @@ class _PostcodeCollector:
 
         return to_add, to_delete, to_update
 
 
         return to_add, to_delete, to_update
 
-
     def _update_from_external(self, analyzer: AbstractAnalyzer, project_dir: Path) -> None:
         """ Look for an external postcode file for the active country in
             the project directory and add missing postcodes when found.
     def _update_from_external(self, analyzer: AbstractAnalyzer, project_dir: Path) -> None:
         """ Look for an external postcode file for the active country in
             the project directory and add missing postcodes when found.
@@ -155,7 +154,6 @@ class _PostcodeCollector:
         finally:
             csvfile.close()
 
         finally:
             csvfile.close()
 
-
     def _open_external(self, project_dir: Path) -> Optional[TextIO]:
         fname = project_dir / f'{self.country}_postcodes.csv'
 
     def _open_external(self, project_dir: Path) -> Optional[TextIO]:
         fname = project_dir / f'{self.country}_postcodes.csv'
 
@@ -225,6 +223,7 @@ def update_postcodes(dsn: str, project_dir: Path, tokenizer: AbstractTokenizer)
 
         analyzer.update_postcodes_from_db()
 
 
         analyzer.update_postcodes_from_db()
 
+
 def can_compute(dsn: str) -> bool:
     """
         Check that the place table exists so that
 def can_compute(dsn: str) -> bool:
     """
         Check that the place table exists so that
index 557c43ae6fd95ee61b10b0a78bec5dad15bc3085..dc98fe4140b1b552abce67609dda467690a9772d 100644 (file)
@@ -16,7 +16,7 @@ from pathlib import Path
 from psycopg import sql as pysql
 
 from ..config import Configuration
 from psycopg import sql as pysql
 
 from ..config import Configuration
-from ..db.connection import Connection, connect, postgis_version_tuple,\
+from ..db.connection import Connection, connect, postgis_version_tuple, \
                             drop_tables
 from ..db.utils import execute_file
 from ..db.sql_preprocessor import SQLPreprocessor
                             drop_tables
 from ..db.utils import execute_file
 from ..db.sql_preprocessor import SQLPreprocessor
@@ -25,6 +25,7 @@ LOG = logging.getLogger()
 
 OSM_TYPE = {'N': 'node', 'W': 'way', 'R': 'relation'}
 
 
 OSM_TYPE = {'N': 'node', 'W': 'way', 'R': 'relation'}
 
+
 def _add_address_level_rows_from_entry(rows: MutableSequence[Tuple[Any, ...]],
                                        entry: Mapping[str, Any]) -> None:
     """ Converts a single entry from the JSON format for address rank
 def _add_address_level_rows_from_entry(rows: MutableSequence[Tuple[Any, ...]],
                                        entry: Mapping[str, Any]) -> None:
     """ Converts a single entry from the JSON format for address rank
@@ -51,7 +52,7 @@ def load_address_levels(conn: Connection, table: str, levels: Sequence[Mapping[s
         The table has the following columns:
             country, class, type, rank_search, rank_address
     """
         The table has the following columns:
             country, class, type, rank_search, rank_address
     """
-    rows: List[Tuple[Any, ...]]  = []
+    rows: List[Tuple[Any, ...]] = []
     for entry in levels:
         _add_address_level_rows_from_entry(rows, entry)
 
     for entry in levels:
         _add_address_level_rows_from_entry(rows, entry)
 
@@ -199,6 +200,7 @@ def import_secondary_importance(dsn: str, data_path: Path, ignore_errors: bool =
 
     return 0
 
 
     return 0
 
+
 def recompute_importance(conn: Connection) -> None:
     """ Recompute wikipedia links and importance for all entries in placex.
         This is a long-running operations that must not be executed in
 def recompute_importance(conn: Connection) -> None:
     """ Recompute wikipedia links and importance for all entries in placex.
         This is a long-running operations that must not be executed in
index eb031f390221c4dcea846f9d12999995ddb38011..082523cd7483d0bcd7a27dc7d99f1f6dccbc7a86 100644 (file)
@@ -33,6 +33,7 @@ except ModuleNotFoundError as exc:
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 def init_replication(conn: Connection, base_url: str,
                      socket_timeout: int = 60) -> None:
     """ Set up replication for the server at the given base URL.
 def init_replication(conn: Connection, base_url: str,
                      socket_timeout: int = 60) -> None:
     """ Set up replication for the server at the given base URL.
@@ -83,6 +84,7 @@ def check_for_updates(conn: Connection, base_url: str,
     LOG.warning("New data available (%i => %i).", seq, state.sequence)
     return 0
 
     LOG.warning("New data available (%i => %i).", seq, state.sequence)
     return 0
 
+
 class UpdateState(Enum):
     """ Possible states after an update has run.
     """
 class UpdateState(Enum):
     """ Possible states after an update has run.
     """
@@ -176,12 +178,12 @@ def _make_replication_server(url: str, timeout: int) -> ContextManager[Replicati
             """ Download a resource from the given URL and return a byte sequence
                 of the content.
             """
             """ Download a resource from the given URL and return a byte sequence
                 of the content.
             """
-            headers = {"User-Agent" : f"Nominatim (pyosmium/{pyo_version.pyosmium_release})"}
+            headers = {"User-Agent": f"Nominatim (pyosmium/{pyo_version.pyosmium_release})"}
 
             if self.session is not None:
                 return self.session.get(url.get_full_url(),
 
             if self.session is not None:
                 return self.session.get(url.get_full_url(),
-                                       headers=headers, timeout=timeout or None,
-                                       stream=True)
+                                        headers=headers, timeout=timeout or None,
+                                        stream=True)
 
             @contextmanager
             def _get_url_with_session() -> Iterator[requests.Response]:
 
             @contextmanager
             def _get_url_with_session() -> Iterator[requests.Response]:
index b197b8356762ac2e492c17605f3d21717267687c..e42715153421215817f51607d1d045238ee79255 100644 (file)
@@ -11,6 +11,7 @@
 import logging
 LOG = logging.getLogger()
 
 import logging
 LOG = logging.getLogger()
 
+
 class SpecialPhrasesImporterStatistics():
     """
         Class handling statistics of the import
 class SpecialPhrasesImporterStatistics():
     """
         Class handling statistics of the import
index db4806cdd034838065b5da62ed4864663345d4ac..9556b88424ab221292b4d7fb18e8ff3cb0aed57b 100644 (file)
@@ -16,6 +16,7 @@ import os
 from ...errors import UsageError
 from .special_phrase import SpecialPhrase
 
 from ...errors import UsageError
 from .special_phrase import SpecialPhrase
 
+
 class SPCsvLoader:
     """
         Handles loading of special phrases from external csv file.
 class SPCsvLoader:
     """
         Handles loading of special phrases from external csv file.
@@ -23,7 +24,6 @@ class SPCsvLoader:
     def __init__(self, csv_path: str) -> None:
         self.csv_path = csv_path
 
     def __init__(self, csv_path: str) -> None:
         self.csv_path = csv_path
 
-
     def generate_phrases(self) -> Iterable[SpecialPhrase]:
         """ Open and parse the given csv file.
             Create the corresponding SpecialPhrases.
     def generate_phrases(self) -> Iterable[SpecialPhrase]:
         """ Open and parse the given csv file.
             Create the corresponding SpecialPhrases.
@@ -35,7 +35,6 @@ class SPCsvLoader:
             for row in reader:
                 yield SpecialPhrase(row['phrase'], row['class'], row['type'], row['operator'])
 
             for row in reader:
                 yield SpecialPhrase(row['phrase'], row['class'], row['type'], row['operator'])
 
-
     def _check_csv_validity(self) -> None:
         """
             Check that the csv file has the right extension.
     def _check_csv_validity(self) -> None:
         """
             Check that the csv file has the right extension.
index 311e37e2010125571449dd4143adb0dd8c16a8a5..0e0d70946453885c28d63a38c9bb9b5389078250 100644 (file)
@@ -28,6 +28,7 @@ from ...tokenizer.base import AbstractTokenizer
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 def _classtype_table(phrase_class: str, phrase_type: str) -> str:
     """ Return the name of the table for the given class and type.
     """
 def _classtype_table(phrase_class: str, phrase_type: str) -> str:
     """ Return the name of the table for the given class and type.
     """
@@ -96,7 +97,6 @@ class SPImporter():
         LOG.warning('Import done.')
         self.statistics_handler.notify_import_done()
 
         LOG.warning('Import done.')
         self.statistics_handler.notify_import_done()
 
-
     def _fetch_existing_place_classtype_tables(self) -> None:
         """
             Fetch existing place_classtype tables.
     def _fetch_existing_place_classtype_tables(self) -> None:
         """
             Fetch existing place_classtype tables.
@@ -114,7 +114,7 @@ class SPImporter():
                 self.table_phrases_to_delete.add(row[0])
 
     def _load_white_and_black_lists(self) \
                 self.table_phrases_to_delete.add(row[0])
 
     def _load_white_and_black_lists(self) \
-          -> Tuple[Mapping[str, Sequence[str]], Mapping[str, Sequence[str]]]:
+            -> Tuple[Mapping[str, Sequence[str]], Mapping[str, Sequence[str]]]:
         """
             Load white and black lists from phrases-settings.json.
         """
         """
             Load white and black lists from phrases-settings.json.
         """
@@ -163,7 +163,6 @@ class SPImporter():
 
         return (phrase.p_class, phrase.p_type)
 
 
         return (phrase.p_class, phrase.p_type)
 
-
     def _create_classtype_table_and_indexes(self,
                                             class_type_pairs: Iterable[Tuple[str, str]]) -> None:
         """
     def _create_classtype_table_and_indexes(self,
                                             class_type_pairs: Iterable[Tuple[str, str]]) -> None:
         """
@@ -207,7 +206,6 @@ class SPImporter():
         with self.db_connection.cursor() as db_cursor:
             db_cursor.execute("DROP INDEX idx_placex_classtype")
 
         with self.db_connection.cursor() as db_cursor:
             db_cursor.execute("DROP INDEX idx_placex_classtype")
 
-
     def _create_place_classtype_table(self, sql_tablespace: str,
                                       phrase_class: str, phrase_type: str) -> None:
         """
     def _create_place_classtype_table(self, sql_tablespace: str,
                                       phrase_class: str, phrase_type: str) -> None:
         """
@@ -224,7 +222,6 @@ class SPImporter():
                              """).format(Identifier(table_name), SQL(sql_tablespace)),
                         (phrase_class, phrase_type))
 
                              """).format(Identifier(table_name), SQL(sql_tablespace)),
                         (phrase_class, phrase_type))
 
-
     def _create_place_classtype_indexes(self, sql_tablespace: str,
                                         phrase_class: str, phrase_type: str) -> None:
         """
     def _create_place_classtype_indexes(self, sql_tablespace: str,
                                         phrase_class: str, phrase_type: str) -> None:
         """
@@ -248,7 +245,6 @@ class SPImporter():
                                           Identifier(base_table),
                                           SQL(sql_tablespace)))
 
                                           Identifier(base_table),
                                           SQL(sql_tablespace)))
 
-
     def _grant_access_to_webuser(self, phrase_class: str, phrase_type: str) -> None:
         """
             Grant access on read to the table place_classtype for the webuser.
     def _grant_access_to_webuser(self, phrase_class: str, phrase_type: str) -> None:
         """
             Grant access on read to the table place_classtype for the webuser.
@@ -259,7 +255,6 @@ class SPImporter():
                               .format(Identifier(table_name),
                                       Identifier(self.config.DATABASE_WEBUSER)))
 
                               .format(Identifier(table_name),
                                       Identifier(self.config.DATABASE_WEBUSER)))
 
-
     def _remove_non_existent_tables_from_db(self) -> None:
         """
             Remove special phrases which doesn't exist on the wiki anymore.
     def _remove_non_existent_tables_from_db(self) -> None:
         """
             Remove special phrases which doesn't exist on the wiki anymore.
index 0fe7c0aa4ff9b69fb7e400bfbf54e09398297db7..9908f753bd81a652c6d22d177ad42b861d476de5 100644 (file)
@@ -17,6 +17,7 @@ from .special_phrase import SpecialPhrase
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 def _get_wiki_content(lang: str) -> str:
     """
         Request and return the wiki page's content
 def _get_wiki_content(lang: str) -> str:
     """
         Request and return the wiki page's content
@@ -43,12 +44,11 @@ class SPWikiLoader:
         self.type_fix_pattern = re.compile(r'\"|&quot;')
 
         self.languages = self.config.get_str_list('LANGUAGES') or \
         self.type_fix_pattern = re.compile(r'\"|&quot;')
 
         self.languages = self.config.get_str_list('LANGUAGES') or \
-                         ['af', 'ar', 'br', 'ca', 'cs', 'de', 'en', 'es',
-                          'et', 'eu', 'fa', 'fi', 'fr', 'gl', 'hr', 'hu',
-                          'ia', 'is', 'it', 'ja', 'mk', 'nl', 'no', 'pl',
-                          'ps', 'pt', 'ru', 'sk', 'sl', 'sv', 'uk', 'vi',
-                          'lv', 'tr']
-
+            ['af', 'ar', 'br', 'ca', 'cs', 'de', 'en', 'es',
+             'et', 'eu', 'fa', 'fi', 'fr', 'gl', 'hr', 'hu',
+             'ia', 'is', 'it', 'ja', 'mk', 'nl', 'no', 'pl',
+             'ps', 'pt', 'ru', 'sk', 'sl', 'sv', 'uk', 'vi',
+             'lv', 'tr']
 
     def generate_phrases(self) -> Iterable[SpecialPhrase]:
         """ Download the wiki pages for the configured languages
 
     def generate_phrases(self) -> Iterable[SpecialPhrase]:
         """ Download the wiki pages for the configured languages
index cf5c504848f8407eb9d9994a9cb8957dd57e1e6d..bb16258f0e563010a8c9f0ebd42ea4f92c5474ee 100644 (file)
@@ -12,6 +12,7 @@
 """
 from typing import Any
 
 """
 from typing import Any
 
+
 class SpecialPhrase:
     """
         Model representing a special phrase.
 class SpecialPhrase:
     """
         Model representing a special phrase.
@@ -29,9 +30,9 @@ class SpecialPhrase:
             return False
 
         return self.p_label == other.p_label \
             return False
 
         return self.p_label == other.p_label \
-               and self.p_class == other.p_class \
-               and self.p_type == other.p_type \
-               and self.p_operator == other.p_operator
+            and self.p_class == other.p_class \
+            and self.p_type == other.p_type \
+            and self.p_operator == other.p_operator
 
     def __hash__(self) -> int:
         return hash((self.p_label, self.p_class, self.p_type, self.p_operator))
 
     def __hash__(self) -> int:
         return hash((self.p_label, self.p_class, self.p_type, self.p_operator))
index f4a7eba770b618df52b91f33946a4b761110b52e..85110ae53bd13125ebd0bfb6e8a0ab7fd67a20f2 100644 (file)
@@ -27,6 +27,7 @@ from . import freeze
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 class TigerInput:
     """ Context manager that goes through Tiger input files which may
         either be in a directory or gzipped together in a tar file.
 class TigerInput:
     """ Context manager that goes through Tiger input files which may
         either be in a directory or gzipped together in a tar file.
@@ -38,7 +39,7 @@ class TigerInput:
 
         if data_dir.endswith('.tar.gz'):
             try:
 
         if data_dir.endswith('.tar.gz'):
             try:
-                self.tar_handle = tarfile.open(data_dir) # pylint: disable=consider-using-with
+                self.tar_handle = tarfile.open(data_dir)
             except tarfile.ReadError as err:
                 LOG.fatal("Cannot open '%s'. Is this a tar file?", data_dir)
                 raise UsageError("Cannot open Tiger data file.") from err
             except tarfile.ReadError as err:
                 LOG.fatal("Cannot open '%s'. Is this a tar file?", data_dir)
                 raise UsageError("Cannot open Tiger data file.") from err
@@ -53,11 +54,9 @@ class TigerInput:
         if not self.files:
             LOG.warning("Tiger data import selected but no files found at %s", data_dir)
 
         if not self.files:
             LOG.warning("Tiger data import selected but no files found at %s", data_dir)
 
-
     def __enter__(self) -> 'TigerInput':
         return self
 
     def __enter__(self) -> 'TigerInput':
         return self
 
-
     def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
         if self.tar_handle:
             self.tar_handle.close()
     def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
         if self.tar_handle:
             self.tar_handle.close()
@@ -77,7 +76,6 @@ class TigerInput:
 
         return open(cast(str, fname), encoding='utf-8')
 
 
         return open(cast(str, fname), encoding='utf-8')
 
-
     def __iter__(self) -> Iterator[Dict[str, Any]]:
         """ Iterate over the lines in each file.
         """
     def __iter__(self) -> Iterator[Dict[str, Any]]:
         """ Iterate over the lines in each file.
         """
@@ -87,7 +85,7 @@ class TigerInput:
 
 
 async def add_tiger_data(data_dir: str, config: Configuration, threads: int,
 
 
 async def add_tiger_data(data_dir: str, config: Configuration, threads: int,
-                   tokenizer: AbstractTokenizer) -> int:
+                         tokenizer: AbstractTokenizer) -> int:
     """ Import tiger data from directory or tar file `data dir`.
     """
     dsn = config.get_libpq_dsn()
     """ Import tiger data from directory or tar file `data dir`.
     """
     dsn = config.get_libpq_dsn()
index 6f0145c36e4d8753561476dcf61d3b55ad42f220..f26e1b0506b8b6ba96cecbe7bac28ff02bd30605 100644 (file)
@@ -11,9 +11,6 @@ Complex type definitions are moved here, to keep the source files readable.
 """
 from typing import Any, Union, Mapping, TypeVar, Sequence, TYPE_CHECKING
 
 """
 from typing import Any, Union, Mapping, TypeVar, Sequence, TYPE_CHECKING
 
-# Generics variable names do not confirm to naming styles, ignore globally here.
-# pylint: disable=invalid-name,abstract-method,multiple-statements
-# pylint: disable=missing-class-docstring,useless-import-alias
 
 if TYPE_CHECKING:
     import os
 
 if TYPE_CHECKING:
     import os
@@ -26,9 +23,11 @@ SysEnv = Mapping[str, str]
 
 T_ResultKey = TypeVar('T_ResultKey', int, str)
 
 
 T_ResultKey = TypeVar('T_ResultKey', int, str)
 
+
 class DictCursorResult(Mapping[str, Any]):
     def __getitem__(self, x: Union[int, str]) -> Any: ...
 
 class DictCursorResult(Mapping[str, Any]):
     def __getitem__(self, x: Union[int, str]) -> Any: ...
 
+
 DictCursorResults = Sequence[DictCursorResult]
 
 # The following typing features require typing_extensions to work
 DictCursorResults = Sequence[DictCursorResult]
 
 # The following typing features require typing_extensions to work
index 21a7c7799a40f5adaf9841a5df43edbe4018a0ec..a45d958b342214e31fb66153f738a11ecd06fd59 100644 (file)
@@ -10,6 +10,7 @@ Functions for computation of centroids.
 from typing import Tuple, Any
 from collections.abc import Collection
 
 from typing import Tuple, Any
 from collections.abc import Collection
 
+
 class PointsCentroid:
     """ Centroid computation from single points using an online algorithm.
         More points may be added at any time.
 class PointsCentroid:
     """ Centroid computation from single points using an online algorithm.
         More points may be added at any time.
@@ -32,11 +33,9 @@ class PointsCentroid:
         return (float(self.sum_x/self.count)/10000000,
                 float(self.sum_y/self.count)/10000000)
 
         return (float(self.sum_x/self.count)/10000000,
                 float(self.sum_y/self.count)/10000000)
 
-
     def __len__(self) -> int:
         return self.count
 
     def __len__(self) -> int:
         return self.count
 
-
     def __iadd__(self, other: Any) -> 'PointsCentroid':
         if isinstance(other, Collection) and len(other) == 2:
             if all(isinstance(p, (float, int)) for p in other):
     def __iadd__(self, other: Any) -> 'PointsCentroid':
         if isinstance(other, Collection) and len(other) == 2:
             if all(isinstance(p, (float, int)) for p in other):
index eb56f72ed3a9cf92c02619040e1a0801e12df9ee..e3446dc9a672caa31aed0ce8dc4c622222c30536 100644 (file)
@@ -7,7 +7,7 @@
 """
 Helper functions for accessing URL.
 """
 """
 Helper functions for accessing URL.
 """
-from typing import IO
+from typing import IO  # noqa
 import logging
 import urllib.request as urlrequest
 
 import logging
 import urllib.request as urlrequest
 
@@ -15,6 +15,7 @@ from ..version import NOMINATIM_VERSION
 
 LOG = logging.getLogger()
 
 
 LOG = logging.getLogger()
 
+
 def get_url(url: str) -> str:
     """ Get the contents from the given URL and return it as a UTF-8 string.
 
 def get_url(url: str) -> str:
     """ Get the contents from the given URL and return it as a UTF-8 string.
 
@@ -24,7 +25,7 @@ def get_url(url: str) -> str:
 
     try:
         request = urlrequest.Request(url, headers=headers)
 
     try:
         request = urlrequest.Request(url, headers=headers)
-        with urlrequest.urlopen(request) as response: # type: IO[bytes]
+        with urlrequest.urlopen(request) as response:  # type: IO[bytes]
             return response.read().decode('utf-8')
     except Exception:
         LOG.fatal('Failed to load URL: %s', url)
             return response.read().decode('utf-8')
     except Exception:
         LOG.fatal('Failed to load URL: %s', url)
index 8cc8e4fe3e0155619edd23453c92b67f19d93b63..76de017dca23ae6248d91fb07fac7b77a083ffa9 100644 (file)
@@ -9,8 +9,6 @@ Version information for Nominatim.
 """
 from typing import NamedTuple, Optional
 
 """
 from typing import NamedTuple, Optional
 
-# See also https://github.com/PyCQA/pylint/issues/6006
-# pylint: disable=useless-import-alias,unused-import
 
 class NominatimVersion(NamedTuple):
     """ Version information for Nominatim. We follow semantic versioning.
 
 class NominatimVersion(NamedTuple):
     """ Version information for Nominatim. We follow semantic versioning.
@@ -47,7 +45,6 @@ class NominatimVersion(NamedTuple):
         return f"{self.major}.{self.minor}.{self.patch_level}"
 
 
         return f"{self.major}.{self.minor}.{self.patch_level}"
 
 
-
 def parse_version(version: str) -> NominatimVersion:
     """ Parse a version string into a version consisting of a tuple of
         four ints: major, minor, patch level, database patch level
 def parse_version(version: str) -> NominatimVersion:
     """ Parse a version string into a version consisting of a tuple of
         four ints: major, minor, patch level, database patch level
@@ -68,4 +65,4 @@ OSM2PGSQL_REQUIRED_VERSION = (1, 8)
 # on every execution of 'make'.
 # cmake/tool-installed.tmpl is used to build the binary 'nominatim'. Inside
 # there is a call to set the variable value below.
 # on every execution of 'make'.
 # cmake/tool-installed.tmpl is used to build the binary 'nominatim'. Inside
 # there is a call to set the variable value below.
-GIT_COMMIT_HASH : Optional[str] = None
+GIT_COMMIT_HASH: Optional[str] = None