795cd2dacf
This fixes CI script tests that accidentally run helper scripts with the
wrong Python interpreter.
Some tests call `run_script(..., env={...})` to pass test-specific
environment variables. `subprocess.run` treats `env` as a full
environment replacement, so the subprocess lost the current `PATH`.
Since these scripts use a shebang like:
```python
#!/usr/bin/env python3
```
they could fall back to the system Python instead of the active test
Python.
In the wheel test environment this caused the CI helper scripts to run
under Python 3.8, even though TVM requires Python >=3.10. Importing
`ci/scripts/jenkins/git_utils.py` then failed on PEP 604 annotations
such as:
```python
Any | None
tuple[str, str] | None
```
with:
```text
TypeError: unsupported operand type(s) for |: '_SpecialForm' and 'NoneType'
```
This patch updates `tests/python/ci/test_utils.py::run_script` to merge
test-provided environment variables into `os.environ` instead of
replacing the entire environment. This preserves the active Python/PATH
while still allowing each test to override or add variables.
81 lines
2.6 KiB
Python
81 lines
2.6 KiB
Python
# Licensed to the Apache Software Foundation (ASF) under one
|
|
# or more contributor license agreements. See the NOTICE file
|
|
# distributed with this work for additional information
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
# to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance
|
|
# with the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
# ruff: noqa: RUF005
|
|
"""
|
|
Constants used in various CI tests
|
|
"""
|
|
|
|
import os
|
|
import pathlib
|
|
import subprocess
|
|
from typing import Any
|
|
|
|
REPO_ROOT = pathlib.Path(__file__).resolve().parent.parent.parent.parent
|
|
GITHUB_SCRIPT_ROOT = REPO_ROOT / "ci" / "scripts" / "github"
|
|
JENKINS_SCRIPT_ROOT = REPO_ROOT / "ci" / "scripts" / "jenkins"
|
|
|
|
|
|
class TempGit:
|
|
"""
|
|
A wrapper to run commands in a directory (specifically for use in CI tests)
|
|
"""
|
|
|
|
def __init__(self, cwd):
|
|
self.cwd = cwd
|
|
# Jenkins git is too old and doesn't have 'git init --initial-branch',
|
|
# so init and checkout need to be separate steps
|
|
self.run("init", stderr=subprocess.PIPE, stdout=subprocess.PIPE)
|
|
self.run("checkout", "-b", "main", stderr=subprocess.PIPE)
|
|
self.run("remote", "add", "origin", "https://github.com/apache/tvm.git")
|
|
|
|
def run(self, *args, **kwargs):
|
|
"""
|
|
Run a git command based on *args
|
|
"""
|
|
proc = subprocess.run(
|
|
["git"] + list(args), encoding="utf-8", cwd=self.cwd, check=False, **kwargs
|
|
)
|
|
if proc.returncode != 0:
|
|
raise RuntimeError(f"git command failed: '{args}'")
|
|
|
|
return proc
|
|
|
|
|
|
def run_script(command: list[Any], check: bool = True, **kwargs):
|
|
"""
|
|
Wrapper to run a script and print its output if there was an error
|
|
"""
|
|
command = [str(c) for c in command]
|
|
kwargs_to_send = {
|
|
"stdout": subprocess.PIPE,
|
|
"stderr": subprocess.PIPE,
|
|
"encoding": "utf-8",
|
|
}
|
|
env = kwargs.pop("env", None)
|
|
if env is not None:
|
|
kwargs_to_send["env"] = {**os.environ, **env}
|
|
kwargs_to_send.update(kwargs)
|
|
proc = subprocess.run(
|
|
command,
|
|
check=False,
|
|
**kwargs_to_send,
|
|
)
|
|
if check and proc.returncode != 0:
|
|
raise RuntimeError(f"Process failed:\nstdout:\n{proc.stdout}\n\nstderr:\n{proc.stderr}")
|
|
|
|
return proc
|