polars-corpus 0.2.0__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.
- polars_corpus-0.2.0/.cargo/config.toml +7 -0
- polars_corpus-0.2.0/.gitignore +40 -0
- polars_corpus-0.2.0/AGENTS.md +96 -0
- polars_corpus-0.2.0/CLAUDE.md +1 -0
- polars_corpus-0.2.0/Cargo.lock +3678 -0
- polars_corpus-0.2.0/Cargo.toml +54 -0
- polars_corpus-0.2.0/DEVELOPMENT_STATUS.md +257 -0
- polars_corpus-0.2.0/LICENSE.txt +21 -0
- polars_corpus-0.2.0/Makefile +35 -0
- polars_corpus-0.2.0/PKG-INFO +107 -0
- polars_corpus-0.2.0/README.md +61 -0
- polars_corpus-0.2.0/pyproject.toml +110 -0
- polars_corpus-0.2.0/python/polars_corpus/__init__.py +29 -0
- polars_corpus-0.2.0/python/polars_corpus/_internal.pyi +100 -0
- polars_corpus-0.2.0/python/polars_corpus/_typing.py +26 -0
- polars_corpus-0.2.0/python/polars_corpus/assoc.py +1221 -0
- polars_corpus-0.2.0/python/polars_corpus/chunk.py +120 -0
- polars_corpus-0.2.0/python/polars_corpus/collocations.py +237 -0
- polars_corpus-0.2.0/python/polars_corpus/convert.py +587 -0
- polars_corpus-0.2.0/python/polars_corpus/corpus_io.py +378 -0
- polars_corpus-0.2.0/python/polars_corpus/cqp_parser.py +218 -0
- polars_corpus-0.2.0/python/polars_corpus/dispersion.py +281 -0
- polars_corpus-0.2.0/python/polars_corpus/embeddings.py +213 -0
- polars_corpus-0.2.0/python/polars_corpus/exprs.py +820 -0
- polars_corpus-0.2.0/python/polars_corpus/frequency.py +150 -0
- polars_corpus-0.2.0/python/polars_corpus/keywords.py +350 -0
- polars_corpus-0.2.0/python/polars_corpus/lexical.py +261 -0
- polars_corpus-0.2.0/python/polars_corpus/matcher.py +397 -0
- polars_corpus-0.2.0/python/polars_corpus/search.py +1524 -0
- polars_corpus-0.2.0/python/polars_corpus/simple_parser.py +349 -0
- polars_corpus-0.2.0/python/polars_corpus/utils.py +342 -0
- polars_corpus-0.2.0/python/polars_corpus/view.py +797 -0
- polars_corpus-0.2.0/python/polars_corpus/visualizations.py +441 -0
- polars_corpus-0.2.0/python/tests/__init__.py +0 -0
- polars_corpus-0.2.0/python/tests/helpers.py +46 -0
- polars_corpus-0.2.0/python/tests/test_assoc.py +557 -0
- polars_corpus-0.2.0/python/tests/test_collocations.py +342 -0
- polars_corpus-0.2.0/python/tests/test_concordance.py +775 -0
- polars_corpus-0.2.0/python/tests/test_convert.py +249 -0
- polars_corpus-0.2.0/python/tests/test_dispersion.py +370 -0
- polars_corpus-0.2.0/python/tests/test_embeddings.py +305 -0
- polars_corpus-0.2.0/python/tests/test_frequency.py +211 -0
- polars_corpus-0.2.0/python/tests/test_keywords.py +432 -0
- polars_corpus-0.2.0/python/tests/test_lazy_search.py +374 -0
- polars_corpus-0.2.0/python/tests/test_lexical.py +262 -0
- polars_corpus-0.2.0/python/tests/test_matcher.py +496 -0
- polars_corpus-0.2.0/python/tests/test_simple_query.py +485 -0
- polars_corpus-0.2.0/python/tests/test_spans.py +267 -0
- polars_corpus-0.2.0/python/tests/test_text_corpus_reader.py +96 -0
- polars_corpus-0.2.0/python/tests/test_utils.py +345 -0
- polars_corpus-0.2.0/python/tests/test_view.py +166 -0
- polars_corpus-0.2.0/python/tests/test_visualizations.py +222 -0
- polars_corpus-0.2.0/python/tests/test_wlp_corpus_reader.py +233 -0
- polars_corpus-0.2.0/rust-toolchain.toml +2 -0
- polars_corpus-0.2.0/rustfmt.toml +3 -0
- polars_corpus-0.2.0/src/assoc.rs +213 -0
- polars_corpus-0.2.0/src/io.rs +157 -0
- polars_corpus-0.2.0/src/lexical.rs +90 -0
- polars_corpus-0.2.0/src/lib.rs +34 -0
- polars_corpus-0.2.0/src/matcher.rs +262 -0
- polars_corpus-0.2.0/src/span.rs +409 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
*.so
|
|
9
|
+
*.dll
|
|
10
|
+
*.pyd
|
|
11
|
+
target/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# Virtual environments
|
|
15
|
+
.venv
|
|
16
|
+
.env
|
|
17
|
+
|
|
18
|
+
# IDEs
|
|
19
|
+
.idea/
|
|
20
|
+
.ipynb_checkpoints/
|
|
21
|
+
|
|
22
|
+
site/
|
|
23
|
+
.coverage
|
|
24
|
+
# Claude Code: shared project config is tracked, per-machine settings are not.
|
|
25
|
+
.claude/*
|
|
26
|
+
!.claude/skills/
|
|
27
|
+
!.claude/commands/
|
|
28
|
+
.pytest_cache/
|
|
29
|
+
stuff/
|
|
30
|
+
.DS_Store
|
|
31
|
+
*.parquet
|
|
32
|
+
/.quarto/
|
|
33
|
+
**/*.quarto_ipynb
|
|
34
|
+
/_site/
|
|
35
|
+
/objects.json
|
|
36
|
+
/site/
|
|
37
|
+
scratch.ipynb
|
|
38
|
+
/scratch.py
|
|
39
|
+
.cache/
|
|
40
|
+
data/
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
`polars-corpus` is a hybrid Python/Rust extension for Polars providing corpus
|
|
5
|
+
search, concordancing, and statistical measures: high-level APIs in Python, the
|
|
6
|
+
matching engine in Rust, bridged zero-copy by pyo3-polars and hung off Polars
|
|
7
|
+
frames and exprs as a `.corpus` namespace. Designed to comfortably handle 100M+
|
|
8
|
+
word corpora on 16GB memory. Target audience: linguists and data scientists,
|
|
9
|
+
especially students.
|
|
10
|
+
|
|
11
|
+
## Development Workflow
|
|
12
|
+
```bash
|
|
13
|
+
ruff format && ruff check # Format and lint Python
|
|
14
|
+
cargo fmt && cargo clippy # Format and lint Rust
|
|
15
|
+
pyrefly check python/polars_corpus/
|
|
16
|
+
pytest # Python changes need no rebuild
|
|
17
|
+
make develop # Rebuild after Rust changes (required); ~1s
|
|
18
|
+
make develop-release # Same, release profile (benchmarking)
|
|
19
|
+
make grid # Test 3.11-3.14 x oldest/newest polars
|
|
20
|
+
make build # Distribution wheels (slow: full LTO)
|
|
21
|
+
make docs # Build the user guide
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Environment
|
|
25
|
+
The venv lives **outside** the source tree, at `~/.venvs/polars_corpus`, and is
|
|
26
|
+
activated automatically by a shell extension. Run `pytest`, `ruff`, etc.
|
|
27
|
+
directly -- do **not** prefix them with `uv run`, which would create a `./.venv`
|
|
28
|
+
here. That breaks two things: this directory is synced via Dropbox to machines
|
|
29
|
+
with different paths, and nltk's `inisec` import guard rejects any module
|
|
30
|
+
resolving under the cwd, so a venv in the project root makes `import nltk` fail
|
|
31
|
+
during test collection.
|
|
32
|
+
|
|
33
|
+
## Dependencies
|
|
34
|
+
All declared in `pyproject.toml` and pinned by `uv.lock` (both tracked):
|
|
35
|
+
- `[project] dependencies`: runtime
|
|
36
|
+
- `[project.optional-dependencies] examples`: published extra for end users
|
|
37
|
+
- `[dependency-groups] dev`: development tools (pytest, pyrefly, maturin, ...)
|
|
38
|
+
- `[dependency-groups] notebooks`: `dev` plus what the example notebooks import
|
|
39
|
+
|
|
40
|
+
Re-resolve with `uv lock` after editing `pyproject.toml`. It only writes the
|
|
41
|
+
lockfile and does not touch the venv, so it is safe to run here.
|
|
42
|
+
|
|
43
|
+
## Data Format
|
|
44
|
+
DataFrame with: `token`, `pos`/`c5`, `mode`, `file_id`, plus annotation columns.
|
|
45
|
+
Column names are defaults, not requirements: every function that reads one of
|
|
46
|
+
these roles takes a `*_column` parameter to point it elsewhere.
|
|
47
|
+
|
|
48
|
+
## Query Languages
|
|
49
|
+
The package supports Simple (BNCweb-style) and CQP query syntaxes. See
|
|
50
|
+
[docs/simple_query.md](docs/simple_query.md) for the Simple language; the CQP
|
|
51
|
+
grammar in `cqp_parser.py` and the `search_cqp()` docstring cover the other.
|
|
52
|
+
|
|
53
|
+
## Coding Standards
|
|
54
|
+
- Use numpy-style docstrings. Keep them minimal, focused on API usage
|
|
55
|
+
- Use **parameterized tests** when possible
|
|
56
|
+
- Avoid code bloat - keep implementations focused
|
|
57
|
+
- **Avoid gratuitous defensive programming**: validate inputs at public APIs and
|
|
58
|
+
give helpful error messages; trust invariants in internal functions. Use
|
|
59
|
+
assertions for debugging, not runtime validation of established invariants
|
|
60
|
+
|
|
61
|
+
### Design principles
|
|
62
|
+
1. When possible, functions should take exprs and return exprs.
|
|
63
|
+
2. When a function must take a frame, prefer accepting both DataFrame and
|
|
64
|
+
LazyFrame, and return whichever type it was given.
|
|
65
|
+
3. Work lazily inside even when given a DataFrame; principle 2 decides the
|
|
66
|
+
return type.
|
|
67
|
+
4. When a function can only work on a DataFrame, check up front and raise
|
|
68
|
+
an error if given a LazyFrame.
|
|
69
|
+
|
|
70
|
+
### Public functions
|
|
71
|
+
Student-facing functions share a shape, with the pieces in `utils.py`
|
|
72
|
+
(internal, so not in its `__all__`):
|
|
73
|
+
```python
|
|
74
|
+
def analyze(corpus, expr, method="ll", file_id_column="file_id"):
|
|
75
|
+
method = check_choice(method, METHODS) # names the options, suggests near misses
|
|
76
|
+
term = as_expr(expr) # column name or expression
|
|
77
|
+
lf = as_corpus(corpus) # rejects non-frames and empty frames
|
|
78
|
+
check_columns(lf, [file_id_column], param="file_id_column")
|
|
79
|
+
... # all internal work lazy
|
|
80
|
+
return collect_like(result, corpus) # eager in, eager out
|
|
81
|
+
```
|
|
82
|
+
Read only the columns the arguments name, so corpora annotated differently
|
|
83
|
+
still work together and column errors surface here rather than out of a
|
|
84
|
+
query plan.
|
|
85
|
+
|
|
86
|
+
A function that can only work eagerly (principle 4) opens with
|
|
87
|
+
`as_eager(corpus)` in place of `as_corpus`, and has no `collect_like` to
|
|
88
|
+
return through: `SearchResults` and `encode_terms` take a corpus that way.
|
|
89
|
+
`search` and `search_cqp` accept a LazyFrame too, but down a separate
|
|
90
|
+
out-of-core path (chunked on `file_id_column`, or a single chunk when the
|
|
91
|
+
frame has no such column) rather than through `as_corpus`.
|
|
92
|
+
|
|
93
|
+
### Rust-Specific
|
|
94
|
+
- **Minimize allocations**: Use `&str` over `String`, `&[T]` over `Vec<T>`; avoid `.clone()` in hot paths
|
|
95
|
+
- **Use iterators** without collecting when possible
|
|
96
|
+
- **Reuse buffers** in hot loops rather than allocating per iteration
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@AGENTS.md
|