lupyne 3.2__tar.gz → 3.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. {lupyne-3.2 → lupyne-3.3}/PKG-INFO +2 -2
  2. {lupyne-3.2 → lupyne-3.3}/README.md +1 -1
  3. {lupyne-3.2 → lupyne-3.3}/lupyne/engine/__init__.py +1 -1
  4. {lupyne-3.2 → lupyne-3.3}/lupyne/engine/analyzers.py +1 -6
  5. {lupyne-3.2 → lupyne-3.3}/lupyne/engine/documents.py +7 -3
  6. {lupyne-3.2 → lupyne-3.3}/lupyne/engine/indexers.py +6 -14
  7. {lupyne-3.2 → lupyne-3.3}/lupyne/engine/queries.py +3 -3
  8. {lupyne-3.2 → lupyne-3.3}/lupyne/engine/utils.py +1 -1
  9. {lupyne-3.2 → lupyne-3.3}/lupyne.egg-info/PKG-INFO +2 -2
  10. {lupyne-3.2 → lupyne-3.3}/pyproject.toml +1 -2
  11. {lupyne-3.2 → lupyne-3.3}/tests/test_engine.py +0 -7
  12. {lupyne-3.2 → lupyne-3.3}/LICENSE.txt +0 -0
  13. {lupyne-3.2 → lupyne-3.3}/lupyne/__init__.py +0 -0
  14. {lupyne-3.2 → lupyne-3.3}/lupyne/py.typed +0 -0
  15. {lupyne-3.2 → lupyne-3.3}/lupyne/services/__init__.py +0 -0
  16. {lupyne-3.2 → lupyne-3.3}/lupyne/services/base.py +0 -0
  17. {lupyne-3.2 → lupyne-3.3}/lupyne/services/graphql.py +0 -0
  18. {lupyne-3.2 → lupyne-3.3}/lupyne/services/rest.py +0 -0
  19. {lupyne-3.2 → lupyne-3.3}/lupyne/services/settings.py +0 -0
  20. {lupyne-3.2 → lupyne-3.3}/lupyne.egg-info/SOURCES.txt +0 -0
  21. {lupyne-3.2 → lupyne-3.3}/lupyne.egg-info/dependency_links.txt +0 -0
  22. {lupyne-3.2 → lupyne-3.3}/lupyne.egg-info/requires.txt +0 -0
  23. {lupyne-3.2 → lupyne-3.3}/lupyne.egg-info/top_level.txt +0 -0
  24. {lupyne-3.2 → lupyne-3.3}/setup.cfg +0 -0
  25. {lupyne-3.2 → lupyne-3.3}/tests/test_graphql.py +0 -0
  26. {lupyne-3.2 → lupyne-3.3}/tests/test_rest.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lupyne
3
- Version: 3.2
3
+ Version: 3.3
4
4
  Summary: Pythonic search engine based on PyLucene.
5
5
  Author-email: Aric Coady <aric.coady@gmail.com>
6
6
  License: Copyright 2022 Aric Coady
@@ -92,7 +92,7 @@ PyLucene is not `pip` installable.
92
92
  * [Homebrew](https://brew.sh) formula: `brew install coady/tap/pylucene`
93
93
 
94
94
  ## Dependencies
95
- * PyLucene >=9.6
95
+ * PyLucene >=9.12
96
96
  * strawberry-graphql (if graphql option)
97
97
  * fastapi (if rest option)
98
98
 
@@ -45,7 +45,7 @@ PyLucene is not `pip` installable.
45
45
  * [Homebrew](https://brew.sh) formula: `brew install coady/tap/pylucene`
46
46
 
47
47
  ## Dependencies
48
- * PyLucene >=9.6
48
+ * PyLucene >=9.12
49
49
  * strawberry-graphql (if graphql option)
50
50
  * fastapi (if rest option)
51
51
 
@@ -12,4 +12,4 @@ from .documents import Document, Field, NestedField, DateTimeField, ShapeField
12
12
  from .indexers import IndexSearcher, MultiSearcher, IndexWriter, Indexer # noqa
13
13
 
14
14
  version = tuple(map(int, lucene.VERSION.split('.')))
15
- assert version >= (9, 6), version
15
+ assert version >= (9, 12), version
@@ -7,7 +7,6 @@ from java.util import HashMap
7
7
  from org.apache.lucene import analysis, queryparser, search, util
8
8
  from org.apache.lucene.search import uhighlight
9
9
  from org.apache.pylucene.analysis import PythonAnalyzer, PythonTokenFilter
10
- from org.apache.pylucene.queryparser.classic import PythonQueryParser
11
10
 
12
11
 
13
12
  class TokenStream(analysis.TokenStream):
@@ -155,11 +154,7 @@ class Analyzer(PythonAnalyzer):
155
154
  setattr(parser, name, value)
156
155
  if isinstance(parser, queryparser.classic.MultiFieldQueryParser):
157
156
  return parser.parse(parser, query)
158
- try:
159
- return parser.parse(query)
160
- finally:
161
- if isinstance(parser, PythonQueryParser):
162
- parser.finalize()
157
+ return parser.parse(query)
163
158
 
164
159
  def highlight(self, query: search.Query, field: str, content: str, count: int = 1) -> str:
165
160
  """Return highlighted content.
@@ -348,7 +348,7 @@ class Hits:
348
348
  self.searcher, self.scoredocs = searcher, scoredocs
349
349
  if hasattr(count, 'relation'):
350
350
  cls = int if count.relation == search.TotalHits.Relation.EQUAL_TO else float
351
- count = cls(count.value)
351
+ count = cls(count.value() if lucene.VERSION.startswith('10.') else count.value)
352
352
  self.count, self.fields = count, fields
353
353
 
354
354
  def select(self, *fields: str):
@@ -450,8 +450,12 @@ class Groups:
450
450
  def __getitem__(self, index):
451
451
  hits = groupdocs = self.groupdocs[index]
452
452
  if isinstance(groupdocs, grouping.GroupDocs):
453
- hits = Hits(self.searcher, groupdocs.scoreDocs, groupdocs.totalHits)
454
- hits.value = convert(groupdocs.groupValue)
453
+ if lucene.VERSION.startswith('10.'): # pragma: no cover
454
+ hits = Hits(self.searcher, groupdocs.scoreDocs(), groupdocs.totalHits())
455
+ hits.value = convert(groupdocs.groupValue())
456
+ else:
457
+ hits = Hits(self.searcher, groupdocs.scoreDocs, groupdocs.totalHits)
458
+ hits.value = convert(groupdocs.groupValue)
455
459
  hits.fields = self.fields
456
460
  return hits
457
461
 
@@ -273,7 +273,7 @@ class IndexReader:
273
273
  yield doc, list(positions)
274
274
 
275
275
  def vector(self, id, field):
276
- terms = self.getTermVector(id, field)
276
+ terms = self.termVectors().get(id, field)
277
277
  termsenum = terms.iterator() if terms else index.TermsEnum.EMPTY
278
278
  terms = map(operator.methodcaller('utf8ToString'), util.BytesRefIterator.cast_(termsenum))
279
279
  return termsenum, terms
@@ -373,7 +373,7 @@ class IndexSearcher(search.IndexSearcher, IndexReader):
373
373
  yield (doc + offset), values
374
374
  offset += reader.maxDoc()
375
375
 
376
- def parse(self, query, spellcheck=False, **kwargs):
376
+ def parse(self, query, spellcheck=False, **kwargs) -> search.Query:
377
377
  if isinstance(query, search.Query):
378
378
  return query
379
379
  if spellcheck:
@@ -394,8 +394,7 @@ class IndexSearcher(search.IndexSearcher, IndexReader):
394
394
  """
395
395
  if len(query) > 1:
396
396
  return self.docFreq(index.Term(*query))
397
- query = self.parse(*query, **options) if query else Query.alldocs()
398
- return super().count(query)
397
+ return super().count(self.parse(*query, **options) if query else Query.alldocs())
399
398
 
400
399
  def collector(self, count=None, sort=None, reverse=False, scores=False, mincount=1000):
401
400
  if count is None:
@@ -403,12 +402,12 @@ class IndexSearcher(search.IndexSearcher, IndexReader):
403
402
  count = min(count, self.maxDoc() or 1)
404
403
  mincount = max(count, mincount)
405
404
  if sort is None:
406
- return search.TopScoreDocCollector.create(count, mincount)
405
+ return search.TopScoreDocCollectorManager(count, mincount).newCollector()
407
406
  if isinstance(sort, str):
408
407
  sort = self.sortfield(sort, reverse=reverse)
409
408
  if not isinstance(sort, search.Sort):
410
409
  sort = search.Sort(sort)
411
- return search.TopFieldCollector.create(sort, count, mincount)
410
+ return search.TopFieldCollectorManager(sort, count, mincount).newCollector()
412
411
 
413
412
  def search(
414
413
  self,
@@ -418,7 +417,6 @@ class IndexSearcher(search.IndexSearcher, IndexReader):
418
417
  reverse=False,
419
418
  scores=False,
420
419
  mincount=1000,
421
- timeout=None,
422
420
  **parser,
423
421
  ) -> Hits:
424
422
  """Run query and return [Hits][lupyne.engine.documents.Hits].
@@ -433,17 +431,11 @@ class IndexSearcher(search.IndexSearcher, IndexReader):
433
431
  reverse: reverse flag used with sort
434
432
  scores: compute scores for candidate results when sorting
435
433
  mincount: total hit count accuracy threshold
436
- timeout: stop search after elapsed number of seconds
437
434
  **parser: [parse][lupyne.engine.analyzers.Analyzer.parse]` options
438
435
  """
439
436
  query = Query.alldocs() if query is None else self.parse(query, **parser)
440
437
  results = cache = collector = self.collector(count, sort, reverse, scores, mincount)
441
- counter = search.TimeLimitingCollector.getGlobalCounter()
442
- if timeout is not None:
443
- results = search.TimeLimitingCollector(collector, counter, int(timeout * 1000))
444
- with suppress(search.TimeLimitingCollector.TimeExceededException):
445
- super().search(query, results)
446
- timeout = None
438
+ super().search(query, results)
447
439
  if isinstance(cache, search.CachingCollector):
448
440
  collector = search.TotalHitCountCollector()
449
441
  cache.replay(collector)
@@ -1,4 +1,4 @@
1
- from collections.abc import Callable, Iterable, Iterator
1
+ from collections.abc import Callable, Iterable
2
2
  import lucene # noqa
3
3
  from java.lang import Double, Integer, Long
4
4
  from java.util import Arrays
@@ -27,7 +27,7 @@ class Query:
27
27
  @classmethod
28
28
  def terms(cls, name: str, values) -> 'Query':
29
29
  """Return lucene TermInSetQuery, optimizing a SHOULD BooleanQuery of many terms."""
30
- return cls(search.TermInSetQuery, name, list(map(util.BytesRef, values)))
30
+ return cls(search.TermInSetQuery, name, Arrays.asList(list(map(util.BytesRef, values))))
31
31
 
32
32
  @classmethod
33
33
  def boolean(cls, occur, *queries, **terms):
@@ -274,8 +274,8 @@ class DocValues:
274
274
 
275
275
  class SortedSet(Sorted):
276
276
  def __getitem__(self, id: int):
277
- ords: Iterator = iter(self.docvalues.nextOrd, self.docvalues.NO_MORE_ORDS)
278
277
  if self.docvalues.advanceExact(id):
278
+ ords = (self.docvalues.nextOrd() for _ in range(self.docvalues.docValueCount()))
279
279
  return tuple(self.type(self.docvalues.lookupOrd(ord)) for ord in ords)
280
280
 
281
281
 
@@ -23,7 +23,7 @@ def suppress(exception):
23
23
  """Suppress specific lucene exception."""
24
24
  try:
25
25
  yield
26
- except lucene.JavaError as exc:
26
+ except lucene.JavaError as exc: # pragma: no cover
27
27
  if not exception.instance_(exc.getJavaException()):
28
28
  raise
29
29
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lupyne
3
- Version: 3.2
3
+ Version: 3.3
4
4
  Summary: Pythonic search engine based on PyLucene.
5
5
  Author-email: Aric Coady <aric.coady@gmail.com>
6
6
  License: Copyright 2022 Aric Coady
@@ -92,7 +92,7 @@ PyLucene is not `pip` installable.
92
92
  * [Homebrew](https://brew.sh) formula: `brew install coady/tap/pylucene`
93
93
 
94
94
  ## Dependencies
95
- * PyLucene >=9.6
95
+ * PyLucene >=9.12
96
96
  * strawberry-graphql (if graphql option)
97
97
  * fastapi (if rest option)
98
98
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "lupyne"
3
- version = "3.2"
3
+ version = "3.3"
4
4
  description = "Pythonic search engine based on PyLucene."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9"
@@ -37,7 +37,6 @@ graphql = ["strawberry-graphql[asgi]>=0.221"]
37
37
 
38
38
  [tool.ruff]
39
39
  line-length = 100
40
- extend-include = ["*.ipynb"]
41
40
 
42
41
  [tool.ruff.format]
43
42
  quote-style = "preserve"
@@ -398,10 +398,6 @@ def test_grouping(tempdir, indexer, zipcodes):
398
398
  assert all(grouping.search(indexer.indexSearcher, Q.alldocs()).facets.values())
399
399
  assert len(grouping) == len(list(grouping)) > 100
400
400
  assert set(grouping) > set(facets)
401
- hits = indexer.search(query, timeout=-1)
402
- assert not hits and not hits.count and math.isnan(hits.maxscore)
403
- hits = indexer.search(query, timeout=10)
404
- assert len(hits) == hits.count == indexer.count(query) and hits.maxscore == 1.0
405
401
  directory = store.ByteBuffersDirectory()
406
402
  query = Q.term('state', 'CA')
407
403
  size = indexer.copy(directory, query)
@@ -465,9 +461,6 @@ def test_fields(indexer, constitution):
465
461
  engine.Field('', stored='invalid')
466
462
  with pytest.raises(AttributeError):
467
463
  engine.Field('', invalid=None)
468
- with pytest.raises(lucene.JavaError):
469
- with engine.utils.suppress(search.TimeLimitingCollector.TimeExceededException):
470
- document.Field('name', 'value', document.FieldType())
471
464
  assert str(engine.Field.String('')) == str(
472
465
  document.StringField('', '', document.Field.Store.NO).fieldType()
473
466
  )
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes