laga 0.1.1__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,148 @@
1
+ name: Bug report
2
+ description: Report a reproducible bug in laga with enough detail to diagnose and fix it.
3
+ title: "Bug: "
4
+ labels:
5
+ - bug
6
+ body:
7
+ - type: markdown
8
+ attributes:
9
+ value: |
10
+ Thanks for taking the time to report a bug.
11
+
12
+ Please provide a minimal, reproducible example and include the exact input that triggers the problem.
13
+
14
+ - type: dropdown
15
+ id: area
16
+ attributes:
17
+ label: Affected area
18
+ description: Pick the part of laga that seems broken.
19
+ options:
20
+ - Public API
21
+ - CLI
22
+ - Parser / repair behavior
23
+ - Tokenizer
24
+ - Documentation
25
+ - Packaging / release
26
+ - Tests / CI
27
+ - Other
28
+ validations:
29
+ required: true
30
+
31
+ - type: dropdown
32
+ id: severity
33
+ attributes:
34
+ label: Severity
35
+ description: How much does this affect your use case?
36
+ options:
37
+ - Blocking
38
+ - High
39
+ - Medium
40
+ - Low
41
+ - Cosmetic
42
+ validations:
43
+ required: true
44
+
45
+ - type: textarea
46
+ id: summary
47
+ attributes:
48
+ label: Summary
49
+ description: Describe the bug in one or two sentences.
50
+ placeholder: laga returns the wrong structure when ...
51
+ validations:
52
+ required: true
53
+
54
+ - type: textarea
55
+ id: input
56
+ attributes:
57
+ label: Input that triggers the bug
58
+ description: Paste the smallest possible text sample that reproduces the issue.
59
+ render: text
60
+ placeholder: |
61
+ {name: 'Ada', roles: ['admin',],}
62
+ validations:
63
+ required: true
64
+
65
+ - type: textarea
66
+ id: expected
67
+ attributes:
68
+ label: Expected result
69
+ description: What should laga have returned or done instead?
70
+ placeholder: The input should be repaired to valid JSON and parse to ...
71
+ validations:
72
+ required: true
73
+
74
+ - type: textarea
75
+ id: actual
76
+ attributes:
77
+ label: Actual result
78
+ description: What happened instead. Include the exact error message or unexpected output.
79
+ placeholder: laga raised LagaError: ...
80
+ validations:
81
+ required: true
82
+
83
+ - type: textarea
84
+ id: steps
85
+ attributes:
86
+ label: Steps to reproduce
87
+ description: List the exact steps so someone else can reproduce the issue.
88
+ placeholder: |
89
+ 1. Install laga
90
+ 2. Run laga.repair(...) with the sample above
91
+ 3. Observe the failure
92
+ validations:
93
+ required: true
94
+
95
+ - type: textarea
96
+ id: environment
97
+ attributes:
98
+ label: Environment
99
+ description: Share the runtime details that matter for reproduction.
100
+ placeholder: |
101
+ Python:
102
+ OS:
103
+ laga version:
104
+ Installation method:
105
+ Shell or editor:
106
+ validations:
107
+ required: true
108
+
109
+ - type: dropdown
110
+ id: reproducibility
111
+ attributes:
112
+ label: Reproducibility
113
+ description: How often does this happen?
114
+ options:
115
+ - Always
116
+ - Sometimes
117
+ - Rarely
118
+ - Only once
119
+ validations:
120
+ required: true
121
+
122
+ - type: textarea
123
+ id: workaround
124
+ attributes:
125
+ label: Workaround
126
+ description: If you found a workaround, describe it here.
127
+ placeholder: Using strict=False avoids the failure, but ...
128
+
129
+ - type: textarea
130
+ id: extra
131
+ attributes:
132
+ label: Additional context
133
+ description: Add logs, stack traces, screenshots, or notes that may help.
134
+ placeholder: Any extra detail that could narrow down the root cause.
135
+
136
+ - type: checkboxes
137
+ id: checklist
138
+ attributes:
139
+ label: Confirmation checklist
140
+ options:
141
+ - label: I have searched existing issues and did not find a duplicate.
142
+ required: true
143
+ - label: I have reduced the example to the smallest reproducible input I could.
144
+ required: true
145
+ - label: I am using the latest released version or I can explain why I am not.
146
+ required: true
147
+ - label: I am comfortable sharing the sample input publicly in this issue.
148
+ required: true
@@ -0,0 +1,8 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Security reporting
4
+ url: https://github.com/olaflaitinen/laga/security/advisories
5
+ about: Use this for private security reports only.
6
+ - name: Project repository
7
+ url: https://github.com/olaflaitinen/laga
8
+ about: Review the README, docs, and existing issues before opening a new ticket.
@@ -0,0 +1,124 @@
1
+ name: Feature request
2
+ description: Suggest an improvement, capability, or workflow enhancement for laga.
3
+ title: "Feature: "
4
+ labels:
5
+ - enhancement
6
+ body:
7
+ - type: markdown
8
+ attributes:
9
+ value: |
10
+ Thanks for suggesting an improvement.
11
+
12
+ The most useful requests explain the current limitation, the user impact, and the exact behavior you want.
13
+
14
+ - type: dropdown
15
+ id: area
16
+ attributes:
17
+ label: Area
18
+ description: Which part of laga would this affect?
19
+ options:
20
+ - Public API
21
+ - CLI
22
+ - Parser / repair behavior
23
+ - Tokenizer
24
+ - Documentation
25
+ - Packaging / release
26
+ - Tests / CI
27
+ - New capability
28
+ - Other
29
+ validations:
30
+ required: true
31
+
32
+ - type: dropdown
33
+ id: priority
34
+ attributes:
35
+ label: Priority
36
+ description: How important is this request to you?
37
+ options:
38
+ - Critical
39
+ - High
40
+ - Medium
41
+ - Low
42
+ - Nice to have
43
+ validations:
44
+ required: true
45
+
46
+ - type: textarea
47
+ id: problem
48
+ attributes:
49
+ label: Problem statement
50
+ description: Describe the limitation or pain point you are trying to solve.
51
+ placeholder: Today I have to ... which causes ...
52
+ validations:
53
+ required: true
54
+
55
+ - type: textarea
56
+ id: goal
57
+ attributes:
58
+ label: Desired outcome
59
+ description: Describe the behavior, output, or workflow you want.
60
+ placeholder: laga should be able to ...
61
+ validations:
62
+ required: true
63
+
64
+ - type: textarea
65
+ id: user_story
66
+ attributes:
67
+ label: User story
68
+ description: Optional, but helpful if you can describe who needs this and why.
69
+ placeholder: As a ... I want ... so that ...
70
+
71
+ - type: textarea
72
+ id: examples
73
+ attributes:
74
+ label: Example input or API shape
75
+ description: Show a concrete example of the proposed behavior.
76
+ render: text
77
+ placeholder: |
78
+ laga.repair('{name: "Ada"}')
79
+ # could optionally return ...
80
+
81
+ - type: textarea
82
+ id: alternatives
83
+ attributes:
84
+ label: Alternatives considered
85
+ description: Describe other approaches you evaluated and why they were not enough.
86
+ placeholder: |
87
+ 1. Use a post-processing step
88
+ 2. Wrap laga in custom logic
89
+ 3. Change upstream data generation
90
+
91
+ - type: textarea
92
+ id: tradeoffs
93
+ attributes:
94
+ label: Tradeoffs and constraints
95
+ description: Mention any compatibility, performance, or maintenance concerns we should keep in mind.
96
+ placeholder: This should remain backwards compatible with ...
97
+
98
+ - type: textarea
99
+ id: acceptance
100
+ attributes:
101
+ label: Acceptance criteria
102
+ description: What would make this feature request complete?
103
+ placeholder: |
104
+ - Works with ...
105
+ - Does not break ...
106
+ - Includes tests/docs ...
107
+
108
+ - type: textarea
109
+ id: context
110
+ attributes:
111
+ label: Additional context
112
+ description: Add links, screenshots, related issues, or any notes that help frame the request.
113
+
114
+ - type: checkboxes
115
+ id: checklist
116
+ attributes:
117
+ label: Confirmation checklist
118
+ options:
119
+ - label: I searched existing issues and discussions before opening this request.
120
+ required: true
121
+ - label: I explained the problem and not just the solution.
122
+ required: true
123
+ - label: I included a concrete example or user story.
124
+ required: true
@@ -0,0 +1,14 @@
1
+ ## Summary
2
+
3
+ Describe the change and why it is needed. Link any related issue or discussion.
4
+
5
+ ## Testing
6
+
7
+ - [ ] `make lint`
8
+ - [ ] `make typecheck`
9
+ - [ ] `make test`
10
+ - [ ] `make build`
11
+
12
+ ## Notes
13
+
14
+ Add any follow-up work, release notes, or migration notes here.
@@ -0,0 +1,47 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ test:
9
+ runs-on: ${{ matrix.os }}
10
+ strategy:
11
+ fail-fast: false
12
+ matrix:
13
+ os: [ubuntu-latest, macos-latest, windows-latest]
14
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
15
+
16
+ steps:
17
+ - name: Checkout repository
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Set up Python
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+ cache: pip
25
+
26
+ - name: Install dependencies
27
+ run: |
28
+ python -m pip install --upgrade pip
29
+ python -m pip install -e ".[dev]"
30
+
31
+ - name: Lint
32
+ run: ruff check .
33
+
34
+ - name: Type check
35
+ run: mypy src/laga
36
+
37
+ - name: Test
38
+ run: pytest
39
+
40
+ - name: Upload coverage report
41
+ if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.13'
42
+ uses: actions/upload-artifact@v4
43
+ with:
44
+ name: coverage-report
45
+ path: |
46
+ coverage.xml
47
+ htmlcov
@@ -0,0 +1,39 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ build-and-publish:
10
+ runs-on: ubuntu-latest
11
+ environment: pypi
12
+ permissions:
13
+ id-token: write
14
+ contents: read
15
+ steps:
16
+ - name: Checkout repository
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: "3.13"
23
+ cache: pip
24
+
25
+ - name: Install build dependencies
26
+ run: |
27
+ python -m pip install --upgrade pip
28
+ python -m pip install build
29
+
30
+ - name: Build distributions
31
+ run: python -m build
32
+
33
+ - name: Verify artifacts
34
+ run: python -m pip install twine && twine check dist/*
35
+
36
+ - name: Publish to PyPI
37
+ uses: pypa/gh-action-pypi-publish@release/v1
38
+ with:
39
+ packages-dir: dist
laga-0.1.1/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ .coverage
2
+ .hypothesis/
3
+ .mypy_cache/
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ .venv/
7
+ .benchmarks/
8
+ coverage.xml
9
+ dist/
10
+ build/
11
+ *.egg-info/
12
+ __pycache__/
13
+ *.py[cod]
@@ -0,0 +1,25 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v4.6.0
4
+ hooks:
5
+ - id: check-added-large-files
6
+ - id: check-ast
7
+ - id: check-byte-order-marker
8
+ - id: check-case-conflict
9
+ - id: check-merge-conflict
10
+ - id: check-symlinks
11
+ - id: end-of-file-fixer
12
+ - id: mixed-line-ending
13
+ - id: trailing-whitespace
14
+ - repo: https://github.com/astral-sh/ruff-pre-commit
15
+ rev: v0.6.9
16
+ hooks:
17
+ - id: ruff
18
+ args: [--fix]
19
+ - id: ruff-format
20
+ - repo: https://github.com/pre-commit/mirrors-mypy
21
+ rev: v1.11.2
22
+ hooks:
23
+ - id: mypy
24
+ additional_dependencies: [hatchling]
25
+ files: ^src/laga/
@@ -0,0 +1,29 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.1] - 2026-07-24
11
+
12
+ ### Added
13
+
14
+ - Repository cleanup, documentation refresh, and GitHub workflow improvements.
15
+ - Root ignore file for Python build and cache artifacts.
16
+ - Project ownership metadata updated for the `olaflaitinen` repository.
17
+
18
+ ### Changed
19
+
20
+ - Dropped Python 3.9 support; laga 0.1.1 targets Python 3.10 through 3.13.
21
+
22
+ ## [0.1.0] - 2026-07-24
23
+
24
+ ### Added
25
+
26
+ - Fast path through `json.loads` for valid JSON.
27
+ - Recovery for comments, fences, prose, smart quotes, single quotes, missing commas, trailing commas, and truncated braces.
28
+ - `repair`, `repair_to_str`, and `loads` public entry points.
29
+ - Type information distributed through `py.typed`.
@@ -0,0 +1,23 @@
1
+ # Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We commit to a respectful, inclusive, and professional community. We do not tolerate harassment, discrimination, or abuse of any kind.
6
+
7
+ ## Expected Behavior
8
+
9
+ - Be considerate and constructive.
10
+ - Give feedback on ideas, not people.
11
+ - Assume good intent and communicate clearly.
12
+
13
+ ## Unacceptable Behavior
14
+
15
+ - Harassment or threats.
16
+ - Hate speech or discriminatory language.
17
+ - Deliberate disruption of discussions or reviews.
18
+
19
+ ## Enforcement
20
+
21
+ Maintainers may remove content, restrict access, or take other actions when needed to protect the community.
22
+
23
+ Reports may be sent to the maintainers listed in the repository or through private project contact channels.
@@ -0,0 +1,26 @@
1
+ # Contributing
2
+
3
+ ## Setup
4
+
5
+ 1. Create and activate a virtual environment.
6
+ 2. Install development dependencies with `python -m pip install -e ".[dev]"`.
7
+ 3. Install pre-commit hooks with `pre-commit install`.
8
+
9
+ ## Local Checks
10
+
11
+ Run the full check set before sending a change:
12
+
13
+ ```bash
14
+ make lint
15
+ make typecheck
16
+ make test
17
+ make build
18
+ ```
19
+
20
+ ## Pull Requests
21
+
22
+ 1. Keep changes focused and easy to review.
23
+ 2. Add or update tests for behavior changes.
24
+ 3. Update documentation when the public API changes.
25
+ 4. Include screenshots only when the change is visual.
26
+ 5. Make sure the CI workflow passes before requesting review.
laga-0.1.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Gustav Olaf Yunus Laitinen-Fredriksson Lundström-Imanov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
laga-0.1.1/Makefile ADDED
@@ -0,0 +1,20 @@
1
+ .PHONY: install lint typecheck test build docs
2
+
3
+ install:
4
+ python -m pip install -e ".[dev]"
5
+
6
+ lint:
7
+ ruff check .
8
+ ruff format --check .
9
+
10
+ typecheck:
11
+ mypy src/laga
12
+
13
+ test:
14
+ pytest
15
+
16
+ build:
17
+ python -m build
18
+
19
+ docs:
20
+ mkdocs build
laga-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,147 @@
1
+ Metadata-Version: 2.4
2
+ Name: laga
3
+ Version: 0.1.1
4
+ Summary: Repair malformed JSON from language models and hand-written config.
5
+ Project-URL: Homepage, https://github.com/olaflaitinen/laga
6
+ Project-URL: Documentation, https://github.com/olaflaitinen/laga/tree/main/docs
7
+ Project-URL: Source, https://github.com/olaflaitinen/laga
8
+ Project-URL: Issue Tracker, https://github.com/olaflaitinen/laga/issues
9
+ Author: Gustav Olaf Yunus Laitinen-Fredriksson Lundström-Imanov
10
+ License: MIT License
11
+
12
+ Copyright (c) 2026 Gustav Olaf Yunus Laitinen-Fredriksson Lundström-Imanov
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in all
22
+ copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+ License-File: LICENSE
32
+ Keywords: data-cleanup,json,llm,parser,repair
33
+ Classifier: Development Status :: 3 - Alpha
34
+ Classifier: Intended Audience :: Developers
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Operating System :: OS Independent
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Programming Language :: Python :: 3.10
39
+ Classifier: Programming Language :: Python :: 3.11
40
+ Classifier: Programming Language :: Python :: 3.12
41
+ Classifier: Programming Language :: Python :: 3.13
42
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
43
+ Classifier: Typing :: Typed
44
+ Requires-Python: <3.14,>=3.10
45
+ Provides-Extra: dev
46
+ Requires-Dist: build>=1.2; extra == 'dev'
47
+ Requires-Dist: coverage[toml]>=7.6; extra == 'dev'
48
+ Requires-Dist: hypothesis>=6.108; extra == 'dev'
49
+ Requires-Dist: mkdocs-material>=9.5; extra == 'dev'
50
+ Requires-Dist: mkdocs>=1.6; extra == 'dev'
51
+ Requires-Dist: mypy>=1.11; extra == 'dev'
52
+ Requires-Dist: pre-commit>=3.8; extra == 'dev'
53
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
54
+ Requires-Dist: pytest>=8.3; extra == 'dev'
55
+ Requires-Dist: ruff>=0.6.9; extra == 'dev'
56
+ Provides-Extra: docs
57
+ Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
58
+ Requires-Dist: mkdocs>=1.6; extra == 'docs'
59
+ Provides-Extra: lint
60
+ Requires-Dist: mypy>=1.11; extra == 'lint'
61
+ Requires-Dist: ruff>=0.6.9; extra == 'lint'
62
+ Provides-Extra: test
63
+ Requires-Dist: coverage[toml]>=7.6; extra == 'test'
64
+ Requires-Dist: hypothesis>=6.108; extra == 'test'
65
+ Requires-Dist: pytest-cov>=5.0; extra == 'test'
66
+ Requires-Dist: pytest>=8.3; extra == 'test'
67
+ Description-Content-Type: text/markdown
68
+
69
+ # laga
70
+
71
+ `laga` repairs malformed JSON and returns Python objects.
72
+
73
+ ## Why
74
+
75
+ Large language models and hand-written configuration often produce almost-JSON with trailing commas, missing commas, comments, code fences, single quotes, unquoted keys, or truncated containers. `laga` keeps the public surface small, tries `json.loads` first for valid input, and only enters the repair path when necessary.
76
+
77
+ ## Install
78
+
79
+ `laga` 0.1.1 supports Python 3.10 through 3.13.
80
+
81
+ ```bash
82
+ python -m pip install -e ".[dev]"
83
+ ```
84
+
85
+ ## Quickstart
86
+
87
+ ```python
88
+ import laga
89
+
90
+ text = """Here is the result:
91
+ ```json
92
+ {
93
+ 'name': 'Ada',
94
+ 'active': True,
95
+ 'roles': ['admin', 'writer',],
96
+ }
97
+ ```
98
+ """
99
+
100
+ data = laga.repair(text)
101
+ print(data)
102
+ print(laga.repair_to_str(text))
103
+ ```
104
+
105
+ ## API Reference
106
+
107
+ | Function | Returns | Description |
108
+ | --- | --- | --- |
109
+ | `laga.repair(text, strict=False)` | Python object | Repairs malformed JSON and returns Python data. |
110
+ | `laga.repair_to_str(text, strict=False)` | `str` | Repairs malformed JSON and returns normalized JSON text. |
111
+ | `laga.loads(text, strict=False)` | Python object | Alias for `laga.repair`. |
112
+ | `laga.LagaError` | Exception type | Raised when repair fails or input is unrecoverable. |
113
+
114
+ ## Repair Rules
115
+
116
+ | Rule | Before | After |
117
+ | --- | --- | --- |
118
+ | Trailing comma | `{"a": 1,}` | `{"a":1}` |
119
+ | Missing comma | `{"a": 1 "b": 2}` | `{"a":1,"b":2}` |
120
+ | Single quotes | `{'a': 'b'}` | `{"a":"b"}` |
121
+ | Unquoted keys | `{name: "Ada"}` | `{"name":"Ada"}` |
122
+ | Python literals | `{"ok": True, "none": None}` | `{"ok":true,"none":null}` |
123
+ | Comments | `{"a": 1 // note\n}` | `{"a":1}` |
124
+ | Markdown fences | <code>```json\n{"a":1}\n```</code> | `{"a":1}` |
125
+ | Smart quotes | `“a”` | `"a"` |
126
+ | Prose around JSON | `Result: {"a":1}` | `{"a":1}` |
127
+ | Truncated structure | `{"a": [1, 2` | `{"a":[1,2]}` |
128
+
129
+ ## Limitations
130
+
131
+ `laga` is intentionally conservative. It does not evaluate expressions, it does not guess at arbitrary JavaScript syntax, and it does not try to recover malformed numbers or deeply ambiguous text in strict mode. If you already control the producer and the input is valid JSON, the standard library remains the best choice because `json.loads` is faster and stricter.
132
+
133
+ When an object contains duplicate keys, the last value wins, matching Python dict behavior.
134
+
135
+ ## When To Use The Standard Library
136
+
137
+ Use `json.loads` when you control the producer and know the input is valid JSON. Use `laga` when the input is noisy, user-facing, or generated by a model and you need a predictable repair step before parsing.
138
+
139
+ ## Development
140
+
141
+ ```bash
142
+ make install
143
+ make lint
144
+ make typecheck
145
+ make test
146
+ make build
147
+ ```