about summary refs log tree commit diff stats
path: root/crates/yt_dlp/src/info_json.rs
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-07-10 16:36:42 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-07-10 16:36:42 +0200
commit82277ca7513eff82365ed54fe9836aae5bd45fe1 (patch)
tree3c1ba24fbcb9ef5bb5d7fbeaeea8a46cd7f61ae9 /crates/yt_dlp/src/info_json.rs
parentrefactor(crates/bytes): Move into yt (diff)
downloadyt-82277ca7513eff82365ed54fe9836aae5bd45fe1.zip
refactor(crates/yt_dlp): Port to `pyo3` again
Rustpyton is slower, does not implement everything correctly and worst
of all, contains code produced by LLM's.

Using the freethreaded mode of pyo3 also works nicely around the GIL,
and enables parallel execution.
Diffstat (limited to 'crates/yt_dlp/src/info_json.rs')
-rw-r--r--crates/yt_dlp/src/info_json.rs48
1 files changed, 22 insertions, 26 deletions
diff --git a/crates/yt_dlp/src/info_json.rs b/crates/yt_dlp/src/info_json.rs
index 31f4a69..3ed08ee 100644
--- a/crates/yt_dlp/src/info_json.rs
+++ b/crates/yt_dlp/src/info_json.rs
@@ -8,50 +8,46 @@
 // You should have received a copy of the License along with this program.
 // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
 
-use rustpython::vm::{
-    PyRef, VirtualMachine,
-    builtins::{PyDict, PyStr},
+use pyo3::{
+    Bound, Python, intern,
+    types::{PyAnyMethods, PyDict},
 };
 
 pub type InfoJson = serde_json::Map<String, serde_json::Value>;
 
+/// # Panics
+/// If expectation about python operations fail.
+#[must_use]
 pub fn json_loads(
     input: serde_json::Map<String, serde_json::Value>,
-    vm: &VirtualMachine,
-) -> PyRef<PyDict> {
-    let json = vm.import("json", 0).expect("Module exists");
-    let loads = json.get_attr("loads", vm).expect("Method exists");
+    py: Python<'_>,
+) -> Bound<'_, PyDict> {
+    let json = py.import(intern!(py, "json")).expect("Module exists");
+    let loads = json.getattr(intern!(py, "loads")).expect("Method exists");
     let self_str = serde_json::to_string(&serde_json::Value::Object(input)).expect("Vaild json");
     let dict = loads
-        .call((self_str,), vm)
+        .call((self_str,), None)
         .expect("Vaild json is always a valid dict");
 
-    dict.downcast().expect("Should always be a dict")
+    dict.downcast_into().expect("Should always be a dict")
 }
 
 /// # Panics
 /// If expectation about python operations fail.
-pub fn json_dumps(
-    input: PyRef<PyDict>,
-    vm: &VirtualMachine,
-) -> serde_json::Map<String, serde_json::Value> {
-    let json = vm.import("json", 0).expect("Module exists");
-    let dumps = json.get_attr("dumps", vm).expect("Method exists");
+#[must_use]
+pub fn json_dumps(input: &Bound<'_, PyDict>) -> serde_json::Map<String, serde_json::Value> {
+    let py = input.py();
+
+    let json = py.import(intern!(py, "json")).expect("Module exists");
+    let dumps = json.getattr(intern!(py, "dumps")).expect("Method exists");
     let dict = dumps
-        .call((input,), vm)
-        .map_err(|err| vm.print_exception(err))
+        .call((input,), None)
+        .map_err(|err| err.print(py))
         .expect("Might not always work, but for our dicts it works");
 
-    let string: PyRef<PyStr> = dict.downcast().expect("Should always be a string");
-
-    let real_string = string.to_str().expect("Should be valid utf8");
-
-    // {
-    //     let mut file = File::create("debug.dump.json").unwrap();
-    //     write!(file, "{}", real_string).unwrap();
-    // }
+    let string: String = dict.extract().expect("Should always be a string");
 
-    let value: serde_json::Value = serde_json::from_str(real_string).expect("Should be valid json");
+    let value: serde_json::Value = serde_json::from_str(&string).expect("Should be valid json");
 
     match value {
         serde_json::Value::Object(map) => map,