Skip to content

Commit 3c66a04

Browse files
authored
First try at accommodating "modern" editable python packages (#52)
* First try at accomidating "modern" editable python packages * `ruff` fixes * Python 3.8 fixes for `glob.glob` * Fix for the Python 3.8 fix * `catch` TypeError when finding editable packages * Better `_find_editable_deps_files` thanks to @cjdoris * Fix up `ruff` complaints * revert version * update changelog * tweak deps.py * update readme * add test * move package out of src to force the particular installation method we are testing --------- Co-authored-by: Christopher Doris <github.com/cjdoris>
1 parent 5c6fbdf commit 3c66a04

File tree

9 files changed

+70
-4
lines changed

9 files changed

+70
-4
lines changed

.github/workflows/tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ jobs:
2727
- name: Install dependencies
2828
run: |
2929
python -m pip install --upgrade pip
30-
pip install ruff pytest pytest-cov
31-
pip install -e .
30+
pip install ruff pytest pytest-cov
31+
pip install -e . -e test/juliapkg_test_editable_setuptools
3232
- name: Lint with ruff
3333
run: |
3434
ruff format --check

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Changelog
22

3+
## Unreleased
4+
* Support editable dependencies from setuptools (experimental).
5+
36
## v0.1.17 (2025-05-13)
47
* Respect `JULIAUP_DEPOT_PATH` when searching for Julia using juliaup.
58
* Add special handling of `<=python` version for OpenSSL compatibility between Julia and Python.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ More strategies may be added in a future release.
104104

105105
JuliaPkg looks for `juliapkg.json` files in many locations, namely:
106106
- `{project}/pyjuliapkg` where project is as above (depending on your environment).
107-
- Every directory and direct sub-directory in `sys.path`.
107+
- Every installed package (looks through `sys.path` and `sys.meta_path`).
108108

109109
The last point means that if you put a `juliapkg.json` file in a package, then install that
110110
package, then JuliaPkg will find those dependencies and install them.

pyproject.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ build-backend = "hatchling.build"
2525
select = ["E", "W", "F", "I"]
2626

2727
[tool.uv]
28-
dev-dependencies = ["pytest", "pre-commit"]
28+
dev-dependencies = ["pytest", "pre-commit", "juliapkg_test_editable_setuptools"]
29+
30+
[tool.uv.sources]
31+
juliapkg_test_editable_setuptools = { path = "test/juliapkg_test_editable_setuptools", editable = true }
2932

3033
[tool.hatch.build.targets.wheel]
3134
packages = ["src/juliapkg"]

src/juliapkg/deps.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,26 @@ def can_skip_resolve():
169169
return deps
170170

171171

172+
def editable_deps_files():
173+
"""Finds setuptools-style editable dependencies."""
174+
ans = []
175+
for finder in sys.meta_path:
176+
module_name = finder.__module__
177+
if module_name.startswith("__editable___") and module_name.endswith("_finder"):
178+
m = sys.modules[module_name]
179+
paths = m.MAPPING.values()
180+
for path in paths:
181+
if not os.path.isdir(path):
182+
continue
183+
fn = os.path.join(path, "juliapkg.json")
184+
ans.append(fn)
185+
for subdir in os.listdir(path):
186+
fn = os.path.join(path, subdir, "juliapkg.json")
187+
ans.append(fn)
188+
189+
return ans
190+
191+
172192
def deps_files():
173193
ans = []
174194
# the default deps file
@@ -184,6 +204,9 @@ def deps_files():
184204
for subdir in os.listdir(path):
185205
fn = os.path.join(path, subdir, "juliapkg.json")
186206
ans.append(fn)
207+
208+
ans += editable_deps_files()
209+
187210
return list(
188211
set(
189212
os.path.normcase(os.path.normpath(os.path.abspath(fn)))
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""Test package for editable installs with juliapkg.json."""
2+
3+
__version__ = "0.1.0"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"julia": "1.6",
3+
"packages": {
4+
"Example": {
5+
"uuid": "7876af07-990d-54b4-ab0e-23690620f79a"
6+
}
7+
}
8+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[build-system]
2+
requires = ["setuptools>=42"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "juliapkg_test_editable_setuptools"
7+
version = "0.1.0"
8+
description = "Test package for editable installs with juliapkg.json"
9+
authors = [{name = "Test User", email = "[email protected]"}]
10+
requires-python = ">=3.7"
11+
12+
[tool.setuptools]
13+
packages = ["juliapkg_test_editable_setuptools"]
14+
package-data = { "juliapkg_test_editable_setuptools" = ["juliapkg.json"] }

test/test_all.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,15 @@ def deps():
112112
juliapkg.rm("Example1", target=tdir)
113113

114114
assert deps() == {"packages": {"Example2": {"uuid": "0002"}}}
115+
116+
117+
def test_editable_setuptools():
118+
# test that editable deps files are found for setuptools packages
119+
fn = os.path.join(
120+
os.path.dirname(__file__),
121+
"juliapkg_test_editable_setuptools",
122+
"juliapkg_test_editable_setuptools",
123+
"juliapkg.json",
124+
)
125+
assert os.path.exists(fn)
126+
assert any(os.path.samefile(fn, x) for x in juliapkg.deps.deps_files())

0 commit comments

Comments
 (0)