@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azure-tools/typespec-python",
3
- "version": "0.45.4",
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.4",
57
+ "@typespec/http-client-python": "~0.12.5",
58
58
  "fs-extra": "~11.2.0"
59
59
  },
60
60
  "devDependencies": {
@@ -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 pip
15
- except ImportError:
16
- raise Exception("Your Python installation doesn't have pip available")
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
- if venv_path.exists():
36
- env_builder = venv.EnvBuilder(with_pip=True)
37
- venv_context = env_builder.ensure_directories(venv_path)
38
- else:
39
- env_builder = ExtendedEnvBuilder(with_pip=True, upgrade_deps=True)
40
- env_builder.create(venv_path)
41
- venv_context = env_builder.context
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
@@ -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 venv
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
- env_builder = venv.EnvBuilder(with_pip=True)
30
- venv_context = env_builder.ensure_directories(venv_path)
25
+ venv_context = create_venv_with_package_manager(venv_path)
26
+
31
27
  try:
32
- python_run(venv_context, "pip", ["install", "-r", f"{_ROOT_DIR}/dev_requirements.txt"])
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
 
@@ -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
- env_builder = venv.EnvBuilder(with_pip=True)
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 pip install ptvsd in order to use VSCode debugging")
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))
@@ -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,