The function is used in 'feature = ssl'. However, the current codebase
defines it without a conditional compilation expression and always be
compiled.
This commit removes the unused warning by adding a conditional
compilation expression, '#[cfg(feature = "ssl")]'.
* Store StopIteration.value in a struct field like SystemExit
* Unmark test_pydoc's test_member_descriptor
* Use expect instead of unwrap in new_stop_iteration
Dual-Root Mismatch in RustPython:
Unlike CPython, RustPython manages the standard library
in two separate locations in the workspace:
- Workspace 'Lib/': Contains the test suite ('Lib/test/...') and
standard library files.
- crates/pylib/Lib/: A helper directory used for packaging.
'crates/pylib/Lib' is a symlink pointing to the real workspace '../../Lib/'.
Runtime Directory Discrepancy:
- 'sys.path' contains 'crates/pylib/Lib' (the path to the symlink).
- Thus, when 'test.support' is imported, its '__file__' is resolved relative
to the symlink: '/opt/RustPython/crates/pylib/Lib/test/support/__init__.py'.
- Consequently, 'STDLIB_DIR' resolves to the symlink root:
'/opt/RustPython/crates/pylib/Lib'.
- However, since 'test_program.py' is executed directly from the workspace,
its 'pkg_dir' is: '/opt/RustPython/Lib/test/test_unittest/testmock'.
- When 'os.path.relpath(pkg_dir, top_dir)' is called:
---
os.path.relpath(
"/opt/RustPython/Lib/test/test_unittest/testmock",
"/opt/RustPython/crates/pylib/Lib"
)
# Result: "../../../Lib/test/test_unittest/testmock"
---
Because the relative path starts with '..', the assertion fails.
Assisted-by: Gemini
* weakref: reuse callback-less proxy objects like CPython
Make PyWeakProxy a #[repr(transparent)] view sharing PyWeak's payload
(manual PyPayload with shared PAYLOAD_TYPE_ID + class check), so a proxy
is the weakref-list node itself and add()'s reuse applies to it
directly. Port CPython's insert_weakref/get_basic_refs slot discipline:
genericref at head, generic proxy right after it, with callback/class
re-verificationbefore reuse. Constructor moves to a slot_new override
since reuse returns an existing object. Drops the hidden __weakproxy
marker subclass and the proxy branch in PyWeakref_GetRef.
Assisted-by: Claude Code:claude-opus-4-8
* weakref: always validate class in basic-proxy slot lookup
* weakref: rustfmt find_generic_proxy_ptr
* weakref: unify reuse check shape
stdlib/_symtable.rs previously provided the public Symbol API. When
7f1fc3602 imported Lib/symtable.py, responsibility for the public Symbol
implementation moved to Python, but the native implementation remained.
Remove it along with the unused identifiers getter.
Assisted-by: Codex:gpt-5.6-sol
When `ordered_attributes` is set, report attributes to the
StartElementHandler as a flat `[name, value, ...]` list matching
CPython's my_StartElementHandler, instead of always passing a dict.
`xml.etree.ElementTree` and `xml.dom.minidom` (via expatbuilder) both
enable this flag and rely on the flat-list contract, so parsing any
element with attributes previously failed: the dict made `_start` do
integer indexing, raising KeyError which was silently swallowed by the
handler invoker, leaving the tree empty ("missing toplevel element").
Reference (CPython 3.14):
https://github.com/python/cpython/blob/3.14/Modules/pyexpat.c#L439-L443
Remove `@unittest.expectedFailure` from tests that now pass
(23 in test_xml_etree, 15 in test_minidom, 1 in test_regrtest).
Assisted-by: Claude:claude-opus-4-8
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* vm: replace fetch_update() with try_update()
fetch_update() in atomic namespace is in the deprecation stage.
* host_env: replace libc::RLIM_NLIMITS with const RLIM_NLIMITS
Define a new const, RLIM_NLIMITS instead of libc::RLIM_NLIMITS in order
to clean up the deprecated const and to prevent breaking API where the const
is still used.
* Validate TextIOWrapper chunk size
Match CPython for non-positive, oversized, and index-compatible values.
Assisted-by: Codex:GPT-5
* Use explicit AssertionError in io snippet
Assisted-by: Codex:GPT-5
* Report original type in chunk size overflow
Assisted-by: Codex:GPT-5
* Chain io snippet assertion error
Assisted-by: Codex:GPT-5
* Match CPython chunk size setter behavior
Assisted-by: Codex:GPT-5
* Format io snippet assertion
Assisted-by: Codex:GPT-5.6
* Match CPython type name truncation
Assisted-by: Codex:GPT-5
* Format non-ASCII chunk size test
Assisted-by: Codex:GPT-5
Casting a u32 to a u16 would truncate the value. It's safer to use
Wtf::encode_wide which already handles converting a CodePoint to a u16.
I removed vec_into_bytes because it was only used in two places. The
function was unsound for T but sound in the way RustPython used it (POD
to POD, less strict alignment).
AI disclosure: I linted this code with AI. I found this issue by
accident while working on another patch in which I introduced a similar
mistake. AI caught that mistake, so I linted the original code to
cross-check it. I wrote the code myself in both instances.
Assisted-by: Codex:gpt-5.4
Apply the maintainer review suggestion from RustPython/RustPython#8270. Codex inspected the review context, made the one-line whitespace-only edit, and ran validation.
Assisted-by: Codex:gpt-5
* csv: map QUOTE_MINIMAL to Necessary quote style
QuoteStyle::Minimal was mapped to csv_core's Always, which quoted every
field even under QUOTE_MINIMAL. Map it to Necessary so only fields that
require quoting are quoted.
Unmarks Test_Csv.test_write_quoting.
Assisted-by: Claude Code:claude-opus-4-8
* csv: apply dialect quoting and lineterminator in writer
csv.writer ignored the quoting and lineterminator from a dialect (whether
passed by name or object), always using the defaults. Resolve both from the
dialect via get_quoting()/get_lineterminator(), mirroring get_delimiter(), so
an explicit keyword argument still overrides the dialect.
Unmarks TestDialectUnix.test_simple_writer.
Assisted-by: Claude Code:claude-opus-4-8
* _queue: check for pending signals during blocking get()
Semaphore::acquire() waited on the condvar in a single uninterrupted call,
so a Python-level signal handler never ran until the wait itself returned.
check_signals() is only invoked from the bytecode dispatch loop, and this
native wait never passed through it -- CPython chunks its equivalent
blocking wait for the same reason.
Cap each wait at a short interval and call check_signals() between chunks,
only giving up once the caller's real deadline has actually elapsed. The
mutex guard must be dropped before check_signals() runs: a signal handler
that calls back into the same queue on the same thread would otherwise try
to relock a mutex it's still holding and deadlock against itself.
Add a regression snippet that arms a SIGALRM well before a helper thread
unblocks the queue, and asserts the handler ran near the alarm instead of
only once get() returned.
Refs #8250
Assisted-by: Claude
* _queue: correct SIGNAL_CHECK_INTERVAL doc comment
The old comment claimed this mirrors CPython's PyThread_acquire_lock_timed,
but CPython doesn't chunk its wait either -- it makes one sem_timedwait call
and relies on the OS reporting EINTR. parking_lot's Condvar has no equivalent
signal to surface, so polling is a workaround for that gap, not a mirror of
CPython's approach.
Assisted-by: Claude
* Apply suggestions from code review
Co-authored-by: Jeong, YunWon <69878+youknowone@users.noreply.github.com>
* _queue: fix comment indentation (cargo fmt)
Assisted-by: Claude
---------
Co-authored-by: Jeong, YunWon <69878+youknowone@users.noreply.github.com>
* Make SystemExit.code a writable attribute set at init
* Read exit status from SystemExit.code in handle_exit_exception
* Store SystemExit.code in a struct field instead of the instance dict
* Create SystemExit through the full constructor path
* module: honor module-level __dir__ (PEP 562)
dir(module) ignored a module-level __dir__ function and returned the raw
__dict__ keys. Look up __dir__ in the module dict and, when present, call
it and return its result — matching CPython's module___dir___impl. The
existing expectedFailure markers on test_module_dir/test_module_dir_errors
are removed since both now pass.
Fixes#8231
Assisted-by: Claude Code:claude-opus-4-8
* test: unmark zoneinfo test_dir_contains_all (PEP 562 __dir__)
Honoring a module-level __dir__ makes dir(zoneinfo) contain everything
in __all__, so test_dir_contains_all now passes. Remove its stale
expectedFailure marker to avoid an unexpected-success CI failure.
Assisted-by: Claude Code:claude-opus-4-8
* test: unmark test_support.test_check__all__ (PEP 562 __dir__)
check__all__ iterates dir(module); honoring a module-level __dir__ fixes
dir(unittest), so test_check__all__ now passes. Remove its stale
expectedFailure marker to avoid an unexpected-success CI failure.
Assisted-by: Claude Code:claude-opus-4-8
* Support array 'w' (Py_UCS4) typecode
Python 3.13 added the 'w' typecode holding fixed 4-byte unicode code
points, unlike 'u' which is platform-dependent wchar_t. Add a Ucs4Char
element type and route it through the existing unicode-array paths:
constructor from str, fromunicode()/tounicode(), __reduce_ex__, repr,
byteswap, and the machine-format code (Utf32). Also register 'w' as a
struct format char in vm::buffer.
Remove the now-passing expectedFailure markers for 'w' tests in
test_array.py.
Assisted-by: Claude
* Reject non-native byte order for the 'w' format char
FormatType::parse accepted 'w' after '<', '>', '!', or '=', but the
non-native branch of FormatType::info has no Ucs4Char arm and hits
unreachable!(), so struct.calcsize('>w') panicked the interpreter.
Add Ucs4Char to the existing native-only filter in FormatCode::parse
(alongside SSizeT/SizeT/VoidP) so those formats fail with the regular
"bad char in struct format" error instead. Native 'w' and
memoryview(array('w', ...)) are unaffected.
Assisted-by: Claude
* Unmark 'w'-typecode tests in test_re and test_csv
test_re's test_empty_array and test_csv's test_char_write construct
array('w', ...) and were marked expectedFailure while the typecode was
unsupported. Now that 'w' works they pass, and regrtest counts the
unexpected successes as failures in CI. Remove the two markers, which
restores both tests to their CPython v3.14.6 form; test_re, test_csv,
and test_array all pass.
Assisted-by: Claude
* Restore pyexpat lexical callback compatibility
Forward processing instructions, comments, and CDATA boundaries already emitted by xml-rs so registered Python handlers observe CPython-compatible events.
Constraint: Reuse existing xml-rs events without changing the dependency
Confidence: high
Scope-risk: narrow
Tested: prek; test_pyexpat; test_sax; 402 extra tests; workspace tests; clippy
Assisted-by: Codex:gpt-5.6-sol
* Recognize XML compatibility restored by lexical events
Remove stale expected-failure markers for CPython XML tests now satisfied by pyexpat lexical-event forwarding, and simplify parser event error propagation.
Constraint: CPython test edits are limited to removing stale expectedFailure markers
Confidence: high
Scope-risk: narrow
Directive: Keep parser event dispatch aligned with pyexpat handler behavior
Tested: user-verified full suite; prek run --all-files; cargo run --release -- -m test test_pyexpat test_xml_etree test_xml_etree_c test_minidom test_sax
Assisted-by: Codex:gpt-5.6-sol
getpath: on Windows, default_prefix falls back to the executable
directory instead of a bare "C:" when landmark search fails.
host_env: errno_io_error carries the raw CRT errno as an io::Error
payload (CrtErrno) instead of translating it to a Win32 error code and
back. The round-trip collapsed every errno outside the errno_to_winerror
table to EINVAL and attached a spurious winerror to the OSError.
posix_errno recovers the exact errno from the payload; ftruncate reuses
the same path. fstat now reports ERROR_INVALID_HANDLE for an invalid fd.
* csv: apply dialect escapechar when reading
ReaderBuilder only received escapechar when it was passed directly as a
keyword argument. A dialect object's or registered dialect's escapechar was
visible through reader.dialect but not used by csv_core.
Pass escapechar through for named, object, and default dialect paths. This
makes escaped delimiters inside quoted fields follow the configured dialect,
for example '"abc\,def"' reads as 'abc,def'.
Unmark TestQuotedEscapedExcel.test_read_escape_fieldsep.
Assisted-by: Codex
* csv: handle escaped delimiters with QUOTE_NONE
csv_core applies escapechar while reading quoted fields, but its unquoted
field state treats an escaped delimiter as a delimiter. Consequently,
QUOTE_NONE with escapechar split 'abc\,def' into 'abc\' and 'def'.
Add a small QUOTE_NONE record parser for dialects with escapechar. It keeps
the byte following an escape character as field data, so escaped delimiters
do not end a field while ordinary delimiters and record terminators retain
their usual meaning.
Unmark TestEscapedExcel.test_read_escape_fieldsep.
Assisted-by: Codex
* csv: respect skipinitialspace with QUOTE_NONE
The QUOTE_NONE parser returned before the normal reader's whitespace
preprocessing, so it ignored skipinitialspace when escapechar was set.
Track whether parsing has just followed a delimiter and skip only ordinary
spaces in that position. Escaped spaces remain field data.
Add a stdlib_csv snippet regression test for QUOTE_NONE with escapechar and
skipinitialspace.
Assisted-by: Codex:gpt-5.6-terra
* csv: deduplicate reader dialect configuration
to_reader configured ReaderBuilder separately for named, object, and default
dialects even though the configuration was identical.
Resolve the PyDialect once, then apply delimiter, double_quote, escapechar,
and quotechar in one place. Preserve the existing unregistered-name fallback
and required excel dialect lookup behavior.
Assisted-by: Codex:gpt-5.6-terra
Match.expand delegated to re._expand, which CPython removed in 3.12
during the template-expansion refactor. With the 3.14 stdlib that
helper no longer exists, so expand raised AttributeError.
Route expand through the compiled-template path
(Template::compile -> re._compile_template) and share the
template-filling logic with Pattern.sub via a Match::expand_template
helper. Each caller still compiles the template once, so sub keeps
its no-recompile-per-match fast path.
Remove the expectedFailure marker on test_re.test_expand.
Assisted-by: Claude Code:claude-opus-4-8
* Fix clippy warning
* Fix clippy warnings surfaced by newer clippy
- exceptions.rs: {b:#02x} -> {b:#04x} (unused_format_specs); output
unchanged for decode-error bytes (always >= 0x80)
- binascii.rs: [b'\r', b'\n'] -> b"\r\n" (byte_str_slice)
- host_env, _io.rs, ssl.rs, pyexpat.rs: expect std_instead_of_core where
the suggested core::io items (ErrorKind, Cursor) are unstable (core_io);
use expect so the suppression is flagged for removal once core::io
stabilizes. build_posix_spawn_attrs co-gates the expect with the cfg
block so it is not left unfulfilled on platforms compiling it out.
Assisted-by: Claude
* Fix more
---------
Co-authored-by: Jeong YunWon <jeong@youknowone.org>
`rename` and `replace` are the same for Unixes but different for Windows
in Python. POSIX's `rename` atomically replaces its target; there is no
`replace` in POSIX. `renameat2` with `RENAME_NOREPLACE` atomically
checks if a file exists and renames if it doesn't, but Python's `rename`
and `replace` predate `renameat2`.
For Windows, `rename` acts like the `RENAME_NOREPLACE` flag while
`replace` functions like `rename`. I implemented both using the Windows
API. Both implementations follow CPython's code by using `MoveFileExW`.
There are modern Windows APIs that may be worth using in the future.
Rust's standard library prefers the modern APIs but falls back to
`MoveFileExW` for deprecated Windows versions.
to_string's normal-magnitude branch and complex::component_to_string
returned Rust's shortest formatting directly, which can pick the odd-digit
neighbour of a rounding tie where repr() picks the even one (e.g. bits
0x42e26687db6b9b04 formats as 161852602146008.13 vs repr's ...08.12).
Route both through prefer_cpython_tie_repr, generalized to fixed-notation
strings. Add unit tests and float/complex repr snippet tests.
Assisted-by: Claude
parse_str split the token then parsed each part with float::parse_str,
which tolerates surrounding whitespace, so "1 +2j" parsed as (1+2j).
Reject whitespace inside the token after stripping optional parentheses.
Add unit tests and complex() snippet tests.
Assisted-by: Claude