From a90bc6120c6cc612738ebedb6ca6961c50ab42dc Mon Sep 17 00:00:00 2001 From: Aric Coady Date: Sun, 20 Oct 2024 11:48:16 -0700 Subject: [PATCH] Python >=3.10 required. --- CHANGELOG.md | 1 + lupyne/engine/analyzers.py | 3 +-- lupyne/engine/documents.py | 7 +++---- lupyne/engine/indexers.py | 3 +-- lupyne/services/base.py | 5 ++--- lupyne/services/graphql.py | 8 ++++---- lupyne/services/rest.py | 3 +-- pyproject.toml | 3 +-- 8 files changed, 14 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0045993..0e08ccb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## Unreleased +* Python >=3.10 required * PyLucene >=10 required ## [3.3](https://pypi.org/project/lupyne/3.3/) - 2024-10-20 diff --git a/lupyne/engine/analyzers.py b/lupyne/engine/analyzers.py index 62ae0d6..cf589b1 100644 --- a/lupyne/engine/analyzers.py +++ b/lupyne/engine/analyzers.py @@ -1,5 +1,4 @@ from collections.abc import Callable, Iterable, Mapping -from typing import Optional import jcc # noqa: F401 needed for building docs from java.io import StringReader from java.lang import Float @@ -123,7 +122,7 @@ def components(self, field, reader=None): def createComponents(self, field): return analysis.Analyzer.TokenStreamComponents(*self.components(field)) - def tokens(self, text: str, field: Optional[str] = None) -> analysis.TokenStream: + def tokens(self, text: str, field: str | None = None) -> analysis.TokenStream: """Return lucene TokenStream from text.""" return self.components(field, StringReader(text))[1] diff --git a/lupyne/engine/documents.py b/lupyne/engine/documents.py index a530871..7d1939d 100644 --- a/lupyne/engine/documents.py +++ b/lupyne/engine/documents.py @@ -3,7 +3,6 @@ import datetime import operator from collections.abc import Callable, Iterator, Sequence -from typing import Optional, Union import lucene # noqa from java.lang import Long from java.util import Arrays, HashSet @@ -244,7 +243,7 @@ def items(self, *shapes: geo.Geometry) -> Iterator[document.Field]: if self.docvalues: yield self.apply(cls.createDocValueField, shape) - def distances(self, point: Union[geo.Point, geo.XYPoint]) -> search.SortField: + def distances(self, point: geo.Point | geo.XYPoint) -> search.SortField: """Return distance SortField.""" xy = isinstance(point, geo.XYGeometry) cls = document.XYDocValuesField if xy else document.LatLonDocValuesField @@ -403,7 +402,7 @@ def docvalues(self, field: str, type=None) -> dict: return self.searcher.docvalues(field, type).select(self.ids) def groupby( - self, func: Callable, count: Optional[int] = None, docs: Optional[int] = None + self, func: Callable, count: int | None = None, docs: int | None = None ) -> 'Groups': """Return ordered list of [Hits][lupyne.engine.documents.Hits] grouped by value of function applied to doc ids. @@ -489,7 +488,7 @@ def __iter__(self): return map(convert, self.allMatchingGroups) def search( - self, searcher, query: search.Query, count: Optional[int] = None, start: int = 0 + self, searcher, query: search.Query, count: int | None = None, start: int = 0 ) -> Groups: """Run query and return [Groups][lupyne.engine.documents.Groups].""" if count is None: diff --git a/lupyne/engine/indexers.py b/lupyne/engine/indexers.py index f649698..4bfc008 100644 --- a/lupyne/engine/indexers.py +++ b/lupyne/engine/indexers.py @@ -5,7 +5,6 @@ from collections.abc import Iterator, Mapping from functools import partial from pathlib import Path -from typing import Optional import lucene from java.io import File, IOException, StringReader from java.util import Arrays, HashSet @@ -462,7 +461,7 @@ def facets(self, query, *fields: str, **query_map: dict) -> dict: return counts def groupby( - self, field: str, query, count: Optional[int] = None, start: int = 0, **attrs + self, field: str, query, count: int | None = None, start: int = 0, **attrs ) -> Groups: """Return [Hits][lupyne.engine.documents.Hits] grouped by field using a [GroupingSearch][lupyne.engine.documents.GroupingSearch].""" diff --git a/lupyne/services/base.py b/lupyne/services/base.py index 58c48ca..3deb820 100644 --- a/lupyne/services/base.py +++ b/lupyne/services/base.py @@ -1,5 +1,4 @@ import time -from typing import Optional import graphql import lucene import strawberry @@ -37,7 +36,7 @@ class Document: """stored fields""" __annotations__ = { - field.name.value: Optional[convert(field.type)] for field in schema.get('Document', []) + field.name.value: convert(field.type) | None for field in schema.get('Document', []) } locals().update(dict.fromkeys(__annotations__)) locals().update(dict.fromkeys(multi_valued(__annotations__), ())) @@ -54,7 +53,7 @@ def __init__(self, **doc): class FieldDoc: """sort fields""" - __annotations__ = {name: Optional[sort_types[name]] for name in sort_types} + __annotations__ = {name: sort_types[name] | None for name in sort_types} locals().update(dict.fromkeys(__annotations__)) assert not multi_valued(__annotations__) diff --git a/lupyne/services/graphql.py b/lupyne/services/graphql.py index dafe1a3..47bae4e 100644 --- a/lupyne/services/graphql.py +++ b/lupyne/services/graphql.py @@ -3,7 +3,7 @@ import inspect import math from collections.abc import Callable -from typing import Annotated, Optional +from typing import Annotated import lucene import strawberry.asgi from starlette.applications import Starlette @@ -35,7 +35,7 @@ def doc_type(cls): return strawberry.type(cls, description=inspect.getdoc(cls)) -def doc_field(func: Optional[Callable] = None, **kwargs: str): +def doc_field(func: Callable | None = None, **kwargs: str): """Return strawberry field with argument and docstring descriptions.""" if func is None: return functools.partial(doc_field, **kwargs) @@ -74,7 +74,7 @@ class Hit: """search result""" id: int - score: Optional[float] + score: float | None if FieldDoc.__annotations__: # pragma: no branch sortkeys: FieldDoc if Document.__annotations__: # pragma: no branch @@ -122,7 +122,7 @@ def terms(self, info: Info) -> IndexedFields: count="maximum number of hits to retrieve", sort="sort by fields", ) - def search(self, info: Info, q: str, count: Optional[int] = None, sort: list[str] = []) -> Hits: + def search(self, info: Info, q: str, count: int | None = None, sort: list[str] = []) -> Hits: """Run query and return hits.""" selected = selections(*info.selected_fields) if 'hits' not in selected or count == 0: diff --git a/lupyne/services/rest.py b/lupyne/services/rest.py index 0c5703d..5ac633a 100644 --- a/lupyne/services/rest.py +++ b/lupyne/services/rest.py @@ -1,7 +1,6 @@ import contextlib import math import time -from typing import Union import lucene from fastapi import FastAPI from .settings import DEBUG, DIRECTORIES @@ -24,7 +23,7 @@ async def lifespan(app: FastAPI): # pragma: no cover @app.get('/terms/{name}') -def terms(name: str, *, counts: bool = False) -> Union[list, dict]: +def terms(name: str, *, counts: bool = False) -> list | dict: terms = root.searcher.terms(name, counts=counts) return (dict if counts else list)(terms) diff --git a/pyproject.toml b/pyproject.toml index b58322d..618aa7c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "lupyne" version = "3.3" description = "Pythonic search engine based on PyLucene." readme = "README.md" -requires-python = ">=3.9" +requires-python = ">=3.10" license = {file = "LICENSE.txt"} authors = [{name = "Aric Coady", email = "aric.coady@gmail.com"}] keywords = ["lucene", "pylucene"] @@ -13,7 +13,6 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12",