Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: bundle pyright inside wheel #300

Merged
merged 2 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ jobs:
- name: Set up Python 3.9
uses: actions/setup-python@v2
with:
python-version: 3.9
python-version: '3.11'

- name: Install dependencies
run: |
python -m pip install -r dev-requirements.txt
- name: Download pyright dist
run: |
python scripts/download_pyright.py
- name: Get version
run: |
echo "NEW_VERSION=$(python .github/scripts/get_version.py --compare)" >> $GITHUB_ENV
Expand Down
23 changes: 23 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ jobs:
python -m pip install --upgrade pip
pip install -r dev-requirements.txt

- name: Download pyright dist
run: |
python scripts/download_pyright.py

- uses: actions/cache@v2
with:
path: ~/.cache/pip
Expand Down Expand Up @@ -124,6 +128,15 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .

- name: Download pyright dist
run: |
python scripts/download_pyright.py

- name: Docker Build
uses: docker/build-push-action@v3
# https://github.com/docker/build-push-action/#inputs
Expand All @@ -141,6 +154,16 @@ jobs:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .

- name: Download pyright dist
run: |
python scripts/download_pyright.py

- name: Docker Build
# Use --% to allow double hyphen
# Caching not currently working since we don't use buildx yet, windows
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ include = [
"tests",
]
exclude = [
"src/pyright/_mureq.py"
"src/pyright/_mureq.py",
"src/pyright/dist",
]
pythonVersion = "3.9"

Expand Down
68 changes: 68 additions & 0 deletions scripts/download_pyright.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import io
import sys
import json
import shutil
import tarfile
from pathlib import Path

import pyright
from pyright import _mureq, __pyright_version__

DIST_DIR = Path(pyright.__file__).parent / 'dist'


def _should_download() -> bool:
if '--force' in sys.argv:
return True

pkg_path = DIST_DIR / 'package.json'
if not pkg_path.exists():
return True

pkg_json = json.loads(pkg_path.read_text())
if pkg_json['version'] == __pyright_version__:
print(
f'skipping download as the current pyright version ({__pyright_version__}) is already downloaded. use --force to override'
)
return False

return True


def download_tarball(*, version: str) -> None:
if not _should_download():
return

if DIST_DIR.exists():
shutil.rmtree(DIST_DIR)

rsp = _mureq.get(f'https://registry.npmjs.org/pyright/{version}')
rsp.raise_for_status()

info = rsp.json()
tar_url = info['dist']['tarball']
print(f'downloading tar from {tar_url}')

rsp = _mureq.get(tar_url)
rsp.raise_for_status()

with tarfile.open(fileobj=io.BytesIO(rsp.body)) as tar:
members = tar.getmembers()

# npm tarballs will always output one `package/` directory which is
# not necessary for our case, so we strip out the `package/` prefix
for member in members:
if member.path.startswith('package/'):
member.path = member.path.replace('package/', '', 1)
else:
raise RuntimeError(f'expected tar member path to start with `package/` but got {member.path}')

tar.extractall(path=DIST_DIR, members=members)


def main() -> None:
download_tarball(version=__pyright_version__)


if __name__ == '__main__':
main()
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
include=['pyright', 'pyright.*'],
),
package_dir={'': 'src'},
package_data={'': ['py.typed']},
package_data={'': ['py.typed', 'dist/**']},
python_requires='>=3.7',
include_package_data=True,
zip_safe=False,
Expand Down
6 changes: 6 additions & 0 deletions src/pyright/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ def install_pyright(args: tuple[object, ...], *, quiet: bool | None) -> Path:
+ 'Please install the new version or set PYRIGHT_PYTHON_FORCE_VERSION to `latest`\n'
)

if version == __pyright_version__ and env_to_bool('PYRIGHT_PYTHON_USE_BUNDLED_PYRIGHT', default=True):
bundled_path = Path(__file__).parent.joinpath('dist')
if bundled_path.exists():
log.debug('using bundled pyright at %s', bundled_path)
return bundled_path

cache_dir = ROOT_CACHE_DIR / version
cache_dir.mkdir(exist_ok=True, parents=True)

Expand Down
8 changes: 7 additions & 1 deletion tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@

import pyright
from pyright import __pyright_version__
from tests.utils import assert_matches
from tests.utils import assert_matches, is_relative_to
from pyright.utils import maybe_decode
from pyright._utils import install_pyright

if TYPE_CHECKING:
from _pytest.monkeypatch import MonkeyPatch
Expand Down Expand Up @@ -238,3 +239,8 @@ def test_package_json_in_parent_dir(tmp_path: Path, monkeypatch: MonkeyPatch) ->
check=True,
)
assert proc.returncode == 0


def test_install_pyright_uses_bundled_by_default() -> None:
install_path = install_pyright(tuple(), quiet=None)
assert is_relative_to(install_path, Path(pyright.__file__).parent)
14 changes: 14 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from __future__ import annotations

import re
from os import PathLike
from pathlib import Path
from typing_extensions import TypeAlias

StrPath: TypeAlias = 'str | PathLike[str]'


def assert_matches(pattern: re.Pattern[str], contents: str) -> re.Match[str]:
Expand All @@ -9,3 +14,12 @@ def assert_matches(pattern: re.Pattern[str], contents: str) -> re.Match[str]:
raise ValueError(f'Pattern, {pattern}, did not match input: {contents}')

return match


def is_relative_to(path: StrPath, to: StrPath) -> bool:
"""Backport of Path.is_relative_to for Python < 3.9"""
try:
Path(path).relative_to(to)
return True
except ValueError:
return False
Loading