docworkspace 0.2.2__tar.gz → 0.2.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.
- {docworkspace-0.2.2 → docworkspace-0.2.3}/PKG-INFO +2 -2
- {docworkspace-0.2.2 → docworkspace-0.2.3}/pyproject.toml +2 -2
- docworkspace-0.2.3/src/docworkspace/workspace/io.py +169 -0
- docworkspace-0.2.3/tests/test_workspace_io_absolute_paths.py +80 -0
- docworkspace-0.2.3/uv.lock +125 -0
- docworkspace-0.2.2/src/docworkspace/workspace/io.py +0 -101
- docworkspace-0.2.2/uv.lock +0 -125
- {docworkspace-0.2.2 → docworkspace-0.2.3}/.github/workflows/ci.yml +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/.github/workflows/release.yml +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/.gitignore +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/PUBLISH.md +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/README.md +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/pytest.ini +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/src/docworkspace/__init__.py +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/src/docworkspace/node/__init__.py +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/src/docworkspace/node/core.py +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/src/docworkspace/node/io.py +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/src/docworkspace/workspace/__init__.py +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/src/docworkspace/workspace/analysis.py +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/src/docworkspace/workspace/core.py +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/tests/conftest.py +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/tests/test_fastapi_integration.py +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/tests/test_node.py +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/tests/test_node_io.py +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/tests/test_simple_operations.py +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/tests/test_workspace.py +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/tests/test_workspace_serialization_types.py +0 -0
- {docworkspace-0.2.2 → docworkspace-0.2.3}/tests/test_workspace_shim.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: docworkspace
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: A workspace library for managing Polars dataframes with parent-child relationships and lazy evaluation
|
|
5
5
|
Requires-Python: >=3.14
|
|
6
|
-
Requires-Dist: polars-text>=0.1.
|
|
6
|
+
Requires-Dist: polars-text>=0.1.3
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
|
|
9
9
|
# DocWorkspace
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "docworkspace"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.3"
|
|
4
4
|
description = "A workspace library for managing Polars dataframes with parent-child relationships and lazy evaluation"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.14"
|
|
7
|
-
dependencies = ["polars-text>=0.1.
|
|
7
|
+
dependencies = ["polars-text>=0.1.3"]
|
|
8
8
|
|
|
9
9
|
[build-system]
|
|
10
10
|
requires = ["hatchling"]
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"""Workspace file persistence helpers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Dict, Iterable, Union
|
|
8
|
+
|
|
9
|
+
from polars_text import list_source_paths, replace_source_paths
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING: # pragma: no cover
|
|
12
|
+
from .core import Workspace
|
|
13
|
+
|
|
14
|
+
from ..node.io import NODE_DATA_DIR
|
|
15
|
+
from ..node.io import from_dict as node_from_dict
|
|
16
|
+
from ..node.io import to_dict as node_to_dict
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _resolve_metadata_path(path: Path) -> Path:
|
|
20
|
+
if path.is_dir():
|
|
21
|
+
return path / "metadata.json"
|
|
22
|
+
if path.suffix.lower() == ".json":
|
|
23
|
+
return path
|
|
24
|
+
raise ValueError("Workspace path must be a directory or a .json file")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _collect_referenced_sources(plbin_paths: Iterable[Path]) -> set[Path]:
|
|
28
|
+
"""Return the set of absolute source paths referenced by every plbin plan."""
|
|
29
|
+
|
|
30
|
+
referenced: set[Path] = set()
|
|
31
|
+
for plbin in plbin_paths:
|
|
32
|
+
for raw in list_source_paths(plbin):
|
|
33
|
+
referenced.add(Path(raw).resolve())
|
|
34
|
+
return referenced
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _rebase_plan_sources(plbin_path: Path, data_dir: Path) -> None:
|
|
38
|
+
"""Rewrite scan source paths inside ``plbin_path`` to ``data_dir`` by basename.
|
|
39
|
+
|
|
40
|
+
Only paths whose basename exists under ``data_dir`` and whose stored value
|
|
41
|
+
differs from the resolved target are rewritten. Paths that already match
|
|
42
|
+
the current workspace layout are left untouched.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
current_sources = list_source_paths(plbin_path)
|
|
46
|
+
if not current_sources:
|
|
47
|
+
return
|
|
48
|
+
|
|
49
|
+
mapping: dict[str, str] = {}
|
|
50
|
+
for old in current_sources:
|
|
51
|
+
target = (data_dir / Path(old).name).resolve()
|
|
52
|
+
if not target.exists():
|
|
53
|
+
continue
|
|
54
|
+
target_str = str(target)
|
|
55
|
+
if old == target_str:
|
|
56
|
+
continue
|
|
57
|
+
mapping[old] = target_str
|
|
58
|
+
|
|
59
|
+
if mapping:
|
|
60
|
+
replace_source_paths(plbin_path, mapping)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _garbage_collect_workspace_data(
|
|
64
|
+
ws_root_dir: Path, nodes_data: list[dict[str, Any]]
|
|
65
|
+
) -> None:
|
|
66
|
+
"""Remove unreferenced parquet and plbin files from the workspace data dir.
|
|
67
|
+
|
|
68
|
+
* Parquet files not referenced by any registered node's plan are deleted.
|
|
69
|
+
* Plbin files whose name does not match a registered node's ``data_path``
|
|
70
|
+
are deleted (they belong to nodes no longer in the workspace).
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
data_dir = ws_root_dir / NODE_DATA_DIR
|
|
74
|
+
if not data_dir.exists() or not data_dir.is_dir():
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
expected_plbin_names = {
|
|
78
|
+
Path(str(node_payload["data_path"])).name for node_payload in nodes_data
|
|
79
|
+
}
|
|
80
|
+
registered_plbins = [
|
|
81
|
+
data_dir / name for name in expected_plbin_names if (data_dir / name).exists()
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
referenced_sources = _collect_referenced_sources(registered_plbins)
|
|
85
|
+
|
|
86
|
+
for candidate in data_dir.iterdir():
|
|
87
|
+
if not candidate.is_file():
|
|
88
|
+
continue
|
|
89
|
+
suffix = candidate.suffix.lower()
|
|
90
|
+
if suffix == ".plbin":
|
|
91
|
+
if candidate.name not in expected_plbin_names:
|
|
92
|
+
candidate.unlink(missing_ok=True)
|
|
93
|
+
elif suffix == ".parquet":
|
|
94
|
+
if candidate.resolve() not in referenced_sources:
|
|
95
|
+
candidate.unlink(missing_ok=True)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def write_workspace(workspace: "Workspace", path: Union[str, Path]) -> None:
|
|
99
|
+
target = _resolve_metadata_path(Path(path))
|
|
100
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
101
|
+
workspace.ws_root_dir = target.parent
|
|
102
|
+
|
|
103
|
+
description = workspace.description
|
|
104
|
+
created_at = workspace.created_at
|
|
105
|
+
modified_at = workspace.modified_at
|
|
106
|
+
|
|
107
|
+
nodes_data: list[dict[str, Any]] = []
|
|
108
|
+
for node in workspace.nodes.values():
|
|
109
|
+
nodes_data.append(node_to_dict(node))
|
|
110
|
+
|
|
111
|
+
workspace_metadata: Dict[str, Any] = {
|
|
112
|
+
"id": workspace.id,
|
|
113
|
+
"name": workspace.name,
|
|
114
|
+
"version": 2,
|
|
115
|
+
"description": description,
|
|
116
|
+
"created_at": created_at,
|
|
117
|
+
"modified_at": modified_at,
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
data = {"workspace_metadata": workspace_metadata, "nodes": nodes_data}
|
|
121
|
+
with target.open("w", encoding="utf-8") as f:
|
|
122
|
+
json.dump(data, f, ensure_ascii=False, indent=2)
|
|
123
|
+
|
|
124
|
+
_garbage_collect_workspace_data(target.parent, nodes_data)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def read_workspace_metadata(path: Union[str, Path]) -> Dict[str, Any]:
|
|
128
|
+
"""Load and return the workspace metadata dictionary from metadata.json.
|
|
129
|
+
|
|
130
|
+
This helper only reads/parses the JSON metadata file and does not attempt
|
|
131
|
+
to load any node data payload files.
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
target = _resolve_metadata_path(Path(path))
|
|
135
|
+
with target.open("r", encoding="utf-8") as f:
|
|
136
|
+
return json.load(f)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def read_workspace(path: Union[str, Path]) -> "Workspace":
|
|
140
|
+
from .core import Workspace
|
|
141
|
+
|
|
142
|
+
target = _resolve_metadata_path(Path(path))
|
|
143
|
+
data = read_workspace_metadata(path)
|
|
144
|
+
|
|
145
|
+
ws_meta = data.get("workspace_metadata", {})
|
|
146
|
+
workspace = Workspace(
|
|
147
|
+
name=ws_meta.get("name", "restored_workspace"),
|
|
148
|
+
ws_root_dir=target.parent,
|
|
149
|
+
)
|
|
150
|
+
workspace.id = ws_meta.get("id", workspace.id)
|
|
151
|
+
workspace.description = ws_meta.get("description", "") or ""
|
|
152
|
+
workspace.created_at = ws_meta.get("created_at")
|
|
153
|
+
workspace.modified_at = ws_meta.get("modified_at")
|
|
154
|
+
|
|
155
|
+
data_dir = (target.parent / NODE_DATA_DIR).resolve()
|
|
156
|
+
for node_entry in data.get("nodes", []):
|
|
157
|
+
plbin_abs = (target.parent / Path(str(node_entry["data_path"]))).resolve()
|
|
158
|
+
if plbin_abs.exists():
|
|
159
|
+
_rebase_plan_sources(plbin_abs, data_dir)
|
|
160
|
+
workspace.add_node(node_from_dict(node_entry, workspace=workspace))
|
|
161
|
+
|
|
162
|
+
return workspace
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
__all__ = [
|
|
166
|
+
"write_workspace",
|
|
167
|
+
"read_workspace_metadata",
|
|
168
|
+
"read_workspace",
|
|
169
|
+
]
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Workspace save-time garbage collection and load-time path rebasing."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import shutil
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import cast
|
|
8
|
+
|
|
9
|
+
import polars as pl
|
|
10
|
+
from polars_text import list_source_paths
|
|
11
|
+
|
|
12
|
+
from docworkspace.node import Node
|
|
13
|
+
from docworkspace.workspace import Workspace
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _make_parquet(path: Path, df: pl.DataFrame) -> None:
|
|
17
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
18
|
+
df.write_parquet(path)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_save_removes_orphan_parquet_and_plbin(tmp_path: Path):
|
|
22
|
+
ws_root = tmp_path / "ws"
|
|
23
|
+
ws_root.mkdir()
|
|
24
|
+
data_dir = ws_root / "data"
|
|
25
|
+
data_dir.mkdir()
|
|
26
|
+
|
|
27
|
+
kept_parquet = data_dir / "kept.parquet"
|
|
28
|
+
_make_parquet(kept_parquet, pl.DataFrame({"a": [1, 2, 3]}))
|
|
29
|
+
|
|
30
|
+
orphan_parquet = data_dir / "orphan.parquet"
|
|
31
|
+
_make_parquet(orphan_parquet, pl.DataFrame({"b": [9]}))
|
|
32
|
+
|
|
33
|
+
orphan_plbin = data_dir / "ghost-node-id.plbin"
|
|
34
|
+
orphan_plbin.write_bytes(b"not-a-real-plan")
|
|
35
|
+
|
|
36
|
+
ws = Workspace(name="gc_ws", ws_root_dir=ws_root)
|
|
37
|
+
lazy = pl.scan_parquet(kept_parquet.resolve())
|
|
38
|
+
ws.add_node(Node(data=lazy, name="kept"))
|
|
39
|
+
|
|
40
|
+
ws.save(ws_root)
|
|
41
|
+
|
|
42
|
+
assert kept_parquet.exists(), "Referenced parquet must be kept"
|
|
43
|
+
assert not orphan_parquet.exists(), "Unreferenced parquet must be deleted"
|
|
44
|
+
assert not orphan_plbin.exists(), "Unregistered plbin must be deleted"
|
|
45
|
+
|
|
46
|
+
plbin_files = list(data_dir.glob("*.plbin"))
|
|
47
|
+
assert len(plbin_files) == 1
|
|
48
|
+
sources = list_source_paths(plbin_files[0])
|
|
49
|
+
assert any(Path(s) == kept_parquet.resolve() for s in sources)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test_load_rebases_source_paths_after_workspace_move(tmp_path: Path):
|
|
53
|
+
original_root = tmp_path / "original"
|
|
54
|
+
original_root.mkdir()
|
|
55
|
+
data_dir = original_root / "data"
|
|
56
|
+
data_dir.mkdir()
|
|
57
|
+
|
|
58
|
+
parquet_path = data_dir / "input.parquet"
|
|
59
|
+
_make_parquet(parquet_path, pl.DataFrame({"x": [10, 20, 30]}))
|
|
60
|
+
|
|
61
|
+
ws = Workspace(name="move_ws", ws_root_dir=original_root)
|
|
62
|
+
lazy = pl.scan_parquet(parquet_path.resolve())
|
|
63
|
+
ws.add_node(Node(data=lazy, name="input"))
|
|
64
|
+
ws.save(original_root)
|
|
65
|
+
|
|
66
|
+
moved_root = tmp_path / "moved"
|
|
67
|
+
shutil.copytree(original_root, moved_root)
|
|
68
|
+
shutil.rmtree(original_root)
|
|
69
|
+
|
|
70
|
+
ws_reloaded = Workspace.load(moved_root)
|
|
71
|
+
assert len(ws_reloaded.nodes) == 1
|
|
72
|
+
node = next(iter(ws_reloaded.nodes.values()))
|
|
73
|
+
|
|
74
|
+
collected = cast(pl.DataFrame, node.data.collect())
|
|
75
|
+
assert collected.to_series().to_list() == [10, 20, 30]
|
|
76
|
+
|
|
77
|
+
plbin_files = list((moved_root / "data").glob("*.plbin"))
|
|
78
|
+
sources = list_source_paths(plbin_files[0])
|
|
79
|
+
moved_parquet = (moved_root / "data" / "input.parquet").resolve()
|
|
80
|
+
assert all(Path(s) == moved_parquet for s in sources)
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
version = 1
|
|
2
|
+
revision = 3
|
|
3
|
+
requires-python = ">=3.14"
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "colorama"
|
|
7
|
+
version = "0.4.6"
|
|
8
|
+
source = { registry = "https://pypi.org/simple" }
|
|
9
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
|
10
|
+
wheels = [
|
|
11
|
+
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
[[package]]
|
|
15
|
+
name = "docworkspace"
|
|
16
|
+
version = "0.2.3"
|
|
17
|
+
source = { editable = "." }
|
|
18
|
+
dependencies = [
|
|
19
|
+
{ name = "polars-text" },
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[package.dev-dependencies]
|
|
23
|
+
dev = [
|
|
24
|
+
{ name = "pytest" },
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[package.metadata]
|
|
28
|
+
requires-dist = [{ name = "polars-text", specifier = ">=0.1.3" }]
|
|
29
|
+
|
|
30
|
+
[package.metadata.requires-dev]
|
|
31
|
+
dev = [{ name = "pytest", specifier = ">=8.0.0" }]
|
|
32
|
+
|
|
33
|
+
[[package]]
|
|
34
|
+
name = "iniconfig"
|
|
35
|
+
version = "2.3.0"
|
|
36
|
+
source = { registry = "https://pypi.org/simple" }
|
|
37
|
+
sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" }
|
|
38
|
+
wheels = [
|
|
39
|
+
{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" },
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[[package]]
|
|
43
|
+
name = "packaging"
|
|
44
|
+
version = "26.1"
|
|
45
|
+
source = { registry = "https://pypi.org/simple" }
|
|
46
|
+
sdist = { url = "https://files.pythonhosted.org/packages/df/de/0d2b39fb4af88a0258f3bac87dfcbb48e73fbdea4a2ed0e2213f9a4c2f9a/packaging-26.1.tar.gz", hash = "sha256:f042152b681c4bfac5cae2742a55e103d27ab2ec0f3d88037136b6bfe7c9c5de", size = 215519, upload-time = "2026-04-14T21:12:49.362Z" }
|
|
47
|
+
wheels = [
|
|
48
|
+
{ url = "https://files.pythonhosted.org/packages/7a/c2/920ef838e2f0028c8262f16101ec09ebd5969864e5a64c4c05fad0617c56/packaging-26.1-py3-none-any.whl", hash = "sha256:5d9c0669c6285e491e0ced2eee587eaf67b670d94a19e94e3984a481aba6802f", size = 95831, upload-time = "2026-04-14T21:12:47.56Z" },
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
[[package]]
|
|
52
|
+
name = "pluggy"
|
|
53
|
+
version = "1.6.0"
|
|
54
|
+
source = { registry = "https://pypi.org/simple" }
|
|
55
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" }
|
|
56
|
+
wheels = [
|
|
57
|
+
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
[[package]]
|
|
61
|
+
name = "polars"
|
|
62
|
+
version = "1.40.0"
|
|
63
|
+
source = { registry = "https://pypi.org/simple" }
|
|
64
|
+
dependencies = [
|
|
65
|
+
{ name = "polars-runtime-32" },
|
|
66
|
+
]
|
|
67
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d9/1b/eea7d6fe6daafc1d784cc0f76c729b28051837ccb2d51ae64a0a3f798142/polars-1.40.0.tar.gz", hash = "sha256:711dd50dcbc35ba42a2625fcadc2a1349e2e9abf48e35631bdabafb90d89874b", size = 732943, upload-time = "2026-04-18T05:25:26.077Z" }
|
|
68
|
+
wheels = [
|
|
69
|
+
{ url = "https://files.pythonhosted.org/packages/b4/ad/d5ed79269b7fe59a3dbbfbdbecbe1e59a0b56e38d36491e57d2bfb5846c1/polars-1.40.0-py3-none-any.whl", hash = "sha256:60b1d677ca363e2fc6fdea8c3d16c0653fd52cc37f0249e0f29d9536d5aa45ef", size = 828012, upload-time = "2026-04-18T05:23:39.055Z" },
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
[[package]]
|
|
73
|
+
name = "polars-runtime-32"
|
|
74
|
+
version = "1.40.0"
|
|
75
|
+
source = { registry = "https://pypi.org/simple" }
|
|
76
|
+
sdist = { url = "https://files.pythonhosted.org/packages/fb/b2/eae6c1b3d16c7a64ff382f557985ff939cce13455e8c9d056ab8e1e0fc87/polars_runtime_32-1.40.0.tar.gz", hash = "sha256:e31bff8bd37492c714e155e2e1429ac2d9ddf2dd6ec6474cc1cc70ac0b2bd6af", size = 2935285, upload-time = "2026-04-18T05:25:28.038Z" }
|
|
77
|
+
wheels = [
|
|
78
|
+
{ url = "https://files.pythonhosted.org/packages/b0/e4/2325689d2af4f9e70699ff98e8a2543707bebc34af78a5fe0e654107d9ed/polars_runtime_32-1.40.0-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:cab3ac7ff5bc9e0f4b3b146015569e9417cf0eaff8d3fb71004d73d67b6f09c7", size = 52092528, upload-time = "2026-04-18T05:23:42.341Z" },
|
|
79
|
+
{ url = "https://files.pythonhosted.org/packages/19/a6/82157b19c5c40b2c1ed0493b87b9eaf9b4863cdedca5575ee083488b45ba/polars_runtime_32-1.40.0-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:d29624c75c4049253300786d00882fce620b3677ce495ebc4199292de8c2ba02", size = 46365073, upload-time = "2026-04-18T05:23:46.7Z" },
|
|
80
|
+
{ url = "https://files.pythonhosted.org/packages/85/b5/5c4f1f2545f56c664cc57bbdd1aa66fcfcb129aa137ed72cc81d58eb480f/polars_runtime_32-1.40.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a034dc0d8481fc1ca0456ab33e98e53a4c6d6cc6a2edb36246cc81c936b925dc", size = 50250561, upload-time = "2026-04-18T05:23:51.316Z" },
|
|
81
|
+
{ url = "https://files.pythonhosted.org/packages/8e/51/cb5eb75394f39c0ec14fddcc9b11adb707e1f28224a552ecbfa72d39b61b/polars_runtime_32-1.40.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70e78c2f13a54a9d92ae30d2625bda759173cc4867ad6a39f85f140058d899c6", size = 56243695, upload-time = "2026-04-18T05:23:55.932Z" },
|
|
82
|
+
{ url = "https://files.pythonhosted.org/packages/16/3a/be1437c0fbecbb07d81b151456089c3cf054eea5a791f849ed39b67611ca/polars_runtime_32-1.40.0-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1843272c0ef49f4a07435888f0059eca08ec16ab9880219c457195a081df0281", size = 50427843, upload-time = "2026-04-18T05:24:00.159Z" },
|
|
83
|
+
{ url = "https://files.pythonhosted.org/packages/be/c7/ea6449a2161816a13ed1d8aa02177d5a0594e011f0df5ddd2fad8e5bf20e/polars_runtime_32-1.40.0-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:081237dba07f15d61fc151825f203165480e9503ebe72a474a8c99aa78021962", size = 54153077, upload-time = "2026-04-18T05:24:05.066Z" },
|
|
84
|
+
{ url = "https://files.pythonhosted.org/packages/aa/1a/0b239138afe8b80a1a0b4c95db3884e6afbbe82ec3318918ab03bc57f231/polars_runtime_32-1.40.0-cp310-abi3-win_amd64.whl", hash = "sha256:a916040e0b7f461ce987e4551fed9eea5914b4fbb5af907b1d9e80db71fadeb5", size = 51822748, upload-time = "2026-04-18T05:24:09.384Z" },
|
|
85
|
+
{ url = "https://files.pythonhosted.org/packages/06/ce/c16ef8fd3030b7342032b040fab21a42f6fee57e47ee7f41e2f1a1e36f01/polars_runtime_32-1.40.0-cp310-abi3-win_arm64.whl", hash = "sha256:719c64eecde24a95aa3599eb9c8efc98c1499bab7ef9c01cbbe8939cd583e654", size = 45819617, upload-time = "2026-04-18T05:24:13.214Z" },
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
[[package]]
|
|
89
|
+
name = "polars-text"
|
|
90
|
+
version = "0.1.3"
|
|
91
|
+
source = { registry = "https://pypi.org/simple" }
|
|
92
|
+
dependencies = [
|
|
93
|
+
{ name = "polars" },
|
|
94
|
+
]
|
|
95
|
+
sdist = { url = "https://files.pythonhosted.org/packages/fc/36/03bb22e59897e878b9b73cf7f8bb826b587affd42276591619a14b955483/polars_text-0.1.3.tar.gz", hash = "sha256:06b361a607d7a6fa204b040768f159acad88c7f6daf64a213a776f10b7468d92", size = 5357581, upload-time = "2026-04-21T14:03:28.096Z" }
|
|
96
|
+
wheels = [
|
|
97
|
+
{ url = "https://files.pythonhosted.org/packages/5c/54/ec8bb8005b4b2fc70787b6191751d92d2eff3a8c7aa34964ec0aca145451/polars_text-0.1.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e3dad2a26f5d18b5eca8075b97103ad50490a95d735a3d83ddbf805d92f40b4f", size = 16551094, upload-time = "2026-04-21T14:03:18.03Z" },
|
|
98
|
+
{ url = "https://files.pythonhosted.org/packages/a8/da/363f0d519bc0df83e71f2815f8c7018ee4c50876f1f23a2952e1e2739930/polars_text-0.1.3-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:245d3703cce24f5e9afea9ba746eb991c3cc6b06a5a7c5fd6863a22f42172331", size = 20896342, upload-time = "2026-04-21T14:03:21.747Z" },
|
|
99
|
+
{ url = "https://files.pythonhosted.org/packages/ed/4f/9de5690509cea46661e9398290a037a472f43eb935a378d158feeddf4792/polars_text-0.1.3-cp314-cp314-win_amd64.whl", hash = "sha256:0e3f6084581756925867b1c393ab4b6407d4eef05ea7cf46d9c5c4b25b925a74", size = 16329073, upload-time = "2026-04-21T14:03:25.411Z" },
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
[[package]]
|
|
103
|
+
name = "pygments"
|
|
104
|
+
version = "2.20.0"
|
|
105
|
+
source = { registry = "https://pypi.org/simple" }
|
|
106
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
|
|
107
|
+
wheels = [
|
|
108
|
+
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
[[package]]
|
|
112
|
+
name = "pytest"
|
|
113
|
+
version = "9.0.3"
|
|
114
|
+
source = { registry = "https://pypi.org/simple" }
|
|
115
|
+
dependencies = [
|
|
116
|
+
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
117
|
+
{ name = "iniconfig" },
|
|
118
|
+
{ name = "packaging" },
|
|
119
|
+
{ name = "pluggy" },
|
|
120
|
+
{ name = "pygments" },
|
|
121
|
+
]
|
|
122
|
+
sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" }
|
|
123
|
+
wheels = [
|
|
124
|
+
{ url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" },
|
|
125
|
+
]
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
"""Workspace file persistence helpers."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import json
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
from typing import TYPE_CHECKING, Any, Dict, Union
|
|
8
|
-
|
|
9
|
-
if TYPE_CHECKING: # pragma: no cover
|
|
10
|
-
from .core import Workspace
|
|
11
|
-
|
|
12
|
-
from ..node.io import from_dict as node_from_dict
|
|
13
|
-
from ..node.io import to_dict as node_to_dict
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def _resolve_metadata_path(path: Path) -> Path:
|
|
17
|
-
if path.is_dir():
|
|
18
|
-
return path / "metadata.json"
|
|
19
|
-
if path.suffix.lower() == ".json":
|
|
20
|
-
return path
|
|
21
|
-
raise ValueError("Workspace path must be a directory or a .json file")
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def write_workspace(workspace: "Workspace", path: Union[str, Path]) -> None:
|
|
25
|
-
target = _resolve_metadata_path(Path(path))
|
|
26
|
-
target.parent.mkdir(parents=True, exist_ok=True)
|
|
27
|
-
workspace.ws_root_dir = target.parent
|
|
28
|
-
|
|
29
|
-
description = workspace.description
|
|
30
|
-
created_at = workspace.created_at
|
|
31
|
-
modified_at = workspace.modified_at
|
|
32
|
-
|
|
33
|
-
nodes_data: list[dict[str, Any]] = []
|
|
34
|
-
for node in workspace.nodes.values():
|
|
35
|
-
nodes_data.append(node_to_dict(node))
|
|
36
|
-
|
|
37
|
-
workspace_metadata: Dict[str, Any] = {
|
|
38
|
-
"id": workspace.id,
|
|
39
|
-
"name": workspace.name,
|
|
40
|
-
"version": 2,
|
|
41
|
-
"description": description,
|
|
42
|
-
"created_at": created_at,
|
|
43
|
-
"modified_at": modified_at,
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
data = {"workspace_metadata": workspace_metadata, "nodes": nodes_data}
|
|
47
|
-
with target.open("w", encoding="utf-8") as f:
|
|
48
|
-
json.dump(data, f, ensure_ascii=False, indent=2)
|
|
49
|
-
|
|
50
|
-
try:
|
|
51
|
-
data_dir = target.parent / "data"
|
|
52
|
-
expected_node_files = {
|
|
53
|
-
Path(str(node_payload["data_path"])).name for node_payload in nodes_data
|
|
54
|
-
}
|
|
55
|
-
if data_dir.exists() and data_dir.is_dir():
|
|
56
|
-
for candidate in data_dir.glob("*.plbin"):
|
|
57
|
-
if candidate.name not in expected_node_files:
|
|
58
|
-
candidate.unlink(missing_ok=True)
|
|
59
|
-
except Exception:
|
|
60
|
-
pass
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def read_workspace_metadata(path: Union[str, Path]) -> Dict[str, Any]:
|
|
64
|
-
"""Load and return the workspace metadata dictionary from metadata.json.
|
|
65
|
-
|
|
66
|
-
This helper only reads/parses the JSON metadata file and does not attempt
|
|
67
|
-
to load any node data payload files.
|
|
68
|
-
"""
|
|
69
|
-
|
|
70
|
-
target = _resolve_metadata_path(Path(path))
|
|
71
|
-
with target.open("r", encoding="utf-8") as f:
|
|
72
|
-
return json.load(f)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def read_workspace(path: Union[str, Path]) -> "Workspace":
|
|
76
|
-
from .core import Workspace
|
|
77
|
-
|
|
78
|
-
target = _resolve_metadata_path(Path(path))
|
|
79
|
-
data = read_workspace_metadata(path)
|
|
80
|
-
|
|
81
|
-
ws_meta = data.get("workspace_metadata", {})
|
|
82
|
-
workspace = Workspace(
|
|
83
|
-
name=ws_meta.get("name", "restored_workspace"),
|
|
84
|
-
ws_root_dir=target.parent,
|
|
85
|
-
)
|
|
86
|
-
workspace.id = ws_meta.get("id", workspace.id)
|
|
87
|
-
workspace.description = ws_meta.get("description", "") or ""
|
|
88
|
-
workspace.created_at = ws_meta.get("created_at")
|
|
89
|
-
workspace.modified_at = ws_meta.get("modified_at")
|
|
90
|
-
|
|
91
|
-
for node_entry in data.get("nodes", []):
|
|
92
|
-
workspace.add_node(node_from_dict(node_entry, workspace=workspace))
|
|
93
|
-
|
|
94
|
-
return workspace
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
__all__ = [
|
|
98
|
-
"write_workspace",
|
|
99
|
-
"read_workspace_metadata",
|
|
100
|
-
"read_workspace",
|
|
101
|
-
]
|
docworkspace-0.2.2/uv.lock
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
version = 1
|
|
2
|
-
revision = 3
|
|
3
|
-
requires-python = ">=3.14"
|
|
4
|
-
|
|
5
|
-
[[package]]
|
|
6
|
-
name = "colorama"
|
|
7
|
-
version = "0.4.6"
|
|
8
|
-
source = { registry = "https://pypi.org/simple" }
|
|
9
|
-
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
|
10
|
-
wheels = [
|
|
11
|
-
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
|
12
|
-
]
|
|
13
|
-
|
|
14
|
-
[[package]]
|
|
15
|
-
name = "docworkspace"
|
|
16
|
-
version = "0.2.2"
|
|
17
|
-
source = { editable = "." }
|
|
18
|
-
dependencies = [
|
|
19
|
-
{ name = "polars-text" },
|
|
20
|
-
]
|
|
21
|
-
|
|
22
|
-
[package.dev-dependencies]
|
|
23
|
-
dev = [
|
|
24
|
-
{ name = "pytest" },
|
|
25
|
-
]
|
|
26
|
-
|
|
27
|
-
[package.metadata]
|
|
28
|
-
requires-dist = [{ name = "polars-text", specifier = ">=0.1.2" }]
|
|
29
|
-
|
|
30
|
-
[package.metadata.requires-dev]
|
|
31
|
-
dev = [{ name = "pytest", specifier = ">=8.0.0" }]
|
|
32
|
-
|
|
33
|
-
[[package]]
|
|
34
|
-
name = "iniconfig"
|
|
35
|
-
version = "2.3.0"
|
|
36
|
-
source = { registry = "https://pypi.org/simple" }
|
|
37
|
-
sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" }
|
|
38
|
-
wheels = [
|
|
39
|
-
{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" },
|
|
40
|
-
]
|
|
41
|
-
|
|
42
|
-
[[package]]
|
|
43
|
-
name = "packaging"
|
|
44
|
-
version = "26.0"
|
|
45
|
-
source = { registry = "https://pypi.org/simple" }
|
|
46
|
-
sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" }
|
|
47
|
-
wheels = [
|
|
48
|
-
{ url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" },
|
|
49
|
-
]
|
|
50
|
-
|
|
51
|
-
[[package]]
|
|
52
|
-
name = "pluggy"
|
|
53
|
-
version = "1.6.0"
|
|
54
|
-
source = { registry = "https://pypi.org/simple" }
|
|
55
|
-
sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" }
|
|
56
|
-
wheels = [
|
|
57
|
-
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
|
|
58
|
-
]
|
|
59
|
-
|
|
60
|
-
[[package]]
|
|
61
|
-
name = "polars"
|
|
62
|
-
version = "1.39.3"
|
|
63
|
-
source = { registry = "https://pypi.org/simple" }
|
|
64
|
-
dependencies = [
|
|
65
|
-
{ name = "polars-runtime-32" },
|
|
66
|
-
]
|
|
67
|
-
sdist = { url = "https://files.pythonhosted.org/packages/93/ab/f19e592fce9e000da49c96bf35e77cef67f9cb4b040bfa538a2764c0263e/polars-1.39.3.tar.gz", hash = "sha256:2e016c7f3e8d14fa777ef86fe0477cec6c67023a20ba4c94d6e8431eefe4a63c", size = 728987, upload-time = "2026-03-20T11:16:24.836Z" }
|
|
68
|
-
wheels = [
|
|
69
|
-
{ url = "https://files.pythonhosted.org/packages/b4/db/08f4ca10c5018813e7e0b59e4472302328b3d2ab1512f5a2157a814540e0/polars-1.39.3-py3-none-any.whl", hash = "sha256:c2b955ccc0a08a2bc9259785decf3d5c007b489b523bf2390cf21cec2bb82a56", size = 823985, upload-time = "2026-03-20T11:14:23.619Z" },
|
|
70
|
-
]
|
|
71
|
-
|
|
72
|
-
[[package]]
|
|
73
|
-
name = "polars-runtime-32"
|
|
74
|
-
version = "1.39.3"
|
|
75
|
-
source = { registry = "https://pypi.org/simple" }
|
|
76
|
-
sdist = { url = "https://files.pythonhosted.org/packages/17/39/c8688696bc22b6c501e3b82ef3be10e543c07a785af5660f30997cd22dd2/polars_runtime_32-1.39.3.tar.gz", hash = "sha256:c728e4f469cafab501947585f36311b8fb222d3e934c6209e83791e0df20b29d", size = 2872335, upload-time = "2026-03-20T11:16:26.581Z" }
|
|
77
|
-
wheels = [
|
|
78
|
-
{ url = "https://files.pythonhosted.org/packages/3b/74/1b41205f7368c9375ab1dea91178eaa20435fe3eff036390a53a7660b416/polars_runtime_32-1.39.3-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:425c0b220b573fa097b4042edff73114cc6d23432a21dfd2dc41adf329d7d2e9", size = 45273243, upload-time = "2026-03-20T11:14:26.691Z" },
|
|
79
|
-
{ url = "https://files.pythonhosted.org/packages/90/bf/297716b3095fe719be20fcf7af1d2b6ab069c38199bbace2469608a69b3a/polars_runtime_32-1.39.3-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:ef5884711e3c617d7dc93519a7d038e242f5741cfe5fe9afd32d58845d86c562", size = 40842924, upload-time = "2026-03-20T11:14:31.154Z" },
|
|
80
|
-
{ url = "https://files.pythonhosted.org/packages/3d/3e/e65236d9d0d9babfa0ecba593413c06530fca60a8feb8f66243aa5dba92e/polars_runtime_32-1.39.3-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06b47f535eb1f97a9a1e5b0053ef50db3a4276e241178e37bbb1a38b1fa53b14", size = 43220650, upload-time = "2026-03-20T11:14:35.458Z" },
|
|
81
|
-
{ url = "https://files.pythonhosted.org/packages/b0/15/fc3e43f3fdf3f20b7dfb5abe871ab6162cf8fb4aeabf4cfad822d5dc4c79/polars_runtime_32-1.39.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bc9e13dc1d2e828331f2fe8ccbc9757554dc4933a8d3e85e906b988178f95ed", size = 46877498, upload-time = "2026-03-20T11:14:40.14Z" },
|
|
82
|
-
{ url = "https://files.pythonhosted.org/packages/3c/81/bd5f895919e32c6ab0a7786cd0c0ca961cb03152c47c3645808b54383f31/polars_runtime_32-1.39.3-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:363d49e3a3e638fc943e2b9887940300a7d06789930855a178a4727949259dc2", size = 43380176, upload-time = "2026-03-20T11:14:45.566Z" },
|
|
83
|
-
{ url = "https://files.pythonhosted.org/packages/7a/3e/c86433c3b5ec0315bdfc7640d0c15d41f1216c0103a0eab9a9b5147d6c4c/polars_runtime_32-1.39.3-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7c206bdcc7bc62ea038d6adea8e44b02f0e675e0191a54c810703b4895208ea4", size = 46485933, upload-time = "2026-03-20T11:14:51.155Z" },
|
|
84
|
-
{ url = "https://files.pythonhosted.org/packages/54/ce/200b310cf91f98e652eb6ea09fdb3a9718aa0293ebf113dce325797c8572/polars_runtime_32-1.39.3-cp310-abi3-win_amd64.whl", hash = "sha256:d66ca522517554a883446957539c40dc7b75eb0c2220357fb28bc8940d305339", size = 46995458, upload-time = "2026-03-20T11:14:56.074Z" },
|
|
85
|
-
{ url = "https://files.pythonhosted.org/packages/da/76/2d48927e0aa2abbdde08cbf4a2536883b73277d47fbeca95e952de86df34/polars_runtime_32-1.39.3-cp310-abi3-win_arm64.whl", hash = "sha256:f49f51461de63f13e5dd4eb080421c8f23f856945f3f8bd5b2b1f59da52c2860", size = 41857648, upload-time = "2026-03-20T11:15:01.142Z" },
|
|
86
|
-
]
|
|
87
|
-
|
|
88
|
-
[[package]]
|
|
89
|
-
name = "polars-text"
|
|
90
|
-
version = "0.1.2"
|
|
91
|
-
source = { registry = "https://pypi.org/simple" }
|
|
92
|
-
dependencies = [
|
|
93
|
-
{ name = "polars" },
|
|
94
|
-
]
|
|
95
|
-
sdist = { url = "https://files.pythonhosted.org/packages/42/b9/1653c8ac742e3b84ebe328d213b5eb09ee96ce6241c27364911a2e29e2aa/polars_text-0.1.2.tar.gz", hash = "sha256:2a080c8e7e0ecef10b3b431fb14dbb90de6faf552e24ffa30f52f0876c5fe5e8", size = 53365, upload-time = "2026-04-07T23:41:59.225Z" }
|
|
96
|
-
wheels = [
|
|
97
|
-
{ url = "https://files.pythonhosted.org/packages/b4/60/829e2048d45aa63ec9c2634f63bf750b9569aded969920db3240737ea9e9/polars_text-0.1.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f7dbd56bc3c90d87defc9e682e816ff7cdf264f19ee458df190322ba92c10c20", size = 7659172, upload-time = "2026-04-07T23:41:53.444Z" },
|
|
98
|
-
{ url = "https://files.pythonhosted.org/packages/a5/60/6417a5e73915e0dbc4c1f0643b41c715428a5350f4b2a97903655b526342/polars_text-0.1.2-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:0283306eb5c185cac89db3abf1ecf877b47c4e18a2afc4ad8892a5ab12116b8f", size = 10981911, upload-time = "2026-04-07T23:41:55.388Z" },
|
|
99
|
-
{ url = "https://files.pythonhosted.org/packages/da/a6/ff1dd58b29c7ac03e7344311e2b82f211d043321d8f9705a9e8e664db900/polars_text-0.1.2-cp314-cp314-win_amd64.whl", hash = "sha256:5b80da5e9902ecaefc4db227a38d20fc6c328ee4254678319329b38248c2ea4e", size = 7771979, upload-time = "2026-04-07T23:41:57.646Z" },
|
|
100
|
-
]
|
|
101
|
-
|
|
102
|
-
[[package]]
|
|
103
|
-
name = "pygments"
|
|
104
|
-
version = "2.20.0"
|
|
105
|
-
source = { registry = "https://pypi.org/simple" }
|
|
106
|
-
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
|
|
107
|
-
wheels = [
|
|
108
|
-
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
|
|
109
|
-
]
|
|
110
|
-
|
|
111
|
-
[[package]]
|
|
112
|
-
name = "pytest"
|
|
113
|
-
version = "9.0.3"
|
|
114
|
-
source = { registry = "https://pypi.org/simple" }
|
|
115
|
-
dependencies = [
|
|
116
|
-
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
117
|
-
{ name = "iniconfig" },
|
|
118
|
-
{ name = "packaging" },
|
|
119
|
-
{ name = "pluggy" },
|
|
120
|
-
{ name = "pygments" },
|
|
121
|
-
]
|
|
122
|
-
sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" }
|
|
123
|
-
wheels = [
|
|
124
|
-
{ url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" },
|
|
125
|
-
]
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|