Skip to content

Commit ec8e006

Browse files
authored
FIX/CI: Support installing from Git URLs (#287)
When installing ESPEI from a git source using package managers, e.g. ```shell pip install git+https://github.com/phasesresearchlab/espei.git@master ``` or entirely from a fresh env using `uv`: ```shell uv init --bare uv add "espei @ git+https://github.com/phasesresearchlab/espei.git@master" ``` the code can successfully install, but give errors like this when you try to use it: ```python Traceback (most recent call last): File "<python-input-0>", line 1, in <module> import espei File "/Users/bocklund1/src/test/.venv/lib/python3.13/site-packages/espei/__init__.py", line 10, in <module> __version__ = get_version(root='..', relative_to=__file__) File "/Users/bocklund1/src/test/.venv/lib/python3.13/site-packages/setuptools_scm/_get_version.py", line 56, in get_version return _get_version_public( root=root, ...<17 lines>... scm=scm, ) File "/Users/bocklund1/src/test/.venv/lib/python3.13/site-packages/vcs_versioning/_get_version_impl.py", line 257, in get_version _version_missing(config) ~~~~~~~~~~~~~~~~^^^^^^^^ File "/Users/bocklund1/src/test/.venv/lib/python3.13/site-packages/vcs_versioning/_get_version_impl.py", line 207, in _version_missing raise LookupError(error_msg) LookupError: setuptools-scm was unable to detect version for /Users/bocklund1/src/test/.venv/lib/python3.13/site-packages. Make sure you're either building from a fully intact git repository or PyPI tarballs. Most other sources (such as GitHub's tarballs, a git checkout without the .git folder) don't contain the necessary metadata and will not work. For example, if you're using pip, instead of https://github.com/user/proj/archive/master.zip use git+https://github.com/user/proj.git#egg=proj Alternatively, set the version with the environment variable SETUPTOOLS_SCM_PRETEND_VERSION_FOR_${NORMALIZED_DIST_NAME} as described in https://setuptools-scm.readthedocs.io/en/latest/config/ ``` Looking at ```python # espei/__init__.py try: from ._dev import get_version # We have a local (editable) installation and can get the version based on the # source control management system at the project root. __version__ = get_version(root='..', relative_to=__file__) del get_version except ImportError: # Fall back on the metadata of the installed package from importlib.metadata import version __version__ = version("espei") del version ``` There current behavior of `__init__.py` expects one of the following cases: 1. Installing from a release version that has a sdist/bdist where `MANIFEST.in` does `prune espei/_dev` and therefore `._dev` doesn't exist and we hit the `ImportError` fallback to `importlib.metadata` 2. For working from the git source checkout, you have full git history and `get_version` from `setuptools_scm` detects the git tag and can set the versions correctly. However, when installing on one of the failure modes above, you get an in between case where a) you get all the files, which includes `_dev/__init__.py`, and b) you don't get the full git repo with the full git version history and thus you don't get the `ImportError`, but you have `setuptools_scm.get_version` raise a `LookupError` when it fails. This PR catches that `LookupError` and falls back onto the `importlib.metadata` version which does work on installs using the `git+` mechanism above on `pip` and `uv`. It also adds a new GitHub Action file for doing smoke tests, where in this case we add a single test that installing ESPEI to a bare repo and then importing works. This should fix issues in getting CI working in downstream packages like here: materialsgenomefoundation/kawin#19
1 parent 6584dc4 commit ec8e006

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

.github/workflows/smoke_tests.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Smoke Tests
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
git-url:
7+
# see the following for valid dependency specifiers
8+
# https://packaging.python.org/en/latest/specifications/dependency-specifiers/#dependency-specifiers
9+
# we construct from the GitHub Actions context
10+
name: Install and import from git url
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: astral-sh/setup-uv@v7
14+
with:
15+
ignore-empty-workdir: "true" # resolve warning about "Empty workdir detected. This may cause unexpected behavior. You can enable ignore-empty-workdir to mute this warning."
16+
cache-dependency-glob: "" # resolve warning about "No file matched to ... The cache will never get invalidated. Make sure you have checked out the target repository and configured the cache-dependency-glob input correctly."
17+
- run: uv init --bare --name smoke-test
18+
- run: uv add "espei @ git+https://github.com/${{ github.repository }}.git@${{ github.sha }}"
19+
- run: uv run python -c "import espei; print(espei.__version__)"

espei/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
# source control management system at the project root.
1010
__version__ = get_version(root='..', relative_to=__file__)
1111
del get_version
12-
except ImportError:
12+
except (ImportError, LookupError):
1313
# Fall back on the metadata of the installed package
14+
# ImportError occurs if there's no ._dev
15+
# LookupError occurs if get_version fails
1416
from importlib.metadata import version
1517
__version__ = version("espei")
1618
del version

0 commit comments

Comments
 (0)