From d95a5735c0ae784361529d7d50d558eee5dca7c3 Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Mon, 30 Sep 2024 12:45:46 +0100 Subject: [PATCH] feat: Adds `vl_convert_to_vega_version`, remove `vegalite_to_vega_version` - Found this to be a much more reliable source - Won't require manual syncing - Can easily be replaced in the future with a public function/attribute accessible in `vl_convert` itself https://github.com/vega/altair/pull/3600#discussion_r1779748538 --- tools/generate_schema_wrapper.py | 79 +++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 11 deletions(-) diff --git a/tools/generate_schema_wrapper.py b/tools/generate_schema_wrapper.py index e490d5a19..4ee1aac89 100644 --- a/tools/generate_schema_wrapper.py +++ b/tools/generate_schema_wrapper.py @@ -5,6 +5,7 @@ import argparse import copy import json +import re import sys import textwrap from collections import deque @@ -12,9 +13,11 @@ from itertools import chain from operator import attrgetter from pathlib import Path -from typing import TYPE_CHECKING, Any, Final, Iterable, Iterator, Literal +from typing import TYPE_CHECKING, Any, Final, Iterable, Iterator, Literal, cast from urllib import request +from packaging.version import Version + import vl_convert as vlc sys.path.insert(0, str(Path.cwd())) @@ -45,10 +48,73 @@ ) if TYPE_CHECKING: + from http.client import HTTPResponse + from tools.schemapi.codegen import ArgInfo, AttrGetter + +def vl_convert_to_vega_version( + *, + version: str | None = None, + url_fmt: str = "https://raw.githubusercontent.com/vega/vl-convert/refs/tags/vl-convert-vendor%40{0}/vl-convert-vendor/src/main.rs", + prefix: bytes = b"const VEGA_PATH", + pattern: str = r".+\/pin\/vega@(?Pv\d\.\d{1,3}\.\d{1,3})", +) -> str: + """ + Return the minimum supported ``vega`` release for a ``vl_convert`` version. + + Parameters + ---------- + version + A target `vl_convert` release. + Defaults to currently installed version. + url_fmt + Format string for source file. + prefix + Byte string prefix of target line. + pattern + Matches and extracts vega version, e.g. `"v5.30.0"`. + + Examples + -------- + >>> vl_convert_to_vega_version(version="0.2.0") + 'v5.22.1' + >>> vl_convert_to_vega_version(version="1.0.0") + 'v5.25.0' + >>> vl_convert_to_vega_version(version="1.3.0") + 'v5.28.0' + >>> vl_convert_to_vega_version(version="1.6.1") + 'v5.30.0' + """ + MIN_VL_CONVERT = "0.2.0" + vlc_version: str = version or vlc.__version__ # pyright: ignore[reportAttributeAccessIssue] + if Version(vlc_version) < Version(MIN_VL_CONVERT): + msg = ( + f"Operation requires `vl_convert>={MIN_VL_CONVERT!r}`\n" + f"but got: {version!r}" + ) + raise NotImplementedError(msg) + with request.urlopen(url_fmt.format(vlc_version)) as response: + response = cast("HTTPResponse", response) + line = response.readline() + while not line.startswith(prefix): + line = response.readline() + if line.startswith(b"fn main"): + msg = f"Failed to find {prefix!r} in {url_fmt.format(vlc_version)}." + raise ValueError(msg) + src_line = line.decode() + if match := re.match(pattern, src_line): + return match.group("vega_version") + else: + msg = ( + f"Failed to match a vega version specifier.\n" + f"{src_line=}\n{pattern=}\n{match=}\n" + ) + raise NotImplementedError(msg) + + SCHEMA_VERSION: Final = "v5.20.1" -VEGA_VERSION: Final = "v5.30.0" +VEGA_VERSION: Final[str] = vl_convert_to_vega_version() HEADER_COMMENT = """\ @@ -474,15 +540,6 @@ def schema_url(version: str = SCHEMA_VERSION) -> str: return SCHEMA_URL_TEMPLATE.format(library="vega-lite", version=version) -def vegalite_to_vega_version(vl_version: str, /) -> str: - """Return the minimum supported ``vega`` release for a ``vega-lite`` version.""" - with request.urlopen(VL_PACKAGE_TEMPLATE.format(version=vl_version)) as response: - package_json = json.load(response) - - version_spec = package_json["peerDependencies"]["vega"] - return f"v{version_spec.lstrip('^~')}" - - def download_schemafile( version: str, schemapath: Path, skip_download: bool = False ) -> Path: