Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ scrypt = { version = "0.11", default-features = false }
# DEFLATE output is byte-identical to the reference C zlib.
flate2 = { version = "1.1.9", default-features = false }
zlib-rs = { version = "0.6.5", default-features = false, features = ["rust-allocator", "__internal-api"] }
# bzip2 backend (pyre-native only): the crate's default feature selects
# libbz2-rs-sys, the pure-Rust libbz2 port from the same source as zlib-rs,
# whose output is byte-identical to the reference C libbz2.
bzip2 = "0.6.1"
# binascii transforms (pure-Rust logic).
base64 = "0.22"
crc32fast = "1.4"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
bridges_compiled=21
bridges_compiled=2
descr_set_absent=0
descr_set_ambiguous=0
descr_set_stale_absent=0
Expand All @@ -8,8 +8,8 @@ fbw_rolled_back_with_effects=0
fbw_store_journal_rollback_failed=0
field_pos_attached_misplaced=0
field_pos_spec_misplaced=0
guard_failures=3780
guard_failures=402
internal_compile_panics=0
loops_aborted=0
loops_compiled=6
loops_compiled=2
retraces_compiled=0
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
bridges_compiled=21
bridges_compiled=2
descr_set_absent=0
descr_set_ambiguous=0
descr_set_stale_absent=0
Expand All @@ -8,8 +8,8 @@ fbw_rolled_back_with_effects=0
fbw_store_journal_rollback_failed=0
field_pos_attached_misplaced=0
field_pos_spec_misplaced=0
guard_failures=3780
guard_failures=402
internal_compile_panics=0
loops_aborted=0
loops_compiled=6
loops_compiled=2
retraces_compiled=0
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
bridges_compiled=21
bridges_compiled=2
descr_set_absent=0
descr_set_ambiguous=0
descr_set_stale_absent=0
Expand All @@ -8,8 +8,8 @@ fbw_rolled_back_with_effects=0
fbw_store_journal_rollback_failed=0
field_pos_attached_misplaced=0
field_pos_spec_misplaced=0
guard_failures=3780
guard_failures=402
internal_compile_panics=0
loops_aborted=0
loops_compiled=6
loops_compiled=2
retraces_compiled=0
10 changes: 5 additions & 5 deletions pyre/cpython_tests/baseline.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@
"dynasm": "IMPORTERROR"
},
"test.test_bz2": {
"dynasm": "CRASH"
"dynasm": "FAIL"
},
"test.test_c_locale_coercion": {
"cranelift": "PASS",
Expand Down Expand Up @@ -1020,7 +1020,7 @@
"dynasm": "PASS"
},
"test.test_shutil": {
"dynasm": "IMPORTERROR"
"dynasm": "FAIL"
},
"test.test_signal": {
"dynasm": "IMPORTERROR"
Expand Down Expand Up @@ -1063,7 +1063,7 @@
"dynasm": "IMPORTERROR"
},
"test.test_stat": {
"dynasm": "FAIL"
"dynasm": "PASS"
},
"test.test_statistics": {
"dynasm": "IMPORTERROR"
Expand Down Expand Up @@ -1142,7 +1142,7 @@
"dynasm": "PASS"
},
"test.test_tarfile": {
"dynasm": "IMPORTERROR"
"dynasm": "TIMEOUT"
},
"test.test_tcl": {
"dynasm": "IMPORTERROR"
Expand Down Expand Up @@ -1415,7 +1415,7 @@
"dynasm": "PASS"
},
"test.test_zipfile": {
"dynasm": "IMPORTERROR"
"dynasm": "FAIL"
},
"test.test_zipfile64": {
"dynasm": "SKIP",
Expand Down
22 changes: 16 additions & 6 deletions pyre/pyre-interpreter/src/baseobjspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8638,12 +8638,22 @@ pub fn text0_wtf8_w(obj: PyObjectRef) -> Result<&'static Wtf8, PyError> {
Ok(s)
}

/// baseobjspace.py:1819 charbuf_w — a read-only character buffer as raw bytes.
pub fn charbuf_w(obj: PyObjectRef) -> Result<&'static [u8], PyError> {
if unsafe { !pyre_object::bytesobject::is_bytes_like(obj) } {
return Err(PyError::type_error("expected a readable buffer"));
}
Ok(unsafe { pyre_object::bytesobject::bytes_like_data(obj) })
/// baseobjspace.py:1819 charbuf_w — `buffer_w(w_obj, BUF_SIMPLE).as_str()`.
///
/// Every exporter of a C-contiguous read-only buffer qualifies, not only the
/// bytes-like builtins: `array.array` and a `memoryview` over one reach a
/// consumer this way. The acquisition already copies, so the result owns its
/// bytes and the export is released before returning.
pub fn charbuf_w(obj: PyObjectRef) -> Result<Vec<u8>, PyError> {
let Some(buffer) = simple_buffer_bytes(obj)? else {
return Err(PyError::type_error(format!(
"a bytes-like object is required, not '{}'",
object_functionstr_type_name(obj)
)));
};
let data = buffer.as_bytes().to_vec();
buffer.release();
Ok(data)
}

/// One copied `PyBUF_SIMPLE` export whose owner remains rooted and acquired
Expand Down
7 changes: 5 additions & 2 deletions pyre/pyre-interpreter/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3084,10 +3084,13 @@ fn call_with_kwargs_in_ctx_impl(
&& !accepts_keywords_despite_nonbase
&& !unsafe { pyre_object::w_type_get_acceptable_as_base_class(current_type()) }
{
// The constructor names itself the way its own argument clause
// does — bare, without the defining module — so a dotted type
// reports `BZ2Compressor()`, not `_bz2.BZ2Compressor()`.
let type_name = unsafe { pyre_object::w_type_get_name(current_type()) };
let type_name = type_name.rsplit('.').next().unwrap_or(type_name);
return Err(crate::PyError::type_error(format!(
"{}() takes no keyword arguments",
type_name,
"{type_name}() takes no keyword arguments",
)));
}
// Three-argument `type(name, bases, namespace, **kw)` must select the
Expand Down
17 changes: 5 additions & 12 deletions pyre/pyre-interpreter/src/importing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,10 @@ pub fn install_builtin_modules() {
pyre_install_module!(msvcrt);
pyre_install_module!(_abc);
pyre_install_module!(_bisect);
pyre_install_module!(_heapq);
// Frozen importlib imports `_stat` while bootstrapping a sandbox that
// deliberately mounts no stdlib files, so it must stay a builtin.
pyre_install_module!(_stat);
pyre_install_module!(_functools);
pyre_install_module!(_symtable);
pyre_install_module!("_thread"(thread));
Expand Down Expand Up @@ -703,6 +707,7 @@ pub fn install_builtin_modules() {
pyre_install_module!(binascii);
pyre_install_module!(marshal);
pyre_install_module!(zlib);
pyre_install_module!(_bz2);
pyre_install_module!(_typing);
pyre_install_module!(_template);
pyre_install_module!(_hashlib);
Expand All @@ -711,22 +716,13 @@ pub fn install_builtin_modules() {
pyre_install_module!(unicodedata);
pyre_install_module!(pyexpat);

// Empty C-extension stubs — `_opcode_metadata.py` etc. exist in the
// real stdlib and are loaded from disk, but their builtin shims here
// simply succeed at `import X`.
//
// Modules whose stdlib wrapper does `import X` + attribute access or
// `from X import *` are deliberately NOT stubbed here: an empty stub
// makes the `import` succeed and the later access raise AttributeError
// (or silently bind nothing), which the wrapper's `try/except
// ImportError` cannot recover from. Leaving them unregistered lets the
// pure-Python fallback take over: `_datetime` -> `_pydatetime`,
// `_decimal` -> `_pydecimal`, `_asyncio` -> pure-Python asyncio.
// `_stat` is the exception: frozen importlib imports it while bootstrapping
// a sandbox that deliberately mounts no stdlib files. `stat.py` already
// defines its portable constants before the optional accelerator import,
// so the empty builtin remains sufficient for both paths.
register_builtin_module("_stat", empty_module_init);
register_builtin_module_with_startup(
"array",
crate::module::array::init_array_module,
Expand Down Expand Up @@ -1370,9 +1366,6 @@ fn init_scproxy(ns: PyObjectRef) {
);
}

/// Empty module initializer for C-extension stubs.
fn empty_module_init(_ns: PyObjectRef) {}

/// Try to load a builtin module by name.
///
/// PyPy equivalent: `find_module()` → C_BUILTIN path →
Expand Down
22 changes: 13 additions & 9 deletions pyre/pyre-interpreter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1129,33 +1129,37 @@ pub fn all_subclass_range_aliases() -> Vec<pyre_object::pyobject::SubclassRangeA
subclass_range_alias(169, typed::<crate::module::zlib::W_Compress>()),
subclass_range_alias(170, typed::<crate::module::zlib::W_Decompress>()),
subclass_range_alias(171, typed::<crate::module::zlib::W_ZlibDecompressor>()),
// `posix.DirEntry` follows the unconditional zlib owners.
// `_bz2`'s two stream objects own their libbz2 state and per-object
// lock. Unconditional, so they stay ahead of the target-gated types.
subclass_range_alias(172, typed::<crate::module::_bz2::W_BZ2Compressor>()),
subclass_range_alias(173, typed::<crate::module::_bz2::W_BZ2Decompressor>()),
// `posix.DirEntry` follows the unconditional native owners.
#[cfg(not(target_arch = "wasm32"))]
subclass_range_alias(172, typed::<crate::module::posix::W_DirEntry>()),
subclass_range_alias(174, typed::<crate::module::posix::W_DirEntry>()),
// rustls-backed `_ssl` native payloads. They are appended after the
// last pre-existing native class in the same order `build_gc`
// registers them, so no established type id moves.
#[cfg(all(not(target_arch = "wasm32"), not(feature = "sandbox")))]
subclass_range_alias(173, typed::<crate::module::_ssl::W_SSLContext>()),
subclass_range_alias(175, typed::<crate::module::_ssl::W_SSLContext>()),
#[cfg(all(not(target_arch = "wasm32"), not(feature = "sandbox")))]
subclass_range_alias(174, typed::<crate::module::_ssl::W_MemoryBIO>()),
subclass_range_alias(176, typed::<crate::module::_ssl::W_MemoryBIO>()),
#[cfg(all(not(target_arch = "wasm32"), not(feature = "sandbox")))]
subclass_range_alias(175, typed::<crate::module::_ssl::W_SSLSession>()),
subclass_range_alias(177, typed::<crate::module::_ssl::W_SSLSession>()),
#[cfg(all(not(target_arch = "wasm32"), not(feature = "sandbox")))]
subclass_range_alias(176, typed::<crate::module::_ssl::W_SSLSocket>()),
subclass_range_alias(178, typed::<crate::module::_ssl::W_SSLSocket>()),
#[cfg(all(not(target_arch = "wasm32"), not(feature = "sandbox")))]
subclass_range_alias(177, typed::<crate::module::_ssl::W_Certificate>()),
subclass_range_alias(179, typed::<crate::module::_ssl::W_Certificate>()),
// `mmap.mmap` follows the optional SSL tail on ordinary Unix builds.
// A sandbox build has no `mmap` module at all (`module/mod.rs`), so it
// contributes no alias rather than sliding into the vacated SSL slot.
#[cfg(all(any(unix, windows), not(feature = "sandbox")))]
subclass_range_alias(178, typed::<crate::module::mmap::W_MMap>()),
subclass_range_alias(180, typed::<crate::module::mmap::W_MMap>()),
// Windows asyncio's Overlapped owner follows mmap at the native tail.
// It is a non-subclassable builtin in Python, but still participates
// in the rclass hierarchy because its managed header and retained
// buffer/result fields are traced by the ordinary object marker.
#[cfg(all(windows, feature = "host_env", not(feature = "sandbox")))]
subclass_range_alias(179, typed::<crate::module::_overlapped::W_Overlapped>()),
subclass_range_alias(181, typed::<crate::module::_overlapped::W_Overlapped>()),
]
}

Expand Down
Loading
Loading