@vercel/python 6.12.0-canary.20260211174907.cdd2da6 → 6.12.0

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.
Files changed (2) hide show
  1. package/dist/index.js +184 -6
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -2753,7 +2753,7 @@ var import_util = require("util");
2753
2753
  var import_path7 = require("path");
2754
2754
 
2755
2755
  // src/runtime-version.ts
2756
- var VERCEL_RUNTIME_VERSION = "0.3.0";
2756
+ var VERCEL_RUNTIME_VERSION = "0.4.0";
2757
2757
 
2758
2758
  // src/index.ts
2759
2759
  var import_build_utils8 = require("@vercel/build-utils");
@@ -3070,7 +3070,8 @@ function createVenvEnv(venvPath, baseEnv = process.env) {
3070
3070
  async function ensureVenv({
3071
3071
  pythonPath,
3072
3072
  venvPath,
3073
- uvPath
3073
+ uvPath,
3074
+ quiet
3074
3075
  }) {
3075
3076
  const marker = (0, import_path3.join)(venvPath, "pyvenv.cfg");
3076
3077
  try {
@@ -3079,7 +3080,9 @@ async function ensureVenv({
3079
3080
  } catch {
3080
3081
  }
3081
3082
  await import_fs2.default.promises.mkdir(venvPath, { recursive: true });
3082
- console.log(`Creating virtual environment at "${venvPath}"...`);
3083
+ if (!quiet) {
3084
+ console.log(`Creating virtual environment at "${venvPath}"...`);
3085
+ }
3083
3086
  if (uvPath) {
3084
3087
  await (0, import_execa2.default)(uvPath, ["venv", venvPath]);
3085
3088
  } else {
@@ -3490,6 +3493,12 @@ async function detectInstallSource({
3490
3493
  });
3491
3494
  } catch (error) {
3492
3495
  if (error instanceof import_python_analysis.PythonAnalysisError) {
3496
+ if (error.fileContent && (error.code.endsWith("_PARSE_ERROR") || error.code.endsWith("_VALIDATION_ERROR"))) {
3497
+ console.log(
3498
+ `Failed to parse "${error.path}". File content:
3499
+ ${error.fileContent}`
3500
+ );
3501
+ }
3493
3502
  throw toBuildError(error);
3494
3503
  }
3495
3504
  throw error;
@@ -3805,6 +3814,7 @@ async function detectPythonEntrypoint(_framework, workPath, configuredEntrypoint
3805
3814
  }
3806
3815
 
3807
3816
  // src/start-dev-server.ts
3817
+ var import_python_analysis2 = require("@vercel/python-analysis");
3808
3818
  function silenceNodeWarnings() {
3809
3819
  const original = process.emitWarning.bind(
3810
3820
  process
@@ -3848,6 +3858,146 @@ function createLogListener(callback, stream) {
3848
3858
  }
3849
3859
  };
3850
3860
  }
3861
+ async function syncDependencies({
3862
+ workPath,
3863
+ uvPath,
3864
+ pythonBin,
3865
+ env,
3866
+ onStdout,
3867
+ onStderr
3868
+ }) {
3869
+ const installInfo = await detectInstallSource({
3870
+ workPath,
3871
+ entryDirectory: "."
3872
+ });
3873
+ let { manifestType, manifestPath } = installInfo;
3874
+ const manifest = installInfo.pythonPackage?.manifest;
3875
+ if (!manifestType || !manifestPath) {
3876
+ (0, import_build_utils7.debug)("No Python project manifest found, skipping dependency sync");
3877
+ return;
3878
+ }
3879
+ if (manifest?.origin && manifestType === "pyproject.toml") {
3880
+ const syncDir = (0, import_path6.join)(workPath, ".vercel", "python", "sync");
3881
+ (0, import_fs4.mkdirSync)(syncDir, { recursive: true });
3882
+ const tempPyproject = (0, import_path6.join)(syncDir, "pyproject.toml");
3883
+ const content = (0, import_python_analysis2.stringifyManifest)(manifest.data);
3884
+ (0, import_fs4.writeFileSync)(tempPyproject, content, "utf8");
3885
+ manifestPath = tempPyproject;
3886
+ (0, import_build_utils7.debug)(
3887
+ `Wrote converted ${manifest.origin.kind} manifest to ${tempPyproject}`
3888
+ );
3889
+ }
3890
+ const writeOut = (msg) => {
3891
+ if (onStdout) {
3892
+ onStdout(Buffer.from(msg));
3893
+ } else {
3894
+ process.stdout.write(msg);
3895
+ }
3896
+ };
3897
+ const writeErr = (msg) => {
3898
+ if (onStderr) {
3899
+ onStderr(Buffer.from(msg));
3900
+ } else {
3901
+ process.stderr.write(msg);
3902
+ }
3903
+ };
3904
+ const captured = [];
3905
+ try {
3906
+ await runSync({
3907
+ manifestType,
3908
+ manifestPath,
3909
+ uvPath,
3910
+ pythonBin,
3911
+ env,
3912
+ onStdout: (data) => captured.push(["stdout", data]),
3913
+ onStderr: (data) => captured.push(["stderr", data])
3914
+ });
3915
+ } catch (err) {
3916
+ for (const [channel, chunk] of captured) {
3917
+ (channel === "stdout" ? writeOut : writeErr)(chunk.toString());
3918
+ }
3919
+ throw new import_build_utils7.NowBuildError({
3920
+ code: "PYTHON_DEPENDENCY_SYNC_FAILED",
3921
+ message: `Failed to install Python dependencies from ${manifestType}: ${err instanceof Error ? err.message : String(err)}`
3922
+ });
3923
+ }
3924
+ }
3925
+ async function runSync({
3926
+ manifestType,
3927
+ manifestPath,
3928
+ uvPath,
3929
+ pythonBin,
3930
+ env,
3931
+ onStdout,
3932
+ onStderr
3933
+ }) {
3934
+ const projectDir = (0, import_path6.dirname)(manifestPath);
3935
+ const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
3936
+ let spawnCmd;
3937
+ let spawnArgs;
3938
+ switch (manifestType) {
3939
+ case "uv.lock": {
3940
+ if (!uvPath) {
3941
+ throw new import_build_utils7.NowBuildError({
3942
+ code: "PYTHON_DEPENDENCY_SYNC_FAILED",
3943
+ message: "uv is required to install dependencies from uv.lock.",
3944
+ link: "https://docs.astral.sh/uv/getting-started/installation/",
3945
+ action: "Install uv"
3946
+ });
3947
+ }
3948
+ spawnCmd = uvPath;
3949
+ spawnArgs = ["sync"];
3950
+ break;
3951
+ }
3952
+ case "pylock.toml": {
3953
+ spawnCmd = pip.cmd;
3954
+ spawnArgs = [...pip.prefix, "-r", manifestPath];
3955
+ break;
3956
+ }
3957
+ case "pyproject.toml": {
3958
+ spawnCmd = pip.cmd;
3959
+ spawnArgs = [...pip.prefix, projectDir];
3960
+ break;
3961
+ }
3962
+ default:
3963
+ (0, import_build_utils7.debug)(`Unknown manifest type: ${manifestType}`);
3964
+ return;
3965
+ }
3966
+ await new Promise((resolve, reject) => {
3967
+ (0, import_build_utils7.debug)(`Running "${spawnCmd} ${spawnArgs.join(" ")}" in ${projectDir}...`);
3968
+ const child = (0, import_child_process2.spawn)(spawnCmd, spawnArgs, {
3969
+ cwd: projectDir,
3970
+ env: getProtectedUvEnv(env),
3971
+ stdio: ["inherit", "pipe", "pipe"]
3972
+ });
3973
+ child.stdout?.on("data", (data) => {
3974
+ if (onStdout) {
3975
+ onStdout(data);
3976
+ } else {
3977
+ process.stdout.write(data.toString());
3978
+ }
3979
+ });
3980
+ child.stderr?.on("data", (data) => {
3981
+ if (onStderr) {
3982
+ onStderr(data);
3983
+ } else {
3984
+ process.stderr.write(data.toString());
3985
+ }
3986
+ });
3987
+ child.on("error", reject);
3988
+ child.on("exit", (code, signal) => {
3989
+ if (code === 0) {
3990
+ resolve();
3991
+ } else {
3992
+ reject(
3993
+ new Error(
3994
+ `Command "${spawnCmd} ${spawnArgs.join(" ")}" failed with code ${code}, signal ${signal}`
3995
+ )
3996
+ );
3997
+ }
3998
+ });
3999
+ });
4000
+ }
3851
4001
  var PERSISTENT_SERVERS = /* @__PURE__ */ new Map();
3852
4002
  var PENDING_STARTS = /* @__PURE__ */ new Map();
3853
4003
  var restoreWarnings = null;
@@ -3928,7 +4078,7 @@ async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath)
3928
4078
  return { command: pythonCmd, args: [] };
3929
4079
  }
3930
4080
  const venvPath = (0, import_path6.join)(workPath, ".venv");
3931
- await ensureVenv({ pythonPath: systemPython, venvPath, uvPath });
4081
+ await ensureVenv({ pythonPath: systemPython, venvPath, uvPath, quiet: true });
3932
4082
  (0, import_build_utils7.debug)(`Created virtualenv at ${venvPath} for multi-service dev`);
3933
4083
  const pythonBin = getVenvPythonBin(venvPath);
3934
4084
  const binDir = getVenvBinDir(venvPath);
@@ -4058,6 +4208,25 @@ If you are using a virtual environment, activate it before running "vercel dev",
4058
4208
  }
4059
4209
  }
4060
4210
  }
4211
+ if (meta.syncDependencies) {
4212
+ const gray = "\x1B[90m";
4213
+ const reset = "\x1B[0m";
4214
+ const syncMessage = `${gray}Synchronizing dependencies...${reset}
4215
+ `;
4216
+ if (onStdout) {
4217
+ onStdout(Buffer.from(syncMessage));
4218
+ } else {
4219
+ console.log(syncMessage);
4220
+ }
4221
+ await syncDependencies({
4222
+ workPath,
4223
+ uvPath,
4224
+ pythonBin: spawnCommand,
4225
+ env,
4226
+ onStdout,
4227
+ onStderr
4228
+ });
4229
+ }
4061
4230
  await new Promise((resolve, reject) => {
4062
4231
  let resolved = false;
4063
4232
  if (framework !== "flask") {
@@ -4372,9 +4541,18 @@ var build = async ({
4372
4541
  }
4373
4542
  if (!declaredPythonVersion && pipfileLockDir) {
4374
4543
  let lock = {};
4544
+ const pipfileLockPath = (0, import_path7.join)(pipfileLockDir, "Pipfile.lock");
4375
4545
  try {
4376
- const json = await readFile((0, import_path7.join)(pipfileLockDir, "Pipfile.lock"), "utf8");
4377
- lock = JSON.parse(json);
4546
+ const pipfileLockContent = await readFile(pipfileLockPath, "utf8");
4547
+ try {
4548
+ lock = JSON.parse(pipfileLockContent);
4549
+ } catch (err) {
4550
+ console.log(
4551
+ `Failed to parse "Pipfile.lock". File content:
4552
+ ${pipfileLockContent}`
4553
+ );
4554
+ throw err;
4555
+ }
4378
4556
  } catch (err) {
4379
4557
  throw new import_build_utils8.NowBuildError({
4380
4558
  code: "INVALID_PIPFILE_LOCK",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/python",
3
- "version": "6.12.0-canary.20260211174907.cdd2da6",
3
+ "version": "6.12.0",
4
4
  "main": "./dist/index.js",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
@@ -16,7 +16,7 @@
16
16
  "directory": "packages/python"
17
17
  },
18
18
  "dependencies": {
19
- "@vercel/python-analysis": "0.5.0-canary.20260211174907.cdd2da6"
19
+ "@vercel/python-analysis": "0.4.1"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@renovatebot/pep440": "4.2.1",
@@ -34,8 +34,8 @@
34
34
  "smol-toml": "1.5.2",
35
35
  "vitest": "2.1.4",
36
36
  "which": "3.0.0",
37
- "@vercel/build-utils": "13.4.0-canary.20260211174907.cdd2da6",
38
- "@vercel/error-utils": "2.1.0-canary.20260211174907.cdd2da6"
37
+ "@vercel/build-utils": "13.4.0",
38
+ "@vercel/error-utils": "2.0.3"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "node ../../utils/build-builder.mjs",