Skip to content

Commit 782a5c2

Browse files
committed
docs: document versioned components
1 parent 8583449 commit 782a5c2

File tree

8 files changed

+137
-7
lines changed

8 files changed

+137
-7
lines changed

docs/source/dev_docs/linter_development.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,19 @@ Best Practices
3030
- etc.
3131
- For **search field validation**, use a corresponding field mapping and helper functions like `map_to_standard()`.
3232

33+
Deprecated syntax diagnostics
34+
-----------------------------
35+
36+
Linters also warn about constructs that are deprecated in newer
37+
versions. Use the ``LINT_DEPRECATED_SYNTAX`` message to flag such
38+
patterns, for example:
39+
40+
.. code-block:: text
41+
42+
LINT_2001: Operator "SAME" is deprecated. Use NEAR/0.
43+
44+
These messages surface to users during parsing and encourage upgrades
45+
via translation of the query to the latest intermediate representation.
46+
3347
.. literalinclude:: linter_skeleton.py
3448
:language: python

docs/source/dev_docs/overview.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,25 @@ Development setup
1717
1818
pip install -e ".[dev]"
1919
20+
Repository layout
21+
-----------------
22+
23+
Versioned implementations live inside
24+
``search_query/<platform>/vX_Y_Z/`` directories:
25+
26+
.. code-block:: text
27+
28+
search_query/
29+
pubmed/
30+
v1_0_0/
31+
parser.py
32+
serializer.py
33+
34+
To add a new parser or serializer version:
35+
36+
1. copy the latest versioned directory (e.g. ``v1_0_0`` → ``v1_1_0``),
37+
2. apply your changes,
38+
3. register the new version in ``search_query.parser.PARSERS`` or
39+
``search_query.serializer.SERIALIZERS`` so it becomes discoverable.
40+
2041
A code skeleton is available for the parser, linter, translator, and tests.

docs/source/dev_docs/parser_development.rst

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,28 @@
11
Parser
22
============
33

4+
Versioned namespaces
5+
--------------------
6+
7+
Parsers live in versioned modules such as
8+
``search_query/pubmed/v1_0_0/parser.py``. Keeping previous versions
9+
allows reproducible parsing and backward compatibility.
10+
11+
The central registry in ``search_query.parser`` exposes a ``PARSERS``
12+
mapping and resolves the appropriate version at runtime. Calling
13+
``parse(..., parser_version="latest")`` loads the highest available
14+
version for the chosen platform.
15+
16+
Version policy follows ``MAJOR.MINOR.PATCH`` (semantic versioning):
17+
18+
* **MAJOR** – breaking changes in syntax.
19+
* **MINOR** – backward compatible features.
20+
* **PATCH** – bug fixes or minor improvements.
21+
22+
When introducing a new parser version, copy the previous versioned
23+
directory, adjust the implementation, and register the version in the
24+
``PARSERS`` dictionary.
25+
426

527
1. Inherit from Base Classes
628
-----------------------------------
Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
1-
search\_query.query
1+
search\_query.query
22
===================
33

4-
.. automodule:: search_query.query
5-
6-
7-
8-
9-
4+
The query classes implement a **generic intermediate representation (IR)**
5+
that abstracts away platform-specific syntax. Parsers from any platform
6+
produce the same tree of logical operators and terms, enabling
7+
cross-platform translation and version upgrades.
108

9+
Example round-trip:
1110

11+
.. code-block:: python
1212
13+
from search_query.parser import parse
1314
15+
q_wos = parse('TS=("digital health")', platform='wos')
16+
ir = q_wos.translate(target_syntax='generic')
17+
q_back = ir.translate(target_syntax='wos')
1418
19+
.. automodule:: search_query.query
1520

1621
.. rubric:: Classes
1722

@@ -20,3 +25,4 @@
2025
Query
2126
SearchField
2227
Term
28+

docs/source/dev_docs/serializer_development.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
Serializer
22
===========
33

4+
Versioned serializers
5+
---------------------
6+
7+
Serializer implementations live under versioned namespaces such as
8+
``search_query/pubmed/v1_0_0/serializer.py``. They are registered in the
9+
central ``search_query.serializer`` module via the ``SERIALIZERS``
10+
mapping. ``LATEST_SERIALIZERS`` resolves the highest semantic version at
11+
runtime when no explicit ``serializer_version`` is provided.
12+
13+
Example stored query with version information:
14+
15+
.. code-block:: json
16+
17+
{
18+
"platform": "wos",
19+
"search_string": "TS=(quantum dot)",
20+
"version": "1.0.0"
21+
}
22+
423
Serializers convert a query object into a string representation.
524
This enables the query to be rendered for human inspection, logging, or submission to search engines.
625

docs/source/dev_docs/tests.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,20 @@ Example:
126126

127127
- Use helper functions like `parser.print_tokens()` to ease debugging.
128128
- Use `assert ... == ...` with fallbacks for `print(...)` for inspection.
129+
130+
4. **Golden File Tests**
131+
- Purpose: Ensure that parsing and serialization remain stable across
132+
versions. Store expected outputs as versioned "golden" files and
133+
compare test results against them.
134+
135+
5. **Deprecated Syntax Tests**
136+
- Purpose: Verify that linters flag outdated constructs using
137+
``LINT_DEPRECATED_SYNTAX``.
138+
- Example:
139+
140+
.. code-block:: python
141+
142+
def test_deprecated_operator():
143+
parser = XYParser('term1 SAME term2')
144+
parser.parse()
145+
assert any(m['code'] == 'LINT_2001' for m in parser.linter.messages)

docs/source/load.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ JSON files in the standard format (Haddaway et al. 2022). Example:
2929
"authors": [{"name": "Wagner, G.", "ORCID": "0000-0000-0000-1111"}],
3030
"date": {"data_entry": "2019.07.01", "search_conducted": "2019.07.01"},
3131
"platform": "Web of Science",
32+
"version": "1.0.0",
3233
"database": ["SCI-EXPANDED", "SSCI", "A&HCI"],
3334
"search_string": "TS=(quantum AND dot AND spin)"
3435
}

docs/source/save.rst

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,39 @@ To write a query to a JSON file, run the serializer:
1616
filename="search-file.json",
1717
query_str=query.to_string(platform="wos"),
1818
platform="wos",
19+
version="1.0.0",
1920
authors=[{"name": "Tom Brady"}],
2021
record_info={},
2122
date={}
2223
)
2324
2425
search_file.save()
26+
27+
Backward compatibility
28+
----------------------
29+
30+
Saved search strings include a ``version`` field so they can be
31+
re-parsed with the exact syntax they were created with:
32+
33+
.. code-block:: json
34+
35+
{
36+
"platform": "wos",
37+
"search_string": "TS=(quantum dot)",
38+
"version": "1.0.0"
39+
}
40+
41+
Queries may optionally be stored in a generic or structured form for
42+
redundancy:
43+
44+
.. code-block:: json
45+
46+
{
47+
"platform": "wos",
48+
"search_string": "TS=(quantum dot)",
49+
"version": "1.0.0",
50+
"generic_query": "AND[quantum[TS=], dot[TS=]]"
51+
}
52+
53+
By default, search-query relies on the version pinning; the generic form
54+
is purely optional and mainly facilitates upgrades.

0 commit comments

Comments
 (0)