@vercel/python 6.10.0 → 6.11.1
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/dist/index.js +206 -291
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -137,12 +137,12 @@ var require_isexe = __commonJS({
|
|
|
137
137
|
if (typeof Promise !== "function") {
|
|
138
138
|
throw new TypeError("callback not provided");
|
|
139
139
|
}
|
|
140
|
-
return new Promise(function(
|
|
140
|
+
return new Promise(function(resolve, reject) {
|
|
141
141
|
isexe(path, options || {}, function(er, is) {
|
|
142
142
|
if (er) {
|
|
143
143
|
reject(er);
|
|
144
144
|
} else {
|
|
145
|
-
|
|
145
|
+
resolve(is);
|
|
146
146
|
}
|
|
147
147
|
});
|
|
148
148
|
});
|
|
@@ -1498,7 +1498,7 @@ var require_parse = __commonJS({
|
|
|
1498
1498
|
var escape = require_escape();
|
|
1499
1499
|
var readShebang = require_readShebang();
|
|
1500
1500
|
var semver = require_semver();
|
|
1501
|
-
var
|
|
1501
|
+
var isWin3 = process.platform === "win32";
|
|
1502
1502
|
var isExecutableRegExp = /\.(?:com|exe)$/i;
|
|
1503
1503
|
var isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;
|
|
1504
1504
|
var supportsShellOption = niceTry(() => semver.satisfies(process.version, "^4.8.0 || ^5.7.0 || >= 6.0.0", true)) || false;
|
|
@@ -1513,7 +1513,7 @@ var require_parse = __commonJS({
|
|
|
1513
1513
|
return parsed.file;
|
|
1514
1514
|
}
|
|
1515
1515
|
function parseNonShell(parsed) {
|
|
1516
|
-
if (!
|
|
1516
|
+
if (!isWin3) {
|
|
1517
1517
|
return parsed;
|
|
1518
1518
|
}
|
|
1519
1519
|
const commandFile = detectShebang(parsed);
|
|
@@ -1535,7 +1535,7 @@ var require_parse = __commonJS({
|
|
|
1535
1535
|
return parsed;
|
|
1536
1536
|
}
|
|
1537
1537
|
const shellCommand = [parsed.command].concat(parsed.args).join(" ");
|
|
1538
|
-
if (
|
|
1538
|
+
if (isWin3) {
|
|
1539
1539
|
parsed.command = typeof parsed.options.shell === "string" ? parsed.options.shell : process.env.comspec || "cmd.exe";
|
|
1540
1540
|
parsed.args = ["/d", "/s", "/c", `"${shellCommand}"`];
|
|
1541
1541
|
parsed.options.windowsVerbatimArguments = true;
|
|
@@ -1578,7 +1578,7 @@ var require_parse = __commonJS({
|
|
|
1578
1578
|
var require_enoent = __commonJS({
|
|
1579
1579
|
"../../node_modules/.pnpm/cross-spawn@6.0.5/node_modules/cross-spawn/lib/enoent.js"(exports, module2) {
|
|
1580
1580
|
"use strict";
|
|
1581
|
-
var
|
|
1581
|
+
var isWin3 = process.platform === "win32";
|
|
1582
1582
|
function notFoundError(original, syscall) {
|
|
1583
1583
|
return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), {
|
|
1584
1584
|
code: "ENOENT",
|
|
@@ -1589,7 +1589,7 @@ var require_enoent = __commonJS({
|
|
|
1589
1589
|
});
|
|
1590
1590
|
}
|
|
1591
1591
|
function hookChildProcess(cp, parsed) {
|
|
1592
|
-
if (!
|
|
1592
|
+
if (!isWin3) {
|
|
1593
1593
|
return;
|
|
1594
1594
|
}
|
|
1595
1595
|
const originalEmit = cp.emit;
|
|
@@ -1604,13 +1604,13 @@ var require_enoent = __commonJS({
|
|
|
1604
1604
|
};
|
|
1605
1605
|
}
|
|
1606
1606
|
function verifyENOENT(status, parsed) {
|
|
1607
|
-
if (
|
|
1607
|
+
if (isWin3 && status === 1 && !parsed.file) {
|
|
1608
1608
|
return notFoundError(parsed.original, "spawn");
|
|
1609
1609
|
}
|
|
1610
1610
|
return null;
|
|
1611
1611
|
}
|
|
1612
1612
|
function verifyENOENTSync(status, parsed) {
|
|
1613
|
-
if (
|
|
1613
|
+
if (isWin3 && status === 1 && !parsed.file) {
|
|
1614
1614
|
return notFoundError(parsed.original, "spawnSync");
|
|
1615
1615
|
}
|
|
1616
1616
|
return null;
|
|
@@ -2042,7 +2042,7 @@ var require_get_stream = __commonJS({
|
|
|
2042
2042
|
options = Object.assign({ maxBuffer: Infinity }, options);
|
|
2043
2043
|
const { maxBuffer } = options;
|
|
2044
2044
|
let stream;
|
|
2045
|
-
return new Promise((
|
|
2045
|
+
return new Promise((resolve, reject) => {
|
|
2046
2046
|
const rejectPromise = (error) => {
|
|
2047
2047
|
if (error) {
|
|
2048
2048
|
error.bufferedData = stream.getBufferedValue();
|
|
@@ -2054,7 +2054,7 @@ var require_get_stream = __commonJS({
|
|
|
2054
2054
|
rejectPromise(error);
|
|
2055
2055
|
return;
|
|
2056
2056
|
}
|
|
2057
|
-
|
|
2057
|
+
resolve();
|
|
2058
2058
|
});
|
|
2059
2059
|
stream.on("data", () => {
|
|
2060
2060
|
if (stream.getBufferedLength() > maxBuffer) {
|
|
@@ -2078,11 +2078,11 @@ var require_p_finally = __commonJS({
|
|
|
2078
2078
|
onFinally = onFinally || (() => {
|
|
2079
2079
|
});
|
|
2080
2080
|
return promise.then(
|
|
2081
|
-
(val) => new Promise((
|
|
2082
|
-
|
|
2081
|
+
(val) => new Promise((resolve) => {
|
|
2082
|
+
resolve(onFinally());
|
|
2083
2083
|
}).then(() => val),
|
|
2084
|
-
(err) => new Promise((
|
|
2085
|
-
|
|
2084
|
+
(err) => new Promise((resolve) => {
|
|
2085
|
+
resolve(onFinally());
|
|
2086
2086
|
}).then(() => {
|
|
2087
2087
|
throw err;
|
|
2088
2088
|
})
|
|
@@ -2143,7 +2143,7 @@ var require_signal_exit = __commonJS({
|
|
|
2143
2143
|
} else {
|
|
2144
2144
|
assert = require("assert");
|
|
2145
2145
|
signals = require_signals();
|
|
2146
|
-
|
|
2146
|
+
isWin3 = /^win/i.test(process2.platform);
|
|
2147
2147
|
EE = require("events");
|
|
2148
2148
|
if (typeof EE !== "function") {
|
|
2149
2149
|
EE = EE.EventEmitter;
|
|
@@ -2215,7 +2215,7 @@ var require_signal_exit = __commonJS({
|
|
|
2215
2215
|
unload();
|
|
2216
2216
|
emit("exit", null, sig);
|
|
2217
2217
|
emit("afterexit", null, sig);
|
|
2218
|
-
if (
|
|
2218
|
+
if (isWin3 && sig === "SIGHUP") {
|
|
2219
2219
|
sig = "SIGINT";
|
|
2220
2220
|
}
|
|
2221
2221
|
process2.kill(process2.pid, sig);
|
|
@@ -2272,7 +2272,7 @@ var require_signal_exit = __commonJS({
|
|
|
2272
2272
|
}
|
|
2273
2273
|
var assert;
|
|
2274
2274
|
var signals;
|
|
2275
|
-
var
|
|
2275
|
+
var isWin3;
|
|
2276
2276
|
var EE;
|
|
2277
2277
|
var emitter;
|
|
2278
2278
|
var unload;
|
|
@@ -2461,8 +2461,8 @@ var require_execa = __commonJS({
|
|
|
2461
2461
|
}
|
|
2462
2462
|
let ret;
|
|
2463
2463
|
if (!buffer) {
|
|
2464
|
-
ret = new Promise((
|
|
2465
|
-
process2[stream].once("end",
|
|
2464
|
+
ret = new Promise((resolve, reject) => {
|
|
2465
|
+
process2[stream].once("end", resolve).once("error", reject);
|
|
2466
2466
|
});
|
|
2467
2467
|
} else if (encoding) {
|
|
2468
2468
|
ret = _getStream(process2[stream], {
|
|
@@ -2551,19 +2551,19 @@ ${stderr}${stdout}`;
|
|
|
2551
2551
|
spawned.kill(parsed.opts.killSignal);
|
|
2552
2552
|
}, parsed.opts.timeout);
|
|
2553
2553
|
}
|
|
2554
|
-
const processDone = new Promise((
|
|
2554
|
+
const processDone = new Promise((resolve) => {
|
|
2555
2555
|
spawned.on("exit", (code, signal) => {
|
|
2556
2556
|
cleanup();
|
|
2557
|
-
|
|
2557
|
+
resolve({ code, signal });
|
|
2558
2558
|
});
|
|
2559
2559
|
spawned.on("error", (err) => {
|
|
2560
2560
|
cleanup();
|
|
2561
|
-
|
|
2561
|
+
resolve({ error: err });
|
|
2562
2562
|
});
|
|
2563
2563
|
if (spawned.stdin) {
|
|
2564
2564
|
spawned.stdin.on("error", (err) => {
|
|
2565
2565
|
cleanup();
|
|
2566
|
-
|
|
2566
|
+
resolve({ error: err });
|
|
2567
2567
|
});
|
|
2568
2568
|
}
|
|
2569
2569
|
});
|
|
@@ -2651,7 +2651,7 @@ ${stderr}${stdout}`;
|
|
|
2651
2651
|
var require_lib = __commonJS({
|
|
2652
2652
|
"../../node_modules/.pnpm/which@3.0.0/node_modules/which/lib/index.js"(exports, module2) {
|
|
2653
2653
|
var isexe = require_isexe();
|
|
2654
|
-
var { join: join7, delimiter, sep, posix } = require("path");
|
|
2654
|
+
var { join: join7, delimiter: delimiter2, sep, posix } = require("path");
|
|
2655
2655
|
var isWindows = process.platform === "win32";
|
|
2656
2656
|
var rSlash = new RegExp(`[${posix.sep}${sep === posix.sep ? "" : sep}]`.replace(/(\\)/g, "\\$1"));
|
|
2657
2657
|
var rRel = new RegExp(`^\\.${rSlash.source}`);
|
|
@@ -2659,7 +2659,7 @@ var require_lib = __commonJS({
|
|
|
2659
2659
|
var getPathInfo = (cmd, {
|
|
2660
2660
|
path: optPath = process.env.PATH,
|
|
2661
2661
|
pathExt: optPathExt = process.env.PATHEXT,
|
|
2662
|
-
delimiter: optDelimiter =
|
|
2662
|
+
delimiter: optDelimiter = delimiter2
|
|
2663
2663
|
}) => {
|
|
2664
2664
|
const pathEnv = cmd.match(rSlash) ? [""] : [
|
|
2665
2665
|
// windows always checks the cwd first
|
|
@@ -2761,9 +2761,9 @@ var import_build_utils8 = require("@vercel/build-utils");
|
|
|
2761
2761
|
// src/install.ts
|
|
2762
2762
|
var import_execa3 = __toESM(require_execa());
|
|
2763
2763
|
var import_fs3 = __toESM(require("fs"));
|
|
2764
|
-
var import_os2 = __toESM(require("os"));
|
|
2765
2764
|
var import_path4 = require("path");
|
|
2766
2765
|
var import_build_utils4 = require("@vercel/build-utils");
|
|
2766
|
+
var import_python_analysis = require("@vercel/python-analysis");
|
|
2767
2767
|
|
|
2768
2768
|
// src/utils.ts
|
|
2769
2769
|
var import_fs2 = __toESM(require("fs"));
|
|
@@ -2856,9 +2856,17 @@ var UvRunner = class {
|
|
|
2856
2856
|
env: getProtectedUvEnv(process.env)
|
|
2857
2857
|
});
|
|
2858
2858
|
} catch (err) {
|
|
2859
|
-
|
|
2859
|
+
const error = new Error(
|
|
2860
2860
|
`Failed to run "${pretty}": ${err instanceof Error ? err.message : String(err)}`
|
|
2861
2861
|
);
|
|
2862
|
+
if (err && typeof err === "object") {
|
|
2863
|
+
if ("code" in err) {
|
|
2864
|
+
error.code = err.code;
|
|
2865
|
+
} else if ("signal" in err) {
|
|
2866
|
+
error.code = err.signal;
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
throw error;
|
|
2862
2870
|
}
|
|
2863
2871
|
}
|
|
2864
2872
|
async addDependencies(options) {
|
|
@@ -3061,7 +3069,8 @@ function createVenvEnv(venvPath, baseEnv = process.env) {
|
|
|
3061
3069
|
}
|
|
3062
3070
|
async function ensureVenv({
|
|
3063
3071
|
pythonPath,
|
|
3064
|
-
venvPath
|
|
3072
|
+
venvPath,
|
|
3073
|
+
uvPath
|
|
3065
3074
|
}) {
|
|
3066
3075
|
const marker = (0, import_path3.join)(venvPath, "pyvenv.cfg");
|
|
3067
3076
|
try {
|
|
@@ -3071,7 +3080,11 @@ async function ensureVenv({
|
|
|
3071
3080
|
}
|
|
3072
3081
|
await import_fs2.default.promises.mkdir(venvPath, { recursive: true });
|
|
3073
3082
|
console.log(`Creating virtual environment at "${venvPath}"...`);
|
|
3074
|
-
|
|
3083
|
+
if (uvPath) {
|
|
3084
|
+
await (0, import_execa2.default)(uvPath, ["venv", venvPath]);
|
|
3085
|
+
} else {
|
|
3086
|
+
await (0, import_execa2.default)(pythonPath, ["-m", "venv", venvPath]);
|
|
3087
|
+
}
|
|
3075
3088
|
}
|
|
3076
3089
|
function getVenvPythonBin(venvPath) {
|
|
3077
3090
|
return (0, import_path3.join)(getVenvBinDir(venvPath), isWin2 ? "python.exe" : "python");
|
|
@@ -3379,7 +3392,6 @@ function isInstalled({ version: version2 }) {
|
|
|
3379
3392
|
}
|
|
3380
3393
|
|
|
3381
3394
|
// src/install.ts
|
|
3382
|
-
var isWin3 = process.platform === "win32";
|
|
3383
3395
|
var makeDependencyCheckCode = (dependency) => `
|
|
3384
3396
|
from importlib import util
|
|
3385
3397
|
dep = '${dependency}'.replace('-', '_')
|
|
@@ -3455,225 +3467,130 @@ function resolveVendorDir() {
|
|
|
3455
3467
|
const vendorDir = process.env.VERCEL_PYTHON_VENDOR_DIR || "_vendor";
|
|
3456
3468
|
return vendorDir;
|
|
3457
3469
|
}
|
|
3470
|
+
function toBuildError(error) {
|
|
3471
|
+
return new import_build_utils4.NowBuildError({
|
|
3472
|
+
code: error.code,
|
|
3473
|
+
message: error.message,
|
|
3474
|
+
link: error.link,
|
|
3475
|
+
action: error.action
|
|
3476
|
+
});
|
|
3477
|
+
}
|
|
3458
3478
|
async function detectInstallSource({
|
|
3459
3479
|
workPath,
|
|
3460
3480
|
entryDirectory,
|
|
3461
|
-
|
|
3481
|
+
repoRootPath
|
|
3462
3482
|
}) {
|
|
3463
|
-
const
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
});
|
|
3475
|
-
const pipfileLockDir = findDir({
|
|
3476
|
-
file: "Pipfile.lock",
|
|
3477
|
-
entryDirectory,
|
|
3478
|
-
workPath,
|
|
3479
|
-
fsFiles
|
|
3480
|
-
});
|
|
3481
|
-
const pipfileDir = findDir({
|
|
3482
|
-
file: "Pipfile",
|
|
3483
|
-
entryDirectory,
|
|
3484
|
-
workPath,
|
|
3485
|
-
fsFiles
|
|
3486
|
-
});
|
|
3487
|
-
const requirementsDir = findDir({
|
|
3488
|
-
file: "requirements.txt",
|
|
3489
|
-
entryDirectory,
|
|
3490
|
-
workPath,
|
|
3491
|
-
fsFiles
|
|
3492
|
-
});
|
|
3493
|
-
let manifestPath = null;
|
|
3494
|
-
let manifestType = null;
|
|
3495
|
-
if (uvLockDir && pyprojectDir) {
|
|
3496
|
-
manifestType = "uv.lock";
|
|
3497
|
-
manifestPath = (0, import_path4.join)(uvLockDir, "uv.lock");
|
|
3498
|
-
} else if (pyprojectDir) {
|
|
3499
|
-
manifestType = "pyproject.toml";
|
|
3500
|
-
manifestPath = (0, import_path4.join)(pyprojectDir, "pyproject.toml");
|
|
3501
|
-
} else if (pipfileLockDir) {
|
|
3502
|
-
manifestType = "Pipfile.lock";
|
|
3503
|
-
manifestPath = (0, import_path4.join)(pipfileLockDir, "Pipfile.lock");
|
|
3504
|
-
} else if (pipfileDir) {
|
|
3505
|
-
manifestType = "Pipfile";
|
|
3506
|
-
manifestPath = (0, import_path4.join)(pipfileDir, "Pipfile");
|
|
3507
|
-
} else if (requirementsDir) {
|
|
3508
|
-
manifestType = "requirements.txt";
|
|
3509
|
-
manifestPath = (0, import_path4.join)(requirementsDir, "requirements.txt");
|
|
3510
|
-
}
|
|
3511
|
-
let manifestContent;
|
|
3512
|
-
if (manifestPath) {
|
|
3513
|
-
try {
|
|
3514
|
-
manifestContent = await import_fs3.default.promises.readFile(manifestPath, "utf8");
|
|
3515
|
-
} catch (err) {
|
|
3516
|
-
(0, import_build_utils4.debug)("Failed to read install manifest contents", err);
|
|
3483
|
+
const entrypointDir = (0, import_path4.join)(workPath, entryDirectory);
|
|
3484
|
+
const rootDir = repoRootPath ?? workPath;
|
|
3485
|
+
let pythonPackage;
|
|
3486
|
+
try {
|
|
3487
|
+
pythonPackage = await (0, import_python_analysis.discoverPythonPackage)({
|
|
3488
|
+
entrypointDir,
|
|
3489
|
+
rootDir
|
|
3490
|
+
});
|
|
3491
|
+
} catch (error) {
|
|
3492
|
+
if (error instanceof import_python_analysis.PythonAnalysisError) {
|
|
3493
|
+
throw toBuildError(error);
|
|
3517
3494
|
}
|
|
3495
|
+
throw error;
|
|
3518
3496
|
}
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
}) {
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
].join("\n") : "dependencies = []";
|
|
3534
|
-
const content = [
|
|
3535
|
-
"[project]",
|
|
3536
|
-
`name = "${projectName}"`,
|
|
3537
|
-
'version = "0.1.0"',
|
|
3538
|
-
`requires-python = "${requiresPython}"`,
|
|
3539
|
-
"classifiers = [",
|
|
3540
|
-
' "Private :: Do Not Upload",',
|
|
3541
|
-
"]",
|
|
3542
|
-
depsToml,
|
|
3543
|
-
""
|
|
3544
|
-
].join("\n");
|
|
3545
|
-
await import_fs3.default.promises.writeFile(pyprojectPath, content);
|
|
3546
|
-
}
|
|
3547
|
-
function findUvLockUpwards(startDir, repoRootPath) {
|
|
3548
|
-
const start = (0, import_path4.resolve)(startDir);
|
|
3549
|
-
const base = repoRootPath ? (0, import_path4.resolve)(repoRootPath) : void 0;
|
|
3550
|
-
for (const dir of (0, import_build_utils4.traverseUpDirectories)({ start, base })) {
|
|
3551
|
-
const lockPath = (0, import_path4.join)(dir, "uv.lock");
|
|
3552
|
-
const pyprojectPath = (0, import_path4.join)(dir, "pyproject.toml");
|
|
3553
|
-
if (import_fs3.default.existsSync(lockPath) && import_fs3.default.existsSync(pyprojectPath)) {
|
|
3554
|
-
return lockPath;
|
|
3555
|
-
}
|
|
3497
|
+
let manifestType = null;
|
|
3498
|
+
let manifestPath = null;
|
|
3499
|
+
const lockFile = pythonPackage.manifest?.lockFile ?? pythonPackage.workspaceLockFile;
|
|
3500
|
+
if (lockFile) {
|
|
3501
|
+
if (lockFile.kind === import_python_analysis.PythonLockFileKind.UvLock) {
|
|
3502
|
+
manifestType = "uv.lock";
|
|
3503
|
+
manifestPath = (0, import_path4.join)(rootDir, lockFile.path);
|
|
3504
|
+
} else if (lockFile.kind === import_python_analysis.PythonLockFileKind.PylockToml) {
|
|
3505
|
+
manifestType = "pylock.toml";
|
|
3506
|
+
manifestPath = (0, import_path4.join)(rootDir, lockFile.path);
|
|
3507
|
+
}
|
|
3508
|
+
} else if (pythonPackage.manifest) {
|
|
3509
|
+
manifestType = "pyproject.toml";
|
|
3510
|
+
manifestPath = (0, import_path4.join)(rootDir, pythonPackage.manifest.path);
|
|
3556
3511
|
}
|
|
3557
|
-
return
|
|
3512
|
+
return { manifestPath, manifestType, pythonPackage };
|
|
3558
3513
|
}
|
|
3559
3514
|
async function ensureUvProject({
|
|
3560
3515
|
workPath,
|
|
3561
3516
|
entryDirectory,
|
|
3562
|
-
fsFiles,
|
|
3563
3517
|
repoRootPath,
|
|
3564
|
-
pythonPath,
|
|
3565
|
-
pipPath,
|
|
3566
3518
|
pythonVersion,
|
|
3567
|
-
uv
|
|
3568
|
-
venvPath,
|
|
3569
|
-
meta
|
|
3519
|
+
uv
|
|
3570
3520
|
}) {
|
|
3571
|
-
const
|
|
3521
|
+
const rootDir = repoRootPath ?? workPath;
|
|
3572
3522
|
const installInfo = await detectInstallSource({
|
|
3573
3523
|
workPath,
|
|
3574
3524
|
entryDirectory,
|
|
3575
|
-
|
|
3525
|
+
repoRootPath
|
|
3576
3526
|
});
|
|
3577
|
-
const { manifestType,
|
|
3527
|
+
const { manifestType, pythonPackage } = installInfo;
|
|
3528
|
+
const manifest = pythonPackage?.manifest;
|
|
3578
3529
|
let projectDir;
|
|
3579
3530
|
let pyprojectPath;
|
|
3580
3531
|
let lockPath = null;
|
|
3581
|
-
if (manifestType === "uv.lock") {
|
|
3582
|
-
|
|
3583
|
-
|
|
3532
|
+
if (manifestType === "uv.lock" || manifestType === "pylock.toml") {
|
|
3533
|
+
const lockFile = pythonPackage?.manifest?.lockFile ?? pythonPackage?.workspaceLockFile;
|
|
3534
|
+
if (!lockFile) {
|
|
3535
|
+
throw new Error(
|
|
3536
|
+
`Expected lock file path to be resolved, but it was null`
|
|
3537
|
+
);
|
|
3584
3538
|
}
|
|
3585
|
-
|
|
3539
|
+
lockPath = (0, import_path4.join)(rootDir, lockFile.path);
|
|
3540
|
+
projectDir = (0, import_path4.dirname)(lockPath);
|
|
3586
3541
|
pyprojectPath = (0, import_path4.join)(projectDir, "pyproject.toml");
|
|
3587
3542
|
if (!import_fs3.default.existsSync(pyprojectPath)) {
|
|
3588
3543
|
throw new Error(
|
|
3589
|
-
`Expected "pyproject.toml" next to "
|
|
3544
|
+
`Expected "pyproject.toml" next to "${lockFile.kind}" in "${projectDir}"`
|
|
3590
3545
|
);
|
|
3591
3546
|
}
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3547
|
+
console.log(`Installing required dependencies from ${lockFile.kind}...`);
|
|
3548
|
+
} else if (manifest) {
|
|
3549
|
+
projectDir = (0, import_path4.join)(rootDir, (0, import_path4.dirname)(manifest.path));
|
|
3550
|
+
pyprojectPath = (0, import_path4.join)(rootDir, manifest.path);
|
|
3551
|
+
const originKind = manifest.origin?.kind;
|
|
3552
|
+
if (originKind === import_python_analysis.PythonManifestConvertedKind.Pipfile) {
|
|
3553
|
+
console.log("Installing required dependencies from Pipfile...");
|
|
3554
|
+
} else if (originKind === import_python_analysis.PythonManifestConvertedKind.PipfileLock) {
|
|
3555
|
+
console.log("Installing required dependencies from Pipfile.lock...");
|
|
3556
|
+
} else if (originKind === import_python_analysis.PythonManifestConvertedKind.RequirementsTxt || originKind === import_python_analysis.PythonManifestConvertedKind.RequirementsIn) {
|
|
3557
|
+
console.log(
|
|
3558
|
+
`Installing required dependencies from ${manifest.origin?.path ?? "requirements.txt"}...`
|
|
3598
3559
|
);
|
|
3599
|
-
}
|
|
3600
|
-
projectDir = (0, import_path4.dirname)(manifestPath);
|
|
3601
|
-
pyprojectPath = manifestPath;
|
|
3602
|
-
console.log("Installing required dependencies from pyproject.toml...");
|
|
3603
|
-
const workspaceLock = findUvLockUpwards(projectDir, repoRootPath);
|
|
3604
|
-
if (workspaceLock) {
|
|
3605
|
-
lockPath = workspaceLock;
|
|
3606
3560
|
} else {
|
|
3607
|
-
|
|
3608
|
-
}
|
|
3609
|
-
} else if (manifestType === "Pipfile.lock" || manifestType === "Pipfile") {
|
|
3610
|
-
if (!manifestPath) {
|
|
3611
|
-
throw new Error(
|
|
3612
|
-
"Expected Pipfile/Pipfile.lock path to be resolved, but it was null"
|
|
3613
|
-
);
|
|
3614
|
-
}
|
|
3615
|
-
projectDir = (0, import_path4.dirname)(manifestPath);
|
|
3616
|
-
console.log(`Installing required dependencies from ${manifestType}...`);
|
|
3617
|
-
const exportedReq = await exportRequirementsFromPipfile({
|
|
3618
|
-
pythonPath,
|
|
3619
|
-
pipPath,
|
|
3620
|
-
uvPath,
|
|
3621
|
-
projectDir,
|
|
3622
|
-
meta
|
|
3623
|
-
});
|
|
3624
|
-
pyprojectPath = (0, import_path4.join)(projectDir, "pyproject.toml");
|
|
3625
|
-
if (!import_fs3.default.existsSync(pyprojectPath)) {
|
|
3626
|
-
await createPyprojectToml({
|
|
3627
|
-
projectName: "app",
|
|
3628
|
-
pyprojectPath,
|
|
3629
|
-
dependencies: [],
|
|
3630
|
-
pythonVersion
|
|
3631
|
-
});
|
|
3561
|
+
console.log("Installing required dependencies from pyproject.toml...");
|
|
3632
3562
|
}
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
throw new Error(
|
|
3641
|
-
"Expected requirements.txt path to be resolved, but it was null"
|
|
3642
|
-
);
|
|
3563
|
+
if (manifest.origin) {
|
|
3564
|
+
if (manifest.data.project && !manifest.data.project["requires-python"]) {
|
|
3565
|
+
manifest.data.project["requires-python"] = `~=${pythonVersion}.0`;
|
|
3566
|
+
}
|
|
3567
|
+
const content = (0, import_python_analysis.stringifyManifest)(manifest.data);
|
|
3568
|
+
pyprojectPath = (0, import_path4.join)(projectDir, "pyproject.toml");
|
|
3569
|
+
await import_fs3.default.promises.writeFile(pyprojectPath, content);
|
|
3643
3570
|
}
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
if (!import_fs3.default.existsSync(pyprojectPath)) {
|
|
3650
|
-
await createPyprojectToml({
|
|
3651
|
-
projectName: "app",
|
|
3652
|
-
pyprojectPath,
|
|
3653
|
-
dependencies: [],
|
|
3654
|
-
pythonVersion
|
|
3655
|
-
});
|
|
3571
|
+
const workspaceLockFile = pythonPackage?.workspaceLockFile;
|
|
3572
|
+
if (workspaceLockFile) {
|
|
3573
|
+
lockPath = (0, import_path4.join)(rootDir, workspaceLockFile.path);
|
|
3574
|
+
} else {
|
|
3575
|
+
await uv.lock(projectDir);
|
|
3656
3576
|
}
|
|
3657
|
-
await uv.addFromFile({
|
|
3658
|
-
venvPath,
|
|
3659
|
-
projectDir,
|
|
3660
|
-
requirementsPath: manifestPath
|
|
3661
|
-
});
|
|
3662
3577
|
} else {
|
|
3663
3578
|
projectDir = workPath;
|
|
3664
3579
|
pyprojectPath = (0, import_path4.join)(projectDir, "pyproject.toml");
|
|
3665
3580
|
console.log(
|
|
3666
3581
|
"No Python manifest found; creating an empty pyproject.toml and uv.lock..."
|
|
3667
3582
|
);
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3583
|
+
const requiresPython = `~=${pythonVersion}.0`;
|
|
3584
|
+
const minimalManifest = (0, import_python_analysis.createMinimalManifest)({
|
|
3585
|
+
name: "app",
|
|
3586
|
+
requiresPython,
|
|
3587
|
+
dependencies: []
|
|
3673
3588
|
});
|
|
3589
|
+
const content = (0, import_python_analysis.stringifyManifest)(minimalManifest);
|
|
3590
|
+
await import_fs3.default.promises.writeFile(pyprojectPath, content);
|
|
3674
3591
|
await uv.lock(projectDir);
|
|
3675
3592
|
}
|
|
3676
|
-
const resolvedLockPath = lockPath && import_fs3.default.existsSync(lockPath) ? lockPath :
|
|
3593
|
+
const resolvedLockPath = lockPath && import_fs3.default.existsSync(lockPath) ? lockPath : (0, import_path4.join)(projectDir, "uv.lock");
|
|
3677
3594
|
return { projectDir, pyprojectPath, lockPath: resolvedLockPath };
|
|
3678
3595
|
}
|
|
3679
3596
|
async function pipInstall(pipPath, uvPath, workPath, args, targetDir) {
|
|
@@ -3767,46 +3684,6 @@ async function installRequirementsFile({
|
|
|
3767
3684
|
targetDir
|
|
3768
3685
|
);
|
|
3769
3686
|
}
|
|
3770
|
-
async function exportRequirementsFromPipfile({
|
|
3771
|
-
pythonPath,
|
|
3772
|
-
pipPath,
|
|
3773
|
-
uvPath,
|
|
3774
|
-
projectDir,
|
|
3775
|
-
meta
|
|
3776
|
-
}) {
|
|
3777
|
-
const tempDir = await import_fs3.default.promises.mkdtemp(
|
|
3778
|
-
(0, import_path4.join)(import_os2.default.tmpdir(), "vercel-pipenv-")
|
|
3779
|
-
);
|
|
3780
|
-
await installRequirement({
|
|
3781
|
-
pythonPath,
|
|
3782
|
-
pipPath,
|
|
3783
|
-
dependency: "pipfile-requirements",
|
|
3784
|
-
version: "0.3.0",
|
|
3785
|
-
workPath: tempDir,
|
|
3786
|
-
meta,
|
|
3787
|
-
args: ["--no-warn-script-location"],
|
|
3788
|
-
uvPath
|
|
3789
|
-
});
|
|
3790
|
-
const tempVendorDir = (0, import_path4.join)(tempDir, resolveVendorDir());
|
|
3791
|
-
const convertCmd = isWin3 ? (0, import_path4.join)(tempVendorDir, "Scripts", "pipfile2req.exe") : (0, import_path4.join)(tempVendorDir, "bin", "pipfile2req");
|
|
3792
|
-
(0, import_build_utils4.debug)(`Running "${convertCmd}" in ${projectDir}...`);
|
|
3793
|
-
let stdout;
|
|
3794
|
-
try {
|
|
3795
|
-
const { stdout: out } = await (0, import_execa3.default)(convertCmd, [], {
|
|
3796
|
-
cwd: projectDir,
|
|
3797
|
-
env: { ...process.env, PYTHONPATH: tempVendorDir }
|
|
3798
|
-
});
|
|
3799
|
-
stdout = out;
|
|
3800
|
-
} catch (err) {
|
|
3801
|
-
throw new Error(
|
|
3802
|
-
`Failed to run "${convertCmd}": ${err instanceof Error ? err.message : String(err)}`
|
|
3803
|
-
);
|
|
3804
|
-
}
|
|
3805
|
-
const outPath = (0, import_path4.join)(tempDir, "requirements.pipenv.txt");
|
|
3806
|
-
await import_fs3.default.promises.writeFile(outPath, stdout);
|
|
3807
|
-
(0, import_build_utils4.debug)(`Exported pipfile requirements to ${outPath}`);
|
|
3808
|
-
return outPath;
|
|
3809
|
-
}
|
|
3810
3687
|
async function mirrorSitePackagesIntoVendor({
|
|
3811
3688
|
venvPath,
|
|
3812
3689
|
vendorDirName
|
|
@@ -4044,6 +3921,21 @@ function createDevWsgiShim(workPath, modulePath) {
|
|
|
4044
3921
|
return null;
|
|
4045
3922
|
}
|
|
4046
3923
|
}
|
|
3924
|
+
async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath) {
|
|
3925
|
+
const { pythonCmd, venvRoot } = useVirtualEnv(workPath, env, systemPython);
|
|
3926
|
+
if (venvRoot) {
|
|
3927
|
+
(0, import_build_utils7.debug)(`Using existing virtualenv at ${venvRoot} for multi-service dev`);
|
|
3928
|
+
return { command: pythonCmd, args: [] };
|
|
3929
|
+
}
|
|
3930
|
+
const venvPath = (0, import_path6.join)(workPath, ".venv");
|
|
3931
|
+
await ensureVenv({ pythonPath: systemPython, venvPath, uvPath });
|
|
3932
|
+
(0, import_build_utils7.debug)(`Created virtualenv at ${venvPath} for multi-service dev`);
|
|
3933
|
+
const pythonBin = getVenvPythonBin(venvPath);
|
|
3934
|
+
const binDir = getVenvBinDir(venvPath);
|
|
3935
|
+
env.VIRTUAL_ENV = venvPath;
|
|
3936
|
+
env.PATH = `${binDir}${import_path6.delimiter}${env.PATH || ""}`;
|
|
3937
|
+
return { command: pythonBin, args: [] };
|
|
3938
|
+
}
|
|
4047
3939
|
var startDevServer = async (opts) => {
|
|
4048
3940
|
const {
|
|
4049
3941
|
entrypoint: rawEntrypoint,
|
|
@@ -4104,44 +3996,70 @@ var startDevServer = async (opts) => {
|
|
|
4104
3996
|
let resolveChildReady;
|
|
4105
3997
|
let rejectChildReady;
|
|
4106
3998
|
const childReady = new Promise(
|
|
4107
|
-
(
|
|
4108
|
-
resolveChildReady =
|
|
3999
|
+
(resolve, reject) => {
|
|
4000
|
+
resolveChildReady = resolve;
|
|
4109
4001
|
rejectChildReady = reject;
|
|
4110
4002
|
}
|
|
4111
4003
|
);
|
|
4112
4004
|
PENDING_STARTS.set(serverKey, childReady);
|
|
4113
4005
|
try {
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4006
|
+
const { pythonPath: systemPython } = getDefaultPythonVersion(meta);
|
|
4007
|
+
const uvPath = await findUvBinary(systemPython);
|
|
4008
|
+
const venv = isInVirtualEnv();
|
|
4009
|
+
const serviceCount = meta.serviceCount ?? 0;
|
|
4010
|
+
const pythonServiceCount = meta.pythonServiceCount ?? 1;
|
|
4011
|
+
if (venv && pythonServiceCount > 1) {
|
|
4012
|
+
const yellow = "\x1B[33m";
|
|
4013
|
+
const white = "\x1B[1m";
|
|
4014
|
+
const reset = "\x1B[0m";
|
|
4015
|
+
throw new import_build_utils7.NowBuildError({
|
|
4016
|
+
code: "PYTHON_EXTERNAL_VENV_DETECTED",
|
|
4017
|
+
message: `Detected activated venv at ${yellow}${venv}${reset}, ${white}vercel dev${reset} manages virtual environments automatically.
|
|
4018
|
+
Run ${white}deactivate${reset} and try again.`
|
|
4019
|
+
});
|
|
4020
|
+
}
|
|
4021
|
+
let spawnCommand = systemPython;
|
|
4022
|
+
let spawnArgsPrefix = [];
|
|
4023
|
+
if (serviceCount > 0) {
|
|
4024
|
+
const runner = await getMultiServicePythonRunner(
|
|
4025
|
+
workPath,
|
|
4026
|
+
env,
|
|
4027
|
+
systemPython,
|
|
4028
|
+
uvPath
|
|
4029
|
+
);
|
|
4030
|
+
spawnCommand = runner.command;
|
|
4031
|
+
spawnArgsPrefix = runner.args;
|
|
4032
|
+
(0, import_build_utils7.debug)(
|
|
4033
|
+
`Multi-service Python runner: ${spawnCommand} ${spawnArgsPrefix.join(" ")}`
|
|
4034
|
+
);
|
|
4035
|
+
} else if (venv) {
|
|
4036
|
+
(0, import_build_utils7.debug)(`Running in virtualenv at ${venv}`);
|
|
4037
|
+
} else {
|
|
4038
|
+
const { pythonCmd: venvPythonCmd, venvRoot } = useVirtualEnv(
|
|
4039
|
+
workPath,
|
|
4040
|
+
env,
|
|
4041
|
+
systemPython
|
|
4042
|
+
);
|
|
4043
|
+
spawnCommand = venvPythonCmd;
|
|
4044
|
+
if (venvRoot) {
|
|
4045
|
+
(0, import_build_utils7.debug)(`Using virtualenv at ${venvRoot}`);
|
|
4121
4046
|
} else {
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
(0, import_build_utils7.debug)(`Using virtualenv at ${venvRoot}`);
|
|
4130
|
-
} else {
|
|
4131
|
-
(0, import_build_utils7.debug)("No virtualenv found");
|
|
4132
|
-
try {
|
|
4133
|
-
const yellow = "\x1B[33m";
|
|
4134
|
-
const reset = "\x1B[0m";
|
|
4135
|
-
const venvCmd = process.platform === "win32" ? "python -m venv .venv && .venv\\Scripts\\activate" : "python -m venv .venv && source .venv/bin/activate";
|
|
4136
|
-
process.stderr.write(
|
|
4137
|
-
`${yellow}Warning: no virtual environment detected in ${workPath}. Using system Python: ${pythonCmd}.${reset}
|
|
4047
|
+
(0, import_build_utils7.debug)("No virtualenv found");
|
|
4048
|
+
try {
|
|
4049
|
+
const yellow = "\x1B[33m";
|
|
4050
|
+
const reset = "\x1B[0m";
|
|
4051
|
+
const venvCmd = process.platform === "win32" ? "python -m venv .venv && .venv\\Scripts\\activate" : "python -m venv .venv && source .venv/bin/activate";
|
|
4052
|
+
process.stderr.write(
|
|
4053
|
+
`${yellow}Warning: no virtual environment detected in ${workPath}. Using system Python: ${systemPython}.${reset}
|
|
4138
4054
|
If you are using a virtual environment, activate it before running "vercel dev", or create one: ${venvCmd}
|
|
4139
4055
|
`
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
}
|
|
4056
|
+
);
|
|
4057
|
+
} catch (_) {
|
|
4143
4058
|
}
|
|
4144
4059
|
}
|
|
4060
|
+
}
|
|
4061
|
+
await new Promise((resolve, reject) => {
|
|
4062
|
+
let resolved = false;
|
|
4145
4063
|
if (framework !== "flask") {
|
|
4146
4064
|
const devShimModule = createDevAsgiShim(workPath, modulePath);
|
|
4147
4065
|
if (devShimModule) {
|
|
@@ -4150,11 +4068,12 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
4150
4068
|
env.PYTHONPATH = existingPythonPath ? `${vercelPythonDir}:${existingPythonPath}` : vercelPythonDir;
|
|
4151
4069
|
}
|
|
4152
4070
|
const moduleToRun = devShimModule || modulePath;
|
|
4153
|
-
const
|
|
4071
|
+
const pythonArgs = ["-u", "-m", moduleToRun];
|
|
4072
|
+
const argv = [...spawnArgsPrefix, ...pythonArgs];
|
|
4154
4073
|
(0, import_build_utils7.debug)(
|
|
4155
|
-
`Starting ASGI dev server (${framework}): ${
|
|
4074
|
+
`Starting ASGI dev server (${framework}): ${spawnCommand} ${argv.join(" ")}`
|
|
4156
4075
|
);
|
|
4157
|
-
const child = (0, import_child_process2.spawn)(
|
|
4076
|
+
const child = (0, import_child_process2.spawn)(spawnCommand, argv, {
|
|
4158
4077
|
cwd: workPath,
|
|
4159
4078
|
env,
|
|
4160
4079
|
stdio: ["inherit", "pipe", "pipe"]
|
|
@@ -4187,7 +4106,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
4187
4106
|
child.stderr?.removeListener("data", onDetect);
|
|
4188
4107
|
const port2 = Number(portMatch[1]);
|
|
4189
4108
|
resolveChildReady({ port: port2, pid: child.pid });
|
|
4190
|
-
|
|
4109
|
+
resolve();
|
|
4191
4110
|
}
|
|
4192
4111
|
}
|
|
4193
4112
|
};
|
|
@@ -4216,9 +4135,10 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
4216
4135
|
env.PYTHONPATH = existingPythonPath ? `${vercelPythonDir}:${existingPythonPath}` : vercelPythonDir;
|
|
4217
4136
|
}
|
|
4218
4137
|
const moduleToRun = devShimModule || modulePath;
|
|
4219
|
-
const
|
|
4220
|
-
|
|
4221
|
-
|
|
4138
|
+
const pythonArgs = ["-u", "-m", moduleToRun];
|
|
4139
|
+
const argv = [...spawnArgsPrefix, ...pythonArgs];
|
|
4140
|
+
(0, import_build_utils7.debug)(`Starting Flask dev server: ${spawnCommand} ${argv.join(" ")}`);
|
|
4141
|
+
const child = (0, import_child_process2.spawn)(spawnCommand, argv, {
|
|
4222
4142
|
cwd: workPath,
|
|
4223
4143
|
env,
|
|
4224
4144
|
stdio: ["inherit", "pipe", "pipe"]
|
|
@@ -4250,7 +4170,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
4250
4170
|
child.stderr?.removeListener("data", onDetect);
|
|
4251
4171
|
const port2 = Number(portMatch[1]);
|
|
4252
4172
|
resolveChildReady({ port: port2, pid: child.pid });
|
|
4253
|
-
|
|
4173
|
+
resolve();
|
|
4254
4174
|
}
|
|
4255
4175
|
}
|
|
4256
4176
|
};
|
|
@@ -4522,14 +4442,9 @@ var build = async ({
|
|
|
4522
4442
|
const { projectDir } = await ensureUvProject({
|
|
4523
4443
|
workPath,
|
|
4524
4444
|
entryDirectory,
|
|
4525
|
-
fsFiles,
|
|
4526
4445
|
repoRootPath,
|
|
4527
|
-
pythonPath: pythonVersion.pythonPath,
|
|
4528
|
-
pipPath: pythonVersion.pipPath,
|
|
4529
4446
|
pythonVersion: pythonVersion.version,
|
|
4530
|
-
uv
|
|
4531
|
-
venvPath,
|
|
4532
|
-
meta
|
|
4447
|
+
uv
|
|
4533
4448
|
});
|
|
4534
4449
|
await uv.sync({
|
|
4535
4450
|
venvPath,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/python",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.11.1",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
|
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
"url": "https://github.com/vercel/vercel.git",
|
|
16
16
|
"directory": "packages/python"
|
|
17
17
|
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@vercel/python-analysis": "0.4.0"
|
|
20
|
+
},
|
|
18
21
|
"devDependencies": {
|
|
19
22
|
"@renovatebot/pep440": "4.2.1",
|
|
20
23
|
"@types/execa": "^0.9.0",
|
|
@@ -31,7 +34,7 @@
|
|
|
31
34
|
"smol-toml": "1.5.2",
|
|
32
35
|
"vitest": "2.1.4",
|
|
33
36
|
"which": "3.0.0",
|
|
34
|
-
"@vercel/build-utils": "13.3.
|
|
37
|
+
"@vercel/build-utils": "13.3.5",
|
|
35
38
|
"@vercel/error-utils": "2.0.3"
|
|
36
39
|
},
|
|
37
40
|
"scripts": {
|