[vpython] Migrate .vpython3 to vpython.toml

Migrate the legacy .vpython3 spec to vpython.toml and
vpython.toml.uv.lock, configure vpython_spec_files in
build_overrides/build.gni, and update testing/tools/BUILD.gn data to
reference the new specs.

Bug: 491263752
LSC: go/vpython-uv-config-lsc
TAG=agy
CONV=b53bdf70-37e7-4696-be50-8ee6fc19b1f8
Change-Id: Iadf2a05a373d031d33a5fdacf872b9d8fdd05038
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/158350
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/.vpython3 b/.vpython3
deleted file mode 100644
index a24de03..0000000
--- a/.vpython3
+++ /dev/null
@@ -1,53 +0,0 @@
-# This is a vpython "spec" file.
-#
-# It describes patterns for python wheel dependencies of the python scripts in
-# the chromium repo, particularly for dependencies that have compiled components
-# (since pure-python dependencies can be easily vendored into third_party).
-#
-# When vpython is invoked, it finds this file and builds a python VirtualEnv,
-# containing all of the dependencies described in this file, fetching them from
-# CIPD (the "Chrome Infrastructure Package Deployer" service). Unlike `pip`,
-# this never requires the end-user machine to have a working python extension
-# compilation environment. All of these packages are built using:
-#   https://chromium.googlesource.com/infra/infra/+/main/infra/tools/dockerbuild/
-#
-# All python scripts in the repo share this same spec, to avoid dependency
-# fragmentation.
-#
-# If you have depot_tools installed in your $PATH, you can invoke python scripts
-# in this repo by running them as you normally would run them, except
-# substituting `vpython` instead of `python` on the command line, e.g.:
-#   vpython path/to/script.py some --arguments
-#
-# Read more about `vpython` and how to modify this file here:
-#   https://chromium.googlesource.com/infra/infra/+/main/doc/users/vpython.md
-
-python_version: "3.11"
-
-# Used by build/util/lib/results/result_sink.py
-wheel: <
-  name: "infra/python/wheels/certifi-py3"
-  version: "version:2023.7.22"
->
-wheel: <
-  name: "infra/python/wheels/charset_normalizer-py3"
-  version: "version:3.1.0"
->
-wheel: <
-  name: "infra/python/wheels/idna-py3"
-  version: "version:3.4"
->
-wheel: <
-  name: "infra/python/wheels/requests-py3"
-  version: "version:2.31.0"
->
-wheel: <
-  name: "infra/python/wheels/urllib3-py3"
-  version: "version:2.0.3"
->
-
-# Used by //testing/scripts/rust unit tests.
-wheel: <
-  name: "infra/python/wheels/pyfakefs-py2_py3"
-  version: "version:3.7.2"
->
diff --git a/build_overrides/build.gni b/build_overrides/build.gni
index dfad930..b11047f 100644
--- a/build_overrides/build.gni
+++ b/build_overrides/build.gni
@@ -26,6 +26,11 @@
 lsan_suppressions_file = "//build/sanitizers/lsan_suppressions.cc"
 tsan_suppressions_file = "//build/sanitizers/tsan_suppressions.cc"
 
+vpython_spec_files = [
+  "//vpython.toml",
+  "//vpython.toml.uv.lock",
+]
+
 declare_args() {
   # Android 32-bit non-component, non-clang builds cannot have symbol_level=2
   # due to 4GiB file size limit, see https://crbug.com/648948.
diff --git a/testing/tools/BUILD.gn b/testing/tools/BUILD.gn
index 860142e..5b6847d 100644
--- a/testing/tools/BUILD.gn
+++ b/testing/tools/BUILD.gn
@@ -25,12 +25,13 @@
       ".",
       "../SUPPRESSIONS",
       "../corpus/",
-      "../../.vpython3",
       "../../build/skia_gold_common/",
       "../../build/util/lib/",
       "../../third_party/test_fonts/",
       "../../tools/resultdb/",
       "../../tools/skia_goldctl/",
+      "../../vpython.toml",
+      "../../vpython.toml.uv.lock",
     ]
 
     # Built runtime dependencies.
diff --git a/vpython.toml b/vpython.toml
new file mode 100644
index 0000000..1349814
--- /dev/null
+++ b/vpython.toml
@@ -0,0 +1,13 @@
+# Copyright 2026 The PDFium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+requires-python = '>=3.11,<3.12'
+dependencies = [
+  'certifi==2023.7.22',
+  'charset-normalizer==3.1.0',
+  'idna==3.4',
+  'pyfakefs==3.7.2',
+  'requests==2.31.0',
+  'urllib3==2.0.3',
+]
diff --git a/vpython.toml.uv.lock b/vpython.toml.uv.lock
new file mode 100644
index 0000000..442cba9
--- /dev/null
+++ b/vpython.toml.uv.lock
@@ -0,0 +1,33 @@
+certifi==2023.7.22 \
+    --hash=sha256:85478a6407953dbbe31f782e3c9b72952c1841d05ac7445371fa1ff9d7ea51cc \
+    --hash=sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9
+    # via requests
+charset-normalizer==3.1.0 \
+    --hash=sha256:2e2eb7f44bc541efc6d333083f1eb1bf9b2ede59eb9c3224f55a6e23b49f06f1 \
+    --hash=sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d
+    # via requests
+idna==3.4 \
+    --hash=sha256:52926a5baa595cfe5376963d8c5bbed33c4c83628dbd1958fc5734d664701b0c \
+    --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 \
+    --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 \
+    --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 \
+    --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 \
+    --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 \
+    --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 \
+    --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 \
+    --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2
+    # via requests
+pyfakefs==3.7.2 \
+    --hash=sha256:8259042941a0690b89d92d55ed8fb1720ca4a83db87713d2fb9717cfd5e5f18e \
+    --hash=sha256:9b3718c246ec98ca8269c6d19e9c33c1cc3af32e22bf189bddb921bc7fc16e39 \
+    --hash=sha256:9e98f7179507c650ce17824e6493a4effef03e726ffe9f84917f5800266edcc9 \
+    --hash=sha256:f415f38fe488b46974700af95f22b37e951a51159403eb9011ca37db0fde8b97 \
+    --hash=sha256:f415f38fe488b46974700af95f22b37e951a51159403eb9011ca37db0fde8b97 \
+    --hash=sha256:f415f38fe488b46974700af95f22b37e951a51159403eb9011ca37db0fde8b97
+requests==2.31.0 \
+    --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
+    --hash=sha256:7c024df3d83d462cc8127c6c9a2dae2e5d2bddb54c1039624ab3baf485d752ca
+urllib3==2.0.3 \
+    --hash=sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1 \
+    --hash=sha256:e8f53a057713d1015942230188267a70017526bcda7d4427b067e4fe9fb53626
+    # via requests