@vercel/python 6.50.0 → 6.51.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.
Files changed (2) hide show
  1. package/dist/index.js +1066 -1085
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ var require_windows = __commonJS({
48
48
  "../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js"(exports, module2) {
49
49
  module2.exports = isexe;
50
50
  isexe.sync = sync;
51
- var fs16 = require("fs");
51
+ var fs17 = require("fs");
52
52
  function checkPathExt(path, options) {
53
53
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
54
54
  if (!pathext) {
@@ -73,12 +73,12 @@ var require_windows = __commonJS({
73
73
  return checkPathExt(path, options);
74
74
  }
75
75
  function isexe(path, options, cb) {
76
- fs16.stat(path, function(er, stat) {
76
+ fs17.stat(path, function(er, stat) {
77
77
  cb(er, er ? false : checkStat(stat, path, options));
78
78
  });
79
79
  }
80
80
  function sync(path, options) {
81
- return checkStat(fs16.statSync(path), path, options);
81
+ return checkStat(fs17.statSync(path), path, options);
82
82
  }
83
83
  }
84
84
  });
@@ -88,14 +88,14 @@ var require_mode = __commonJS({
88
88
  "../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js"(exports, module2) {
89
89
  module2.exports = isexe;
90
90
  isexe.sync = sync;
91
- var fs16 = require("fs");
91
+ var fs17 = require("fs");
92
92
  function isexe(path, options, cb) {
93
- fs16.stat(path, function(er, stat) {
93
+ fs17.stat(path, function(er, stat) {
94
94
  cb(er, er ? false : checkStat(stat, options));
95
95
  });
96
96
  }
97
97
  function sync(path, options) {
98
- return checkStat(fs16.statSync(path), options);
98
+ return checkStat(fs17.statSync(path), options);
99
99
  }
100
100
  function checkStat(stat, options) {
101
101
  return stat.isFile() && checkMode(stat, options);
@@ -119,7 +119,7 @@ var require_mode = __commonJS({
119
119
  // ../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js
120
120
  var require_isexe = __commonJS({
121
121
  "../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js"(exports, module2) {
122
- var fs16 = require("fs");
122
+ var fs17 = require("fs");
123
123
  var core;
124
124
  if (process.platform === "win32" || global.TESTING_WINDOWS) {
125
125
  core = require_windows();
@@ -395,7 +395,7 @@ var require_shebang_command = __commonJS({
395
395
  var require_readShebang = __commonJS({
396
396
  "../../node_modules/.pnpm/cross-spawn@6.0.5/node_modules/cross-spawn/lib/util/readShebang.js"(exports, module2) {
397
397
  "use strict";
398
- var fs16 = require("fs");
398
+ var fs17 = require("fs");
399
399
  var shebangCommand = require_shebang_command();
400
400
  function readShebang(command) {
401
401
  const size = 150;
@@ -408,9 +408,9 @@ var require_readShebang = __commonJS({
408
408
  }
409
409
  let fd;
410
410
  try {
411
- fd = fs16.openSync(command, "r");
412
- fs16.readSync(fd, buffer, 0, size, 0);
413
- fs16.closeSync(fd);
411
+ fd = fs17.openSync(command, "r");
412
+ fs17.readSync(fd, buffer, 0, size, 0);
413
+ fs17.closeSync(fd);
414
414
  } catch (e) {
415
415
  }
416
416
  return shebangCommand(buffer.toString());
@@ -423,15 +423,15 @@ var require_readShebang = __commonJS({
423
423
  var require_semver = __commonJS({
424
424
  "../../node_modules/.pnpm/semver@5.7.2/node_modules/semver/semver.js"(exports, module2) {
425
425
  exports = module2.exports = SemVer;
426
- var debug13;
426
+ var debug14;
427
427
  if (typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG)) {
428
- debug13 = function() {
428
+ debug14 = function() {
429
429
  var args = Array.prototype.slice.call(arguments, 0);
430
430
  args.unshift("SEMVER");
431
431
  console.log.apply(console, args);
432
432
  };
433
433
  } else {
434
- debug13 = function() {
434
+ debug14 = function() {
435
435
  };
436
436
  }
437
437
  exports.SEMVER_SPEC_VERSION = "2.0.0";
@@ -540,7 +540,7 @@ var require_semver = __commonJS({
540
540
  var STAR = R++;
541
541
  src[STAR] = "(<|>)?=?\\s*\\*";
542
542
  for (i = 0; i < R; i++) {
543
- debug13(i, src[i]);
543
+ debug14(i, src[i]);
544
544
  if (!re[i]) {
545
545
  re[i] = new RegExp(src[i]);
546
546
  safeRe[i] = new RegExp(makeSafeRe(src[i]));
@@ -607,7 +607,7 @@ var require_semver = __commonJS({
607
607
  if (!(this instanceof SemVer)) {
608
608
  return new SemVer(version2, options);
609
609
  }
610
- debug13("SemVer", version2, options);
610
+ debug14("SemVer", version2, options);
611
611
  this.options = options;
612
612
  this.loose = !!options.loose;
613
613
  var m = version2.trim().match(options.loose ? safeRe[LOOSE] : safeRe[FULL]);
@@ -654,7 +654,7 @@ var require_semver = __commonJS({
654
654
  return this.version;
655
655
  };
656
656
  SemVer.prototype.compare = function(other) {
657
- debug13("SemVer.compare", this.version, this.options, other);
657
+ debug14("SemVer.compare", this.version, this.options, other);
658
658
  if (!(other instanceof SemVer)) {
659
659
  other = new SemVer(other, this.options);
660
660
  }
@@ -681,7 +681,7 @@ var require_semver = __commonJS({
681
681
  do {
682
682
  var a = this.prerelease[i2];
683
683
  var b = other.prerelease[i2];
684
- debug13("prerelease compare", i2, a, b);
684
+ debug14("prerelease compare", i2, a, b);
685
685
  if (a === void 0 && b === void 0) {
686
686
  return 0;
687
687
  } else if (b === void 0) {
@@ -935,7 +935,7 @@ var require_semver = __commonJS({
935
935
  return new Comparator(comp, options);
936
936
  }
937
937
  comp = comp.trim().split(/\s+/).join(" ");
938
- debug13("comparator", comp, options);
938
+ debug14("comparator", comp, options);
939
939
  this.options = options;
940
940
  this.loose = !!options.loose;
941
941
  this.parse(comp);
@@ -944,7 +944,7 @@ var require_semver = __commonJS({
944
944
  } else {
945
945
  this.value = this.operator + this.semver.version;
946
946
  }
947
- debug13("comp", this);
947
+ debug14("comp", this);
948
948
  }
949
949
  var ANY = {};
950
950
  Comparator.prototype.parse = function(comp) {
@@ -967,7 +967,7 @@ var require_semver = __commonJS({
967
967
  return this.value;
968
968
  };
969
969
  Comparator.prototype.test = function(version2) {
970
- debug13("Comparator.test", version2, this.options.loose);
970
+ debug14("Comparator.test", version2, this.options.loose);
971
971
  if (this.semver === ANY) {
972
972
  return true;
973
973
  }
@@ -1050,9 +1050,9 @@ var require_semver = __commonJS({
1050
1050
  var loose = this.options.loose;
1051
1051
  var hr = loose ? safeRe[HYPHENRANGELOOSE] : safeRe[HYPHENRANGE];
1052
1052
  range = range.replace(hr, hyphenReplace);
1053
- debug13("hyphen replace", range);
1053
+ debug14("hyphen replace", range);
1054
1054
  range = range.replace(safeRe[COMPARATORTRIM], comparatorTrimReplace);
1055
- debug13("comparator trim", range, safeRe[COMPARATORTRIM]);
1055
+ debug14("comparator trim", range, safeRe[COMPARATORTRIM]);
1056
1056
  range = range.replace(safeRe[TILDETRIM], tildeTrimReplace);
1057
1057
  range = range.replace(safeRe[CARETTRIM], caretTrimReplace);
1058
1058
  var compRe = loose ? safeRe[COMPARATORLOOSE] : safeRe[COMPARATOR];
@@ -1092,15 +1092,15 @@ var require_semver = __commonJS({
1092
1092
  });
1093
1093
  }
1094
1094
  function parseComparator(comp, options) {
1095
- debug13("comp", comp, options);
1095
+ debug14("comp", comp, options);
1096
1096
  comp = replaceCarets(comp, options);
1097
- debug13("caret", comp);
1097
+ debug14("caret", comp);
1098
1098
  comp = replaceTildes(comp, options);
1099
- debug13("tildes", comp);
1099
+ debug14("tildes", comp);
1100
1100
  comp = replaceXRanges(comp, options);
1101
- debug13("xrange", comp);
1101
+ debug14("xrange", comp);
1102
1102
  comp = replaceStars(comp, options);
1103
- debug13("stars", comp);
1103
+ debug14("stars", comp);
1104
1104
  return comp;
1105
1105
  }
1106
1106
  function isX(id) {
@@ -1114,7 +1114,7 @@ var require_semver = __commonJS({
1114
1114
  function replaceTilde(comp, options) {
1115
1115
  var r = options.loose ? safeRe[TILDELOOSE] : safeRe[TILDE];
1116
1116
  return comp.replace(r, function(_, M, m, p, pr) {
1117
- debug13("tilde", comp, _, M, m, p, pr);
1117
+ debug14("tilde", comp, _, M, m, p, pr);
1118
1118
  var ret;
1119
1119
  if (isX(M)) {
1120
1120
  ret = "";
@@ -1123,12 +1123,12 @@ var require_semver = __commonJS({
1123
1123
  } else if (isX(p)) {
1124
1124
  ret = ">=" + M + "." + m + ".0 <" + M + "." + (+m + 1) + ".0";
1125
1125
  } else if (pr) {
1126
- debug13("replaceTilde pr", pr);
1126
+ debug14("replaceTilde pr", pr);
1127
1127
  ret = ">=" + M + "." + m + "." + p + "-" + pr + " <" + M + "." + (+m + 1) + ".0";
1128
1128
  } else {
1129
1129
  ret = ">=" + M + "." + m + "." + p + " <" + M + "." + (+m + 1) + ".0";
1130
1130
  }
1131
- debug13("tilde return", ret);
1131
+ debug14("tilde return", ret);
1132
1132
  return ret;
1133
1133
  });
1134
1134
  }
@@ -1138,10 +1138,10 @@ var require_semver = __commonJS({
1138
1138
  }).join(" ");
1139
1139
  }
1140
1140
  function replaceCaret(comp, options) {
1141
- debug13("caret", comp, options);
1141
+ debug14("caret", comp, options);
1142
1142
  var r = options.loose ? safeRe[CARETLOOSE] : safeRe[CARET];
1143
1143
  return comp.replace(r, function(_, M, m, p, pr) {
1144
- debug13("caret", comp, _, M, m, p, pr);
1144
+ debug14("caret", comp, _, M, m, p, pr);
1145
1145
  var ret;
1146
1146
  if (isX(M)) {
1147
1147
  ret = "";
@@ -1154,7 +1154,7 @@ var require_semver = __commonJS({
1154
1154
  ret = ">=" + M + "." + m + ".0 <" + (+M + 1) + ".0.0";
1155
1155
  }
1156
1156
  } else if (pr) {
1157
- debug13("replaceCaret pr", pr);
1157
+ debug14("replaceCaret pr", pr);
1158
1158
  if (M === "0") {
1159
1159
  if (m === "0") {
1160
1160
  ret = ">=" + M + "." + m + "." + p + "-" + pr + " <" + M + "." + m + "." + (+p + 1);
@@ -1165,7 +1165,7 @@ var require_semver = __commonJS({
1165
1165
  ret = ">=" + M + "." + m + "." + p + "-" + pr + " <" + (+M + 1) + ".0.0";
1166
1166
  }
1167
1167
  } else {
1168
- debug13("no pr");
1168
+ debug14("no pr");
1169
1169
  if (M === "0") {
1170
1170
  if (m === "0") {
1171
1171
  ret = ">=" + M + "." + m + "." + p + " <" + M + "." + m + "." + (+p + 1);
@@ -1176,12 +1176,12 @@ var require_semver = __commonJS({
1176
1176
  ret = ">=" + M + "." + m + "." + p + " <" + (+M + 1) + ".0.0";
1177
1177
  }
1178
1178
  }
1179
- debug13("caret return", ret);
1179
+ debug14("caret return", ret);
1180
1180
  return ret;
1181
1181
  });
1182
1182
  }
1183
1183
  function replaceXRanges(comp, options) {
1184
- debug13("replaceXRanges", comp, options);
1184
+ debug14("replaceXRanges", comp, options);
1185
1185
  return comp.split(/\s+/).map(function(comp2) {
1186
1186
  return replaceXRange(comp2, options);
1187
1187
  }).join(" ");
@@ -1190,7 +1190,7 @@ var require_semver = __commonJS({
1190
1190
  comp = comp.trim();
1191
1191
  var r = options.loose ? safeRe[XRANGELOOSE] : safeRe[XRANGE];
1192
1192
  return comp.replace(r, function(ret, gtlt, M, m, p, pr) {
1193
- debug13("xRange", comp, ret, gtlt, M, m, p, pr);
1193
+ debug14("xRange", comp, ret, gtlt, M, m, p, pr);
1194
1194
  var xM = isX(M);
1195
1195
  var xm = xM || isX(m);
1196
1196
  var xp = xm || isX(p);
@@ -1233,12 +1233,12 @@ var require_semver = __commonJS({
1233
1233
  } else if (xp) {
1234
1234
  ret = ">=" + M + "." + m + ".0 <" + M + "." + (+m + 1) + ".0";
1235
1235
  }
1236
- debug13("xRange return", ret);
1236
+ debug14("xRange return", ret);
1237
1237
  return ret;
1238
1238
  });
1239
1239
  }
1240
1240
  function replaceStars(comp, options) {
1241
- debug13("replaceStars", comp, options);
1241
+ debug14("replaceStars", comp, options);
1242
1242
  return comp.trim().replace(safeRe[STAR], "");
1243
1243
  }
1244
1244
  function hyphenReplace($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr, tb) {
@@ -1286,7 +1286,7 @@ var require_semver = __commonJS({
1286
1286
  }
1287
1287
  if (version2.prerelease.length && !options.includePrerelease) {
1288
1288
  for (i2 = 0; i2 < set.length; i2++) {
1289
- debug13(set[i2].semver);
1289
+ debug14(set[i2].semver);
1290
1290
  if (set[i2].semver === ANY) {
1291
1291
  continue;
1292
1292
  }
@@ -1895,9 +1895,9 @@ var require_pump = __commonJS({
1895
1895
  "../../node_modules/.pnpm/pump@3.0.4/node_modules/pump/index.js"(exports, module2) {
1896
1896
  var once = require_once();
1897
1897
  var eos = require_end_of_stream();
1898
- var fs16;
1898
+ var fs17;
1899
1899
  try {
1900
- fs16 = require("fs");
1900
+ fs17 = require("fs");
1901
1901
  } catch (e) {
1902
1902
  }
1903
1903
  var noop = function() {
@@ -1909,9 +1909,9 @@ var require_pump = __commonJS({
1909
1909
  var isFS = function(stream) {
1910
1910
  if (!ancient)
1911
1911
  return false;
1912
- if (!fs16)
1912
+ if (!fs17)
1913
1913
  return false;
1914
- return (stream instanceof (fs16.ReadStream || noop) || stream instanceof (fs16.WriteStream || noop)) && isFn(stream.close);
1914
+ return (stream instanceof (fs17.ReadStream || noop) || stream instanceof (fs17.WriteStream || noop)) && isFn(stream.close);
1915
1915
  };
1916
1916
  var isRequest = function(stream) {
1917
1917
  return stream.setHeader && isFn(stream.abort);
@@ -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: join17, delimiter: delimiter2, sep: sep3, posix } = require("path");
2654
+ var { join: join18, delimiter: delimiter2, sep: sep3, posix } = require("path");
2655
2655
  var isWindows = process.platform === "win32";
2656
2656
  var rSlash = new RegExp(`[${posix.sep}${sep3 === posix.sep ? "" : sep3}]`.replace(/(\\)/g, "\\$1"));
2657
2657
  var rRel = new RegExp(`^\\.${rSlash.source}`);
@@ -2680,7 +2680,7 @@ var require_lib = __commonJS({
2680
2680
  var getPathPart = (raw, cmd) => {
2681
2681
  const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw;
2682
2682
  const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : "";
2683
- return prefix + join17(pathPart, cmd);
2683
+ return prefix + join18(pathPart, cmd);
2684
2684
  };
2685
2685
  var which2 = async (cmd, opt = {}) => {
2686
2686
  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
@@ -2739,15 +2739,15 @@ var require_lib = __commonJS({
2739
2739
  var require_semver2 = __commonJS({
2740
2740
  "../../node_modules/.pnpm/semver@6.3.1/node_modules/semver/semver.js"(exports, module2) {
2741
2741
  exports = module2.exports = SemVer;
2742
- var debug13;
2742
+ var debug14;
2743
2743
  if (typeof process === "object" && process.env && process.env.NODE_DEBUG && /\bsemver\b/i.test(process.env.NODE_DEBUG)) {
2744
- debug13 = function() {
2744
+ debug14 = function() {
2745
2745
  var args = Array.prototype.slice.call(arguments, 0);
2746
2746
  args.unshift("SEMVER");
2747
2747
  console.log.apply(console, args);
2748
2748
  };
2749
2749
  } else {
2750
- debug13 = function() {
2750
+ debug14 = function() {
2751
2751
  };
2752
2752
  }
2753
2753
  exports.SEMVER_SPEC_VERSION = "2.0.0";
@@ -2865,7 +2865,7 @@ var require_semver2 = __commonJS({
2865
2865
  tok("STAR");
2866
2866
  src[t.STAR] = "(<|>)?=?\\s*\\*";
2867
2867
  for (i = 0; i < R; i++) {
2868
- debug13(i, src[i]);
2868
+ debug14(i, src[i]);
2869
2869
  if (!re[i]) {
2870
2870
  re[i] = new RegExp(src[i]);
2871
2871
  safeRe[i] = new RegExp(makeSafeRe(src[i]));
@@ -2932,7 +2932,7 @@ var require_semver2 = __commonJS({
2932
2932
  if (!(this instanceof SemVer)) {
2933
2933
  return new SemVer(version2, options);
2934
2934
  }
2935
- debug13("SemVer", version2, options);
2935
+ debug14("SemVer", version2, options);
2936
2936
  this.options = options;
2937
2937
  this.loose = !!options.loose;
2938
2938
  var m = version2.trim().match(options.loose ? safeRe[t.LOOSE] : safeRe[t.FULL]);
@@ -2979,7 +2979,7 @@ var require_semver2 = __commonJS({
2979
2979
  return this.version;
2980
2980
  };
2981
2981
  SemVer.prototype.compare = function(other) {
2982
- debug13("SemVer.compare", this.version, this.options, other);
2982
+ debug14("SemVer.compare", this.version, this.options, other);
2983
2983
  if (!(other instanceof SemVer)) {
2984
2984
  other = new SemVer(other, this.options);
2985
2985
  }
@@ -3006,7 +3006,7 @@ var require_semver2 = __commonJS({
3006
3006
  do {
3007
3007
  var a = this.prerelease[i2];
3008
3008
  var b = other.prerelease[i2];
3009
- debug13("prerelease compare", i2, a, b);
3009
+ debug14("prerelease compare", i2, a, b);
3010
3010
  if (a === void 0 && b === void 0) {
3011
3011
  return 0;
3012
3012
  } else if (b === void 0) {
@@ -3028,7 +3028,7 @@ var require_semver2 = __commonJS({
3028
3028
  do {
3029
3029
  var a = this.build[i2];
3030
3030
  var b = other.build[i2];
3031
- debug13("prerelease compare", i2, a, b);
3031
+ debug14("prerelease compare", i2, a, b);
3032
3032
  if (a === void 0 && b === void 0) {
3033
3033
  return 0;
3034
3034
  } else if (b === void 0) {
@@ -3288,7 +3288,7 @@ var require_semver2 = __commonJS({
3288
3288
  return new Comparator(comp, options);
3289
3289
  }
3290
3290
  comp = comp.trim().split(/\s+/).join(" ");
3291
- debug13("comparator", comp, options);
3291
+ debug14("comparator", comp, options);
3292
3292
  this.options = options;
3293
3293
  this.loose = !!options.loose;
3294
3294
  this.parse(comp);
@@ -3297,7 +3297,7 @@ var require_semver2 = __commonJS({
3297
3297
  } else {
3298
3298
  this.value = this.operator + this.semver.version;
3299
3299
  }
3300
- debug13("comp", this);
3300
+ debug14("comp", this);
3301
3301
  }
3302
3302
  var ANY = {};
3303
3303
  Comparator.prototype.parse = function(comp) {
@@ -3320,7 +3320,7 @@ var require_semver2 = __commonJS({
3320
3320
  return this.value;
3321
3321
  };
3322
3322
  Comparator.prototype.test = function(version2) {
3323
- debug13("Comparator.test", version2, this.options.loose);
3323
+ debug14("Comparator.test", version2, this.options.loose);
3324
3324
  if (this.semver === ANY || version2 === ANY) {
3325
3325
  return true;
3326
3326
  }
@@ -3413,9 +3413,9 @@ var require_semver2 = __commonJS({
3413
3413
  var loose = this.options.loose;
3414
3414
  var hr = loose ? safeRe[t.HYPHENRANGELOOSE] : safeRe[t.HYPHENRANGE];
3415
3415
  range = range.replace(hr, hyphenReplace);
3416
- debug13("hyphen replace", range);
3416
+ debug14("hyphen replace", range);
3417
3417
  range = range.replace(safeRe[t.COMPARATORTRIM], comparatorTrimReplace);
3418
- debug13("comparator trim", range, safeRe[t.COMPARATORTRIM]);
3418
+ debug14("comparator trim", range, safeRe[t.COMPARATORTRIM]);
3419
3419
  range = range.replace(safeRe[t.TILDETRIM], tildeTrimReplace);
3420
3420
  range = range.replace(safeRe[t.CARETTRIM], caretTrimReplace);
3421
3421
  range = range.split(/\s+/).join(" ");
@@ -3468,15 +3468,15 @@ var require_semver2 = __commonJS({
3468
3468
  });
3469
3469
  }
3470
3470
  function parseComparator(comp, options) {
3471
- debug13("comp", comp, options);
3471
+ debug14("comp", comp, options);
3472
3472
  comp = replaceCarets(comp, options);
3473
- debug13("caret", comp);
3473
+ debug14("caret", comp);
3474
3474
  comp = replaceTildes(comp, options);
3475
- debug13("tildes", comp);
3475
+ debug14("tildes", comp);
3476
3476
  comp = replaceXRanges(comp, options);
3477
- debug13("xrange", comp);
3477
+ debug14("xrange", comp);
3478
3478
  comp = replaceStars(comp, options);
3479
- debug13("stars", comp);
3479
+ debug14("stars", comp);
3480
3480
  return comp;
3481
3481
  }
3482
3482
  function isX(id) {
@@ -3490,7 +3490,7 @@ var require_semver2 = __commonJS({
3490
3490
  function replaceTilde(comp, options) {
3491
3491
  var r = options.loose ? safeRe[t.TILDELOOSE] : safeRe[t.TILDE];
3492
3492
  return comp.replace(r, function(_, M, m, p, pr) {
3493
- debug13("tilde", comp, _, M, m, p, pr);
3493
+ debug14("tilde", comp, _, M, m, p, pr);
3494
3494
  var ret;
3495
3495
  if (isX(M)) {
3496
3496
  ret = "";
@@ -3499,12 +3499,12 @@ var require_semver2 = __commonJS({
3499
3499
  } else if (isX(p)) {
3500
3500
  ret = ">=" + M + "." + m + ".0 <" + M + "." + (+m + 1) + ".0";
3501
3501
  } else if (pr) {
3502
- debug13("replaceTilde pr", pr);
3502
+ debug14("replaceTilde pr", pr);
3503
3503
  ret = ">=" + M + "." + m + "." + p + "-" + pr + " <" + M + "." + (+m + 1) + ".0";
3504
3504
  } else {
3505
3505
  ret = ">=" + M + "." + m + "." + p + " <" + M + "." + (+m + 1) + ".0";
3506
3506
  }
3507
- debug13("tilde return", ret);
3507
+ debug14("tilde return", ret);
3508
3508
  return ret;
3509
3509
  });
3510
3510
  }
@@ -3514,10 +3514,10 @@ var require_semver2 = __commonJS({
3514
3514
  }).join(" ");
3515
3515
  }
3516
3516
  function replaceCaret(comp, options) {
3517
- debug13("caret", comp, options);
3517
+ debug14("caret", comp, options);
3518
3518
  var r = options.loose ? safeRe[t.CARETLOOSE] : safeRe[t.CARET];
3519
3519
  return comp.replace(r, function(_, M, m, p, pr) {
3520
- debug13("caret", comp, _, M, m, p, pr);
3520
+ debug14("caret", comp, _, M, m, p, pr);
3521
3521
  var ret;
3522
3522
  if (isX(M)) {
3523
3523
  ret = "";
@@ -3530,7 +3530,7 @@ var require_semver2 = __commonJS({
3530
3530
  ret = ">=" + M + "." + m + ".0 <" + (+M + 1) + ".0.0";
3531
3531
  }
3532
3532
  } else if (pr) {
3533
- debug13("replaceCaret pr", pr);
3533
+ debug14("replaceCaret pr", pr);
3534
3534
  if (M === "0") {
3535
3535
  if (m === "0") {
3536
3536
  ret = ">=" + M + "." + m + "." + p + "-" + pr + " <" + M + "." + m + "." + (+p + 1);
@@ -3541,7 +3541,7 @@ var require_semver2 = __commonJS({
3541
3541
  ret = ">=" + M + "." + m + "." + p + "-" + pr + " <" + (+M + 1) + ".0.0";
3542
3542
  }
3543
3543
  } else {
3544
- debug13("no pr");
3544
+ debug14("no pr");
3545
3545
  if (M === "0") {
3546
3546
  if (m === "0") {
3547
3547
  ret = ">=" + M + "." + m + "." + p + " <" + M + "." + m + "." + (+p + 1);
@@ -3552,12 +3552,12 @@ var require_semver2 = __commonJS({
3552
3552
  ret = ">=" + M + "." + m + "." + p + " <" + (+M + 1) + ".0.0";
3553
3553
  }
3554
3554
  }
3555
- debug13("caret return", ret);
3555
+ debug14("caret return", ret);
3556
3556
  return ret;
3557
3557
  });
3558
3558
  }
3559
3559
  function replaceXRanges(comp, options) {
3560
- debug13("replaceXRanges", comp, options);
3560
+ debug14("replaceXRanges", comp, options);
3561
3561
  return comp.split(/\s+/).map(function(comp2) {
3562
3562
  return replaceXRange(comp2, options);
3563
3563
  }).join(" ");
@@ -3566,7 +3566,7 @@ var require_semver2 = __commonJS({
3566
3566
  comp = comp.trim();
3567
3567
  var r = options.loose ? safeRe[t.XRANGELOOSE] : safeRe[t.XRANGE];
3568
3568
  return comp.replace(r, function(ret, gtlt, M, m, p, pr) {
3569
- debug13("xRange", comp, ret, gtlt, M, m, p, pr);
3569
+ debug14("xRange", comp, ret, gtlt, M, m, p, pr);
3570
3570
  var xM = isX(M);
3571
3571
  var xm = xM || isX(m);
3572
3572
  var xp = xm || isX(p);
@@ -3610,12 +3610,12 @@ var require_semver2 = __commonJS({
3610
3610
  } else if (xp) {
3611
3611
  ret = ">=" + M + "." + m + ".0" + pr + " <" + M + "." + (+m + 1) + ".0" + pr;
3612
3612
  }
3613
- debug13("xRange return", ret);
3613
+ debug14("xRange return", ret);
3614
3614
  return ret;
3615
3615
  });
3616
3616
  }
3617
3617
  function replaceStars(comp, options) {
3618
- debug13("replaceStars", comp, options);
3618
+ debug14("replaceStars", comp, options);
3619
3619
  return comp.trim().replace(safeRe[t.STAR], "");
3620
3620
  }
3621
3621
  function hyphenReplace($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr, tb) {
@@ -3667,7 +3667,7 @@ var require_semver2 = __commonJS({
3667
3667
  }
3668
3668
  if (version2.prerelease.length && !options.includePrerelease) {
3669
3669
  for (i2 = 0; i2 < set.length; i2++) {
3670
- debug13(set[i2].semver);
3670
+ debug14(set[i2].semver);
3671
3671
  if (set[i2].semver === ANY) {
3672
3672
  continue;
3673
3673
  }
@@ -3912,27 +3912,27 @@ var require_process = __commonJS({
3912
3912
  var require_filesystem = __commonJS({
3913
3913
  "../../node_modules/.pnpm/detect-libc@2.1.2/node_modules/detect-libc/lib/filesystem.js"(exports, module2) {
3914
3914
  "use strict";
3915
- var fs16 = require("fs");
3915
+ var fs17 = require("fs");
3916
3916
  var LDD_PATH = "/usr/bin/ldd";
3917
3917
  var SELF_PATH = "/proc/self/exe";
3918
3918
  var MAX_LENGTH = 2048;
3919
3919
  var readFileSync2 = (path) => {
3920
- const fd = fs16.openSync(path, "r");
3920
+ const fd = fs17.openSync(path, "r");
3921
3921
  const buffer = Buffer.alloc(MAX_LENGTH);
3922
- const bytesRead = fs16.readSync(fd, buffer, 0, MAX_LENGTH, 0);
3923
- fs16.close(fd, () => {
3922
+ const bytesRead = fs17.readSync(fd, buffer, 0, MAX_LENGTH, 0);
3923
+ fs17.close(fd, () => {
3924
3924
  });
3925
3925
  return buffer.subarray(0, bytesRead);
3926
3926
  };
3927
3927
  var readFile2 = (path) => new Promise((resolve3, reject) => {
3928
- fs16.open(path, "r", (err, fd) => {
3928
+ fs17.open(path, "r", (err, fd) => {
3929
3929
  if (err) {
3930
3930
  reject(err);
3931
3931
  } else {
3932
3932
  const buffer = Buffer.alloc(MAX_LENGTH);
3933
- fs16.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
3933
+ fs17.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
3934
3934
  resolve3(buffer.subarray(0, bytesRead));
3935
- fs16.close(fd, () => {
3935
+ fs17.close(fd, () => {
3936
3936
  });
3937
3937
  });
3938
3938
  }
@@ -4379,15 +4379,15 @@ __export(src_exports, {
4379
4379
  });
4380
4380
  module.exports = __toCommonJS(src_exports);
4381
4381
  var import_assert = __toESM(require("assert"));
4382
- var import_fs17 = __toESM(require("fs"));
4383
- var import_path17 = require("path");
4382
+ var import_fs18 = __toESM(require("fs"));
4383
+ var import_path18 = require("path");
4384
4384
 
4385
4385
  // src/package-versions.ts
4386
4386
  var VERCEL_RUNTIME_VERSION = "0.16.0";
4387
4387
  var VERCEL_WORKERS_VERSION = "0.0.25";
4388
4388
 
4389
4389
  // src/index.ts
4390
- var import_build_utils20 = require("@vercel/build-utils");
4390
+ var import_build_utils21 = require("@vercel/build-utils");
4391
4391
 
4392
4392
  // src/install.ts
4393
4393
  var import_execa3 = __toESM(require_execa());
@@ -5641,230 +5641,11 @@ async function installRequirementsFile({
5641
5641
  }
5642
5642
 
5643
5643
  // src/dependency-externalizer.ts
5644
- var import_fs6 = __toESM(require("fs"));
5645
- var import_util = require("util");
5646
- var import_path7 = require("path");
5647
- var import_build_utils7 = require("@vercel/build-utils");
5648
- var import_python_analysis3 = require("@vercel/python-analysis");
5649
-
5650
- // src/compileall.ts
5651
- var import_execa4 = __toESM(require_execa());
5652
- var import_build_utils6 = require("@vercel/build-utils");
5653
5644
  var import_fs5 = __toESM(require("fs"));
5645
+ var import_util = require("util");
5654
5646
  var import_path6 = require("path");
5655
- var COMPILEALL_TIMEOUT_MS = 5 * 60 * 1e3;
5656
- var PYCACHE_PREFIX_DIR = "_vc_pycache";
5657
- var RUNTIME_PYCACHE_PREFIX = `/var/task/${PYCACHE_PREFIX_DIR}`;
5658
- function isCompileAllFlagEnabled() {
5659
- const val = process.env.VERCEL_PYTHON_COMPILEALL;
5660
- if (val === void 0 || val === "")
5661
- return false;
5662
- const lower = val.toLowerCase();
5663
- return lower === "1" || lower === "true";
5664
- }
5665
- function shouldCompileAll({
5666
- isDev,
5667
- hasCustomCommand,
5668
- hasPreDeployCommand
5669
- }) {
5670
- if (isDev)
5671
- return false;
5672
- if (hasCustomCommand)
5673
- return false;
5674
- if (hasPreDeployCommand)
5675
- return false;
5676
- return isCompileAllFlagEnabled();
5677
- }
5678
- async function runCompileAll({
5679
- pythonBin,
5680
- filesOrDirectories,
5681
- env,
5682
- excludeRegex,
5683
- pycachePrefix
5684
- }) {
5685
- if (filesOrDirectories.length === 0)
5686
- return;
5687
- const args = [
5688
- "-m",
5689
- "compileall",
5690
- "-q",
5691
- "-j",
5692
- "0",
5693
- "-f",
5694
- "--invalidation-mode",
5695
- "unchecked-hash",
5696
- ...excludeRegex ? ["-x", excludeRegex] : [],
5697
- ...filesOrDirectories
5698
- ];
5699
- const baseEnv = env || process.env;
5700
- const subprocessEnv = pycachePrefix ? { ...baseEnv, PYTHONPYCACHEPREFIX: pycachePrefix } : baseEnv;
5701
- try {
5702
- await (0, import_execa4.default)(pythonBin, args, {
5703
- env: subprocessEnv,
5704
- timeout: COMPILEALL_TIMEOUT_MS
5705
- });
5706
- } catch (err) {
5707
- (0, import_build_utils6.debug)(`compileall error details: ${JSON.stringify(err)}`);
5708
- }
5709
- }
5710
- function derivePycPath(pyRelPath, pythonMajor, pythonMinor) {
5711
- if (!pyRelPath.endsWith(".py"))
5712
- return null;
5713
- const lastSlash = pyRelPath.lastIndexOf("/");
5714
- const dir = lastSlash === -1 ? "" : pyRelPath.slice(0, lastSlash + 1);
5715
- const baseName = pyRelPath.slice(lastSlash + 1, -3);
5716
- return `${dir}__pycache__/${baseName}.cpython-${pythonMajor}${pythonMinor}.pyc`;
5717
- }
5718
- function derivePrefixPycRelPath(pyRelPath, pythonMajor, pythonMinor) {
5719
- if (!pyRelPath.endsWith(".py"))
5720
- return null;
5721
- return `${pyRelPath.slice(0, -3)}.cpython-${pythonMajor}${pythonMinor}.pyc`;
5722
- }
5723
- function stripPycachePrefixRoot(head) {
5724
- const pycachePathSeparators = /* @__PURE__ */ new Set(["/", "\\"]);
5725
- if (head.length > 1 && head[1] === ":" && !pycachePathSeparators.has(head[0])) {
5726
- head = head.slice(2);
5727
- }
5728
- let start = 0;
5729
- while (start < head.length && pycachePathSeparators.has(head[start])) {
5730
- start++;
5731
- }
5732
- return head.slice(start);
5733
- }
5734
- function deriveStagedPycFsPath(stagingDir, srcAbsPath, pythonMajor, pythonMinor) {
5735
- const rel = derivePrefixPycRelPath(
5736
- stripPycachePrefixRoot(srcAbsPath),
5737
- pythonMajor,
5738
- pythonMinor
5739
- );
5740
- if (!rel)
5741
- return null;
5742
- return (0, import_path6.join)(stagingDir, rel.replaceAll("/", import_path6.sep));
5743
- }
5744
- function derivePrefixPycBundlePath(runtimeAbsPath, pythonMajor, pythonMinor) {
5745
- const rel = derivePrefixPycRelPath(
5746
- stripPycachePrefixRoot(runtimeAbsPath),
5747
- pythonMajor,
5748
- pythonMinor
5749
- );
5750
- if (!rel)
5751
- return null;
5752
- return `${PYCACHE_PREFIX_DIR}/${rel}`;
5753
- }
5754
- var COMPILEALL_APP_EXCLUDED_DIRS = [
5755
- ".git",
5756
- ".vercel",
5757
- ".pnpm-store",
5758
- "node_modules",
5759
- ".next",
5760
- ".nuxt",
5761
- ".venv",
5762
- "venv",
5763
- "__pycache__",
5764
- ".mypy_cache",
5765
- ".ruff_cache",
5766
- "public"
5767
- ];
5768
- function escapePythonRegex(value) {
5769
- return value.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
5770
- }
5771
- function getCompileAllAppExcludeRegex(workPath) {
5772
- const excludedDirs = COMPILEALL_APP_EXCLUDED_DIRS.map(escapePythonRegex).join("|");
5773
- return `${escapePythonRegex(workPath)}[/\\\\](?:${excludedDirs})(?:[/\\\\]|$)`;
5774
- }
5775
- async function collectAppPrefixBytecodeFiles({
5776
- stagingDir,
5777
- workPath,
5778
- files: appFiles,
5779
- runtimeTaskRoot,
5780
- pythonMajor,
5781
- pythonMinor
5782
- }) {
5783
- const pending = [];
5784
- for (const bundlePath of Object.keys(appFiles)) {
5785
- if (!bundlePath.endsWith(".py"))
5786
- continue;
5787
- const stagedFsPath = deriveStagedPycFsPath(
5788
- stagingDir,
5789
- (0, import_path6.join)(workPath, bundlePath.replaceAll("/", import_path6.sep)),
5790
- pythonMajor,
5791
- pythonMinor
5792
- );
5793
- const pycBundlePath = derivePrefixPycBundlePath(
5794
- `${runtimeTaskRoot}/${bundlePath}`,
5795
- pythonMajor,
5796
- pythonMinor
5797
- );
5798
- if (!stagedFsPath || !pycBundlePath)
5799
- continue;
5800
- pending.push({ bundlePath: pycBundlePath, srcFsPath: stagedFsPath });
5801
- }
5802
- const results = await Promise.all(
5803
- pending.map(async ({ bundlePath, srcFsPath }) => {
5804
- try {
5805
- const stats = await import_fs5.default.promises.stat(srcFsPath);
5806
- return { bundlePath, srcFsPath, size: stats.size };
5807
- } catch {
5808
- return null;
5809
- }
5810
- })
5811
- );
5812
- const files = {};
5813
- const perItemSizes = /* @__PURE__ */ new Map();
5814
- let totalSize = 0;
5815
- for (const result of results) {
5816
- if (!result)
5817
- continue;
5818
- files[result.bundlePath] = new import_build_utils6.FileFsRef({
5819
- fsPath: result.srcFsPath,
5820
- size: result.size
5821
- });
5822
- perItemSizes.set(result.bundlePath, result.size);
5823
- totalSize += result.size;
5824
- }
5825
- return { files, totalSize, perItemSizes };
5826
- }
5827
- async function collectAppBytecodeFiles({
5828
- workPath,
5829
- files: appFiles,
5830
- pythonMajor,
5831
- pythonMinor
5832
- }) {
5833
- const pending = [];
5834
- for (const bundlePath of Object.keys(appFiles)) {
5835
- const pycRel = derivePycPath(bundlePath, pythonMajor, pythonMinor);
5836
- if (!pycRel)
5837
- continue;
5838
- pending.push({
5839
- bundlePath: pycRel,
5840
- srcFsPath: (0, import_path6.join)(workPath, pycRel.replaceAll("/", import_path6.sep))
5841
- });
5842
- }
5843
- const results = await Promise.all(
5844
- pending.map(async ({ bundlePath, srcFsPath }) => {
5845
- try {
5846
- const stats = await import_fs5.default.promises.stat(srcFsPath);
5847
- return { bundlePath, srcFsPath, size: stats.size };
5848
- } catch {
5849
- return null;
5850
- }
5851
- })
5852
- );
5853
- const files = {};
5854
- const perItemSizes = /* @__PURE__ */ new Map();
5855
- let totalSize = 0;
5856
- for (const result of results) {
5857
- if (!result)
5858
- continue;
5859
- files[result.bundlePath] = new import_build_utils6.FileFsRef({
5860
- fsPath: result.srcFsPath,
5861
- size: result.size
5862
- });
5863
- perItemSizes.set(result.bundlePath, result.size);
5864
- totalSize += result.size;
5865
- }
5866
- return { files, totalSize, perItemSizes };
5867
- }
5647
+ var import_build_utils6 = require("@vercel/build-utils");
5648
+ var import_python_analysis3 = require("@vercel/python-analysis");
5868
5649
 
5869
5650
  // src/large-functions.ts
5870
5651
  function isLargeFunctionsEnabled() {
@@ -5873,24 +5654,7 @@ function isLargeFunctionsEnabled() {
5873
5654
  }
5874
5655
 
5875
5656
  // src/dependency-externalizer.ts
5876
- var readFile = (0, import_util.promisify)(import_fs6.default.readFile);
5877
- var STRIP_BASENAMES = /* @__PURE__ */ new Set([
5878
- "py.typed",
5879
- "WHEEL",
5880
- "INSTALLER",
5881
- "direct_url.json"
5882
- ]);
5883
- function shouldStripVendorFile(filePath) {
5884
- const segments = filePath.split(import_path7.sep);
5885
- if (segments.includes("__pycache__"))
5886
- return true;
5887
- const name = segments[segments.length - 1] ?? "";
5888
- if (name.endsWith(".pyc") || name.endsWith(".pyi"))
5889
- return true;
5890
- if (STRIP_BASENAMES.has(name))
5891
- return true;
5892
- return false;
5893
- }
5657
+ var readFile = (0, import_util.promisify)(import_fs5.default.readFile);
5894
5658
  var LAMBDA_SIZE_THRESHOLD_BYTES = 225 * 1024 * 1024;
5895
5659
  var BYTECODE_FILL_MARGIN_BYTES = 5 * 1024 * 1024;
5896
5660
  var BYTECODE_FILL_CEILING_BYTES = LAMBDA_SIZE_THRESHOLD_BYTES - BYTECODE_FILL_MARGIN_BYTES;
@@ -5898,24 +5662,20 @@ var LAMBDA_EPHEMERAL_STORAGE_BYTES = 500 * 1024 * 1024;
5898
5662
  var EPHEMERAL_INSTALL_BUDGET_BYTES = LAMBDA_EPHEMERAL_STORAGE_BYTES - 50 * 1024 * 1024;
5899
5663
  var RUNTIME_DEPS_DIR = "/tmp/_vc_deps";
5900
5664
  var MAX_LARGE_FUNCTION_UNCOMPRESSED_SIZE = 5 * 1024 * 1024 * 1024;
5665
+ var LARGE_FUNCTION_FILL_CEILING_BYTES = MAX_LARGE_FUNCTION_UNCOMPRESSED_SIZE - BYTECODE_FILL_MARGIN_BYTES;
5901
5666
  var BUNDLING_DOCS_LINK = "https://vercel.com/docs/functions/runtimes/python#controlling-what-gets-bundled";
5902
5667
  var PythonDependencyExternalizer = class {
5903
5668
  constructor(options) {
5904
- // Populated by analyze()
5905
- this.sitePackageDirs = [];
5906
- this.distributions = /* @__PURE__ */ new Map();
5907
5669
  this.allVendorFiles = {};
5908
5670
  this.totalBundleSize = 0;
5909
5671
  this.analyzed = false;
5910
- this.venvPath = options.venvPath;
5672
+ this.installedDistributions = options.installedDistributions;
5911
5673
  this.vendorDir = options.vendorDir;
5912
5674
  this.workPath = options.workPath;
5913
5675
  this.uvLockPath = options.uvLockPath;
5914
5676
  this.uvProjectDir = options.uvProjectDir;
5915
5677
  this.projectName = options.projectName;
5916
- this.pythonMajor = options.pythonMajor;
5917
- this.pythonMinor = options.pythonMinor;
5918
- this.pythonPath = options.pythonPath;
5678
+ this.pythonVersion = options.pythonVersion;
5919
5679
  this.hasCustomCommand = options.hasCustomCommand;
5920
5680
  this.alwaysBundlePackages = options.alwaysBundlePackages ?? [];
5921
5681
  }
@@ -5937,17 +5697,7 @@ var PythonDependencyExternalizer = class {
5937
5697
  * Must be called before generateBundle().
5938
5698
  */
5939
5699
  async analyze(files, options = {}) {
5940
- this.sitePackageDirs = await getVenvSitePackagesDirs(this.venvPath);
5941
- this.distributions = /* @__PURE__ */ new Map();
5942
- for (const dir of this.sitePackageDirs) {
5943
- try {
5944
- await import_fs6.default.promises.access(dir);
5945
- } catch {
5946
- continue;
5947
- }
5948
- this.distributions.set(dir, await (0, import_python_analysis3.scanDistributions)(dir));
5949
- }
5950
- this.allVendorFiles = await this.mirrorPackagesIntoVendor({
5700
+ this.allVendorFiles = await this.installedDistributions.mirrorPackagesIntoVendor({
5951
5701
  vendorDirName: this.vendorDir
5952
5702
  });
5953
5703
  const tempFilesForSizing = { ...files };
@@ -5957,7 +5707,7 @@ var PythonDependencyExternalizer = class {
5957
5707
  this.totalBundleSize = await calculateBundleSize(tempFilesForSizing);
5958
5708
  this.analyzed = true;
5959
5709
  const totalBundleSizeMB = (this.totalBundleSize / (1024 * 1024)).toFixed(2);
5960
- (0, import_build_utils7.debug)(`Total bundle size: ${totalBundleSizeMB} MB`);
5710
+ (0, import_build_utils6.debug)(`Total bundle size: ${totalBundleSizeMB} MB`);
5961
5711
  const runtimeInstallEnabled = this.shouldEnableRuntimeInstall();
5962
5712
  const largeFunctionsEnabled = isLargeFunctionsEnabled();
5963
5713
  options.onSized?.({
@@ -5966,7 +5716,7 @@ var PythonDependencyExternalizer = class {
5966
5716
  });
5967
5717
  if (this.totalBundleSize > LAMBDA_SIZE_THRESHOLD_BYTES && this.hasCustomCommand && !largeFunctionsEnabled) {
5968
5718
  const limitMB = (LAMBDA_SIZE_THRESHOLD_BYTES / (1024 * 1024)).toFixed(0);
5969
- throw new import_build_utils7.NowBuildError({
5719
+ throw new import_build_utils6.NowBuildError({
5970
5720
  code: "LAMBDA_SIZE_EXCEEDED",
5971
5721
  message: `Total bundle size (${totalBundleSizeMB} MB) exceeds the maximum function size (${limitMB} MB).
5972
5722
 
@@ -5981,7 +5731,7 @@ function bundle size automatically. To fix this, you can:
5981
5731
  }
5982
5732
  if (largeFunctionsEnabled && this.totalBundleSize >= MAX_LARGE_FUNCTION_UNCOMPRESSED_SIZE) {
5983
5733
  const limitMB = (MAX_LARGE_FUNCTION_UNCOMPRESSED_SIZE / (1024 * 1024)).toFixed(0);
5984
- throw new import_build_utils7.NowBuildError({
5734
+ throw new import_build_utils6.NowBuildError({
5985
5735
  code: "LAMBDA_SIZE_EXCEEDED",
5986
5736
  message: `Total bundle size (${totalBundleSizeMB} MB) exceeds the extended function size limit (${limitMB} MB).
5987
5737
 
@@ -6027,7 +5777,7 @@ application into smaller functions.`,
6027
5777
  const limitMB = (LAMBDA_EPHEMERAL_STORAGE_BYTES / (1024 * 1024)).toFixed(
6028
5778
  0
6029
5779
  );
6030
- throw new import_build_utils7.NowBuildError({
5780
+ throw new import_build_utils6.NowBuildError({
6031
5781
  code: "LAMBDA_SIZE_EXCEEDED",
6032
5782
  message: `Total bundle size (${totalBundleSizeMB} MB) exceeds the maximum function size (${limitMB} MB).
6033
5783
 
@@ -6037,15 +5787,15 @@ smaller functions.`,
6037
5787
  action: "Learn More"
6038
5788
  });
6039
5789
  }
6040
- const relLockPath = (0, import_path7.relative)(this.workPath, this.uvLockPath);
5790
+ const relLockPath = (0, import_path6.relative)(this.workPath, this.uvLockPath);
6041
5791
  let lockContent;
6042
5792
  try {
6043
5793
  lockContent = await readFile(this.uvLockPath, "utf8");
6044
5794
  } catch (error) {
6045
- (0, import_build_utils7.debug)(
5795
+ (0, import_build_utils6.debug)(
6046
5796
  `Failed to read uv.lock at ${this.uvLockPath}: ${error instanceof Error ? error.message : String(error)}`
6047
5797
  );
6048
- throw new import_build_utils7.NowBuildError({
5798
+ throw new import_build_utils6.NowBuildError({
6049
5799
  code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
6050
5800
  message: `Failed to read the uv.lock file at "${relLockPath}".`
6051
5801
  });
@@ -6056,12 +5806,12 @@ smaller functions.`,
6056
5806
  } catch (error) {
6057
5807
  if (error instanceof import_python_analysis3.PythonAnalysisError) {
6058
5808
  if (error.fileContent) {
6059
- (0, import_build_utils7.debug)(
5809
+ (0, import_build_utils6.debug)(
6060
5810
  `Failed to parse "${error.path}". File content:
6061
5811
  ${error.fileContent}`
6062
5812
  );
6063
5813
  }
6064
- throw new import_build_utils7.NowBuildError({
5814
+ throw new import_build_utils6.NowBuildError({
6065
5815
  code: error.code,
6066
5816
  message: error.message
6067
5817
  });
@@ -6071,7 +5821,7 @@ ${error.fileContent}`
6071
5821
  const excludePackages = [];
6072
5822
  if (this.projectName) {
6073
5823
  excludePackages.push(this.projectName);
6074
- (0, import_build_utils7.debug)(
5824
+ (0, import_build_utils6.debug)(
6075
5825
  `Excluding project package "${this.projectName}" from runtime installation`
6076
5826
  );
6077
5827
  }
@@ -6079,7 +5829,7 @@ ${error.fileContent}`
6079
5829
  lockFile,
6080
5830
  excludePackages
6081
5831
  });
6082
- (0, import_build_utils7.debug)(
5832
+ (0, import_build_utils6.debug)(
6083
5833
  `Package classification: ${classification.privatePackages.length} private, ${classification.publicPackages.length} public`
6084
5834
  );
6085
5835
  const forceBundledDueToWheels = await this.findPackagesWithoutCompatibleWheels(
@@ -6101,7 +5851,7 @@ ${error.fileContent}`
6101
5851
  if (largeFunctionsEnabled) {
6102
5852
  return this.bundleAllForHive(files);
6103
5853
  }
6104
- throw new import_build_utils7.NowBuildError({
5854
+ throw new import_build_utils6.NowBuildError({
6105
5855
  code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
6106
5856
  message: `Total bundle size (${totalBundleSizeMB} MB) exceeds the maximum function size and
6107
5857
  can't be optimized automatically because some dependencies don't
@@ -6112,7 +5862,7 @@ To fix this, either:
6112
5862
  2. Replace the packages that don't provide a pre-built wheel.`
6113
5863
  });
6114
5864
  }
6115
- const packageSizes = await this.calculatePerPackageSizes();
5865
+ const packageSizes = await this.installedDistributions.calculatePerPackageSizes();
6116
5866
  const alwaysBundled = [
6117
5867
  ...classification.privatePackages,
6118
5868
  "vercel-runtime",
@@ -6120,7 +5870,7 @@ To fix this, either:
6120
5870
  ...this.alwaysBundlePackages,
6121
5871
  ...forceBundledDueToWheels
6122
5872
  ];
6123
- const alwaysBundledFiles = await this.mirrorPackagesIntoVendor({
5873
+ const alwaysBundledFiles = await this.installedDistributions.mirrorPackagesIntoVendor({
6124
5874
  vendorDirName: this.vendorDir,
6125
5875
  includePackages: alwaysBundled
6126
5876
  });
@@ -6132,26 +5882,26 @@ To fix this, either:
6132
5882
  let runtimeToolingOverhead = 0;
6133
5883
  try {
6134
5884
  const uvBinaryPath = await this.resolveUvBinaryForBundling();
6135
- const uvStats = await import_fs6.default.promises.stat(uvBinaryPath);
5885
+ const uvStats = await import_fs5.default.promises.stat(uvBinaryPath);
6136
5886
  runtimeToolingOverhead = uvStats.size;
6137
5887
  } catch {
6138
5888
  runtimeToolingOverhead = 50 * 1024 * 1024;
6139
5889
  }
6140
5890
  runtimeToolingOverhead += 4 * 1024;
6141
- const projectDirRel = (0, import_path7.relative)(this.workPath, this.uvProjectDir);
6142
- const uvLockRel = (0, import_path7.relative)(this.workPath, this.uvLockPath);
5891
+ const projectDirRel = (0, import_path6.relative)(this.workPath, this.uvProjectDir);
5892
+ const uvLockRel = (0, import_path6.relative)(this.workPath, this.uvLockPath);
6143
5893
  const isOutsideWorkPath = projectDirRel.startsWith("..") || uvLockRel.startsWith("..");
6144
5894
  if (isOutsideWorkPath) {
6145
- const pyprojectPath = (0, import_path7.join)(this.uvProjectDir, "pyproject.toml");
6146
- const pyprojectStats = await import_fs6.default.promises.stat(pyprojectPath).catch(() => null);
6147
- const uvLockStats = await import_fs6.default.promises.stat(this.uvLockPath).catch(() => null);
5895
+ const pyprojectPath = (0, import_path6.join)(this.uvProjectDir, "pyproject.toml");
5896
+ const pyprojectStats = await import_fs5.default.promises.stat(pyprojectPath).catch(() => null);
5897
+ const uvLockStats = await import_fs5.default.promises.stat(this.uvLockPath).catch(() => null);
6148
5898
  if (pyprojectStats)
6149
5899
  runtimeToolingOverhead += pyprojectStats.size;
6150
5900
  if (uvLockStats)
6151
5901
  runtimeToolingOverhead += uvLockStats.size;
6152
5902
  }
6153
5903
  const remainingCapacity = LAMBDA_SIZE_THRESHOLD_BYTES - fixedOverhead - runtimeToolingOverhead;
6154
- (0, import_build_utils7.debug)(
5904
+ (0, import_build_utils6.debug)(
6155
5905
  `Fixed overhead: ${(fixedOverhead / (1024 * 1024)).toFixed(2)} MB, runtime tooling: ${(runtimeToolingOverhead / (1024 * 1024)).toFixed(2)} MB, remaining capacity for public packages: ${(remainingCapacity / (1024 * 1024)).toFixed(2)} MB`
6156
5906
  );
6157
5907
  if (largeFunctionsEnabled && remainingCapacity < 0) {
@@ -6174,7 +5924,7 @@ To fix this, either:
6174
5924
  bytecodeFirst: options.bytecodeFirst ?? false
6175
5925
  });
6176
5926
  if (options.bytecodeFirst && packingMode === "knapsack") {
6177
- (0, import_build_utils7.debug)(
5927
+ (0, import_build_utils6.debug)(
6178
5928
  `bytecode-first packing disabled: the public package set exceeds the ephemeral install budget (${(EPHEMERAL_INSTALL_BUDGET_BYTES / (1024 * 1024)).toFixed(2)} MB); falling back to knapsack packing`
6179
5929
  );
6180
5930
  }
@@ -6183,7 +5933,7 @@ To fix this, either:
6183
5933
  (name) => !bundledPublicSet.has((0, import_python_analysis3.normalizePackageName)(name))
6184
5934
  );
6185
5935
  const allBundledPackages = [...alwaysBundled, ...bundledPublic];
6186
- const selectedVendorFiles = await this.mirrorPackagesIntoVendor({
5936
+ const selectedVendorFiles = await this.installedDistributions.mirrorPackagesIntoVendor({
6187
5937
  vendorDirName: this.vendorDir,
6188
5938
  includePackages: allBundledPackages
6189
5939
  });
@@ -6197,11 +5947,11 @@ To fix this, either:
6197
5947
  ...forceBundledDueToWheels
6198
5948
  ];
6199
5949
  if (isOutsideWorkPath) {
6200
- const srcPyproject = (0, import_path7.join)(this.uvProjectDir, "pyproject.toml");
6201
- files[`${UV_BUNDLE_DIR}/pyproject.toml`] = new import_build_utils7.FileFsRef({
5950
+ const srcPyproject = (0, import_path6.join)(this.uvProjectDir, "pyproject.toml");
5951
+ files[`${UV_BUNDLE_DIR}/pyproject.toml`] = new import_build_utils6.FileFsRef({
6202
5952
  fsPath: srcPyproject
6203
5953
  });
6204
- files[`${UV_BUNDLE_DIR}/uv.lock`] = new import_build_utils7.FileFsRef({
5954
+ files[`${UV_BUNDLE_DIR}/uv.lock`] = new import_build_utils6.FileFsRef({
6205
5955
  fsPath: this.uvLockPath
6206
5956
  });
6207
5957
  }
@@ -6209,27 +5959,27 @@ To fix this, either:
6209
5959
  projectDir: isOutsideWorkPath ? UV_BUNDLE_DIR : projectDirRel,
6210
5960
  bundledPackages: bundledPackagesForConfig
6211
5961
  });
6212
- files[`${UV_BUNDLE_DIR}/_runtime_config.json`] = new import_build_utils7.FileBlob({
5962
+ files[`${UV_BUNDLE_DIR}/_runtime_config.json`] = new import_build_utils6.FileBlob({
6213
5963
  data: runtimeConfigData
6214
5964
  });
6215
5965
  try {
6216
5966
  const uvBinaryPath = await this.resolveUvBinaryForBundling();
6217
- const uvBundleDir = (0, import_path7.join)(this.workPath, UV_BUNDLE_DIR);
6218
- const uvLocalPath = (0, import_path7.join)(uvBundleDir, "uv");
6219
- await import_fs6.default.promises.mkdir(uvBundleDir, { recursive: true });
6220
- await import_fs6.default.promises.copyFile(uvBinaryPath, uvLocalPath);
6221
- await import_fs6.default.promises.chmod(uvLocalPath, 493);
5967
+ const uvBundleDir = (0, import_path6.join)(this.workPath, UV_BUNDLE_DIR);
5968
+ const uvLocalPath = (0, import_path6.join)(uvBundleDir, "uv");
5969
+ await import_fs5.default.promises.mkdir(uvBundleDir, { recursive: true });
5970
+ await import_fs5.default.promises.copyFile(uvBinaryPath, uvLocalPath);
5971
+ await import_fs5.default.promises.chmod(uvLocalPath, 493);
6222
5972
  const uvBundlePath = `${UV_BUNDLE_DIR}/uv`;
6223
- files[uvBundlePath] = new import_build_utils7.FileFsRef({
5973
+ files[uvBundlePath] = new import_build_utils6.FileFsRef({
6224
5974
  fsPath: uvLocalPath,
6225
5975
  mode: 33261
6226
5976
  });
6227
- (0, import_build_utils7.debug)(`Bundled uv binary from ${uvBinaryPath} to ${uvLocalPath}`);
5977
+ (0, import_build_utils6.debug)(`Bundled uv binary from ${uvBinaryPath} to ${uvLocalPath}`);
6228
5978
  } catch (err) {
6229
- (0, import_build_utils7.debug)(
5979
+ (0, import_build_utils6.debug)(
6230
5980
  `Failed to bundle uv binary: ${err instanceof Error ? err.message : String(err)}`
6231
5981
  );
6232
- throw new import_build_utils7.NowBuildError({
5982
+ throw new import_build_utils6.NowBuildError({
6233
5983
  code: "RUNTIME_DEPENDENCY_INSTALLATION_FAILED",
6234
5984
  message: "Failed to prepare dependency tooling."
6235
5985
  });
@@ -6241,7 +5991,7 @@ To fix this, either:
6241
5991
  }
6242
5992
  const finalSizeMB = (finalBundleSize / (1024 * 1024)).toFixed(2);
6243
5993
  const limitMB = (LAMBDA_SIZE_THRESHOLD_BYTES / (1024 * 1024)).toFixed(0);
6244
- throw new import_build_utils7.NowBuildError({
5994
+ throw new import_build_utils6.NowBuildError({
6245
5995
  code: "LAMBDA_SIZE_EXCEEDED",
6246
5996
  message: `Total bundle size (${finalSizeMB} MB) exceeds the maximum function size (${limitMB} MB) even after
6247
5997
  optimizing dependencies.
@@ -6278,7 +6028,7 @@ functions.`,
6278
6028
  for (const [p, f] of Object.entries(this.allVendorFiles)) {
6279
6029
  files[p] = f;
6280
6030
  }
6281
- (0, import_build_utils7.debug)("Bundling all dependencies for the large functions path.");
6031
+ (0, import_build_utils6.debug)("Bundling all dependencies for the large functions path.");
6282
6032
  return { fellBackToFullBundle: true };
6283
6033
  }
6284
6034
  /**
@@ -6293,15 +6043,15 @@ functions.`,
6293
6043
  */
6294
6044
  async findPackagesWithoutCompatibleWheels(lockFile, publicPackageNames) {
6295
6045
  const platform = detectTargetPlatform();
6296
- if (this.pythonMajor === void 0 || this.pythonMinor === void 0) {
6297
- (0, import_build_utils7.debug)("Skipping wheel compatibility check: dev mode");
6046
+ if (this.pythonVersion.major === void 0 || this.pythonVersion.minor === void 0) {
6047
+ (0, import_build_utils6.debug)("Skipping wheel compatibility check: dev mode");
6298
6048
  return [];
6299
6049
  }
6300
6050
  const reachable = await getPackagesReachableOnPlatform(
6301
6051
  lockFile,
6302
6052
  this.projectName,
6303
- this.pythonMajor,
6304
- this.pythonMinor,
6053
+ this.pythonVersion.major,
6054
+ this.pythonVersion.minor,
6305
6055
  platform.sysPlatform,
6306
6056
  platform.archName
6307
6057
  );
@@ -6309,7 +6059,7 @@ functions.`,
6309
6059
  (name) => reachable.has((0, import_python_analysis3.normalizePackageName)(name))
6310
6060
  ) : publicPackageNames;
6311
6061
  if (relevantPackages.length < publicPackageNames.length) {
6312
- (0, import_build_utils7.debug)(
6062
+ (0, import_build_utils6.debug)(
6313
6063
  `Skipping wheel check for ${publicPackageNames.length - relevantPackages.length} package(s) not reachable on the target platform`
6314
6064
  );
6315
6065
  }
@@ -6337,8 +6087,8 @@ functions.`,
6337
6087
  try {
6338
6088
  const compatible = await (0, import_python_analysis3.isWheelCompatible)(
6339
6089
  filename,
6340
- this.pythonMajor,
6341
- this.pythonMinor,
6090
+ this.pythonVersion.major,
6091
+ this.pythonVersion.minor,
6342
6092
  platform.osName,
6343
6093
  platform.archName,
6344
6094
  platform.osMajor,
@@ -6349,7 +6099,7 @@ functions.`,
6349
6099
  break;
6350
6100
  }
6351
6101
  } catch (err) {
6352
- (0, import_build_utils7.debug)(
6102
+ (0, import_build_utils6.debug)(
6353
6103
  `Failed to check wheel compatibility for ${filename}: ${err instanceof Error ? err.message : String(err)}`
6354
6104
  );
6355
6105
  }
@@ -6363,301 +6113,12 @@ functions.`,
6363
6113
  /** Resolve the uv binary for bundling (host binary on build image, downloaded on local). */
6364
6114
  async resolveUvBinaryForBundling() {
6365
6115
  if (process.env.VERCEL_BUILD_IMAGE) {
6366
- return getUvBinaryForBundling(this.pythonPath);
6116
+ return getUvBinaryForBundling(this.pythonVersion.pythonPath);
6367
6117
  }
6368
6118
  return downloadUvBinaryForTarget(
6369
- (0, import_path7.join)(this.workPath, ".vercel", "python", "cache")
6119
+ (0, import_path6.join)(this.workPath, ".vercel", "python", "cache")
6370
6120
  );
6371
6121
  }
6372
- /**
6373
- * Mirror packages from site-packages into the _vendor directory.
6374
- *
6375
- * When `includePackages` is provided, only distributions whose normalized
6376
- * name is in the list are included. When omitted, every distribution is
6377
- * included.
6378
- *
6379
- * Reads `this.sitePackageDirs` and `this.distributions` which are
6380
- * resolved once at the start of `analyze()`.
6381
- */
6382
- async mirrorPackagesIntoVendor({
6383
- vendorDirName,
6384
- includePackages
6385
- }) {
6386
- const vendorFiles = {};
6387
- if (includePackages && includePackages.length === 0) {
6388
- return vendorFiles;
6389
- }
6390
- const includeSet = includePackages ? new Set(includePackages.map(import_python_analysis3.normalizePackageName)) : null;
6391
- const pending = [];
6392
- for (const dir of this.sitePackageDirs) {
6393
- const dirDistributions = this.distributions.get(dir);
6394
- if (!dirDistributions)
6395
- continue;
6396
- const resolvedDir = (0, import_path7.resolve)(dir);
6397
- const dirPrefix = resolvedDir + import_path7.sep;
6398
- for (const [name, dist] of dirDistributions) {
6399
- if (includeSet && !includeSet.has(name))
6400
- continue;
6401
- for (const { path: rawPath, size: recordSize } of dist.files) {
6402
- const filePath = rawPath.replaceAll("/", import_path7.sep);
6403
- if (!(0, import_path7.resolve)(resolvedDir, filePath).startsWith(dirPrefix)) {
6404
- continue;
6405
- }
6406
- if (shouldStripVendorFile(filePath)) {
6407
- continue;
6408
- }
6409
- const srcFsPath = (0, import_path7.join)(dir, filePath);
6410
- const bundlePath = (0, import_path7.join)(vendorDirName, filePath).replace(/\\/g, "/");
6411
- pending.push({
6412
- bundlePath,
6413
- srcFsPath,
6414
- // RECORD sizes are bigint; convert to number for FileFsRef.
6415
- recordSize: recordSize !== void 0 && recordSize !== null ? Number(recordSize) : void 0
6416
- });
6417
- }
6418
- }
6419
- }
6420
- const results = await Promise.all(
6421
- pending.map(async ({ bundlePath, srcFsPath, recordSize }) => {
6422
- if (recordSize !== void 0) {
6423
- try {
6424
- await import_fs6.default.promises.access(srcFsPath);
6425
- return { bundlePath, srcFsPath, size: recordSize };
6426
- } catch {
6427
- return null;
6428
- }
6429
- } else {
6430
- try {
6431
- const stats = await import_fs6.default.promises.stat(srcFsPath);
6432
- return { bundlePath, srcFsPath, size: stats.size };
6433
- } catch {
6434
- return null;
6435
- }
6436
- }
6437
- })
6438
- );
6439
- for (const result of results) {
6440
- if (result) {
6441
- vendorFiles[result.bundlePath] = new import_build_utils7.FileFsRef({
6442
- fsPath: result.srcFsPath,
6443
- size: result.size
6444
- });
6445
- }
6446
- }
6447
- (0, import_build_utils7.debug)(
6448
- `Mirrored ${Object.keys(vendorFiles).length} files` + (includePackages ? ` from ${includePackages.length} packages` : "")
6449
- );
6450
- return vendorFiles;
6451
- }
6452
- /**
6453
- * Calculate the uncompressed size of each installed distribution.
6454
- *
6455
- * Returns a map of normalized package name to total size in bytes.
6456
- * Uses RECORD sizes when available, falling back to stat for files
6457
- * without a recorded size. All stat calls run in parallel.
6458
- */
6459
- async calculatePerPackageSizes() {
6460
- const sizes = /* @__PURE__ */ new Map();
6461
- for (const dir of this.sitePackageDirs) {
6462
- const dirDistributions = this.distributions.get(dir);
6463
- if (!dirDistributions)
6464
- continue;
6465
- const resolvedDir = (0, import_path7.resolve)(dir);
6466
- const dirPrefix = resolvedDir + import_path7.sep;
6467
- for (const [name, dist] of dirDistributions) {
6468
- let knownSize = 0;
6469
- const statPromises = [];
6470
- for (const { path: rawPath, size: recordSize } of dist.files) {
6471
- const filePath = rawPath.replaceAll("/", import_path7.sep);
6472
- if (!(0, import_path7.resolve)(resolvedDir, filePath).startsWith(dirPrefix)) {
6473
- continue;
6474
- }
6475
- if (shouldStripVendorFile(filePath)) {
6476
- continue;
6477
- }
6478
- if (recordSize !== void 0 && recordSize !== null) {
6479
- knownSize += Number(recordSize);
6480
- } else {
6481
- statPromises.push(
6482
- import_fs6.default.promises.stat((0, import_path7.join)(dir, filePath)).then((stats) => stats.size).catch(() => 0)
6483
- );
6484
- }
6485
- }
6486
- const statSizes = await Promise.all(statPromises);
6487
- let totalSize = knownSize;
6488
- for (const s of statSizes) {
6489
- totalSize += s;
6490
- }
6491
- sizes.set(name, totalSize);
6492
- }
6493
- }
6494
- return sizes;
6495
- }
6496
- /**
6497
- * Collect pre-compiled `.pyc` bytecode files for vendor packages.
6498
- *
6499
- * For each `.py` file listed in a package's RECORD, derives the expected
6500
- * `__pycache__/*.cpython-XY.pyc` path and checks whether it exists on
6501
- * disk (i.e. whether `compileall` produced it). Files that do not exist
6502
- * are silently skipped.
6503
- *
6504
- * Must be called after `analyze()` which populates `sitePackageDirs` and
6505
- * `distributions`.
6506
- */
6507
- async collectBytecodeFiles({
6508
- vendorDirName,
6509
- includePackages
6510
- }) {
6511
- if (!this.sitePackageDirs || !this.distributions) {
6512
- throw new Error("collectBytecodeFiles() must be called after analyze()");
6513
- }
6514
- if (this.pythonMajor == null || this.pythonMinor == null) {
6515
- return { files: {}, totalSize: 0, perItemSizes: /* @__PURE__ */ new Map() };
6516
- }
6517
- const includeSet = includePackages ? new Set(includePackages.map(import_python_analysis3.normalizePackageName)) : null;
6518
- const pending = [];
6519
- for (const dir of this.sitePackageDirs) {
6520
- const dirDistributions = this.distributions.get(dir);
6521
- if (!dirDistributions)
6522
- continue;
6523
- for (const [name, dist] of dirDistributions) {
6524
- if (includeSet && !includeSet.has(name))
6525
- continue;
6526
- for (const { path: rawPath } of dist.files) {
6527
- const pycRel = derivePycPath(
6528
- rawPath,
6529
- this.pythonMajor,
6530
- this.pythonMinor
6531
- );
6532
- if (!pycRel)
6533
- continue;
6534
- const pycFilePath = pycRel.replaceAll("/", import_path7.sep);
6535
- const srcFsPath = (0, import_path7.join)(dir, pycFilePath);
6536
- const bundlePath = (0, import_path7.join)(vendorDirName, pycFilePath).replace(
6537
- /\\/g,
6538
- "/"
6539
- );
6540
- pending.push({ bundlePath, srcFsPath, packageName: name });
6541
- }
6542
- }
6543
- }
6544
- const results = await Promise.all(
6545
- pending.map(async ({ bundlePath, srcFsPath, packageName }) => {
6546
- try {
6547
- const stats = await import_fs6.default.promises.stat(srcFsPath);
6548
- return { bundlePath, srcFsPath, size: stats.size, packageName };
6549
- } catch {
6550
- return null;
6551
- }
6552
- })
6553
- );
6554
- const files = {};
6555
- let totalSize = 0;
6556
- const perItemSizes = /* @__PURE__ */ new Map();
6557
- for (const result of results) {
6558
- if (!result)
6559
- continue;
6560
- files[result.bundlePath] = new import_build_utils7.FileFsRef({
6561
- fsPath: result.srcFsPath,
6562
- size: result.size
6563
- });
6564
- totalSize += result.size;
6565
- perItemSizes.set(
6566
- result.packageName,
6567
- (perItemSizes.get(result.packageName) ?? 0) + result.size
6568
- );
6569
- }
6570
- (0, import_build_utils7.debug)(
6571
- `Collected ${Object.keys(files).length} bytecode files (${(totalSize / (1024 * 1024)).toFixed(2)} MB)` + (includePackages ? ` from ${includePackages.length} packages` : "")
6572
- );
6573
- return { files, totalSize, perItemSizes };
6574
- }
6575
- /**
6576
- * Collect staged prefix `.pyc` files for vendor packages, keyed under
6577
- * `_vc_pycache/<runtimeRoot>/...` (`runtimeRoot` = `/var/task/_vendor`
6578
- * for bundled packages, the /tmp site-packages dir for externalized
6579
- * ones). Missing staged files are silently skipped. Must be called after
6580
- * `analyze()`.
6581
- */
6582
- async collectPrefixBytecodeFiles({
6583
- stagingDir,
6584
- runtimeRoot,
6585
- includePackages
6586
- }) {
6587
- if (!this.sitePackageDirs || !this.distributions) {
6588
- throw new Error(
6589
- "collectPrefixBytecodeFiles() must be called after analyze()"
6590
- );
6591
- }
6592
- if (this.pythonMajor == null || this.pythonMinor == null) {
6593
- return { files: {}, totalSize: 0, perItemSizes: /* @__PURE__ */ new Map() };
6594
- }
6595
- const includeSet = includePackages ? new Set(includePackages.map(import_python_analysis3.normalizePackageName)) : null;
6596
- const pending = [];
6597
- for (const dir of this.sitePackageDirs) {
6598
- const dirDistributions = this.distributions.get(dir);
6599
- if (!dirDistributions)
6600
- continue;
6601
- const resolvedDir = (0, import_path7.resolve)(dir);
6602
- const dirPrefix = resolvedDir + import_path7.sep;
6603
- for (const [name, dist] of dirDistributions) {
6604
- if (includeSet && !includeSet.has(name))
6605
- continue;
6606
- for (const { path: rawPath } of dist.files) {
6607
- if (!rawPath.endsWith(".py"))
6608
- continue;
6609
- const filePath = rawPath.replaceAll("/", import_path7.sep);
6610
- if (!(0, import_path7.resolve)(resolvedDir, filePath).startsWith(dirPrefix)) {
6611
- continue;
6612
- }
6613
- const srcFsPath = deriveStagedPycFsPath(
6614
- stagingDir,
6615
- (0, import_path7.join)(dir, filePath),
6616
- this.pythonMajor,
6617
- this.pythonMinor
6618
- );
6619
- const bundlePath = derivePrefixPycBundlePath(
6620
- `${runtimeRoot}/${rawPath}`,
6621
- this.pythonMajor,
6622
- this.pythonMinor
6623
- );
6624
- if (!srcFsPath || !bundlePath)
6625
- continue;
6626
- pending.push({ bundlePath, srcFsPath, packageName: name });
6627
- }
6628
- }
6629
- }
6630
- const results = await Promise.all(
6631
- pending.map(async ({ bundlePath, srcFsPath, packageName }) => {
6632
- try {
6633
- const stats = await import_fs6.default.promises.stat(srcFsPath);
6634
- return { bundlePath, srcFsPath, size: stats.size, packageName };
6635
- } catch {
6636
- return null;
6637
- }
6638
- })
6639
- );
6640
- const files = {};
6641
- let totalSize = 0;
6642
- const perItemSizes = /* @__PURE__ */ new Map();
6643
- for (const result of results) {
6644
- if (!result)
6645
- continue;
6646
- files[result.bundlePath] = new import_build_utils7.FileFsRef({
6647
- fsPath: result.srcFsPath,
6648
- size: result.size
6649
- });
6650
- totalSize += result.size;
6651
- perItemSizes.set(
6652
- result.packageName,
6653
- (perItemSizes.get(result.packageName) ?? 0) + result.size
6654
- );
6655
- }
6656
- (0, import_build_utils7.debug)(
6657
- `Collected ${Object.keys(files).length} prefix bytecode files (${(totalSize / (1024 * 1024)).toFixed(2)} MB) for runtime root ${runtimeRoot}` + (includePackages ? ` from ${includePackages.length} packages` : "")
6658
- );
6659
- return { files, totalSize, perItemSizes };
6660
- }
6661
6122
  };
6662
6123
  async function getPackagesReachableOnPlatform(lockFile, projectName, pythonMajor, pythonMinor, sysPlatform, platformMachine) {
6663
6124
  if (!projectName)
@@ -6690,13 +6151,13 @@ async function getPackagesReachableOnPlatform(lockFile, projectName, pythonMajor
6690
6151
  platformMachine
6691
6152
  );
6692
6153
  if (!compatible) {
6693
- (0, import_build_utils7.debug)(
6154
+ (0, import_build_utils6.debug)(
6694
6155
  `Skipping dependency ${dep.name}: marker "${dep.marker}" not satisfied on ${sysPlatform}`
6695
6156
  );
6696
6157
  continue;
6697
6158
  }
6698
6159
  } catch (err) {
6699
- (0, import_build_utils7.debug)(
6160
+ (0, import_build_utils6.debug)(
6700
6161
  `Failed to evaluate marker "${dep.marker}" for ${dep.name}, including conservatively: ${err instanceof Error ? err.message : String(err)}`
6701
6162
  );
6702
6163
  }
@@ -6730,7 +6191,7 @@ async function calculateBundleSize(files, filter) {
6730
6191
  knownSize += fsRef.size;
6731
6192
  } else {
6732
6193
  statPromises.push(
6733
- import_fs6.default.promises.stat(fsRef.fsPath).then((stats) => {
6194
+ import_fs5.default.promises.stat(fsRef.fsPath).then((stats) => {
6734
6195
  fsRef.size = stats.size;
6735
6196
  return stats.size;
6736
6197
  }).catch((err) => {
@@ -6753,12 +6214,6 @@ async function calculateBundleSize(files, filter) {
6753
6214
  }
6754
6215
  return totalSize;
6755
6216
  }
6756
- var PYC_TO_PY_RATIO = 1.2;
6757
- var BYTECODE_COVERAGE_FLOOR = 0.5;
6758
- async function estimateBytecodeSize(files) {
6759
- const pyBytes = await calculateBundleSize(files, (p) => p.endsWith(".py"));
6760
- return PYC_TO_PY_RATIO * pyBytes;
6761
- }
6762
6217
  function lambdaKnapsack(packages, capacity) {
6763
6218
  if (capacity <= 0) {
6764
6219
  return [];
@@ -6793,8 +6248,8 @@ function planPublicPackagePacking({
6793
6248
  }
6794
6249
 
6795
6250
  // src/diagnostics.ts
6796
- var import_fs7 = __toESM(require("fs"));
6797
- var import_build_utils8 = require("@vercel/build-utils");
6251
+ var import_fs6 = __toESM(require("fs"));
6252
+ var import_build_utils7 = require("@vercel/build-utils");
6798
6253
  var import_python_analysis4 = require("@vercel/python-analysis");
6799
6254
  function isDependencyGroupInclude(entry) {
6800
6255
  return typeof entry === "object" && "include-group" in entry;
@@ -6908,7 +6363,7 @@ async function generateProjectManifest({
6908
6363
  const directEntries = [];
6909
6364
  const transitiveEntries = [];
6910
6365
  {
6911
- const content = await import_fs7.default.promises.readFile(uvLockPath, "utf-8");
6366
+ const content = await import_fs6.default.promises.readFile(uvLockPath, "utf-8");
6912
6367
  const uvLock = (0, import_python_analysis4.parseUvLock)(content, uvLockPath);
6913
6368
  const projectName = project?.name;
6914
6369
  const excludeSet = new Set(
@@ -6999,7 +6454,7 @@ async function generateProjectManifest({
6999
6454
  }
7000
6455
  }
7001
6456
  const manifest = {
7002
- version: import_build_utils8.MANIFEST_VERSION,
6457
+ version: import_build_utils7.MANIFEST_VERSION,
7003
6458
  runtime: "python",
7004
6459
  ...framework ? { framework } : {},
7005
6460
  ...serviceType ? { serviceType } : {},
@@ -7013,22 +6468,22 @@ async function generateProjectManifest({
7013
6468
  ...transitiveEntries.sort((a, b) => a.name.localeCompare(b.name))
7014
6469
  ]
7015
6470
  };
7016
- await (0, import_build_utils8.writeProjectManifest)(manifest, workPath, "python");
6471
+ await (0, import_build_utils7.writeProjectManifest)(manifest, workPath, "python");
7017
6472
  }
7018
- var diagnostics = (0, import_build_utils8.createDiagnostics)("python");
6473
+ var diagnostics = (0, import_build_utils7.createDiagnostics)("python");
7019
6474
 
7020
6475
  // src/crons.ts
7021
- var import_fs9 = __toESM(require("fs"));
7022
- var import_path9 = require("path");
7023
- var import_execa5 = __toESM(require_execa());
7024
- var import_build_utils12 = require("@vercel/build-utils");
7025
-
7026
- // src/entrypoint.ts
7027
6476
  var import_fs8 = __toESM(require("fs"));
7028
6477
  var import_path8 = require("path");
6478
+ var import_execa4 = __toESM(require_execa());
6479
+ var import_build_utils11 = require("@vercel/build-utils");
6480
+
6481
+ // src/entrypoint.ts
6482
+ var import_fs7 = __toESM(require("fs"));
6483
+ var import_path7 = require("path");
6484
+ var import_build_utils8 = require("@vercel/build-utils");
7029
6485
  var import_build_utils9 = require("@vercel/build-utils");
7030
6486
  var import_build_utils10 = require("@vercel/build-utils");
7031
- var import_build_utils11 = require("@vercel/build-utils");
7032
6487
  var import_python_analysis5 = require("@vercel/python-analysis");
7033
6488
  var PYTHON_ENTRYPOINT_FILENAMES = [
7034
6489
  "app",
@@ -7047,13 +6502,13 @@ var SKIP_DIRS = /* @__PURE__ */ new Set(["__pycache__", "node_modules"]);
7047
6502
  function getCandidateEntrypointsInDirs(dirs) {
7048
6503
  return dirs.flatMap(
7049
6504
  (dir) => PYTHON_ENTRYPOINT_FILENAMES.map(
7050
- (filename) => import_path8.posix.join(dir, `${filename}.py`)
6505
+ (filename) => import_path7.posix.join(dir, `${filename}.py`)
7051
6506
  )
7052
6507
  );
7053
6508
  }
7054
6509
  async function fileExists(filePath) {
7055
6510
  try {
7056
- const stat = await import_fs8.default.promises.stat(filePath);
6511
+ const stat = await import_fs7.default.promises.stat(filePath);
7057
6512
  return stat.isFile();
7058
6513
  } catch {
7059
6514
  return false;
@@ -7108,28 +6563,28 @@ function entrypointToModule(entrypoint) {
7108
6563
  return entrypoint.replace(/\\/g, "/").replace(/\.py$/i, "").replace(/\/__init__$/i, "").replace(/\//g, ".");
7109
6564
  }
7110
6565
  async function checkEntrypoint(workPath, relPath) {
7111
- const absPath = (0, import_path8.join)(workPath, relPath);
6566
+ const absPath = (0, import_path7.join)(workPath, relPath);
7112
6567
  if (!await fileExists(absPath))
7113
6568
  return null;
7114
- const content = await import_fs8.default.promises.readFile(absPath, "utf-8");
6569
+ const content = await import_fs7.default.promises.readFile(absPath, "utf-8");
7115
6570
  return (0, import_python_analysis5.findAppOrHandler)(content);
7116
6571
  }
7117
6572
  async function findPythonFilesRecursive(dir, rootDir) {
7118
6573
  const results = [];
7119
6574
  let entries;
7120
6575
  try {
7121
- entries = await import_fs8.default.promises.readdir(dir, { withFileTypes: true });
6576
+ entries = await import_fs7.default.promises.readdir(dir, { withFileTypes: true });
7122
6577
  } catch {
7123
6578
  return results;
7124
6579
  }
7125
6580
  for (const entry of entries) {
7126
6581
  if (entry.name.startsWith(".") || SKIP_DIRS.has(entry.name))
7127
6582
  continue;
7128
- const fullPath = (0, import_path8.join)(dir, entry.name);
6583
+ const fullPath = (0, import_path7.join)(dir, entry.name);
7129
6584
  if (entry.isDirectory()) {
7130
6585
  results.push(...await findPythonFilesRecursive(fullPath, rootDir));
7131
6586
  } else if (entry.isFile() && entry.name.endsWith(".py")) {
7132
- results.push((0, import_path8.relative)(rootDir, fullPath).replace(/\\/g, "/"));
6587
+ results.push((0, import_path7.relative)(rootDir, fullPath).replace(/\\/g, "/"));
7133
6588
  }
7134
6589
  }
7135
6590
  return results;
@@ -7139,8 +6594,8 @@ async function findEntrypointCandidates(workPath) {
7139
6594
  const candidates = [];
7140
6595
  for (const relPath of pyFiles) {
7141
6596
  try {
7142
- const content = await import_fs8.default.promises.readFile(
7143
- (0, import_path8.join)(workPath, relPath),
6597
+ const content = await import_fs7.default.promises.readFile(
6598
+ (0, import_path7.join)(workPath, relPath),
7144
6599
  "utf-8"
7145
6600
  );
7146
6601
  const varName = await (0, import_python_analysis5.findAppOrHandler)(content);
@@ -7175,24 +6630,24 @@ async function resolveModuleAttrEntrypoint(workPath, value) {
7175
6630
  const relPath = modulePath.replace(/\./g, "/");
7176
6631
  const candidates = [`${relPath}.py`, `${relPath}/__init__.py`];
7177
6632
  for (const candidate of candidates) {
7178
- if (await fileExists((0, import_path8.join)(workPath, candidate))) {
6633
+ if (await fileExists((0, import_path7.join)(workPath, candidate))) {
7179
6634
  return { entrypoint: candidate, variableName };
7180
6635
  }
7181
6636
  }
7182
6637
  return null;
7183
6638
  }
7184
6639
  async function getVercelToolsEntrypoint(workPath, repoRootPath) {
7185
- const pyprojectPath = (0, import_path8.join)(workPath, "pyproject.toml");
7186
- const pyprojectData = await (0, import_build_utils11.readConfigFile)(pyprojectPath);
6640
+ const pyprojectPath = (0, import_path7.join)(workPath, "pyproject.toml");
6641
+ const pyprojectData = await (0, import_build_utils10.readConfigFile)(pyprojectPath);
7187
6642
  if (!pyprojectData)
7188
6643
  return null;
7189
6644
  const vercelEntrypoint = pyprojectData.tool?.vercel?.entrypoint;
7190
6645
  if (vercelEntrypoint === void 0)
7191
6646
  return null;
7192
- const relPyprojectPath = (0, import_path8.relative)(repoRootPath ?? workPath, pyprojectPath);
6647
+ const relPyprojectPath = (0, import_path7.relative)(repoRootPath ?? workPath, pyprojectPath);
7193
6648
  const displayPath = !relPyprojectPath || relPyprojectPath.startsWith("..") ? pyprojectPath : relPyprojectPath;
7194
6649
  if (typeof vercelEntrypoint !== "string") {
7195
- throw new import_build_utils9.NowBuildError({
6650
+ throw new import_build_utils8.NowBuildError({
7196
6651
  code: "PYTHON_INVALID_ENTRYPOINT",
7197
6652
  message: `"tool.vercel.entrypoint" in "${displayPath}" must be a string in "module:object" format (e.g. "main:app").`,
7198
6653
  link: PYTHON_ENTRYPOINT_DOCS_URL,
@@ -7204,7 +6659,7 @@ async function getVercelToolsEntrypoint(workPath, repoRootPath) {
7204
6659
  vercelEntrypoint
7205
6660
  );
7206
6661
  if (!resolved) {
7207
- throw new import_build_utils9.NowBuildError({
6662
+ throw new import_build_utils8.NowBuildError({
7208
6663
  code: "PYTHON_ENTRYPOINT_NOT_FOUND",
7209
6664
  message: `"tool.vercel.entrypoint" in "${displayPath}" is "${vercelEntrypoint}" but no matching module file was found. Use "module:object" format (e.g. "main:app") and ensure the module file exists, or remove the setting to use automatic entrypoint detection.`,
7210
6665
  link: PYTHON_ENTRYPOINT_DOCS_URL,
@@ -7214,7 +6669,7 @@ async function getVercelToolsEntrypoint(workPath, repoRootPath) {
7214
6669
  return resolved;
7215
6670
  }
7216
6671
  async function getPyprojectEntrypointWithDiagnostics(workPath) {
7217
- const pyprojectData = await (0, import_build_utils11.readConfigFile)((0, import_path8.join)(workPath, "pyproject.toml"));
6672
+ const pyprojectData = await (0, import_build_utils10.readConfigFile)((0, import_path7.join)(workPath, "pyproject.toml"));
7218
6673
  if (!pyprojectData)
7219
6674
  return { entrypoint: null };
7220
6675
  const scripts = pyprojectData.project?.scripts;
@@ -7229,7 +6684,7 @@ async function getPyprojectEntrypointWithDiagnostics(workPath) {
7229
6684
  const relPath = modulePath.replace(/\./g, "/");
7230
6685
  const candidates = [`${relPath}.py`, `${relPath}/__init__.py`];
7231
6686
  for (const candidate of candidates) {
7232
- if (await fileExists((0, import_path8.join)(workPath, candidate))) {
6687
+ if (await fileExists((0, import_path7.join)(workPath, candidate))) {
7233
6688
  return { entrypoint: { entrypoint: candidate, variableName } };
7234
6689
  }
7235
6690
  }
@@ -7238,13 +6693,13 @@ async function getPyprojectEntrypointWithDiagnostics(workPath) {
7238
6693
  async function findValidEntrypoint(workPath, candidates) {
7239
6694
  const existingWithoutEntrypoint = [];
7240
6695
  for (const candidate of candidates) {
7241
- const absPath = (0, import_path8.join)(workPath, candidate);
6696
+ const absPath = (0, import_path7.join)(workPath, candidate);
7242
6697
  if (!await fileExists(absPath))
7243
6698
  continue;
7244
- const content = await import_fs8.default.promises.readFile(absPath, "utf-8");
6699
+ const content = await import_fs7.default.promises.readFile(absPath, "utf-8");
7245
6700
  const varName = await (0, import_python_analysis5.findAppOrHandler)(content);
7246
6701
  if (varName) {
7247
- (0, import_build_utils10.debug)(`Detected Python entrypoint: ${candidate} (variable: ${varName})`);
6702
+ (0, import_build_utils9.debug)(`Detected Python entrypoint: ${candidate} (variable: ${varName})`);
7248
6703
  return {
7249
6704
  entrypoint: { entrypoint: candidate, variableName: varName },
7250
6705
  existingWithoutEntrypoint
@@ -7255,12 +6710,12 @@ async function findValidEntrypoint(workPath, candidates) {
7255
6710
  return { entrypoint: null, existingWithoutEntrypoint };
7256
6711
  }
7257
6712
  async function checkDjangoManage(workPath) {
7258
- const managePath = (0, import_path8.join)(workPath, "manage.py");
6713
+ const managePath = (0, import_path7.join)(workPath, "manage.py");
7259
6714
  try {
7260
- const content = await import_fs8.default.promises.readFile(managePath, "utf-8");
6715
+ const content = await import_fs7.default.promises.readFile(managePath, "utf-8");
7261
6716
  if (!content.includes("DJANGO_SETTINGS_MODULE"))
7262
6717
  return false;
7263
- (0, import_build_utils10.debug)(`Found Django manage.py with DJANGO_SETTINGS_MODULE at ${workPath}`);
6718
+ (0, import_build_utils9.debug)(`Found Django manage.py with DJANGO_SETTINGS_MODULE at ${workPath}`);
7264
6719
  return true;
7265
6720
  } catch {
7266
6721
  return false;
@@ -7268,7 +6723,7 @@ async function checkDjangoManage(workPath) {
7268
6723
  }
7269
6724
  async function getSubdirectories(workPath) {
7270
6725
  try {
7271
- const entries = await import_fs8.default.promises.readdir(workPath, {
6726
+ const entries = await import_fs7.default.promises.readdir(workPath, {
7272
6727
  withFileTypes: true
7273
6728
  });
7274
6729
  return entries.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name).sort();
@@ -7313,7 +6768,7 @@ ${suggestion}`;
7313
6768
  const searchedList = PYTHON_CANDIDATE_ENTRYPOINTS.join(", ");
7314
6769
  message = `No ${displayName} entrypoint found. Set "tool.vercel.entrypoint" in pyproject.toml or define an entrypoint in one of: ${searchedList}.`;
7315
6770
  }
7316
- return new import_build_utils9.NowBuildError({ code, message, link, action });
6771
+ return new import_build_utils8.NowBuildError({ code, message, link, action });
7317
6772
  }
7318
6773
  async function detectGenericPythonEntrypoint(workPath) {
7319
6774
  try {
@@ -7326,7 +6781,7 @@ async function detectGenericPythonEntrypoint(workPath) {
7326
6781
  findDiagnostics: result
7327
6782
  };
7328
6783
  } catch {
7329
- (0, import_build_utils10.debug)("Failed to discover Python entrypoint");
6784
+ (0, import_build_utils9.debug)("Failed to discover Python entrypoint");
7330
6785
  return {
7331
6786
  detected: null,
7332
6787
  findDiagnostics: { entrypoint: null, existingWithoutEntrypoint: [] }
@@ -7345,7 +6800,7 @@ async function detectDjangoPythonEntrypoint(workPath) {
7345
6800
  const subdirs = await getSubdirectories(workPath);
7346
6801
  const rootDirs = ["", ...subdirs];
7347
6802
  for (const rootDir of rootDirs) {
7348
- const currPath = (0, import_path8.join)(workPath, rootDir);
6803
+ const currPath = (0, import_path7.join)(workPath, rootDir);
7349
6804
  const isDjango = await checkDjangoManage(currPath);
7350
6805
  if (isDjango) {
7351
6806
  return {
@@ -7361,7 +6816,7 @@ async function detectDjangoPythonEntrypoint(workPath) {
7361
6816
  findDiagnostics: result
7362
6817
  };
7363
6818
  } catch {
7364
- (0, import_build_utils10.debug)("Failed to discover Django Python entrypoint");
6819
+ (0, import_build_utils9.debug)("Failed to discover Django Python entrypoint");
7365
6820
  return emptyResult;
7366
6821
  }
7367
6822
  }
@@ -7369,10 +6824,10 @@ async function detectPythonEntrypoint(framework, workPath, configuredEntrypoint,
7369
6824
  if (configuredEntrypoint) {
7370
6825
  const { filePath: configEntryFile, varName: configEntryVar } = configuredEntrypoint;
7371
6826
  const entrypoint = configEntryFile.endsWith(".py") ? configEntryFile : `${configEntryFile}.py`;
7372
- const entrypointExists = await fileExists((0, import_path8.join)(workPath, entrypoint));
6827
+ const entrypointExists = await fileExists((0, import_path7.join)(workPath, entrypoint));
7373
6828
  if (!entrypointExists) {
7374
6829
  return {
7375
- error: new import_build_utils9.NowBuildError({
6830
+ error: new import_build_utils8.NowBuildError({
7376
6831
  code: "PYTHON_ENTRYPOINT_NOT_FOUND",
7377
6832
  message: `Configured Python entrypoint "${entrypoint}" was not found.`,
7378
6833
  link: PYTHON_ENTRYPOINT_DOCS_URL,
@@ -7382,17 +6837,17 @@ async function detectPythonEntrypoint(framework, workPath, configuredEntrypoint,
7382
6837
  }
7383
6838
  let varName = configEntryVar ?? await checkEntrypoint(workPath, entrypoint);
7384
6839
  if (!varName) {
7385
- const needsDynamicApp = !!service && ((0, import_build_utils9.isScheduleTriggeredService)(service) || (0, import_build_utils9.isQueueTriggeredService)(service) || (0, import_build_utils9.isWorkflowTriggeredService)(service));
6840
+ const needsDynamicApp = !!service && ((0, import_build_utils8.isScheduleTriggeredService)(service) || (0, import_build_utils8.isQueueTriggeredService)(service) || (0, import_build_utils8.isWorkflowTriggeredService)(service));
7386
6841
  if (needsDynamicApp) {
7387
6842
  varName = "app";
7388
6843
  }
7389
6844
  }
7390
6845
  if (varName) {
7391
- (0, import_build_utils10.debug)(`Using configured Python entrypoint: ${entrypoint}`);
6846
+ (0, import_build_utils9.debug)(`Using configured Python entrypoint: ${entrypoint}`);
7392
6847
  return { entrypoint: { entrypoint, variableName: varName } };
7393
6848
  } else {
7394
6849
  return {
7395
- error: new import_build_utils9.NowBuildError({
6850
+ error: new import_build_utils8.NowBuildError({
7396
6851
  code: "PYTHON_ENTRYPOINT_NOT_FOUND",
7397
6852
  message: `Could not find a top-level "app", "application", or "handler" in "${entrypoint}".`,
7398
6853
  link: PYTHON_ENTRYPOINT_DOCS_URL,
@@ -7442,7 +6897,7 @@ var detectEntrypoint = async ({
7442
6897
  workPath,
7443
6898
  framework
7444
6899
  }) => {
7445
- if (!(0, import_build_utils9.isPythonFramework)(framework))
6900
+ if (!(0, import_build_utils8.isPythonFramework)(framework))
7446
6901
  return null;
7447
6902
  let detected;
7448
6903
  try {
@@ -7451,7 +6906,7 @@ var detectEntrypoint = async ({
7451
6906
  workPath
7452
6907
  );
7453
6908
  } catch (err) {
7454
- (0, import_build_utils10.debug)(
6909
+ (0, import_build_utils9.debug)(
7455
6910
  `Python entrypoint detection failed for ${workPath}: ${err instanceof Error ? err.message : String(err)}`
7456
6911
  );
7457
6912
  return null;
@@ -7467,8 +6922,8 @@ var detectEntrypoint = async ({
7467
6922
 
7468
6923
  // src/crons.ts
7469
6924
  var DYNAMIC_SCHEDULE = "<dynamic>";
7470
- var scriptPath = (0, import_path9.join)(__dirname, "..", "templates", "vc_cron_detect.py");
7471
- var script = import_fs9.default.readFileSync(scriptPath, "utf-8");
6925
+ var scriptPath = (0, import_path8.join)(__dirname, "..", "templates", "vc_cron_detect.py");
6926
+ var script = import_fs8.default.readFileSync(scriptPath, "utf-8");
7472
6927
  function buildCronRouteTable(crons) {
7473
6928
  const table = {};
7474
6929
  for (const cron of crons) {
@@ -7478,13 +6933,13 @@ function buildCronRouteTable(crons) {
7478
6933
  }
7479
6934
  async function getServiceCrons(opts) {
7480
6935
  const { service, entrypoint, rawEntrypoint, handlerFunction } = opts;
7481
- const isScheduledService = !!service && (0, import_build_utils12.isScheduleTriggeredService)(service);
6936
+ const isScheduledService = !!service && (0, import_build_utils11.isScheduleTriggeredService)(service);
7482
6937
  if (!isScheduledService || !service.name || typeof service.schedule !== "string" && !Array.isArray(service.schedule)) {
7483
6938
  return void 0;
7484
6939
  }
7485
6940
  const cronEntrypoint = entrypoint || rawEntrypoint;
7486
6941
  if (!cronEntrypoint) {
7487
- throw new import_build_utils12.NowBuildError({
6942
+ throw new import_build_utils11.NowBuildError({
7488
6943
  code: "PYTHON_CRON_NO_ENTRYPOINT",
7489
6944
  message: "Cron service is missing an entrypoint."
7490
6945
  });
@@ -7499,7 +6954,7 @@ async function getServiceCrons(opts) {
7499
6954
  workPath: opts.workPath
7500
6955
  });
7501
6956
  }
7502
- const cronPath = (0, import_build_utils12.getInternalServiceCronPath)(
6957
+ const cronPath = (0, import_build_utils11.getInternalServiceCronPath)(
7503
6958
  service.name,
7504
6959
  cronEntrypoint,
7505
6960
  handlerFunction || "cron"
@@ -7523,7 +6978,7 @@ async function getServiceCronsDynamic(opts) {
7523
6978
  workPath
7524
6979
  } = opts;
7525
6980
  if (!handlerFunction) {
7526
- throw new import_build_utils12.NowBuildError({
6981
+ throw new import_build_utils11.NowBuildError({
7527
6982
  code: "PYTHON_DYNAMIC_CRON_NO_HANDLER",
7528
6983
  message: 'Dynamic cron detection requires a "module:object" entrypoint where the object has a get_crons() method.'
7529
6984
  });
@@ -7540,7 +6995,7 @@ async function getServiceCronsDynamic(opts) {
7540
6995
  `Detected ${entries.length} cron entry(s): ${entries.map((e) => `${e.module_function} (${e.schedule})`).join(", ")}`
7541
6996
  );
7542
6997
  if (entries.length === 0) {
7543
- throw new import_build_utils12.NowBuildError({
6998
+ throw new import_build_utils11.NowBuildError({
7544
6999
  code: "PYTHON_DYNAMIC_CRON_EMPTY",
7545
7000
  message: `Dynamic cron detection returned no entries. "${moduleName}.${handlerFunction}.get_crons()" returned an empty iterable.`
7546
7001
  });
@@ -7561,7 +7016,7 @@ async function detectDynamicCrons(opts) {
7561
7016
  const { pythonBin, env, workPath, moduleName, attrName } = opts;
7562
7017
  let stdout;
7563
7018
  try {
7564
- const result = await (0, import_execa5.default)(
7019
+ const result = await (0, import_execa4.default)(
7565
7020
  pythonBin,
7566
7021
  ["-c", script, moduleName, attrName],
7567
7022
  { env, cwd: workPath }
@@ -7575,7 +7030,7 @@ async function detectDynamicCrons(opts) {
7575
7030
  detail = parsed2.error;
7576
7031
  } catch {
7577
7032
  }
7578
- throw new import_build_utils12.NowBuildError({
7033
+ throw new import_build_utils11.NowBuildError({
7579
7034
  code: "PYTHON_DYNAMIC_CRON_DETECTION_FAILED",
7580
7035
  message: `Failed to detect dynamic cron entries: ${detail}`
7581
7036
  });
@@ -7584,7 +7039,7 @@ async function detectDynamicCrons(opts) {
7584
7039
  try {
7585
7040
  parsed = JSON.parse(stdout);
7586
7041
  } catch {
7587
- throw new import_build_utils12.NowBuildError({
7042
+ throw new import_build_utils11.NowBuildError({
7588
7043
  code: "PYTHON_DYNAMIC_CRON_DETECTION_FAILED",
7589
7044
  message: `Dynamic cron detection returned invalid JSON: ${stdout}`
7590
7045
  });
@@ -7594,7 +7049,7 @@ async function detectDynamicCrons(opts) {
7594
7049
  function moduleColonFuncToCronPath(serviceName, moduleFunction) {
7595
7050
  const colonIdx = moduleFunction.indexOf(":");
7596
7051
  if (colonIdx === -1) {
7597
- throw new import_build_utils12.NowBuildError({
7052
+ throw new import_build_utils11.NowBuildError({
7598
7053
  code: "PYTHON_DYNAMIC_CRON_INVALID_FORMAT",
7599
7054
  message: `Dynamic cron entry must use "module:function" format, got: "${moduleFunction}"`
7600
7055
  });
@@ -7602,14 +7057,14 @@ function moduleColonFuncToCronPath(serviceName, moduleFunction) {
7602
7057
  const modulePart = moduleFunction.slice(0, colonIdx);
7603
7058
  const funcPart = moduleFunction.slice(colonIdx + 1);
7604
7059
  const entrypointPath = modulePart.replace(/\./g, "/");
7605
- return (0, import_build_utils12.getInternalServiceCronPath)(serviceName, entrypointPath, funcPart);
7060
+ return (0, import_build_utils11.getInternalServiceCronPath)(serviceName, entrypointPath, funcPart);
7606
7061
  }
7607
7062
 
7608
7063
  // src/start-dev-server.ts
7609
7064
  var import_child_process2 = require("child_process");
7610
- var import_fs10 = require("fs");
7611
- var import_path10 = require("path");
7612
- var import_build_utils13 = require("@vercel/build-utils");
7065
+ var import_fs9 = require("fs");
7066
+ var import_path9 = require("path");
7067
+ var import_build_utils12 = require("@vercel/build-utils");
7613
7068
  var import_get_port = __toESM(require_get_port());
7614
7069
  var import_is_port_reachable = __toESM(require_is_port_reachable());
7615
7070
  var import_python_analysis6 = require("@vercel/python-analysis");
@@ -7715,17 +7170,17 @@ async function syncDependencies({
7715
7170
  let { manifestPath } = installInfo;
7716
7171
  const manifest = pythonPackage.manifest;
7717
7172
  if (!manifestType || !manifestPath) {
7718
- (0, import_build_utils13.debug)("No Python project manifest found, skipping dependency sync");
7173
+ (0, import_build_utils12.debug)("No Python project manifest found, skipping dependency sync");
7719
7174
  return;
7720
7175
  }
7721
7176
  if (manifest?.origin && manifestType === "pyproject.toml") {
7722
- const syncDir = (0, import_path10.join)(workPath, ".vercel", "python", "sync");
7723
- (0, import_fs10.mkdirSync)(syncDir, { recursive: true });
7724
- const tempPyproject = (0, import_path10.join)(syncDir, "pyproject.toml");
7177
+ const syncDir = (0, import_path9.join)(workPath, ".vercel", "python", "sync");
7178
+ (0, import_fs9.mkdirSync)(syncDir, { recursive: true });
7179
+ const tempPyproject = (0, import_path9.join)(syncDir, "pyproject.toml");
7725
7180
  const content = (0, import_python_analysis6.stringifyManifest)(manifest.data);
7726
- (0, import_fs10.writeFileSync)(tempPyproject, content, "utf8");
7181
+ (0, import_fs9.writeFileSync)(tempPyproject, content, "utf8");
7727
7182
  manifestPath = tempPyproject;
7728
- (0, import_build_utils13.debug)(
7183
+ (0, import_build_utils12.debug)(
7729
7184
  `Wrote converted ${manifest.origin.kind} manifest to ${tempPyproject}`
7730
7185
  );
7731
7186
  }
@@ -7758,7 +7213,7 @@ async function syncDependencies({
7758
7213
  for (const [channel, chunk] of captured) {
7759
7214
  (channel === "stdout" ? writeOut : writeErr)(chunk.toString());
7760
7215
  }
7761
- throw new import_build_utils13.NowBuildError({
7216
+ throw new import_build_utils12.NowBuildError({
7762
7217
  code: "PYTHON_DEPENDENCY_SYNC_FAILED",
7763
7218
  message: `Failed to install Python dependencies from ${manifestType}: ${err instanceof Error ? err.message : String(err)}`
7764
7219
  });
@@ -7773,14 +7228,14 @@ async function runSync({
7773
7228
  onStdout,
7774
7229
  onStderr
7775
7230
  }) {
7776
- const projectDir = (0, import_path10.dirname)(manifestPath);
7231
+ const projectDir = (0, import_path9.dirname)(manifestPath);
7777
7232
  const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
7778
7233
  let spawnCmd;
7779
7234
  let spawnArgs;
7780
7235
  switch (manifestType) {
7781
7236
  case "uv.lock": {
7782
7237
  if (!uvPath) {
7783
- throw new import_build_utils13.NowBuildError({
7238
+ throw new import_build_utils12.NowBuildError({
7784
7239
  code: "PYTHON_DEPENDENCY_SYNC_FAILED",
7785
7240
  message: "uv is required to install dependencies from uv.lock.",
7786
7241
  link: "https://docs.astral.sh/uv/getting-started/installation/",
@@ -7802,11 +7257,11 @@ async function runSync({
7802
7257
  break;
7803
7258
  }
7804
7259
  default:
7805
- (0, import_build_utils13.debug)(`Unknown manifest type: ${manifestType}`);
7260
+ (0, import_build_utils12.debug)(`Unknown manifest type: ${manifestType}`);
7806
7261
  return;
7807
7262
  }
7808
7263
  await new Promise((resolve3, reject) => {
7809
- (0, import_build_utils13.debug)(`Running "${spawnCmd} ${spawnArgs.join(" ")}" in ${projectDir}...`);
7264
+ (0, import_build_utils12.debug)(`Running "${spawnCmd} ${spawnArgs.join(" ")}" in ${projectDir}...`);
7810
7265
  const child = (0, import_child_process2.spawn)(spawnCmd, spawnArgs, {
7811
7266
  cwd: projectDir,
7812
7267
  env: getProtectedUvEnv(env),
@@ -7845,7 +7300,7 @@ var COMPLETED_INSTALLS = /* @__PURE__ */ new Set();
7845
7300
  function hasInstalledDistribution(targetDir, packageName) {
7846
7301
  const prefix = `${packageName.replace("-", "_")}-`;
7847
7302
  try {
7848
- return (0, import_fs10.readdirSync)(targetDir).some(
7303
+ return (0, import_fs9.readdirSync)(targetDir).some(
7849
7304
  (entry) => entry.startsWith(prefix) && entry.endsWith(".dist-info")
7850
7305
  );
7851
7306
  } catch {
@@ -7853,7 +7308,7 @@ function hasInstalledDistribution(targetDir, packageName) {
7853
7308
  }
7854
7309
  }
7855
7310
  async function installInjectedDevPackage(pkg, opts) {
7856
- const targetDir = (0, import_path10.join)(opts.workPath, ".vercel", "python");
7311
+ const targetDir = (0, import_path9.join)(opts.workPath, ".vercel", "python");
7857
7312
  const source = pkg.envOverride || pkg.pinnedVersion;
7858
7313
  const key = `${targetDir}:${pkg.name}:${source}`;
7859
7314
  if (COMPLETED_INSTALLS.has(key) && hasInstalledDistribution(targetDir, pkg.name)) {
@@ -7867,22 +7322,22 @@ async function installInjectedDevPackage(pkg, opts) {
7867
7322
  }
7868
7323
  async function doInstallInjectedDevPackage(pkg, opts) {
7869
7324
  const { targetDir, workPath, uvPath, pythonBin, env, onStdout, onStderr } = opts;
7870
- (0, import_fs10.mkdirSync)(targetDir, { recursive: true });
7871
- const localDir = (0, import_path10.join)(__dirname, "..", "..", "..", "python", pkg.name);
7872
- const isLocalDev = (0, import_fs10.existsSync)((0, import_path10.join)(localDir, "pyproject.toml"));
7325
+ (0, import_fs9.mkdirSync)(targetDir, { recursive: true });
7326
+ const localDir = (0, import_path9.join)(__dirname, "..", "..", "..", "python", pkg.name);
7327
+ const isLocalDev = (0, import_fs9.existsSync)((0, import_path9.join)(localDir, "pyproject.toml"));
7873
7328
  const dep = pkg.envOverride || (isLocalDev ? localDir : `${pkg.name}==${pkg.pinnedVersion}`);
7874
7329
  if (!isLocalDev && !pkg.envOverride) {
7875
7330
  const distInfoName = pkg.name.replace("-", "_");
7876
- const distInfo = (0, import_path10.join)(
7331
+ const distInfo = (0, import_path9.join)(
7877
7332
  targetDir,
7878
7333
  `${distInfoName}-${pkg.pinnedVersion}.dist-info`
7879
7334
  );
7880
- if ((0, import_fs10.existsSync)(distInfo)) {
7881
- (0, import_build_utils13.debug)(`${pkg.name} ${pkg.pinnedVersion} already installed, skipping`);
7335
+ if ((0, import_fs9.existsSync)(distInfo)) {
7336
+ (0, import_build_utils12.debug)(`${pkg.name} ${pkg.pinnedVersion} already installed, skipping`);
7882
7337
  return;
7883
7338
  }
7884
7339
  }
7885
- (0, import_build_utils13.debug)(
7340
+ (0, import_build_utils12.debug)(
7886
7341
  `Installing ${pkg.name} into ${targetDir} (type: ${isLocalDev ? "local" : "pypi"}, source: ${dep})`
7887
7342
  );
7888
7343
  const pip = uvPath ? { cmd: uvPath, prefix: ["pip", "install"] } : { cmd: pythonBin, prefix: ["-m", "pip", "install"] };
@@ -7904,14 +7359,14 @@ async function doInstallInjectedDevPackage(pkg, opts) {
7904
7359
  if (onStdout) {
7905
7360
  onStdout(data);
7906
7361
  } else {
7907
- (0, import_build_utils13.debug)(data.toString());
7362
+ (0, import_build_utils12.debug)(data.toString());
7908
7363
  }
7909
7364
  });
7910
7365
  child.stderr?.on("data", (data) => {
7911
7366
  if (onStderr) {
7912
7367
  onStderr(data);
7913
7368
  } else {
7914
- (0, import_build_utils13.debug)(data.toString());
7369
+ (0, import_build_utils12.debug)(data.toString());
7915
7370
  }
7916
7371
  });
7917
7372
  child.on("error", reject);
@@ -7941,12 +7396,12 @@ function installGlobalCleanupHandlers() {
7941
7396
  try {
7942
7397
  process.kill(info.pid, "SIGTERM");
7943
7398
  } catch (err) {
7944
- (0, import_build_utils13.debug)(`Error sending SIGTERM to ${info.pid}: ${err}`);
7399
+ (0, import_build_utils12.debug)(`Error sending SIGTERM to ${info.pid}: ${err}`);
7945
7400
  }
7946
7401
  try {
7947
7402
  process.kill(info.pid, "SIGKILL");
7948
7403
  } catch (err) {
7949
- (0, import_build_utils13.debug)(`Error sending SIGKILL to ${info.pid}: ${err}`);
7404
+ (0, import_build_utils12.debug)(`Error sending SIGKILL to ${info.pid}: ${err}`);
7950
7405
  }
7951
7406
  PERSISTENT_SERVERS.delete(key);
7952
7407
  }
@@ -7954,7 +7409,7 @@ function installGlobalCleanupHandlers() {
7954
7409
  try {
7955
7410
  restoreWarnings();
7956
7411
  } catch (err) {
7957
- (0, import_build_utils13.debug)(`Error restoring warnings: ${err}`);
7412
+ (0, import_build_utils12.debug)(`Error restoring warnings: ${err}`);
7958
7413
  }
7959
7414
  restoreWarnings = null;
7960
7415
  }
@@ -7971,46 +7426,46 @@ function installGlobalCleanupHandlers() {
7971
7426
  }
7972
7427
  function createDevShim(workPath, entry, modulePath, serviceName, framework, variableName) {
7973
7428
  try {
7974
- const vercelPythonDir = serviceName ? (0, import_path10.join)(workPath, ".vercel", "python", "services", serviceName) : (0, import_path10.join)(workPath, ".vercel", "python");
7975
- (0, import_fs10.mkdirSync)(vercelPythonDir, { recursive: true });
7429
+ const vercelPythonDir = serviceName ? (0, import_path9.join)(workPath, ".vercel", "python", "services", serviceName) : (0, import_path9.join)(workPath, ".vercel", "python");
7430
+ (0, import_fs9.mkdirSync)(vercelPythonDir, { recursive: true });
7976
7431
  let qualifiedModule = modulePath;
7977
7432
  let extraPythonPath;
7978
- if ((0, import_fs10.existsSync)((0, import_path10.join)(workPath, "__init__.py"))) {
7979
- const pkgName = (0, import_path10.basename)(workPath);
7433
+ if ((0, import_fs9.existsSync)((0, import_path9.join)(workPath, "__init__.py"))) {
7434
+ const pkgName = (0, import_path9.basename)(workPath);
7980
7435
  qualifiedModule = `${pkgName}.${modulePath}`;
7981
- extraPythonPath = (0, import_path10.dirname)(workPath);
7436
+ extraPythonPath = (0, import_path9.dirname)(workPath);
7982
7437
  }
7983
- const entryAbs = (0, import_path10.join)(workPath, entry);
7984
- const shimPath = (0, import_path10.join)(vercelPythonDir, `${DEV_SHIM_MODULE}.py`);
7985
- const templatePath = (0, import_path10.join)(
7438
+ const entryAbs = (0, import_path9.join)(workPath, entry);
7439
+ const shimPath = (0, import_path9.join)(vercelPythonDir, `${DEV_SHIM_MODULE}.py`);
7440
+ const templatePath = (0, import_path9.join)(
7986
7441
  __dirname,
7987
7442
  "..",
7988
7443
  "templates",
7989
7444
  `${DEV_SHIM_MODULE}.py`
7990
7445
  );
7991
- const template = (0, import_fs10.readFileSync)(templatePath, "utf8");
7446
+ const template = (0, import_fs9.readFileSync)(templatePath, "utf8");
7992
7447
  const shimSource = template.replace(/__VC_DEV_MODULE_NAME__/g, qualifiedModule).replace(/__VC_DEV_ENTRY_ABS__/g, entryAbs).replace(/__VC_DEV_FRAMEWORK__/g, framework).replace(/__VC_DEV_VARIABLE_NAME__/g, variableName);
7993
- (0, import_fs10.writeFileSync)(shimPath, shimSource, "utf8");
7994
- (0, import_build_utils13.debug)(`Prepared Python dev shim at ${shimPath}`);
7448
+ (0, import_fs9.writeFileSync)(shimPath, shimSource, "utf8");
7449
+ (0, import_build_utils12.debug)(`Prepared Python dev shim at ${shimPath}`);
7995
7450
  return {
7996
7451
  module: DEV_SHIM_MODULE,
7997
7452
  extraPythonPath,
7998
7453
  shimDir: vercelPythonDir
7999
7454
  };
8000
7455
  } catch (err) {
8001
- (0, import_build_utils13.debug)(`Failed to prepare dev shim: ${err?.message || err}`);
7456
+ (0, import_build_utils12.debug)(`Failed to prepare dev shim: ${err?.message || err}`);
8002
7457
  return null;
8003
7458
  }
8004
7459
  }
8005
7460
  async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath) {
8006
- const venvPath = (0, import_path10.join)(workPath, ".venv");
7461
+ const venvPath = (0, import_path9.join)(workPath, ".venv");
8007
7462
  const pendingCreation = PENDING_MANAGED_VENV_CREATIONS.get(venvPath);
8008
7463
  if (pendingCreation) {
8009
7464
  await pendingCreation;
8010
7465
  }
8011
7466
  const { pythonCmd, venvRoot } = useVirtualEnv(workPath, env, systemPython);
8012
7467
  if (venvRoot) {
8013
- (0, import_build_utils13.debug)(`Using existing virtualenv at ${venvRoot} for multi-service dev`);
7468
+ (0, import_build_utils12.debug)(`Using existing virtualenv at ${venvRoot} for multi-service dev`);
8014
7469
  return { command: pythonCmd, args: [] };
8015
7470
  }
8016
7471
  await dedupePendingOperation(
@@ -8023,11 +7478,11 @@ async function getMultiServicePythonRunner(workPath, env, systemPython, uvPath)
8023
7478
  quiet: true
8024
7479
  })
8025
7480
  );
8026
- (0, import_build_utils13.debug)(`Created virtualenv at ${venvPath} for multi-service dev`);
7481
+ (0, import_build_utils12.debug)(`Created virtualenv at ${venvPath} for multi-service dev`);
8027
7482
  const pythonBin = getVenvPythonBin(venvPath);
8028
7483
  const binDir = getVenvBinDir(venvPath);
8029
7484
  env.VIRTUAL_ENV = venvPath;
8030
- env.PATH = `${binDir}${import_path10.delimiter}${env.PATH || ""}`;
7485
+ env.PATH = `${binDir}${import_path9.delimiter}${env.PATH || ""}`;
8031
7486
  return { command: pythonBin, args: [] };
8032
7487
  }
8033
7488
  var startDevServer = async (opts) => {
@@ -8072,24 +7527,34 @@ var startDevServer = async (opts) => {
8072
7527
  installGlobalCleanupHandlers();
8073
7528
  const env = { ...process.env, ...meta.env || {} };
8074
7529
  const entrypoint = rawEntrypoint === "<detect>" ? void 0 : rawEntrypoint;
7530
+ const isPyprojectEntrypoint = entrypoint === "pyproject.toml";
8075
7531
  let resolved;
8076
7532
  const handlerFunction = typeof config?.handlerFunction === "string" ? config.handlerFunction : void 0;
8077
- const detected = await detectPythonEntrypoint(
8078
- framework,
8079
- workPath,
8080
- entrypoint ? {
8081
- filePath: entrypoint,
8082
- // Schedule-triggered services create their own "app" wrapper dynamically.
8083
- // Other services use handlerFunction as the entrypoint variable name.
8084
- varName: service && (0, import_build_utils13.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
8085
- } : void 0,
8086
- service,
8087
- opts.repoRootPath
8088
- );
7533
+ let detected;
7534
+ if (isPyprojectEntrypoint) {
7535
+ const declaredEntrypoint = await getVercelToolsEntrypoint(
7536
+ workPath,
7537
+ opts.repoRootPath
7538
+ );
7539
+ detected = declaredEntrypoint ? { entrypoint: declaredEntrypoint } : null;
7540
+ } else {
7541
+ detected = await detectPythonEntrypoint(
7542
+ framework,
7543
+ workPath,
7544
+ entrypoint ? {
7545
+ filePath: entrypoint,
7546
+ // Schedule-triggered services create their own "app" wrapper dynamically.
7547
+ // Other services use handlerFunction as the entrypoint variable name.
7548
+ varName: service && (0, import_build_utils12.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
7549
+ } : void 0,
7550
+ service,
7551
+ opts.repoRootPath
7552
+ );
7553
+ }
8089
7554
  let hookResult;
8090
7555
  if (detected?.entrypoint) {
8091
7556
  resolved = detected.entrypoint;
8092
- } else {
7557
+ } else if (!isPyprojectEntrypoint) {
8093
7558
  hookResult = await runFrameworkHook(framework, {
8094
7559
  pythonEnv: env,
8095
7560
  workPath,
@@ -8102,9 +7567,9 @@ var startDevServer = async (opts) => {
8102
7567
  if (detected?.error) {
8103
7568
  throw detected.error;
8104
7569
  }
8105
- throw new import_build_utils13.NowBuildError({
8106
- code: "PYTHON_ENTRYPOINT_NOT_FOUND",
8107
- message: "No Python entrypoint could be detected. Please specify an entrypoint file."
7570
+ throw new import_build_utils12.NowBuildError({
7571
+ code: isPyprojectEntrypoint ? "PYTHON_PYPROJECT_NOTHING_TO_BUILD" : "PYTHON_ENTRYPOINT_NOT_FOUND",
7572
+ message: isPyprojectEntrypoint ? 'Entrypoint "pyproject.toml" does not declare a web app. Set "tool.vercel.entrypoint" in pyproject.toml.' : "No Python entrypoint could be detected. Please specify an entrypoint file."
8108
7573
  });
8109
7574
  }
8110
7575
  const { entrypoint: entry, variableName } = resolved;
@@ -8134,7 +7599,7 @@ var startDevServer = async (opts) => {
8134
7599
  const yellow = "\x1B[33m";
8135
7600
  const white = "\x1B[1m";
8136
7601
  const reset = "\x1B[0m";
8137
- throw new import_build_utils13.NowBuildError({
7602
+ throw new import_build_utils12.NowBuildError({
8138
7603
  code: "PYTHON_EXTERNAL_VENV_DETECTED",
8139
7604
  message: `Detected activated venv at ${yellow}${venv}${reset}, ${white}vercel dev${reset} manages virtual environments automatically.
8140
7605
  Run ${white}deactivate${reset} and try again.`
@@ -8151,11 +7616,11 @@ Run ${white}deactivate${reset} and try again.`
8151
7616
  );
8152
7617
  spawnCommand = runner.command;
8153
7618
  spawnArgsPrefix = runner.args;
8154
- (0, import_build_utils13.debug)(
7619
+ (0, import_build_utils12.debug)(
8155
7620
  `Multi-service Python runner: ${spawnCommand} ${spawnArgsPrefix.join(" ")}`
8156
7621
  );
8157
7622
  } else if (venv) {
8158
- (0, import_build_utils13.debug)(`Running in virtualenv at ${venv}`);
7623
+ (0, import_build_utils12.debug)(`Running in virtualenv at ${venv}`);
8159
7624
  } else {
8160
7625
  const { pythonCmd: venvPythonCmd, venvRoot } = useVirtualEnv(
8161
7626
  workPath,
@@ -8164,9 +7629,9 @@ Run ${white}deactivate${reset} and try again.`
8164
7629
  );
8165
7630
  spawnCommand = venvPythonCmd;
8166
7631
  if (venvRoot) {
8167
- (0, import_build_utils13.debug)(`Using virtualenv at ${venvRoot}`);
7632
+ (0, import_build_utils12.debug)(`Using virtualenv at ${venvRoot}`);
8168
7633
  } else {
8169
- (0, import_build_utils13.debug)("No virtualenv found");
7634
+ (0, import_build_utils12.debug)("No virtualenv found");
8170
7635
  try {
8171
7636
  const yellow = "\x1B[33m";
8172
7637
  const reset = "\x1B[0m";
@@ -8237,7 +7702,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
8237
7702
  const port = typeof meta.port === "number" ? meta.port : await (0, import_get_port.default)();
8238
7703
  env.PORT = `${port}`;
8239
7704
  if (entry) {
8240
- env.__VC_HANDLER_ENTRYPOINT_ABS = (0, import_path10.join)(workPath, entry);
7705
+ env.__VC_HANDLER_ENTRYPOINT_ABS = (0, import_path9.join)(workPath, entry);
8241
7706
  }
8242
7707
  const devShim = createDevShim(
8243
7708
  workPath,
@@ -8248,8 +7713,8 @@ If you are using a virtual environment, activate it before running "vercel dev",
8248
7713
  variableName ?? ""
8249
7714
  );
8250
7715
  if (devShim) {
8251
- const shimDir = devShim.shimDir || (0, import_path10.join)(workPath, ".vercel", "python");
8252
- const runtimeDir = (0, import_path10.join)(workPath, ".vercel", "python");
7716
+ const shimDir = devShim.shimDir || (0, import_path9.join)(workPath, ".vercel", "python");
7717
+ const runtimeDir = (0, import_path9.join)(workPath, ".vercel", "python");
8253
7718
  const pathParts = shimDir !== runtimeDir ? [shimDir, runtimeDir] : [shimDir];
8254
7719
  if (devShim.extraPythonPath) {
8255
7720
  pathParts.push(devShim.extraPythonPath);
@@ -8261,12 +7726,12 @@ If you are using a virtual environment, activate it before running "vercel dev",
8261
7726
  if (existingPythonPath) {
8262
7727
  pathParts.push(existingPythonPath);
8263
7728
  }
8264
- env.PYTHONPATH = pathParts.join(import_path10.delimiter);
7729
+ env.PYTHONPATH = pathParts.join(import_path9.delimiter);
8265
7730
  }
8266
7731
  const moduleToRun = devShim?.module || modulePath;
8267
7732
  const pythonArgs = ["-u", "-m", moduleToRun];
8268
7733
  const argv = [...spawnArgsPrefix, ...pythonArgs];
8269
- (0, import_build_utils13.debug)(
7734
+ (0, import_build_utils12.debug)(
8270
7735
  `Starting Python dev server (${framework}): ${spawnCommand} ${argv.join(" ")} [PORT=${port}]`
8271
7736
  );
8272
7737
  if (process.stdout.columns) {
@@ -8320,7 +7785,7 @@ If you are using a virtual environment, activate it before running "vercel dev",
8320
7785
  };
8321
7786
 
8322
7787
  // src/quirks/index.ts
8323
- var import_build_utils16 = require("@vercel/build-utils");
7788
+ var import_build_utils15 = require("@vercel/build-utils");
8324
7789
  var import_python_analysis8 = require("@vercel/python-analysis");
8325
7790
 
8326
7791
  // src/quirks/matplotlib.ts
@@ -8334,9 +7799,9 @@ var matplotlibQuirk = {
8334
7799
  };
8335
7800
 
8336
7801
  // src/quirks/litellm.ts
8337
- var import_fs11 = __toESM(require("fs"));
8338
- var import_path11 = require("path");
8339
- var import_build_utils14 = require("@vercel/build-utils");
7802
+ var import_fs10 = __toESM(require("fs"));
7803
+ var import_path10 = require("path");
7804
+ var import_build_utils13 = require("@vercel/build-utils");
8340
7805
  var LAMBDA_ROOT = "/var/task";
8341
7806
  var CONFIG_CANDIDATES = [
8342
7807
  "litellm_config.yaml",
@@ -8346,9 +7811,9 @@ var CONFIG_CANDIDATES = [
8346
7811
  ];
8347
7812
  async function findConfigFile(workPath) {
8348
7813
  for (const name of CONFIG_CANDIDATES) {
8349
- const candidate = (0, import_path11.join)(workPath, name);
7814
+ const candidate = (0, import_path10.join)(workPath, name);
8350
7815
  try {
8351
- await import_fs11.default.promises.access(candidate);
7816
+ await import_fs10.default.promises.access(candidate);
8352
7817
  return name;
8353
7818
  } catch {
8354
7819
  }
@@ -8363,32 +7828,32 @@ var litellmQuirk = {
8363
7828
  const env = {};
8364
7829
  const sitePackagesDirs = await getVenvSitePackagesDirs(ctx.venvPath);
8365
7830
  for (const sitePackages of sitePackagesDirs) {
8366
- const schemaPath = (0, import_path11.join)(
7831
+ const schemaPath = (0, import_path10.join)(
8367
7832
  sitePackages,
8368
7833
  "litellm",
8369
7834
  "proxy",
8370
7835
  "schema.prisma"
8371
7836
  );
8372
7837
  try {
8373
- await import_fs11.default.promises.access(schemaPath);
8374
- (0, import_build_utils14.debug)(`LiteLLM quirk: found schema at ${schemaPath}`);
7838
+ await import_fs10.default.promises.access(schemaPath);
7839
+ (0, import_build_utils13.debug)(`LiteLLM quirk: found schema at ${schemaPath}`);
8375
7840
  buildEnv.PRISMA_SCHEMA_PATH = schemaPath;
8376
7841
  break;
8377
7842
  } catch {
8378
7843
  }
8379
7844
  }
8380
7845
  if (!buildEnv.PRISMA_SCHEMA_PATH) {
8381
- (0, import_build_utils14.debug)("LiteLLM quirk: schema.prisma not found in any site-packages");
7846
+ (0, import_build_utils13.debug)("LiteLLM quirk: schema.prisma not found in any site-packages");
8382
7847
  }
8383
7848
  if (!process.env.CONFIG_FILE_PATH) {
8384
7849
  const configName = await findConfigFile(ctx.workPath);
8385
7850
  if (configName) {
8386
- (0, import_build_utils14.debug)(`LiteLLM quirk: found config at ${configName}`);
8387
- buildEnv.CONFIG_FILE_PATH = (0, import_path11.join)(ctx.workPath, configName);
8388
- env.CONFIG_FILE_PATH = (0, import_path11.join)(LAMBDA_ROOT, configName);
7851
+ (0, import_build_utils13.debug)(`LiteLLM quirk: found config at ${configName}`);
7852
+ buildEnv.CONFIG_FILE_PATH = (0, import_path10.join)(ctx.workPath, configName);
7853
+ env.CONFIG_FILE_PATH = (0, import_path10.join)(LAMBDA_ROOT, configName);
8389
7854
  }
8390
7855
  } else {
8391
- (0, import_build_utils14.debug)(
7856
+ (0, import_build_utils13.debug)(
8392
7857
  `LiteLLM quirk: CONFIG_FILE_PATH already set to ${process.env.CONFIG_FILE_PATH}`
8393
7858
  );
8394
7859
  }
@@ -8397,10 +7862,10 @@ var litellmQuirk = {
8397
7862
  };
8398
7863
 
8399
7864
  // src/quirks/prisma.ts
8400
- var import_fs12 = __toESM(require("fs"));
8401
- var import_path12 = require("path");
8402
- var import_execa6 = __toESM(require_execa());
8403
- var import_build_utils15 = require("@vercel/build-utils");
7865
+ var import_fs11 = __toESM(require("fs"));
7866
+ var import_path11 = require("path");
7867
+ var import_execa5 = __toESM(require_execa());
7868
+ var import_build_utils14 = require("@vercel/build-utils");
8404
7869
  var import_python_analysis7 = require("@vercel/python-analysis");
8405
7870
  function execErrorMessage(err) {
8406
7871
  if (err != null && typeof err === "object" && "stderr" in err) {
@@ -8438,22 +7903,22 @@ model DummyModel {
8438
7903
  async function findUserSchema(workPath) {
8439
7904
  const envPath = process.env.PRISMA_SCHEMA_PATH;
8440
7905
  if (envPath) {
8441
- const resolved = (0, import_path12.isAbsolute)(envPath) ? envPath : (0, import_path12.join)(workPath, envPath);
7906
+ const resolved = (0, import_path11.isAbsolute)(envPath) ? envPath : (0, import_path11.join)(workPath, envPath);
8442
7907
  try {
8443
- await import_fs12.default.promises.access(resolved);
7908
+ await import_fs11.default.promises.access(resolved);
8444
7909
  return resolved;
8445
7910
  } catch {
8446
- (0, import_build_utils15.debug)(`PRISMA_SCHEMA_PATH=${envPath} not found at ${resolved}`);
7911
+ (0, import_build_utils14.debug)(`PRISMA_SCHEMA_PATH=${envPath} not found at ${resolved}`);
8447
7912
  return null;
8448
7913
  }
8449
7914
  }
8450
7915
  const candidates = [
8451
- (0, import_path12.join)(workPath, "schema.prisma"),
8452
- (0, import_path12.join)(workPath, "prisma", "schema.prisma")
7916
+ (0, import_path11.join)(workPath, "schema.prisma"),
7917
+ (0, import_path11.join)(workPath, "prisma", "schema.prisma")
8453
7918
  ];
8454
7919
  for (const candidate of candidates) {
8455
7920
  try {
8456
- await import_fs12.default.promises.access(candidate);
7921
+ await import_fs11.default.promises.access(candidate);
8457
7922
  return candidate;
8458
7923
  } catch {
8459
7924
  }
@@ -8464,32 +7929,32 @@ async function collectFiles(dir, base) {
8464
7929
  const result = [];
8465
7930
  let entries;
8466
7931
  try {
8467
- entries = await import_fs12.default.promises.readdir(dir, { withFileTypes: true });
7932
+ entries = await import_fs11.default.promises.readdir(dir, { withFileTypes: true });
8468
7933
  } catch {
8469
7934
  return result;
8470
7935
  }
8471
7936
  for (const entry of entries) {
8472
7937
  if (entry.name === "__pycache__")
8473
7938
  continue;
8474
- const full = (0, import_path12.join)(dir, entry.name);
7939
+ const full = (0, import_path11.join)(dir, entry.name);
8475
7940
  if (entry.isDirectory()) {
8476
7941
  result.push(...await collectFiles(full, base));
8477
7942
  } else {
8478
- result.push((0, import_path12.relative)(base, full));
7943
+ result.push((0, import_path11.relative)(base, full));
8479
7944
  }
8480
7945
  }
8481
7946
  return result;
8482
7947
  }
8483
7948
  async function cleanCacheArtifacts(cacheDir, extras = []) {
8484
7949
  const paths = [
8485
- (0, import_path12.join)(cacheDir, "node_modules"),
8486
- (0, import_path12.join)(cacheDir, "package.json"),
8487
- (0, import_path12.join)(cacheDir, "package-lock.json"),
7950
+ (0, import_path11.join)(cacheDir, "node_modules"),
7951
+ (0, import_path11.join)(cacheDir, "package.json"),
7952
+ (0, import_path11.join)(cacheDir, "package-lock.json"),
8488
7953
  ...extras
8489
7954
  ];
8490
7955
  for (const p of paths) {
8491
7956
  try {
8492
- await import_fs12.default.promises.rm(p, { recursive: true, force: true });
7957
+ await import_fs11.default.promises.rm(p, { recursive: true, force: true });
8493
7958
  } catch (err) {
8494
7959
  console.warn(
8495
7960
  `could not clean up ${p}: ${err instanceof Error ? err.message : String(err)}`
@@ -8499,7 +7964,7 @@ async function cleanCacheArtifacts(cacheDir, extras = []) {
8499
7964
  }
8500
7965
  async function isClientGenerated(pythonPath, env) {
8501
7966
  try {
8502
- await (0, import_execa6.default)(pythonPath, ["-c", "import prisma.client"], {
7967
+ await (0, import_execa5.default)(pythonPath, ["-c", "import prisma.client"], {
8503
7968
  env,
8504
7969
  stdio: "pipe"
8505
7970
  });
@@ -8513,7 +7978,7 @@ var prismaQuirk = {
8513
7978
  async run(ctx) {
8514
7979
  const { venvPath, pythonEnv, workPath } = ctx;
8515
7980
  const pythonPath = getVenvPythonBin(venvPath);
8516
- const runtimeCacheDir = (0, import_path12.join)(
7981
+ const runtimeCacheDir = (0, import_path11.join)(
8517
7982
  LAMBDA_ROOT2,
8518
7983
  resolveVendorDir(),
8519
7984
  "prisma",
@@ -8523,7 +7988,7 @@ var prismaQuirk = {
8523
7988
  let sitePackages;
8524
7989
  for (const dir of sitePackagesDirs) {
8525
7990
  try {
8526
- await import_fs12.default.promises.access((0, import_path12.join)(dir, "prisma"));
7991
+ await import_fs11.default.promises.access((0, import_path11.join)(dir, "prisma"));
8527
7992
  sitePackages = dir;
8528
7993
  break;
8529
7994
  } catch {
@@ -8535,21 +8000,21 @@ var prismaQuirk = {
8535
8000
  );
8536
8001
  return {};
8537
8002
  }
8538
- const cacheDir = (0, import_path12.join)(sitePackages, "prisma", "__bincache__");
8539
- await import_fs12.default.promises.mkdir(cacheDir, { recursive: true });
8003
+ const cacheDir = (0, import_path11.join)(sitePackages, "prisma", "__bincache__");
8004
+ await import_fs11.default.promises.mkdir(cacheDir, { recursive: true });
8540
8005
  const generateEnv = {
8541
8006
  ...pythonEnv,
8542
8007
  PRISMA_BINARY_CACHE_DIR: cacheDir
8543
8008
  };
8544
- const generatedDir = (0, import_path12.join)(workPath, "_prisma_generated");
8545
- const dummySchemaPath = (0, import_path12.join)(workPath, DUMMY_SCHEMA_NAME);
8546
- await import_fs12.default.promises.writeFile(
8009
+ const generatedDir = (0, import_path11.join)(workPath, "_prisma_generated");
8010
+ const dummySchemaPath = (0, import_path11.join)(workPath, DUMMY_SCHEMA_NAME);
8011
+ await import_fs11.default.promises.writeFile(
8547
8012
  dummySchemaPath,
8548
8013
  buildDummySchema(generatedDir)
8549
8014
  );
8550
- (0, import_build_utils15.debug)(`Running prisma generate (dummy) with cache dir: ${cacheDir}`);
8015
+ (0, import_build_utils14.debug)(`Running prisma generate (dummy) with cache dir: ${cacheDir}`);
8551
8016
  try {
8552
- const dummyResult = await (0, import_execa6.default)(
8017
+ const dummyResult = await (0, import_execa5.default)(
8553
8018
  pythonPath,
8554
8019
  ["-m", "prisma", "generate", `--schema=${dummySchemaPath}`],
8555
8020
  {
@@ -8559,11 +8024,11 @@ var prismaQuirk = {
8559
8024
  }
8560
8025
  );
8561
8026
  if (dummyResult.stdout)
8562
- (0, import_build_utils15.debug)(`prisma generate (dummy) stdout: ${dummyResult.stdout}`);
8027
+ (0, import_build_utils14.debug)(`prisma generate (dummy) stdout: ${dummyResult.stdout}`);
8563
8028
  if (dummyResult.stderr)
8564
- (0, import_build_utils15.debug)(`prisma generate (dummy) stderr: ${dummyResult.stderr}`);
8029
+ (0, import_build_utils14.debug)(`prisma generate (dummy) stderr: ${dummyResult.stderr}`);
8565
8030
  } catch (err) {
8566
- throw new import_build_utils15.NowBuildError({
8031
+ throw new import_build_utils14.NowBuildError({
8567
8032
  code: "PRISMA_GENERATE_FAILED",
8568
8033
  message: `Prisma engine download failed during \`prisma generate\`. Check that your prisma version is compatible with this Python version.
8569
8034
  ` + execErrorMessage(err)
@@ -8571,47 +8036,47 @@ var prismaQuirk = {
8571
8036
  }
8572
8037
  const srcBinaryPrefix = `query-engine-${getLambdaBinaryTarget()}`;
8573
8038
  const runtimeName = `prisma-query-engine-rhel-openssl-${RUNTIME_OPENSSL_VERSION}.x`;
8574
- const nodeModulesDir = (0, import_path12.join)(cacheDir, "node_modules", "prisma");
8039
+ const nodeModulesDir = (0, import_path11.join)(cacheDir, "node_modules", "prisma");
8575
8040
  let engineCopied = false;
8576
8041
  try {
8577
- const entries = await import_fs12.default.promises.readdir(nodeModulesDir);
8042
+ const entries = await import_fs11.default.promises.readdir(nodeModulesDir);
8578
8043
  for (const entry of entries) {
8579
8044
  if (!entry.startsWith(srcBinaryPrefix))
8580
8045
  continue;
8581
- const srcPath = (0, import_path12.join)(nodeModulesDir, entry);
8582
- const destPath = (0, import_path12.join)(cacheDir, runtimeName);
8046
+ const srcPath = (0, import_path11.join)(nodeModulesDir, entry);
8047
+ const destPath = (0, import_path11.join)(cacheDir, runtimeName);
8583
8048
  try {
8584
- await import_fs12.default.promises.access(destPath);
8585
- (0, import_build_utils15.debug)(`Engine binary: ${runtimeName} already exists, skipping`);
8049
+ await import_fs11.default.promises.access(destPath);
8050
+ (0, import_build_utils14.debug)(`Engine binary: ${runtimeName} already exists, skipping`);
8586
8051
  } catch {
8587
- (0, import_build_utils15.debug)(`Engine binary: copying ${entry} -> ${runtimeName}`);
8588
- await import_fs12.default.promises.copyFile(srcPath, destPath);
8052
+ (0, import_build_utils14.debug)(`Engine binary: copying ${entry} -> ${runtimeName}`);
8053
+ await import_fs11.default.promises.copyFile(srcPath, destPath);
8589
8054
  }
8590
8055
  engineCopied = true;
8591
8056
  }
8592
8057
  } catch (err) {
8593
- throw new import_build_utils15.NowBuildError({
8058
+ throw new import_build_utils14.NowBuildError({
8594
8059
  code: "PRISMA_ENGINE_NOT_FOUND",
8595
8060
  message: `could not read Prisma engine directory "${nodeModulesDir}". This may indicate an incompatible prisma version.
8596
8061
  ` + (err instanceof Error ? err.message : String(err))
8597
8062
  });
8598
8063
  }
8599
8064
  if (!engineCopied) {
8600
- throw new import_build_utils15.NowBuildError({
8065
+ throw new import_build_utils14.NowBuildError({
8601
8066
  code: "PRISMA_ENGINE_NOT_FOUND",
8602
8067
  message: `could not find engine binary matching "${srcBinaryPrefix}*" in "${nodeModulesDir}". This may indicate an incompatible prisma version or an unsupported platform (${process.arch}).`
8603
8068
  });
8604
8069
  }
8605
- const shimPath = (0, import_path12.join)(cacheDir, "openssl");
8606
- await import_fs12.default.promises.writeFile(
8070
+ const shimPath = (0, import_path11.join)(cacheDir, "openssl");
8071
+ await import_fs11.default.promises.writeFile(
8607
8072
  shimPath,
8608
8073
  `#!/bin/sh
8609
8074
  echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIME_OPENSSL_VERSION}.0)"
8610
8075
  `
8611
8076
  );
8612
- await import_fs12.default.promises.chmod(shimPath, 493);
8077
+ await import_fs11.default.promises.chmod(shimPath, 493);
8613
8078
  for (const p of [generatedDir, dummySchemaPath]) {
8614
- await import_fs12.default.promises.rm(p, { recursive: true, force: true });
8079
+ await import_fs11.default.promises.rm(p, { recursive: true, force: true });
8615
8080
  }
8616
8081
  await cleanCacheArtifacts(cacheDir);
8617
8082
  const generateMode = (process.env.VERCEL_PRISMA_GENERATE_CLIENT ?? "auto").toLowerCase();
@@ -8624,16 +8089,16 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
8624
8089
  pythonEnv
8625
8090
  );
8626
8091
  if (clientAlreadyGenerated) {
8627
- (0, import_build_utils15.debug)(
8092
+ (0, import_build_utils14.debug)(
8628
8093
  "Prisma quirk: client already generated, skipping user schema generate"
8629
8094
  );
8630
8095
  shouldGenerate = false;
8631
8096
  }
8632
8097
  }
8633
8098
  if (shouldGenerate) {
8634
- (0, import_build_utils15.debug)(`Running prisma generate with user schema: ${userSchema}`);
8099
+ (0, import_build_utils14.debug)(`Running prisma generate with user schema: ${userSchema}`);
8635
8100
  try {
8636
- const userResult = await (0, import_execa6.default)(
8101
+ const userResult = await (0, import_execa5.default)(
8637
8102
  pythonPath,
8638
8103
  ["-m", "prisma", "generate", `--schema=${userSchema}`],
8639
8104
  {
@@ -8643,11 +8108,11 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
8643
8108
  }
8644
8109
  );
8645
8110
  if (userResult.stdout)
8646
- (0, import_build_utils15.debug)(`prisma generate stdout: ${userResult.stdout}`);
8111
+ (0, import_build_utils14.debug)(`prisma generate stdout: ${userResult.stdout}`);
8647
8112
  if (userResult.stderr)
8648
- (0, import_build_utils15.debug)(`prisma generate stderr: ${userResult.stderr}`);
8113
+ (0, import_build_utils14.debug)(`prisma generate stderr: ${userResult.stderr}`);
8649
8114
  } catch (err) {
8650
- throw new import_build_utils15.NowBuildError({
8115
+ throw new import_build_utils14.NowBuildError({
8651
8116
  code: "PRISMA_GENERATE_FAILED",
8652
8117
  message: `\`prisma generate\` failed for schema "${userSchema}".
8653
8118
  ` + execErrorMessage(err)
@@ -8658,12 +8123,12 @@ echo "OpenSSL ${RUNTIME_OPENSSL_VERSION}.0 1 Jan 2024 (Library: OpenSSL ${RUNTIM
8658
8123
  }
8659
8124
  try {
8660
8125
  const allFiles = await collectFiles(
8661
- (0, import_path12.join)(sitePackages, "prisma"),
8126
+ (0, import_path11.join)(sitePackages, "prisma"),
8662
8127
  sitePackages
8663
8128
  );
8664
8129
  const count = await (0, import_python_analysis7.extendDistRecord)(sitePackages, "prisma", allFiles);
8665
8130
  if (count > 0) {
8666
- (0, import_build_utils15.debug)(`Appended ${count} entries to prisma RECORD`);
8131
+ (0, import_build_utils14.debug)(`Appended ${count} entries to prisma RECORD`);
8667
8132
  }
8668
8133
  } catch (err) {
8669
8134
  console.warn(
@@ -8757,13 +8222,13 @@ async function runQuirks(ctx) {
8757
8222
  (0, import_python_analysis8.normalizePackageName)(quirk.dependency)
8758
8223
  );
8759
8224
  if (!installed) {
8760
- (0, import_build_utils16.debug)(`Quirk "${quirk.dependency}": not installed, skipping`);
8225
+ (0, import_build_utils15.debug)(`Quirk "${quirk.dependency}": not installed, skipping`);
8761
8226
  }
8762
8227
  return installed;
8763
8228
  });
8764
8229
  const sorted = toposortQuirks(activated);
8765
8230
  for (const quirk of sorted) {
8766
- (0, import_build_utils16.debug)(`Quirk "${quirk.dependency}": detected, running fix-up`);
8231
+ (0, import_build_utils15.debug)(`Quirk "${quirk.dependency}": detected, running fix-up`);
8767
8232
  const result = await quirk.run(ctx);
8768
8233
  if (result.env) {
8769
8234
  Object.assign(mergedEnv, result.env);
@@ -8784,14 +8249,14 @@ async function runQuirks(ctx) {
8784
8249
  }
8785
8250
 
8786
8251
  // src/django.ts
8787
- var import_fs13 = __toESM(require("fs"));
8788
- var import_path13 = require("path");
8789
- var import_execa7 = __toESM(require_execa());
8790
- var import_build_utils17 = require("@vercel/build-utils");
8791
- var scriptPath2 = (0, import_path13.join)(__dirname, "..", "templates", "vc_django_settings.py");
8792
- var script2 = import_fs13.default.readFileSync(scriptPath2, "utf-8");
8252
+ var import_fs12 = __toESM(require("fs"));
8253
+ var import_path12 = require("path");
8254
+ var import_execa6 = __toESM(require_execa());
8255
+ var import_build_utils16 = require("@vercel/build-utils");
8256
+ var scriptPath2 = (0, import_path12.join)(__dirname, "..", "templates", "vc_django_settings.py");
8257
+ var script2 = import_fs12.default.readFileSync(scriptPath2, "utf-8");
8793
8258
  async function getDjangoSettings(projectDir, env) {
8794
- const { stdout } = await (0, import_execa7.default)("python", ["-c", script2], {
8259
+ const { stdout } = await (0, import_execa6.default)("python", ["-c", script2], {
8795
8260
  env,
8796
8261
  cwd: projectDir
8797
8262
  });
@@ -8817,21 +8282,21 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
8817
8282
  const installedApps = djangoSettings["INSTALLED_APPS"] ?? [];
8818
8283
  const staticfilesDirs = djangoSettings["STATICFILES_DIRS"] ?? [];
8819
8284
  const staticSourceDirs = [
8820
- ...installedApps.map((app) => (0, import_path13.join)(djangoPath, ...app.split("."), "static")),
8285
+ ...installedApps.map((app) => (0, import_path12.join)(djangoPath, ...app.split("."), "static")),
8821
8286
  // TODO: Deal with optional prefixes in STATICFILES_DIRS.
8822
8287
  ...staticfilesDirs.map((d) => Array.isArray(d) ? d[1] : d)
8823
- ].filter((d) => import_fs13.default.existsSync(d));
8288
+ ].filter((d) => import_fs12.default.existsSync(d));
8824
8289
  if (storageBackend.startsWith("storages.backends.")) {
8825
8290
  console.log(
8826
8291
  "django-storages detected \u2014 running collectstatic with original settings"
8827
8292
  );
8828
- await (0, import_execa7.default)(pythonPath, ["manage.py", "collectstatic", "--noinput"], {
8293
+ await (0, import_execa6.default)(pythonPath, ["manage.py", "collectstatic", "--noinput"], {
8829
8294
  env: { ...env, DJANGO_SETTINGS_MODULE: settingsModule },
8830
8295
  cwd: djangoPath
8831
8296
  });
8832
8297
  return {
8833
8298
  staticSourceDirs,
8834
- staticRoot: staticRoot ? (0, import_path13.resolve)(djangoPath, staticRoot) : null,
8299
+ staticRoot: staticRoot ? (0, import_path12.resolve)(djangoPath, staticRoot) : null,
8835
8300
  cdnOutputDir: null,
8836
8301
  manifestRelPath: null
8837
8302
  };
@@ -8843,9 +8308,9 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
8843
8308
  return null;
8844
8309
  }
8845
8310
  const staticUrlPath = staticUrl.replace(/^\/|\/$/g, "") || "static";
8846
- const staticOutputDir = (0, import_path13.join)(outputStaticDir, staticUrlPath);
8847
- await import_fs13.default.promises.mkdir(staticOutputDir, { recursive: true });
8848
- const shimPath = (0, import_path13.join)(djangoPath, "_vercel_collectstatic_settings.py");
8311
+ const staticOutputDir = (0, import_path12.join)(outputStaticDir, staticUrlPath);
8312
+ await import_fs12.default.promises.mkdir(staticOutputDir, { recursive: true });
8313
+ const shimPath = (0, import_path12.join)(djangoPath, "_vercel_collectstatic_settings.py");
8849
8314
  const shimLines = [
8850
8315
  `from ${settingsModule} import *`,
8851
8316
  `STATIC_ROOT = ${JSON.stringify(staticOutputDir)}`
@@ -8853,10 +8318,10 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
8853
8318
  if (whitenoiseUseFinders) {
8854
8319
  shimLines.push(`WHITENOISE_USE_FINDERS = False`);
8855
8320
  }
8856
- await import_fs13.default.promises.writeFile(shimPath, shimLines.join("\n") + "\n");
8321
+ await import_fs12.default.promises.writeFile(shimPath, shimLines.join("\n") + "\n");
8857
8322
  try {
8858
8323
  console.log("Running collectstatic...");
8859
- await (0, import_execa7.default)(pythonPath, ["manage.py", "collectstatic", "--noinput"], {
8324
+ await (0, import_execa6.default)(pythonPath, ["manage.py", "collectstatic", "--noinput"], {
8860
8325
  env: {
8861
8326
  ...env,
8862
8327
  DJANGO_SETTINGS_MODULE: "_vercel_collectstatic_settings"
@@ -8864,7 +8329,7 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
8864
8329
  cwd: djangoPath
8865
8330
  });
8866
8331
  } finally {
8867
- await import_fs13.default.promises.unlink(shimPath).catch(() => {
8332
+ await import_fs12.default.promises.unlink(shimPath).catch(() => {
8868
8333
  });
8869
8334
  }
8870
8335
  const MANIFEST_STORAGE_BACKENDS = [
@@ -8873,64 +8338,555 @@ async function runDjangoCollectStatic(venvPath, workPath, djangoPath, env, outpu
8873
8338
  ];
8874
8339
  let manifestRelPath = null;
8875
8340
  if (MANIFEST_STORAGE_BACKENDS.includes(storageBackend) && staticRoot) {
8876
- const manifestSrc = (0, import_path13.join)(staticOutputDir, "staticfiles.json");
8877
- const resolvedStaticRoot = (0, import_path13.resolve)(djangoPath, staticRoot);
8878
- const manifestDest = (0, import_path13.join)(resolvedStaticRoot, "staticfiles.json");
8879
- await import_fs13.default.promises.mkdir(resolvedStaticRoot, { recursive: true });
8880
- await import_fs13.default.promises.copyFile(manifestSrc, manifestDest);
8881
- manifestRelPath = (0, import_path13.relative)(workPath, manifestDest);
8882
- (0, import_build_utils17.debug)(`Copied staticfiles.json to ${manifestDest} for Lambda bundle`);
8341
+ const manifestSrc = (0, import_path12.join)(staticOutputDir, "staticfiles.json");
8342
+ const resolvedStaticRoot = (0, import_path12.resolve)(djangoPath, staticRoot);
8343
+ const manifestDest = (0, import_path12.join)(resolvedStaticRoot, "staticfiles.json");
8344
+ await import_fs12.default.promises.mkdir(resolvedStaticRoot, { recursive: true });
8345
+ await import_fs12.default.promises.copyFile(manifestSrc, manifestDest);
8346
+ manifestRelPath = (0, import_path12.relative)(workPath, manifestDest);
8347
+ (0, import_build_utils16.debug)(`Copied staticfiles.json to ${manifestDest} for Lambda bundle`);
8883
8348
  }
8884
8349
  return {
8885
8350
  staticSourceDirs,
8886
- staticRoot: staticRoot ? (0, import_path13.resolve)(djangoPath, staticRoot) : null,
8351
+ staticRoot: staticRoot ? (0, import_path12.resolve)(djangoPath, staticRoot) : null,
8887
8352
  cdnOutputDir: outputStaticDir,
8888
8353
  manifestRelPath
8889
8354
  };
8890
8355
  }
8891
8356
 
8892
8357
  // src/index.ts
8893
- var import_python_analysis9 = require("@vercel/python-analysis");
8358
+ var import_python_analysis10 = require("@vercel/python-analysis");
8894
8359
 
8895
- // src/subscribers.ts
8896
- var import_path15 = require("path");
8897
- var import_fs15 = __toESM(require("fs"));
8898
- var import_build_utils18 = require("@vercel/build-utils");
8899
-
8900
- // src/module-entrypoint.ts
8901
- var import_path14 = require("path");
8902
- var import_fs14 = __toESM(require("fs"));
8903
- var MODULE_ATTR_RE = /^([A-Za-z_][\w]*(?:\.[A-Za-z_][\w]*)*):([A-Za-z_][\w]*)$/;
8904
- function parseModuleEntrypoint(value) {
8905
- const match = MODULE_ATTR_RE.exec(value);
8906
- if (!match) {
8907
- return null;
8908
- }
8909
- return {
8910
- moduleName: match[1],
8911
- variableName: match[2],
8912
- filePath: `${match[1].replace(/\./g, "/")}.py`
8913
- };
8914
- }
8915
- function getModuleEntrypointName({
8916
- moduleName,
8917
- variableName
8918
- }) {
8919
- return `${moduleName.replace(/\./g, "-")}_${variableName}`;
8920
- }
8921
- function safePathSegment(value) {
8922
- return [...value].map((char) => {
8923
- if (char === "_") {
8924
- return "__";
8925
- }
8926
- return /[A-Za-z0-9-]/.test(char) ? char : `_${char.charCodeAt(0).toString(16).toUpperCase().padStart(2, "0")}`;
8360
+ // src/compileall.ts
8361
+ var import_execa7 = __toESM(require_execa());
8362
+ var import_build_utils17 = require("@vercel/build-utils");
8363
+ var import_fs13 = __toESM(require("fs"));
8364
+ var import_path13 = require("path");
8365
+ var COMPILEALL_TIMEOUT_MS = 5 * 60 * 1e3;
8366
+ var PYCACHE_PREFIX_DIR = "_vc_pycache";
8367
+ var RUNTIME_PYCACHE_PREFIX = `/var/task/${PYCACHE_PREFIX_DIR}`;
8368
+ function isCompileAllFlagEnabled() {
8369
+ const val = process.env.VERCEL_PYTHON_COMPILEALL;
8370
+ if (val === void 0 || val === "")
8371
+ return false;
8372
+ const lower = val.toLowerCase();
8373
+ return lower === "1" || lower === "true";
8374
+ }
8375
+ function shouldCompileAll({
8376
+ isDev,
8377
+ hasCustomCommand,
8378
+ hasPreDeployCommand
8379
+ }) {
8380
+ if (isDev)
8381
+ return false;
8382
+ if (hasCustomCommand)
8383
+ return false;
8384
+ if (hasPreDeployCommand)
8385
+ return false;
8386
+ return isCompileAllFlagEnabled();
8387
+ }
8388
+ async function runCompileAll({
8389
+ pythonBin,
8390
+ filesOrDirectories,
8391
+ env,
8392
+ excludeRegex,
8393
+ pycachePrefix
8394
+ }) {
8395
+ if (filesOrDirectories.length === 0)
8396
+ return;
8397
+ const args = [
8398
+ "-m",
8399
+ "compileall",
8400
+ "-q",
8401
+ "-j",
8402
+ "0",
8403
+ "-f",
8404
+ "--invalidation-mode",
8405
+ "unchecked-hash",
8406
+ ...excludeRegex ? ["-x", excludeRegex] : [],
8407
+ ...filesOrDirectories
8408
+ ];
8409
+ const baseEnv = env || process.env;
8410
+ const subprocessEnv = pycachePrefix ? { ...baseEnv, PYTHONPYCACHEPREFIX: pycachePrefix } : baseEnv;
8411
+ try {
8412
+ await (0, import_execa7.default)(pythonBin, args, {
8413
+ env: subprocessEnv,
8414
+ timeout: COMPILEALL_TIMEOUT_MS
8415
+ });
8416
+ } catch (err) {
8417
+ (0, import_build_utils17.debug)(`compileall error details: ${JSON.stringify(err)}`);
8418
+ }
8419
+ }
8420
+ function derivePycPath(pyRelPath, pythonMajor, pythonMinor) {
8421
+ if (!pyRelPath.endsWith(".py"))
8422
+ return null;
8423
+ const lastSlash = pyRelPath.lastIndexOf("/");
8424
+ const dir = lastSlash === -1 ? "" : pyRelPath.slice(0, lastSlash + 1);
8425
+ const baseName = pyRelPath.slice(lastSlash + 1, -3);
8426
+ return `${dir}__pycache__/${baseName}.cpython-${pythonMajor}${pythonMinor}.pyc`;
8427
+ }
8428
+ function derivePrefixPycRelPath(pyRelPath, pythonMajor, pythonMinor) {
8429
+ if (!pyRelPath.endsWith(".py"))
8430
+ return null;
8431
+ return `${pyRelPath.slice(0, -3)}.cpython-${pythonMajor}${pythonMinor}.pyc`;
8432
+ }
8433
+ function stripPycachePrefixRoot(head) {
8434
+ const pycachePathSeparators = /* @__PURE__ */ new Set(["/", "\\"]);
8435
+ if (head.length > 1 && head[1] === ":" && !pycachePathSeparators.has(head[0])) {
8436
+ head = head.slice(2);
8437
+ }
8438
+ let start = 0;
8439
+ while (start < head.length && pycachePathSeparators.has(head[start])) {
8440
+ start++;
8441
+ }
8442
+ return head.slice(start);
8443
+ }
8444
+ function deriveStagedPycFsPath(stagingDir, srcAbsPath, pythonMajor, pythonMinor) {
8445
+ const rel = derivePrefixPycRelPath(
8446
+ stripPycachePrefixRoot(srcAbsPath),
8447
+ pythonMajor,
8448
+ pythonMinor
8449
+ );
8450
+ if (!rel)
8451
+ return null;
8452
+ return (0, import_path13.join)(stagingDir, rel.replaceAll("/", import_path13.sep));
8453
+ }
8454
+ function derivePrefixPycBundlePath(runtimeAbsPath, pythonMajor, pythonMinor) {
8455
+ const rel = derivePrefixPycRelPath(
8456
+ stripPycachePrefixRoot(runtimeAbsPath),
8457
+ pythonMajor,
8458
+ pythonMinor
8459
+ );
8460
+ if (!rel)
8461
+ return null;
8462
+ return `${PYCACHE_PREFIX_DIR}/${rel}`;
8463
+ }
8464
+ var COMPILEALL_APP_EXCLUDED_DIRS = [
8465
+ ".git",
8466
+ ".vercel",
8467
+ ".pnpm-store",
8468
+ "node_modules",
8469
+ ".next",
8470
+ ".nuxt",
8471
+ ".venv",
8472
+ "venv",
8473
+ "__pycache__",
8474
+ ".mypy_cache",
8475
+ ".ruff_cache",
8476
+ "public"
8477
+ ];
8478
+ function escapePythonRegex(value) {
8479
+ return value.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
8480
+ }
8481
+ function getCompileAllAppExcludeRegex(workPath) {
8482
+ const excludedDirs = COMPILEALL_APP_EXCLUDED_DIRS.map(escapePythonRegex).join("|");
8483
+ return `${escapePythonRegex(workPath)}[/\\\\](?:${excludedDirs})(?:[/\\\\]|$)`;
8484
+ }
8485
+ async function collectAppPrefixBytecodeFiles({
8486
+ stagingDir,
8487
+ workPath,
8488
+ files: appFiles,
8489
+ runtimeTaskRoot,
8490
+ pythonMajor,
8491
+ pythonMinor
8492
+ }) {
8493
+ const pending = [];
8494
+ for (const bundlePath of Object.keys(appFiles)) {
8495
+ if (!bundlePath.endsWith(".py"))
8496
+ continue;
8497
+ const stagedFsPath = deriveStagedPycFsPath(
8498
+ stagingDir,
8499
+ (0, import_path13.join)(workPath, bundlePath.replaceAll("/", import_path13.sep)),
8500
+ pythonMajor,
8501
+ pythonMinor
8502
+ );
8503
+ const pycBundlePath = derivePrefixPycBundlePath(
8504
+ `${runtimeTaskRoot}/${bundlePath}`,
8505
+ pythonMajor,
8506
+ pythonMinor
8507
+ );
8508
+ if (!stagedFsPath || !pycBundlePath)
8509
+ continue;
8510
+ pending.push({ bundlePath: pycBundlePath, srcFsPath: stagedFsPath });
8511
+ }
8512
+ const results = await Promise.all(
8513
+ pending.map(async ({ bundlePath, srcFsPath }) => {
8514
+ try {
8515
+ const stats = await import_fs13.default.promises.stat(srcFsPath);
8516
+ return { bundlePath, srcFsPath, size: stats.size };
8517
+ } catch {
8518
+ return null;
8519
+ }
8520
+ })
8521
+ );
8522
+ const files = {};
8523
+ const perItemSizes = /* @__PURE__ */ new Map();
8524
+ let totalSize = 0;
8525
+ for (const result of results) {
8526
+ if (!result)
8527
+ continue;
8528
+ files[result.bundlePath] = new import_build_utils17.FileFsRef({
8529
+ fsPath: result.srcFsPath,
8530
+ size: result.size
8531
+ });
8532
+ perItemSizes.set(result.bundlePath, result.size);
8533
+ totalSize += result.size;
8534
+ }
8535
+ return { files, totalSize, perItemSizes };
8536
+ }
8537
+ async function collectAppBytecodeFiles({
8538
+ workPath,
8539
+ files: appFiles,
8540
+ pythonMajor,
8541
+ pythonMinor
8542
+ }) {
8543
+ const pending = [];
8544
+ for (const bundlePath of Object.keys(appFiles)) {
8545
+ const pycRel = derivePycPath(bundlePath, pythonMajor, pythonMinor);
8546
+ if (!pycRel)
8547
+ continue;
8548
+ pending.push({
8549
+ bundlePath: pycRel,
8550
+ srcFsPath: (0, import_path13.join)(workPath, pycRel.replaceAll("/", import_path13.sep))
8551
+ });
8552
+ }
8553
+ const results = await Promise.all(
8554
+ pending.map(async ({ bundlePath, srcFsPath }) => {
8555
+ try {
8556
+ const stats = await import_fs13.default.promises.stat(srcFsPath);
8557
+ return { bundlePath, srcFsPath, size: stats.size };
8558
+ } catch {
8559
+ return null;
8560
+ }
8561
+ })
8562
+ );
8563
+ const files = {};
8564
+ const perItemSizes = /* @__PURE__ */ new Map();
8565
+ let totalSize = 0;
8566
+ for (const result of results) {
8567
+ if (!result)
8568
+ continue;
8569
+ files[result.bundlePath] = new import_build_utils17.FileFsRef({
8570
+ fsPath: result.srcFsPath,
8571
+ size: result.size
8572
+ });
8573
+ perItemSizes.set(result.bundlePath, result.size);
8574
+ totalSize += result.size;
8575
+ }
8576
+ return { files, totalSize, perItemSizes };
8577
+ }
8578
+
8579
+ // src/installed-distributions.ts
8580
+ var import_fs14 = __toESM(require("fs"));
8581
+ var import_path14 = require("path");
8582
+ var import_build_utils18 = require("@vercel/build-utils");
8583
+ var import_python_analysis9 = require("@vercel/python-analysis");
8584
+ var STRIP_BASENAMES = /* @__PURE__ */ new Set([
8585
+ "py.typed",
8586
+ "WHEEL",
8587
+ "INSTALLER",
8588
+ "direct_url.json"
8589
+ ]);
8590
+ function shouldStripVendorFile(filePath) {
8591
+ const segments = filePath.split(import_path14.sep);
8592
+ if (segments.includes("__pycache__"))
8593
+ return true;
8594
+ const name = segments[segments.length - 1] ?? "";
8595
+ if (name.endsWith(".pyc") || name.endsWith(".pyi"))
8596
+ return true;
8597
+ if (STRIP_BASENAMES.has(name))
8598
+ return true;
8599
+ return false;
8600
+ }
8601
+ function getDistributionFileGroups({
8602
+ sitePackageDirs,
8603
+ distributions,
8604
+ includePackages
8605
+ }) {
8606
+ if (includePackages?.length === 0) {
8607
+ return [];
8608
+ }
8609
+ const includeSet = includePackages ? new Set(includePackages.map(import_python_analysis9.normalizePackageName)) : null;
8610
+ const groups = [];
8611
+ for (const dir of sitePackageDirs) {
8612
+ const dirDistributions = distributions.get(dir);
8613
+ if (!dirDistributions)
8614
+ continue;
8615
+ const sitePackagesDir = (0, import_path14.resolve)(dir);
8616
+ for (const [name, distribution] of dirDistributions) {
8617
+ const packageName = (0, import_python_analysis9.normalizePackageName)(name);
8618
+ if (includeSet && !includeSet.has(packageName))
8619
+ continue;
8620
+ const files = [];
8621
+ for (const record of distribution.files) {
8622
+ const absolutePath = (0, import_path14.resolve)(
8623
+ sitePackagesDir,
8624
+ record.path.replaceAll("/", import_path14.sep)
8625
+ );
8626
+ const relativePath = (0, import_path14.relative)(sitePackagesDir, absolutePath);
8627
+ if (relativePath === "" || relativePath === ".." || relativePath.startsWith(`..${import_path14.sep}`) || (0, import_path14.isAbsolute)(relativePath)) {
8628
+ continue;
8629
+ }
8630
+ files.push({ absolutePath, relativePath, record });
8631
+ }
8632
+ groups.push({ packageName, sitePackagesDir, files });
8633
+ }
8634
+ }
8635
+ return groups;
8636
+ }
8637
+ var InstalledPythonDistributions = class _InstalledPythonDistributions {
8638
+ static async load({
8639
+ venvPath,
8640
+ pythonMajor,
8641
+ pythonMinor
8642
+ }) {
8643
+ const sitePackageDirs = await getVenvSitePackagesDirs(venvPath);
8644
+ const distributions = /* @__PURE__ */ new Map();
8645
+ for (const dir of sitePackageDirs) {
8646
+ try {
8647
+ await import_fs14.default.promises.access(dir);
8648
+ } catch {
8649
+ continue;
8650
+ }
8651
+ distributions.set(dir, await (0, import_python_analysis9.scanDistributions)(dir));
8652
+ }
8653
+ return new _InstalledPythonDistributions({
8654
+ sitePackageDirs,
8655
+ distributions,
8656
+ pythonMajor,
8657
+ pythonMinor
8658
+ });
8659
+ }
8660
+ constructor(options) {
8661
+ this.sitePackageDirs = options.sitePackageDirs;
8662
+ this.distributions = options.distributions;
8663
+ this.pythonMajor = options.pythonMajor;
8664
+ this.pythonMinor = options.pythonMinor;
8665
+ }
8666
+ async mirrorPackagesIntoVendor({
8667
+ vendorDirName,
8668
+ includePackages
8669
+ }) {
8670
+ const pending = [];
8671
+ const distributionGroups = getDistributionFileGroups({
8672
+ sitePackageDirs: this.sitePackageDirs,
8673
+ distributions: this.distributions,
8674
+ includePackages
8675
+ });
8676
+ for (const { files } of distributionGroups) {
8677
+ for (const { absolutePath, relativePath, record } of files) {
8678
+ if (shouldStripVendorFile(relativePath))
8679
+ continue;
8680
+ pending.push({
8681
+ bundlePath: (0, import_path14.join)(vendorDirName, relativePath).replace(/\\/g, "/"),
8682
+ srcFsPath: absolutePath,
8683
+ recordSize: record.size != null ? Number(record.size) : void 0
8684
+ });
8685
+ }
8686
+ }
8687
+ const results = await Promise.all(
8688
+ pending.map(async ({ bundlePath, srcFsPath, recordSize }) => {
8689
+ try {
8690
+ if (recordSize === void 0) {
8691
+ const stats = await import_fs14.default.promises.stat(srcFsPath);
8692
+ return { bundlePath, srcFsPath, size: stats.size };
8693
+ }
8694
+ await import_fs14.default.promises.access(srcFsPath);
8695
+ return { bundlePath, srcFsPath, size: recordSize };
8696
+ } catch {
8697
+ return null;
8698
+ }
8699
+ })
8700
+ );
8701
+ const vendorFiles = {};
8702
+ for (const result of results) {
8703
+ if (!result)
8704
+ continue;
8705
+ vendorFiles[result.bundlePath] = new import_build_utils18.FileFsRef({
8706
+ fsPath: result.srcFsPath,
8707
+ size: result.size
8708
+ });
8709
+ }
8710
+ (0, import_build_utils18.debug)(
8711
+ `Mirrored ${Object.keys(vendorFiles).length} files` + (includePackages ? ` from ${includePackages.length} packages` : "")
8712
+ );
8713
+ return vendorFiles;
8714
+ }
8715
+ async calculatePerPackageSizes() {
8716
+ const sizes = /* @__PURE__ */ new Map();
8717
+ const distributionGroups = getDistributionFileGroups({
8718
+ sitePackageDirs: this.sitePackageDirs,
8719
+ distributions: this.distributions
8720
+ });
8721
+ for (const { packageName, files } of distributionGroups) {
8722
+ let knownSize = 0;
8723
+ const statPromises = [];
8724
+ for (const { absolutePath, relativePath, record } of files) {
8725
+ if (shouldStripVendorFile(relativePath))
8726
+ continue;
8727
+ if (record.size != null) {
8728
+ knownSize += Number(record.size);
8729
+ } else {
8730
+ statPromises.push(
8731
+ import_fs14.default.promises.stat(absolutePath).then((stats) => stats.size).catch(() => 0)
8732
+ );
8733
+ }
8734
+ }
8735
+ const statSizes = await Promise.all(statPromises);
8736
+ sizes.set(
8737
+ packageName,
8738
+ statSizes.reduce((total, size) => total + size, knownSize)
8739
+ );
8740
+ }
8741
+ return sizes;
8742
+ }
8743
+ async collectBytecodeFiles({
8744
+ vendorDirName,
8745
+ includePackages
8746
+ }) {
8747
+ if (this.pythonMajor == null || this.pythonMinor == null) {
8748
+ return { files: {}, totalSize: 0, perItemSizes: /* @__PURE__ */ new Map() };
8749
+ }
8750
+ const pending = [];
8751
+ const distributionGroups = getDistributionFileGroups({
8752
+ sitePackageDirs: this.sitePackageDirs,
8753
+ distributions: this.distributions,
8754
+ includePackages
8755
+ });
8756
+ for (const { packageName, sitePackagesDir, files } of distributionGroups) {
8757
+ for (const { relativePath } of files) {
8758
+ const pycRelativePath = derivePycPath(
8759
+ relativePath.replaceAll(import_path14.sep, "/"),
8760
+ this.pythonMajor,
8761
+ this.pythonMinor
8762
+ );
8763
+ if (!pycRelativePath)
8764
+ continue;
8765
+ const pycFilePath = pycRelativePath.replaceAll("/", import_path14.sep);
8766
+ pending.push({
8767
+ bundlePath: (0, import_path14.join)(vendorDirName, pycFilePath).replace(/\\/g, "/"),
8768
+ srcFsPath: (0, import_path14.join)(sitePackagesDir, pycFilePath),
8769
+ packageName
8770
+ });
8771
+ }
8772
+ }
8773
+ const result = await this.collectExistingBytecode(pending);
8774
+ (0, import_build_utils18.debug)(
8775
+ `Collected ${Object.keys(result.files).length} bytecode files (${(result.totalSize / (1024 * 1024)).toFixed(2)} MB)` + (includePackages ? ` from ${includePackages.length} packages` : "")
8776
+ );
8777
+ return result;
8778
+ }
8779
+ async collectPrefixBytecodeFiles({
8780
+ stagingDir,
8781
+ runtimeRoot,
8782
+ includePackages
8783
+ }) {
8784
+ if (this.pythonMajor == null || this.pythonMinor == null) {
8785
+ return { files: {}, totalSize: 0, perItemSizes: /* @__PURE__ */ new Map() };
8786
+ }
8787
+ const pending = [];
8788
+ const distributionGroups = getDistributionFileGroups({
8789
+ sitePackageDirs: this.sitePackageDirs,
8790
+ distributions: this.distributions,
8791
+ includePackages
8792
+ });
8793
+ for (const { packageName, files } of distributionGroups) {
8794
+ for (const { absolutePath, relativePath } of files) {
8795
+ if (!relativePath.endsWith(".py"))
8796
+ continue;
8797
+ const recordPath = relativePath.replaceAll(import_path14.sep, "/");
8798
+ const srcFsPath = deriveStagedPycFsPath(
8799
+ stagingDir,
8800
+ absolutePath,
8801
+ this.pythonMajor,
8802
+ this.pythonMinor
8803
+ );
8804
+ const bundlePath = derivePrefixPycBundlePath(
8805
+ `${runtimeRoot}/${recordPath}`,
8806
+ this.pythonMajor,
8807
+ this.pythonMinor
8808
+ );
8809
+ if (!srcFsPath || !bundlePath)
8810
+ continue;
8811
+ pending.push({ bundlePath, srcFsPath, packageName });
8812
+ }
8813
+ }
8814
+ const result = await this.collectExistingBytecode(pending);
8815
+ (0, import_build_utils18.debug)(
8816
+ `Collected ${Object.keys(result.files).length} prefix bytecode files (${(result.totalSize / (1024 * 1024)).toFixed(2)} MB) for runtime root ${runtimeRoot}` + (includePackages ? ` from ${includePackages.length} packages` : "")
8817
+ );
8818
+ return result;
8819
+ }
8820
+ async collectExistingBytecode(pending) {
8821
+ const results = await Promise.all(
8822
+ pending.map(async ({ bundlePath, srcFsPath, packageName }) => {
8823
+ try {
8824
+ const stats = await import_fs14.default.promises.stat(srcFsPath);
8825
+ return { bundlePath, srcFsPath, size: stats.size, packageName };
8826
+ } catch {
8827
+ return null;
8828
+ }
8829
+ })
8830
+ );
8831
+ const files = {};
8832
+ let totalSize = 0;
8833
+ const perItemSizes = /* @__PURE__ */ new Map();
8834
+ for (const result of results) {
8835
+ if (!result)
8836
+ continue;
8837
+ files[result.bundlePath] = new import_build_utils18.FileFsRef({
8838
+ fsPath: result.srcFsPath,
8839
+ size: result.size
8840
+ });
8841
+ totalSize += result.size;
8842
+ perItemSizes.set(
8843
+ result.packageName,
8844
+ (perItemSizes.get(result.packageName) ?? 0) + result.size
8845
+ );
8846
+ }
8847
+ return { files, totalSize, perItemSizes };
8848
+ }
8849
+ };
8850
+
8851
+ // src/subscribers.ts
8852
+ var import_path16 = require("path");
8853
+ var import_fs16 = __toESM(require("fs"));
8854
+ var import_build_utils19 = require("@vercel/build-utils");
8855
+
8856
+ // src/module-entrypoint.ts
8857
+ var import_path15 = require("path");
8858
+ var import_fs15 = __toESM(require("fs"));
8859
+ var MODULE_ATTR_RE = /^([A-Za-z_][\w]*(?:\.[A-Za-z_][\w]*)*):([A-Za-z_][\w]*)$/;
8860
+ function parseModuleEntrypoint(value) {
8861
+ const match = MODULE_ATTR_RE.exec(value);
8862
+ if (!match) {
8863
+ return null;
8864
+ }
8865
+ return {
8866
+ moduleName: match[1],
8867
+ variableName: match[2],
8868
+ filePath: `${match[1].replace(/\./g, "/")}.py`
8869
+ };
8870
+ }
8871
+ function getModuleEntrypointName({
8872
+ moduleName,
8873
+ variableName
8874
+ }) {
8875
+ return `${moduleName.replace(/\./g, "-")}_${variableName}`;
8876
+ }
8877
+ function safePathSegment(value) {
8878
+ return [...value].map((char) => {
8879
+ if (char === "_") {
8880
+ return "__";
8881
+ }
8882
+ return /[A-Za-z0-9-]/.test(char) ? char : `_${char.charCodeAt(0).toString(16).toUpperCase().padStart(2, "0")}`;
8927
8883
  }).join("");
8928
8884
  }
8929
8885
  async function resolveExistingEntrypoint(workPath, filePath) {
8930
8886
  const candidates = [filePath, filePath.replace(/\.py$/i, "/__init__.py")];
8931
8887
  for (const candidate of candidates) {
8932
8888
  try {
8933
- const stat = await import_fs14.default.promises.stat((0, import_path14.join)(workPath, candidate));
8889
+ const stat = await import_fs15.default.promises.stat((0, import_path15.join)(workPath, candidate));
8934
8890
  if (stat.isFile()) {
8935
8891
  return candidate;
8936
8892
  }
@@ -8977,14 +8933,14 @@ function getSubscriberOutputPath(subscriberName) {
8977
8933
  return `${SUBSCRIBER_OUTPUT_DIR}/${safePathSegment(subscriberName)}`;
8978
8934
  }
8979
8935
  function getSubscriberConsumerName(subscriberName) {
8980
- return (0, import_build_utils18.sanitizeConsumerName)(getSubscriberOutputPath(subscriberName));
8936
+ return (0, import_build_utils19.sanitizeConsumerName)(getSubscriberOutputPath(subscriberName));
8981
8937
  }
8982
8938
  async function getPyprojectSubscribers(workPath) {
8983
- const pyprojectPath = (0, import_path15.join)(workPath, "pyproject.toml");
8984
- if (!import_fs15.default.existsSync(pyprojectPath)) {
8939
+ const pyprojectPath = (0, import_path16.join)(workPath, "pyproject.toml");
8940
+ if (!import_fs16.default.existsSync(pyprojectPath)) {
8985
8941
  return [];
8986
8942
  }
8987
- const pyproject = await (0, import_build_utils18.readConfigFile)(pyprojectPath);
8943
+ const pyproject = await (0, import_build_utils19.readConfigFile)(pyprojectPath);
8988
8944
  const subscribers = pyproject?.tool?.vercel?.subscribers;
8989
8945
  if (!subscribers) {
8990
8946
  return [];
@@ -9076,16 +9032,16 @@ function parseTriggerDefaults(subscriber, config) {
9076
9032
  return defaults;
9077
9033
  }
9078
9034
  function subscriberError(message) {
9079
- return new import_build_utils18.NowBuildError({
9035
+ return new import_build_utils19.NowBuildError({
9080
9036
  code: "PYTHON_INVALID_SUBSCRIBER_CONFIG",
9081
9037
  message
9082
9038
  });
9083
9039
  }
9084
9040
 
9085
9041
  // src/workflows.ts
9086
- var import_path16 = require("path");
9087
- var import_fs16 = __toESM(require("fs"));
9088
- var import_build_utils19 = require("@vercel/build-utils");
9042
+ var import_path17 = require("path");
9043
+ var import_fs17 = __toESM(require("fs"));
9044
+ var import_build_utils20 = require("@vercel/build-utils");
9089
9045
  var WORKFLOW_OUTPUT_DIR = "_py_workflows";
9090
9046
  var WORKFLOW_TOPIC_PATTERN = "__wkf_*";
9091
9047
  var WORKFLOW_FIELD_NAMES = /* @__PURE__ */ new Set(["entrypoint"]);
@@ -9093,14 +9049,14 @@ function getWorkflowOutputPath(workflowName) {
9093
9049
  return `${WORKFLOW_OUTPUT_DIR}/${safePathSegment(workflowName)}`;
9094
9050
  }
9095
9051
  function getWorkflowConsumerName(workflowName) {
9096
- return (0, import_build_utils19.sanitizeConsumerName)(getWorkflowOutputPath(workflowName));
9052
+ return (0, import_build_utils20.sanitizeConsumerName)(getWorkflowOutputPath(workflowName));
9097
9053
  }
9098
9054
  async function getPyprojectWorkflows(workPath) {
9099
- const pyprojectPath = (0, import_path16.join)(workPath, "pyproject.toml");
9100
- if (!import_fs16.default.existsSync(pyprojectPath)) {
9055
+ const pyprojectPath = (0, import_path17.join)(workPath, "pyproject.toml");
9056
+ if (!import_fs17.default.existsSync(pyprojectPath)) {
9101
9057
  return [];
9102
9058
  }
9103
- const pyproject = await (0, import_build_utils19.readConfigFile)(pyprojectPath);
9059
+ const pyproject = await (0, import_build_utils20.readConfigFile)(pyprojectPath);
9104
9060
  const workflows = pyproject?.tool?.vercel?.workflows;
9105
9061
  if (!workflows) {
9106
9062
  return [];
@@ -9154,14 +9110,14 @@ async function parseWorkflow(workPath, index, config) {
9154
9110
  };
9155
9111
  }
9156
9112
  function workflowError(message) {
9157
- return new import_build_utils19.NowBuildError({
9113
+ return new import_build_utils20.NowBuildError({
9158
9114
  code: "PYTHON_INVALID_WORKFLOW_CONFIG",
9159
9115
  message
9160
9116
  });
9161
9117
  }
9162
9118
 
9163
9119
  // src/index.ts
9164
- var writeFile = import_fs17.default.promises.writeFile;
9120
+ var writeFile = import_fs18.default.promises.writeFile;
9165
9121
  var PYTHON_ENTRYPOINT_DOCS_URL2 = "https://vercel.com/docs/functions/runtimes/python#python-entrypoints";
9166
9122
  var version = -1;
9167
9123
  function getDevSubscriberTopics(subscriber) {
@@ -9174,10 +9130,13 @@ function getDevSubscriberTopics(subscriber) {
9174
9130
  }
9175
9131
  async function getDevSidecars({
9176
9132
  workPath,
9177
- build: build2
9133
+ build: build2,
9134
+ service
9178
9135
  }) {
9179
9136
  const framework = build2.config?.framework;
9180
- if (build2.config?.middleware === true || typeof framework !== "string" || !(0, import_build_utils20.isPythonFramework)(framework)) {
9137
+ const isPyprojectEntrypoint = (0, import_path18.basename)(build2.src ?? "") === "pyproject.toml";
9138
+ const isPyprojectService = service !== void 0 && (0, import_path18.basename)(service.entrypoint ?? "") === "pyproject.toml";
9139
+ if (build2.config?.middleware === true || service !== void 0 && !isPyprojectService || service === void 0 && !isPyprojectEntrypoint && (typeof framework !== "string" || !(0, import_build_utils21.isPythonFramework)(framework))) {
9181
9140
  return [];
9182
9141
  }
9183
9142
  const subscribers = await getPyprojectSubscribers(workPath);
@@ -9189,7 +9148,7 @@ async function getDevSidecars({
9189
9148
  name: subscriber.name,
9190
9149
  consumer: getSubscriberConsumerName(subscriber.name),
9191
9150
  workspace: ".",
9192
- framework,
9151
+ framework: typeof framework === "string" ? framework : void 0,
9193
9152
  runtime: "python",
9194
9153
  builder: {
9195
9154
  use: build2.use,
@@ -9207,7 +9166,7 @@ async function getDevSidecars({
9207
9166
  name: workflow.name,
9208
9167
  consumer: getWorkflowConsumerName(workflow.name),
9209
9168
  workspace: ".",
9210
- framework,
9169
+ framework: typeof framework === "string" ? framework : void 0,
9211
9170
  runtime: "python",
9212
9171
  builder: {
9213
9172
  use: build2.use,
@@ -9247,7 +9206,7 @@ function addBytecodeWithinCapacity(files, bytecodeInfo, capacity) {
9247
9206
  }
9248
9207
  async function addVendorBytecodeWithinCapacity({
9249
9208
  files,
9250
- depExternalizer,
9209
+ installedDistributions,
9251
9210
  vendorDir,
9252
9211
  bytecodeInfo,
9253
9212
  capacity
@@ -9262,7 +9221,7 @@ async function addVendorBytecodeWithinCapacity({
9262
9221
  const selectedPkgs = lambdaKnapsack(bytecodeInfo.perItemSizes, capacity);
9263
9222
  if (selectedPkgs.length === 0)
9264
9223
  return capacity;
9265
- const selectedBytecode = await depExternalizer.collectBytecodeFiles({
9224
+ const selectedBytecode = await installedDistributions.collectBytecodeFiles({
9266
9225
  vendorDirName: vendorDir,
9267
9226
  includePackages: selectedPkgs
9268
9227
  });
@@ -9271,7 +9230,7 @@ async function addVendorBytecodeWithinCapacity({
9271
9230
  }
9272
9231
  async function addVendorBytecodeInTiers({
9273
9232
  files,
9274
- depExternalizer,
9233
+ installedDistributions,
9275
9234
  vendorDir,
9276
9235
  capacity,
9277
9236
  vendorPackageTiers
@@ -9282,13 +9241,13 @@ async function addVendorBytecodeInTiers({
9282
9241
  break;
9283
9242
  if (tier && tier.length === 0)
9284
9243
  continue;
9285
- const bytecodeInfo = await depExternalizer.collectBytecodeFiles({
9244
+ const bytecodeInfo = await installedDistributions.collectBytecodeFiles({
9286
9245
  vendorDirName: vendorDir,
9287
9246
  includePackages: tier
9288
9247
  });
9289
9248
  remainingCapacity = await addVendorBytecodeWithinCapacity({
9290
9249
  files,
9291
- depExternalizer,
9250
+ installedDistributions,
9292
9251
  vendorDir,
9293
9252
  bytecodeInfo,
9294
9253
  capacity: remainingCapacity
@@ -9330,13 +9289,13 @@ var frameworkHooks = {
9330
9289
  }) => {
9331
9290
  let baseDir = detected?.baseDir;
9332
9291
  if (baseDir === void 0) {
9333
- if (!import_fs17.default.existsSync((0, import_path17.join)(workPath, "manage.py"))) {
9334
- (0, import_build_utils20.debug)("Django hook: no manage.py detected, skipping");
9292
+ if (!import_fs18.default.existsSync((0, import_path18.join)(workPath, "manage.py"))) {
9293
+ (0, import_build_utils21.debug)("Django hook: no manage.py detected, skipping");
9335
9294
  return;
9336
9295
  }
9337
9296
  baseDir = "";
9338
9297
  }
9339
- const djangoPath = (0, import_path17.join)(workPath, baseDir);
9298
+ const djangoPath = (0, import_path18.join)(workPath, baseDir);
9340
9299
  let settingsResult;
9341
9300
  try {
9342
9301
  settingsResult = await getDjangoSettings(djangoPath, pythonEnv);
@@ -9348,13 +9307,13 @@ Hint: activate a venv or run with \`uv run vercel dev\``;
9348
9307
  } else {
9349
9308
  detail = err?.stderr || err?.message || String(err);
9350
9309
  }
9351
- throw new import_build_utils20.NowBuildError({
9310
+ throw new import_build_utils21.NowBuildError({
9352
9311
  code: "DJANGO_SETTINGS_FAILED",
9353
9312
  message: `Failed to read Django application settings from ${djangoPath}/manage.py:
9354
9313
  ${detail}`
9355
9314
  });
9356
9315
  }
9357
- (0, import_build_utils20.debug)(`Django settings: ${JSON.stringify(settingsResult)}`);
9316
+ (0, import_build_utils21.debug)(`Django settings: ${JSON.stringify(settingsResult)}`);
9358
9317
  const { djangoSettings, settingsModule, djangoVersion } = settingsResult;
9359
9318
  if (djangoVersion) {
9360
9319
  console.log(`Django ${djangoVersion.join(".")} detected`);
@@ -9366,7 +9325,7 @@ ${detail}`
9366
9325
  const variableName = parts.at(-1);
9367
9326
  const rel = `${parts.slice(0, -1).join("/")}.py`;
9368
9327
  const ep = baseDir ? `${baseDir}/${rel}` : rel;
9369
- (0, import_build_utils20.debug)(`Django hook: ASGI entrypoint: ${ep} (variable: ${variableName})`);
9328
+ (0, import_build_utils21.debug)(`Django hook: ASGI entrypoint: ${ep} (variable: ${variableName})`);
9370
9329
  resolvedEntrypoint = { entrypoint: ep, variableName };
9371
9330
  } else {
9372
9331
  const wsgiApp = djangoSettings["WSGI_APPLICATION"];
@@ -9375,7 +9334,7 @@ ${detail}`
9375
9334
  const variableName = parts.at(-1);
9376
9335
  const rel = `${parts.slice(0, -1).join("/")}.py`;
9377
9336
  const ep = baseDir ? `${baseDir}/${rel}` : rel;
9378
- (0, import_build_utils20.debug)(
9337
+ (0, import_build_utils21.debug)(
9379
9338
  `Django hook: WSGI entrypoint: ${ep} (variable: ${variableName})`
9380
9339
  );
9381
9340
  resolvedEntrypoint = { entrypoint: ep, variableName };
@@ -9383,7 +9342,7 @@ ${detail}`
9383
9342
  }
9384
9343
  let djangoStatic = null;
9385
9344
  if (workPath && venvPath) {
9386
- const outputStaticDir = (0, import_path17.join)(workPath, ".vercel", "output", "static");
9345
+ const outputStaticDir = (0, import_path18.join)(workPath, ".vercel", "output", "static");
9387
9346
  djangoStatic = await runDjangoCollectStatic(
9388
9347
  venvPath,
9389
9348
  workPath,
@@ -9398,7 +9357,7 @@ ${detail}`
9398
9357
  return {
9399
9358
  entrypoint: resolvedEntrypoint,
9400
9359
  djangoStatic,
9401
- extraPythonPath: baseDir ? (0, import_path17.join)(workPath, baseDir) : void 0
9360
+ extraPythonPath: baseDir ? (0, import_path18.join)(workPath, baseDir) : void 0
9402
9361
  };
9403
9362
  }
9404
9363
  };
@@ -9457,23 +9416,23 @@ async function downloadFilesInWorkPath({
9457
9416
  files,
9458
9417
  meta = {}
9459
9418
  }) {
9460
- (0, import_build_utils20.debug)("Downloading user files...");
9461
- let downloadedFiles = await (0, import_build_utils20.download)(files, workPath, meta);
9419
+ (0, import_build_utils21.debug)("Downloading user files...");
9420
+ let downloadedFiles = await (0, import_build_utils21.download)(files, workPath, meta);
9462
9421
  if (meta.isDev && entrypoint) {
9463
9422
  const normalizedEntrypoint = entrypoint.endsWith(".py") ? entrypoint : `${entrypoint}.py`;
9464
9423
  if (!hasProp(downloadedFiles, entrypoint) && !hasProp(downloadedFiles, normalizedEntrypoint)) {
9465
- throw new import_build_utils20.NowBuildError({
9424
+ throw new import_build_utils21.NowBuildError({
9466
9425
  code: "PYTHON_ENTRYPOINT_NOT_FOUND",
9467
9426
  message: `Configured Python entrypoint "${normalizedEntrypoint}" was not found.`,
9468
9427
  link: PYTHON_ENTRYPOINT_DOCS_URL2,
9469
9428
  action: "Learn More"
9470
9429
  });
9471
9430
  }
9472
- const { devCacheDir = (0, import_path17.join)(workPath, ".now", "cache") } = meta;
9473
- const cacheKey = (0, import_path17.basename)(entrypoint).replace(/\./g, "_");
9474
- const destCache = (0, import_path17.join)(devCacheDir, cacheKey);
9475
- await (0, import_build_utils20.download)(downloadedFiles, destCache);
9476
- downloadedFiles = await (0, import_build_utils20.glob)("**", destCache);
9431
+ const { devCacheDir = (0, import_path18.join)(workPath, ".now", "cache") } = meta;
9432
+ const cacheKey = (0, import_path18.basename)(entrypoint).replace(/\./g, "_");
9433
+ const destCache = (0, import_path18.join)(devCacheDir, cacheKey);
9434
+ await (0, import_build_utils21.download)(downloadedFiles, destCache);
9435
+ downloadedFiles = await (0, import_build_utils21.glob)("**", destCache);
9477
9436
  workPath = destCache;
9478
9437
  }
9479
9438
  return workPath;
@@ -9509,7 +9468,7 @@ async function getPythonLambdaOptions({
9509
9468
  sources.add(entrypoint.slice(0, -".py".length));
9510
9469
  }
9511
9470
  for (const sourceFile of sources) {
9512
- const lambdaOptions = await (0, import_build_utils20.getLambdaOptionsFromFunction)({
9471
+ const lambdaOptions = await (0, import_build_utils21.getLambdaOptionsFromFunction)({
9513
9472
  sourceFile,
9514
9473
  config
9515
9474
  });
@@ -9529,11 +9488,11 @@ async function installInjectedPackage({
9529
9488
  projectDir,
9530
9489
  pipPlatformArgs
9531
9490
  }) {
9532
- const localDir = (0, import_path17.join)(__dirname, "..", "..", "..", "python", name);
9533
- const isLocalDev = import_fs17.default.existsSync((0, import_path17.join)(localDir, "pyproject.toml"));
9491
+ const localDir = (0, import_path18.join)(__dirname, "..", "..", "..", "python", name);
9492
+ const isLocalDev = import_fs18.default.existsSync((0, import_path18.join)(localDir, "pyproject.toml"));
9534
9493
  const dep = envOverride || (isLocalDev ? localDir : pinned);
9535
9494
  const noExclude = ["--exclude-newer-package", `${name}=false`];
9536
- (0, import_build_utils20.debug)(`Installing ${dep}`);
9495
+ (0, import_build_utils21.debug)(`Installing ${dep}`);
9537
9496
  await uv.pip({
9538
9497
  venvPath,
9539
9498
  projectDir,
@@ -9559,14 +9518,14 @@ var build = async ({
9559
9518
  registerPreDeploy
9560
9519
  }) => {
9561
9520
  let entrypoint = rawEntrypoint === "<detect>" ? void 0 : rawEntrypoint;
9562
- const isPyprojectEntrypoint = entrypoint !== void 0 && (0, import_path17.basename)(entrypoint) === "pyproject.toml";
9521
+ const isPyprojectEntrypoint = entrypoint !== void 0 && (0, import_path18.basename)(entrypoint) === "pyproject.toml";
9563
9522
  if (isPyprojectEntrypoint && entrypoint !== "pyproject.toml") {
9564
- throw new import_build_utils20.NowBuildError({
9523
+ throw new import_build_utils21.NowBuildError({
9565
9524
  code: "PYTHON_INVALID_PYPROJECT_ENTRYPOINT",
9566
- message: `A "pyproject.toml" entrypoint must sit at the service root. Set the service "root" to "${(0, import_path17.dirname)(entrypoint)}" and use entrypoint "pyproject.toml".`
9525
+ message: `A "pyproject.toml" entrypoint must sit at the service root. Set the service "root" to "${(0, import_path18.dirname)(entrypoint)}" and use entrypoint "pyproject.toml".`
9567
9526
  });
9568
9527
  }
9569
- const builderSpan = parentSpan ?? new import_build_utils20.Span({ name: "vc.builder" });
9528
+ const builderSpan = parentSpan ?? new import_build_utils21.Span({ name: "vc.builder" });
9570
9529
  const framework = config?.framework;
9571
9530
  let shouldInstallVercelWorkers = config?.hasWorkerServices === true;
9572
9531
  let subscribers = [];
@@ -9575,21 +9534,21 @@ var build = async ({
9575
9534
  let projectInstallCommand;
9576
9535
  let hasCustomCommand = false;
9577
9536
  const target = getTargetPlatform(meta.isDev ?? false);
9578
- (0, import_build_utils20.debug)(`workPath: ${workPath}`);
9537
+ (0, import_build_utils21.debug)(`workPath: ${workPath}`);
9579
9538
  workPath = await downloadFilesInWorkPath({
9580
9539
  workPath,
9581
9540
  files: originalFiles,
9582
9541
  entrypoint,
9583
9542
  meta
9584
9543
  });
9585
- if (isPyprojectEntrypoint || !service && (0, import_build_utils20.isPythonFramework)(framework)) {
9544
+ if (isPyprojectEntrypoint || !service && (0, import_build_utils21.isPythonFramework)(framework)) {
9586
9545
  subscribers = await getPyprojectSubscribers(workPath);
9587
9546
  workflows = await getPyprojectWorkflows(workPath);
9588
9547
  shouldInstallVercelWorkers ||= subscribers.length > 0 || workflows.length > 0;
9589
9548
  }
9590
9549
  try {
9591
9550
  if (meta.isDev) {
9592
- const setupCfg = (0, import_path17.join)(workPath, "setup.cfg");
9551
+ const setupCfg = (0, import_path18.join)(workPath, "setup.cfg");
9593
9552
  await writeFile(setupCfg, "[install]\nprefix=\n");
9594
9553
  }
9595
9554
  } catch (err) {
@@ -9603,7 +9562,7 @@ var build = async ({
9603
9562
  if (declared) {
9604
9563
  detected = { entrypoint: declared };
9605
9564
  } else if (subscribers.length === 0 && workflows.length === 0) {
9606
- throw new import_build_utils20.NowBuildError({
9565
+ throw new import_build_utils21.NowBuildError({
9607
9566
  code: "PYTHON_PYPROJECT_NOTHING_TO_BUILD",
9608
9567
  message: 'Entrypoint "pyproject.toml" declares nothing to build. Set "tool.vercel.entrypoint" for a web app and/or declare "[[tool.vercel.subscribers]]" or "[[tool.vercel.workflows]]" entries in pyproject.toml.'
9609
9568
  });
@@ -9617,7 +9576,7 @@ var build = async ({
9617
9576
  filePath: entrypoint,
9618
9577
  // For schedule-triggered jobs, the WSGI variable is always 'app' (created dynamically).
9619
9578
  // For other services, handlerFunction is used as the entrypoint variable name.
9620
- varName: service && (0, import_build_utils20.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
9579
+ varName: service && (0, import_build_utils21.isScheduleTriggeredService)(service) ? void 0 : handlerFunction
9621
9580
  } : void 0,
9622
9581
  service,
9623
9582
  repoRootPath
@@ -9626,8 +9585,8 @@ var build = async ({
9626
9585
  if (detected?.error && detected?.baseDir === void 0) {
9627
9586
  throw detected?.error;
9628
9587
  }
9629
- const entryDirectory = detected?.baseDir ?? (entrypoint ? (0, import_path17.dirname)(entrypoint) : ".");
9630
- const entrypointAbsDir = (0, import_path17.join)(workPath, entryDirectory);
9588
+ const entryDirectory = detected?.baseDir ?? (entrypoint ? (0, import_path18.dirname)(entrypoint) : ".");
9589
+ const entrypointAbsDir = (0, import_path18.join)(workPath, entryDirectory);
9631
9590
  const rootDir = repoRootPath ?? workPath;
9632
9591
  const pythonPackage = await builderSpan.child("vc.builder.python.discover").trace(
9633
9592
  () => discoverPackage({
@@ -9668,12 +9627,12 @@ var build = async ({
9668
9627
  }
9669
9628
  const uvVersion = checkUvBinaryVersion(uv.getPath());
9670
9629
  console.log(`Using ${uvVersion}`);
9671
- const venvPath = service?.name ? (0, import_path17.join)(workPath, ".vercel", "python", "services", service.name, ".venv") : (0, import_path17.join)(workPath, ".vercel", "python", ".venv");
9672
- const hasCachedVenv = import_fs17.default.existsSync((0, import_path17.join)(venvPath, "pyvenv.cfg"));
9673
- const hasCachedUv = import_fs17.default.existsSync(uvCacheDir);
9630
+ const venvPath = service?.name ? (0, import_path18.join)(workPath, ".vercel", "python", "services", service.name, ".venv") : (0, import_path18.join)(workPath, ".vercel", "python", ".venv");
9631
+ const hasCachedVenv = import_fs18.default.existsSync((0, import_path18.join)(venvPath, "pyvenv.cfg"));
9632
+ const hasCachedUv = import_fs18.default.existsSync(uvCacheDir);
9674
9633
  const restoredCache = hasCachedVenv && hasCachedUv ? "both" : hasCachedVenv ? "venv" : hasCachedUv ? "uv" : "none";
9675
9634
  if (hasCachedVenv || hasCachedUv) {
9676
- (0, import_build_utils20.debug)(
9635
+ (0, import_build_utils21.debug)(
9677
9636
  `Build cache detected: venv=${hasCachedVenv}, uv-cache=${hasCachedUv}`
9678
9637
  );
9679
9638
  }
@@ -9685,14 +9644,14 @@ var build = async ({
9685
9644
  uvCacheDir
9686
9645
  });
9687
9646
  });
9688
- if ((0, import_build_utils20.isPythonFramework)(framework)) {
9647
+ if ((0, import_build_utils21.isPythonFramework)(framework)) {
9689
9648
  const {
9690
9649
  cliType,
9691
9650
  lockfileVersion,
9692
9651
  packageJsonPackageManager,
9693
9652
  turboSupportsCorepackHome
9694
- } = await (0, import_build_utils20.scanParentDirs)(workPath, true);
9695
- spawnEnv = (0, import_build_utils20.getEnvForPackageManager)({
9653
+ } = await (0, import_build_utils21.scanParentDirs)(workPath, true);
9654
+ spawnEnv = (0, import_build_utils21.getEnvForPackageManager)({
9696
9655
  cliType,
9697
9656
  lockfileVersion,
9698
9657
  packageJsonPackageManager,
@@ -9717,13 +9676,13 @@ var build = async ({
9717
9676
  let uvLockPath = null;
9718
9677
  let uvProjectDir = null;
9719
9678
  let projectName;
9720
- await builderSpan.child(import_build_utils20.BUILDER_INSTALLER_STEP, {
9679
+ await builderSpan.child(import_build_utils21.BUILDER_INSTALLER_STEP, {
9721
9680
  installCommand: projectInstallCommand || void 0,
9722
9681
  runtime: "python",
9723
9682
  "python.cache.restored": restoredCache
9724
9683
  }).trace(async () => {
9725
9684
  if (projectInstallCommand) {
9726
- await import_fs17.default.promises.rm(venvPath, { recursive: true, force: true });
9685
+ await import_fs18.default.promises.rm(venvPath, { recursive: true, force: true });
9727
9686
  await ensureVenv({
9728
9687
  pythonVersion,
9729
9688
  venvPath,
@@ -9734,7 +9693,7 @@ var build = async ({
9734
9693
  console.log(
9735
9694
  `Running "install" command: \`${projectInstallCommand}\`...`
9736
9695
  );
9737
- await (0, import_build_utils20.execCommand)(projectInstallCommand, {
9696
+ await (0, import_build_utils21.execCommand)(projectInstallCommand, {
9738
9697
  env: pythonEnv,
9739
9698
  cwd: workPath
9740
9699
  });
@@ -9755,7 +9714,7 @@ var build = async ({
9755
9714
  }
9756
9715
  if (!assumeDepsInstalled) {
9757
9716
  const lockCacheKey = service?.name ? `uv.lock.${service.name}` : "uv.lock";
9758
- const cachedLockPath = (0, import_path17.join)(uvCacheDir, lockCacheKey);
9717
+ const cachedLockPath = (0, import_path18.join)(uvCacheDir, lockCacheKey);
9759
9718
  const { projectDir, lockPath, lockFileProvidedByUser } = await ensureUvProject({
9760
9719
  workPath,
9761
9720
  rootDir,
@@ -9776,21 +9735,21 @@ var build = async ({
9776
9735
  locked: !lockFileProvidedByUser,
9777
9736
  pythonPlatform: target.uvPlatform
9778
9737
  });
9779
- if (lockPath && import_fs17.default.existsSync(lockPath)) {
9780
- await import_fs17.default.promises.mkdir(uvCacheDir, { recursive: true });
9781
- await import_fs17.default.promises.copyFile(lockPath, cachedLockPath);
9738
+ if (lockPath && import_fs18.default.existsSync(lockPath)) {
9739
+ await import_fs18.default.promises.mkdir(uvCacheDir, { recursive: true });
9740
+ await import_fs18.default.promises.copyFile(lockPath, cachedLockPath);
9782
9741
  }
9783
9742
  }
9784
9743
  });
9785
- if ((0, import_build_utils20.isPythonFramework)(framework)) {
9744
+ if ((0, import_build_utils21.isPythonFramework)(framework)) {
9786
9745
  const projectBuildCommand = config?.projectSettings?.buildCommand ?? // fallback if provided directly on config (some callers set this)
9787
9746
  config?.buildCommand;
9788
- await builderSpan.child(import_build_utils20.BUILDER_COMPILE_STEP, {
9747
+ await builderSpan.child(import_build_utils21.BUILDER_COMPILE_STEP, {
9789
9748
  buildCommand: projectBuildCommand || void 0
9790
9749
  }).trace(async () => {
9791
9750
  if (projectBuildCommand) {
9792
9751
  console.log(`Running "${projectBuildCommand}"`);
9793
- await (0, import_build_utils20.execCommand)(projectBuildCommand, {
9752
+ await (0, import_build_utils21.execCommand)(projectBuildCommand, {
9794
9753
  env: pythonEnv,
9795
9754
  cwd: workPath
9796
9755
  });
@@ -9817,7 +9776,7 @@ var build = async ({
9817
9776
  entrypoint = resolved?.entrypoint;
9818
9777
  const isWorkersOnly = !entrypoint && isPyprojectEntrypoint && (subscribers.length > 0 || workflows.length > 0);
9819
9778
  if (!entrypoint && !isWorkersOnly) {
9820
- throw new import_build_utils20.NowBuildError({
9779
+ throw new import_build_utils21.NowBuildError({
9821
9780
  code: "PYTHON_ENTRYPOINT_NOT_FOUND",
9822
9781
  message: "No Python entrypoint could be detected. Please specify an entrypoint file."
9823
9782
  });
@@ -9830,7 +9789,7 @@ var build = async ({
9830
9789
  envOverride: baseEnv.VERCEL_RUNTIME_PYTHON,
9831
9790
  uv,
9832
9791
  venvPath,
9833
- projectDir: (0, import_path17.join)(workPath, entryDirectory),
9792
+ projectDir: (0, import_path18.join)(workPath, entryDirectory),
9834
9793
  pipPlatformArgs
9835
9794
  });
9836
9795
  if (shouldInstallVercelWorkers) {
@@ -9840,7 +9799,7 @@ var build = async ({
9840
9799
  envOverride: baseEnv.VERCEL_WORKERS_PYTHON,
9841
9800
  uv,
9842
9801
  venvPath,
9843
- projectDir: (0, import_path17.join)(workPath, entryDirectory),
9802
+ projectDir: (0, import_path18.join)(workPath, entryDirectory),
9844
9803
  pipPlatformArgs
9845
9804
  });
9846
9805
  }
@@ -9853,11 +9812,11 @@ var build = async ({
9853
9812
  const capturedEnv = { ...pythonEnv };
9854
9813
  const capturedCwd = workPath;
9855
9814
  registerPreDeploy(async () => {
9856
- await builderSpan.child(import_build_utils20.BUILDER_PRE_DEPLOY_STEP, {
9815
+ await builderSpan.child(import_build_utils21.BUILDER_PRE_DEPLOY_STEP, {
9857
9816
  preDeployCommand
9858
9817
  }).trace(async () => {
9859
9818
  console.log(`Running pre-deploy command: \`${preDeployCommand}\``);
9860
- await (0, import_build_utils20.execCommand)(preDeployCommand, {
9819
+ await (0, import_build_utils21.execCommand)(preDeployCommand, {
9861
9820
  env: capturedEnv,
9862
9821
  cwd: capturedCwd
9863
9822
  });
@@ -9868,14 +9827,14 @@ var build = async ({
9868
9827
  let crons;
9869
9828
  let runtimeTrampoline;
9870
9829
  if (entrypoint) {
9871
- (0, import_build_utils20.debug)("Entrypoint is", entrypoint);
9830
+ (0, import_build_utils21.debug)("Entrypoint is", entrypoint);
9872
9831
  const moduleName = entrypointToModule(entrypoint);
9873
9832
  if (handlerFunction) {
9874
- const entrypointPath = (0, import_path17.join)(workPath, entrypoint);
9875
- const source = await import_fs17.default.promises.readFile(entrypointPath, "utf-8");
9876
- const found = await (0, import_python_analysis9.containsTopLevelCallable)(source, handlerFunction);
9833
+ const entrypointPath = (0, import_path18.join)(workPath, entrypoint);
9834
+ const source = await import_fs18.default.promises.readFile(entrypointPath, "utf-8");
9835
+ const found = await (0, import_python_analysis10.containsTopLevelCallable)(source, handlerFunction);
9877
9836
  if (!found) {
9878
- throw new import_build_utils20.NowBuildError({
9837
+ throw new import_build_utils21.NowBuildError({
9879
9838
  code: "PYTHON_HANDLER_NOT_FOUND",
9880
9839
  message: `Handler function "${handlerFunction}" not found in ${entrypoint}. Ensure it is defined at the module's top level.`
9881
9840
  });
@@ -9883,7 +9842,7 @@ var build = async ({
9883
9842
  }
9884
9843
  const suffix = meta.isDev && !entrypoint.endsWith(".py") ? ".py" : "";
9885
9844
  const entrypointWithSuffix = `${entrypoint}${suffix}`;
9886
- (0, import_build_utils20.debug)("Entrypoint with suffix is", entrypointWithSuffix);
9845
+ (0, import_build_utils21.debug)("Entrypoint with suffix is", entrypointWithSuffix);
9887
9846
  crons = await getServiceCrons({
9888
9847
  service,
9889
9848
  entrypoint,
@@ -9944,34 +9903,37 @@ var build = async ({
9944
9903
  cwd: workPath,
9945
9904
  ignore: config && typeof config.excludeFiles === "string" ? [...predefinedExcludes, config.excludeFiles] : predefinedExcludes
9946
9905
  };
9947
- const files = await (0, import_build_utils20.glob)("**", globOptions);
9906
+ const files = await (0, import_build_utils21.glob)("**", globOptions);
9948
9907
  if (djangoStatic?.manifestRelPath) {
9949
- files[djangoStatic.manifestRelPath] = new import_build_utils20.FileFsRef({
9950
- fsPath: (0, import_path17.join)(workPath, djangoStatic.manifestRelPath)
9908
+ files[djangoStatic.manifestRelPath] = new import_build_utils21.FileFsRef({
9909
+ fsPath: (0, import_path18.join)(workPath, djangoStatic.manifestRelPath)
9951
9910
  });
9952
9911
  }
9953
9912
  const handlerPyFilename = "vc__handler__python";
9954
9913
  if (config.framework === "fasthtml") {
9955
9914
  const { SESSKEY = "" } = process.env;
9956
- files[".sesskey"] = new import_build_utils20.FileBlob({ data: `"${SESSKEY}"` });
9915
+ files[".sesskey"] = new import_build_utils21.FileBlob({ data: `"${SESSKEY}"` });
9957
9916
  }
9958
- const depExternalizer = new PythonDependencyExternalizer({
9959
- venvPath,
9960
- vendorDir,
9961
- workPath,
9962
- uvLockPath,
9963
- uvProjectDir,
9964
- projectName,
9965
- pythonMajor: pythonVersion.major,
9966
- pythonMinor: pythonVersion.minor,
9967
- pythonPath: pythonVersion.pythonPath,
9968
- hasCustomCommand,
9969
- alwaysBundlePackages: [
9970
- ...quirksResult.alwaysBundlePackages ?? [],
9971
- ...shouldInstallVercelWorkers ? ["vercel-workers", "vercel_workers"] : []
9972
- ]
9973
- });
9974
9917
  await builderSpan.child("vc.builder.python.bundle").trace(async (bundleSpan) => {
9918
+ const installedDistributions = await InstalledPythonDistributions.load({
9919
+ venvPath,
9920
+ pythonMajor: pythonVersion.major,
9921
+ pythonMinor: pythonVersion.minor
9922
+ });
9923
+ const depExternalizer = new PythonDependencyExternalizer({
9924
+ installedDistributions,
9925
+ vendorDir,
9926
+ workPath,
9927
+ uvLockPath,
9928
+ uvProjectDir,
9929
+ projectName,
9930
+ pythonVersion,
9931
+ hasCustomCommand,
9932
+ alwaysBundlePackages: [
9933
+ ...quirksResult.alwaysBundlePackages ?? [],
9934
+ ...shouldInstallVercelWorkers ? ["vercel-workers", "vercel_workers"] : []
9935
+ ]
9936
+ });
9975
9937
  const depAnalysis = await depExternalizer.analyze(files, {
9976
9938
  onSized: ({ totalSizeBytes, runtimeInstallEnabled }) => {
9977
9939
  bundleSpan.setAttributes({
@@ -9985,7 +9947,7 @@ var build = async ({
9985
9947
  const runCompileAllAndFillBytecode = async (capacityBytes, vendorPackageTiers) => {
9986
9948
  try {
9987
9949
  await builderSpan.child("vc.builder.python.compileall").trace(async (compileSpan) => {
9988
- const sitePackageDirs = (await getVenvSitePackagesDirs(venvPath)).filter((d) => import_fs17.default.existsSync(d));
9950
+ const sitePackageDirs = (await getVenvSitePackagesDirs(venvPath)).filter((d) => import_fs18.default.existsSync(d));
9989
9951
  const pythonBin = getVenvPythonBin(venvPath);
9990
9952
  console.log("Compiling Python bytecode...");
9991
9953
  await runCompileAll({
@@ -10023,7 +9985,7 @@ var build = async ({
10023
9985
  }
10024
9986
  await addVendorBytecodeInTiers({
10025
9987
  files,
10026
- depExternalizer,
9988
+ installedDistributions,
10027
9989
  vendorDir,
10028
9990
  capacity: remainingCapacity,
10029
9991
  vendorPackageTiers: vendorPackageTiers ?? [void 0]
@@ -10032,7 +9994,7 @@ var build = async ({
10032
9994
  console.log(
10033
9995
  "Bytecode precompilation failed; continuing without precompiled bytecode."
10034
9996
  );
10035
- (0, import_build_utils20.debug)(`bytecode precompilation error details: ${err}`);
9997
+ (0, import_build_utils21.debug)(`bytecode precompilation error details: ${err}`);
10036
9998
  }
10037
9999
  };
10038
10000
  const runPrefixCompileAndFill = async (bundleResult) => {
@@ -10044,16 +10006,16 @@ var build = async ({
10044
10006
  const currentSize = await calculateBundleSize(files);
10045
10007
  let remainingCapacity = BYTECODE_FILL_CEILING_BYTES - currentSize;
10046
10008
  if (remainingCapacity <= 0) {
10047
- (0, import_build_utils20.debug)(
10009
+ (0, import_build_utils21.debug)(
10048
10010
  `skipping bytecode precompilation: no zip capacity remaining (bundle is ${(currentSize / (1024 * 1024)).toFixed(2)} MB)`
10049
10011
  );
10050
10012
  return;
10051
10013
  }
10052
- const stagingDir = (0, import_path17.join)(workPath, ".vercel", "python", "pycache");
10053
- await import_fs17.default.promises.rm(stagingDir, { recursive: true, force: true });
10054
- await import_fs17.default.promises.mkdir(stagingDir, { recursive: true });
10014
+ const stagingDir = (0, import_path18.join)(workPath, ".vercel", "python", "pycache");
10015
+ await import_fs18.default.promises.rm(stagingDir, { recursive: true, force: true });
10016
+ await import_fs18.default.promises.mkdir(stagingDir, { recursive: true });
10055
10017
  await builderSpan.child("vc.builder.python.compileall").trace(async (compileSpan) => {
10056
- const sitePackageDirs = (await getVenvSitePackagesDirs(venvPath)).filter((d) => import_fs17.default.existsSync(d));
10018
+ const sitePackageDirs = (await getVenvSitePackagesDirs(venvPath)).filter((d) => import_fs18.default.existsSync(d));
10057
10019
  const pythonBin = getVenvPythonBin(venvPath);
10058
10020
  console.log("Compiling Python bytecode...");
10059
10021
  await runCompileAll({
@@ -10095,7 +10057,7 @@ var build = async ({
10095
10057
  remainingCapacity = await addCollectedVendorBytecode({
10096
10058
  files,
10097
10059
  capacity: remainingCapacity,
10098
- collect: (include) => depExternalizer.collectPrefixBytecodeFiles({
10060
+ collect: (include) => installedDistributions.collectPrefixBytecodeFiles({
10099
10061
  stagingDir,
10100
10062
  runtimeRoot: `/var/task/${vendorDir}`,
10101
10063
  includePackages: include ?? alwaysBundled
@@ -10105,7 +10067,7 @@ var build = async ({
10105
10067
  await addCollectedVendorBytecode({
10106
10068
  files,
10107
10069
  capacity: remainingCapacity,
10108
- collect: (include) => depExternalizer.collectPrefixBytecodeFiles({
10070
+ collect: (include) => installedDistributions.collectPrefixBytecodeFiles({
10109
10071
  stagingDir,
10110
10072
  runtimeRoot: `${RUNTIME_DEPS_DIR}/lib/python${pyMajor}.${pyMinor}/site-packages`,
10111
10073
  includePackages: include ?? externalized
@@ -10118,22 +10080,25 @@ var build = async ({
10118
10080
  console.log(
10119
10081
  "Bytecode precompilation failed; continuing without precompiled bytecode."
10120
10082
  );
10121
- (0, import_build_utils20.debug)(`bytecode precompilation error details: ${err}`);
10083
+ (0, import_build_utils21.debug)(`bytecode precompilation error details: ${err}`);
10122
10084
  }
10123
10085
  };
10124
10086
  const announceLargeFunction = () => console.log(
10125
10087
  `Function "${entrypoint ?? rawEntrypoint}" exceeds the standard size limit; enabling large functions (beta).`
10126
10088
  );
10089
+ let packingMode;
10127
10090
  if (depAnalysis.runtimeInstallEnabled) {
10091
+ packingMode = "runtime-install";
10128
10092
  const bytecodeFirst = compileAllEnabled && pythonVersion.major != null && pythonVersion.minor != null;
10129
10093
  const bundleResult = await depExternalizer.generateBundle(files, {
10130
10094
  bytecodeFirst
10131
10095
  });
10132
10096
  if (bundleResult.fellBackToFullBundle) {
10097
+ packingMode = "hive";
10133
10098
  announceLargeFunction();
10134
10099
  if (compileAllEnabled) {
10135
10100
  await runCompileAllAndFillBytecode(
10136
- MAX_LARGE_FUNCTION_UNCOMPRESSED_SIZE
10101
+ LARGE_FUNCTION_FILL_CEILING_BYTES
10137
10102
  );
10138
10103
  }
10139
10104
  } else if (bundleResult.packingMode === "bytecode-first") {
@@ -10141,45 +10106,61 @@ var build = async ({
10141
10106
  } else if (compileAllEnabled) {
10142
10107
  const currentSize = await calculateBundleSize(files);
10143
10108
  const capacity = BYTECODE_FILL_CEILING_BYTES - currentSize;
10144
- const estimate = await estimateBytecodeSize(files);
10145
- if (capacity >= BYTECODE_COVERAGE_FLOOR * estimate) {
10109
+ if (capacity > 0) {
10146
10110
  await runCompileAllAndFillBytecode(BYTECODE_FILL_CEILING_BYTES, [
10147
10111
  bundleResult.alwaysBundledPackages ?? [],
10148
10112
  bundleResult.bundledPublicPackages ?? []
10149
10113
  ]);
10114
+ } else {
10115
+ (0, import_build_utils21.debug)(
10116
+ `skipping bytecode precompilation: no zip capacity remaining (bundle is ${(currentSize / (1024 * 1024)).toFixed(2)} MB)`
10117
+ );
10150
10118
  }
10151
10119
  }
10152
10120
  } else {
10153
10121
  addFiles(files, depAnalysis.allVendorFiles);
10154
10122
  if (depAnalysis.totalBundleSize > LAMBDA_SIZE_THRESHOLD_BYTES) {
10123
+ packingMode = "hive";
10155
10124
  if (isLargeFunctionsEnabled()) {
10156
10125
  announceLargeFunction();
10157
10126
  }
10158
10127
  if (compileAllEnabled) {
10159
10128
  await runCompileAllAndFillBytecode(
10160
- MAX_LARGE_FUNCTION_UNCOMPRESSED_SIZE
10129
+ LARGE_FUNCTION_FILL_CEILING_BYTES
10161
10130
  );
10162
10131
  }
10163
- } else if (compileAllEnabled) {
10164
- const capacity = BYTECODE_FILL_CEILING_BYTES - depAnalysis.totalBundleSize;
10165
- const estimate = await estimateBytecodeSize(files);
10166
- if (capacity >= BYTECODE_COVERAGE_FLOOR * estimate) {
10167
- await runCompileAllAndFillBytecode(BYTECODE_FILL_CEILING_BYTES);
10132
+ } else {
10133
+ packingMode = "standard";
10134
+ if (compileAllEnabled) {
10135
+ const capacity = BYTECODE_FILL_CEILING_BYTES - depAnalysis.totalBundleSize;
10136
+ if (capacity > 0) {
10137
+ await runCompileAllAndFillBytecode(BYTECODE_FILL_CEILING_BYTES);
10138
+ } else {
10139
+ (0, import_build_utils21.debug)(
10140
+ `skipping bytecode precompilation: no zip capacity remaining (bundle is ${(depAnalysis.totalBundleSize / (1024 * 1024)).toFixed(2)} MB)`
10141
+ );
10142
+ }
10168
10143
  }
10169
10144
  }
10170
10145
  }
10146
+ bundleSpan.setAttributes({
10147
+ "python.bundle.totalSizeBytes": String(
10148
+ await calculateBundleSize(files)
10149
+ ),
10150
+ "python.bundle.packingMode": packingMode
10151
+ });
10171
10152
  });
10172
10153
  let output;
10173
10154
  if (entrypoint && runtimeTrampoline) {
10174
10155
  const webFiles = {
10175
10156
  ...files,
10176
- [`${handlerPyFilename}.py`]: new import_build_utils20.FileBlob({ data: runtimeTrampoline })
10157
+ [`${handlerPyFilename}.py`]: new import_build_utils21.FileBlob({ data: runtimeTrampoline })
10177
10158
  };
10178
10159
  const lambdaOptions = await getPythonLambdaOptions({
10179
10160
  config,
10180
10161
  entrypoint
10181
10162
  });
10182
- output = new import_build_utils20.Lambda({
10163
+ output = new import_build_utils21.Lambda({
10183
10164
  files: webFiles,
10184
10165
  handler: `${handlerPyFilename}.vc_handler`,
10185
10166
  runtime: pythonVersion.runtime,
@@ -10201,10 +10182,10 @@ var build = async ({
10201
10182
  ...subscriber.triggerDefaults
10202
10183
  })
10203
10184
  );
10204
- subscriberLambdas[outputPath] = new import_build_utils20.Lambda({
10185
+ subscriberLambdas[outputPath] = new import_build_utils21.Lambda({
10205
10186
  files: {
10206
10187
  ...files,
10207
- [`${handlerPyFilename}.py`]: new import_build_utils20.FileBlob({
10188
+ [`${handlerPyFilename}.py`]: new import_build_utils21.FileBlob({
10208
10189
  data: createRuntimeTrampoline({
10209
10190
  moduleName: subscriber.moduleName,
10210
10191
  entrypoint: subscriber.entrypoint,
@@ -10236,10 +10217,10 @@ var build = async ({
10236
10217
  consumer: getWorkflowConsumerName(workflow.name)
10237
10218
  }
10238
10219
  ];
10239
- workflowLambdas[outputPath] = new import_build_utils20.Lambda({
10220
+ workflowLambdas[outputPath] = new import_build_utils21.Lambda({
10240
10221
  files: {
10241
10222
  ...files,
10242
- [`${handlerPyFilename}.py`]: new import_build_utils20.FileBlob({
10223
+ [`${handlerPyFilename}.py`]: new import_build_utils21.FileBlob({
10243
10224
  data: createRuntimeTrampoline({
10244
10225
  moduleName: workflow.moduleName,
10245
10226
  entrypoint: workflow.entrypoint,
@@ -10269,20 +10250,20 @@ var build = async ({
10269
10250
  pythonVersion,
10270
10251
  uvLockPath,
10271
10252
  framework,
10272
- serviceType: service ? (0, import_build_utils20.getReportedServiceType)(service) : void 0
10253
+ serviceType: service ? (0, import_build_utils21.getReportedServiceType)(service) : void 0
10273
10254
  });
10274
10255
  } catch (err) {
10275
- (0, import_build_utils20.debug)(
10256
+ (0, import_build_utils21.debug)(
10276
10257
  `Failed to write project manifest: ${err instanceof Error ? err.message : String(err)}`
10277
10258
  );
10278
10259
  }
10279
10260
  }
10280
- if (!(0, import_build_utils20.isPythonFramework)(framework) && !service?.name && !isPyprojectEntrypoint) {
10261
+ if (!(0, import_build_utils21.isPythonFramework)(framework) && !service?.name && !isPyprojectEntrypoint) {
10281
10262
  (0, import_assert.default)(output, "web Lambda must exist for non-service builds");
10282
10263
  return { resultVersion: 3, result: { output } };
10283
10264
  }
10284
10265
  const lambdaPath = service?.name && service.type ? `_svc/${service.name}/index` : "index";
10285
- const staticFiles = djangoStatic?.cdnOutputDir ? await (0, import_build_utils20.glob)("**", { cwd: djangoStatic.cdnOutputDir }) : {};
10266
+ const staticFiles = djangoStatic?.cdnOutputDir ? await (0, import_build_utils21.glob)("**", { cwd: djangoStatic.cdnOutputDir }) : {};
10286
10267
  const isNonWebService = service?.name && service.type && service.type !== "web";
10287
10268
  const routes = isNonWebService || !output ? void 0 : [
10288
10269
  { handle: "filesystem" },
@@ -10317,14 +10298,14 @@ var prepareCache = async ({
10317
10298
  }
10318
10299
  } catch {
10319
10300
  }
10320
- return (0, import_build_utils20.glob)("**/.vercel/python/{.venv,services/*/.venv,cache/uv}/**", {
10301
+ return (0, import_build_utils21.glob)("**/.vercel/python/{.venv,services/*/.venv,cache/uv}/**", {
10321
10302
  cwd: root,
10322
10303
  ignore
10323
10304
  });
10324
10305
  };
10325
10306
  var shouldServe = (opts) => {
10326
10307
  const framework = opts.config.framework;
10327
- if ((0, import_build_utils20.isPythonFramework)(framework)) {
10308
+ if ((0, import_build_utils21.isPythonFramework)(framework)) {
10328
10309
  const requestPath = opts.requestPath.replace(/\/$/, "");
10329
10310
  if (requestPath.startsWith("api") && opts.hasMatched) {
10330
10311
  return false;
@@ -10343,7 +10324,7 @@ var defaultShouldServe = ({
10343
10324
  if (entrypoint === requestPath && hasProp(files, entrypoint)) {
10344
10325
  return true;
10345
10326
  }
10346
- const { dir, name } = (0, import_path17.parse)(entrypoint);
10327
+ const { dir, name } = (0, import_path18.parse)(entrypoint);
10347
10328
  if (name === "index" && dir === requestPath && hasProp(files, entrypoint)) {
10348
10329
  return true;
10349
10330
  }