mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Take &Py<T> in getset closures, try_value_with, slice and ssl helpers (#8787)
- `try_value_with` passes `&Py<T>` to its closure instead of `&T`, and its four callers follow. - structseq and pyexpat getset closures take `&Py<T>`. - `get_jit_args` takes `&Py<PyFunction>`. - `SaturatedSlice::with_slice` takes `&Py<PySlice>`; `to_saturated` moves from `impl PySlice` to `impl Py<PySlice>`. - The ssl compat helpers take `&Py<PySSLSocket>`; `do_handshake`, `read`, `write` and `shutdown` take `zelf: &Py<Self>` so they can pass it on. An inherent `impl Py<PySSLSocket>` is not possible in the stdlib crate. The csv `&PyDialect` sites keep the payload reference: the dialect is stored by value, so no `Py<PyDialect>` is available there. Assisted-by: Claude Opus 5 (1M context) Assisted-by: grok-4.7
This commit is contained in:
1 parent
01bd5ca370
commit
cb3d5dbb1a
12 files changed
+102
-98
No files matched your search
@@ -122,8 +122,8 @@ macro_rules! create_property {
|
||||
let attr = $ctx.new_static_getset(
|
||||
$name,
|
||||
$class,
|
||||
move |this: &PyExpatLikeXmlParser| this.$element.read().clone(),
|
||||
move |this: &PyExpatLikeXmlParser, func: PyObjectRef| *this.$element.write() = func,
|
||||
move |this: &Py<PyExpatLikeXmlParser>| this.$element.read().clone(),
|
||||
move |this: &Py<PyExpatLikeXmlParser>, func: PyObjectRef| *this.$element.write() = func,
|
||||
);
|
||||
|
||||
$attributes.insert($ctx.intern_str($name), attr.into());
|
||||
@@ -133,7 +133,7 @@ macro_rules! create_property {
|
||||
macro_rules! create_readonly_int_property {
|
||||
($ctx: expr, $attributes: expr, $name: expr, $class: expr, $element: ident) => {
|
||||
let getset = crate::vm::builtins::PyGetSet::new($name, $class).with_get(
|
||||
move |this: &PyExpatLikeXmlParser, vm: &VirtualMachine| -> PyObjectRef {
|
||||
move |this: &Py<PyExpatLikeXmlParser>, vm: &VirtualMachine| -> PyObjectRef {
|
||||
vm.ctx.new_int(*this.$element.read()).into()
|
||||
},
|
||||
);
|
||||
@@ -148,8 +148,8 @@ macro_rules! create_bool_property {
|
||||
let attr = $ctx.new_static_getset(
|
||||
$name,
|
||||
$class,
|
||||
move |this: &PyExpatLikeXmlParser| this.$element.read().clone(),
|
||||
move |this: &PyExpatLikeXmlParser,
|
||||
move |this: &Py<PyExpatLikeXmlParser>| this.$element.read().clone(),
|
||||
move |this: &Py<PyExpatLikeXmlParser>,
|
||||
value: PyObjectRef,
|
||||
vm: &VirtualMachine|
|
||||
-> PyResult<()> {
|
||||
|
||||
+67
-67
@@ -2953,37 +2953,37 @@ mod _ssl {
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn do_handshake(&self, vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn do_handshake(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
|
||||
// Check if handshake already done
|
||||
if self.handshake_completed() {
|
||||
if zelf.handshake_completed() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let accepted = self.accept_client_hello(vm)?;
|
||||
let mut conn_guard = self.connection.lock();
|
||||
let accepted = zelf.accept_client_hello(vm)?;
|
||||
let mut conn_guard = zelf.connection.lock();
|
||||
|
||||
// Initialize connection if not already done
|
||||
if conn_guard.is_none() {
|
||||
if self.server_side {
|
||||
if let Err(error) = self.initialize_server_connection(
|
||||
if zelf.server_side {
|
||||
if let Err(error) = zelf.initialize_server_connection(
|
||||
&mut conn_guard,
|
||||
accepted
|
||||
.ok_or_else(|| vm.new_value_error("TLS connection is not available"))?,
|
||||
vm,
|
||||
) {
|
||||
drop(conn_guard);
|
||||
if matches!(*self.state.lock(), TlsState::SendingAlert { .. }) {
|
||||
if matches!(*zelf.state.lock(), TlsState::SendingAlert { .. }) {
|
||||
return Err(error);
|
||||
}
|
||||
self.reject_connection(error, super::handshake::sni_alert(40), vm);
|
||||
return self.accept_client_hello(vm).map(|_| ());
|
||||
zelf.reject_connection(error, super::handshake::sni_alert(40), vm);
|
||||
return zelf.accept_client_hello(vm).map(|_| ());
|
||||
}
|
||||
} else {
|
||||
// Client-side connection
|
||||
let ctx = self.context.read();
|
||||
let ctx = zelf.context.read();
|
||||
|
||||
// Prepare common protocol settings (TLS versions, ECDH curve, cipher suites, ALPN)
|
||||
let protocol_settings = self.prepare_protocol_settings(vm)?;
|
||||
let protocol_settings = zelf.prepare_protocol_settings(vm)?;
|
||||
|
||||
// Clone values we need before building config
|
||||
let verify_mode = *ctx.verify_mode.read();
|
||||
@@ -3018,7 +3018,7 @@ mod _ssl {
|
||||
// Parse server name for SNI
|
||||
// Convert to ServerName
|
||||
use rustls::pki_types::ServerName;
|
||||
let hostname_opt = self.server_hostname.read().clone();
|
||||
let hostname_opt = zelf.server_hostname.read().clone();
|
||||
|
||||
let server_name = if let Some(ref hostname) = hostname_opt {
|
||||
// Use the provided hostname for SNI
|
||||
@@ -3033,7 +3033,7 @@ mod _ssl {
|
||||
)
|
||||
};
|
||||
|
||||
let explicit_session = self.session.read().clone();
|
||||
let explicit_session = zelf.session.read().clone();
|
||||
let session_store = Arc::new(CapturingClientSessionStore::new(session_cache));
|
||||
let (mut config, chain_builder) = if let Some(session) = explicit_session {
|
||||
let session = session
|
||||
@@ -3075,11 +3075,11 @@ mod _ssl {
|
||||
};
|
||||
create_client_config(config_options).map_err(|e| vm.new_value_error(e))?
|
||||
};
|
||||
Arc::make_mut(&mut config).key_log = self.key_log.clone();
|
||||
Arc::make_mut(&mut config).key_log = zelf.key_log.clone();
|
||||
|
||||
*self.chain_builder.write() = Some(chain_builder);
|
||||
*self.client_config.write() = Some(config.clone());
|
||||
*self.client_session_store.write() = Some(session_store);
|
||||
*zelf.chain_builder.write() = Some(chain_builder);
|
||||
*zelf.client_config.write() = Some(config.clone());
|
||||
*zelf.client_session_store.write() = Some(session_store);
|
||||
|
||||
let mut conn = ClientConnection::new(config, server_name).map_err(|e| {
|
||||
vm.new_value_error(format!("Failed to create client connection: {e}"))
|
||||
@@ -3092,30 +3092,30 @@ mod _ssl {
|
||||
drop(conn_guard);
|
||||
|
||||
// Perform the actual handshake by exchanging data with the socket/BIO
|
||||
let handshake_result = ssl_do_handshake(self, vm);
|
||||
let handshake_result = ssl_do_handshake(zelf, vm);
|
||||
if let Err(error @ (SslError::Rustls(_) | SslError::PreauthData)) = handshake_result {
|
||||
// rustls queued the fatal alert while processing the failing
|
||||
// record. Retain it and the original error across output retries.
|
||||
let bytes = self
|
||||
let bytes = zelf
|
||||
.connection
|
||||
.lock()
|
||||
.as_mut()
|
||||
.and_then(|conn| conn.drain_tls().ok())
|
||||
.unwrap_or_default();
|
||||
self.reject_connection(error.into_py_err(vm), bytes, vm);
|
||||
return self.accept_client_hello(vm).map(|_| ());
|
||||
zelf.reject_connection(error.into_py_err(vm), bytes, vm);
|
||||
return zelf.accept_client_hello(vm).map(|_| ());
|
||||
}
|
||||
handshake_result.map_err(|e| e.into_py_err(vm))?;
|
||||
if let Some(exc) = self.take_msg_exc() {
|
||||
if let Some(exc) = zelf.take_msg_exc() {
|
||||
return Err(exc);
|
||||
}
|
||||
self.complete_handshake(vm);
|
||||
zelf.complete_handshake(vm);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn read(
|
||||
&self,
|
||||
zelf: &Py<Self>,
|
||||
len: OptionalArg<isize>,
|
||||
buffer: OptionalArg<ArgMemoryBuffer>,
|
||||
vm: &VirtualMachine,
|
||||
@@ -3155,13 +3155,13 @@ mod _ssl {
|
||||
|
||||
// Ensure handshake is done - if not, complete it first
|
||||
// This matches OpenSSL behavior where SSL_read() auto-completes handshake
|
||||
if !self.handshake_completed() {
|
||||
self.do_handshake(vm)?;
|
||||
if !zelf.handshake_completed() {
|
||||
Self::do_handshake(zelf, vm)?;
|
||||
}
|
||||
|
||||
// Check if connection has been shut down
|
||||
// Only block after shutdown is COMPLETED, not during shutdown process
|
||||
if matches!(*self.state.lock(), TlsState::ShutDown) {
|
||||
if matches!(*zelf.state.lock(), TlsState::ShutDown) {
|
||||
return Err(vm
|
||||
.new_os_subtype_error(
|
||||
PySSLError::class(&vm.ctx).to_owned(),
|
||||
@@ -3198,13 +3198,13 @@ mod _ssl {
|
||||
// Use compat layer for unified read logic with proper EOF handling
|
||||
// This matches SSL_read_ex() approach
|
||||
let mut buf = vm.new_zeroed_bytes(len)?;
|
||||
let read_result = crate::ssl::compat::ssl_read(self, &mut buf, vm);
|
||||
let read_result = crate::ssl::compat::ssl_read(zelf, &mut buf, vm);
|
||||
match read_result {
|
||||
Ok(n) => {
|
||||
// Check for deferred certificate verification errors (TLS 1.3)
|
||||
// Must be checked AFTER ssl_read, as the error is set during I/O
|
||||
self.check_deferred_cert_error(vm)?;
|
||||
if let Some(exc) = self.take_msg_exc() {
|
||||
zelf.check_deferred_cert_error(vm)?;
|
||||
if let Some(exc) = zelf.take_msg_exc() {
|
||||
return Err(exc);
|
||||
}
|
||||
buf.truncate(n);
|
||||
@@ -3213,7 +3213,7 @@ mod _ssl {
|
||||
Err(error) if error.is_eof() => {
|
||||
// If plaintext is still buffered, return it before EOF.
|
||||
let pending = {
|
||||
let mut conn_guard = self.connection.lock();
|
||||
let mut conn_guard = zelf.connection.lock();
|
||||
let conn = match conn_guard.as_mut() {
|
||||
Some(conn) => conn,
|
||||
None => return Err(create_ssl_eof_error(vm).upcast()),
|
||||
@@ -3222,7 +3222,7 @@ mod _ssl {
|
||||
};
|
||||
if pending > 0 {
|
||||
let mut buf = vec![0u8; pending.min(len)];
|
||||
let read_retry = crate::ssl::compat::ssl_read(self, &mut buf, vm);
|
||||
let read_retry = crate::ssl::compat::ssl_read(zelf, &mut buf, vm);
|
||||
if let Ok(n) = read_retry {
|
||||
buf.truncate(n);
|
||||
return return_data(buf, &buffer, vm);
|
||||
@@ -3234,7 +3234,7 @@ mod _ssl {
|
||||
Err(error) if error.is_zero_return() => {
|
||||
// If plaintext is still buffered, return it before clean EOF.
|
||||
let pending = {
|
||||
let mut conn_guard = self.connection.lock();
|
||||
let mut conn_guard = zelf.connection.lock();
|
||||
let conn = match conn_guard.as_mut() {
|
||||
Some(conn) => conn,
|
||||
None => return Err(create_ssl_zero_return_error(vm).upcast()),
|
||||
@@ -3243,7 +3243,7 @@ mod _ssl {
|
||||
};
|
||||
if pending > 0 {
|
||||
let mut buf = vec![0u8; pending.min(len)];
|
||||
let read_retry = crate::ssl::compat::ssl_read(self, &mut buf, vm);
|
||||
let read_retry = crate::ssl::compat::ssl_read(zelf, &mut buf, vm);
|
||||
if let Ok(n) = read_retry {
|
||||
buf.truncate(n);
|
||||
return return_data(buf, &buffer, vm);
|
||||
@@ -3255,7 +3255,7 @@ mod _ssl {
|
||||
// Otherwise return empty bytes, which callers (asyncore,
|
||||
// asyncio sslproto) interpret as EOF.
|
||||
if matches!(
|
||||
*self.state.lock(),
|
||||
*zelf.state.lock(),
|
||||
TlsState::ShuttingDown | TlsState::ShutDown
|
||||
) {
|
||||
Err(create_ssl_zero_return_error(vm).upcast())
|
||||
@@ -3298,7 +3298,7 @@ mod _ssl {
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn write(&self, data: ArgBytesLike, vm: &VirtualMachine) -> PyResult<usize> {
|
||||
fn write(zelf: &Py<Self>, data: ArgBytesLike, vm: &VirtualMachine) -> PyResult<usize> {
|
||||
let data_bytes = data.borrow_buf();
|
||||
let data_len = data_bytes.len();
|
||||
|
||||
@@ -3307,13 +3307,13 @@ mod _ssl {
|
||||
}
|
||||
|
||||
// Ensure handshake is done (SSL_write auto-completes handshake)
|
||||
if !self.handshake_completed() {
|
||||
self.do_handshake(vm)?;
|
||||
if !zelf.handshake_completed() {
|
||||
Self::do_handshake(zelf, vm)?;
|
||||
}
|
||||
|
||||
// Application data cannot follow our close_notify.
|
||||
if matches!(
|
||||
*self.state.lock(),
|
||||
*zelf.state.lock(),
|
||||
TlsState::ShuttingDown | TlsState::ShutDown
|
||||
) {
|
||||
return Err(vm
|
||||
@@ -3326,12 +3326,12 @@ mod _ssl {
|
||||
}
|
||||
|
||||
// Call ssl_write (matches CPython's SSL_write_ex loop)
|
||||
let result = crate::ssl::compat::ssl_write(self, data_bytes.as_ref(), vm);
|
||||
let result = crate::ssl::compat::ssl_write(zelf, data_bytes.as_ref(), vm);
|
||||
|
||||
match result {
|
||||
Ok(n) => {
|
||||
self.check_deferred_cert_error(vm)?;
|
||||
if let Some(exc) = self.take_msg_exc() {
|
||||
zelf.check_deferred_cert_error(vm)?;
|
||||
if let Some(exc) = zelf.take_msg_exc() {
|
||||
return Err(exc);
|
||||
}
|
||||
Ok(n)
|
||||
@@ -3609,17 +3609,17 @@ mod _ssl {
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn shutdown(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
|
||||
fn shutdown(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
|
||||
// A failed shutdown may still owe the peer a fatal alert. Resume
|
||||
// that output on unwrap retries before reporting the saved error.
|
||||
if matches!(*self.state.lock(), TlsState::SendingAlert { .. })
|
||||
&& !self.pending_tls_output.lock().is_empty()
|
||||
if matches!(*zelf.state.lock(), TlsState::SendingAlert { .. })
|
||||
&& !zelf.pending_tls_output.lock().is_empty()
|
||||
{
|
||||
return self
|
||||
return zelf
|
||||
.accept_client_hello(vm)
|
||||
.map(|_| self.io.socket_object(vm));
|
||||
.map(|_| zelf.io.socket_object(vm));
|
||||
}
|
||||
if !self.handshake_completed() {
|
||||
if !zelf.handshake_completed() {
|
||||
return Err(SslError::create_ssl_error_with_reason(
|
||||
vm,
|
||||
Some("SSL"),
|
||||
@@ -3627,43 +3627,43 @@ mod _ssl {
|
||||
"[SSL: SHUTDOWN_WHILE_IN_INIT] shutdown while in init",
|
||||
));
|
||||
}
|
||||
if matches!(*self.state.lock(), TlsState::ShutDown) {
|
||||
return Ok(self.io.socket_object(vm));
|
||||
if matches!(*zelf.state.lock(), TlsState::ShutDown) {
|
||||
return Ok(zelf.io.socket_object(vm));
|
||||
}
|
||||
|
||||
let timeout = self.get_socket_timeout(vm)?;
|
||||
let timeout = zelf.get_socket_timeout(vm)?;
|
||||
let deadline = timeout
|
||||
.filter(|timeout| !timeout.is_zero())
|
||||
.map(|timeout| std::time::Instant::now() + timeout);
|
||||
{
|
||||
let mut conn_guard = self.connection.lock();
|
||||
let mut conn_guard = zelf.connection.lock();
|
||||
let conn = conn_guard
|
||||
.as_mut()
|
||||
.ok_or_else(|| vm.new_value_error("Connection not established"))?;
|
||||
|
||||
if matches!(*self.state.lock(), TlsState::Connected) {
|
||||
if matches!(*zelf.state.lock(), TlsState::Connected) {
|
||||
// rustls queues close_notify after previously buffered data.
|
||||
// Record this before any fallible write so retries never queue
|
||||
// another alert, even if the transport cannot accept output.
|
||||
conn.send_close_notify();
|
||||
*self.state.lock() = TlsState::ShuttingDown;
|
||||
*zelf.state.lock() = TlsState::ShuttingDown;
|
||||
}
|
||||
}
|
||||
|
||||
let result = (|| loop {
|
||||
let bytes = {
|
||||
let mut conn_guard = self.connection.lock();
|
||||
let mut conn_guard = zelf.connection.lock();
|
||||
let conn = conn_guard
|
||||
.as_mut()
|
||||
.ok_or_else(|| vm.new_value_error("Connection not established"))?;
|
||||
conn.drain_tls()
|
||||
.map_err(|e| SslError::from(e).into_py_err(vm))?
|
||||
};
|
||||
super::compat::send_all_bytes(self, bytes, vm, deadline)
|
||||
super::compat::send_all_bytes(zelf, bytes, vm, deadline)
|
||||
.map_err(|e| e.into_py_err(vm))?;
|
||||
|
||||
let io_state = {
|
||||
let mut conn_guard = self.connection.lock();
|
||||
let mut conn_guard = zelf.connection.lock();
|
||||
let conn = conn_guard
|
||||
.as_mut()
|
||||
.ok_or_else(|| vm.new_value_error("Connection not established"))?;
|
||||
@@ -3679,8 +3679,8 @@ mod _ssl {
|
||||
));
|
||||
}
|
||||
if io_state.peer_has_closed() {
|
||||
*self.state.lock() = TlsState::ShutDown;
|
||||
return Ok(self.io.socket_object(vm));
|
||||
*zelf.state.lock() = TlsState::ShutDown;
|
||||
return Ok(zelf.io.socket_object(vm));
|
||||
}
|
||||
|
||||
let remaining = match deadline {
|
||||
@@ -3694,20 +3694,20 @@ mod _ssl {
|
||||
),
|
||||
None => timeout,
|
||||
};
|
||||
if self.sock_wait_for_io_with_timeout(SockWaitKind::Read, remaining, vm)? {
|
||||
if zelf.sock_wait_for_io_with_timeout(SockWaitKind::Read, remaining, vm)? {
|
||||
return Err(
|
||||
timeout_error_msg(vm, "The read operation timed out".to_owned()).upcast(),
|
||||
);
|
||||
}
|
||||
// Stop at each TLS record boundary, leaving an unencrypted
|
||||
// trailer after close_notify in the socket or incoming BIO.
|
||||
let data = super::compat::recv_at_most_one_tls_record(self, vm)
|
||||
let data = super::compat::recv_at_most_one_tls_record(zelf, vm)
|
||||
.map_err(|e| e.into_py_err(vm))?;
|
||||
let mut conn_guard = self.connection.lock();
|
||||
let mut conn_guard = zelf.connection.lock();
|
||||
let conn = conn_guard
|
||||
.as_mut()
|
||||
.ok_or_else(|| vm.new_value_error("Connection not established"))?;
|
||||
super::compat::ssl_read_tls_records(conn, data, self.is_bio_mode(), vm)
|
||||
super::compat::ssl_read_tls_records(conn, data, zelf.is_bio_mode(), vm)
|
||||
.map_err(|e| e.into_py_err(vm))?;
|
||||
})();
|
||||
if let Err(error) = &result
|
||||
@@ -3717,16 +3717,16 @@ mod _ssl {
|
||||
{
|
||||
// A protocol failure cannot resume as a normal shutdown. Keep
|
||||
// any fatal alert rustls queued and preserve the original error.
|
||||
let bytes = self
|
||||
let bytes = zelf
|
||||
.connection
|
||||
.lock()
|
||||
.as_mut()
|
||||
.and_then(|conn| conn.drain_tls().ok())
|
||||
.unwrap_or_default();
|
||||
self.reject_connection(error.clone(), bytes, vm);
|
||||
return self
|
||||
zelf.reject_connection(error.clone(), bytes, vm);
|
||||
return zelf
|
||||
.accept_client_hello(vm)
|
||||
.map(|_| self.io.socket_object(vm));
|
||||
.map(|_| zelf.io.socket_object(vm));
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
@@ -329,7 +329,7 @@ pub(super) fn is_blocking_io_error(err: &Py<PyBaseException>, vm: &VirtualMachin
|
||||
/// inside `f`; rustls is sans-I/O and another thread may need this lock to
|
||||
/// encrypt or decrypt while we wait on the transport.
|
||||
fn with_conn_mut<R>(
|
||||
socket: &PySSLSocket,
|
||||
socket: &Py<PySSLSocket>,
|
||||
vm: &VirtualMachine,
|
||||
f: impl FnOnce(&mut TlsConnection) -> SslResult<R>,
|
||||
) -> SslResult<R> {
|
||||
@@ -347,7 +347,7 @@ fn with_conn_mut<R>(
|
||||
/// if no progress can be made.
|
||||
/// Optional deadline parameter allows respecting a read deadline during flush.
|
||||
pub(super) fn send_all_bytes(
|
||||
socket: &PySSLSocket,
|
||||
socket: &Py<PySSLSocket>,
|
||||
buf: Vec<u8>,
|
||||
vm: &VirtualMachine,
|
||||
deadline: Option<std::time::Instant>,
|
||||
@@ -374,7 +374,7 @@ pub(super) fn send_all_bytes(
|
||||
///
|
||||
/// Drains all pending TLS data from rustls and sends it to the peer.
|
||||
/// Returns whether any progress was made.
|
||||
fn handshake_write_loop(socket: &PySSLSocket, vm: &VirtualMachine) -> SslResult<bool> {
|
||||
fn handshake_write_loop(socket: &Py<PySSLSocket>, vm: &VirtualMachine) -> SslResult<bool> {
|
||||
let mut made_progress = false;
|
||||
|
||||
// Flush any previously pending TLS data before generating new output
|
||||
@@ -416,7 +416,7 @@ fn handshake_write_loop(socket: &PySSLSocket, vm: &VirtualMachine) -> SslResult<
|
||||
/// and recv() only that many bytes. Any remaining data stays in the kernel
|
||||
/// buffer and remains visible to select().
|
||||
pub(super) fn recv_at_most_one_tls_record(
|
||||
socket: &PySSLSocket,
|
||||
socket: &Py<PySSLSocket>,
|
||||
vm: &VirtualMachine,
|
||||
) -> SslResult<PyObjectRef> {
|
||||
let bytes = socket.sock_recv_at_most_one_tls_record(vm).map_err(|e| {
|
||||
@@ -441,7 +441,7 @@ pub(super) fn recv_at_most_one_tls_record(
|
||||
/// Read up to a single TLS record for post-handshake I/O while preserving the
|
||||
/// SSL-vs-socket error precedence from the old sock_recv() path.
|
||||
fn recv_at_most_one_tls_record_for_data(
|
||||
socket: &PySSLSocket,
|
||||
socket: &Py<PySSLSocket>,
|
||||
vm: &VirtualMachine,
|
||||
) -> SslResult<PyObjectRef> {
|
||||
match recv_at_most_one_tls_record(socket, vm) {
|
||||
@@ -467,7 +467,7 @@ fn recv_at_most_one_tls_record_for_data(
|
||||
}
|
||||
}
|
||||
|
||||
fn handshake_read_data(socket: &PySSLSocket, vm: &VirtualMachine) -> SslResult<()> {
|
||||
fn handshake_read_data(socket: &Py<PySSLSocket>, vm: &VirtualMachine) -> SslResult<()> {
|
||||
if socket
|
||||
.sock_wait_for_io_impl(SockWaitKind::Read, vm)
|
||||
.map_err(SslError::Py)?
|
||||
@@ -496,7 +496,7 @@ fn try_read_plaintext(conn: &mut TlsConnection, buf: &mut [u8]) -> SslResult<Opt
|
||||
/// This abstracts away the low-level rustls read_tls/write_tls loop.
|
||||
///
|
||||
/// = SSL_do_handshake()
|
||||
pub(super) fn ssl_do_handshake(socket: &PySSLSocket, vm: &VirtualMachine) -> SslResult<()> {
|
||||
pub(super) fn ssl_do_handshake(socket: &Py<PySSLSocket>, vm: &VirtualMachine) -> SslResult<()> {
|
||||
loop {
|
||||
// Both transports drain writes first and feed complete/partial records
|
||||
// through the same path. An empty BIO naturally returns WantRead.
|
||||
@@ -534,7 +534,7 @@ pub(super) fn ssl_do_handshake(socket: &PySSLSocket, vm: &VirtualMachine) -> Ssl
|
||||
///
|
||||
/// = SSL_read_ex()
|
||||
pub(super) fn ssl_read(
|
||||
socket: &PySSLSocket,
|
||||
socket: &Py<PySSLSocket>,
|
||||
buf: &mut [u8],
|
||||
vm: &VirtualMachine,
|
||||
) -> SslResult<usize> {
|
||||
@@ -739,7 +739,7 @@ pub(super) fn ssl_read(
|
||||
///
|
||||
/// = SSL_write_ex()
|
||||
pub(super) fn ssl_write(
|
||||
socket: &PySSLSocket,
|
||||
socket: &Py<PySSLSocket>,
|
||||
data: &[u8],
|
||||
vm: &VirtualMachine,
|
||||
) -> SslResult<usize> {
|
||||
@@ -944,7 +944,7 @@ fn is_connection_closed_error(exc: &Py<PyBaseException>, vm: &VirtualMachine) ->
|
||||
|
||||
/// Ensure TLS data is available for reading
|
||||
/// Returns the number of bytes read from the socket
|
||||
fn ssl_ensure_data_available(socket: &PySSLSocket, vm: &VirtualMachine) -> SslResult<usize> {
|
||||
fn ssl_ensure_data_available(socket: &Py<PySSLSocket>, vm: &VirtualMachine) -> SslResult<usize> {
|
||||
// Unlike OpenSSL's SSL_read, rustls requires explicit I/O
|
||||
if with_conn_mut(socket, vm, |conn| Ok(conn.wants_read()))? {
|
||||
let is_bio = socket.is_bio_mode();
|
||||
|
||||
@@ -9,7 +9,7 @@ pub(crate) use unicodedata::module_def;
|
||||
use rustpython_unicode::{self as unicode_core, NormalizeForm};
|
||||
|
||||
use crate::vm::{
|
||||
PyObject, PyResult, VirtualMachine, builtins::PyStr, convert::TryFromBorrowedObject,
|
||||
Py, PyObject, PyResult, VirtualMachine, builtins::PyStr, convert::TryFromBorrowedObject,
|
||||
};
|
||||
|
||||
struct NormalizeFormArg(NormalizeForm);
|
||||
@@ -17,7 +17,7 @@ struct NormalizeFormArg(NormalizeForm);
|
||||
impl<'a> TryFromBorrowedObject<'a> for NormalizeFormArg {
|
||||
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
|
||||
obj.try_value_with(
|
||||
|form: &PyStr| match form.as_bytes() {
|
||||
|form: &Py<PyStr>| match form.as_bytes() {
|
||||
b"NFC" => Ok(Self(NormalizeForm::Nfc)),
|
||||
b"NFKC" => Ok(Self(NormalizeForm::Nfkc)),
|
||||
b"NFD" => Ok(Self(NormalizeForm::Nfd)),
|
||||
|
||||
@@ -158,7 +158,7 @@ fn get_jit_value(vm: &VirtualMachine, obj: &PyObject) -> Result<AbiValue, ArgsEr
|
||||
/// `fill_locals_from_args` which will raise the actual exception if needed.
|
||||
#[cfg(feature = "jit")]
|
||||
pub(crate) fn get_jit_args<'a>(
|
||||
func: &PyFunction,
|
||||
func: &Py<PyFunction>,
|
||||
func_args: &FuncArgs,
|
||||
jitted_code: &'a CompiledCode,
|
||||
vm: &VirtualMachine,
|
||||
|
||||
@@ -115,7 +115,7 @@ macro_rules! impl_try_from_object_int {
|
||||
($(($t:ty, $to_prim:ident),)*) => {$(
|
||||
impl<'a> TryFromBorrowedObject<'a> for $t {
|
||||
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
|
||||
obj.try_value_with(|int: &PyInt| {
|
||||
obj.try_value_with(|int: &Py<PyInt>| {
|
||||
int.try_to_primitive(vm)
|
||||
}, vm)
|
||||
}
|
||||
|
||||
@@ -120,10 +120,6 @@ impl PySlice {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_saturated(&self, vm: &VirtualMachine) -> PyResult<SaturatedSlice> {
|
||||
SaturatedSlice::with_slice(self, vm)
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
fn slot_new(cls: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||
let slice: Self = match args.args.len() {
|
||||
@@ -269,6 +265,12 @@ impl PySlice {
|
||||
}
|
||||
}
|
||||
|
||||
impl Py<PySlice> {
|
||||
pub fn to_saturated(&self, vm: &VirtualMachine) -> PyResult<SaturatedSlice> {
|
||||
SaturatedSlice::with_slice(self, vm)
|
||||
}
|
||||
}
|
||||
|
||||
impl Hashable for PySlice {
|
||||
#[inline]
|
||||
fn hash(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyHash> {
|
||||
|
||||
@@ -52,7 +52,7 @@ use rustpython_unicode::{self as unicode, case};
|
||||
|
||||
impl<'a> TryFromBorrowedObject<'a> for String {
|
||||
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
|
||||
obj.try_value_with(|pystr: &PyUtf8Str| Ok(pystr.as_str().to_owned()), vm)
|
||||
obj.try_value_with(|pystr: &Py<PyUtf8Str>| Ok(pystr.as_str().to_owned()), vm)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ impl PyObject {
|
||||
pub fn try_value_with<T, F, R>(&self, f: F, vm: &VirtualMachine) -> PyResult<R>
|
||||
where
|
||||
T: PyPayload,
|
||||
F: Fn(&T) -> PyResult<R>,
|
||||
F: Fn(&Py<T>) -> PyResult<R>,
|
||||
{
|
||||
let class = T::class(&vm.ctx);
|
||||
let py_ref = if self.fast_isinstance(class) {
|
||||
|
||||
@@ -31,7 +31,9 @@ pub use number::{ArgIndex, ArgIntoBool, ArgIntoComplex, ArgIntoFloat, ArgPrimiti
|
||||
pub use protocol::{ArgCallable, ArgIterable, ArgMapping, ArgSequence};
|
||||
pub use time::TimeoutSeconds;
|
||||
|
||||
use crate::{PyObject, PyResult, VirtualMachine, builtins::PyStr, convert::TryFromBorrowedObject};
|
||||
use crate::{
|
||||
Py, PyObject, PyResult, VirtualMachine, builtins::PyStr, convert::TryFromBorrowedObject,
|
||||
};
|
||||
use builtin::{BorrowedParam, OwnedParam, RefParam};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
@@ -43,7 +45,7 @@ pub enum ArgByteOrder {
|
||||
impl<'a> TryFromBorrowedObject<'a> for ArgByteOrder {
|
||||
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &'a PyObject) -> PyResult<Self> {
|
||||
obj.try_value_with(
|
||||
|s: &PyStr| match s.as_bytes() {
|
||||
|s: &Py<PyStr>| match s.as_bytes() {
|
||||
b"big" => Ok(Self::Big),
|
||||
b"little" => Ok(Self::Little),
|
||||
_ => Err(vm.new_value_error("byteorder must be either 'little' or 'big'")),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// export through sliceable module, not slice.
|
||||
use crate::{
|
||||
PyObject, PyResult, VirtualMachine,
|
||||
Py, PyObject, PyResult, VirtualMachine,
|
||||
builtins::{int::PyInt, slice::PySlice},
|
||||
};
|
||||
use core::ops::Range;
|
||||
@@ -387,7 +387,7 @@ impl SaturatedSlice {
|
||||
}
|
||||
|
||||
// Equivalent to PySlice_Unpack.
|
||||
pub fn with_slice(slice: &PySlice, vm: &VirtualMachine) -> PyResult<Self> {
|
||||
pub fn with_slice(slice: &Py<PySlice>, vm: &VirtualMachine) -> PyResult<Self> {
|
||||
let step = to_isize_index(vm, slice.step_ref(vm))?.unwrap_or(1);
|
||||
if step == 0 {
|
||||
return Err(vm.new_value_error("slice step cannot be zero"));
|
||||
|
||||
@@ -373,7 +373,7 @@ pub trait PyStructSequence: StaticType + PyClassImpl + Sized + 'static {
|
||||
let i = i as u8;
|
||||
class.set_attr(
|
||||
ctx.intern_str(name),
|
||||
ctx.new_readonly_getset(name, class, move |zelf: &PyTuple| {
|
||||
ctx.new_readonly_getset(name, class, move |zelf: &Py<PyTuple>| {
|
||||
zelf[i as usize].to_owned()
|
||||
})
|
||||
.into(),
|
||||
@@ -386,7 +386,7 @@ pub trait PyStructSequence: StaticType + PyClassImpl + Sized + 'static {
|
||||
let idx = (visible_count + i) as u8;
|
||||
class.set_attr(
|
||||
ctx.intern_str(name),
|
||||
ctx.new_readonly_getset(name, class, move |zelf: &PyTuple| {
|
||||
ctx.new_readonly_getset(name, class, move |zelf: &Py<PyTuple>| {
|
||||
zelf[idx as usize].to_owned()
|
||||
})
|
||||
.into(),
|
||||
|
||||
Reference in new issue
Block a user