Skip to content

Commit ce9bf99

Browse files
Merge pull request #742 from bespokelabsai/codex/shared-bespokelabs-namespace
Fix shared namespace packaging for Curator and sibling SDKs
2 parents 461b417 + 6e25db3 commit ce9bf99

5 files changed

Lines changed: 56 additions & 4 deletions

File tree

‎README.md‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,28 @@ Check out our full documentation for [getting started](https://docs.bespokelabs.
5656
```bash
5757
pip install bespokelabs-curator
5858
```
59+
60+
Curator and Sandbox share the `bespokelabs` import namespace:
61+
62+
```bash
63+
python -m pip install bespokelabs-curator bespokelabs-sandbox
64+
```
65+
66+
```python
67+
from bespokelabs import curator, sandbox
68+
```
69+
70+
The separate `bespokelabs` distribution is not required. The Nimble SDK's
71+
distribution is `bespokelabs-nimble`. Each project must own only its subpackage
72+
(`bespokelabs/curator`, `bespokelabs/sandbox`, or `bespokelabs/nimble`), leaving
73+
the shared `bespokelabs` directory without an `__init__.py`.
74+
75+
When upgrading from releases that installed that shared file, use a fresh virtual
76+
environment and run `python -m pip` with the Python interpreter used by your app
77+
or notebook. Old editable checkouts or a local `bespokelabs.py` can shadow the
78+
installed namespace. A traceback naming a dependency inside Curator indicates a
79+
dependency failure; changing the package name alone will not fix it.
80+
5981
## 📕 Examples
6082

6183
### Finetuning/Distillation

‎poetry.lock‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎pyproject.toml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description = "Bespoke Labs Curator"
55
authors = ["Bespoke Labs <company@bespokelabs.ai>"]
66
readme = "README.md"
77
packages = [
8-
{include = "bespokelabs", from = "src"},
8+
{include = "bespokelabs/curator", from = "src"},
99
]
1010
include = [
1111
"src/bespokelabs/curator/viewer/static/**/*"
@@ -35,7 +35,7 @@ aiofiles = ">=22.0,<26.0"
3535
anthropic = "^0.84.0"
3636
vertexai = "1.71.1"
3737
vllm = { version = "^0.6.3", optional = true }
38-
bespokelabs-sandbox = "0.1.1"
38+
bespokelabs-sandbox = ">=0.1.1,<0.2.0"
3939
tinker = { version = "^0.8.0", optional = true, python = ">=3.11" }
4040

4141
posthog = "^3.11.0"

‎src/bespokelabs/__init__.py‎

Lines changed: 0 additions & 1 deletion
This file was deleted.

‎tests/unittests/test_namespace.py‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""Check that a source install can share its namespace with another project."""
2+
3+
import subprocess
4+
import sys
5+
from pathlib import Path
6+
7+
import pytest
8+
9+
10+
@pytest.mark.parametrize("source_first", [True, False])
11+
def test_separate_namespace_portions(tmp_path: Path, source_first: bool):
12+
source = Path(__file__).resolve().parents[2] / "src"
13+
sibling = tmp_path / "other-project"
14+
package = sibling / "bespokelabs" / "namespace_probe"
15+
package.mkdir(parents=True)
16+
(package / "__init__.py").write_text("VALUE = 42\n")
17+
paths = [str(source), str(sibling)]
18+
if not source_first:
19+
paths.reverse()
20+
code = f"""
21+
import sys
22+
from importlib.util import find_spec
23+
sys.path[:0] = {paths!r}
24+
from bespokelabs import namespace_probe
25+
import bespokelabs
26+
assert namespace_probe.VALUE == 42
27+
assert bespokelabs.__file__ is None
28+
assert find_spec('bespokelabs.curator').origin == {str(source / 'bespokelabs/curator/__init__.py')!r}
29+
"""
30+
# Disable site-packages so installed siblings cannot mask the source layout.
31+
subprocess.run([sys.executable, "-I", "-S", "-c", code], check=True, capture_output=True, text=True)

0 commit comments

Comments
 (0)