@azure-tools/typespec-python 0.45.4 → 0.45.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/scripts/__pycache__/package_manager.cpython-310.pyc +0 -0
- package/scripts/__pycache__/venvtools.cpython-310.pyc +0 -0
- package/scripts/install.py +14 -16
- package/scripts/package_manager.py +141 -0
- package/scripts/prepare.py +4 -8
- package/scripts/run_tsp.py +3 -4
- package/scripts/venvtools.py +1 -38
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@azure-tools/typespec-python",
|
|
3
|
-
"version": "0.45.
|
|
3
|
+
"version": "0.45.5",
|
|
4
4
|
"author": "Microsoft Corporation",
|
|
5
5
|
"description": "TypeSpec emitter for Python SDKs",
|
|
6
6
|
"homepage": "https://github.com/Azure/autorest.python",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"js-yaml": "~4.1.0",
|
|
55
55
|
"semver": "~7.6.2",
|
|
56
56
|
"tsx": "~4.19.1",
|
|
57
|
-
"@typespec/http-client-python": "~0.12.
|
|
57
|
+
"@typespec/http-client-python": "~0.12.5",
|
|
58
58
|
"fs-extra": "~11.2.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
Binary file
|
|
Binary file
|
package/scripts/install.py
CHANGED
|
@@ -11,9 +11,11 @@ if not sys.version_info >= (3, 9, 0):
|
|
|
11
11
|
raise Exception("Autorest for Python extension requires Python 3.9 at least")
|
|
12
12
|
|
|
13
13
|
try:
|
|
14
|
-
import
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
from package_manager import detect_package_manager, PackageManagerNotFoundError
|
|
15
|
+
|
|
16
|
+
detect_package_manager() # Just check if we have a package manager
|
|
17
|
+
except (ImportError, ModuleNotFoundError, PackageManagerNotFoundError):
|
|
18
|
+
raise Exception("Your Python installation doesn't have a suitable package manager (pip or uv) available")
|
|
17
19
|
|
|
18
20
|
try:
|
|
19
21
|
import venv
|
|
@@ -21,27 +23,23 @@ except ImportError:
|
|
|
21
23
|
raise Exception("Your Python installation doesn't have venv available")
|
|
22
24
|
|
|
23
25
|
|
|
24
|
-
# Now we have pip and Py >= 3.9, go to work
|
|
26
|
+
# Now we have a package manager (uv or pip) and Py >= 3.9, go to work
|
|
25
27
|
|
|
26
28
|
from pathlib import Path
|
|
27
29
|
|
|
28
|
-
from venvtools import ExtendedEnvBuilder, python_run
|
|
29
|
-
|
|
30
30
|
_ROOT_DIR = Path(__file__).parent.parent
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
def main():
|
|
34
34
|
venv_path = _ROOT_DIR / "venv"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
python_run(venv_context, "pip", ["install", "-U", "pip"])
|
|
44
|
-
python_run(venv_context, "pip", ["install", "-U", "black"])
|
|
35
|
+
|
|
36
|
+
# Create virtual environment using package manager abstraction
|
|
37
|
+
from package_manager import create_venv_with_package_manager, install_packages
|
|
38
|
+
|
|
39
|
+
venv_context = create_venv_with_package_manager(venv_path)
|
|
40
|
+
|
|
41
|
+
# Install required packages - install_packages handles package manager logic
|
|
42
|
+
install_packages(["-U", "black"], venv_context)
|
|
45
43
|
|
|
46
44
|
|
|
47
45
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
# -------------------------------------------------------------------------
|
|
4
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
5
|
+
# Licensed under the MIT License. See License.txt in the project root for
|
|
6
|
+
# license information.
|
|
7
|
+
# --------------------------------------------------------------------------
|
|
8
|
+
"""Package manager utilities for detecting and using pip or uv."""
|
|
9
|
+
|
|
10
|
+
import subprocess
|
|
11
|
+
import sys
|
|
12
|
+
import venv
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from venvtools import ExtendedEnvBuilder
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class PackageManagerNotFoundError(Exception):
|
|
18
|
+
"""Raised when no suitable package manager is found."""
|
|
19
|
+
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _check_command_available(command: str) -> bool:
|
|
24
|
+
"""Check if a command is available in the environment."""
|
|
25
|
+
try:
|
|
26
|
+
subprocess.run([command, "--version"], capture_output=True, check=True)
|
|
27
|
+
return True
|
|
28
|
+
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
29
|
+
return False
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def detect_package_manager() -> str:
|
|
33
|
+
"""Detect the best available package manager.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
str: The package manager command ('uv' or 'pip')
|
|
37
|
+
|
|
38
|
+
Raises:
|
|
39
|
+
PackageManagerNotFoundError: If no suitable package manager is found
|
|
40
|
+
"""
|
|
41
|
+
# Check for uv first since it's more modern and faster
|
|
42
|
+
if _check_command_available("uv"):
|
|
43
|
+
return "uv"
|
|
44
|
+
|
|
45
|
+
# Fall back to pip
|
|
46
|
+
if _check_command_available("pip"):
|
|
47
|
+
return "pip"
|
|
48
|
+
|
|
49
|
+
# As a last resort, try using python -m pip
|
|
50
|
+
try:
|
|
51
|
+
subprocess.run([sys.executable, "-m", "pip", "--version"], capture_output=True, check=True)
|
|
52
|
+
return "python -m pip"
|
|
53
|
+
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
raise PackageManagerNotFoundError("No suitable package manager found. Please install either uv or pip.")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def get_install_command(package_manager: str, venv_context=None) -> list:
|
|
60
|
+
"""Get the install command for the given package manager.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
package_manager: The package manager command ('uv', 'pip', or 'python -m pip')
|
|
64
|
+
venv_context: The virtual environment context (optional, used for pip)
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
list: The base install command as a list
|
|
68
|
+
"""
|
|
69
|
+
if package_manager == "uv":
|
|
70
|
+
cmd = ["uv", "pip", "install"]
|
|
71
|
+
if venv_context:
|
|
72
|
+
cmd.extend(["--python", venv_context.env_exe])
|
|
73
|
+
return cmd
|
|
74
|
+
elif package_manager == "pip":
|
|
75
|
+
if venv_context:
|
|
76
|
+
return [venv_context.env_exe, "-m", "pip", "install"]
|
|
77
|
+
else:
|
|
78
|
+
return ["pip", "install"]
|
|
79
|
+
elif package_manager == "python -m pip":
|
|
80
|
+
if venv_context:
|
|
81
|
+
return [venv_context.env_exe, "-m", "pip", "install"]
|
|
82
|
+
else:
|
|
83
|
+
return [sys.executable, "-m", "pip", "install"]
|
|
84
|
+
else:
|
|
85
|
+
raise ValueError(f"Unknown package manager: {package_manager}")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def install_packages(packages: list, venv_context=None, package_manager: str = None) -> None:
|
|
89
|
+
"""Install packages using the available package manager.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
packages: List of packages to install
|
|
93
|
+
venv_context: Virtual environment context (optional)
|
|
94
|
+
package_manager: Package manager to use (auto-detected if None)
|
|
95
|
+
"""
|
|
96
|
+
if package_manager is None:
|
|
97
|
+
package_manager = detect_package_manager()
|
|
98
|
+
|
|
99
|
+
install_cmd = get_install_command(package_manager, venv_context)
|
|
100
|
+
|
|
101
|
+
try:
|
|
102
|
+
subprocess.check_call(install_cmd + packages)
|
|
103
|
+
except subprocess.CalledProcessError as e:
|
|
104
|
+
raise RuntimeError(f"Failed to install packages with {package_manager}: {e}")
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def create_venv_with_package_manager(venv_path):
|
|
108
|
+
"""Create virtual environment using the best available package manager.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
venv_path: Path where to create the virtual environment
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
venv_context: Virtual environment context object
|
|
115
|
+
"""
|
|
116
|
+
package_manager = detect_package_manager()
|
|
117
|
+
|
|
118
|
+
if package_manager == "uv":
|
|
119
|
+
# Use uv to create and manage the virtual environment
|
|
120
|
+
if not venv_path.exists():
|
|
121
|
+
subprocess.check_call(["uv", "venv", str(venv_path)])
|
|
122
|
+
|
|
123
|
+
# Create a mock venv_context for compatibility
|
|
124
|
+
class MockVenvContext:
|
|
125
|
+
def __init__(self, venv_path):
|
|
126
|
+
self.env_exe = (
|
|
127
|
+
str(venv_path / "bin" / "python")
|
|
128
|
+
if sys.platform != "win32"
|
|
129
|
+
else str(venv_path / "Scripts" / "python.exe")
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
return MockVenvContext(venv_path)
|
|
133
|
+
else:
|
|
134
|
+
# Use standard venv for pip
|
|
135
|
+
if venv_path.exists():
|
|
136
|
+
env_builder = venv.EnvBuilder(with_pip=True)
|
|
137
|
+
return env_builder.ensure_directories(venv_path)
|
|
138
|
+
else:
|
|
139
|
+
env_builder = ExtendedEnvBuilder(with_pip=True, upgrade_deps=True)
|
|
140
|
+
env_builder.create(venv_path)
|
|
141
|
+
return env_builder.context
|
package/scripts/prepare.py
CHANGED
|
@@ -6,16 +6,12 @@
|
|
|
6
6
|
# license information.
|
|
7
7
|
# --------------------------------------------------------------------------
|
|
8
8
|
import sys
|
|
9
|
-
import os
|
|
10
|
-
import argparse
|
|
11
9
|
|
|
12
10
|
if not sys.version_info >= (3, 9, 0):
|
|
13
11
|
raise Exception("Autorest for Python extension requires Python 3.9 at least")
|
|
14
12
|
|
|
15
13
|
from pathlib import Path
|
|
16
|
-
import
|
|
17
|
-
|
|
18
|
-
from venvtools import python_run
|
|
14
|
+
from package_manager import create_venv_with_package_manager, install_packages
|
|
19
15
|
|
|
20
16
|
_ROOT_DIR = Path(__file__).parent.parent
|
|
21
17
|
|
|
@@ -26,10 +22,10 @@ def main():
|
|
|
26
22
|
|
|
27
23
|
assert venv_preexists # Otherwise install was not done
|
|
28
24
|
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
venv_context = create_venv_with_package_manager(venv_path)
|
|
26
|
+
|
|
31
27
|
try:
|
|
32
|
-
|
|
28
|
+
install_packages(["-r", f"{_ROOT_DIR}/dev_requirements.txt"], venv_context)
|
|
33
29
|
except FileNotFoundError as e:
|
|
34
30
|
raise ValueError(e.filename)
|
|
35
31
|
|
package/scripts/run_tsp.py
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
6
|
import sys
|
|
7
|
-
import venv
|
|
8
7
|
import logging
|
|
9
8
|
from pathlib import Path
|
|
10
9
|
from pygen import preprocess, codegen
|
|
11
10
|
from pygen.utils import parse_args
|
|
11
|
+
from package_manager import create_venv_with_package_manager
|
|
12
12
|
|
|
13
13
|
_ROOT_DIR = Path(__file__).parent.parent
|
|
14
14
|
|
|
@@ -20,14 +20,13 @@ if __name__ == "__main__":
|
|
|
20
20
|
|
|
21
21
|
assert venv_preexists # Otherwise install was not done
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
venv_context = env_builder.ensure_directories(venv_path)
|
|
23
|
+
venv_context = create_venv_with_package_manager(venv_path)
|
|
25
24
|
|
|
26
25
|
if "--debug" in sys.argv or "--debug=true" in sys.argv:
|
|
27
26
|
try:
|
|
28
27
|
import debugpy # pylint: disable=import-outside-toplevel
|
|
29
28
|
except ImportError:
|
|
30
|
-
raise SystemExit("Please
|
|
29
|
+
raise SystemExit("Please install ptvsd in order to use VSCode debugging")
|
|
31
30
|
|
|
32
31
|
# 5678 is the default attach port in the VS Code debug configurations
|
|
33
32
|
debugpy.listen(("localhost", 5678))
|
package/scripts/venvtools.py
CHANGED
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
# Licensed under the MIT License. See License.txt in the project root for
|
|
4
4
|
# license information.
|
|
5
5
|
# --------------------------------------------------------------------------
|
|
6
|
-
from contextlib import contextmanager
|
|
7
|
-
import tempfile
|
|
8
6
|
import subprocess
|
|
9
7
|
import venv
|
|
10
8
|
import sys
|
|
@@ -28,45 +26,10 @@ class ExtendedEnvBuilder(venv.EnvBuilder):
|
|
|
28
26
|
return self.context
|
|
29
27
|
|
|
30
28
|
|
|
31
|
-
def create(
|
|
32
|
-
env_dir, system_site_packages=False, clear=False, symlinks=False, with_pip=False, prompt=None, upgrade_deps=False
|
|
33
|
-
):
|
|
34
|
-
"""Create a virtual environment in a directory."""
|
|
35
|
-
builder = ExtendedEnvBuilder(
|
|
36
|
-
system_site_packages=system_site_packages,
|
|
37
|
-
clear=clear,
|
|
38
|
-
symlinks=symlinks,
|
|
39
|
-
with_pip=with_pip,
|
|
40
|
-
prompt=prompt,
|
|
41
|
-
upgrade_deps=upgrade_deps,
|
|
42
|
-
)
|
|
43
|
-
builder.create(env_dir)
|
|
44
|
-
return builder.context
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
@contextmanager
|
|
48
|
-
def create_venv_with_package(packages):
|
|
49
|
-
"""Create a venv with these packages in a temp dir and yield the env.
|
|
50
|
-
|
|
51
|
-
packages should be an iterable of pip version instructions (e.g. package~=1.2.3)
|
|
52
|
-
"""
|
|
53
|
-
with tempfile.TemporaryDirectory() as tempdir:
|
|
54
|
-
myenv = create(tempdir, with_pip=True, upgrade_deps=True)
|
|
55
|
-
pip_call = [
|
|
56
|
-
myenv.env_exe,
|
|
57
|
-
"-m",
|
|
58
|
-
"pip",
|
|
59
|
-
"install",
|
|
60
|
-
]
|
|
61
|
-
subprocess.check_call(pip_call + ["-U", "pip"])
|
|
62
|
-
if packages:
|
|
63
|
-
subprocess.check_call(pip_call + packages)
|
|
64
|
-
yield myenv
|
|
65
|
-
|
|
66
|
-
|
|
67
29
|
def python_run(venv_context, module, command=None, *, additional_dir="."):
|
|
68
30
|
try:
|
|
69
31
|
cmd_line = [venv_context.env_exe, "-m", module] + (command if command else [])
|
|
32
|
+
|
|
70
33
|
print("Executing: {}".format(" ".join(cmd_line)))
|
|
71
34
|
subprocess.run(
|
|
72
35
|
cmd_line,
|