linksql 0.1.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.
@@ -0,0 +1,162 @@
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ lerna-debug.log*
8
+
9
+ # Diagnostic reports (https://nodejs.org/api/report.html)
10
+ report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11
+
12
+ # Runtime data
13
+ pids
14
+ *.pid
15
+ *.seed
16
+ *.pid.lock
17
+
18
+ # Directory for instrumented libs generated by jscoverage/JSCover
19
+ lib-cov
20
+
21
+ # Coverage directory used by tools like istanbul
22
+ coverage
23
+ *.lcov
24
+
25
+ # nyc test coverage
26
+ .nyc_output
27
+
28
+ # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29
+ .grunt
30
+
31
+ # Bower dependency directory (https://bower.io/)
32
+ bower_components
33
+
34
+ # node-waf configuration
35
+ .lock-wscript
36
+
37
+ # Compiled binary addons (https://nodejs.org/api/addons.html)
38
+ build/Release
39
+
40
+ # Dependency directories
41
+ node_modules/
42
+ jspm_packages/
43
+
44
+ # Snowpack dependency directory (https://snowpack.dev/)
45
+ web_modules/
46
+
47
+ # TypeScript cache
48
+ *.tsbuildinfo
49
+
50
+ # Optional npm cache directory
51
+ .npm
52
+
53
+ # Optional eslint cache
54
+ .eslintcache
55
+ .playwright-mcp/
56
+
57
+ # Optional stylelint cache
58
+ .stylelintcache
59
+
60
+ # Optional REPL history
61
+ .node_repl_history
62
+
63
+ # Output of 'npm pack'
64
+ *.tgz
65
+
66
+ # Yarn Integrity file
67
+ .yarn-integrity
68
+
69
+ # dotenv environment variable files
70
+ .env
71
+ .env.*
72
+ !.env.example
73
+
74
+ # parcel-bundler cache (https://parceljs.org/)
75
+ .cache
76
+ .parcel-cache
77
+
78
+ # Next.js build output
79
+ .next
80
+ out
81
+
82
+ # Nuxt.js build / generate output
83
+ .nuxt
84
+ dist
85
+
86
+ # Gatsby files
87
+ .cache/
88
+ # Comment in the public line in if your project uses Gatsby and not Next.js
89
+ # https://nextjs.org/blog/next-9-1#public-directory-support
90
+ # public
91
+
92
+ # vuepress build output
93
+ .vuepress/dist
94
+
95
+ # vuepress v2.x temp and cache directory
96
+ .temp
97
+ .cache
98
+
99
+ # Sveltekit cache directory
100
+ .svelte-kit/
101
+
102
+ # vitepress build output
103
+ **/.vitepress/dist
104
+
105
+ # vitepress cache directory
106
+ **/.vitepress/cache
107
+
108
+ # Docusaurus cache and generated files
109
+ .docusaurus
110
+
111
+ # Serverless directories
112
+ .serverless/
113
+
114
+ # FuseBox cache
115
+ .fusebox/
116
+
117
+ # DynamoDB Local files
118
+ .dynamodb/
119
+
120
+ # Firebase cache directory
121
+ .firebase/
122
+
123
+ # TernJS port file
124
+ .tern-port
125
+
126
+ # Stores VSCode versions used for testing VSCode extensions
127
+ .vscode-test
128
+
129
+ # yarn v3
130
+ .pnp.*
131
+ .yarn/*
132
+ !.yarn/patches
133
+ !.yarn/plugins
134
+ !.yarn/releases
135
+ !.yarn/sdks
136
+ !.yarn/versions
137
+
138
+ # Vite logs files
139
+ vite.config.js.timestamp-*
140
+ vite.config.ts.timestamp-*
141
+
142
+ # jscpd reports
143
+ reports/
144
+
145
+ # === Polyglot reference implementations (rust/, python/, csharp/) ===
146
+ # Rust build output
147
+ rust/target/
148
+ # Python virtual environments and caches/build artifacts (scoped to python/ so the JS repo is unaffected)
149
+ python/.venv/
150
+ python/venv/
151
+ python/**/__pycache__/
152
+ python/**/*.py[cod]
153
+ python/.pytest_cache/
154
+ python/.mypy_cache/
155
+ python/.ruff_cache/
156
+ python/**/*.egg-info/
157
+ python/.coverage
158
+ python/coverage.xml
159
+ # C# build output (scoped to csharp/ so the repo-root bin/linksql.js is never ignored)
160
+ csharp/**/bin/
161
+ csharp/**/obj/
162
+ csharp/**/TestResults/
linksql-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,90 @@
1
+ Metadata-Version: 2.5
2
+ Name: linksql
3
+ Version: 0.1.0
4
+ Summary: Python reference implementation of LinksQL — an associative query language built around a single substitution operation.
5
+ Project-URL: Homepage, https://github.com/link-foundation/linksql
6
+ Project-URL: Repository, https://github.com/link-foundation/linksql
7
+ Project-URL: Issues, https://github.com/link-foundation/linksql/issues
8
+ License: Unlicense
9
+ Keywords: associative,doublets,links,linksql,query
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: The Unlicense (Unlicense)
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Requires-Python: >=3.9
20
+ Provides-Extra: dev
21
+ Requires-Dist: mypy>=1.13.0; extra == 'dev'
22
+ Requires-Dist: pytest>=8.3.0; extra == 'dev'
23
+ Requires-Dist: ruff>=0.8.0; extra == 'dev'
24
+ Description-Content-Type: text/markdown
25
+
26
+ # LinksQL (Python reference implementation)
27
+
28
+ A faithful, behaviourally-identical Python port of the JavaScript reference
29
+ implementation of **LinksQL** — an associative query language built on **one data
30
+ primitive** (the link, a doublet) and **one operation** (substitution).
31
+
32
+ Everything is a link: a triple `(index: source target)` of positive integers. A
33
+ link whose `source` and `target` both equal its own `index` is a *point*, the
34
+ atom of the graph. A query is a pair of pattern lists — a *restriction* and a
35
+ *substitution* — written `(restriction) (substitution)`; the four CRUD
36
+ behaviours (read, create, update, delete) are derived from how the two lists line
37
+ up positionally.
38
+
39
+ The JavaScript implementation in `../js/src` is the ground truth, and the
40
+ normative behaviour is defined in
41
+ [`../docs/SPECIFICATION.md`](../docs/SPECIFICATION.md).
42
+
43
+ A link has exactly two endpoints, so a relation like "alice loves bob" is the
44
+ higher-order link `((alice loves) bob)` — every pattern carries 0 or 2 values.
45
+
46
+ ## Quick start
47
+
48
+ ```python
49
+ from linksql import Database
50
+
51
+ db = Database()
52
+ db.query("() (((alice loves) bob))") # create the higher-order link
53
+ report = db.query("(($i: $s $t))") # read every relation
54
+ print(report.operation, report.matched)
55
+ ```
56
+
57
+ ## Development
58
+
59
+ This package uses a src layout. Create a virtual environment and install it with
60
+ the development extras:
61
+
62
+ ```bash
63
+ python -m venv .venv
64
+ . .venv/bin/activate
65
+ pip install -e ".[dev]"
66
+ ```
67
+
68
+ Then run the checks (all must pass):
69
+
70
+ ```bash
71
+ ruff check .
72
+ ruff format --check .
73
+ mypy src
74
+ pytest tests/ -v
75
+ ```
76
+
77
+ ## Public API
78
+
79
+ The top-level `linksql` package re-exports the engine surface:
80
+
81
+ - `linksql.lino` — `tokenize`, `parse`, `serialize`, `serialize_all`, the AST
82
+ types (`Ref`, `Link`/`LinkNode`, `Node`, `Token`) and `LinoSyntaxError`.
83
+ - `linksql.store` — `LinksStore`, `Link`, `LinkIntegrityError`.
84
+ - `linksql.names` — `Names`, `UnknownNameError`.
85
+ - `linksql.substitution` — `link_slots`, `match_restriction`, `execute`,
86
+ `link_matches`, `Context`, and `SubstitutionError`.
87
+ - `linksql.query` — `Database`, `split_query`, `link_to_lino`, `QueryReport`,
88
+ `QueryError`.
89
+ - `linksql.schema` — the GraphQL-class schema model: `Schema`, `Relation`,
90
+ `NamedQuery`, `NamedSubscription`, and `SchemaError`.
@@ -0,0 +1,65 @@
1
+ # LinksQL (Python reference implementation)
2
+
3
+ A faithful, behaviourally-identical Python port of the JavaScript reference
4
+ implementation of **LinksQL** — an associative query language built on **one data
5
+ primitive** (the link, a doublet) and **one operation** (substitution).
6
+
7
+ Everything is a link: a triple `(index: source target)` of positive integers. A
8
+ link whose `source` and `target` both equal its own `index` is a *point*, the
9
+ atom of the graph. A query is a pair of pattern lists — a *restriction* and a
10
+ *substitution* — written `(restriction) (substitution)`; the four CRUD
11
+ behaviours (read, create, update, delete) are derived from how the two lists line
12
+ up positionally.
13
+
14
+ The JavaScript implementation in `../js/src` is the ground truth, and the
15
+ normative behaviour is defined in
16
+ [`../docs/SPECIFICATION.md`](../docs/SPECIFICATION.md).
17
+
18
+ A link has exactly two endpoints, so a relation like "alice loves bob" is the
19
+ higher-order link `((alice loves) bob)` — every pattern carries 0 or 2 values.
20
+
21
+ ## Quick start
22
+
23
+ ```python
24
+ from linksql import Database
25
+
26
+ db = Database()
27
+ db.query("() (((alice loves) bob))") # create the higher-order link
28
+ report = db.query("(($i: $s $t))") # read every relation
29
+ print(report.operation, report.matched)
30
+ ```
31
+
32
+ ## Development
33
+
34
+ This package uses a src layout. Create a virtual environment and install it with
35
+ the development extras:
36
+
37
+ ```bash
38
+ python -m venv .venv
39
+ . .venv/bin/activate
40
+ pip install -e ".[dev]"
41
+ ```
42
+
43
+ Then run the checks (all must pass):
44
+
45
+ ```bash
46
+ ruff check .
47
+ ruff format --check .
48
+ mypy src
49
+ pytest tests/ -v
50
+ ```
51
+
52
+ ## Public API
53
+
54
+ The top-level `linksql` package re-exports the engine surface:
55
+
56
+ - `linksql.lino` — `tokenize`, `parse`, `serialize`, `serialize_all`, the AST
57
+ types (`Ref`, `Link`/`LinkNode`, `Node`, `Token`) and `LinoSyntaxError`.
58
+ - `linksql.store` — `LinksStore`, `Link`, `LinkIntegrityError`.
59
+ - `linksql.names` — `Names`, `UnknownNameError`.
60
+ - `linksql.substitution` — `link_slots`, `match_restriction`, `execute`,
61
+ `link_matches`, `Context`, and `SubstitutionError`.
62
+ - `linksql.query` — `Database`, `split_query`, `link_to_lino`, `QueryReport`,
63
+ `QueryError`.
64
+ - `linksql.schema` — the GraphQL-class schema model: `Schema`, `Relation`,
65
+ `NamedQuery`, `NamedSubscription`, and `SchemaError`.
@@ -0,0 +1,82 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "linksql"
7
+ version = "0.1.0"
8
+ description = "Python reference implementation of LinksQL — an associative query language built around a single substitution operation."
9
+ readme = "README.md"
10
+ license = {text = "Unlicense"}
11
+ requires-python = ">=3.9"
12
+ keywords = ["linksql", "links", "doublets", "associative", "query"]
13
+ classifiers = [
14
+ "Development Status :: 3 - Alpha",
15
+ "Intended Audience :: Developers",
16
+ "License :: OSI Approved :: The Unlicense (Unlicense)",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3.9",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ ]
24
+
25
+ [project.optional-dependencies]
26
+ dev = [
27
+ "ruff>=0.8.0",
28
+ "mypy>=1.13.0",
29
+ "pytest>=8.3.0",
30
+ ]
31
+
32
+ [project.urls]
33
+ Homepage = "https://github.com/link-foundation/linksql"
34
+ Repository = "https://github.com/link-foundation/linksql"
35
+ Issues = "https://github.com/link-foundation/linksql/issues"
36
+
37
+ [tool.hatch.build.targets.wheel]
38
+ packages = ["src/linksql"]
39
+
40
+ [tool.ruff]
41
+ line-length = 88
42
+ target-version = "py39"
43
+
44
+ [tool.ruff.lint]
45
+ select = [
46
+ "E", "W", "F", "I", "N", "UP", "B", "C4", "DTZ", "T10", "EM", "ISC",
47
+ "ICN", "PIE", "PT", "Q", "RSE", "RET", "SIM", "TID", "ARG", "PTH",
48
+ "ERA", "PL", "PERF", "RUF",
49
+ ]
50
+ ignore = [
51
+ "E501",
52
+ "PLR0913",
53
+ "PLR2004",
54
+ ]
55
+
56
+ [tool.ruff.lint.per-file-ignores]
57
+ "tests/**/*.py" = ["S101", "ARG", "PLR2004"]
58
+
59
+ [tool.ruff.format]
60
+ quote-style = "double"
61
+ indent-style = "space"
62
+ line-ending = "lf"
63
+ skip-magic-trailing-comma = false
64
+
65
+ [tool.mypy]
66
+ python_version = "3.9"
67
+ warn_return_any = true
68
+ warn_unused_configs = true
69
+ disallow_untyped_defs = true
70
+ disallow_incomplete_defs = true
71
+ check_untyped_defs = true
72
+ no_implicit_optional = true
73
+ warn_redundant_casts = true
74
+ warn_unused_ignores = true
75
+ warn_no_return = true
76
+ strict_equality = true
77
+
78
+ [tool.pytest.ini_options]
79
+ minversion = "7.0"
80
+ addopts = "-ra -q --strict-markers"
81
+ testpaths = ["tests"]
82
+ pythonpath = ["src"]
@@ -0,0 +1,117 @@
1
+ """LinksQL — a Python reference implementation.
2
+
3
+ LinksQL is an associative query language built on **one data primitive** (the
4
+ link, a doublet) and **one operation** (substitution). This package is a
5
+ faithful, behaviourally-identical port of the JavaScript reference implementation
6
+ in ``../src``; the normative specification lives in ``../docs/SPECIFICATION.md``.
7
+
8
+ The public surface mirrors the JavaScript package entry point: parse and
9
+ serialise LiNo, build a :class:`LinksStore`, and run queries through a
10
+ :class:`Database`.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from .lino import (
16
+ Link as LinkNode,
17
+ )
18
+ from .lino import (
19
+ LinoSyntaxError,
20
+ Node,
21
+ Ref,
22
+ Token,
23
+ parse,
24
+ serialize,
25
+ serialize_all,
26
+ tokenize,
27
+ )
28
+ from .names import Names, UnknownNameError
29
+ from .protocol import (
30
+ JSON_CONTENT_TYPE,
31
+ LINO_CONTENT_TYPE,
32
+ decode,
33
+ encode,
34
+ escape_reference,
35
+ prefers_json,
36
+ )
37
+ from .query import (
38
+ Database,
39
+ Introspection,
40
+ MatchRow,
41
+ QueryError,
42
+ QueryReport,
43
+ SplitQuery,
44
+ link_to_lino,
45
+ patterns_of,
46
+ split_query,
47
+ )
48
+ from .schema import (
49
+ NamedQuery,
50
+ NamedSubscription,
51
+ Relation,
52
+ Schema,
53
+ SchemaError,
54
+ )
55
+ from .store import Link, LinkIntegrityError, LinksStore
56
+ from .substitution import (
57
+ Context,
58
+ RawResult,
59
+ Row,
60
+ Slots,
61
+ Spec,
62
+ SubstitutionError,
63
+ execute,
64
+ link_matches,
65
+ link_slots,
66
+ match_restriction,
67
+ )
68
+
69
+ __version__ = "0.1.0"
70
+
71
+ __all__ = [
72
+ "JSON_CONTENT_TYPE",
73
+ "LINO_CONTENT_TYPE",
74
+ "Context",
75
+ "Database",
76
+ "Introspection",
77
+ "Link",
78
+ "LinkIntegrityError",
79
+ "LinkNode",
80
+ "LinksStore",
81
+ "LinoSyntaxError",
82
+ "MatchRow",
83
+ "NamedQuery",
84
+ "NamedSubscription",
85
+ "Names",
86
+ "Node",
87
+ "QueryError",
88
+ "QueryReport",
89
+ "RawResult",
90
+ "Ref",
91
+ "Relation",
92
+ "Row",
93
+ "Schema",
94
+ "SchemaError",
95
+ "Slots",
96
+ "Spec",
97
+ "SplitQuery",
98
+ "SubstitutionError",
99
+ "Token",
100
+ "UnknownNameError",
101
+ "__version__",
102
+ "decode",
103
+ "encode",
104
+ "escape_reference",
105
+ "execute",
106
+ "link_matches",
107
+ "link_slots",
108
+ "link_to_lino",
109
+ "match_restriction",
110
+ "parse",
111
+ "patterns_of",
112
+ "prefers_json",
113
+ "serialize",
114
+ "serialize_all",
115
+ "split_query",
116
+ "tokenize",
117
+ ]