bump pyo3

This commit is contained in:
Jean-Marie Mineau 2025-01-23 12:01:28 +01:00
parent 65176749bb
commit eb89441dad
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
9 changed files with 135 additions and 258 deletions

159
Cargo.lock generated
View file

@ -98,12 +98,6 @@ dependencies = [
"rustc-demangle",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "block-buffer"
version = "0.10.4"
@ -242,9 +236,9 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "heck"
version = "0.4.1"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "indoc"
@ -264,16 +258,6 @@ version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]]
name = "lock_api"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.20"
@ -319,29 +303,6 @@ version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-targets",
]
[[package]]
name = "portable-atomic"
version = "1.6.0"
@ -366,25 +327,25 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.78"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
dependencies = [
"unicode-ident",
]
[[package]]
name = "pyo3"
version = "0.21.2"
version = "0.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5e00b96a521718e08e03b1a622f01c8a8deb50719335de3f60b3b3950f069d8"
checksum = "57fe09249128b3173d092de9523eaa75136bf7ba85e0d69eca241c7939c933cc"
dependencies = [
"anyhow",
"cfg-if",
"indoc",
"libc",
"memoffset",
"parking_lot",
"once_cell",
"portable-atomic",
"pyo3-build-config",
"pyo3-ffi",
@ -394,9 +355,9 @@ dependencies = [
[[package]]
name = "pyo3-build-config"
version = "0.21.2"
version = "0.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7883df5835fafdad87c0d888b266c8ec0f4c9ca48a5bed6bbb592e8dedee1b50"
checksum = "1cd3927b5a78757a0d71aa9dff669f903b1eb64b54142a9bd9f757f8fde65fd7"
dependencies = [
"once_cell",
"target-lexicon",
@ -404,9 +365,9 @@ dependencies = [
[[package]]
name = "pyo3-ffi"
version = "0.21.2"
version = "0.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01be5843dc60b916ab4dad1dca6d20b9b4e6ddc8e15f50c47fe6d85f1fb97403"
checksum = "dab6bb2102bd8f991e7749f130a70d05dd557613e39ed2deeee8e9ca0c4d548d"
dependencies = [
"libc",
"pyo3-build-config",
@ -414,9 +375,9 @@ dependencies = [
[[package]]
name = "pyo3-log"
version = "0.10.0"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2af49834b8d2ecd555177e63b273b708dea75150abc6f5341d0a6e1a9623976c"
checksum = "be5bb22b77965a7b5394e9aae9897a0607b51df5167561ffc3b02643b4200bc7"
dependencies = [
"arc-swap",
"log",
@ -425,9 +386,9 @@ dependencies = [
[[package]]
name = "pyo3-macros"
version = "0.21.2"
version = "0.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77b34069fc0682e11b31dbd10321cbf94808394c56fd996796ce45217dfac53c"
checksum = "91871864b353fd5ffcb3f91f2f703a22a9797c91b9ab497b1acac7b07ae509c7"
dependencies = [
"proc-macro2",
"pyo3-macros-backend",
@ -437,9 +398,9 @@ dependencies = [
[[package]]
name = "pyo3-macros-backend"
version = "0.21.2"
version = "0.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08260721f32db5e1a5beae69a55553f56b99bd0e1c3e6e0a5e8851a9d0f5a85c"
checksum = "43abc3b80bc20f3facd86cd3c60beed58c3e2aa26213f3cda368de39c60a27e4"
dependencies = [
"heck",
"proc-macro2",
@ -507,15 +468,6 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "redox_syscall"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [
"bitflags",
]
[[package]]
name = "rustc-demangle"
version = "0.1.23"
@ -528,12 +480,6 @@ version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
version = "1.0.195"
@ -576,17 +522,11 @@ dependencies = [
"digest",
]
[[package]]
name = "smallvec"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
[[package]]
name = "syn"
version = "2.0.48"
version = "2.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
dependencies = [
"proc-macro2",
"quote",
@ -595,9 +535,9 @@ dependencies = [
[[package]]
name = "target-lexicon"
version = "0.12.11"
version = "0.12.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a"
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
[[package]]
name = "typenum"
@ -629,63 +569,6 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "yansi"
version = "1.0.1"

View file

@ -14,8 +14,8 @@ androscalpel_serializer = { version = "0.1.0", path = "../androscalpel_serialize
anyhow = { version = "1.0.75", features = ["backtrace"] }
apk_frauder = { version = "0.1.0", path = "../apk_frauder" }
log = "0.4.20"
pyo3 = { version = "0.21.0", features = ["anyhow", "abi3-py38"] }
pyo3-log = "0.10.0"
pyo3 = { version = "0.23.4", features = ["anyhow", "abi3-py38"] }
pyo3-log = "0.12.1"
rayon = "1.9.0"
serde = { version = "1.0.195", features = ["derive"] }
serde_json = "1.0.111"

View file

@ -35,46 +35,6 @@ pub struct Apk {
}
impl Apk {
/// Add the content of a dex file to the apk.
///
/// # Parameters
/// - `name`: the name of the dex file
/// - `data`: the dex file binary
/// - `label_each_ins`: if set to true, insert a label before each instruction
/// indicating the instruction address
/// - `cache`: if set to true, copy and cache the binary data format.
pub fn add_dex_file(
&mut self,
name: &str,
data: &[u8],
label_each_ins: bool,
cache: bool,
) -> Result<()> {
let name: String = name.into();
if self.dex_files.contains_key(&name) {
bail!("{name} already exist in the application")
}
let mut dex = DexFileReader::new(data)?;
let classes = dex
.get_class_defs()
.par_iter()
.enumerate()
.map(|(idx, class)| self.get_class_from_dex_file(class, idx, &dex, label_each_ins))
.map(|class| class.map(|class| (class.descriptor.clone(), class)))
.collect::<Result<HashMap<IdType, Class>, _>>()?;
let dex_file = DexFile {
classes,
not_referenced_strings: dex
.get_not_resolved_strings()?
.into_iter()
.map(DexString)
.collect(),
bin_cache: if cache { Some(data.to_vec()) } else { None },
};
self.dex_files.insert(name, dex_file);
Ok(())
}
/// Extract a class from a dex file reader.
/// `class_item_idx` if the index of the `class_def_item` of the class, **not** the
/// `class_idx`.
@ -3026,20 +2986,46 @@ impl Apk {
}
}
#[pyo3(name = "add_dex_file")]
pub fn py_add_dex_file(
// TODO: change cache to true when cache invalidation is setup
/// Add the content of a dex file to the apk.
///
/// # Parameters
/// - `name`: the name of the dex file
/// - `data`: the dex file binary
/// - `label_each_ins`: if set to true, insert a label before each instruction
/// indicating the instruction address
/// - `cache`: if set to true, copy and cache the binary data format.
#[pyo3(signature = (name, data, label_each_ins=false, cache=false))]
pub fn add_dex_file(
&mut self,
name: &str,
data: &[u8],
label_each_ins: Option<bool>,
cache: Option<bool>,
label_each_ins: bool,
cache: bool,
) -> Result<()> {
self.add_dex_file(
name,
data,
label_each_ins.unwrap_or(false),
cache.unwrap_or(false), // TODO: change to true when cache invalidation is setup
)
let name: String = name.into();
if self.dex_files.contains_key(&name) {
bail!("{name} already exist in the application")
}
let mut dex = DexFileReader::new(data)?;
let classes = dex
.get_class_defs()
.par_iter()
.enumerate()
.map(|(idx, class)| self.get_class_from_dex_file(class, idx, &dex, label_each_ins))
.map(|class| class.map(|class| (class.descriptor.clone(), class)))
.collect::<Result<HashMap<IdType, Class>, _>>()?;
let dex_file = DexFile {
classes,
not_referenced_strings: dex
.get_not_resolved_strings()?
.into_iter()
.map(DexString)
.collect(),
bin_cache: if cache { Some(data.to_vec()) } else { None },
};
self.dex_files.insert(name, dex_file);
Ok(())
}
pub fn add_class(&mut self, dex_file: &str, class: Class) -> Result<()> {
@ -3066,6 +3052,7 @@ impl Apk {
Ok(())
}
#[pyo3(signature = (method_id, code=None, dex_file=None))]
pub fn set_method_code(
&mut self,
method_id: IdMethod,
@ -3109,7 +3096,7 @@ impl Apk {
Ok(self
.gen_raw_dex()?
.into_iter()
.map(|(file_name, bytes)| (file_name, PyBytes::new_bound(py, &bytes).into()))
.map(|(file_name, bytes)| (file_name, PyBytes::new(py, &bytes).into()))
.collect())
}
@ -3122,6 +3109,7 @@ impl Apk {
Ok(serde_json::from_str(json)?)
}
#[pyo3(signature = (class, dex_file=None))]
pub fn remove_class(&mut self, class: &IdType, dex_file: Option<&str>) -> Result<()> {
if let Some(dex_file) = dex_file {
self.dex_files

View file

@ -64,6 +64,7 @@ impl Code {
}
#[new]
#[pyo3(signature = (registers_size, ins_size, outs_size, insns, parameter_names=None))]
pub fn new(
registers_size: u16,
ins_size: u16,

View file

@ -50,7 +50,7 @@ pub struct Field {
}
/// Represent the visibility of a field
#[pyclass]
#[pyclass(eq, eq_int)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub enum FieldVisibility {
Public,

View file

@ -79,10 +79,10 @@ fn androscalpel(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<Code>()?;
m.add_class::<Apk>()?;
let ins_module = PyModule::new_bound(py, "ins")?;
let ins_module = PyModule::new(py, "ins")?;
androscalpel_ins(py, &ins_module)?;
m.add_submodule(&ins_module)?;
let utils_module = PyModule::new_bound(py, "utils")?;
let utils_module = PyModule::new(py, "utils")?;
py_utils::export_module(py, &utils_module)?;
m.add_submodule(&utils_module)?;

View file

@ -13,7 +13,7 @@ use androscalpel_serializer::consts::*;
/// Represent a method.
#[pyclass]
#[derive(Debug, Clone, Deserialize, Serialize)] //, PartialEq)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Method {
/// The structure used to reference this method.
#[pyo3(get)]
@ -70,18 +70,9 @@ pub struct Method {
#[pyo3(get)]
pub code: Option<Code>,
}
impl PartialEq for Method {
fn eq(&self, other: &Self) -> bool {
let res = self.code.eq(&other.code);
if !res {
//panic!("{} code don't match", self.descriptor.__str__());
}
return res;
}
}
/// Represent the visibility of a field
#[pyclass]
#[pyclass(eq, eq_int)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
pub enum MethodVisibility {
Public,

View file

@ -1,7 +1,7 @@
//! Function that are can be usefull on the python side.
use pyo3::prelude::*;
use pyo3::types::PyBytes;
use pyo3::types::{PyBytes, PyBytesMethods};
use std::collections::{HashMap, HashSet};
use std::fs::File;
@ -17,18 +17,18 @@ use apk_frauder::{end_of_central_directory::EndCentralDirectory, ZipFileReader};
/// Convert an integer to the uleb128 byte encoding
#[pyfunction]
pub fn int_to_uleb128(py: Python, x: u32) -> Result<PyObject> {
Ok(PyBytes::new_bound(py, &Uleb128(x).serialize_to_vec()?).into())
Ok(PyBytes::new(py, &Uleb128(x).serialize_to_vec()?).into())
}
/// Convert an integer to the uleb128p1 byte encoding
#[pyfunction]
pub fn int_to_uleb128p1(py: Python, x: u32) -> Result<PyObject> {
Ok(PyBytes::new_bound(py, &Uleb128p1(x).serialize_to_vec()?).into())
Ok(PyBytes::new(py, &Uleb128p1(x).serialize_to_vec()?).into())
}
/// Convert an integer to the sleb128 byte encoding
#[pyfunction]
pub fn int_to_sleb128(py: Python, x: i32) -> Result<PyObject> {
Ok(PyBytes::new_bound(py, &Sleb128(x).serialize_to_vec()?).into())
Ok(PyBytes::new(py, &Sleb128(x).serialize_to_vec()?).into())
}
/// Decode an uleb128 encoded integer
@ -109,26 +109,36 @@ pub fn is_zip(file: PathBuf) -> bool {
/// The keys are the file names and the values are `None` to remove the file, or
/// `bytes` for the content of the file.
#[pyfunction]
#[pyo3(signature = (
apk,
dst,
dexfiles,
keystore,
zipalign=None,
apksigner=None,
additionnal_files=None
))]
pub fn replace_dex(
apk: PathBuf,
dst: PathBuf,
dexfiles: Vec<&PyBytes>,
dexfiles: Vec<Bound<'_, PyBytes>>,
keystore: PathBuf,
zipalign: Option<PathBuf>,
apksigner: Option<PathBuf>,
additionnal_files: Option<HashMap<String, Option<&PyBytes>>>,
additionnal_files: Option<HashMap<String, Option<Bound<'_, PyBytes>>>>,
) {
let mut dexfiles: Vec<_> = dexfiles
.into_iter()
.map(PyBytes::as_bytes)
.iter()
.map(PyBytesMethods::as_bytes)
.map(Cursor::new)
.collect();
let additionnal_files: Option<HashMap<_, _>> = additionnal_files.map(|additionnal_files| {
additionnal_files
.into_iter()
.map(|(k, v)| (k, v.map(PyBytes::as_bytes).map(Cursor::new)))
.collect()
});
let additionnal_files: Option<HashMap<_, _>> = additionnal_files.as_ref().map(|additionnal_files|
additionnal_files.iter()
.map(|(k, v)| (
k.clone(),
v.as_ref().map(|bytes| bytes.as_bytes()).map(Cursor::new)
)).collect()
);
apk_frauder::replace_dex(
apk,
dst,

View file

@ -84,42 +84,42 @@ impl<V: VisitorMut> VisitableMut<V> for DexValue {
}
impl<'source> FromPyObject<'source> for DexValue {
fn extract(ob: &'source PyAny) -> PyResult<Self> {
if let Ok(val) = DexByte::extract(ob) {
fn extract_bound(ob: &Bound<'source, PyAny>) -> PyResult<Self> {
if let Ok(val) = DexByte::extract_bound(ob) {
Ok(Self::Byte(val))
} else if let Ok(val) = DexShort::extract(ob) {
} else if let Ok(val) = DexShort::extract_bound(ob) {
Ok(Self::Short(val))
} else if let Ok(val) = DexChar::extract(ob) {
} else if let Ok(val) = DexChar::extract_bound(ob) {
Ok(Self::Char(val))
} else if let Ok(val) = DexInt::extract(ob) {
} else if let Ok(val) = DexInt::extract_bound(ob) {
Ok(Self::Int(val))
} else if let Ok(val) = DexLong::extract(ob) {
} else if let Ok(val) = DexLong::extract_bound(ob) {
Ok(Self::Long(val))
} else if let Ok(val) = DexFloat::extract(ob) {
} else if let Ok(val) = DexFloat::extract_bound(ob) {
Ok(Self::Float(val))
} else if let Ok(val) = DexDouble::extract(ob) {
} else if let Ok(val) = DexDouble::extract_bound(ob) {
Ok(Self::Double(val))
} else if let Ok(val) = DexString::extract(ob) {
} else if let Ok(val) = DexString::extract_bound(ob) {
Ok(Self::String(val))
} else if let Ok(val) = IdType::extract(ob) {
} else if let Ok(val) = IdType::extract_bound(ob) {
Ok(Self::Type(val))
} else if let Ok(val) = IdField::extract(ob) {
} else if let Ok(val) = IdField::extract_bound(ob) {
Ok(Self::Field(val))
} else if let Ok(val) = IdMethod::extract(ob) {
} else if let Ok(val) = IdMethod::extract_bound(ob) {
Ok(Self::Method(val))
} else if let Ok(val) = IdEnum::extract(ob) {
} else if let Ok(val) = IdEnum::extract_bound(ob) {
Ok(Self::Enum(val))
} else if let Ok(val) = DexArray::extract(ob) {
} else if let Ok(val) = DexArray::extract_bound(ob) {
Ok(Self::Array(val))
} else if let Ok(val) = DexAnnotation::extract(ob) {
} else if let Ok(val) = DexAnnotation::extract_bound(ob) {
Ok(Self::Annotation(val))
} else if let Ok(val) = DexNull::extract(ob) {
} else if let Ok(val) = DexNull::extract_bound(ob) {
Ok(Self::Null(val))
} else if let Ok(val) = DexBoolean::extract(ob) {
} else if let Ok(val) = DexBoolean::extract_bound(ob) {
Ok(Self::Boolean(val))
} else if let Ok(val) = IdMethodType::extract(ob) {
} else if let Ok(val) = IdMethodType::extract_bound(ob) {
Ok(Self::MethodType(val))
} else if let Ok(val) = MethodHandle::extract(ob) {
} else if let Ok(val) = MethodHandle::extract_bound(ob) {
Ok(Self::MethodHandle(val))
} else {
Err(PyErr::new::<PyTypeError, _>(format!(
@ -306,27 +306,31 @@ impl DexValue {
}
}
impl IntoPy<PyObject> for DexValue {
fn into_py(self, py: Python<'_>) -> PyObject {
impl<'py> IntoPyObject<'py> for DexValue {
type Target = PyAny;
type Output = Bound<'py, Self::Target>;
type Error = PyErr;
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
match self {
DexValue::Byte(val) => val.into_py(py),
DexValue::Short(val) => val.into_py(py),
DexValue::Char(val) => val.into_py(py),
DexValue::Int(val) => val.into_py(py),
DexValue::Long(val) => val.into_py(py),
DexValue::Float(val) => val.into_py(py),
DexValue::Double(val) => val.into_py(py),
DexValue::MethodType(val) => val.into_py(py),
DexValue::MethodHandle(val) => val.into_py(py),
DexValue::String(val) => val.into_py(py),
DexValue::Type(val) => val.into_py(py),
DexValue::Field(val) => val.into_py(py),
DexValue::Method(val) => val.into_py(py),
DexValue::Enum(val) => val.into_py(py),
DexValue::Array(val) => val.into_py(py),
DexValue::Annotation(val) => val.into_py(py),
DexValue::Null(val) => val.into_py(py),
DexValue::Boolean(val) => val.into_py(py),
DexValue::Byte(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::Short(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::Char(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::Int(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::Long(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::Float(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::Double(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::MethodType(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::MethodHandle(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::String(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::Type(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::Field(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::Method(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::Enum(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::Array(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::Annotation(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::Null(val) => Bound::new(py, val).map(Bound::<_>::into_any),
DexValue::Boolean(val) => Bound::new(py, val).map(Bound::<_>::into_any),
}
}
}