Pewarta Proxy

📋 Server Request & Proxy Logs

Loading active proxy settings...
Developed by Khairul Adha (adhexa.id)
Mengambil log server...

⚙️ Pengaturan Proxy Target

Skip to content
Draft
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6de5237
Add _zstd stdlib module backing compression.zstd
JamesClarke7283 May 23, 2026
78c3702
Fix iOS build by removing static PyMutex<PyTypeRef>
JamesClarke7283 May 23, 2026
cb70b82
Fix clippy errors in zstd module
JamesClarke7283 May 23, 2026
fb78bef
Retrigger CI
JamesClarke7283 May 23, 2026
97ba0b4
chore: format zstd module
JamesClarke7283 May 23, 2026
31c4296
Update crates/stdlib/src/zstd.rs
JamesClarke7283 May 24, 2026
ca664fd
chore: remove rustdoc comments from zstd module
JamesClarke7283 May 24, 2026
a9ce31b
commit message
JamesClarke7283 May 25, 2026
b77ba8b
commit message
JamesClarke7283 May 25, 2026
acfb59b
Identify zstd parameter enums by type identity, not name
JamesClarke7283 Jun 3, 2026
cca16a0
Match CPython error behavior in _zstd ZstdCompressor
JamesClarke7283 Jun 3, 2026
5b558cf
Address review: drop decorative separators and unused zstd crate
JamesClarke7283 Aug 9, 2026
265e591
Switch _zstd backend from zstd-safe to pure-Rust libzstd-rs-sys
JamesClarke7283 Aug 9, 2026
e84daba
Fix data loss in ZstdDecompressor.decompress(max_length=0)
JamesClarke7283 Aug 9, 2026
2466964
Drop duplicate spell-checker line in zstd.rs
JamesClarke7283 Aug 9, 2026
3372949
Address review on _zstd constants, version attrs and dict markers
JamesClarke7283 Aug 19, 2026
a7f161c
Replace the _zstd flush-mode constants with a CompressMode enum
JamesClarke7283 Aug 19, 2026
04d560c
Correct the _zstd explanatory comments and raise MemoryError on OOM
JamesClarke7283 Aug 19, 2026
97b6f48
Fix CPython divergences and a crash in the _zstd module
JamesClarke7283 Aug 19, 2026
acd733c
Restore Lib/test/test_zstd.py to its vendored CPython state
JamesClarke7283 Aug 19, 2026
bae349d
Rewrite _zstd against rusty_zstd
youknowone Oct 1, 2026
d9130bd
Use libzstd-rs-sys for _zstd
youknowone Oct 1, 2026
4707f1b
Add zstd context and dictionary names to spell-checker ignore
youknowone Oct 15, 2026
bd61e5f
Exclude _zstd from wasm32-unknown-unknown
youknowone Oct 15, 2026
cb083af
Build _zstd on wasm32-unknown-unknown with a libzstd-rs-sys fork
youknowone Oct 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Identify zstd parameter enums by type identity, not name
- Have set_parameter_types stash the CompressionParameter/DecompressionParameter classes as private _zstd module attributes instead of validating and discarding them
- check_wrong_param_kind now compares key classes by identity against the registered type, matching CPython's Py_TYPE check, and skips when unregistered
- Error message names the actual key type as an attribute
  • Loading branch information
JamesClarke7283 authored and youknowone committed Oct 16, 2026
commit acfb59b7c846c7b9d4e6a68ff58419164c3267ff
87 changes: 41 additions & 46 deletions crates/stdlib/src/zstd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,6 @@ mod _zstd {
use zstd_safe::zstd_sys;
use zstd_safe::{CCtx, CParameter, DCtx, DParameter, InBuffer, OutBuffer};

/// Class names of the `CompressionParameter` and `DecompressionParameter`
/// `IntEnum`s defined by the pure-Python wrapper at
/// `Lib/compression/zstd/__init__.py`. We identify these by name rather
/// than identity because storing `PyTypeRef` in a Rust `static` requires
/// `Sync`, which `PyMutex` does not provide on single-threaded targets
/// (Android, iOS, wasm32). Name comparison is sufficient since both names
/// originate from a module we ship and control.
const C_PARAMETER_TYPE_NAME: &str = "CompressionParameter";
const D_PARAMETER_TYPE_NAME: &str = "DecompressionParameter";

// =========================================================================
// Module-level constants
// =========================================================================
Expand Down Expand Up @@ -177,29 +167,30 @@ mod _zstd {
// Parameter helpers
// =========================================================================

/// If `key`'s class is the wrong kind of parameter enum for the caller's
/// context (a `CompressionParameter` passed to a decompressor, or vice
/// versa), return a `TypeError`. Used by both (de)compressor option-dict
/// loops so the resulting message names the actual type rather than the
/// generic "out of range" wording.
/// Reject an options-dict `key` whose class is the parameter enum that is
/// invalid for the caller's context (a `CompressionParameter` passed to a
/// decompressor, or vice versa) with a `TypeError` naming the type.
///
/// We identify the enums by class name (see [`C_PARAMETER_TYPE_NAME`]),
/// which avoids storing a `PyTypeRef` in a Rust `static` (impossible on
/// single-threaded builds whose `PyMutex` is not `Sync`).
/// `forbidden` is that invalid enum class, resolved once by the caller from
/// the types the pure-Python wrapper registers via [`set_parameter_types`];
/// `None` (the wrapper never ran) skips the check, matching CPython's NULL
/// module-state pointers. The comparison is by identity, mirroring
/// CPython's `Py_TYPE(key) == ...` check.
fn check_wrong_param_kind(
key: &PyObjectRef,
is_compress: bool,
forbidden: Option<&PyObjectRef>,
kind: &str,
vm: &VirtualMachine,
) -> PyResult<()> {
let class_name = key.class().name();
let (forbidden, kind) = if is_compress {
(D_PARAMETER_TYPE_NAME, "compression")
} else {
(C_PARAMETER_TYPE_NAME, "decompression")
let Some(forbidden) = forbidden else {
return Ok(());
};
if &*class_name == forbidden {
if key.class().is(forbidden) {
// `key`'s class is `forbidden` here, so name it directly (the same
// string CPython formats from `Py_TYPE(key)->tp_name`).
let name = key.class().name();
return Err(vm.new_type_error(format!(
"{kind} options dictionary key must not be a {forbidden}"
"{kind} options dictionary key must not be a {name} attribute"
)));
}
Ok(())
Expand Down Expand Up @@ -705,12 +696,21 @@ mod _zstd {
let dict = options_obj
.downcast::<PyDict>()
.map_err(|_| vm.new_type_error("options must be a dict"))?;
// Resolve the parameter enum class that is invalid for this direction
// (registered by the pure-Python wrapper via set_parameter_types) once,
// so a key from the wrong family yields a clear TypeError naming the
// type. `None` when the wrapper never ran (e.g. `_zstd` used directly).
let (wrong_kind_attr, kind) = if is_compress {
("_decompression_parameter_type", "compression")
} else {
("_compression_parameter_type", "decompression")
};
let wrong_kind = vm.get_attribute_opt(vm.import("_zstd", 0)?, wrong_kind_attr)?;
for (k, v) in dict {
// Reject the wrong enum kind ("CompressionParameter" vs
// "DecompressionParameter") before doing any numeric coercion,
// so the error carries the documented type name rather than a
// Reject a key from the wrong parameter family before any numeric
// coercion, so the error names the type rather than giving a
// generic out-of-range message.
check_wrong_param_kind(&k, is_compress, vm)?;
check_wrong_param_kind(&k, wrong_kind.as_ref(), kind, vm)?;
let key_int: i32 = k.try_to_value(vm)?;
let val_int: i32 = v.try_to_value(vm)?;
// libzstd silently clamps out-of-range values for some
Expand Down Expand Up @@ -1572,26 +1572,21 @@ mod _zstd {
Ok((bounds.lowerBound, bounds.upperBound))
}

// The (de)compressor constructors identify the parameter enums by class
// *name* (see [`check_wrong_param_kind`]) rather than identity, so this
// function does not need to retain the type objects beyond the call.
// CPython retains them to produce nicer error messages naming the specific
// enum member; matching that would require a `Sync` cell-of-`PyTypeRef`,
// which is not available on single-threaded targets. The pure-Python
// wrapper at `Lib/compression/zstd/__init__.py:242` calls this exactly
// once at import time.
// Register the `CompressionParameter` / `DecompressionParameter` enum
// classes defined by the pure-Python wrapper so [`check_wrong_param_kind`]
// can reject a key from the wrong parameter family by identity. The types
// are stashed as private `_zstd` module attributes — the RustPython
// equivalent of the module state CPython keeps these in. The wrapper in
// `Lib/compression/zstd/__init__.py` calls this exactly once at import.
#[pyfunction]
fn set_parameter_types(
c_parameter_type: PyObjectRef,
d_parameter_type: PyObjectRef,
c_parameter_type: PyTypeRef,
d_parameter_type: PyTypeRef,
vm: &VirtualMachine,
) -> PyResult<()> {
let _ = c_parameter_type
.downcast::<PyType>()
.map_err(|_| vm.new_type_error("c_parameter_type must be a type object"))?;
let _ = d_parameter_type
.downcast::<PyType>()
.map_err(|_| vm.new_type_error("d_parameter_type must be a type object"))?;
let module = vm.import("_zstd", 0)?;
module.set_attr("_compression_parameter_type", c_parameter_type, vm)?;
module.set_attr("_decompression_parameter_type", d_parameter_type, vm)?;
Ok(())
}
}