Reject payload receivers on #[pymethod] and #[pygetset] (#8898)

* Report errors from #[pyclass] trait items

The trait branch of impl_pyclass_impl built its own ImplContext, so the
errors collected while extracting trait items were never emitted: an
invalid #[pymethod] or #[pygetset] in a #[pyclass] trait was left out of
the class without a compile error. The trait branch now uses the shared
context whose errors are emitted.

Assisted-by: Claude Code:claude-opus-5-5

* Pass the object to #[pymethod] and #[pygetset] receivers outside vm

Outside crates/vm, where impl Py<T> cannot be written, #[pymethod] and
#[pygetset] receivers that took &self become zelf: &Py<Self> inside the
existing impl T blocks. Where Rust code calls one of these methods on a
payload value, the logic stays in a payload method and the Python method
forwards to it.

Assisted-by: Claude Code:claude-opus-5-5
Assisted-by: Grok:grok-4.7

* Reject payload receivers on #[pymethod] and #[pygetset]

A #[pymethod] or #[pygetset] item with a self receiver is now a compile
error when self is the payload: in an impl for T rather than Py<T> or
PyRef<T>, and in a #[pyclass] trait. The error points to taking
zelf: &Py<Self> or zelf: PyRef<Self>, or defining the item in impl Py<T>.

Assisted-by: Claude Code:claude-opus-5-5

* Pass the object to the layout test getter

The subclass layout test's extra getter is a #[pygetset] on the
payload. Take zelf: &Py<Self> so the receiver is the object.

Assisted-by: Grok:4.7
This commit is contained in:
Jeong, YunWon authored and GitHub committed 2026-09-30 22:12:16 +09:00
1 parent 536737f4a0
commit 100dac0bbe
37 files changed
+2150 -1808

No files matched your search

+36 -4
View File
@@ -72,6 +72,9 @@ struct ImplContext {
/// Set when the impl has no generic parameters, so `Self` in argument
/// types can be replaced before it appears in a nested const.
self_ty_subst: Option<syn::Type>,
/// Set when `self` in this impl is the payload rather than the object:
/// an impl for `T` rather than `Py<T>` or `PyRef<T>`, or a trait.
self_is_payload: bool,
}
fn extract_items_into_context<'a, Item>(
@@ -108,6 +111,13 @@ pub(crate) fn impl_pyclass_impl(attr: PunctuatedNestedMeta, item: Item) -> Resul
context.self_ty_subst = Some((*imp.self_ty).clone());
context.getset_items.class_ty = context.self_ty_subst.clone();
}
context.self_is_payload = !matches!(
imp.self_ty.as_ref(),
syn::Type::Path(syn::TypePath { path, .. })
if path.segments.last().is_some_and(|segment| {
segment.ident == "Py" || segment.ident == "PyRef"
})
);
extract_items_into_context(&mut context, imp.items.iter_mut());
let attr_nonempty = !attr.is_empty();
@@ -272,10 +282,8 @@ pub(crate) fn impl_pyclass_impl(attr: PunctuatedNestedMeta, item: Item) -> Resul
}
}
Item::Trait(mut trai) => {
let mut context = ImplContext {
is_trait: true,
..Default::default()
};
context.is_trait = true;
context.self_is_payload = true;
let mut has_extend_slots = false;
for item in &trai.items {
let has = match item {
@@ -1122,6 +1130,25 @@ define_content_item!(
struct MemberItem
);
/// Rejects a `self` receiver where `self` is the payload: Python methods and
/// getset descriptors receive the object, as `&Py<Self>` or `PyRef<Self>`.
fn check_object_receiver(sig: &syn::Signature, context: &ImplContext, attr: &str) -> Result<()> {
if !context.self_is_payload {
return Ok(());
}
match sig.receiver() {
Some(receiver) => Err(syn::Error::new_spanned(
receiver,
format!(
"#[{attr}] must receive the object, not the payload. \
Take `zelf: &Py<Self>` or `zelf: PyRef<Self>` instead of `self`, \
or define it in `impl Py<T>`."
),
)),
None => Ok(()),
}
}
struct ImplItemArgs<'a, Item: ItemLike> {
item: &'a Item,
attrs: &'a mut Vec<Attribute>,
@@ -1258,6 +1285,10 @@ where
}
}
if matches!(self.inner.attr_name, AttrName::Method) {
check_object_receiver(func.sig(), args.context, "pymethod")?;
}
let raw = item_meta.raw()?;
let has_receiver = func
.sig()
@@ -1331,6 +1362,7 @@ where
let item_meta = GetSetItemMeta::from_attr(ident.clone(), &item_attr)?;
let (py_name, kind) = item_meta.getset_name()?;
check_object_receiver(func.sig(), args.context, "pygetset")?;
// Add #[allow(non_snake_case)] for setter methods
if matches!(kind, GetSetItemKind::Set) {
+169 -165
View File
@@ -215,20 +215,20 @@ pub(crate) mod _asyncio {
}
#[pymethod]
fn result(&self, vm: &VirtualMachine) -> PyResult {
match self.fut_state.load() {
fn result(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
match zelf.fut_state.load() {
FutureState::Pending => Err(new_invalid_state_error(vm, "Result is not ready.")),
FutureState::Cancelled => {
let exc = self.make_cancelled_error_impl(vm);
let exc = zelf.make_cancelled_error_impl(vm);
Err(exc)
}
FutureState::Finished => {
self.fut_log_tb.store(false, Ordering::Relaxed);
let fut_exception = self.fut_exception.read().clone();
zelf.fut_log_tb.store(false, Ordering::Relaxed);
let fut_exception = zelf.fut_exception.read().clone();
if let Some(exc) = fut_exception {
let exc: PyBaseExceptionRef = exc.downcast().unwrap();
// Restore the original traceback to prevent traceback accumulation
let fut_exception_tb = self.fut_exception_tb.read().clone();
let fut_exception_tb = zelf.fut_exception_tb.read().clone();
if let Some(tb) = fut_exception_tb
&& let Ok(tb) = tb.downcast::<PyTraceback>()
{
@@ -236,7 +236,7 @@ pub(crate) mod _asyncio {
}
Err(exc)
} else {
Ok(self
Ok(zelf
.fut_result
.read()
.clone()
@@ -247,16 +247,16 @@ pub(crate) mod _asyncio {
}
#[pymethod]
fn exception(&self, vm: &VirtualMachine) -> PyResult {
match self.fut_state.load() {
fn exception(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
match zelf.fut_state.load() {
FutureState::Pending => Err(new_invalid_state_error(vm, "Exception is not set.")),
FutureState::Cancelled => {
let exc = self.make_cancelled_error_impl(vm);
let exc = zelf.make_cancelled_error_impl(vm);
Err(exc)
}
FutureState::Finished => {
self.fut_log_tb.store(false, Ordering::Relaxed);
Ok(self
zelf.fut_log_tb.store(false, Ordering::Relaxed);
Ok(zelf
.fut_exception
.read()
.clone()
@@ -366,29 +366,29 @@ pub(crate) mod _asyncio {
#[pymethod]
fn remove_done_callback(
&self,
zelf: &Py<Self>,
RemoveDoneCallbackArgs { func }: RemoveDoneCallbackArgs,
vm: &VirtualMachine,
) -> PyResult<usize> {
if self.fut_loop.read().is_none() {
if zelf.fut_loop.read().is_none() {
return Err(vm.new_runtime_error("Future object is not initialized."));
}
let mut cleared_callback0 = 0usize;
// Check fut_callback0 first
// Clone to release lock before comparison (which may run Python code)
let cb0 = self.fut_callback0.read().clone();
let cb0 = zelf.fut_callback0.read().clone();
if let Some(cb0) = cb0 {
let cmp = vm.identical_or_equal(&cb0, &func)?;
if cmp {
*self.fut_callback0.write() = None;
*self.fut_context0.write() = None;
*zelf.fut_callback0.write() = None;
*zelf.fut_context0.write() = None;
cleared_callback0 = 1;
}
}
// Check if fut_callbacks exists
let callbacks = self.fut_callbacks.read().clone();
let callbacks = zelf.fut_callbacks.read().clone();
let callbacks = match callbacks {
Some(c) => c,
None => return Ok(cleared_callback0),
@@ -398,7 +398,7 @@ pub(crate) mod _asyncio {
let len = list.borrow_vec().len();
if len == 0 {
*self.fut_callbacks.write() = None;
*zelf.fut_callbacks.write() = None;
return Ok(cleared_callback0);
}
@@ -410,7 +410,7 @@ pub(crate) mod _asyncio {
let cb = tuple.as_slice().first().unwrap().clone();
let cmp = vm.identical_or_equal(&cb, &func)?;
if cmp {
*self.fut_callbacks.write() = None;
*zelf.fut_callbacks.write() = None;
return Ok(1 + cleared_callback0);
}
}
@@ -425,7 +425,7 @@ pub(crate) mod _asyncio {
loop {
// Re-check fut_callbacks on each iteration (evil code may have cleared it)
let callbacks = self.fut_callbacks.read().clone();
let callbacks = zelf.fut_callbacks.read().clone();
let callbacks = match callbacks {
Some(c) => c,
None => break,
@@ -457,9 +457,9 @@ pub(crate) mod _asyncio {
// Update fut_callbacks with filtered list
if new_callbacks.is_empty() {
*self.fut_callbacks.write() = None;
*zelf.fut_callbacks.write() = None;
} else {
*self.fut_callbacks.write() = Some(vm.ctx.new_list(new_callbacks).into());
*zelf.fut_callbacks.write() = Some(vm.ctx.new_list(new_callbacks).into());
}
Ok(removed + cleared_callback0)
@@ -483,26 +483,26 @@ pub(crate) mod _asyncio {
}
#[pymethod]
fn cancelled(&self) -> bool {
self.fut_state.load() == FutureState::Cancelled
fn cancelled(zelf: &Py<Self>) -> bool {
zelf.fut_state.load() == FutureState::Cancelled
}
#[pymethod]
fn done(&self) -> bool {
self.fut_state.load() != FutureState::Pending
fn done(zelf: &Py<Self>) -> bool {
zelf.fut_state.load() != FutureState::Pending
}
#[pymethod]
fn get_loop(&self, vm: &VirtualMachine) -> PyResult {
self.fut_loop
fn get_loop(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
zelf.fut_loop
.read()
.clone()
.ok_or_else(|| vm.new_runtime_error("Future object is not initialized."))
}
#[pymethod]
fn _make_cancelled_error(&self, vm: &VirtualMachine) -> PyBaseExceptionRef {
self.make_cancelled_error_impl(vm)
fn _make_cancelled_error(zelf: &Py<Self>, vm: &VirtualMachine) -> PyBaseExceptionRef {
zelf.make_cancelled_error_impl(vm)
}
fn make_cancelled_error_impl(&self, vm: &VirtualMachine) -> PyBaseExceptionRef {
@@ -585,24 +585,24 @@ pub(crate) mod _asyncio {
// Properties
#[pygetset]
fn _state(&self) -> &'static str {
self.fut_state.load().as_str()
fn _state(zelf: &Py<Self>) -> &'static str {
zelf.fut_state.load().as_str()
}
#[pygetset]
fn _asyncio_future_blocking(&self) -> bool {
self.fut_blocking.load(Ordering::Relaxed)
fn _asyncio_future_blocking(zelf: &Py<Self>) -> bool {
zelf.fut_blocking.load(Ordering::Relaxed)
}
#[pygetset(setter)]
fn set__asyncio_future_blocking(
&self,
zelf: &Py<Self>,
value: PySetterValue<bool>,
vm: &VirtualMachine,
) -> PyResult<()> {
match value {
PySetterValue::Assign(v) => {
self.fut_blocking.store(v, Ordering::Relaxed);
zelf.fut_blocking.store(v, Ordering::Relaxed);
Ok(())
}
PySetterValue::Delete => Err(vm.new_attribute_error("cannot delete attribute")),
@@ -610,20 +610,20 @@ pub(crate) mod _asyncio {
}
#[pygetset]
fn _loop(&self, vm: &VirtualMachine) -> PyObjectRef {
self.fut_loop
fn _loop(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.fut_loop
.read()
.clone()
.unwrap_or_else(|| vm.ctx.none())
}
#[pygetset]
fn _callbacks(&self, vm: &VirtualMachine) -> PyObjectRef {
fn _callbacks(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
let mut result = Vec::new();
let fut_callback0 = self.fut_callback0.read().clone();
let fut_callback0 = zelf.fut_callback0.read().clone();
if let Some(cb0) = fut_callback0 {
let ctx0 = self
let ctx0 = zelf
.fut_context0
.read()
.clone()
@@ -631,7 +631,7 @@ pub(crate) mod _asyncio {
result.push(vm.ctx.new_tuple(vec![cb0, ctx0]).into());
}
let fut_callbacks = self.fut_callbacks.read().clone();
let fut_callbacks = zelf.fut_callbacks.read().clone();
if let Some(callbacks) = fut_callbacks {
let list: PyListRef = callbacks.downcast().unwrap();
for item in list.borrow_vec().iter() {
@@ -648,29 +648,29 @@ pub(crate) mod _asyncio {
}
#[pygetset]
fn _result(&self, vm: &VirtualMachine) -> PyObjectRef {
self.fut_result
fn _result(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.fut_result
.read()
.clone()
.unwrap_or_else(|| vm.ctx.none())
}
#[pygetset]
fn _exception(&self, vm: &VirtualMachine) -> PyObjectRef {
self.fut_exception
fn _exception(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.fut_exception
.read()
.clone()
.unwrap_or_else(|| vm.ctx.none())
}
#[pygetset]
fn _log_traceback(&self) -> bool {
self.fut_log_tb.load(Ordering::Relaxed)
fn _log_traceback(zelf: &Py<Self>) -> bool {
zelf.fut_log_tb.load(Ordering::Relaxed)
}
#[pygetset(setter)]
fn set__log_traceback(
&self,
zelf: &Py<Self>,
value: PySetterValue<bool>,
vm: &VirtualMachine,
) -> PyResult<()> {
@@ -679,7 +679,7 @@ pub(crate) mod _asyncio {
if v {
return Err(vm.new_value_error("_log_traceback can only be set to False"));
}
self.fut_log_tb.store(false, Ordering::Relaxed);
zelf.fut_log_tb.store(false, Ordering::Relaxed);
Ok(())
}
PySetterValue::Delete => Err(vm.new_attribute_error("cannot delete attribute")),
@@ -687,36 +687,36 @@ pub(crate) mod _asyncio {
}
#[pygetset]
fn _source_traceback(&self, vm: &VirtualMachine) -> PyObjectRef {
self.fut_source_tb
fn _source_traceback(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.fut_source_tb
.read()
.clone()
.unwrap_or_else(|| vm.ctx.none())
}
#[pygetset]
fn _cancel_message(&self, vm: &VirtualMachine) -> PyObjectRef {
self.fut_cancel_msg
fn _cancel_message(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.fut_cancel_msg
.read()
.clone()
.unwrap_or_else(|| vm.ctx.none())
}
#[pygetset(setter)]
fn set__cancel_message(&self, value: PySetterValue) {
fn set__cancel_message(zelf: &Py<Self>, value: PySetterValue) {
match value {
PySetterValue::Assign(v) => *self.fut_cancel_msg.write() = Some(v),
PySetterValue::Delete => *self.fut_cancel_msg.write() = None,
PySetterValue::Assign(v) => *zelf.fut_cancel_msg.write() = Some(v),
PySetterValue::Delete => *zelf.fut_cancel_msg.write() = None,
}
}
#[pygetset]
fn _asyncio_awaited_by(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
let awaited_by = self.fut_awaited_by.read().clone();
fn _asyncio_awaited_by(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
let awaited_by = zelf.fut_awaited_by.read().clone();
match awaited_by {
None => Ok(vm.ctx.none()),
Some(obj) => {
if self.fut_awaited_by_is_set.load(Ordering::Relaxed) {
if zelf.fut_awaited_by_is_set.load(Ordering::Relaxed) {
// Already a Set
Ok(obj)
} else {
@@ -961,8 +961,8 @@ pub(crate) mod _asyncio {
#[pyclass(with(IterNext, Iterable))]
impl PyFutureIter {
#[pymethod]
fn send(&self, _value: PyObjectRef, vm: &VirtualMachine) -> PyResult {
let future = self.future.read().clone();
fn send(zelf: &Py<Self>, _value: PyObjectRef, vm: &VirtualMachine) -> PyResult {
let future = zelf.future.read().clone();
let future = match future {
Some(f) => f,
None => return Err(vm.new_stop_iteration(None)),
@@ -984,7 +984,7 @@ pub(crate) mod _asyncio {
// Check if future is done
let done = vm.call_method(&future, "done", ())?;
if done.try_to_bool(vm)? {
*self.future.write() = None;
*zelf.future.write() = None;
let result = vm.call_method(&future, "result", ())?;
return Err(vm.new_stop_iteration(Some(result)));
}
@@ -1012,7 +1012,7 @@ pub(crate) mod _asyncio {
#[pymethod]
fn throw(
&self,
zelf: &Py<Self>,
exc_type: PyObjectRef,
exc_val: OptionalArg,
exc_tb: OptionalArg,
@@ -1034,7 +1034,7 @@ pub(crate) mod _asyncio {
)?;
}
*self.future.write() = None;
*zelf.future.write() = None;
// Validate tb if present
if let OptionalArg::Present(ref tb) = exc_tb
@@ -1105,15 +1105,15 @@ pub(crate) mod _asyncio {
}
#[pymethod]
fn close(&self) {
*self.future.write() = None;
fn close(zelf: &Py<Self>) {
*zelf.future.write() = None;
}
}
impl SelfIter for PyFutureIter {}
impl IterNext for PyFutureIter {
fn next(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyIterReturn> {
PyIterReturn::from_pyresult(zelf.send(vm.ctx.none(), vm), vm)
PyIterReturn::from_pyresult(Self::send(zelf, vm.ctx.none(), vm), vm)
}
}
@@ -1272,17 +1272,17 @@ pub(crate) mod _asyncio {
// Future methods delegation
#[pymethod]
fn result(&self, vm: &VirtualMachine) -> PyResult {
match self.base.fut_state.load() {
fn result(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
match zelf.base.fut_state.load() {
FutureState::Pending => Err(new_invalid_state_error(vm, "Result is not ready.")),
FutureState::Cancelled => Err(self.make_cancelled_error_impl(vm)),
FutureState::Cancelled => Err(zelf.make_cancelled_error_impl(vm)),
FutureState::Finished => {
self.base.fut_log_tb.store(false, Ordering::Relaxed);
let fut_exception = self.base.fut_exception.read().clone();
zelf.base.fut_log_tb.store(false, Ordering::Relaxed);
let fut_exception = zelf.base.fut_exception.read().clone();
if let Some(exc) = fut_exception {
let exc: PyBaseExceptionRef = exc.downcast().unwrap();
// Restore the original traceback to prevent traceback accumulation
let fut_exception_tb = self.base.fut_exception_tb.read().clone();
let fut_exception_tb = zelf.base.fut_exception_tb.read().clone();
if let Some(tb) = fut_exception_tb
&& let Ok(tb) = tb.downcast::<PyTraceback>()
{
@@ -1291,7 +1291,7 @@ pub(crate) mod _asyncio {
Err(exc)
} else {
Ok(self
Ok(zelf
.base
.fut_result
.read()
@@ -1303,13 +1303,13 @@ pub(crate) mod _asyncio {
}
#[pymethod]
fn exception(&self, vm: &VirtualMachine) -> PyResult {
match self.base.fut_state.load() {
fn exception(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
match zelf.base.fut_state.load() {
FutureState::Pending => Err(new_invalid_state_error(vm, "Exception is not set.")),
FutureState::Cancelled => Err(self.make_cancelled_error_impl(vm)),
FutureState::Cancelled => Err(zelf.make_cancelled_error_impl(vm)),
FutureState::Finished => {
self.base.fut_log_tb.store(false, Ordering::Relaxed);
Ok(self
zelf.base.fut_log_tb.store(false, Ordering::Relaxed);
Ok(zelf
.base
.fut_exception
.read()
@@ -1329,7 +1329,11 @@ pub(crate) mod _asyncio {
}
#[pymethod]
fn set_exception(&self, _exception: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
fn set_exception(
_zelf: &Py<Self>,
_exception: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
Err(vm.new_runtime_error("Task does not support set_exception operation"))
}
@@ -1384,29 +1388,29 @@ pub(crate) mod _asyncio {
#[pymethod]
fn remove_done_callback(
&self,
zelf: &Py<Self>,
RemoveDoneCallbackArgs { func }: RemoveDoneCallbackArgs,
vm: &VirtualMachine,
) -> PyResult<usize> {
if self.base.fut_loop.read().is_none() {
if zelf.base.fut_loop.read().is_none() {
return Err(vm.new_runtime_error("Future object is not initialized."));
}
let mut cleared_callback0 = 0usize;
// Check fut_callback0 first
// Clone to release lock before comparison (which may run Python code)
let cb0 = self.base.fut_callback0.read().clone();
let cb0 = zelf.base.fut_callback0.read().clone();
if let Some(cb0) = cb0 {
let cmp = vm.identical_or_equal(&cb0, &func)?;
if cmp {
*self.base.fut_callback0.write() = None;
*self.base.fut_context0.write() = None;
*zelf.base.fut_callback0.write() = None;
*zelf.base.fut_context0.write() = None;
cleared_callback0 = 1;
}
}
// Check if fut_callbacks exists
let callbacks = self.base.fut_callbacks.read().clone();
let callbacks = zelf.base.fut_callbacks.read().clone();
let callbacks = match callbacks {
Some(c) => c,
None => return Ok(cleared_callback0),
@@ -1416,7 +1420,7 @@ pub(crate) mod _asyncio {
let len = list.borrow_vec().len();
if len == 0 {
*self.base.fut_callbacks.write() = None;
*zelf.base.fut_callbacks.write() = None;
return Ok(cleared_callback0);
}
@@ -1428,7 +1432,7 @@ pub(crate) mod _asyncio {
let cb = tuple.as_slice().first().unwrap().clone();
let cmp = vm.identical_or_equal(&cb, &func)?;
if cmp {
*self.base.fut_callbacks.write() = None;
*zelf.base.fut_callbacks.write() = None;
return Ok(1 + cleared_callback0);
}
}
@@ -1443,7 +1447,7 @@ pub(crate) mod _asyncio {
loop {
// Re-check fut_callbacks on each iteration (evil code may have cleared it)
let callbacks = self.base.fut_callbacks.read().clone();
let callbacks = zelf.base.fut_callbacks.read().clone();
let callbacks = match callbacks {
Some(c) => c,
None => break,
@@ -1475,9 +1479,9 @@ pub(crate) mod _asyncio {
// Update fut_callbacks with filtered list
if new_callbacks.is_empty() {
*self.base.fut_callbacks.write() = None;
*zelf.base.fut_callbacks.write() = None;
} else {
*self.base.fut_callbacks.write() = Some(vm.ctx.new_list(new_callbacks).into());
*zelf.base.fut_callbacks.write() = Some(vm.ctx.new_list(new_callbacks).into());
}
Ok(removed + cleared_callback0)
@@ -1545,19 +1549,19 @@ pub(crate) mod _asyncio {
}
#[pymethod]
fn cancel(&self, args: CancelArgs, vm: &VirtualMachine) -> PyResult<bool> {
if self.base.fut_state.load() != FutureState::Pending {
fn cancel(zelf: &Py<Self>, args: CancelArgs, vm: &VirtualMachine) -> PyResult<bool> {
if zelf.base.fut_state.load() != FutureState::Pending {
// Clear log_tb even when cancel fails (task is already done)
self.base.fut_log_tb.store(false, Ordering::Relaxed);
zelf.base.fut_log_tb.store(false, Ordering::Relaxed);
return Ok(false);
}
self.task_num_cancels_requested
zelf.task_num_cancels_requested
.fetch_add(1, Ordering::SeqCst);
let msg_value = args.msg;
let task_fut_waiter = self.task_fut_waiter.read().clone();
let task_fut_waiter = zelf.task_fut_waiter.read().clone();
if let Some(fut_waiter) = task_fut_waiter {
// Call cancel with msg=msg keyword argument
let cancel_args = if let Some(ref m) = msg_value {
@@ -1574,82 +1578,82 @@ pub(crate) mod _asyncio {
}
}
self.task_must_cancel.store(true, Ordering::Relaxed);
*self.base.fut_cancel_msg.write() = msg_value;
zelf.task_must_cancel.store(true, Ordering::Relaxed);
*zelf.base.fut_cancel_msg.write() = msg_value;
Ok(true)
}
#[pymethod]
fn cancelled(&self) -> bool {
self.base.fut_state.load() == FutureState::Cancelled
fn cancelled(zelf: &Py<Self>) -> bool {
zelf.base.fut_state.load() == FutureState::Cancelled
}
#[pymethod]
fn done(&self) -> bool {
self.base.fut_state.load() != FutureState::Pending
fn done(zelf: &Py<Self>) -> bool {
zelf.base.fut_state.load() != FutureState::Pending
}
#[pymethod]
fn cancelling(&self) -> i32 {
self.task_num_cancels_requested.load(Ordering::SeqCst)
fn cancelling(zelf: &Py<Self>) -> i32 {
zelf.task_num_cancels_requested.load(Ordering::SeqCst)
}
#[pymethod]
fn uncancel(&self) -> i32 {
let prev = self
fn uncancel(zelf: &Py<Self>) -> i32 {
let prev = zelf
.task_num_cancels_requested
.fetch_sub(1, Ordering::SeqCst);
if prev <= 0 {
self.task_num_cancels_requested.store(0, Ordering::SeqCst);
zelf.task_num_cancels_requested.store(0, Ordering::SeqCst);
0
} else {
let new_val = prev - 1;
// When cancelling count reaches 0, reset _must_cancel
if new_val == 0 {
self.task_must_cancel.store(false, Ordering::SeqCst);
zelf.task_must_cancel.store(false, Ordering::SeqCst);
}
new_val
}
}
#[pymethod]
fn get_coro(&self, vm: &VirtualMachine) -> PyObjectRef {
self.task_coro
fn get_coro(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.task_coro
.read()
.clone()
.unwrap_or_else(|| vm.ctx.none())
}
#[pymethod]
fn get_context(&self, vm: &VirtualMachine) -> PyObjectRef {
self.task_context
fn get_context(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.task_context
.read()
.clone()
.unwrap_or_else(|| vm.ctx.none())
}
#[pymethod]
fn get_name(&self, vm: &VirtualMachine) -> PyObjectRef {
self.task_name
fn get_name(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.task_name
.read()
.clone()
.unwrap_or_else(|| vm.ctx.none())
}
#[pymethod]
fn set_name(&self, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
fn set_name(zelf: &Py<Self>, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
let name = if !value.fast_isinstance(vm.ctx.types.str_type) {
value.str(vm)?.into()
} else {
value
};
*self.task_name.write() = Some(name);
*zelf.task_name.write() = Some(name);
Ok(())
}
#[pymethod]
fn get_loop(&self, vm: &VirtualMachine) -> PyResult {
self.base
fn get_loop(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
zelf.base
.fut_loop
.read()
.clone()
@@ -1684,30 +1688,30 @@ pub(crate) mod _asyncio {
}
#[pymethod]
fn _make_cancelled_error(&self, vm: &VirtualMachine) -> PyBaseExceptionRef {
self.make_cancelled_error_impl(vm)
fn _make_cancelled_error(zelf: &Py<Self>, vm: &VirtualMachine) -> PyBaseExceptionRef {
zelf.make_cancelled_error_impl(vm)
}
// Properties
#[pygetset]
fn _state(&self) -> &'static str {
self.base.fut_state.load().as_str()
fn _state(zelf: &Py<Self>) -> &'static str {
zelf.base.fut_state.load().as_str()
}
#[pygetset]
fn _asyncio_future_blocking(&self) -> bool {
self.base.fut_blocking.load(Ordering::Relaxed)
fn _asyncio_future_blocking(zelf: &Py<Self>) -> bool {
zelf.base.fut_blocking.load(Ordering::Relaxed)
}
#[pygetset(setter)]
fn set__asyncio_future_blocking(
&self,
zelf: &Py<Self>,
value: PySetterValue<bool>,
vm: &VirtualMachine,
) -> PyResult<()> {
match value {
PySetterValue::Assign(v) => {
self.base.fut_blocking.store(v, Ordering::Relaxed);
zelf.base.fut_blocking.store(v, Ordering::Relaxed);
Ok(())
}
PySetterValue::Delete => Err(vm.new_attribute_error("cannot delete attribute")),
@@ -1715,8 +1719,8 @@ pub(crate) mod _asyncio {
}
#[pygetset]
fn _loop(&self, vm: &VirtualMachine) -> PyObjectRef {
self.base
fn _loop(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.base
.fut_loop
.read()
.clone()
@@ -1724,19 +1728,19 @@ pub(crate) mod _asyncio {
}
#[pygetset]
fn _log_destroy_pending(&self) -> bool {
self.task_log_destroy_pending.load(Ordering::Relaxed)
fn _log_destroy_pending(zelf: &Py<Self>) -> bool {
zelf.task_log_destroy_pending.load(Ordering::Relaxed)
}
#[pygetset(setter)]
fn set__log_destroy_pending(
&self,
zelf: &Py<Self>,
value: PySetterValue<bool>,
vm: &VirtualMachine,
) -> PyResult<()> {
match value {
PySetterValue::Assign(v) => {
self.task_log_destroy_pending.store(v, Ordering::Relaxed);
zelf.task_log_destroy_pending.store(v, Ordering::Relaxed);
Ok(())
}
PySetterValue::Delete => {
@@ -1746,13 +1750,13 @@ pub(crate) mod _asyncio {
}
#[pygetset]
fn _log_traceback(&self) -> bool {
self.base.fut_log_tb.load(Ordering::Relaxed)
fn _log_traceback(zelf: &Py<Self>) -> bool {
zelf.base.fut_log_tb.load(Ordering::Relaxed)
}
#[pygetset(setter)]
fn set__log_traceback(
&self,
zelf: &Py<Self>,
value: PySetterValue<bool>,
vm: &VirtualMachine,
) -> PyResult<()> {
@@ -1761,7 +1765,7 @@ pub(crate) mod _asyncio {
if v {
return Err(vm.new_value_error("_log_traceback can only be set to False"));
}
self.base.fut_log_tb.store(false, Ordering::Relaxed);
zelf.base.fut_log_tb.store(false, Ordering::Relaxed);
Ok(())
}
PySetterValue::Delete => Err(vm.new_attribute_error("cannot delete attribute")),
@@ -1769,29 +1773,29 @@ pub(crate) mod _asyncio {
}
#[pygetset]
fn _must_cancel(&self) -> bool {
self.task_must_cancel.load(Ordering::Relaxed)
fn _must_cancel(zelf: &Py<Self>) -> bool {
zelf.task_must_cancel.load(Ordering::Relaxed)
}
#[pygetset]
fn _coro(&self, vm: &VirtualMachine) -> PyObjectRef {
self.task_coro
fn _coro(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.task_coro
.read()
.clone()
.unwrap_or_else(|| vm.ctx.none())
}
#[pygetset]
fn _fut_waiter(&self, vm: &VirtualMachine) -> PyObjectRef {
self.task_fut_waiter
fn _fut_waiter(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.task_fut_waiter
.read()
.clone()
.unwrap_or_else(|| vm.ctx.none())
}
#[pygetset]
fn _source_traceback(&self, vm: &VirtualMachine) -> PyObjectRef {
self.base
fn _source_traceback(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.base
.fut_source_tb
.read()
.clone()
@@ -1799,8 +1803,8 @@ pub(crate) mod _asyncio {
}
#[pygetset]
fn _result(&self, vm: &VirtualMachine) -> PyObjectRef {
self.base
fn _result(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.base
.fut_result
.read()
.clone()
@@ -1808,8 +1812,8 @@ pub(crate) mod _asyncio {
}
#[pygetset]
fn _exception(&self, vm: &VirtualMachine) -> PyObjectRef {
self.base
fn _exception(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.base
.fut_exception
.read()
.clone()
@@ -1817,8 +1821,8 @@ pub(crate) mod _asyncio {
}
#[pygetset]
fn _cancel_message(&self, vm: &VirtualMachine) -> PyObjectRef {
self.base
fn _cancel_message(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.base
.fut_cancel_msg
.read()
.clone()
@@ -1826,20 +1830,20 @@ pub(crate) mod _asyncio {
}
#[pygetset(setter)]
fn set__cancel_message(&self, value: PySetterValue) {
fn set__cancel_message(zelf: &Py<Self>, value: PySetterValue) {
match value {
PySetterValue::Assign(v) => *self.base.fut_cancel_msg.write() = Some(v),
PySetterValue::Delete => *self.base.fut_cancel_msg.write() = None,
PySetterValue::Assign(v) => *zelf.base.fut_cancel_msg.write() = Some(v),
PySetterValue::Delete => *zelf.base.fut_cancel_msg.write() = None,
}
}
#[pygetset]
fn _callbacks(&self, vm: &VirtualMachine) -> PyObjectRef {
fn _callbacks(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
let mut result: Vec<PyObjectRef> = Vec::new();
let fut_callback0 = self.base.fut_callback0.read().clone();
let fut_callback0 = zelf.base.fut_callback0.read().clone();
if let Some(cb) = fut_callback0 {
let ctx = self
let ctx = zelf
.base
.fut_context0
.read()
@@ -1848,7 +1852,7 @@ pub(crate) mod _asyncio {
result.push(vm.ctx.new_tuple(vec![cb, ctx]).into());
}
if let Some(callbacks) = self.base.fut_callbacks.read().clone()
if let Some(callbacks) = zelf.base.fut_callbacks.read().clone()
&& let Ok(list) = callbacks.downcast::<PyList>()
{
for item in list.borrow_vec().iter() {
@@ -2882,13 +2886,13 @@ pub(crate) mod _asyncio {
// __self__ property returns the task, used by _format_handle in base_events.py
#[pygetset]
fn __self__(&self, vm: &VirtualMachine) -> PyObjectRef {
self.task.read().clone().unwrap_or_else(|| vm.ctx.none())
fn __self__(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.task.read().clone().unwrap_or_else(|| vm.ctx.none())
}
#[pygetset]
fn __qualname__(&self, vm: &VirtualMachine) -> PyResult<Option<PyObjectRef>> {
match self.task.read().as_ref() {
fn __qualname__(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<Option<PyObjectRef>> {
match zelf.task.read().as_ref() {
Some(t) => vm.get_attribute_opt(t, vm.ctx.intern_str("__qualname__")),
None => Ok(None),
}
@@ -2933,8 +2937,8 @@ pub(crate) mod _asyncio {
}
#[pygetset]
fn __qualname__(&self, vm: &VirtualMachine) -> PyResult<Option<PyObjectRef>> {
match self.task.read().as_ref() {
fn __qualname__(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<Option<PyObjectRef>> {
match zelf.task.read().as_ref() {
Some(t) => vm.get_attribute_opt(t, vm.ctx.intern_str("__qualname__")),
None => Ok(None),
}
+79 -71
View File
@@ -889,8 +889,8 @@ mod _datetime {
)]
impl PyDelta {
#[pymethod]
fn total_seconds(&self, vm: &VirtualMachine) -> PyResult {
let us = vm.ctx.new_bigint(&self.to_microseconds_big());
fn total_seconds(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
let us = vm.ctx.new_bigint(&zelf.to_microseconds_big());
let per_second = vm.ctx.new_int(US_PER_SECOND);
vm._truediv(us.as_object(), per_second.as_object())
}
@@ -2004,8 +2004,8 @@ mod _datetime {
}
#[pymethod]
fn ctime(&self) -> String {
format_ctime(self.y(), self.m(), self.d(), 0, 0, 0)
fn ctime(zelf: &Py<Self>) -> String {
format_ctime(zelf.y(), zelf.m(), zelf.d(), 0, 0, 0)
}
#[pymethod]
@@ -2021,15 +2021,15 @@ mod _datetime {
}
#[pymethod]
fn timetuple(&self, vm: &VirtualMachine) -> PyResult {
build_struct_time(self.y(), self.m(), self.d(), 0, 0, 0, -1, vm)
fn timetuple(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
build_struct_time(zelf.y(), zelf.m(), zelf.d(), 0, 0, 0, -1, vm)
}
#[pymethod]
fn isocalendar(&self, vm: &VirtualMachine) -> PyResult {
let mut year = self.y();
fn isocalendar(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
let mut year = zelf.y();
let mut week1_monday = iso_week1_monday(year);
let today = self.ordinal();
let today = zelf.ordinal();
let (mut week, mut day) = divmod(i64::from(today - week1_monday), 7);
if week < 0 {
year -= 1;
@@ -2050,23 +2050,23 @@ mod _datetime {
}
#[pymethod]
fn isoformat(&self) -> String {
format!("{:04}-{:02}-{:02}", self.year, self.month, self.day)
fn isoformat(zelf: &Py<Self>) -> String {
format!("{:04}-{:02}-{:02}", zelf.year, zelf.month, zelf.day)
}
#[pymethod]
fn isoweekday(&self) -> i32 {
weekday(self.y(), self.m(), self.d()) + 1
fn isoweekday(zelf: &Py<Self>) -> i32 {
weekday(zelf.y(), zelf.m(), zelf.d()) + 1
}
#[pymethod]
fn toordinal(&self) -> i32 {
self.ordinal()
fn toordinal(zelf: &Py<Self>) -> i32 {
zelf.ordinal()
}
#[pymethod]
fn weekday(&self) -> i32 {
weekday(self.y(), self.m(), self.d())
fn weekday(zelf: &Py<Self>) -> i32 {
weekday(zelf.y(), zelf.m(), zelf.d())
}
#[pymethod]
@@ -2305,23 +2305,23 @@ mod _datetime {
#[pyclass(with(Constructor, Representable), flags(IMMUTABLETYPE))]
impl PyIsoCalendarDate {
#[pygetset]
fn year(&self) -> PyObjectRef {
self.item(0)
fn year(zelf: &Py<Self>) -> PyObjectRef {
zelf.item(0)
}
#[pygetset]
fn week(&self) -> PyObjectRef {
self.item(1)
fn week(zelf: &Py<Self>) -> PyObjectRef {
zelf.item(1)
}
#[pygetset]
fn weekday(&self) -> PyObjectRef {
self.item(2)
fn weekday(zelf: &Py<Self>) -> PyObjectRef {
zelf.item(2)
}
#[pymethod]
fn __reduce__(&self, vm: &VirtualMachine) -> PyRef<PyTuple> {
let items = vm.new_tuple((self.item(0), self.item(1), self.item(2)));
fn __reduce__(zelf: &Py<Self>, vm: &VirtualMachine) -> PyRef<PyTuple> {
let items = vm.new_tuple((zelf.item(0), zelf.item(1), zelf.item(2)));
vm.new_tuple((vm.ctx.types.tuple_type.to_owned(), (items,)))
}
}
@@ -2348,17 +2348,17 @@ mod _datetime {
#[pyclass(with(Constructor), flags(BASETYPE))]
impl PyTzInfo {
#[pymethod]
fn tzname(&self, _object: PyObjectRef, vm: &VirtualMachine) -> PyResult {
fn tzname(_zelf: &Py<Self>, _object: PyObjectRef, vm: &VirtualMachine) -> PyResult {
tzinfo_nogo("tzname", vm)
}
#[pymethod]
fn utcoffset(&self, _object: PyObjectRef, vm: &VirtualMachine) -> PyResult {
fn utcoffset(_zelf: &Py<Self>, _object: PyObjectRef, vm: &VirtualMachine) -> PyResult {
tzinfo_nogo("utcoffset", vm)
}
#[pymethod]
fn dst(&self, _object: PyObjectRef, vm: &VirtualMachine) -> PyResult {
fn dst(_zelf: &Py<Self>, _object: PyObjectRef, vm: &VirtualMachine) -> PyResult {
tzinfo_nogo("dst", vm)
}
@@ -2559,14 +2559,18 @@ mod _datetime {
}
#[pymethod]
fn utcoffset(&self, object: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyRef<PyDelta>> {
fn utcoffset(
zelf: &Py<Self>,
object: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<PyRef<PyDelta>> {
let dt = object;
timezone_check_argument(&dt, "utcoffset", vm)?;
Ok(self.offset.clone())
Ok(zelf.offset.clone())
}
#[pymethod]
fn dst(&self, object: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
fn dst(_zelf: &Py<Self>, object: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
let dt = object;
timezone_check_argument(&dt, "dst", vm)?;
Ok(())
@@ -2585,10 +2589,10 @@ mod _datetime {
}
#[pymethod]
fn __getinitargs__(&self, vm: &VirtualMachine) -> PyRef<PyTuple> {
match &self.name {
None => vm.new_tuple((self.offset.clone(),)),
Some(name) => vm.new_tuple((self.offset.clone(), name.clone())),
fn __getinitargs__(zelf: &Py<Self>, vm: &VirtualMachine) -> PyRef<PyTuple> {
match &zelf.name {
None => vm.new_tuple((zelf.offset.clone(),)),
Some(name) => vm.new_tuple((zelf.offset.clone(), name.clone())),
}
}
@@ -2890,20 +2894,24 @@ mod _datetime {
}
#[pymethod]
fn isoformat(&self, args: TimeIsoformatArgs, vm: &VirtualMachine) -> PyResult<String> {
fn isoformat(
zelf: &Py<Self>,
args: TimeIsoformatArgs,
vm: &VirtualMachine,
) -> PyResult<String> {
let spec = args.timespec.into_option().map(|s| s.to_string());
let mut result = format_time_spec(
spec.as_deref(),
self.hour,
self.minute,
self.second,
self.microsecond,
zelf.hour,
zelf.minute,
zelf.second,
zelf.microsecond,
)
.map_err(|()| vm.new_value_error("Unknown timespec value"))?;
if self.tzinfo.is_some() {
if zelf.tzinfo.is_some() {
result.push_str(&format_utcoffset(
":",
self.tzinfo.as_ref(),
zelf.tzinfo.as_ref(),
&vm.ctx.none(),
vm,
)?);
@@ -2944,23 +2952,23 @@ mod _datetime {
}
#[pymethod]
fn utcoffset(&self, vm: &VirtualMachine) -> PyResult {
fn utcoffset(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
Ok(offset_to_py(
call_utcoffset(self.tzinfo.as_ref(), &vm.ctx.none(), vm)?,
call_utcoffset(zelf.tzinfo.as_ref(), &vm.ctx.none(), vm)?,
vm,
))
}
#[pymethod]
fn tzname(&self, vm: &VirtualMachine) -> PyResult {
Ok(call_tzname(self.tzinfo.as_ref(), &vm.ctx.none(), vm)?
fn tzname(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
Ok(call_tzname(zelf.tzinfo.as_ref(), &vm.ctx.none(), vm)?
.map_or_else(|| vm.ctx.none(), Into::into))
}
#[pymethod]
fn dst(&self, vm: &VirtualMachine) -> PyResult {
fn dst(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
Ok(offset_to_py(
call_dst(self.tzinfo.as_ref(), &vm.ctx.none(), vm)?,
call_dst(zelf.tzinfo.as_ref(), &vm.ctx.none(), vm)?,
vm,
))
}
@@ -3939,45 +3947,45 @@ mod _datetime {
}
#[pymethod]
fn date(&self, vm: &VirtualMachine) -> PyRef<PyDate> {
PyDate::new(self.date.y(), self.date.m(), self.date.d()).into_ref(&vm.ctx)
fn date(zelf: &Py<Self>, vm: &VirtualMachine) -> PyRef<PyDate> {
PyDate::new(zelf.date.y(), zelf.date.m(), zelf.date.d()).into_ref(&vm.ctx)
}
#[pymethod]
fn time(&self, vm: &VirtualMachine) -> PyRef<PyTime> {
fn time(zelf: &Py<Self>, vm: &VirtualMachine) -> PyRef<PyTime> {
PyTime::new(
i32::from(self.hour),
i32::from(self.minute),
i32::from(self.second),
self.microsecond as i32,
i32::from(zelf.hour),
i32::from(zelf.minute),
i32::from(zelf.second),
zelf.microsecond as i32,
None,
i32::from(self.fold),
i32::from(zelf.fold),
)
.into_ref(&vm.ctx)
}
#[pymethod]
fn timetz(&self, vm: &VirtualMachine) -> PyRef<PyTime> {
fn timetz(zelf: &Py<Self>, vm: &VirtualMachine) -> PyRef<PyTime> {
PyTime::new(
i32::from(self.hour),
i32::from(self.minute),
i32::from(self.second),
self.microsecond as i32,
self.tzinfo.load_owned(),
i32::from(self.fold),
i32::from(zelf.hour),
i32::from(zelf.minute),
i32::from(zelf.second),
zelf.microsecond as i32,
zelf.tzinfo.load_owned(),
i32::from(zelf.fold),
)
.into_ref(&vm.ctx)
}
#[pymethod]
fn ctime(&self) -> String {
fn ctime(zelf: &Py<Self>) -> String {
format_ctime(
self.date.y(),
self.date.m(),
self.date.d(),
self.hour,
self.minute,
self.second,
zelf.date.y(),
zelf.date.m(),
zelf.date.d(),
zelf.hour,
zelf.minute,
zelf.second,
)
}
@@ -4008,7 +4016,7 @@ mod _datetime {
vm,
)?;
let delta = Self::subtract_datetime(zelf, &epoch, vm)?;
return delta.total_seconds(vm);
return PyDelta::total_seconds(&delta, vm);
}
let (y, mo, d, h, mi, s, us) = zelf.fields();
let seconds = local_to_seconds(y, mo, d, h, mi, s, zelf.fold != 0, vm)?;
+15 -15
View File
@@ -232,33 +232,33 @@ mod _queue {
)]
impl PySimpleQueue {
#[pymethod]
fn empty(&self) -> bool {
self.buf.lock().is_empty()
fn empty(zelf: &Py<Self>) -> bool {
zelf.buf.lock().is_empty()
}
#[pymethod]
fn qsize(&self) -> usize {
self.buf.lock().len()
fn qsize(zelf: &Py<Self>) -> usize {
zelf.buf.lock().len()
}
#[pymethod]
fn put(&self, args: PutArgs, vm: &VirtualMachine) {
fn put(zelf: &Py<Self>, args: PutArgs, vm: &VirtualMachine) {
let PutArgs { item, .. } = args;
self.push(item, vm);
zelf.push(item, vm);
}
#[pymethod]
fn put_nowait(&self, ItemArg { item }: ItemArg, vm: &VirtualMachine) {
self.push(item, vm);
fn put_nowait(zelf: &Py<Self>, ItemArg { item }: ItemArg, vm: &VirtualMachine) {
zelf.push(item, vm);
}
#[pymethod]
fn get(&self, args: GetArgs, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
fn get(zelf: &Py<Self>, args: GetArgs, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
let GetArgs { block, timeout } = args;
// Non-blocking: just try once
if !block {
return Self::get_inner(&mut self.buf.lock()).ok_or_else(|| empty_error(vm));
return Self::get_inner(&mut zelf.buf.lock()).ok_or_else(|| empty_error(vm));
}
#[cfg_attr(
@@ -278,24 +278,24 @@ mod _queue {
#[cfg(feature = "threading")]
{
if !self.sem.acquire(block, deadline, vm)? {
if !zelf.sem.acquire(block, deadline, vm)? {
return Err(empty_error(vm));
}
}
Self::get_inner(&mut self.buf.lock()).ok_or_else(|| empty_error(vm))
Self::get_inner(&mut zelf.buf.lock()).ok_or_else(|| empty_error(vm))
}
#[pymethod]
fn get_nowait(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
fn get_nowait(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
#[cfg(feature = "threading")]
{
if !self.sem.acquire(false, None, vm)? {
if !zelf.sem.acquire(false, None, vm)? {
return Err(empty_error(vm));
}
}
Self::get_inner(&mut self.buf.lock()).ok_or_else(|| empty_error(vm))
Self::get_inner(&mut zelf.buf.lock()).ok_or_else(|| empty_error(vm))
}
#[pyclassmethod]
+131 -110
View File
@@ -1137,9 +1137,9 @@ mod _sqlite3 {
}
#[pymethod]
fn close(&self, vm: &VirtualMachine) -> PyResult<()> {
self.check_thread(vm)?;
self.drop_db(vm)
fn close(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
zelf.check_thread(vm)?;
zelf.drop_db(vm)
}
fn is_closed(&self) -> bool {
@@ -1147,9 +1147,9 @@ mod _sqlite3 {
}
#[pymethod]
fn commit(&self, vm: &VirtualMachine) -> PyResult<()> {
let db = self.db_lock(vm)?;
let mode = *self.autocommit.lock();
fn commit(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
let db = zelf.db_lock(vm)?;
let mode = *zelf.autocommit.lock();
match mode {
AutocommitMode::Legacy => db.implicit_commit(vm),
AutocommitMode::Enabled => Ok(()),
@@ -1161,9 +1161,9 @@ mod _sqlite3 {
}
#[pymethod]
fn rollback(&self, vm: &VirtualMachine) -> PyResult<()> {
let db = self.db_lock(vm)?;
let mode = *self.autocommit.lock();
fn rollback(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
let db = zelf.db_lock(vm)?;
let mode = *zelf.autocommit.lock();
match mode {
AutocommitMode::Legacy => {
if db.is_autocommit() {
@@ -1287,14 +1287,18 @@ mod _sqlite3 {
}
#[pymethod]
fn create_function(&self, args: CreateFunctionArgs, vm: &VirtualMachine) -> PyResult<()> {
fn create_function(
zelf: &Py<Self>,
args: CreateFunctionArgs,
vm: &VirtualMachine,
) -> PyResult<()> {
let name = args.name.to_cstring(vm)?;
let flags = if args.deterministic {
SQLITE_UTF8 | SQLITE_DETERMINISTIC
} else {
SQLITE_UTF8
};
let db = self.db_lock(vm)?;
let db = zelf.db_lock(vm)?;
check_num_params(&db, args.narg, "narg", vm)?;
let Some(data) = CallbackData::new(args.func, vm) else {
return db.create_function(
@@ -1324,9 +1328,13 @@ mod _sqlite3 {
}
#[pymethod]
fn create_aggregate(&self, args: CreateAggregateArgs, vm: &VirtualMachine) -> PyResult<()> {
fn create_aggregate(
zelf: &Py<Self>,
args: CreateAggregateArgs,
vm: &VirtualMachine,
) -> PyResult<()> {
let name = args.name.to_cstring(vm)?;
let db = self.db_lock(vm)?;
let db = zelf.db_lock(vm)?;
check_num_params(&db, args.narg, "n_arg", vm)?;
let Some(data) = CallbackData::new(args.aggregate_class, vm) else {
return db.create_function(
@@ -1357,13 +1365,13 @@ mod _sqlite3 {
#[pymethod]
fn create_collation(
&self,
zelf: &Py<Self>,
name: PyUtf8StrRef,
callable: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
let name = name.to_cstring(vm)?;
let db = self.db_lock(vm)?;
let db = zelf.db_lock(vm)?;
let Some(data) = CallbackData::new(callable.clone(), vm) else {
unsafe {
sqlite3_create_collation_v2(
@@ -1402,14 +1410,14 @@ mod _sqlite3 {
#[pymethod]
fn create_window_function(
&self,
zelf: &Py<Self>,
name: PyStrRef,
narg: c_int,
aggregate_class: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
let name = name.to_cstring(vm)?;
let db = self.db_lock(vm)?;
let db = zelf.db_lock(vm)?;
check_num_params(&db, narg, "num_params", vm)?;
let Some(data) = CallbackData::new(aggregate_class, vm) else {
unsafe {
@@ -1448,8 +1456,12 @@ mod _sqlite3 {
}
#[pymethod]
fn set_authorizer(&self, callable: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
let db = self.db_lock(vm)?;
fn set_authorizer(
zelf: &Py<Self>,
callable: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
let db = zelf.db_lock(vm)?;
let Some(data) = CallbackData::new(callable, vm) else {
unsafe { sqlite3_set_authorizer(db.db, None, null_mut()) };
return Ok(());
@@ -1468,8 +1480,12 @@ mod _sqlite3 {
}
#[pymethod]
fn set_trace_callback(&self, callable: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
let db = self.db_lock(vm)?;
fn set_trace_callback(
zelf: &Py<Self>,
callable: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
let db = zelf.db_lock(vm)?;
let Some(data) = CallbackData::new(callable, vm) else {
unsafe { sqlite3_trace_v2(db.db, SQLITE_TRACE_STMT, None, null_mut()) };
return Ok(());
@@ -1489,12 +1505,12 @@ mod _sqlite3 {
#[pymethod]
fn set_progress_handler(
&self,
zelf: &Py<Self>,
callable: PyObjectRef,
n: c_int,
vm: &VirtualMachine,
) -> PyResult<()> {
let db = self.db_lock(vm)?;
let db = zelf.db_lock(vm)?;
let Some(data) = CallbackData::new(callable, vm) else {
unsafe { sqlite3_progress_handler(db.db, n, None, null_mut()) };
return Ok(());
@@ -1525,29 +1541,34 @@ mod _sqlite3 {
}
#[pymethod]
fn interrupt(&self, vm: &VirtualMachine) -> PyResult<()> {
fn interrupt(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
// DO NOT check thread safety
self._db_lock(vm).map(|x| x.interrupt())
zelf._db_lock(vm).map(|x| x.interrupt())
}
#[pymethod]
fn getlimit(&self, category: c_int, vm: &VirtualMachine) -> PyResult<c_int> {
self.db_lock(vm)?.limit(category, -1, vm)
fn getlimit(zelf: &Py<Self>, category: c_int, vm: &VirtualMachine) -> PyResult<c_int> {
zelf.db_lock(vm)?.limit(category, -1, vm)
}
#[pymethod]
fn setlimit(&self, category: c_int, limit: c_int, vm: &VirtualMachine) -> PyResult<c_int> {
self.db_lock(vm)?.limit(category, limit, vm)
fn setlimit(
zelf: &Py<Self>,
category: c_int,
limit: c_int,
vm: &VirtualMachine,
) -> PyResult<c_int> {
zelf.db_lock(vm)?.limit(category, limit, vm)
}
#[pymethod]
fn setconfig(
&self,
zelf: &Py<Self>,
op: c_int,
enable: OptionalArg<bool>,
vm: &VirtualMachine,
) -> PyResult<()> {
let db = self.db_lock(vm)?;
let db = zelf.db_lock(vm)?;
if !is_int_dbconfig(op) {
return Err(vm.new_value_error(format!("unknown config 'op': {op}")));
}
@@ -1562,8 +1583,8 @@ mod _sqlite3 {
}
#[pymethod]
fn getconfig(&self, op: c_int, vm: &VirtualMachine) -> PyResult<bool> {
let db = self.db_lock(vm)?;
fn getconfig(zelf: &Py<Self>, op: c_int, vm: &VirtualMachine) -> PyResult<bool> {
let db = zelf.db_lock(vm)?;
if !is_int_dbconfig(op) {
return Err(vm.new_value_error(format!("unknown config 'op': {op}")));
}
@@ -1580,26 +1601,26 @@ mod _sqlite3 {
#[pymethod]
fn __exit__(
&self,
zelf: &Py<Self>,
cls: PyObjectRef,
exc: PyObjectRef,
tb: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
if vm.is_none(&cls) && vm.is_none(&exc) && vm.is_none(&tb) {
self.commit(vm)
Self::commit(zelf, vm)
} else {
self.rollback(vm)
Self::rollback(zelf, vm)
}
}
#[pygetset]
fn isolation_level(&self) -> Option<PyStrRef> {
self.isolation_level.deref().map(|x| x.to_owned())
fn isolation_level(zelf: &Py<Self>) -> Option<PyStrRef> {
zelf.isolation_level.deref().map(|x| x.to_owned())
}
#[pygetset(setter)]
fn set_isolation_level(
&self,
zelf: &Py<Self>,
value: PySetterValue<IsolationLevelArg>,
vm: &VirtualMachine,
) -> PyResult<()> {
@@ -1611,9 +1632,9 @@ mod _sqlite3 {
// If setting isolation_level to None (auto-commit mode), commit any pending transaction
if value.is_none() {
self.commit(vm)?;
Self::commit(zelf, vm)?;
}
let _ = unsafe { self.isolation_level.swap(value) };
let _ = unsafe { zelf.isolation_level.swap(value) };
Ok(())
}
PySetterValue::Delete => {
@@ -1623,8 +1644,8 @@ mod _sqlite3 {
}
#[pygetset]
fn autocommit(&self, vm: &VirtualMachine) -> PyObjectRef {
let mode = *self.autocommit.lock();
fn autocommit(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
let mode = *zelf.autocommit.lock();
match mode {
AutocommitMode::Enabled => vm.ctx.true_value.clone().into(),
AutocommitMode::Disabled => vm.ctx.false_value.clone().into(),
@@ -1632,10 +1653,10 @@ mod _sqlite3 {
}
}
#[pygetset(setter)]
fn set_autocommit(&self, val: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
fn set_autocommit(zelf: &Py<Self>, val: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
let mode = AutocommitMode::try_from_borrowed_object(vm, &val)?;
let db = self.db_lock(vm)?;
*self.autocommit.lock() = mode;
let db = zelf.db_lock(vm)?;
*zelf.autocommit.lock() = mode;
// Handle transaction state based on mode change
match mode {
@@ -1659,18 +1680,18 @@ mod _sqlite3 {
}
#[pygetset]
fn text_factory(&self) -> PyObjectRef {
self.text_factory.to_owned()
fn text_factory(zelf: &Py<Self>) -> PyObjectRef {
zelf.text_factory.to_owned()
}
#[pygetset(setter)]
fn set_text_factory(
&self,
zelf: &Py<Self>,
val: PySetterValue<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<()> {
match val {
PySetterValue::Assign(val) => {
let _ = unsafe { self.text_factory.swap(val) };
let _ = unsafe { zelf.text_factory.swap(val) };
Ok(())
}
PySetterValue::Delete => {
@@ -1680,18 +1701,18 @@ mod _sqlite3 {
}
#[pygetset]
fn row_factory(&self) -> Option<PyObjectRef> {
self.row_factory.load_owned()
fn row_factory(zelf: &Py<Self>) -> Option<PyObjectRef> {
zelf.row_factory.load_owned()
}
#[pygetset(setter)]
fn set_row_factory(
&self,
zelf: &Py<Self>,
val: PySetterValue<Option<PyObjectRef>>,
vm: &VirtualMachine,
) -> PyResult<()> {
match val {
PySetterValue::Assign(val) => {
let _ = unsafe { self.row_factory.swap(val) };
let _ = unsafe { zelf.row_factory.swap(val) };
Ok(())
}
PySetterValue::Delete => {
@@ -1715,53 +1736,53 @@ mod _sqlite3 {
}
#[pygetset]
fn in_transaction(&self, vm: &VirtualMachine) -> PyResult<bool> {
self._db_lock(vm).map(|x| !x.is_autocommit())
fn in_transaction(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<bool> {
zelf._db_lock(vm).map(|x| !x.is_autocommit())
}
#[pygetset]
fn total_changes(&self, vm: &VirtualMachine) -> PyResult<c_int> {
self._db_lock(vm).map(|x| x.total_changes())
fn total_changes(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<c_int> {
zelf._db_lock(vm).map(|x| x.total_changes())
}
#[pygetset(name = "Warning")]
fn exc_warning(&self) -> PyTypeRef {
fn exc_warning(_zelf: &Py<Self>) -> PyTypeRef {
warning_type().to_owned()
}
#[pygetset(name = "Error")]
fn exc_error(&self) -> PyTypeRef {
fn exc_error(_zelf: &Py<Self>) -> PyTypeRef {
error_type().to_owned()
}
#[pygetset(name = "InterfaceError")]
fn exc_interface_error(&self) -> PyTypeRef {
fn exc_interface_error(_zelf: &Py<Self>) -> PyTypeRef {
interface_error_type().to_owned()
}
#[pygetset(name = "DatabaseError")]
fn exc_database_error(&self) -> PyTypeRef {
fn exc_database_error(_zelf: &Py<Self>) -> PyTypeRef {
database_error_type().to_owned()
}
#[pygetset(name = "DataError")]
fn exc_data_error(&self) -> PyTypeRef {
fn exc_data_error(_zelf: &Py<Self>) -> PyTypeRef {
data_error_type().to_owned()
}
#[pygetset(name = "OperationalError")]
fn exc_operational_error(&self) -> PyTypeRef {
fn exc_operational_error(_zelf: &Py<Self>) -> PyTypeRef {
operational_error_type().to_owned()
}
#[pygetset(name = "IntegrityError")]
fn exc_integrity_error(&self) -> PyTypeRef {
fn exc_integrity_error(_zelf: &Py<Self>) -> PyTypeRef {
integrity_error_type().to_owned()
}
#[pygetset(name = "InternalError")]
fn exc_internal_error(&self) -> PyTypeRef {
fn exc_internal_error(_zelf: &Py<Self>) -> PyTypeRef {
internal_error_type().to_owned()
}
#[pygetset(name = "ProgrammingError")]
fn exc_programming_error(&self) -> PyTypeRef {
fn exc_programming_error(_zelf: &Py<Self>) -> PyTypeRef {
programming_error_type().to_owned()
}
#[pygetset(name = "NotSupportedError")]
fn exc_not_supported_error(&self) -> PyTypeRef {
fn exc_not_supported_error(_zelf: &Py<Self>) -> PyTypeRef {
not_supported_error_type().to_owned()
}
}
@@ -2095,9 +2116,9 @@ mod _sqlite3 {
}
#[pymethod]
fn close(&self, vm: &VirtualMachine) -> PyResult<()> {
fn close(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
// Check if __init__ was called
let mut guard = self.inner.lock();
let mut guard = zelf.inner.lock();
let Some(inner) = guard.as_mut() else {
return Err(new_programming_error(
@@ -2115,55 +2136,55 @@ mod _sqlite3 {
}
#[pymethod]
fn setinputsizes(&self, _sizes: PyObjectRef) {}
fn setinputsizes(_zelf: &Py<Self>, _sizes: PyObjectRef) {}
#[pymethod]
fn setoutputsize(&self, _size: PyObjectRef, _column: OptionalArg<PyObjectRef>) {}
fn setoutputsize(_zelf: &Py<Self>, _size: PyObjectRef, _column: OptionalArg<PyObjectRef>) {}
#[pygetset]
fn connection(&self) -> PyRef<Connection> {
self.connection.clone()
fn connection(zelf: &Py<Self>) -> PyRef<Connection> {
zelf.connection.clone()
}
#[pygetset]
fn lastrowid(&self, vm: &VirtualMachine) -> PyResult<i64> {
self.inner(vm).map(|x| x.lastrowid)
fn lastrowid(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<i64> {
zelf.inner(vm).map(|x| x.lastrowid)
}
#[pygetset]
fn rowcount(&self, vm: &VirtualMachine) -> PyResult<i64> {
self.inner(vm).map(|x| x.rowcount)
fn rowcount(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<i64> {
zelf.inner(vm).map(|x| x.rowcount)
}
#[pygetset]
fn description(&self, vm: &VirtualMachine) -> PyResult<Option<PyTupleRef>> {
self.inner(vm).map(|x| x.description.clone())
fn description(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<Option<PyTupleRef>> {
zelf.inner(vm).map(|x| x.description.clone())
}
#[pygetset]
fn arraysize(&self) -> c_int {
self.arraysize.load(Ordering::Relaxed)
fn arraysize(zelf: &Py<Self>) -> c_int {
zelf.arraysize.load(Ordering::Relaxed)
}
#[pygetset(setter)]
fn set_arraysize(&self, val: c_int, vm: &VirtualMachine) -> PyResult<()> {
fn set_arraysize(zelf: &Py<Self>, val: c_int, vm: &VirtualMachine) -> PyResult<()> {
if val < 0 {
return Err(vm.new_value_error("arraysize may not be negative"));
}
self.arraysize.store(val, Ordering::Relaxed);
zelf.arraysize.store(val, Ordering::Relaxed);
Ok(())
}
#[pygetset]
fn row_factory(&self) -> Option<PyObjectRef> {
self.row_factory.load_owned()
fn row_factory(zelf: &Py<Self>) -> Option<PyObjectRef> {
zelf.row_factory.load_owned()
}
#[pygetset(setter)]
fn set_row_factory(&self, val: Option<PyObjectRef>) {
let _ = unsafe { self.row_factory.swap(val) };
fn set_row_factory(zelf: &Py<Self>, val: Option<PyObjectRef>) {
let _ = unsafe { zelf.row_factory.swap(val) };
}
fn build_row_cast_map(
@@ -2382,8 +2403,8 @@ mod _sqlite3 {
)]
impl Row {
#[pymethod]
fn keys(&self, _vm: &VirtualMachine) -> Vec<PyObjectRef> {
self.description
fn keys(zelf: &Py<Self>, _vm: &VirtualMachine) -> Vec<PyObjectRef> {
zelf.description
.as_slice()
.iter()
.map(|x| x.downcast_ref::<PyTuple>().unwrap().as_slice()[0].clone())
@@ -2533,8 +2554,8 @@ mod _sqlite3 {
#[pyclass(flags(DISALLOW_INSTANTIATION), with(AsMapping, AsNumber, AsSequence))]
impl Blob {
#[pymethod]
fn close(&self) {
self.inner.lock().take();
fn close(zelf: &Py<Self>) {
zelf.inner.lock().take();
}
fn ensure_connection_open(&self, vm: &VirtualMachine) -> PyResult<()> {
@@ -2550,14 +2571,14 @@ mod _sqlite3 {
#[pymethod]
fn read(
&self,
zelf: &Py<Self>,
length: OptionalArg<c_int>,
vm: &VirtualMachine,
) -> PyResult<PyRef<PyBytes>> {
self.ensure_connection_open(vm)?;
zelf.ensure_connection_open(vm)?;
let mut length = length.unwrap_or(-1);
let mut inner = self.inner(vm)?;
let mut inner = zelf.inner(vm)?;
let blob_len = inner.blob.bytes();
let max_read = blob_len - inner.offset;
@@ -2572,7 +2593,7 @@ mod _sqlite3 {
let ret = inner
.blob
.read(buf.as_mut_ptr().cast(), length, inner.offset);
self.check(ret, vm)?;
zelf.check(ret, vm)?;
unsafe { buf.set_len(length as usize) };
inner.offset += length;
Ok(vm.ctx.new_bytes(buf))
@@ -2580,9 +2601,9 @@ mod _sqlite3 {
}
#[pymethod]
fn write(&self, data: PyBuffer, vm: &VirtualMachine) -> PyResult<()> {
self.ensure_connection_open(vm)?;
let mut inner = self.inner(vm)?;
fn write(zelf: &Py<Self>, data: PyBuffer, vm: &VirtualMachine) -> PyResult<()> {
zelf.ensure_connection_open(vm)?;
let mut inner = zelf.inner(vm)?;
let blob_len = inner.blob.bytes();
let length = Self::expect_write(blob_len, data.desc.len, inner.offset, vm)?;
@@ -2590,27 +2611,27 @@ mod _sqlite3 {
inner.blob.write(buf.as_ptr().cast(), length, inner.offset)
});
self.check(ret, vm)?;
zelf.check(ret, vm)?;
inner.offset += length;
Ok(())
}
#[pymethod]
fn tell(&self, vm: &VirtualMachine) -> PyResult<c_int> {
self.ensure_connection_open(vm)?;
self.inner(vm).map(|x| x.offset)
fn tell(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<c_int> {
zelf.ensure_connection_open(vm)?;
zelf.inner(vm).map(|x| x.offset)
}
#[pymethod]
fn seek(
&self,
zelf: &Py<Self>,
mut offset: c_int,
origin: OptionalArg<c_int>,
vm: &VirtualMachine,
) -> PyResult<()> {
self.ensure_connection_open(vm)?;
zelf.ensure_connection_open(vm)?;
let origin = origin.unwrap_or(libc::SEEK_SET);
let mut inner = self.inner(vm)?;
let mut inner = zelf.inner(vm)?;
let blob_len = inner.blob.bytes();
let overflow_err = || vm.new_overflow_error("seek offset results in overflow");
@@ -2644,10 +2665,10 @@ mod _sqlite3 {
}
#[pymethod]
fn __exit__(&self, _args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
self.ensure_connection_open(vm)?;
let _ = self.inner(vm)?;
self.close();
fn __exit__(zelf: &Py<Self>, _args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
zelf.ensure_connection_open(vm)?;
let _ = zelf.inner(vm)?;
Self::close(zelf);
Ok(())
}
+45 -40
View File
@@ -872,15 +872,15 @@ pub mod array {
}
#[pygetset]
fn typecode(&self, vm: &VirtualMachine) -> PyStrRef {
fn typecode(zelf: &Py<Self>, vm: &VirtualMachine) -> PyStrRef {
vm.ctx
.intern_str(self.read().typecode().to_string())
.intern_str(zelf.read().typecode().to_string())
.to_owned()
}
#[pygetset]
fn itemsize(&self) -> usize {
self.read().itemsize()
fn itemsize(zelf: &Py<Self>) -> usize {
zelf.read().itemsize()
}
#[pymethod]
@@ -897,21 +897,21 @@ pub mod array {
}
#[pymethod]
fn buffer_info(&self) -> (usize, usize) {
let array = self.read();
fn buffer_info(zelf: &Py<Self>) -> (usize, usize) {
let array = zelf.read();
(array.addr(), array.len())
}
#[pymethod]
fn count(&self, v: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
let array = self.read();
fn count(zelf: &Py<Self>, v: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
let array = zelf.read();
if let Some(item) = ArrayContentType::search_item(array.typecode(), &v, vm) {
return item.map_or(Ok(0), |item| array.count_item(&item, vm));
}
drop(array);
let mut count = 0;
for index in 0..usize::MAX {
let item = self.read().get(index, vm);
let item = zelf.read().get(index, vm);
let Some(item) = item else { break };
if item?.rich_compare_bool(&v, PyComparisonOp::Eq, vm)? {
count += 1;
@@ -1035,15 +1035,15 @@ pub mod array {
}
#[pymethod]
fn tounicode(&self, vm: &VirtualMachine) -> PyResult<Wtf8Buf> {
let array = self.array.read();
fn tounicode(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<Wtf8Buf> {
let array = zelf.array.read();
if !matches!(array.typecode(), 'u' | 'w') {
return Err(vm.new_value_error(
"tounicode() may only be called on unicode type arrays ('u' or 'w')",
));
}
let bytes = array.get_bytes();
Self::_wchar_bytes_to_string(bytes, self.itemsize(), vm)
Self::_wchar_bytes_to_string(bytes, Self::itemsize(zelf), vm)
}
fn _from_bytes(&self, b: &[u8], itemsize: usize, vm: &VirtualMachine) -> PyResult<()> {
@@ -1057,20 +1057,25 @@ pub mod array {
}
#[pymethod]
fn frombytes(&self, buffer: ArgBytesLike, vm: &VirtualMachine) -> PyResult<()> {
fn frombytes(zelf: &Py<Self>, buffer: ArgBytesLike, vm: &VirtualMachine) -> PyResult<()> {
// The source is read as bytes, so items of any other width would
// be reinterpreted rather than appended.
if buffer.itemsize() != 1 {
return Err(vm.new_type_error("a bytes-like object is required"));
}
let buffer = buffer.borrow_buf();
let itemsize = self.read().itemsize();
self._from_bytes(&buffer, itemsize, vm)
let itemsize = zelf.read().itemsize();
zelf._from_bytes(&buffer, itemsize, vm)
}
#[pymethod]
fn fromfile(&self, f: PyObjectRef, n: isize, vm: &VirtualMachine) -> PyResult<()> {
let itemsize = self.itemsize();
fn fromfile(
zelf: &Py<Self>,
f: PyObjectRef,
n: isize,
vm: &VirtualMachine,
) -> PyResult<()> {
let itemsize = Self::itemsize(zelf);
if n < 0 {
return Err(vm.new_value_error("negative count"));
}
@@ -1084,7 +1089,7 @@ pub mod array {
let not_enough_bytes = b.as_bytes().len() != n_bytes;
self._from_bytes(b.as_bytes(), itemsize, vm)?;
zelf._from_bytes(b.as_bytes(), itemsize, vm)?;
if not_enough_bytes {
Err(vm.new_eof_error("read() didn't return enough bytes"))
@@ -1094,18 +1099,18 @@ pub mod array {
}
#[pymethod]
fn byteswap(&self) {
self.write().byteswap();
fn byteswap(zelf: &Py<Self>) {
zelf.write().byteswap();
}
#[pymethod]
fn index(
&self,
zelf: &Py<Self>,
v: PyObjectRef,
ArrayIndexArgs { start, stop }: ArrayIndexArgs,
vm: &VirtualMachine,
) -> PyResult<usize> {
let len = self.__len__();
let len = zelf.__len__();
let bound = |value: ArgIndex| {
let value = value.as_ref().as_bigint();
value.saturated_at(if value.is_negative() {
@@ -1116,7 +1121,7 @@ pub mod array {
};
let start = start.map_or(0, bound);
let stop = stop.map_or(isize::MAX as usize, bound);
self.find(&v, start, stop, vm)?
zelf.find(&v, start, stop, vm)?
.ok_or_else(|| vm.new_value_error("array.index(x): x not in array"))
}
@@ -1139,18 +1144,18 @@ pub mod array {
}
#[pymethod]
pub(crate) fn tobytes(&self) -> Vec<u8> {
self.read().get_bytes().to_vec()
pub(crate) fn tobytes(zelf: &Py<Self>) -> Vec<u8> {
zelf.read().get_bytes().to_vec()
}
#[pymethod]
fn tofile(&self, f: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
fn tofile(zelf: &Py<Self>, f: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
/* Write 64K blocks at a time */
/* XXX Make the block size settable */
const BLOCKSIZE: usize = 64 * 1024;
let bytes = {
let bytes = self.read();
let bytes = zelf.read();
bytes.get_bytes().to_vec()
};
@@ -1170,8 +1175,8 @@ pub mod array {
}
#[pymethod]
fn tolist(&self, vm: &VirtualMachine) -> PyResult<Vec<PyObjectRef>> {
let array = self.read();
fn tolist(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<Vec<PyObjectRef>> {
let array = zelf.read();
let mut v = Vec::with_capacity(array.len());
for obj in array.iter(vm) {
v.push(obj?);
@@ -1185,18 +1190,18 @@ pub mod array {
}
#[pymethod]
fn reverse(&self) {
self.write().reverse()
fn reverse(zelf: &Py<Self>) {
zelf.write().reverse()
}
#[pymethod]
fn __copy__(&self) -> Self {
self.array.read().clone().into()
fn __copy__(zelf: &Py<Self>) -> Self {
zelf.array.read().clone().into()
}
#[pymethod]
fn __deepcopy__(&self, _unused: PyObjectRef) -> Self {
self.__copy__()
fn __deepcopy__(zelf: &Py<Self>, _unused: PyObjectRef) -> Self {
Self::__copy__(zelf)
}
fn getitem_inner(&self, needle: &PyObject, vm: &VirtualMachine) -> PyResult {
@@ -1503,7 +1508,7 @@ pub mod array {
if zelf.__len__() == 0 {
return Ok(format!("{class_name}('{typecode}')"));
}
let to_unicode = zelf.tounicode(vm)?;
let to_unicode = Self::tounicode(zelf, vm)?;
let escape = crate::vm::literal::escape::UnicodeEscape::new_repr(&to_unicode);
return Ok(format!("{class_name}('{typecode}', {})", escape.str_repr()));
}
@@ -1630,16 +1635,16 @@ pub mod array {
#[pyclass(with(IterNext, Iterable), flags(HAS_DICT, DISALLOW_INSTANTIATION))]
impl PyArrayIter {
#[pymethod]
fn __setstate__(&self, state: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
self.internal
fn __setstate__(zelf: &Py<Self>, state: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
zelf.internal
.lock()
.set_state(&state, |obj, pos| pos.min(obj.__len__()), vm)
}
#[pymethod]
fn __reduce__(&self, vm: &VirtualMachine) -> PyResult<PyTupleRef> {
fn __reduce__(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyTupleRef> {
let func = builtins_iter(vm)?;
Ok(self.internal.lock().reduce(
Ok(zelf.internal.lock().reduce(
func,
|x| x.clone().into(),
|vm| vm.ctx.empty_tuple.clone().into(),
+28 -28
View File
@@ -157,39 +157,39 @@ mod _blake2 {
}
#[pygetset]
fn name(&self) -> &'static str {
self.inner.name()
fn name(zelf: &Py<Self>) -> &'static str {
zelf.inner.name()
}
#[pygetset]
fn digest_size(&self) -> usize {
self.inner.digest_size()
fn digest_size(zelf: &Py<Self>) -> usize {
zelf.inner.digest_size()
}
#[pygetset]
fn block_size(&self) -> usize {
self.inner.block_size()
fn block_size(zelf: &Py<Self>) -> usize {
zelf.inner.block_size()
}
#[pymethod]
fn update(&self, data: ArgBytesLike) {
data.with_ref(|bytes| self.inner.update(bytes));
fn update(zelf: &Py<Self>, data: ArgBytesLike) {
data.with_ref(|bytes| zelf.inner.update(bytes));
}
#[pymethod]
fn digest(&self) -> PyBytes {
self.inner.digest().into()
fn digest(zelf: &Py<Self>) -> PyBytes {
zelf.inner.digest().into()
}
#[pymethod]
fn hexdigest(&self) -> String {
self.inner.hexdigest()
fn hexdigest(zelf: &Py<Self>) -> String {
zelf.inner.hexdigest()
}
#[pymethod]
fn copy(&self) -> Self {
fn copy(zelf: &Py<Self>) -> Self {
Self {
inner: self.inner.copy(),
inner: zelf.inner.copy(),
}
}
}
@@ -254,39 +254,39 @@ mod _blake2 {
}
#[pygetset]
fn name(&self) -> &'static str {
self.inner.name()
fn name(zelf: &Py<Self>) -> &'static str {
zelf.inner.name()
}
#[pygetset]
fn digest_size(&self) -> usize {
self.inner.digest_size()
fn digest_size(zelf: &Py<Self>) -> usize {
zelf.inner.digest_size()
}
#[pygetset]
fn block_size(&self) -> usize {
self.inner.block_size()
fn block_size(zelf: &Py<Self>) -> usize {
zelf.inner.block_size()
}
#[pymethod]
fn update(&self, data: ArgBytesLike) {
data.with_ref(|bytes| self.inner.update(bytes));
fn update(zelf: &Py<Self>, data: ArgBytesLike) {
data.with_ref(|bytes| zelf.inner.update(bytes));
}
#[pymethod]
fn digest(&self) -> PyBytes {
self.inner.digest().into()
fn digest(zelf: &Py<Self>) -> PyBytes {
zelf.inner.digest().into()
}
#[pymethod]
fn hexdigest(&self) -> String {
self.inner.hexdigest()
fn hexdigest(zelf: &Py<Self>) -> String {
zelf.inner.hexdigest()
}
#[pymethod]
fn copy(&self) -> Self {
fn copy(zelf: &Py<Self>) -> Self {
Self {
inner: self.inner.copy(),
inner: zelf.inner.copy(),
}
}
}
+16 -12
View File
@@ -74,11 +74,15 @@ mod _bz2 {
#[pyclass(with(Constructor))]
impl BZ2Decompressor {
#[pymethod]
fn decompress(&self, args: DecompressorArgs, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
fn decompress(
zelf: &Py<Self>,
args: DecompressorArgs,
vm: &VirtualMachine,
) -> PyResult<Vec<u8>> {
let max_length = args.max_length();
let data = &*args.data();
let mut inner = self.inner.lock();
let mut inner = zelf.inner.lock();
if inner.decompress.eof() {
return Err(vm.new_eof_error("End of stream already reached"));
}
@@ -86,23 +90,23 @@ mod _bz2 {
return Err(vm.new_value_error("Decompressor is unusable after a previous error"));
}
let result = inner.decompress.decompress(data, max_length);
self.eof.store(inner.decompress.eof(), Ordering::Relaxed);
self.needs_input
zelf.eof.store(inner.decompress.eof(), Ordering::Relaxed);
zelf.needs_input
.store(inner.decompress.needs_input(), Ordering::Relaxed);
let stale = self.unused_data.deref().is_none_or(|obj| {
let stale = zelf.unused_data.deref().is_none_or(|obj| {
obj.downcast_ref::<PyBytes>()
.is_none_or(|bytes| bytes.as_bytes() != inner.decompress.unused_data())
});
if stale {
let bytes = vm.ctx.new_bytes(inner.decompress.unused_data().to_vec());
// The previous bytes object is dropped after the slot is replaced.
let _previous = unsafe { self.unused_data.swap(Some(bytes.into())) };
let _previous = unsafe { zelf.unused_data.swap(Some(bytes.into())) };
}
result.map_err(|error| map_bz2_error(error, vm))
}
#[pymethod(name = "__reduce__")]
fn reduce(&self, vm: &VirtualMachine) -> PyResult<()> {
fn reduce(_zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
Err(vm.new_type_error("cannot pickle '_bz2.BZ2Decompressor' object"))
}
}
@@ -145,8 +149,8 @@ mod _bz2 {
#[pyclass(with(Constructor))]
impl BZ2Compressor {
#[pymethod]
fn compress(&self, data: ArgBytesLike, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
let mut compressor = self.state.lock();
fn compress(zelf: &Py<Self>, data: ArgBytesLike, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
let mut compressor = zelf.state.lock();
if compressor.is_flushed() {
return Err(vm.new_value_error("Compressor has been flushed"));
}
@@ -155,8 +159,8 @@ mod _bz2 {
}
#[pymethod]
fn flush(&self, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
let mut compressor = self.state.lock();
fn flush(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
let mut compressor = zelf.state.lock();
if compressor.is_flushed() {
return Err(vm.new_value_error("Repeated call to flush()"));
}
@@ -164,7 +168,7 @@ mod _bz2 {
}
#[pymethod(name = "__reduce__")]
fn reduce(&self, vm: &VirtualMachine) -> PyResult<()> {
fn reduce(_zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
Err(vm.new_type_error("cannot pickle '_bz2.BZ2Compressor' object"))
}
}
+74 -66
View File
@@ -557,18 +557,18 @@ mod _multibytecodec {
#[pyclass(flags(DISALLOW_INSTANTIATION, IMMUTABLETYPE))]
impl MultibyteCodec {
#[pymethod]
fn encode(&self, args: CodecEncodeArgs, vm: &VirtualMachine) -> PyResult {
fn encode(zelf: &Py<Self>, args: CodecEncodeArgs, vm: &VirtualMachine) -> PyResult {
let CodecEncodeArgs { input, errors } = args;
let input = to_text(input, vm)?;
let chars = input.char_len();
let errors = ErrorHandler::new(errors);
let mut state = cjk::initial_state(self.codec.codec, false);
let (out, _) = encode(self.codec, &mut state, input, &errors, true, true, vm)?;
let mut state = cjk::initial_state(zelf.codec.codec, false);
let (out, _) = encode(zelf.codec, &mut state, input, &errors, true, true, vm)?;
Ok(vm.new_tuple((vm.ctx.new_bytes(out), chars)).into())
}
#[pymethod]
fn decode(&self, args: CodecDecodeArgs, vm: &VirtualMachine) -> PyResult {
fn decode(zelf: &Py<Self>, args: CodecDecodeArgs, vm: &VirtualMachine) -> PyResult {
let CodecDecodeArgs { input, errors } = args;
let data = input.borrow_buf().to_vec();
let len = data.len();
@@ -576,14 +576,14 @@ mod _multibytecodec {
return Ok(vm.new_tuple((vm.ctx.new_str(""), 0)).into());
}
let errors = ErrorHandler::new(errors);
let mut state = cjk::initial_state(self.codec.codec, true);
let mut state = cjk::initial_state(zelf.codec.codec, true);
let mut buf = DecodeBuffer {
data,
pos: 0,
out: Wtf8Buf::new(),
exception: None,
};
decode_into(self.codec, &mut state, &mut buf, &errors, false, vm)?;
decode_into(zelf.codec, &mut state, &mut buf, &errors, false, vm)?;
Ok(vm.new_tuple((vm.ctx.new_str(buf.out), len)).into())
}
}
@@ -733,33 +733,33 @@ mod _multibytecodec {
#[pyclass(with(Constructor, Initializer), flags(BASETYPE))]
impl MultibyteIncrementalEncoder {
#[pygetset]
fn errors(&self, vm: &VirtualMachine) -> PyStrRef {
self.inner.lock().errors.name(vm)
fn errors(zelf: &Py<Self>, vm: &VirtualMachine) -> PyStrRef {
zelf.inner.lock().errors.name(vm)
}
#[pygetset(setter)]
fn set_errors(
&self,
zelf: &Py<Self>,
value: PySetterValue<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<()> {
self.inner.lock().errors = set_errors(value, vm)?;
zelf.inner.lock().errors = set_errors(value, vm)?;
Ok(())
}
#[pymethod]
fn encode(
&self,
zelf: &Py<Self>,
args: IncrementalEncodeArgs,
vm: &VirtualMachine,
) -> PyResult<PyObjectRef> {
let final_input = final_arg(args.final_input, vm)?;
// Driven on a detached copy: an error handler can re-enter this object.
let mut local = self.inner.lock().clone();
let result = self
let mut local = zelf.inner.lock().clone();
let result = zelf
.codec
.encode_stateful(&mut local, args.input, final_input, vm);
self.commit(local);
zelf.commit(local);
Ok(vm.ctx.new_bytes(result?).into())
}
@@ -770,15 +770,15 @@ mod _multibytecodec {
}
#[pymethod]
fn getstate(&self, vm: &VirtualMachine) -> PyResult<BigInt> {
let inner = self.inner.lock();
fn getstate(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<BigInt> {
let inner = zelf.inner.lock();
let mut statebytes = Vec::with_capacity(ENCODER_STATE_SIZE);
match &inner.pending {
Some(pending) => {
let bytes = pending.as_wtf8().as_bytes();
if bytes.len() > MAXENCPENDING * 4 {
return Err(vm.new_unicode_encode_error(
vm.ctx.new_str(self.codec.encoding),
vm.ctx.new_str(zelf.codec.encoding),
pending.clone(),
0,
pending.char_len(),
@@ -795,7 +795,7 @@ mod _multibytecodec {
}
#[pymethod]
fn setstate(&self, state: PyRef<PyInt>, vm: &VirtualMachine) -> PyResult<()> {
fn setstate(zelf: &Py<Self>, state: PyRef<PyInt>, vm: &VirtualMachine) -> PyResult<()> {
let statebytes = int_to_state(&state, ENCODER_STATE_SIZE, vm)?;
let pending_size = statebytes[0] as usize;
if pending_size > MAXENCPENDING * 4 {
@@ -813,7 +813,7 @@ mod _multibytecodec {
vm,
)?;
let mut inner = self.inner.lock();
let mut inner = zelf.inner.lock();
inner.pending = (!pending.is_empty()).then_some(pending);
inner
.state
@@ -822,9 +822,9 @@ mod _multibytecodec {
}
#[pymethod]
fn reset(&self) {
let mut inner = self.inner.lock();
let _ = cjk::encode_reset(self.codec.codec, &mut inner.state);
fn reset(zelf: &Py<Self>) {
let mut inner = zelf.inner.lock();
let _ = cjk::encode_reset(zelf.codec.codec, &mut inner.state);
inner.pending = None;
}
}
@@ -864,25 +864,29 @@ mod _multibytecodec {
#[pyclass(with(Constructor, Initializer), flags(BASETYPE))]
impl MultibyteIncrementalDecoder {
#[pygetset]
fn errors(&self, vm: &VirtualMachine) -> PyStrRef {
self.inner.lock().errors.name(vm)
fn errors(zelf: &Py<Self>, vm: &VirtualMachine) -> PyStrRef {
zelf.inner.lock().errors.name(vm)
}
#[pygetset(setter)]
fn set_errors(
&self,
zelf: &Py<Self>,
value: PySetterValue<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<()> {
self.inner.lock().errors = set_errors(value, vm)?;
zelf.inner.lock().errors = set_errors(value, vm)?;
Ok(())
}
#[pymethod]
fn decode(&self, args: IncrementalDecodeArgs, vm: &VirtualMachine) -> PyResult<PyStrRef> {
fn decode(
zelf: &Py<Self>,
args: IncrementalDecodeArgs,
vm: &VirtualMachine,
) -> PyResult<PyStrRef> {
let final_input = final_arg(args.final_input, vm)?;
// Driven on a detached copy: an error handler can re-enter this object.
let mut local = self.inner.lock().clone();
let mut local = zelf.inner.lock().clone();
let original_pending = core::mem::take(&mut local.pending);
let mut data = original_pending.clone();
data.extend_from_slice(&args.input.borrow_buf());
@@ -895,23 +899,23 @@ mod _multibytecodec {
let errors = local.errors.clone();
let mut error = None;
if let Err(e) = decode_into(self.codec, &mut local.state, &mut buf, &errors, true, vm) {
if let Err(e) = decode_into(zelf.codec, &mut local.state, &mut buf, &errors, true, vm) {
error = Some(e);
} else if final_input
&& buf.pos < buf.data.len()
&& let Err(e) = decode_incomplete(self.codec.encoding, &mut buf, &errors, vm)
&& let Err(e) = decode_incomplete(zelf.codec.encoding, &mut buf, &errors, vm)
{
// Only the final flush hands the caller its pending bytes back.
local.pending = original_pending;
error = Some(e);
} else if buf.pos < buf.data.len()
&& let Err(e) = self.codec.append_pending(&mut local, &buf, vm)
&& let Err(e) = zelf.codec.append_pending(&mut local, &buf, vm)
{
error = Some(e);
}
{
let mut inner = self.inner.lock();
let mut inner = zelf.inner.lock();
inner.state = local.state;
inner.pending = local.pending;
}
@@ -922,8 +926,8 @@ mod _multibytecodec {
}
#[pymethod]
fn getstate(&self, vm: &VirtualMachine) -> (PyObjectRef, BigInt) {
let inner = self.inner.lock();
fn getstate(zelf: &Py<Self>, vm: &VirtualMachine) -> (PyObjectRef, BigInt) {
let inner = zelf.inner.lock();
(
vm.ctx.new_bytes(inner.pending.clone()).into(),
state_to_int(&inner.state),
@@ -931,7 +935,7 @@ mod _multibytecodec {
}
#[pymethod]
fn setstate(&self, state: PyRef<PyTuple>, vm: &VirtualMachine) -> PyResult<()> {
fn setstate(zelf: &Py<Self>, state: PyRef<PyTuple>, vm: &VirtualMachine) -> PyResult<()> {
let [buffer, flags] = state.as_slice() else {
return Err(vm.new_type_error("setstate(): illegal state argument"));
};
@@ -946,7 +950,7 @@ mod _multibytecodec {
let pending = buffer.as_bytes();
if pending.len() > MAXDECPENDING {
return Err(vm.new_unicode_decode_error(
vm.ctx.new_str(self.codec.encoding),
vm.ctx.new_str(zelf.codec.encoding),
buffer.to_owned(),
0,
pending.len(),
@@ -954,16 +958,16 @@ mod _multibytecodec {
));
}
let mut inner = self.inner.lock();
let mut inner = zelf.inner.lock();
inner.pending = pending.to_vec();
inner.state.copy_from_slice(&statebytes);
Ok(())
}
#[pymethod]
fn reset(&self) {
let mut inner = self.inner.lock();
cjk::decode_reset(self.codec.codec, &mut inner.state);
fn reset(zelf: &Py<Self>) {
let mut inner = zelf.inner.lock();
cjk::decode_reset(zelf.codec.codec, &mut inner.state);
inner.pending.clear();
}
}
@@ -1008,17 +1012,17 @@ mod _multibytecodec {
#[pyclass(with(Constructor, Initializer), flags(BASETYPE))]
impl MultibyteStreamReader {
#[pygetset]
fn errors(&self, vm: &VirtualMachine) -> PyStrRef {
self.inner.lock().errors.name(vm)
fn errors(zelf: &Py<Self>, vm: &VirtualMachine) -> PyStrRef {
zelf.inner.lock().errors.name(vm)
}
#[pygetset(setter)]
fn set_errors(
&self,
zelf: &Py<Self>,
value: PySetterValue<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<()> {
self.inner.lock().errors = set_errors(value, vm)?;
zelf.inner.lock().errors = set_errors(value, vm)?;
Ok(())
}
@@ -1098,28 +1102,32 @@ mod _multibytecodec {
}
#[pymethod]
fn read(&self, args: StreamReadArgs, vm: &VirtualMachine) -> PyResult<PyStrRef> {
fn read(zelf: &Py<Self>, args: StreamReadArgs, vm: &VirtualMachine) -> PyResult<PyStrRef> {
let size = size_hint(args.sizeobj, vm)?;
Ok(vm.ctx.new_str(self.iread("read", size, vm)?))
Ok(vm.ctx.new_str(zelf.iread("read", size, vm)?))
}
#[pymethod]
fn readline(&self, args: StreamReadArgs, vm: &VirtualMachine) -> PyResult<PyStrRef> {
fn readline(
zelf: &Py<Self>,
args: StreamReadArgs,
vm: &VirtualMachine,
) -> PyResult<PyStrRef> {
let size = size_hint(args.sizeobj, vm)?;
Ok(vm.ctx.new_str(self.iread("readline", size, vm)?))
Ok(vm.ctx.new_str(zelf.iread("readline", size, vm)?))
}
#[pymethod]
fn readlines(&self, args: StreamReadLinesArgs, vm: &VirtualMachine) -> PyResult {
fn readlines(zelf: &Py<Self>, args: StreamReadLinesArgs, vm: &VirtualMachine) -> PyResult {
let size = size_hint(args.sizehintobj, vm)?;
let text = vm.ctx.new_str(self.iread("read", size, vm)?);
let text = vm.ctx.new_str(zelf.iread("read", size, vm)?);
vm.call_method(text.as_object(), "splitlines", (true,))
}
#[pymethod]
fn reset(&self) {
let mut inner = self.inner.lock();
cjk::decode_reset(self.codec.codec, &mut inner.state);
fn reset(zelf: &Py<Self>) {
let mut inner = zelf.inner.lock();
cjk::decode_reset(zelf.codec.codec, &mut inner.state);
inner.pending.clear();
}
}
@@ -1164,17 +1172,17 @@ mod _multibytecodec {
#[pyclass(with(Constructor, Initializer), flags(BASETYPE))]
impl MultibyteStreamWriter {
#[pygetset]
fn errors(&self, vm: &VirtualMachine) -> PyStrRef {
self.inner.lock().errors.name(vm)
fn errors(zelf: &Py<Self>, vm: &VirtualMachine) -> PyStrRef {
zelf.inner.lock().errors.name(vm)
}
#[pygetset(setter)]
fn set_errors(
&self,
zelf: &Py<Self>,
value: PySetterValue<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<()> {
self.inner.lock().errors = set_errors(value, vm)?;
zelf.inner.lock().errors = set_errors(value, vm)?;
Ok(())
}
@@ -1196,12 +1204,12 @@ mod _multibytecodec {
}
#[pymethod]
fn write(&self, strobj: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
self.iwrite(strobj, vm)
fn write(zelf: &Py<Self>, strobj: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
zelf.iwrite(strobj, vm)
}
#[pymethod]
fn writelines(&self, lines: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
fn writelines(zelf: &Py<Self>, lines: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
let sequence = PySequence { obj: &lines };
if !sequence.check() {
return Err(vm.new_type_error("arg must be a sequence object"));
@@ -1209,22 +1217,22 @@ mod _multibytecodec {
let mut i = 0;
while i < sequence.length(vm)? {
let line = sequence.get_item(i as isize, vm)?;
self.iwrite(line, vm)?;
zelf.iwrite(line, vm)?;
i += 1;
}
Ok(())
}
#[pymethod]
fn reset(&self, vm: &VirtualMachine) -> PyResult<()> {
let mut local = self.inner.lock().clone();
fn reset(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
let mut local = zelf.inner.lock().clone();
let Some(pending) = local.pending.take() else {
return Ok(());
};
let errors = local.errors.clone();
// A strict failure drops the pending text: reset exists to clear it.
let result = encode(
self.codec,
zelf.codec,
&mut local.state,
pending,
&errors,
@@ -1232,10 +1240,10 @@ mod _multibytecodec {
true,
vm,
);
self.commit(local);
zelf.commit(local);
let encoded = result?.0;
if !encoded.is_empty() {
vm.call_method(&self.stream, "write", (vm.ctx.new_bytes(encoded),))?;
vm.call_method(&zelf.stream, "write", (vm.ctx.new_bytes(encoded),))?;
}
Ok(())
}
+13 -9
View File
@@ -185,10 +185,10 @@ mod _contextvars {
}
#[pymethod]
fn copy(&self, vm: &VirtualMachine) -> Self {
fn copy(zelf: &Py<Self>, vm: &VirtualMachine) -> Self {
// Deep copy the vars - clone the underlying Hamt data, not just the PyRef
let vars_copy = HamtObject {
hamt: PyMutex::new(self.inner.vars.hamt.lock().clone()),
hamt: PyMutex::new(zelf.inner.vars.hamt.lock().clone()),
};
Self {
inner: ContextInner {
@@ -213,9 +213,13 @@ mod _contextvars {
}
#[pymethod]
fn get(&self, args: ContextGetArgs, vm: &VirtualMachine) -> PyResult<Option<PyObjectRef>> {
fn get(
zelf: &Py<Self>,
args: ContextGetArgs,
vm: &VirtualMachine,
) -> PyResult<Option<PyObjectRef>> {
let key = context_check_key_type(&args.key, vm)?;
let found = self.get_inner(key);
let found = zelf.get_inner(key);
if found.is_some() {
Ok(found)
} else {
@@ -618,13 +622,13 @@ mod _contextvars {
#[pyclass(with(Constructor, Representable))]
impl ContextToken {
#[pygetset]
fn var(&self, _vm: &VirtualMachine) -> PyRef<ContextVar> {
self.var.clone()
fn var(zelf: &Py<Self>, _vm: &VirtualMachine) -> PyRef<ContextVar> {
zelf.var.clone()
}
#[pygetset]
fn old_value(&self, _vm: &VirtualMachine) -> PyObjectRef {
match &self.old_value {
fn old_value(zelf: &Py<Self>, _vm: &VirtualMachine) -> PyObjectRef {
match &zelf.old_value {
Some(value) => value.clone(),
None => ContextTokenMissing::static_type().to_owned().into(),
}
@@ -700,7 +704,7 @@ mod _contextvars {
#[pyfunction]
fn copy_context(vm: &VirtualMachine) -> PyContext {
PyContext::current(vm).copy(vm)
PyContext::copy(&PyContext::current(vm), vm)
}
// Set Token.MISSING attribute
+42 -42
View File
@@ -100,43 +100,43 @@ mod _csv {
#[pyclass(with(Constructor))]
impl PyDialect {
#[pygetset]
fn delimiter(&self, vm: &VirtualMachine) -> PyRef<PyStr> {
vm.ctx.new_str(format!("{}", self.delimiter as char))
fn delimiter(zelf: &Py<Self>, vm: &VirtualMachine) -> PyRef<PyStr> {
vm.ctx.new_str(format!("{}", zelf.delimiter as char))
}
#[pygetset]
fn quotechar(&self, vm: &VirtualMachine) -> Option<PyRef<PyStr>> {
Some(vm.ctx.new_str(format!("{}", self.quotechar? as char)))
fn quotechar(zelf: &Py<Self>, vm: &VirtualMachine) -> Option<PyRef<PyStr>> {
Some(vm.ctx.new_str(format!("{}", zelf.quotechar? as char)))
}
#[pygetset]
const fn doublequote(&self) -> bool {
self.doublequote
fn doublequote(zelf: &Py<Self>) -> bool {
zelf.doublequote
}
#[pygetset]
const fn skipinitialspace(&self) -> bool {
self.skipinitialspace
fn skipinitialspace(zelf: &Py<Self>) -> bool {
zelf.skipinitialspace
}
#[pygetset]
fn lineterminator(&self, vm: &VirtualMachine) -> PyRef<PyStr> {
vm.ctx.new_str(self.lineterminator.clone())
fn lineterminator(zelf: &Py<Self>, vm: &VirtualMachine) -> PyRef<PyStr> {
vm.ctx.new_str(zelf.lineterminator.clone())
}
#[pygetset]
fn quoting(&self) -> isize {
self.quoting.into()
fn quoting(zelf: &Py<Self>) -> isize {
zelf.quoting.into()
}
#[pygetset]
fn escapechar(&self, vm: &VirtualMachine) -> Option<PyRef<PyStr>> {
Some(vm.ctx.new_str(format!("{}", self.escapechar? as char)))
fn escapechar(zelf: &Py<Self>, vm: &VirtualMachine) -> Option<PyRef<PyStr>> {
Some(vm.ctx.new_str(format!("{}", zelf.escapechar? as char)))
}
#[pygetset(name = "strict")]
const fn get_strict(&self) -> bool {
self.strict
fn get_strict(zelf: &Py<Self>) -> bool {
zelf.strict
}
}
@@ -831,13 +831,13 @@ mod _csv {
#[pyclass(with(IterNext, Iterable), flags(DISALLOW_INSTANTIATION))]
impl Reader {
#[pygetset]
fn line_num(&self) -> u64 {
self.state.lock().line_num
fn line_num(zelf: &Py<Self>) -> u64 {
zelf.state.lock().line_num
}
#[pygetset]
fn dialect(&self, _vm: &VirtualMachine) -> PyDialect {
self.dialect.clone()
fn dialect(zelf: &Py<Self>, _vm: &VirtualMachine) -> PyDialect {
zelf.dialect.clone()
}
}
@@ -1267,13 +1267,13 @@ mod _csv {
#[pyclass(flags(DISALLOW_INSTANTIATION))]
impl Writer {
#[pygetset(name = "dialect")]
fn get_dialect(&self, _vm: &VirtualMachine) -> PyDialect {
self.dialect.clone()
fn get_dialect(zelf: &Py<Self>, _vm: &VirtualMachine) -> PyDialect {
zelf.dialect.clone()
}
#[pymethod]
fn writerow(&self, row: PyObjectRef, vm: &VirtualMachine) -> PyResult {
let _state = self.state.lock();
fn writerow(zelf: &Py<Self>, row: PyObjectRef, vm: &VirtualMachine) -> PyResult {
let _state = zelf.state.lock();
let row: ArgIterable =
ArgIterable::try_from_object(vm, row.to_owned()).map_err(|_e| {
new_csv_error(
@@ -1287,7 +1287,7 @@ mod _csv {
for (index, field) in fields.into_iter().enumerate() {
if index > 0 {
output.push(self.dialect.delimiter);
output.push(zelf.dialect.delimiter);
}
let stringified;
@@ -1302,10 +1302,10 @@ mod _csv {
if single_field
&& data.is_empty()
&& (self.dialect.quoting == QuoteStyle::None
&& (zelf.dialect.quoting == QuoteStyle::None
|| (is_none
&& matches!(
self.dialect.quoting,
zelf.dialect.quoting,
QuoteStyle::Strings | QuoteStyle::Notnull
)))
{
@@ -1316,12 +1316,12 @@ mod _csv {
}
if data.is_empty()
&& self.dialect.delimiter == b' '
&& self.dialect.skipinitialspace
&& (self.dialect.quoting == QuoteStyle::None
&& zelf.dialect.delimiter == b' '
&& zelf.dialect.skipinitialspace
&& (zelf.dialect.quoting == QuoteStyle::None
|| (is_none
&& matches!(
self.dialect.quoting,
zelf.dialect.quoting,
QuoteStyle::Strings | QuoteStyle::Notnull
)))
{
@@ -1331,7 +1331,7 @@ mod _csv {
));
}
let mut should_quote = match self.dialect.quoting {
let mut should_quote = match zelf.dialect.quoting {
QuoteStyle::All => true,
QuoteStyle::Nonnumeric => !PyNumber::check(&field),
QuoteStyle::Strings => is_str,
@@ -1339,33 +1339,33 @@ mod _csv {
QuoteStyle::Minimal | QuoteStyle::None => false,
};
if self.dialect.quoting != QuoteStyle::None
if zelf.dialect.quoting != QuoteStyle::None
&& ((data.is_empty()
&& self.dialect.delimiter == b' '
&& self.dialect.skipinitialspace)
&& zelf.dialect.delimiter == b' '
&& zelf.dialect.skipinitialspace)
|| (single_field && data.is_empty())
|| (!should_quote && field_needs_quotes(data, &self.dialect)))
|| (!should_quote && field_needs_quotes(data, &zelf.dialect)))
{
should_quote = true;
}
if should_quote {
write_quoted_field(&mut output, data, &self.dialect, vm)?;
write_quoted_field(&mut output, data, &zelf.dialect, vm)?;
} else {
write_unquoted_field(&mut output, data, &self.dialect, vm)?;
write_unquoted_field(&mut output, data, &zelf.dialect, vm)?;
}
}
write_lineterminator(&mut output, &self.dialect.lineterminator);
write_lineterminator(&mut output, &zelf.dialect.lineterminator);
let s =
core::str::from_utf8(&output).map_err(|e| new_not_utf8_error(vm, &output, e))?;
self.write.call((s,), vm)
zelf.write.call((s,), vm)
}
#[pymethod]
fn writerows(&self, rows: ArgIterable, vm: &VirtualMachine) -> PyResult<()> {
fn writerows(zelf: &Py<Self>, rows: ArgIterable, vm: &VirtualMachine) -> PyResult<()> {
for row in rows.iter(vm)? {
self.writerow(row?, vm)?;
Self::writerow(zelf, row?, vm)?;
}
Ok(())
}
+75 -65
View File
@@ -486,85 +486,85 @@ pub(crate) mod _elementtree {
)]
impl PyElement {
#[pygetset]
fn tag(&self) -> PyObjectRef {
self.inner.read().tag.clone()
fn tag(zelf: &Py<Self>) -> PyObjectRef {
zelf.inner.read().tag.clone()
}
#[pygetset(setter)]
fn set_tag(&self, value: PySetterValue, vm: &VirtualMachine) -> PyResult<()> {
fn set_tag(zelf: &Py<Self>, value: PySetterValue, vm: &VirtualMachine) -> PyResult<()> {
let value = setter_value(value, vm)?;
// Whatever is replaced may run __del__ on drop, and that code is
// free to touch this very element, so it must not be dropped
// while the lock is held (test_bpo_31728).
let _recycle = core::mem::replace(&mut self.inner.write().tag, value);
let _recycle = core::mem::replace(&mut zelf.inner.write().tag, value);
Ok(())
}
#[pygetset]
fn text(&self, vm: &VirtualMachine) -> PyResult {
self.joined_get(false, vm)
fn text(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
zelf.joined_get(false, vm)
}
#[pygetset(setter)]
fn set_text(&self, value: PySetterValue, vm: &VirtualMachine) -> PyResult<()> {
fn set_text(zelf: &Py<Self>, value: PySetterValue, vm: &VirtualMachine) -> PyResult<()> {
let value = setter_value(value, vm)?;
let _recycle = core::mem::replace(&mut self.inner.write().text, Joined::plain(value));
let _recycle = core::mem::replace(&mut zelf.inner.write().text, Joined::plain(value));
Ok(())
}
#[pygetset]
fn tail(&self, vm: &VirtualMachine) -> PyResult {
self.joined_get(true, vm)
fn tail(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
zelf.joined_get(true, vm)
}
#[pygetset(setter)]
fn set_tail(&self, value: PySetterValue, vm: &VirtualMachine) -> PyResult<()> {
fn set_tail(zelf: &Py<Self>, value: PySetterValue, vm: &VirtualMachine) -> PyResult<()> {
let value = setter_value(value, vm)?;
let _recycle = core::mem::replace(&mut self.inner.write().tail, Joined::plain(value));
let _recycle = core::mem::replace(&mut zelf.inner.write().tail, Joined::plain(value));
Ok(())
}
#[pygetset]
fn attrib(&self, vm: &VirtualMachine) -> PyDictRef {
self.attrib_or_new(vm)
fn attrib(zelf: &Py<Self>, vm: &VirtualMachine) -> PyDictRef {
zelf.attrib_or_new(vm)
}
#[pygetset(setter)]
fn set_attrib(&self, value: PySetterValue, vm: &VirtualMachine) -> PyResult<()> {
fn set_attrib(zelf: &Py<Self>, value: PySetterValue, vm: &VirtualMachine) -> PyResult<()> {
let value = setter_value(value, vm)?;
let dict = value.downcast::<PyDict>().map_err(|obj| {
vm.new_type_error(format!("attrib must be dict, not {}", obj.class().name()))
})?;
let _recycle = self.inner.write().attrib.replace(dict);
let _recycle = zelf.inner.write().attrib.replace(dict);
Ok(())
}
#[pymethod]
fn append(&self, subelement: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
fn append(zelf: &Py<Self>, subelement: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
check_element(&subelement, vm)?;
self.inner.write().children.push(subelement);
zelf.inner.write().children.push(subelement);
Ok(())
}
#[pymethod]
fn extend(&self, elements: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
fn extend(zelf: &Py<Self>, elements: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
let items: Vec<PyObjectRef> = elements.try_to_value(vm)?;
for element in &items {
check_element(element, vm)?;
}
self.inner.write().children.extend(items);
zelf.inner.write().children.extend(items);
Ok(())
}
#[pymethod]
fn insert(
&self,
zelf: &Py<Self>,
index: isize,
subelement: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
check_element(&subelement, vm)?;
let mut inner = self.inner.write();
let mut inner = zelf.inner.write();
let len = inner.children.len();
let pos = if index < 0 {
let i = index + len as isize;
@@ -577,7 +577,7 @@ pub(crate) mod _elementtree {
}
#[pymethod]
fn remove(&self, subelement: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
fn remove(zelf: &Py<Self>, subelement: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
check_element(&subelement, vm)?;
// Identity first, then equality, the way `element_remove` does;
// the equality test can run arbitrary code, so the lock is
@@ -586,7 +586,7 @@ pub(crate) mod _elementtree {
let mut i = 0;
loop {
let child = {
let inner = self.inner.read();
let inner = zelf.inner.read();
match inner.children.get(i) {
Some(child) => child.clone(),
None => break,
@@ -606,16 +606,16 @@ pub(crate) mod _elementtree {
return Err(vm.new_value_error("Element.remove(x): element not found"));
};
let _recycle = {
let mut inner = self.inner.write();
let mut inner = zelf.inner.write();
(i < inner.children.len()).then(|| inner.children.remove(i))
};
Ok(())
}
#[pymethod]
fn clear(&self, vm: &VirtualMachine) {
fn clear(zelf: &Py<Self>, vm: &VirtualMachine) {
let _recycle = {
let mut inner = self.inner.write();
let mut inner = zelf.inner.write();
(
inner.attrib.take(),
core::mem::take(&mut inner.children),
@@ -626,31 +626,36 @@ pub(crate) mod _elementtree {
}
#[pymethod]
fn get(&self, args: GetArgs, vm: &VirtualMachine) -> PyResult {
fn get(zelf: &Py<Self>, args: GetArgs, vm: &VirtualMachine) -> PyResult {
let default = args.default.unwrap_or_else(|| vm.ctx.none());
let Some(attrib) = self.attrib_opt() else {
let Some(attrib) = zelf.attrib_opt() else {
return Ok(default);
};
Ok(attrib.get_item_opt(&*args.key, vm)?.unwrap_or(default))
}
#[pymethod]
fn set(&self, key: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
let attrib = self.attrib_or_new(vm);
fn set(
zelf: &Py<Self>,
key: PyObjectRef,
value: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
let attrib = zelf.attrib_or_new(vm);
attrib.set_item(&*key, value, vm)
}
#[pymethod]
fn keys(&self) -> Vec<PyObjectRef> {
let Some(attrib) = self.attrib_opt() else {
fn keys(zelf: &Py<Self>) -> Vec<PyObjectRef> {
let Some(attrib) = zelf.attrib_opt() else {
return vec![];
};
attrib.into_iter().map(|(k, _)| k).collect()
}
#[pymethod]
fn items(&self, vm: &VirtualMachine) -> Vec<PyObjectRef> {
let Some(attrib) = self.attrib_opt() else {
fn items(zelf: &Py<Self>, vm: &VirtualMachine) -> Vec<PyObjectRef> {
let Some(attrib) = zelf.attrib_opt() else {
return vec![];
};
attrib
@@ -825,8 +830,8 @@ pub(crate) mod _elementtree {
}
#[pymethod]
fn __getstate__(&self, vm: &VirtualMachine) -> PyResult<PyDictRef> {
let inner = self.inner.read();
fn __getstate__(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyDictRef> {
let inner = zelf.inner.read();
let children = vm.ctx.new_list(inner.children.clone());
let attrib = inner.attrib.clone().unwrap_or_else(|| vm.ctx.new_dict());
let text = inner.text.obj.clone();
@@ -843,7 +848,7 @@ pub(crate) mod _elementtree {
}
#[pymethod]
fn __setstate__(&self, state: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
fn __setstate__(zelf: &Py<Self>, state: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
let dict = state.downcast_ref::<PyDict>().ok_or_else(|| {
vm.new_type_error(format!(
"Don't know how to unpickle \"{}\" as an Element",
@@ -897,7 +902,7 @@ pub(crate) mod _elementtree {
None => Joined::plain(vm.ctx.none()),
};
let _recycle = {
let mut inner = self.inner.write();
let mut inner = zelf.inner.write();
let old_tag = core::mem::replace(&mut inner.tag, tag);
let old_text = core::mem::replace(&mut inner.text, new_text);
let old_tail = core::mem::replace(&mut inner.tail, new_tail);
@@ -1761,39 +1766,44 @@ pub(crate) mod _elementtree {
#[pyclass(with(Constructor, Initializer), flags(BASETYPE, HAS_WEAKREF))]
impl PyTreeBuilder {
#[pymethod]
fn start(&self, tag: PyObjectRef, attrs: PyObjectRef, vm: &VirtualMachine) -> PyResult {
fn start(
zelf: &Py<Self>,
tag: PyObjectRef,
attrs: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult {
let attrs = attrs.downcast::<PyDict>().map_err(|obj| {
vm.new_type_error(format!(
"start() argument 2 must be dict, not {}",
obj.class().name()
))
})?;
self.handle_start(tag, Some(attrs), vm)
zelf.handle_start(tag, Some(attrs), vm)
}
#[pymethod]
fn data(&self, data: PyObjectRef, vm: &VirtualMachine) {
self.handle_data(data, vm);
fn data(zelf: &Py<Self>, data: PyObjectRef, vm: &VirtualMachine) {
zelf.handle_data(data, vm);
}
#[pymethod]
fn end(&self, _tag: PyObjectRef, vm: &VirtualMachine) -> PyResult {
self.handle_end(vm)
fn end(zelf: &Py<Self>, _tag: PyObjectRef, vm: &VirtualMachine) -> PyResult {
zelf.handle_end(vm)
}
#[pymethod]
fn comment(&self, text: PyObjectRef, vm: &VirtualMachine) -> PyResult {
self.handle_comment(text, vm)
fn comment(zelf: &Py<Self>, text: PyObjectRef, vm: &VirtualMachine) -> PyResult {
zelf.handle_comment(text, vm)
}
#[pymethod]
fn pi(&self, args: PiArgs, vm: &VirtualMachine) -> PyResult {
self.handle_pi(args.target, args.text.unwrap_or_else(|| vm.ctx.none()), vm)
fn pi(zelf: &Py<Self>, args: PiArgs, vm: &VirtualMachine) -> PyResult {
zelf.handle_pi(args.target, args.text.unwrap_or_else(|| vm.ctx.none()), vm)
}
#[pymethod]
fn close(&self, vm: &VirtualMachine) -> PyObjectRef {
self.done(vm)
fn close(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.done(vm)
}
}
@@ -2136,7 +2146,7 @@ pub(crate) mod _elementtree {
#[pyclass(with(Constructor, Initializer), flags(BASETYPE, HAS_WEAKREF))]
impl PyXMLParser {
#[pygetset]
fn version(&self, vm: &VirtualMachine) -> PyResult<String> {
fn version(_zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
let expat = vm.import("pyexpat", 0)?;
let info: Vec<PyObjectRef> = expat.get_attr("version_info", vm)?.try_to_value(vm)?;
let part = |i: usize| -> String {
@@ -2148,17 +2158,17 @@ pub(crate) mod _elementtree {
}
#[pymethod]
fn feed(&self, data: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
self.expat_parse(data, false, vm)
fn feed(zelf: &Py<Self>, data: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
zelf.expat_parse(data, false, vm)
}
#[pymethod]
fn close(&self, vm: &VirtualMachine) -> PyResult {
self.expat_parse(vm.ctx.new_bytes(vec![]).into(), true, vm)?;
if let Some(builder) = self.native_target(vm) {
fn close(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
zelf.expat_parse(vm.ctx.new_bytes(vec![]).into(), true, vm)?;
if let Some(builder) = zelf.native_target(vm) {
return Ok(builder.done(vm));
}
let close = self.state.read().handle_close.clone();
let close = zelf.state.read().handle_close.clone();
match close {
Some(close) => close.call((), vm),
None => Ok(vm.ctx.none()),
@@ -2166,17 +2176,17 @@ pub(crate) mod _elementtree {
}
#[pymethod]
fn flush(&self, vm: &VirtualMachine) -> PyResult<()> {
fn flush(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
// This backend has no reparse deferral to turn off, so, like the
// C accelerator built against an expat without
// XML_SetReparseDeferralEnabled, there is nothing to flush.
self.check(vm)?;
zelf.check(vm)?;
Ok(())
}
#[pymethod]
fn _parse_whole(&self, file: PyObjectRef, vm: &VirtualMachine) -> PyResult {
self.check(vm)?;
fn _parse_whole(zelf: &Py<Self>, file: PyObjectRef, vm: &VirtualMachine) -> PyResult {
zelf.check(vm)?;
let read = file.get_attr("read", vm)?;
loop {
let buffer = read.call((64 * 1024,), vm)?;
@@ -2191,10 +2201,10 @@ pub(crate) mod _elementtree {
} else {
break;
}
self.expat_parse(buffer, false, vm)?;
zelf.expat_parse(buffer, false, vm)?;
}
self.expat_parse(vm.ctx.new_bytes(vec![]).into(), true, vm)?;
if let Some(builder) = self.native_target(vm) {
zelf.expat_parse(vm.ctx.new_bytes(vec![]).into(), true, vm)?;
if let Some(builder) = zelf.native_target(vm) {
return Ok(builder.done(vm));
}
Ok(vm.ctx.none())
+64 -60
View File
@@ -478,42 +478,42 @@ pub(crate) mod _hashlib {
}
#[pygetset]
fn name(&self) -> String {
format!("hmac-{}", self.algo_name)
fn name(zelf: &Py<Self>) -> String {
format!("hmac-{}", zelf.algo_name)
}
#[pygetset]
fn digest_size(&self) -> usize {
self.digest_size
fn digest_size(zelf: &Py<Self>) -> usize {
zelf.digest_size
}
#[pygetset]
fn block_size(&self) -> usize {
self.block_size
fn block_size(zelf: &Py<Self>) -> usize {
zelf.block_size
}
#[pymethod]
fn update(&self, args: HmacUpdateArgs) {
args.msg.with_ref(|bytes| self.ctx.update(bytes));
fn update(zelf: &Py<Self>, args: HmacUpdateArgs) {
args.msg.with_ref(|bytes| zelf.ctx.update(bytes));
}
#[pymethod]
fn digest(&self) -> PyBytes {
self.ctx.digest().into()
fn digest(zelf: &Py<Self>) -> PyBytes {
zelf.ctx.digest().into()
}
#[pymethod]
fn hexdigest(&self) -> String {
hex::encode(self.ctx.digest())
fn hexdigest(zelf: &Py<Self>) -> String {
hex::encode(zelf.ctx.digest())
}
#[pymethod]
fn copy(&self) -> Self {
fn copy(zelf: &Py<Self>) -> Self {
Self {
algo_name: self.algo_name.clone(),
digest_size: self.digest_size,
block_size: self.block_size,
ctx: self.ctx.copy(),
algo_name: zelf.algo_name.clone(),
digest_size: zelf.digest_size,
block_size: zelf.block_size,
ctx: zelf.ctx.copy(),
}
}
}
@@ -594,64 +594,64 @@ pub(crate) mod _hashlib {
}
#[pygetset]
fn name(&self) -> String {
self.name.clone()
fn name(zelf: &Py<Self>) -> String {
zelf.name.clone()
}
#[pygetset]
fn digest_size(&self) -> usize {
self.digest_size
fn digest_size(zelf: &Py<Self>) -> usize {
zelf.digest_size
}
#[pygetset]
fn block_size(&self) -> usize {
hasher_block_size(&self.name)
fn block_size(zelf: &Py<Self>) -> usize {
hasher_block_size(&zelf.name)
}
#[pygetset]
fn _capacity_bits(&self, vm: &VirtualMachine) -> PyResult<usize> {
let block_size = hasher_block_size(&self.name);
match keccak_capacity_bits(&self.name, block_size) {
fn _capacity_bits(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<usize> {
let block_size = hasher_block_size(&zelf.name);
match keccak_capacity_bits(&zelf.name, block_size) {
Some(capacity) => Ok(capacity),
None => missing_hash_attribute(vm, "HASH", "_capacity_bits"),
}
}
#[pygetset]
fn _rate_bits(&self, vm: &VirtualMachine) -> PyResult<usize> {
let block_size = hasher_block_size(&self.name);
match keccak_rate_bits(&self.name, block_size) {
fn _rate_bits(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<usize> {
let block_size = hasher_block_size(&zelf.name);
match keccak_rate_bits(&zelf.name, block_size) {
Some(rate) => Ok(rate),
None => missing_hash_attribute(vm, "HASH", "_rate_bits"),
}
}
#[pygetset]
fn _suffix(&self, vm: &VirtualMachine) -> PyResult<PyBytes> {
match keccak_suffix(&self.name) {
fn _suffix(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyBytes> {
match keccak_suffix(&zelf.name) {
Some(suffix) => Ok(vec![suffix].into()),
None => missing_hash_attribute(vm, "HASH", "_suffix"),
}
}
#[pymethod]
fn update(&self, obj: ArgBytesLike) {
obj.with_ref(|bytes| self.ctx.update(bytes));
fn update(zelf: &Py<Self>, obj: ArgBytesLike) {
obj.with_ref(|bytes| zelf.ctx.update(bytes));
}
#[pymethod]
fn digest(&self) -> PyBytes {
self.ctx.digest(self.digest_size).into()
fn digest(zelf: &Py<Self>) -> PyBytes {
zelf.ctx.digest(zelf.digest_size).into()
}
#[pymethod]
fn hexdigest(&self) -> String {
hex::encode(self.ctx.digest(self.digest_size))
fn hexdigest(zelf: &Py<Self>) -> String {
hex::encode(zelf.ctx.digest(zelf.digest_size))
}
#[pymethod]
fn copy(&self) -> Self {
Self::new(&self.name, self.ctx.copy(), self.digest_size)
fn copy(zelf: &Py<Self>) -> Self {
Self::new(&zelf.name, zelf.ctx.copy(), zelf.digest_size)
}
}
@@ -693,64 +693,68 @@ pub(crate) mod _hashlib {
}
#[pygetset]
fn name(&self) -> String {
self.name.clone()
fn name(zelf: &Py<Self>) -> String {
zelf.name.clone()
}
#[pygetset]
const fn digest_size(&self) -> usize {
fn digest_size(_zelf: &Py<Self>) -> usize {
0
}
#[pygetset]
fn block_size(&self) -> usize {
hasher_block_size(&self.name)
fn block_size(zelf: &Py<Self>) -> usize {
hasher_block_size(&zelf.name)
}
#[pygetset]
fn _capacity_bits(&self, vm: &VirtualMachine) -> PyResult<usize> {
let block_size = hasher_block_size(&self.name);
match keccak_capacity_bits(&self.name, block_size) {
fn _capacity_bits(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<usize> {
let block_size = hasher_block_size(&zelf.name);
match keccak_capacity_bits(&zelf.name, block_size) {
Some(capacity) => Ok(capacity),
None => missing_hash_attribute(vm, "HASHXOF", "_capacity_bits"),
}
}
#[pygetset]
fn _rate_bits(&self, vm: &VirtualMachine) -> PyResult<usize> {
let block_size = hasher_block_size(&self.name);
match keccak_rate_bits(&self.name, block_size) {
fn _rate_bits(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<usize> {
let block_size = hasher_block_size(&zelf.name);
match keccak_rate_bits(&zelf.name, block_size) {
Some(rate) => Ok(rate),
None => missing_hash_attribute(vm, "HASHXOF", "_rate_bits"),
}
}
#[pygetset]
fn _suffix(&self, vm: &VirtualMachine) -> PyResult<PyBytes> {
match keccak_suffix(&self.name) {
fn _suffix(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyBytes> {
match keccak_suffix(&zelf.name) {
Some(suffix) => Ok(vec![suffix].into()),
None => missing_hash_attribute(vm, "HASHXOF", "_suffix"),
}
}
#[pymethod]
fn update(&self, data: ArgBytesLike) {
data.with_ref(|bytes| self.ctx.update(bytes));
fn update(zelf: &Py<Self>, data: ArgBytesLike) {
data.with_ref(|bytes| zelf.ctx.update(bytes));
}
#[pymethod]
fn digest(&self, args: XofDigestArgs, vm: &VirtualMachine) -> PyResult<PyBytes> {
Ok(self.ctx.digest(args.length(vm)?).into())
fn digest(zelf: &Py<Self>, args: XofDigestArgs, vm: &VirtualMachine) -> PyResult<PyBytes> {
Ok(zelf.ctx.digest(args.length(vm)?).into())
}
#[pymethod]
fn hexdigest(&self, args: XofDigestArgs, vm: &VirtualMachine) -> PyResult<String> {
Ok(hex::encode(self.ctx.digest(args.length(vm)?)))
fn hexdigest(
zelf: &Py<Self>,
args: XofDigestArgs,
vm: &VirtualMachine,
) -> PyResult<String> {
Ok(hex::encode(zelf.ctx.digest(args.length(vm)?)))
}
#[pymethod]
fn copy(&self) -> Self {
Self::new(&self.name, self.ctx.copy())
fn copy(zelf: &Py<Self>) -> Self {
Self::new(&zelf.name, zelf.ctx.copy())
}
}
+15 -11
View File
@@ -334,22 +334,26 @@ mod _lzma {
#[pyclass(with(Constructor))]
impl LZMADecompressor {
#[pymethod]
fn decompress(&self, args: DecompressorArgs, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
fn decompress(
zelf: &Py<Self>,
args: DecompressorArgs,
vm: &VirtualMachine,
) -> PyResult<Vec<u8>> {
let max_length = args.max_length();
let data = &*args.data();
let mut state = self.state.lock();
let mut state = zelf.state.lock();
let result = state.backend.decompress(data, max_length);
self.check.store(state.backend.check(), Ordering::Relaxed);
self.eof.store(state.backend.eof(), Ordering::Relaxed);
self.needs_input
zelf.check.store(state.backend.check(), Ordering::Relaxed);
zelf.eof.store(state.backend.eof(), Ordering::Relaxed);
zelf.needs_input
.store(state.backend.needs_input(), Ordering::Relaxed);
let stale = self.unused_data.deref().is_none_or(|obj| {
let stale = zelf.unused_data.deref().is_none_or(|obj| {
obj.downcast_ref::<PyBytes>()
.is_none_or(|bytes| bytes.as_bytes() != state.backend.unused_data())
});
if stale {
let bytes = vm.ctx.new_bytes(state.backend.unused_data().to_vec());
let _previous = unsafe { self.unused_data.swap(Some(bytes.into())) };
let _previous = unsafe { zelf.unused_data.swap(Some(bytes.into())) };
}
result.map_err(|error| map_backend_error(error, vm))
}
@@ -415,14 +419,14 @@ mod _lzma {
#[pyclass(with(Constructor))]
impl LZMACompressor {
#[pymethod]
fn compress(&self, data: ArgBytesLike, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
data.with_ref(|data| self.state.lock().compress(data))
fn compress(zelf: &Py<Self>, data: ArgBytesLike, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
data.with_ref(|data| zelf.state.lock().compress(data))
.map_err(|error| map_backend_error(error, vm))
}
#[pymethod]
fn flush(&self, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
self.state
fn flush(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
zelf.state
.lock()
.flush()
.map_err(|error| map_backend_error(error, vm))
+73 -73
View File
@@ -796,25 +796,25 @@ mod mmap {
}
#[pygetset]
fn closed(&self) -> bool {
self.closed.load()
fn closed(zelf: &Py<Self>) -> bool {
zelf.closed.load()
}
#[pymethod]
fn close(&self, vm: &VirtualMachine) -> PyResult<()> {
if self.closed() {
fn close(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
if Self::closed(zelf) {
return Ok(());
}
if self.exports.load() > 0 {
if zelf.exports.load() > 0 {
return Err(vm.new_buffer_error("cannot close exported pointers exist."));
}
let mut mmap = self.mmap.lock();
self.closed.store(true);
let mut mmap = zelf.mmap.lock();
zelf.closed.store(true);
*mmap = None;
self.close_handle();
zelf.close_handle();
Ok(())
}
@@ -862,26 +862,26 @@ mod mmap {
}
#[pymethod]
fn find(&self, options: FindOptions, vm: &VirtualMachine) -> PyResult<PyInt> {
self.find_inner(options, false, vm)
fn find(zelf: &Py<Self>, options: FindOptions, vm: &VirtualMachine) -> PyResult<PyInt> {
zelf.find_inner(options, false, vm)
}
#[pymethod]
fn rfind(&self, options: FindOptions, vm: &VirtualMachine) -> PyResult<PyInt> {
self.find_inner(options, true, vm)
fn rfind(zelf: &Py<Self>, options: FindOptions, vm: &VirtualMachine) -> PyResult<PyInt> {
zelf.find_inner(options, true, vm)
}
#[pymethod]
fn flush(&self, options: FlushOptions, vm: &VirtualMachine) -> PyResult<()> {
fn flush(zelf: &Py<Self>, options: FlushOptions, vm: &VirtualMachine) -> PyResult<()> {
let (offset, size) = options
.values(self.__len__())
.values(zelf.__len__())
.ok_or_else(|| vm.new_value_error("flush values out of range"))?;
if self.access == AccessMode::Read || self.access == AccessMode::Copy {
if zelf.access == AccessMode::Read || zelf.access == AccessMode::Copy {
return Ok(());
}
match self.check_valid(vm)?.deref().as_ref().unwrap() {
match zelf.check_valid(vm)?.deref().as_ref().unwrap() {
MmapObj::Mapped(mmap) => {
mmap.flush_range(offset, size)
.map_err(|e| e.to_pyexception(vm))?;
@@ -899,13 +899,13 @@ mod mmap {
#[cfg(all(unix, not(target_os = "redox")))]
#[pymethod]
fn madvise(&self, options: AdviseOptions, vm: &VirtualMachine) -> PyResult<()> {
let (option, start, length) = options.values(self.__len__(), vm)?;
fn madvise(zelf: &Py<Self>, options: AdviseOptions, vm: &VirtualMachine) -> PyResult<()> {
let (option, start, length) = options.values(zelf.__len__(), vm)?;
if !host_mmap::validate_advice(option) {
return Err(vm.new_value_error("Not a valid Advice value"));
}
let guard = self.check_valid(vm)?;
let guard = zelf.check_valid(vm)?;
let mmap = guard.deref().as_ref().unwrap();
match mmap {
MmapObj::Mapped(m) => m.madvise_range(start, length, option),
@@ -919,7 +919,7 @@ mod mmap {
#[pymethod(name = "move")]
fn move_(
&self,
zelf: &Py<Self>,
dest: PyIntRef,
src: PyIntRef,
count: PyIntRef,
@@ -947,14 +947,14 @@ mod mmap {
Some((dest, src, cnt))
}
let size = self.__len__();
let size = zelf.__len__();
let (dest, src, cnt) = args(&dest, &src, &count, size, vm)
.ok_or_else(|| vm.new_value_error("source, destination, or count out of range"))?;
let dest_end = dest + cnt;
let src_end = src + cnt;
self.try_writable(vm, |mmap| {
zelf.try_writable(vm, |mmap| {
let src_buf = mmap[src..src_end].to_vec();
(&mut mmap[dest..dest_end])
.write(&src_buf)
@@ -964,7 +964,7 @@ mod mmap {
}
#[pymethod]
fn read(&self, args: ReadArgs, vm: &VirtualMachine) -> PyResult<PyBytesRef> {
fn read(zelf: &Py<Self>, args: ReadArgs, vm: &VirtualMachine) -> PyResult<PyBytesRef> {
let num_bytes = args
.n
.map(|obj| {
@@ -978,9 +978,9 @@ mod mmap {
})
.transpose()?
.flatten();
let mmap = self.check_valid(vm)?;
let pos = self.pos();
let remaining = self.__len__().saturating_sub(pos);
let mmap = zelf.check_valid(vm)?;
let pos = zelf.pos();
let remaining = zelf.__len__().saturating_sub(pos);
let num_bytes = num_bytes
.filter(|&n| n >= 0 && (n as usize) <= remaining)
.map_or(remaining, |n| n as usize);
@@ -990,31 +990,31 @@ mod mmap {
let result = PyBytes::from(bytes).into_ref(&vm.ctx);
self.advance_pos(num_bytes);
zelf.advance_pos(num_bytes);
Ok(result)
}
#[pymethod]
fn read_byte(&self, vm: &VirtualMachine) -> PyResult<PyIntRef> {
let pos = self.pos();
if pos >= self.__len__() {
fn read_byte(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyIntRef> {
let pos = zelf.pos();
if pos >= zelf.__len__() {
return Err(vm.new_value_error("read byte out of range"));
}
let b = self.check_valid(vm)?.deref().as_ref().unwrap().as_slice()[pos];
let b = zelf.check_valid(vm)?.deref().as_ref().unwrap().as_slice()[pos];
self.advance_pos(1);
zelf.advance_pos(1);
Ok(PyInt::from(b).into_ref(&vm.ctx))
}
#[pymethod]
fn readline(&self, vm: &VirtualMachine) -> PyResult<PyBytesRef> {
let pos = self.pos();
let mmap = self.check_valid(vm)?;
fn readline(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyBytesRef> {
let pos = zelf.pos();
let mmap = zelf.check_valid(vm)?;
let remaining = self.__len__().saturating_sub(pos);
let remaining = zelf.__len__().saturating_sub(pos);
if remaining == 0 {
return Ok(PyBytes::from(vec![]).into_ref(&vm.ctx));
}
@@ -1025,30 +1025,30 @@ mod mmap {
let end_pos = if let Some(i) = eof {
pos + i + 1
} else {
self.__len__()
zelf.__len__()
};
let bytes = slice[pos..end_pos].to_vec();
let result = PyBytes::from(bytes).into_ref(&vm.ctx);
self.advance_pos(end_pos - pos);
zelf.advance_pos(end_pos - pos);
Ok(result)
}
#[cfg(unix)]
#[pymethod]
fn resize(&self, _newsize: PyIntRef, vm: &VirtualMachine) -> PyResult<()> {
self.check_resizeable(vm)?;
fn resize(zelf: &Py<Self>, _newsize: PyIntRef, vm: &VirtualMachine) -> PyResult<()> {
zelf.check_resizeable(vm)?;
// TODO: implement using mremap on Linux
Err(vm.new_system_error("mmap: resizing not available--no mremap()"))
}
#[cfg(windows)]
#[pymethod]
fn resize(&self, newsize: PyIntRef, vm: &VirtualMachine) -> PyResult<()> {
self.check_resizeable(vm)?;
fn resize(zelf: &Py<Self>, newsize: PyIntRef, vm: &VirtualMachine) -> PyResult<()> {
zelf.check_resizeable(vm)?;
let newsize: usize = newsize
.try_to_primitive(vm)
@@ -1058,10 +1058,10 @@ mod mmap {
return Err(vm.new_value_error("new size must be positive"));
}
let handle = self.handle.load();
let handle = zelf.handle.load();
// Get the lock on mmap
let mut mmap_guard = self.mmap.lock();
let mut mmap_guard = zelf.mmap.lock();
// Check if this is a Named mmap - these cannot be resized
if let Some(MmapObj::Named(_)) = mmap_guard.as_ref() {
@@ -1076,7 +1076,7 @@ mod mmap {
// 2. Copy data from old mmap to new mmap
// 3. Replace the old mmap
let old_size = self.size.load();
let old_size = zelf.size.load();
let copy_size = core::cmp::min(old_size, newsize);
// Create new anonymous mmap
@@ -1090,21 +1090,21 @@ mod mmap {
}
*mmap_guard = Some(MmapObj::Mapped(new_mmap));
self.size.store(newsize);
zelf.size.store(newsize);
} else {
// File-backed mmap resize
// Drop the current mmap to release the file mapping
*mmap_guard = None;
let required_size = self.offset + newsize as i64;
let required_size = zelf.offset + newsize as i64;
if let Err(err) = host_mmap::extend_file(handle as host_mmap::Handle, required_size)
{
// Restore original mmap on error
self.try_restore_mmap(
zelf.try_restore_mmap(
&mut mmap_guard,
handle as host_mmap::Handle,
self.size.load(),
zelf.size.load(),
);
return Err(err.to_pyexception(vm));
}
@@ -1112,36 +1112,36 @@ mod mmap {
// Create new mmap with the new size
let new_mmap = Self::create_mmap_windows(
handle as host_mmap::Handle,
self.offset,
zelf.offset,
newsize,
&self.access,
&zelf.access,
)
.map_err(|e| e.to_pyexception(vm))?;
*mmap_guard = Some(new_mmap);
self.size.store(newsize);
zelf.size.store(newsize);
}
// Adjust position if it's beyond the new size
let pos = self.pos.load();
let pos = zelf.pos.load();
if pos > newsize {
self.pos.store(newsize);
zelf.pos.store(newsize);
}
Ok(())
}
#[pymethod]
fn seek(&self, args: SeekArgs, vm: &VirtualMachine) -> PyResult<usize> {
fn seek(zelf: &Py<Self>, args: SeekArgs, vm: &VirtualMachine) -> PyResult<usize> {
let dist = args.pos;
let how = args.whence;
let size = self.__len__();
let size = zelf.__len__();
let new_pos = match how {
0 => dist, // relative to start
1 => {
// relative to current position
let pos = self.pos();
let pos = zelf.pos();
if (((isize::MAX as usize) - pos) as isize) < dist {
return Err(vm.new_value_error("seek out of range"));
}
@@ -1161,26 +1161,26 @@ mod mmap {
return Err(vm.new_value_error("seek out of range"));
}
self.pos.store(new_pos as usize);
zelf.pos.store(new_pos as usize);
Ok(new_pos as usize)
}
#[cfg(unix)]
#[pymethod]
fn size(&self, vm: &VirtualMachine) -> std::io::Result<PyIntRef> {
let fd = unsafe { crt_fd::Borrowed::try_borrow_raw(self.fd.load())? };
fn size(zelf: &Py<Self>, vm: &VirtualMachine) -> std::io::Result<PyIntRef> {
let fd = unsafe { crt_fd::Borrowed::try_borrow_raw(zelf.fd.load())? };
let file_len = host_mmap::file_len(fd)?;
Ok(PyInt::from(file_len).into_ref(&vm.ctx))
}
#[cfg(windows)]
#[pymethod]
fn size(&self, vm: &VirtualMachine) -> PyResult<PyIntRef> {
let handle = self.handle.load();
fn size(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyIntRef> {
let handle = zelf.handle.load();
if host_mmap::is_invalid_handle_value(handle) {
// Anonymous mapping, return the mmap size
return Ok(PyInt::from(self.__len__()).into_ref(&vm.ctx));
return Ok(PyInt::from(zelf.__len__()).into_ref(&vm.ctx));
}
let file_len = host_mmap::get_file_len(handle as host_mmap::Handle)
@@ -1189,12 +1189,12 @@ mod mmap {
}
#[pymethod]
fn tell(&self) -> usize {
self.pos()
fn tell(zelf: &Py<Self>) -> usize {
zelf.pos()
}
#[pymethod]
fn seekable(&self) -> bool {
fn seekable(_zelf: &Py<Self>) -> bool {
true
}
@@ -1233,21 +1233,21 @@ mod mmap {
}
#[pymethod]
fn write_byte(&self, byte: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
fn write_byte(zelf: &Py<Self>, byte: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
let b = value_from_object(vm, &byte)?;
let pos = self.pos();
let size = self.__len__();
let pos = zelf.pos();
let size = zelf.__len__();
if pos >= size {
return Err(vm.new_value_error("write byte out of range"));
}
self.try_writable(vm, |mmap| {
zelf.try_writable(vm, |mmap| {
mmap[pos] = b;
})?;
self.advance_pos(1);
zelf.advance_pos(1);
Ok(())
}
@@ -1279,12 +1279,12 @@ mod mmap {
_traceback: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
zelf.close(vm)
Self::close(zelf, vm)
}
#[cfg(windows)]
#[pymethod]
fn __sizeof__(&self) -> usize {
fn __sizeof__(_zelf: &Py<Self>) -> usize {
core::mem::size_of::<Self>()
}
}
+85 -81
View File
@@ -153,7 +153,7 @@ mod _multiprocessing {
#[pyclass(with(Constructor), flags(BASETYPE))]
impl SemLock {
#[pymethod]
fn acquire(&self, args: AcquireArgs, vm: &VirtualMachine) -> PyResult<bool> {
fn acquire(zelf: &Py<Self>, args: AcquireArgs, vm: &VirtualMachine) -> PyResult<bool> {
let blocking = args.block;
let timeout_obj = args.timeout;
@@ -176,18 +176,18 @@ mod _multiprocessing {
// Check whether we already own the lock
{
let _crit = self.crit.lock();
if self.kind == RECURSIVE_MUTEX && ismine!(self) {
self.count.fetch_add(1, Ordering::Release);
let _crit = zelf.crit.lock();
if zelf.kind == RECURSIVE_MUTEX && ismine!(zelf) {
zelf.count.fetch_add(1, Ordering::Release);
return Ok(true);
}
// Check whether we can acquire without blocking
match self.handle.wait(0) {
match zelf.handle.wait(0) {
x if x == host_multiprocessing::wait_object_0() => {
self.last_tid
zelf.last_tid
.store(host_multiprocessing::current_thread_id(), Ordering::Release);
self.count.fetch_add(1, Ordering::Release);
zelf.count.fetch_add(1, Ordering::Release);
return Ok(true);
}
x if x == host_multiprocessing::wait_failed() => {
@@ -211,15 +211,15 @@ mod _multiprocessing {
remaining.min(poll_ms)
};
let handle = &self.handle;
let handle = &zelf.handle;
let res = vm.allow_threads(|| handle.wait(wait_ms));
match res {
x if x == host_multiprocessing::wait_object_0() => {
let _crit = self.crit.lock();
self.last_tid
let _crit = zelf.crit.lock();
zelf.last_tid
.store(host_multiprocessing::current_thread_id(), Ordering::Release);
self.count.fetch_add(1, Ordering::Release);
zelf.count.fetch_add(1, Ordering::Release);
return Ok(true);
}
x if x == host_multiprocessing::wait_timeout() => {
@@ -241,34 +241,35 @@ mod _multiprocessing {
}
#[pymethod]
fn release(&self, vm: &VirtualMachine) -> PyResult<()> {
let _crit = self.crit.lock();
if self.kind == RECURSIVE_MUTEX {
if !ismine!(self) {
fn release(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
let _crit = zelf.crit.lock();
if zelf.kind == RECURSIVE_MUTEX {
if !ismine!(zelf) {
return Err(vm.new_assertion_error(
"attempt to release recursive lock not owned by thread",
));
}
if self.count.load(Ordering::Acquire) > 1 {
self.count.fetch_sub(1, Ordering::Release);
if zelf.count.load(Ordering::Acquire) > 1 {
zelf.count.fetch_sub(1, Ordering::Release);
return Ok(());
}
}
if let Err(err) = self.handle.release() {
if let Err(err) = zelf.handle.release() {
if host_multiprocessing::is_too_many_posts(err) {
return Err(vm.new_value_error("semaphore or lock released too many times"));
}
return Err(vm.new_last_os_error());
}
self.count.fetch_sub(1, Ordering::Release);
zelf.count.fetch_sub(1, Ordering::Release);
Ok(())
}
#[pymethod(name = "__enter__")]
fn enter(&self, vm: &VirtualMachine) -> PyResult<bool> {
self.acquire(
fn enter(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<bool> {
Self::acquire(
zelf,
AcquireArgs {
block: true,
timeout: None,
@@ -278,8 +279,8 @@ mod _multiprocessing {
}
#[pymethod]
fn __exit__(&self, _args: ExitArgs, vm: &VirtualMachine) -> PyResult<()> {
self.release(vm)
fn __exit__(zelf: &Py<Self>, _args: ExitArgs, vm: &VirtualMachine) -> PyResult<()> {
Self::release(zelf, vm)
}
#[pyclassmethod(name = "_rebuild")]
@@ -309,36 +310,36 @@ mod _multiprocessing {
}
#[pymethod]
fn _after_fork(&self) {
let _crit = self.crit.lock();
self.count.store(0, Ordering::Release);
self.last_tid.store(0, Ordering::Release);
fn _after_fork(zelf: &Py<Self>) {
let _crit = zelf.crit.lock();
zelf.count.store(0, Ordering::Release);
zelf.last_tid.store(0, Ordering::Release);
}
#[pymethod]
fn __reduce__(&self, vm: &VirtualMachine) -> PyResult {
fn __reduce__(_zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
Err(vm.new_type_error("cannot pickle 'SemLock' object"))
}
#[pymethod]
fn _count(&self) -> i32 {
let _crit = self.crit.lock();
self.count.load(Ordering::Acquire)
fn _count(zelf: &Py<Self>) -> i32 {
let _crit = zelf.crit.lock();
zelf.count.load(Ordering::Acquire)
}
#[pymethod]
fn _is_mine(&self) -> bool {
ismine!(self)
fn _is_mine(zelf: &Py<Self>) -> bool {
ismine!(zelf)
}
#[pymethod]
fn _get_value(&self, vm: &VirtualMachine) -> PyResult<i32> {
self.handle.value().map_err(|_| vm.new_last_os_error())
fn _get_value(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<i32> {
zelf.handle.value().map_err(|_| vm.new_last_os_error())
}
#[pymethod]
fn _is_zero(&self, vm: &VirtualMachine) -> PyResult<bool> {
let val = self.handle.value().map_err(|_| vm.new_last_os_error())?;
fn _is_zero(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<bool> {
let val = zelf.handle.value().map_err(|_| vm.new_last_os_error())?;
Ok(val == 0)
}
@@ -547,13 +548,13 @@ mod _multiprocessing {
impl SemLock {
// _multiprocessing_SemLock_acquire_impl
#[pymethod]
fn acquire(&self, args: AcquireArgs, vm: &VirtualMachine) -> PyResult<bool> {
fn acquire(zelf: &Py<Self>, args: AcquireArgs, vm: &VirtualMachine) -> PyResult<bool> {
let blocking = args.block;
let timeout_obj = args.timeout;
let _crit = self.crit.lock();
if self.kind == RECURSIVE_MUTEX && ismine!(self) {
self.count.fetch_add(1, Ordering::Release);
let _crit = zelf.crit.lock();
if zelf.kind == RECURSIVE_MUTEX && ismine!(zelf) {
zelf.count.fetch_add(1, Ordering::Release);
return Ok(true);
}
@@ -574,7 +575,7 @@ mod _multiprocessing {
// Check whether we can acquire without releasing the GIL and blocking
let try_status = loop {
match self.handle.trywait() {
match zelf.handle.trywait() {
TryAcquireStatus::Interrupted => {
vm.check_signals()?;
}
@@ -590,7 +591,7 @@ mod _multiprocessing {
#[cfg(not(target_vendor = "apple"))]
{
loop {
let handle = &self.handle;
let handle = &zelf.handle;
match vm.allow_threads(|| handle.wait(deadline.as_ref())) {
WaitStatus::Acquired => break,
WaitStatus::Interrupted => {
@@ -606,7 +607,7 @@ mod _multiprocessing {
{
// macOS: use polled fallback since sem_timedwait is not available
if let Some(ref dl) = deadline {
match sem_timedwait_polled(&self.handle, dl, vm) {
match sem_timedwait_polled(&zelf.handle, dl, vm) {
Ok(()) => {}
Err(SemWaitError::Timeout) => {
return Ok(false);
@@ -621,7 +622,7 @@ mod _multiprocessing {
} else {
// No timeout: use sem_wait (available on macOS)
loop {
let handle = &self.handle;
let handle = &zelf.handle;
match vm.allow_threads(|| handle.wait(None)) {
WaitStatus::Acquired => break,
WaitStatus::Interrupted => {
@@ -634,8 +635,8 @@ mod _multiprocessing {
}
}
}
let _crit = self.crit.lock();
self.mark_acquired();
let _crit = zelf.crit.lock();
zelf.mark_acquired();
return Ok(true);
} else if !matches!(try_status, TryAcquireStatus::Acquired) {
// Non-blocking path failed, or blocking=false
@@ -647,7 +648,7 @@ mod _multiprocessing {
}
}
self.mark_acquired();
zelf.mark_acquired();
Ok(true)
}
@@ -659,18 +660,18 @@ mod _multiprocessing {
// _multiprocessing_SemLock_release_impl
#[pymethod]
fn release(&self, vm: &VirtualMachine) -> PyResult<()> {
let _crit = self.crit.lock();
if self.kind == RECURSIVE_MUTEX {
fn release(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
let _crit = zelf.crit.lock();
if zelf.kind == RECURSIVE_MUTEX {
// if (!ISMINE(self))
if !ismine!(self) {
if !ismine!(zelf) {
return Err(vm.new_assertion_error(
"attempt to release recursive lock not owned by thread",
));
}
// if (self->count > 1) { --self->count; Py_RETURN_NONE; }
if self.count.load(Ordering::Acquire) > 1 {
self.count.fetch_sub(1, Ordering::Release);
if zelf.count.load(Ordering::Acquire) > 1 {
zelf.count.fetch_sub(1, Ordering::Release);
return Ok(());
}
// assert(self->count == 1);
@@ -679,8 +680,8 @@ mod _multiprocessing {
#[cfg(not(target_vendor = "apple"))]
{
// Linux: use sem_getvalue
let sval = self.handle.value().map_err(|err| os_error(vm, err))?;
if sval >= self.maxvalue {
let sval = zelf.handle.value().map_err(|err| os_error(vm, err))?;
if sval >= zelf.maxvalue {
return Err(vm.new_value_error("semaphore or lock released too many times"));
}
}
@@ -688,12 +689,12 @@ mod _multiprocessing {
{
// macOS: HAVE_BROKEN_SEM_GETVALUE
// We will only check properly the maxvalue == 1 case
if self.maxvalue == 1 {
if zelf.maxvalue == 1 {
// make sure that already locked
match self.handle.trywait() {
match zelf.handle.trywait() {
TryAcquireStatus::WouldBlock => {}
TryAcquireStatus::Acquired => {
if let Err(err) = self.handle.post() {
if let Err(err) = zelf.handle.post() {
return Err(os_error(vm, err));
}
return Err(
@@ -709,19 +710,20 @@ mod _multiprocessing {
}
}
if let Err(err) = self.handle.post() {
if let Err(err) = zelf.handle.post() {
return Err(os_error(vm, err));
}
self.count.fetch_sub(1, Ordering::Release);
zelf.count.fetch_sub(1, Ordering::Release);
Ok(())
}
// _multiprocessing_SemLock___enter___impl
#[pymethod(name = "__enter__")]
fn enter(&self, vm: &VirtualMachine) -> PyResult<bool> {
fn enter(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<bool> {
// return _multiprocessing_SemLock_acquire_impl(self, 1, Py_None);
self.acquire(
Self::acquire(
zelf,
AcquireArgs {
block: true,
timeout: None,
@@ -732,8 +734,8 @@ mod _multiprocessing {
// _multiprocessing_SemLock___exit___impl
#[pymethod]
fn __exit__(&self, _args: ExitArgs, vm: &VirtualMachine) -> PyResult<()> {
self.release(vm)
fn __exit__(zelf: &Py<Self>, _args: ExitArgs, vm: &VirtualMachine) -> PyResult<()> {
Self::release(zelf, vm)
}
// Rebuild a SemLock from pickled state.
@@ -770,40 +772,42 @@ mod _multiprocessing {
// _multiprocessing_SemLock__after_fork_impl
#[pymethod]
fn _after_fork(&self) {
let _crit = self.crit.lock();
self.count.store(0, Ordering::Release);
fn _after_fork(zelf: &Py<Self>) {
let _crit = zelf.crit.lock();
zelf.count.store(0, Ordering::Release);
// Also reset last_tid for safety
self.last_tid.store(0, Ordering::Release);
zelf.last_tid.store(0, Ordering::Release);
}
// SemLock objects cannot be pickled directly.
// Use multiprocessing.synchronize.SemLock wrapper which handles pickling.
#[pymethod]
fn __reduce__(&self, vm: &VirtualMachine) -> PyResult {
fn __reduce__(_zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
Err(vm.new_type_error("cannot pickle 'SemLock' object"))
}
// _multiprocessing_SemLock__count_impl
#[pymethod]
fn _count(&self) -> i32 {
let _crit = self.crit.lock();
self.count.load(Ordering::Acquire)
fn _count(zelf: &Py<Self>) -> i32 {
let _crit = zelf.crit.lock();
zelf.count.load(Ordering::Acquire)
}
// _multiprocessing_SemLock__is_mine_impl
#[pymethod]
fn _is_mine(&self) -> bool {
ismine!(self)
fn _is_mine(zelf: &Py<Self>) -> bool {
ismine!(zelf)
}
// _multiprocessing_SemLock__get_value_impl
#[pymethod]
fn _get_value(&self, vm: &VirtualMachine) -> PyResult<i32> {
fn _get_value(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<i32> {
#[cfg(target_vendor = "apple")]
let _ = zelf;
#[cfg(not(target_vendor = "apple"))]
{
// Linux: use sem_getvalue
self.handle.value().map_err(|err| os_error(vm, err))
zelf.handle.value().map_err(|err| os_error(vm, err))
}
#[cfg(target_vendor = "apple")]
{
@@ -814,16 +818,16 @@ mod _multiprocessing {
// _multiprocessing_SemLock__is_zero_impl
#[pymethod]
fn _is_zero(&self, vm: &VirtualMachine) -> PyResult<bool> {
fn _is_zero(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<bool> {
#[cfg(not(target_vendor = "apple"))]
{
Ok(self._get_value(vm)? == 0)
Ok(Self::_get_value(zelf, vm)? == 0)
}
#[cfg(target_vendor = "apple")]
{
// macOS: HAVE_BROKEN_SEM_GETVALUE
// Try to acquire - if EAGAIN, value is 0
match self.handle.trywait() {
match zelf.handle.trywait() {
TryAcquireStatus::WouldBlock => return Ok(true),
TryAcquireStatus::Interrupted => {
return Err(os_error(vm, SemError::Interrupted));
@@ -832,7 +836,7 @@ mod _multiprocessing {
TryAcquireStatus::Acquired => {}
}
// Successfully acquired - undo and return false
if let Err(err) = self.handle.post() {
if let Err(err) = zelf.handle.post() {
return Err(os_error(vm, err));
}
Ok(false)
File diff suppressed because it is too large. Load diff
+5 -5
View File
@@ -74,7 +74,7 @@ pub(crate) mod ssl_cert {
impl PySSLCertificate {
#[pymethod]
fn public_bytes(
&self,
zelf: &Py<Self>,
format: OptionalArg<i32>,
vm: &VirtualMachine,
) -> PyResult<PyObjectRef> {
@@ -83,7 +83,7 @@ pub(crate) mod ssl_cert {
match format {
ENCODING_DER => {
// DER encoding
let der = self
let der = zelf
.cert
.to_der()
.map_err(|e| convert_openssl_error(vm, e))?;
@@ -91,7 +91,7 @@ pub(crate) mod ssl_cert {
}
ENCODING_PEM => {
// PEM encoding - returns string
let pem = self
let pem = zelf
.cert
.to_pem()
.map_err(|e| convert_openssl_error(vm, e))?;
@@ -104,8 +104,8 @@ pub(crate) mod ssl_cert {
}
#[pymethod]
fn get_info(&self, vm: &VirtualMachine) -> PyResult {
cert_to_dict(vm, &self.cert)
fn get_info(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult {
cert_to_dict(vm, &zelf.cert)
}
}
+8 -8
View File
@@ -262,27 +262,27 @@ mod _overlapped {
#[pyclass(with(Constructor, Destructor))]
impl Overlapped {
#[pygetset]
fn address(&self, _vm: &VirtualMachine) -> usize {
let inner = self.inner.lock();
fn address(zelf: &Py<Self>, _vm: &VirtualMachine) -> usize {
let inner = zelf.inner.lock();
&inner.overlapped as *const _ as usize
}
#[pygetset]
fn pending(&self, _vm: &VirtualMachine) -> bool {
let inner = self.inner.lock();
fn pending(zelf: &Py<Self>, _vm: &VirtualMachine) -> bool {
let inner = zelf.inner.lock();
!host_overlapped::has_overlapped_io_completed(&inner.overlapped)
&& !matches!(inner.data, OverlappedData::NotStarted)
}
#[pygetset]
fn error(&self, _vm: &VirtualMachine) -> u32 {
let inner = self.inner.lock();
fn error(zelf: &Py<Self>, _vm: &VirtualMachine) -> u32 {
let inner = zelf.inner.lock();
inner.error
}
#[pygetset]
fn event(&self, _vm: &VirtualMachine) -> isize {
let inner = self.inner.lock();
fn event(zelf: &Py<Self>, _vm: &VirtualMachine) -> isize {
let inner = zelf.inner.lock();
inner.overlapped.hEvent as isize
}
+27 -20
View File
@@ -98,8 +98,11 @@ mod _pickle {
}
#[pymethod]
fn raw(&self, vm: &VirtualMachine) -> PyResult<PyRef<crate::vm::builtins::PyMemoryView>> {
let buffer = self.get(vm)?;
fn raw(
zelf: &Py<Self>,
vm: &VirtualMachine,
) -> PyResult<PyRef<crate::vm::builtins::PyMemoryView>> {
let buffer = zelf.get(vm)?;
if !buffer.desc.is_contiguous() {
return Err(vm.new_buffer_error(
"cannot pickle a non-contiguous buffer: PickleBuffer is not contiguous",
@@ -109,8 +112,8 @@ mod _pickle {
}
#[pymethod]
fn release(&self) {
*self.buffer.write() = None;
fn release(zelf: &Py<Self>) {
*zelf.buffer.write() = None;
}
}
@@ -403,14 +406,14 @@ mod _pickle {
#[pyclass(flags(DISALLOW_INSTANTIATION))]
impl UnpicklerMemoProxy {
#[pymethod]
fn clear(&self) {
self.unpickler.memo.write().clear();
fn clear(zelf: &Py<Self>) {
zelf.unpickler.memo.write().clear();
}
#[pymethod]
fn copy(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
fn copy(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
let dict = vm.ctx.new_dict();
for (i, entry) in self.unpickler.memo.read().iter().enumerate() {
for (i, entry) in zelf.unpickler.memo.read().iter().enumerate() {
if let Some(obj) = entry {
let key: PyObjectRef = vm.ctx.new_int(i).into();
dict.set_item(&*key, obj.clone(), vm)?;
@@ -420,8 +423,8 @@ mod _pickle {
}
#[pymethod]
fn __reduce__(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
let contents = self.copy(vm)?;
fn __reduce__(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
let contents = Self::copy(zelf, vm)?;
Ok(vm
.ctx
.new_tuple(vec![
@@ -567,7 +570,11 @@ mod _pickle {
// The default hook: no persistent ids are supported.
#[pymethod]
fn persistent_load(&self, _pid: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
fn persistent_load(
_zelf: &Py<Self>,
_pid: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
Err(new_unpickling_error(
vm,
"A load persistent id instruction was encountered, but no persistent_load function was specified.",
@@ -1898,15 +1905,15 @@ mod _pickle {
#[pyclass(flags(DISALLOW_INSTANTIATION))]
impl PicklerMemoProxy {
#[pymethod]
fn clear(&self) {
self.pickler.memo.write().clear();
fn clear(zelf: &Py<Self>) {
zelf.pickler.memo.write().clear();
}
#[pymethod]
fn copy(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
fn copy(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
let dict = vm.ctx.new_dict();
#[allow(clippy::iter_over_hash_type)] // insertion order does not matter here
for (id, (idx, obj)) in self.pickler.memo.read().iter() {
for (id, (idx, obj)) in zelf.pickler.memo.read().iter() {
let key: PyObjectRef = vm.ctx.new_int(*id).into();
let value: PyObjectRef = vm
.ctx
@@ -1918,8 +1925,8 @@ mod _pickle {
}
#[pymethod]
fn __reduce__(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
let contents = self.copy(vm)?;
fn __reduce__(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
let contents = Self::copy(zelf, vm)?;
Ok(vm
.ctx
.new_tuple(vec![
@@ -2045,13 +2052,13 @@ mod _pickle {
}
#[pymethod]
fn clear_memo(&self) {
self.memo.write().clear();
fn clear_memo(zelf: &Py<Self>) {
zelf.memo.write().clear();
}
// The default hook: nothing has a persistent id.
#[pymethod]
fn persistent_id(&self, _obj: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
fn persistent_id(_zelf: &Py<Self>, _obj: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
vm.ctx.none()
}
+10 -10
View File
@@ -1014,14 +1014,14 @@ mod _pyexpat {
}
#[pymethod(name = "SetParamEntityParsing")]
fn set_param_entity_parsing(&self, _flag: i32) -> i32 {
fn set_param_entity_parsing(_zelf: &Py<Self>, _flag: i32) -> i32 {
// Compatibility shim: xml.sax requires this setup API, but xml-rs
// does not expose Expat parameter entity parsing configuration.
1
}
#[pymethod(name = "UseForeignDTD")]
fn use_foreign_dtd(&self, _flag: OptionalArg<bool>) {
fn use_foreign_dtd(_zelf: &Py<Self>, _flag: OptionalArg<bool>) {
// Compatibility shim: CPython's implementation forwards the flag to
// libexpat's XML_UseForeignDTD, which lets a DTD handler splice in an
// external subset for documents that only declare one (e.g. via
@@ -1032,16 +1032,16 @@ mod _pyexpat {
}
#[pymethod(name = "SetBase")]
fn set_base(&self, base: PyStrRef) {
fn set_base(zelf: &Py<Self>, base: PyStrRef) {
// Store-only compatibility state for xml.sax locator APIs. The
// xml-rs backend still does not perform Expat-style base URI
// resolution for external entities.
*self.base.write() = Some(AsRef::<str>::as_ref(&base).to_owned());
*zelf.base.write() = Some(AsRef::<str>::as_ref(&base).to_owned());
}
#[pymethod(name = "GetBase")]
fn get_base(&self, vm: &VirtualMachine) -> PyObjectRef {
self.base.read().as_ref().map_or_else(
fn get_base(zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
zelf.base.read().as_ref().map_or_else(
|| vm.ctx.none(),
|base| vm.ctx.new_str(base.as_str()).into(),
)
@@ -1398,7 +1398,7 @@ mod _pyexpat {
#[pymethod(name = "Parse")]
fn parse(
&self,
zelf: &Py<Self>,
data: Either<PyStrRef, PyBytesRef>,
isfinal: OptionalArg<bool>,
vm: &VirtualMachine,
@@ -1407,18 +1407,18 @@ mod _pyexpat {
Either::A(s) => s.as_bytes().to_vec(),
Either::B(b) => b.as_bytes().to_vec(),
};
self.feed(vm, &bytes, isfinal.unwrap_or(false))?;
zelf.feed(vm, &bytes, isfinal.unwrap_or(false))?;
Ok(1)
}
#[pymethod(name = "ParseFile")]
fn parse_file(&self, file: PyObjectRef, vm: &VirtualMachine) -> PyResult<i32> {
fn parse_file(zelf: &Py<Self>, file: PyObjectRef, vm: &VirtualMachine) -> PyResult<i32> {
let read_res = vm.call_method(&file, "read", ())?;
let bytes_like = ArgBytesLike::try_from_object(vm, read_res)?;
let buf = bytes_like.borrow_buf().to_vec();
// `file.read()` with no argument reads to EOF, so this chunk is
// always the last one.
self.feed(vm, &buf, true)?;
zelf.feed(vm, &buf, true)?;
Ok(1)
}
}
+26 -18
View File
@@ -224,8 +224,8 @@ pub(crate) mod _struct {
#[pyclass(with(IterNext, Iterable), flags(DISALLOW_INSTANTIATION))]
impl UnpackIterator {
#[pymethod]
fn __length_hint__(&self) -> usize {
self.buffer.len().saturating_sub(self.offset.load()) / self.format_spec.size
fn __length_hint__(zelf: &Py<Self>) -> usize {
zelf.buffer.len().saturating_sub(zelf.offset.load()) / zelf.format_spec.size
}
}
impl SelfIter for UnpackIterator {}
@@ -314,34 +314,34 @@ pub(crate) mod _struct {
}
#[pygetset]
fn format(&self, vm: &VirtualMachine) -> PyResult<PyStrRef> {
Ok(self.ready(vm)?.format.clone())
fn format(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyStrRef> {
Ok(zelf.ready(vm)?.format.clone())
}
// The size an uninitialized `Struct` reports, which no format has
// yet given a value.
#[pygetset]
fn size(&self) -> isize {
self.inner
fn size(zelf: &Py<Self>) -> isize {
zelf.inner
.read()
.as_ref()
.map_or(-1, |inner| inner.spec.size as isize)
}
#[pymethod]
fn pack(&self, args: PosArgs, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
self.ready(vm)?.spec.pack(args.into_vec(), vm)
fn pack(zelf: &Py<Self>, args: PosArgs, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
zelf.ready(vm)?.spec.pack(args.into_vec(), vm)
}
#[pymethod]
fn pack_into(
&self,
zelf: &Py<Self>,
buffer: ArgMemoryBuffer,
offset: isize,
args: PosArgs,
vm: &VirtualMachine,
) -> PyResult<()> {
let inner = self.ready(vm)?;
let inner = zelf.ready(vm)?;
let offset = get_buffer_offset(buffer.len(), offset, inner.spec.size, true, vm)?;
buffer.with_ref(|data| {
inner
@@ -351,14 +351,22 @@ pub(crate) mod _struct {
}
#[pymethod]
fn unpack(&self, buffer: ArgBytesLike, vm: &VirtualMachine) -> PyResult<PyTupleRef> {
let inner = self.ready(vm)?;
fn unpack(
zelf: &Py<Self>,
buffer: ArgBytesLike,
vm: &VirtualMachine,
) -> PyResult<PyTupleRef> {
let inner = zelf.ready(vm)?;
buffer.with_ref(|buf| inner.spec.unpack(buf, vm))
}
#[pymethod]
fn unpack_from(&self, args: UpdateFromArgs, vm: &VirtualMachine) -> PyResult<PyTupleRef> {
let inner = self.ready(vm)?;
fn unpack_from(
zelf: &Py<Self>,
args: UpdateFromArgs,
vm: &VirtualMachine,
) -> PyResult<PyTupleRef> {
let inner = zelf.ready(vm)?;
let size = inner.spec.size;
let offset = get_buffer_offset(args.buffer.len(), args.offset, size, false, vm)?;
args.buffer
@@ -367,17 +375,17 @@ pub(crate) mod _struct {
#[pymethod]
fn iter_unpack(
&self,
zelf: &Py<Self>,
buffer: ArgBytesLike,
vm: &VirtualMachine,
) -> PyResult<UnpackIterator> {
let spec = self.ready(vm)?.spec.clone();
let spec = zelf.ready(vm)?.spec.clone();
UnpackIterator::with_buffer(vm, spec, buffer)
}
#[pymethod]
fn __sizeof__(&self, vm: &VirtualMachine) -> PyResult<usize> {
let inner = self.ready(vm)?;
fn __sizeof__(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<usize> {
let inner = zelf.ready(vm)?;
Ok(core::mem::size_of::<Self>() + inner.spec.codes_sizeof())
}
}
+11 -11
View File
@@ -36,21 +36,21 @@ mod _random {
type Args = SeedArgs;
fn init(zelf: &Py<Self>, args: Self::Args, vm: &VirtualMachine) -> PyResult<()> {
zelf.seed(args, vm)
Self::seed(zelf, args, vm)
}
}
#[pyclass(flags(BASETYPE), with(Constructor, Initializer))]
impl PyRandom {
#[pymethod]
fn random(&self) -> f64 {
let mut rng = self.rng.lock();
fn random(zelf: &Py<Self>) -> f64 {
let mut rng = zelf.rng.lock();
mt19937::gen_res53(&mut *rng)
}
#[pymethod]
fn seed(&self, args: SeedArgs, vm: &VirtualMachine) -> PyResult<()> {
*self.rng.lock() = match args.n {
fn seed(zelf: &Py<Self>, args: SeedArgs, vm: &VirtualMachine) -> PyResult<()> {
*zelf.rng.lock() = match args.n {
Some(n) => {
// Fallback to using hash if object isn't Int-like.
let (_, mut key) = match n.downcast::<PyInt>() {
@@ -70,7 +70,7 @@ mod _random {
}
#[pymethod]
fn getrandbits(&self, k: PyObjectRef, vm: &VirtualMachine) -> PyResult<BigInt> {
fn getrandbits(zelf: &Py<Self>, k: PyObjectRef, vm: &VirtualMachine) -> PyResult<BigInt> {
let k_int = k.try_index(vm)?;
let k_bigint = k_int.as_bigint();
if k_bigint.is_negative() {
@@ -82,7 +82,7 @@ mod _random {
match k {
0 => Ok(BigInt::zero()),
mut k => {
let mut rng = self.rng.lock();
let mut rng = zelf.rng.lock();
let mut gen_u32 = |k| {
let r = rng.next_u32();
if k < 32 { r >> (32 - k) } else { r }
@@ -110,8 +110,8 @@ mod _random {
}
#[pymethod]
fn getstate(&self, vm: &VirtualMachine) -> PyTupleRef {
let rng = self.rng.lock();
fn getstate(zelf: &Py<Self>, vm: &VirtualMachine) -> PyTupleRef {
let rng = zelf.rng.lock();
vm.new_tuple(
rng.get_state()
.iter()
@@ -123,7 +123,7 @@ mod _random {
}
#[pymethod]
fn setstate(&self, state: PyTupleRef, vm: &VirtualMachine) -> PyResult<()> {
fn setstate(zelf: &Py<Self>, state: PyTupleRef, vm: &VirtualMachine) -> PyResult<()> {
let state: &[_; mt19937::N + 1] = state
.as_slice()
.try_into()
@@ -138,7 +138,7 @@ mod _random {
.map(|i| i.try_to_value(vm))
.process_results(|it| it.collect_array())?
.unwrap();
let mut rng = self.rng.lock();
let mut rng = zelf.rng.lock();
rng.set_state(&state);
rng.set_index(index);
Ok(())
+32 -27
View File
@@ -9,7 +9,7 @@ mod re {
* system.
*/
use crate::vm::{
PyObjectRef, PyPayload, PyResult, VirtualMachine,
Py, PyObjectRef, PyPayload, PyResult, VirtualMachine,
builtins::{PyInt, PyIntRef, PyStr, PyStrRef},
convert::{ToPyObject, TryFromObject},
function::{OptionalArg, PosArgs},
@@ -320,54 +320,59 @@ mod re {
#[pyclass(flags(HAS_WEAKREF))]
impl PyPattern {
#[pymethod(name = "match")]
fn match_(&self, text: PyStrRef) -> Option<PyMatch> {
do_match(self, text)
fn match_(zelf: &Py<Self>, text: PyStrRef) -> Option<PyMatch> {
do_match(zelf, text)
}
#[pymethod]
fn search(&self, text: PyStrRef) -> Option<PyMatch> {
do_search(self, text)
fn search(zelf: &Py<Self>, text: PyStrRef) -> Option<PyMatch> {
do_search(zelf, text)
}
#[pymethod]
fn sub(&self, repl: PyStrRef, text: PyStrRef, vm: &VirtualMachine) -> PyResult<PyStrRef> {
let replaced_text = self.regex.replace_all(text.as_bytes(), repl.as_bytes());
fn sub(
zelf: &Py<Self>,
repl: PyStrRef,
text: PyStrRef,
vm: &VirtualMachine,
) -> PyResult<PyStrRef> {
let replaced_text = zelf.regex.replace_all(text.as_bytes(), repl.as_bytes());
let replaced_text = String::from_utf8_lossy(&replaced_text).into_owned();
Ok(vm.ctx.new_str(replaced_text))
}
#[pymethod]
fn subn(&self, repl: PyStrRef, text: PyStrRef, vm: &VirtualMachine) -> PyResult {
self.sub(repl, text, vm)
fn subn(zelf: &Py<Self>, repl: PyStrRef, text: PyStrRef, vm: &VirtualMachine) -> PyResult {
Self::sub(zelf, repl, text, vm)
}
#[pygetset]
fn pattern(&self, vm: &VirtualMachine) -> PyResult<PyStrRef> {
Ok(vm.ctx.new_str(self.pattern.clone()))
fn pattern(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyStrRef> {
Ok(vm.ctx.new_str(zelf.pattern.clone()))
}
#[pymethod]
fn split(
&self,
zelf: &Py<Self>,
search_text: PyStrRef,
maxsplit: OptionalArg<PyIntRef>,
vm: &VirtualMachine,
) -> PyResult {
do_split(vm, self, search_text, maxsplit.into_option())
do_split(vm, zelf, search_text, maxsplit.into_option())
}
#[pymethod]
fn findall(&self, search_text: PyStrRef, vm: &VirtualMachine) -> PyResult {
do_findall(vm, self, search_text)
fn findall(zelf: &Py<Self>, search_text: PyStrRef, vm: &VirtualMachine) -> PyResult {
do_findall(vm, zelf, search_text)
}
}
#[pyclass]
impl PyMatch {
#[pymethod]
fn start(&self, group: OptionalArg, vm: &VirtualMachine) -> PyResult {
fn start(zelf: &Py<Self>, group: OptionalArg, vm: &VirtualMachine) -> PyResult {
let group = group.unwrap_or_else(|| vm.ctx.new_int(0).into());
let start = self.get_bounds(group, vm)?.map_or_else(
let start = zelf.get_bounds(group, vm)?.map_or_else(
|| vm.ctx.new_int(-1).into(),
|r| vm.ctx.new_int(r.start).into(),
);
@@ -375,9 +380,9 @@ mod re {
}
#[pymethod]
fn end(&self, group: OptionalArg, vm: &VirtualMachine) -> PyResult {
fn end(zelf: &Py<Self>, group: OptionalArg, vm: &VirtualMachine) -> PyResult {
let group = group.unwrap_or_else(|| vm.ctx.new_int(0).into());
let end = self.get_bounds(group, vm)?.map_or_else(
let end = zelf.get_bounds(group, vm)?.map_or_else(
|| vm.ctx.new_int(-1).into(),
|r| vm.ctx.new_int(r.end).into(),
);
@@ -413,19 +418,19 @@ mod re {
}
#[pymethod]
fn group(&self, groups: PosArgs, vm: &VirtualMachine) -> PyResult {
fn group(zelf: &Py<Self>, groups: PosArgs, vm: &VirtualMachine) -> PyResult {
let mut groups = groups.into_vec();
match groups.len() {
0 => Ok(self
.subgroup(self.captures[0].clone().unwrap())
0 => Ok(zelf
.subgroup(zelf.captures[0].clone().unwrap())
.to_pyobject(vm)),
1 => self
1 => zelf
.get_group(groups.pop().unwrap(), vm)
.map(|g| g.to_pyobject(vm)),
_ => {
let output: Result<Vec<_>, _> = groups
.into_iter()
.map(|id| self.get_group(id, vm).map(|g| g.to_pyobject(vm)))
.map(|id| zelf.get_group(id, vm).map(|g| g.to_pyobject(vm)))
.collect();
Ok(vm.ctx.new_tuple(output?)).into()
}
@@ -433,16 +438,16 @@ mod re {
}
#[pymethod]
fn groups(&self, default: OptionalArg, vm: &VirtualMachine) -> PyTupleRef {
fn groups(zelf: &Py<Self>, default: OptionalArg, vm: &VirtualMachine) -> PyTupleRef {
let default = default.into_option();
let groups = self
let groups = zelf
.captures
.iter()
.map(|capture| {
vm.unwrap_or_none(
capture
.as_ref()
.map(|bounds| self.subgroup(bounds.clone()).to_pyobject(vm))
.map(|bounds| zelf.subgroup(bounds.clone()).to_pyobject(vm))
.or_else(|| default.clone()),
)
})
+51 -34
View File
@@ -310,22 +310,22 @@ mod decl {
#[pyclass(flags(DISALLOW_INSTANTIATION))]
impl PyPoll {
#[pymethod]
fn register(&self, Fildes(fd): Fildes, eventmask: OptionalArg<EventMask>) {
fn register(zelf: &Py<Self>, Fildes(fd): Fildes, eventmask: OptionalArg<EventMask>) {
let mask = match eventmask {
OptionalArg::Present(event_mask) => event_mask.0,
OptionalArg::Missing => DEFAULT_EVENTS,
};
host_select::insert_poll_fd(&mut self.fds.lock(), fd, mask);
host_select::insert_poll_fd(&mut zelf.fds.lock(), fd, mask);
}
#[pymethod]
fn modify(
&self,
zelf: &Py<Self>,
Fildes(fd): Fildes,
eventmask: EventMask,
vm: &VirtualMachine,
) -> PyResult<()> {
let mut fds = self.fds.lock();
let mut fds = zelf.fds.lock();
// CPython raises KeyError if fd is not registered, match that behavior
let pfd = host_select::get_poll_fd_mut(&mut fds, fd)
.ok_or_else(|| vm.new_key_error(vm.ctx.new_int(fd).into()))?;
@@ -334,8 +334,12 @@ mod decl {
}
#[pymethod]
fn unregister(&self, Fildes(fd): Fildes, vm: &VirtualMachine) -> PyResult<()> {
let removed = host_select::remove_poll_fd(&mut self.fds.lock(), fd);
fn unregister(
zelf: &Py<Self>,
Fildes(fd): Fildes,
vm: &VirtualMachine,
) -> PyResult<()> {
let removed = host_select::remove_poll_fd(&mut zelf.fds.lock(), fd);
removed
.map(drop)
.ok_or_else(|| vm.new_key_error(vm.ctx.new_int(fd).into()))
@@ -343,11 +347,11 @@ mod decl {
#[pymethod]
fn poll(
&self,
zelf: &Py<Self>,
timeout: OptionalArg<TimeoutArg<true>>,
vm: &VirtualMachine,
) -> PyResult<Vec<PyObjectRef>> {
if self.poll_running.swap(true, Ordering::SeqCst) {
if zelf.poll_running.swap(true, Ordering::SeqCst) {
return Err(vm.new_runtime_error("concurrent poll() invocation"));
}
struct ClearRunning<'a>(&'a AtomicBool);
@@ -356,12 +360,12 @@ mod decl {
self.0.store(false, Ordering::Release);
}
}
let _running = ClearRunning(&self.poll_running);
let _running = ClearRunning(&zelf.poll_running);
// Poll a copy: the wait releases the GIL-equivalent and runs
// signal handlers, which can register or unregister on the same
// object, and a held lock would deadlock them.
let mut fds = self.fds.lock().clone();
let mut fds = zelf.fds.lock().clone();
let TimeoutArg(timeout) = timeout.unwrap_or_default();
let timeout_ms = match timeout {
Some(d) => host_select::duration_as_millis_ceiling(d)
@@ -481,8 +485,8 @@ mod decl {
}
#[pymethod]
fn close(&self) -> std::io::Result<()> {
let fd = self.epoll_fd.write().take();
fn close(zelf: &Py<Self>) -> std::io::Result<()> {
let fd = zelf.epoll_fd.write().take();
if let Some(fd) = fd {
host_select::epoll::close(fd)?;
}
@@ -490,8 +494,8 @@ mod decl {
}
#[pygetset]
fn closed(&self) -> bool {
self.epoll_fd.read().is_none()
fn closed(zelf: &Py<Self>) -> bool {
zelf.epoll_fd.read().is_none()
}
fn get_epoll(
@@ -503,8 +507,8 @@ mod decl {
}
#[pymethod]
fn fileno(&self, vm: &VirtualMachine) -> PyResult<i32> {
self.get_epoll(vm).map(|epoll_fd| epoll_fd.as_raw_fd())
fn fileno(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<i32> {
zelf.get_epoll(vm).map(|epoll_fd| epoll_fd.as_raw_fd())
}
#[pyclassmethod]
@@ -515,7 +519,7 @@ mod decl {
#[pymethod]
fn register(
&self,
zelf: &Py<Self>,
fd: Fildes,
eventmask: OptionalArg<u32>,
vm: &VirtualMachine,
@@ -527,26 +531,35 @@ mod decl {
| host_select::epoll::EventFlags::OUT)
.bits(),
};
let epoll_fd = &*self.get_epoll(vm)?;
let epoll_fd = &*zelf.get_epoll(vm)?;
host_select::epoll::add(epoll_fd, fd, fd.as_raw_fd() as u64, events)
.map_err(|e| e.into_pyexception(vm))
}
#[pymethod]
fn modify(&self, fd: Fildes, eventmask: u32, vm: &VirtualMachine) -> PyResult<()> {
let epoll_fd = &*self.get_epoll(vm)?;
fn modify(
zelf: &Py<Self>,
fd: Fildes,
eventmask: u32,
vm: &VirtualMachine,
) -> PyResult<()> {
let epoll_fd = &*zelf.get_epoll(vm)?;
host_select::epoll::modify(epoll_fd, fd, fd.as_raw_fd() as u64, eventmask)
.map_err(|e| e.into_pyexception(vm))
}
#[pymethod]
fn unregister(&self, fd: Fildes, vm: &VirtualMachine) -> PyResult<()> {
let epoll_fd = &*self.get_epoll(vm)?;
fn unregister(zelf: &Py<Self>, fd: Fildes, vm: &VirtualMachine) -> PyResult<()> {
let epoll_fd = &*zelf.get_epoll(vm)?;
host_select::epoll::delete(epoll_fd, fd).map_err(|e| e.into_pyexception(vm))
}
#[pymethod]
fn poll(&self, args: EpollPollArgs, vm: &VirtualMachine) -> PyResult<PyListRef> {
fn poll(
zelf: &Py<Self>,
args: EpollPollArgs,
vm: &VirtualMachine,
) -> PyResult<PyListRef> {
let poll::TimeoutArg(timeout) = args.timeout;
let maxevents = args.maxevents;
@@ -574,7 +587,7 @@ mod decl {
let mut events = Vec::<host_select::epoll::Event>::with_capacity(maxevents);
let epoll = &*self.get_epoll(vm)?;
let epoll = &*zelf.get_epoll(vm)?;
loop {
match vm.allow_threads(|| {
@@ -615,12 +628,12 @@ mod decl {
#[pymethod]
fn __exit__(
&self,
zelf: &Py<Self>,
_exc_type: OptionalArg,
_exc_value: OptionalArg,
_exc_tb: OptionalArg,
) -> std::io::Result<()> {
self.close()
Self::close(zelf)
}
}
}
@@ -902,8 +915,8 @@ mod decl {
#[pyclass(with(Constructor, Destructor))]
impl PyKqueue {
#[pymethod]
fn close(&self) -> io::Result<()> {
let cell = self.kqfd.write().take();
fn close(zelf: &Py<Self>) -> io::Result<()> {
let cell = zelf.kqfd.write().take();
if let Some(cell) = cell {
host_select::kqueue::close(&cell)?;
}
@@ -911,8 +924,8 @@ mod decl {
}
#[pygetset]
fn closed(&self) -> bool {
self.kqfd
fn closed(zelf: &Py<Self>) -> bool {
zelf.kqfd
.read()
.as_ref()
.is_none_or(|cell| host_select::kqueue::fd(cell) < 0)
@@ -933,8 +946,8 @@ mod decl {
}
#[pymethod]
fn fileno(&self, vm: &VirtualMachine) -> PyResult<i32> {
Self::fd_or_closed(self.kqfd.read().as_ref(), vm)
fn fileno(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<i32> {
Self::fd_or_closed(zelf.kqfd.read().as_ref(), vm)
}
#[pyclassmethod]
@@ -946,7 +959,11 @@ mod decl {
}
#[pymethod]
fn control(&self, args: KqueueControlArgs, vm: &VirtualMachine) -> PyResult<PyListRef> {
fn control(
zelf: &Py<Self>,
args: KqueueControlArgs,
vm: &VirtualMachine,
) -> PyResult<PyListRef> {
if args.maxevents < 0 {
return Err(vm.new_value_error(format!(
"Length of eventlist must be 0 or positive, got {}",
@@ -988,7 +1005,7 @@ mod decl {
let n = loop {
let result = {
let guard = self.kqfd.read();
let guard = zelf.kqfd.read();
let fd = Self::fd_or_closed(guard.as_ref(), vm)?;
vm.allow_threads(|| {
host_select::kqueue::kevent(
+111 -83
View File
@@ -1700,7 +1700,7 @@ mod _socket {
fn repr_str(zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<String> {
Ok(format!(
"<socket object, fd={}, family={}, type={}, proto={}>",
zelf.fileno(),
Self::fileno(zelf),
zelf.family.load(Ordering::Relaxed),
zelf.kind.load(Ordering::Relaxed),
zelf.proto.load(Ordering::Relaxed),
@@ -1725,7 +1725,7 @@ mod _socket {
vm,
);
}
let _ = zelf.close();
let _ = Self::close(zelf);
Ok(())
}
}
@@ -1853,21 +1853,29 @@ mod _socket {
}
#[pymethod]
fn connect(&self, object: PyObjectRef, vm: &VirtualMachine) -> Result<(), IoOrPyException> {
self.connect_inner(object, "connect", vm)
fn connect(
zelf: &Py<Self>,
object: PyObjectRef,
vm: &VirtualMachine,
) -> Result<(), IoOrPyException> {
zelf.connect_inner(object, "connect", vm)
}
#[pymethod]
fn connect_ex(&self, object: PyObjectRef, vm: &VirtualMachine) -> PyResult<i32> {
match self.connect_inner(object, "connect_ex", vm) {
fn connect_ex(zelf: &Py<Self>, object: PyObjectRef, vm: &VirtualMachine) -> PyResult<i32> {
match zelf.connect_inner(object, "connect_ex", vm) {
Ok(()) => Ok(0),
Err(err) => err.errno(),
}
}
#[pymethod]
fn bind(&self, object: PyObjectRef, vm: &VirtualMachine) -> Result<(), IoOrPyException> {
let sock_addr = self.extract_address(object, "bind", vm)?;
fn bind(
zelf: &Py<Self>,
object: PyObjectRef,
vm: &VirtualMachine,
) -> Result<(), IoOrPyException> {
let sock_addr = zelf.extract_address(object, "bind", vm)?;
if let Some(addr) = sock_addr.as_socket() {
vm.audit("socket.bind", || {
@@ -1879,36 +1887,36 @@ mod _socket {
})?;
}
Ok(self.sock()?.bind(&sock_addr)?)
Ok(zelf.sock()?.bind(&sock_addr)?)
}
#[pymethod]
fn listen(&self, backlog: OptionalArg<i32>) -> io::Result<()> {
fn listen(zelf: &Py<Self>, backlog: OptionalArg<i32>) -> io::Result<()> {
let backlog = backlog.unwrap_or(128);
let backlog = if backlog < 0 { 0 } else { backlog };
self.sock()?.listen(backlog)
zelf.sock()?.listen(backlog)
}
#[pymethod]
fn _accept(
&self,
zelf: &Py<Self>,
vm: &VirtualMachine,
) -> Result<(RawSocket, PyObjectRef), IoOrPyException> {
// Use accept_raw() instead of accept() to avoid socket2's set_common_flags()
// which tries to set SO_NOSIGPIPE and fails with EINVAL on Unix domain sockets on macOS
let (sock, addr) = self.sock_op(vm, SockWaitKind::Read, || {
self.sock_snapshot()?.accept_raw()
let (sock, addr) = zelf.sock_op(vm, SockWaitKind::Read, || {
zelf.sock_snapshot()?.accept_raw()
})?;
let fd = into_sock_fileno(sock);
Ok((
fd,
get_addr_tuple(&addr, self.proto.load(Ordering::Relaxed), vm),
get_addr_tuple(&addr, zelf.proto.load(Ordering::Relaxed), vm),
))
}
#[pymethod]
fn recv(
&self,
zelf: &Py<Self>,
bufsize: usize,
flags: OptionalArg<i32>,
vm: &VirtualMachine,
@@ -1918,8 +1926,8 @@ mod _socket {
buffer
.try_reserve_exact(bufsize)
.map_err(|_| vm.no_memory_error())?;
let n = self.sock_op(vm, SockWaitKind::Read, || {
self.sock_snapshot()?
let n = zelf.sock_op(vm, SockWaitKind::Read, || {
zelf.sock_snapshot()?
.recv_with_flags(buffer.spare_capacity_mut(), flags)
})?;
unsafe { buffer.set_len(n) };
@@ -1928,7 +1936,7 @@ mod _socket {
#[pymethod]
fn recv_into(
&self,
zelf: &Py<Self>,
buf: ArgMemoryBuffer,
nbytes: OptionalArg<isize>,
flags: OptionalArg<i32>,
@@ -1947,8 +1955,8 @@ mod _socket {
};
let mut scratch = alloc_recv_scratch(read_len, vm)?;
let n = self.sock_op(vm, SockWaitKind::Read, || {
self.sock_snapshot()?
let n = zelf.sock_op(vm, SockWaitKind::Read, || {
zelf.sock_snapshot()?
.recv_with_flags(&mut scratch.spare_capacity_mut()[..read_len], flags)
})?;
unsafe { scratch.set_len(n) };
@@ -1958,7 +1966,7 @@ mod _socket {
#[pymethod]
fn recvfrom(
&self,
zelf: &Py<Self>,
bufsize: isize,
flags: OptionalArg<i32>,
vm: &VirtualMachine,
@@ -1971,20 +1979,20 @@ mod _socket {
buffer
.try_reserve_exact(bufsize)
.map_err(|_| vm.no_memory_error())?;
let (n, addr) = self.sock_op(vm, SockWaitKind::Read, || {
self.sock_snapshot()?
let (n, addr) = zelf.sock_op(vm, SockWaitKind::Read, || {
zelf.sock_snapshot()?
.recv_from_with_flags(buffer.spare_capacity_mut(), flags)
})?;
unsafe { buffer.set_len(n) };
Ok((
buffer,
get_addr_tuple(&addr, self.proto.load(Ordering::Relaxed), vm),
get_addr_tuple(&addr, zelf.proto.load(Ordering::Relaxed), vm),
))
}
#[pymethod]
fn recvfrom_into(
&self,
zelf: &Py<Self>,
buf: ArgMemoryBuffer,
nbytes: OptionalArg<isize>,
flags: OptionalArg<i32>,
@@ -2006,21 +2014,21 @@ mod _socket {
};
let flags = flags.unwrap_or(0);
let mut scratch = alloc_recv_scratch(read_len, vm)?;
let (n, addr) = self.sock_op(vm, SockWaitKind::Read, || {
self.sock_snapshot()?
let (n, addr) = zelf.sock_op(vm, SockWaitKind::Read, || {
zelf.sock_snapshot()?
.recv_from_with_flags(&mut scratch.spare_capacity_mut()[..read_len], flags)
})?;
unsafe { scratch.set_len(n) };
buf.borrow_buf_mut()[..n].copy_from_slice(&scratch);
Ok((
n,
get_addr_tuple(&addr, self.proto.load(Ordering::Relaxed), vm),
get_addr_tuple(&addr, zelf.proto.load(Ordering::Relaxed), vm),
))
}
#[pymethod]
fn send(
&self,
zelf: &Py<Self>,
bytes: ArgBytesLike,
flags: OptionalArg<i32>,
vm: &VirtualMachine,
@@ -2028,21 +2036,21 @@ mod _socket {
let flags = flags.unwrap_or(0);
let buf = bytes.borrow_buf_unlocked(vm)?;
let buf = &*buf;
self.sock_op(vm, SockWaitKind::Write, || {
self.sock_snapshot()?.send_with_flags(buf, flags)
zelf.sock_op(vm, SockWaitKind::Write, || {
zelf.sock_snapshot()?.send_with_flags(buf, flags)
})
}
#[pymethod]
fn sendall(
&self,
zelf: &Py<Self>,
bytes: ArgBytesLike,
flags: OptionalArg<i32>,
vm: &VirtualMachine,
) -> Result<(), IoOrPyException> {
let flags = flags.unwrap_or(0);
let timeout = self.get_timeout().ok();
let timeout = zelf.get_timeout().ok();
let mut deadline = None;
let buf = bytes.borrow_buf_unlocked(vm)?;
@@ -2050,9 +2058,9 @@ mod _socket {
let mut buf_offset = 0;
// now we have like 3 layers of interrupt loop :)
while buf_offset < buf.len() {
self.sock_op_timeout_err(vm, SockWaitKind::Write, &mut deadline, timeout, || {
zelf.sock_op_timeout_err(vm, SockWaitKind::Write, &mut deadline, timeout, || {
let subbuf = &buf[buf_offset..];
buf_offset += self.sock_snapshot()?.send_with_flags(subbuf, flags)?;
buf_offset += zelf.sock_snapshot()?.send_with_flags(subbuf, flags)?;
Ok(())
})?;
vm.check_signals()?;
@@ -2061,7 +2069,11 @@ mod _socket {
}
#[pymethod]
fn sendto(&self, args: FuncArgs, vm: &VirtualMachine) -> Result<usize, IoOrPyException> {
fn sendto(
zelf: &Py<Self>,
args: FuncArgs,
vm: &VirtualMachine,
) -> Result<usize, IoOrPyException> {
if !args.kwargs.is_empty() {
return Err(vm
.new_type_error("sendto() takes no keyword arguments")
@@ -2081,18 +2093,18 @@ mod _socket {
}
};
let bytes = ArgBytesLike::try_from_object(vm, bytes)?;
let addr = self.extract_address(address, "sendto", vm)?;
let addr = zelf.extract_address(address, "sendto", vm)?;
let buf = bytes.borrow_buf_unlocked(vm)?;
let buf = &*buf;
self.sock_op(vm, SockWaitKind::Write, || {
self.sock_snapshot()?.send_to_with_flags(buf, &addr, flags)
zelf.sock_op(vm, SockWaitKind::Write, || {
zelf.sock_snapshot()?.send_to_with_flags(buf, &addr, flags)
})
}
#[cfg(all(unix, not(target_os = "redox")))]
#[pymethod]
fn sendmsg(
&self,
zelf: &Py<Self>,
buffers: PyObjectRef,
ancdata: OptionalArg<PyObjectRef>,
flags: OptionalArg<i32>,
@@ -2104,7 +2116,7 @@ mod _socket {
let sockaddr;
if let Some(addr) = addr.addr {
sockaddr = self
sockaddr = zelf
.extract_address(addr, "sendmsg", vm)
.map_err(|e| e.into_pyexception(vm))?;
msg = msg.with_addr(&sockaddr);
@@ -2161,8 +2173,8 @@ mod _socket {
}
}
self.sock_op(vm, SockWaitKind::Write, || {
let sock = self.sock_snapshot()?;
zelf.sock_op(vm, SockWaitKind::Write, || {
let sock = zelf.sock_snapshot()?;
sock.sendmsg(&msg, flags)
})
.map_err(|e| e.into_pyexception(vm))
@@ -2170,7 +2182,11 @@ mod _socket {
#[cfg(target_os = "linux")]
#[pymethod]
fn sendmsg_afalg(&self, args: SendmsgAfalgArgs, vm: &VirtualMachine) -> PyResult<usize> {
fn sendmsg_afalg(
zelf: &Py<Self>,
args: SendmsgAfalgArgs,
vm: &VirtualMachine,
) -> PyResult<usize> {
use std::os::fd::BorrowedFd;
let msg = args.msg;
@@ -2194,8 +2210,8 @@ mod _socket {
.collect::<Vec<_>>();
let iv = iv.map(|iv| iv.borrow_buf().to_vec());
self.sock_op(vm, SockWaitKind::Write, || {
let sock = self.sock_snapshot()?;
zelf.sock_op(vm, SockWaitKind::Write, || {
let sock = zelf.sock_snapshot()?;
let fd = unsafe { BorrowedFd::borrow_raw(sock_fileno(&sock)) };
host_socket::sendmsg_afalg(fd, &buffers, op, iv.as_deref(), assoclen, flags)
})
@@ -2205,7 +2221,7 @@ mod _socket {
#[cfg(all(unix, not(target_os = "redox")))]
#[pymethod]
fn recvmsg(
&self,
zelf: &Py<Self>,
bufsize: isize,
ancbufsize: OptionalArg<isize>,
flags: OptionalArg<i32>,
@@ -2223,9 +2239,9 @@ mod _socket {
let ancbufsize = ancbufsize as usize;
let flags = flags.unwrap_or(0);
let msg = self
let msg = zelf
.sock_op(vm, SockWaitKind::Read, || {
let sock = self.sock_snapshot()?;
let sock = zelf.sock_snapshot()?;
let fd = unsafe { std::os::fd::BorrowedFd::borrow_raw(sock_fileno(&sock)) };
host_socket::recvmsg(fd, bufsize, ancbufsize, flags)
})
@@ -2239,7 +2255,7 @@ mod _socket {
let storage: host_socket::raw::SockAddrStorage =
unsafe { core::mem::transmute(address.storage) };
let addr = unsafe { host_socket::raw::SockAddr::new(storage, address.len as _) };
get_addr_tuple(&addr, self.proto.load(Ordering::Relaxed), vm)
get_addr_tuple(&addr, zelf.proto.load(Ordering::Relaxed), vm)
} else {
vm.ctx.none()
};
@@ -2296,8 +2312,8 @@ mod _socket {
}
#[pymethod]
fn close(&self) -> io::Result<()> {
let sock = self.sock.write().take();
fn close(zelf: &Py<Self>) -> io::Result<()> {
let sock = zelf.sock.write().take();
if let Some(sock) = sock {
close_inner(into_sock_fileno(sock))?;
}
@@ -2306,60 +2322,64 @@ mod _socket {
#[pymethod]
#[inline]
fn detach(&self) -> i64 {
let sock = self.sock.write().take();
fn detach(zelf: &Py<Self>) -> i64 {
let sock = zelf.sock.write().take();
sock.map_or(INVALID_SOCKET as i64, |s| into_sock_fileno(s) as i64)
}
#[pymethod]
fn fileno(&self) -> i64 {
self.sock
fn fileno(zelf: &Py<Self>) -> i64 {
zelf.sock
.read()
.as_ref()
.map_or(INVALID_SOCKET as i64, |s| sock_fileno(s) as i64)
}
#[pymethod]
fn getsockname(&self, vm: &VirtualMachine) -> std::io::Result<PyObjectRef> {
let addr = self.sock()?.local_addr()?;
fn getsockname(zelf: &Py<Self>, vm: &VirtualMachine) -> std::io::Result<PyObjectRef> {
let addr = zelf.sock()?.local_addr()?;
Ok(get_addr_tuple(
&addr,
self.proto.load(Ordering::Relaxed),
zelf.proto.load(Ordering::Relaxed),
vm,
))
}
#[pymethod]
fn getpeername(&self, vm: &VirtualMachine) -> std::io::Result<PyObjectRef> {
let addr = self.sock()?.peer_addr()?;
fn getpeername(zelf: &Py<Self>, vm: &VirtualMachine) -> std::io::Result<PyObjectRef> {
let addr = zelf.sock()?.peer_addr()?;
Ok(get_addr_tuple(
&addr,
self.proto.load(Ordering::Relaxed),
zelf.proto.load(Ordering::Relaxed),
vm,
))
}
#[pymethod]
fn gettimeout(&self) -> Option<f64> {
let timeout = self.timeout.load();
fn gettimeout(zelf: &Py<Self>) -> Option<f64> {
let timeout = zelf.timeout.load();
if timeout >= 0.0 { Some(timeout) } else { None }
}
#[pymethod]
fn setblocking(&self, object: bool) -> io::Result<()> {
self.timeout.store(if object { -1.0 } else { 0.0 });
self.sock()?.set_nonblocking(!object)
fn setblocking(zelf: &Py<Self>, object: bool) -> io::Result<()> {
zelf.timeout.store(if object { -1.0 } else { 0.0 });
zelf.sock()?.set_nonblocking(!object)
}
#[pymethod]
fn getblocking(&self) -> bool {
self.timeout.load() != 0.0
fn getblocking(zelf: &Py<Self>) -> bool {
zelf.timeout.load() != 0.0
}
#[pymethod]
fn settimeout(&self, object: Option<ArgIntoFloat>, vm: &VirtualMachine) -> PyResult<()> {
fn settimeout(
zelf: &Py<Self>,
object: Option<ArgIntoFloat>,
vm: &VirtualMachine,
) -> PyResult<()> {
let timeout = match object {
Some(t) => {
let f = t.into_float();
@@ -2373,10 +2393,10 @@ mod _socket {
}
None => None,
};
self.timeout.store(timeout.unwrap_or(-1.0));
zelf.timeout.store(timeout.unwrap_or(-1.0));
// even if timeout is > 0 the socket needs to be nonblocking in order for us to select() on
// it
self.sock()
zelf.sock()
.map_err(|e| e.into_pyexception(vm))?
.set_nonblocking(timeout.is_some())
.map_err(|e| e.into_pyexception(vm))
@@ -2384,13 +2404,13 @@ mod _socket {
#[pymethod]
fn getsockopt(
&self,
zelf: &Py<Self>,
level: i32,
name: i32,
buflen: OptionalArg<i32>,
vm: &VirtualMachine,
) -> Result<PyObjectRef, IoOrPyException> {
let sock = self.sock()?;
let sock = zelf.sock()?;
let fd = sock_fileno(&sock);
let buflen = buflen.unwrap_or(0);
if buflen == 0 {
@@ -2407,14 +2427,14 @@ mod _socket {
#[pymethod]
fn setsockopt(
&self,
zelf: &Py<Self>,
level: i32,
name: i32,
value: Option<Either<ArgBytesLike, i32>>,
optlen: OptionalArg<u32>,
vm: &VirtualMachine,
) -> Result<(), IoOrPyException> {
let sock = self.sock()?;
let sock = zelf.sock()?;
let fd = sock_fileno(&sock);
match (value, optlen) {
(Some(Either::A(b)), OptionalArg::Missing) => {
@@ -2436,7 +2456,11 @@ mod _socket {
}
#[pymethod]
fn shutdown(&self, object: i32, vm: &VirtualMachine) -> Result<(), IoOrPyException> {
fn shutdown(
zelf: &Py<Self>,
object: i32,
vm: &VirtualMachine,
) -> Result<(), IoOrPyException> {
let how = match object {
c::SHUT_RD => Shutdown::Read,
c::SHUT_WR => Shutdown::Write,
@@ -2447,13 +2471,13 @@ mod _socket {
.into());
}
};
Ok(self.sock()?.shutdown(how)?)
Ok(zelf.sock()?.shutdown(how)?)
}
#[cfg(windows)]
#[pymethod]
fn ioctl(
&self,
zelf: &Py<Self>,
cmd: PyObjectRef,
option: PyObjectRef,
vm: &VirtualMachine,
@@ -2461,7 +2485,7 @@ mod _socket {
use crate::vm::builtins::PyInt;
use crate::vm::convert::TryFromObject;
let sock = self.sock()?;
let sock = zelf.sock()?;
let fd = sock_fileno(&sock);
// Convert cmd to u32, returning ValueError for invalid/negative values
@@ -2523,8 +2547,12 @@ mod _socket {
#[cfg(windows)]
#[pymethod]
fn share(&self, process_id: u32, _vm: &VirtualMachine) -> Result<Vec<u8>, IoOrPyException> {
let sock = self.sock()?;
fn share(
zelf: &Py<Self>,
process_id: u32,
_vm: &VirtualMachine,
) -> Result<Vec<u8>, IoOrPyException> {
let sock = zelf.sock()?;
let fd = sock_fileno(&sock);
host_socket::share_socket(fd as _, process_id).map_err(Into::into)
}
+50 -37
View File
@@ -239,29 +239,33 @@ mod _socket {
}
#[pymethod]
fn fileno(&self) -> i32 {
if *self.closed.lock() { -1 } else { 0 }
fn fileno(zelf: &Py<Self>) -> i32 {
if *zelf.closed.lock() { -1 } else { 0 }
}
#[pymethod]
fn close(&self) {
*self.closed.lock() = true;
fn close(zelf: &Py<Self>) {
*zelf.closed.lock() = true;
}
#[pymethod]
fn detach(&self) -> i32 {
*self.closed.lock() = true;
fn detach(zelf: &Py<Self>) -> i32 {
*zelf.closed.lock() = true;
-1
}
#[pymethod]
fn gettimeout(&self) -> Option<f64> {
*self.timeout.lock()
fn gettimeout(zelf: &Py<Self>) -> Option<f64> {
*zelf.timeout.lock()
}
#[pymethod]
fn settimeout(&self, timeout: Option<ArgIntoFloat>, vm: &VirtualMachine) -> PyResult<()> {
*self.timeout.lock() = match timeout {
fn settimeout(
zelf: &Py<Self>,
timeout: Option<ArgIntoFloat>,
vm: &VirtualMachine,
) -> PyResult<()> {
*zelf.timeout.lock() = match timeout {
None => None,
Some(value) => {
let value = value.into_float();
@@ -278,20 +282,25 @@ mod _socket {
}
#[pymethod]
fn setblocking(&self, blocking: bool) {
*self.timeout.lock() = if blocking { None } else { Some(0.0) };
fn setblocking(zelf: &Py<Self>, blocking: bool) {
*zelf.timeout.lock() = if blocking { None } else { Some(0.0) };
}
#[pymethod]
fn getblocking(&self) -> bool {
!matches!(*self.timeout.lock(), Some(t) if t == 0.0)
fn getblocking(zelf: &Py<Self>) -> bool {
!matches!(*zelf.timeout.lock(), Some(t) if t == 0.0)
}
#[pymethod]
fn getsockopt(&self, level: i32, optname: i32, vm: &VirtualMachine) -> PyResult<i32> {
self.ensure_open(vm)?;
fn getsockopt(
zelf: &Py<Self>,
level: i32,
optname: i32,
vm: &VirtualMachine,
) -> PyResult<i32> {
zelf.ensure_open(vm)?;
if level == SOL_SOCKET && optname == SO_TYPE {
return Ok(self.kind.load(Ordering::Relaxed));
return Ok(zelf.kind.load(Ordering::Relaxed));
}
if level == SOL_SOCKET && optname == SO_ERROR {
return Ok(0);
@@ -301,67 +310,71 @@ mod _socket {
#[pymethod]
fn setsockopt(
&self,
zelf: &Py<Self>,
_level: i32,
_optname: i32,
_value: OptionalArg<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<()> {
self.ensure_open(vm)?;
zelf.ensure_open(vm)?;
Ok(())
}
#[pymethod]
fn bind(&self, _address: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
self.ensure_open(vm)?;
fn bind(zelf: &Py<Self>, _address: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
zelf.ensure_open(vm)?;
Err(unsupported(vm, "bind").into())
}
#[pymethod]
fn connect(&self, _address: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
self.ensure_open(vm)?;
fn connect(zelf: &Py<Self>, _address: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
zelf.ensure_open(vm)?;
Err(unsupported(vm, "connect").into())
}
#[pymethod]
fn listen(&self, _backlog: OptionalArg<i32>, vm: &VirtualMachine) -> PyResult<()> {
self.ensure_open(vm)?;
fn listen(
zelf: &Py<Self>,
_backlog: OptionalArg<i32>,
vm: &VirtualMachine,
) -> PyResult<()> {
zelf.ensure_open(vm)?;
Err(unsupported(vm, "listen").into())
}
#[pymethod]
fn _accept(&self, vm: &VirtualMachine) -> PyResult<(PyObjectRef, PyObjectRef)> {
self.ensure_open(vm)?;
fn _accept(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<(PyObjectRef, PyObjectRef)> {
zelf.ensure_open(vm)?;
Err(unsupported(vm, "accept").into())
}
#[pymethod]
fn send(&self, _data: ArgBytesLike, vm: &VirtualMachine) -> PyResult<usize> {
self.ensure_open(vm)?;
fn send(zelf: &Py<Self>, _data: ArgBytesLike, vm: &VirtualMachine) -> PyResult<usize> {
zelf.ensure_open(vm)?;
Err(unsupported(vm, "send").into())
}
#[pymethod]
fn recv(&self, _bufsize: i32, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
self.ensure_open(vm)?;
fn recv(zelf: &Py<Self>, _bufsize: i32, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
zelf.ensure_open(vm)?;
Err(unsupported(vm, "recv").into())
}
#[pymethod]
fn shutdown(&self, _how: i32, vm: &VirtualMachine) -> PyResult<()> {
self.ensure_open(vm)?;
fn shutdown(zelf: &Py<Self>, _how: i32, vm: &VirtualMachine) -> PyResult<()> {
zelf.ensure_open(vm)?;
Err(unsupported(vm, "shutdown").into())
}
#[pymethod]
fn getsockname(&self, vm: &VirtualMachine) -> PyResult<(String, i32)> {
self.ensure_open(vm)?;
fn getsockname(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<(String, i32)> {
zelf.ensure_open(vm)?;
Ok(("0.0.0.0".to_owned(), 0))
}
#[pymethod]
fn getpeername(&self, vm: &VirtualMachine) -> PyResult<(String, i32)> {
self.ensure_open(vm)?;
fn getpeername(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<(String, i32)> {
zelf.ensure_open(vm)?;
Err(unsupported(vm, "getpeername").into())
}
}
+233 -198
View File
File diff suppressed because it is too large. Load diff
+131 -95
View File
@@ -212,98 +212,98 @@ mod _ssl {
#[pyclass(with(Constructor, Representable), flags(BASETYPE))]
impl PySSLContext {
#[pygetset]
fn check_hostname(&self) -> bool {
*self.check_hostname.read()
fn check_hostname(zelf: &Py<Self>) -> bool {
*zelf.check_hostname.read()
}
#[pygetset(setter)]
fn set_check_hostname(&self, value: bool) {
*self.check_hostname.write() = value;
if value && *self.verify_mode.read() == CERT_NONE {
*self.verify_mode.write() = CERT_REQUIRED;
fn set_check_hostname(zelf: &Py<Self>, value: bool) {
*zelf.check_hostname.write() = value;
if value && *zelf.verify_mode.read() == CERT_NONE {
*zelf.verify_mode.write() = CERT_REQUIRED;
}
}
#[pygetset]
fn _host_flags(&self) -> i32 {
*self.host_flags.read()
fn _host_flags(zelf: &Py<Self>) -> i32 {
*zelf.host_flags.read()
}
#[pygetset(setter)]
fn set__host_flags(&self, value: i32) {
*self.host_flags.write() = value;
fn set__host_flags(zelf: &Py<Self>, value: i32) {
*zelf.host_flags.write() = value;
}
#[pygetset]
fn verify_mode(&self) -> i32 {
*self.verify_mode.read()
fn verify_mode(zelf: &Py<Self>) -> i32 {
*zelf.verify_mode.read()
}
#[pygetset(setter)]
fn set_verify_mode(&self, mode: i32, vm: &VirtualMachine) -> PyResult<()> {
fn set_verify_mode(zelf: &Py<Self>, mode: i32, vm: &VirtualMachine) -> PyResult<()> {
if !(CERT_NONE..=CERT_REQUIRED).contains(&mode) {
return Err(vm.new_value_error("invalid verify mode"));
}
if mode == CERT_NONE && *self.check_hostname.read() {
if mode == CERT_NONE && *zelf.check_hostname.read() {
return Err(vm.new_value_error(
"Cannot set verify_mode to CERT_NONE when check_hostname is enabled",
));
}
*self.verify_mode.write() = mode;
*zelf.verify_mode.write() = mode;
Ok(())
}
#[pygetset]
fn protocol(&self) -> i32 {
self.protocol
fn protocol(zelf: &Py<Self>) -> i32 {
zelf.protocol
}
#[pygetset]
fn verify_flags(&self) -> i32 {
*self.verify_flags.read()
fn verify_flags(zelf: &Py<Self>) -> i32 {
*zelf.verify_flags.read()
}
#[pygetset(setter)]
fn set_verify_flags(&self, value: i32) {
*self.verify_flags.write() = value;
fn set_verify_flags(zelf: &Py<Self>, value: i32) {
*zelf.verify_flags.write() = value;
}
#[pygetset]
fn post_handshake_auth(&self) -> bool {
*self.post_handshake_auth.read()
fn post_handshake_auth(zelf: &Py<Self>) -> bool {
*zelf.post_handshake_auth.read()
}
#[pygetset(setter)]
fn set_post_handshake_auth(&self, value: bool) {
*self.post_handshake_auth.write() = value;
fn set_post_handshake_auth(zelf: &Py<Self>, value: bool) {
*zelf.post_handshake_auth.write() = value;
}
#[pygetset]
fn num_tickets(&self) -> i32 {
*self.num_tickets.read()
fn num_tickets(zelf: &Py<Self>) -> i32 {
*zelf.num_tickets.read()
}
#[pygetset(setter)]
fn set_num_tickets(&self, value: i32, vm: &VirtualMachine) -> PyResult<()> {
fn set_num_tickets(zelf: &Py<Self>, value: i32, vm: &VirtualMachine) -> PyResult<()> {
if value < 0 {
return Err(vm.new_value_error("num_tickets must be a non-negative integer"));
}
if self.protocol != PROTOCOL_TLS_SERVER {
if zelf.protocol != PROTOCOL_TLS_SERVER {
return Err(
vm.new_value_error("num_tickets can only be set on server-side contexts")
);
}
*self.num_tickets.write() = value;
*zelf.num_tickets.write() = value;
Ok(())
}
#[pygetset]
fn options(&self) -> i32 {
*self.options.read()
fn options(zelf: &Py<Self>) -> i32 {
*zelf.options.read()
}
#[pygetset(setter)]
fn set_options(&self, value: i32, vm: &VirtualMachine) -> PyResult<()> {
fn set_options(zelf: &Py<Self>, value: i32, vm: &VirtualMachine) -> PyResult<()> {
if value < 0 {
return Err(vm.new_value_error("options must be non-negative"));
}
@@ -313,7 +313,7 @@ mod _ssl {
| OP_NO_TLSv1_1
| OP_NO_TLSv1_2
| OP_NO_TLSv1_3;
let old_opts = *self.options.read();
let old_opts = *zelf.options.read();
let set = !old_opts & value;
if (set & opt_no) != 0 {
_warnings::warn(
@@ -323,18 +323,18 @@ mod _ssl {
vm,
)?;
}
*self.options.write() = value;
*zelf.options.write() = value;
Ok(())
}
#[pygetset]
fn minimum_version(&self) -> i32 {
let v = *self.minimum_version.read();
fn minimum_version(zelf: &Py<Self>) -> i32 {
let v = *zelf.minimum_version.read();
if v == 0 { PROTO_MINIMUM_SUPPORTED } else { v }
}
#[pygetset(setter)]
fn set_minimum_version(&self, value: i32, vm: &VirtualMachine) -> PyResult<()> {
fn set_minimum_version(zelf: &Py<Self>, value: i32, vm: &VirtualMachine) -> PyResult<()> {
if value != 0
&& value != -2
&& value != -1
@@ -342,18 +342,18 @@ mod _ssl {
{
return Err(vm.new_value_error(format!("invalid protocol version: {value}")));
}
*self.minimum_version.write() = value;
*zelf.minimum_version.write() = value;
Ok(())
}
#[pygetset]
fn maximum_version(&self) -> i32 {
let v = *self.maximum_version.read();
fn maximum_version(zelf: &Py<Self>) -> i32 {
let v = *zelf.maximum_version.read();
if v == 0 { PROTO_MAXIMUM_SUPPORTED } else { v }
}
#[pygetset(setter)]
fn set_maximum_version(&self, value: i32, vm: &VirtualMachine) -> PyResult<()> {
fn set_maximum_version(zelf: &Py<Self>, value: i32, vm: &VirtualMachine) -> PyResult<()> {
if value != 0
&& value != -2
&& value != -1
@@ -361,18 +361,18 @@ mod _ssl {
{
return Err(vm.new_value_error(format!("invalid protocol version: {value}")));
}
*self.maximum_version.write() = value;
*zelf.maximum_version.write() = value;
Ok(())
}
#[pygetset]
fn sni_callback(&self) -> Option<PyObjectRef> {
self.sni_callback.read().clone()
fn sni_callback(zelf: &Py<Self>) -> Option<PyObjectRef> {
zelf.sni_callback.read().clone()
}
#[pygetset(setter)]
fn set_sni_callback(
&self,
zelf: &Py<Self>,
callback: Option<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<()> {
@@ -382,32 +382,32 @@ mod _ssl {
{
return Err(vm.new_type_error("sni_callback must be callable or None"));
}
*self.sni_callback.write() = callback;
*zelf.sni_callback.write() = callback;
Ok(())
}
#[pymethod]
fn set_servername_callback(
&self,
zelf: &Py<Self>,
callback: Option<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<()> {
self.set_sni_callback(callback, vm)
Self::set_sni_callback(zelf, callback, vm)
}
#[pygetset]
fn security_level(&self) -> i32 {
fn security_level(_zelf: &Py<Self>) -> i32 {
2
}
#[pygetset]
fn _msg_callback(&self) -> Option<PyObjectRef> {
self.msg_callback.read().clone()
fn _msg_callback(zelf: &Py<Self>) -> Option<PyObjectRef> {
zelf.msg_callback.read().clone()
}
#[pygetset(setter)]
fn set__msg_callback(
&self,
zelf: &Py<Self>,
callback: Option<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<()> {
@@ -417,49 +417,57 @@ mod _ssl {
{
return Err(vm.new_type_error("msg_callback must be callable or None"));
}
*self.msg_callback.write() = callback;
*zelf.msg_callback.write() = callback;
Ok(())
}
#[pygetset]
fn keylog_filename(&self) -> Option<PyObjectRef> {
self.keylog_filename.read().clone()
fn keylog_filename(zelf: &Py<Self>) -> Option<PyObjectRef> {
zelf.keylog_filename.read().clone()
}
#[pygetset(setter)]
fn set_keylog_filename(&self, value: PySetterValue, vm: &VirtualMachine) -> PyResult<()> {
fn set_keylog_filename(
zelf: &Py<Self>,
value: PySetterValue,
vm: &VirtualMachine,
) -> PyResult<()> {
let PySetterValue::Assign(value) = value else {
return Err(vm.new_attribute_error("attribute 'keylog_filename' cannot be deleted"));
};
if vm.is_none(&value) {
*self.keylog_filename.write() = None;
*zelf.keylog_filename.write() = None;
return Ok(());
}
*self.keylog_filename.write() = Some(value);
*zelf.keylog_filename.write() = Some(value);
Ok(())
}
#[pymethod]
fn _set_alpn_protocols(&self, protos: ArgBytesLike, vm: &VirtualMachine) -> PyResult<()> {
fn _set_alpn_protocols(
zelf: &Py<Self>,
protos: ArgBytesLike,
vm: &VirtualMachine,
) -> PyResult<()> {
let bytes = protos.borrow_buf();
let alpn_list = parse_length_prefixed_alpn(&bytes, vm)?;
*self.alpn_protocols.write() = alpn_list;
*zelf.alpn_protocols.write() = alpn_list;
Ok(())
}
#[pymethod]
fn set_default_verify_paths(&self, _vm: &VirtualMachine) -> PyResult<()> {
fn set_default_verify_paths(_zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<()> {
Ok(())
}
#[pymethod]
fn load_default_certs(&self, _vm: &VirtualMachine) -> PyResult<()> {
fn load_default_certs(_zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<()> {
Ok(())
}
#[pymethod]
fn load_verify_locations(
&self,
_zelf: &Py<Self>,
args: LoadVerifyLocationsArgs,
vm: &VirtualMachine,
) -> PyResult<()> {
@@ -473,38 +481,54 @@ mod _ssl {
}
#[pymethod]
fn load_cert_chain(&self, _args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
fn load_cert_chain(_zelf: &Py<Self>, _args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
ssl_error(vm, UNAVAILABLE)
}
#[pymethod]
fn set_ciphers(&self, _ciphers: PyUtf8StrRef, vm: &VirtualMachine) -> PyResult<()> {
fn set_ciphers(
_zelf: &Py<Self>,
_ciphers: PyUtf8StrRef,
vm: &VirtualMachine,
) -> PyResult<()> {
ssl_error(vm, UNAVAILABLE)
}
#[pymethod]
fn set_ecdh_curve(&self, _name: PyUtf8StrRef, vm: &VirtualMachine) -> PyResult<()> {
fn set_ecdh_curve(
_zelf: &Py<Self>,
_name: PyUtf8StrRef,
vm: &VirtualMachine,
) -> PyResult<()> {
ssl_error(vm, UNAVAILABLE)
}
#[pymethod]
fn load_dh_params(&self, _filepath: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
fn load_dh_params(
_zelf: &Py<Self>,
_filepath: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
ssl_error(vm, UNAVAILABLE)
}
#[pymethod]
fn get_ciphers(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
fn get_ciphers(_zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
Ok(vm.ctx.new_list(Vec::new()).into())
}
#[pymethod]
fn get_ca_certs(&self, args: GetCertArgs, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
fn get_ca_certs(
_zelf: &Py<Self>,
args: GetCertArgs,
vm: &VirtualMachine,
) -> PyResult<PyObjectRef> {
let _ = args.binary_form;
Ok(vm.ctx.new_list(Vec::new()).into())
}
#[pymethod]
fn cert_store_stats(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
fn cert_store_stats(_zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
let dict = vm.ctx.new_dict();
dict.set_item("x509", vm.ctx.new_int(0).into(), vm)?;
dict.set_item("crl", vm.ctx.new_int(0).into(), vm)?;
@@ -513,7 +537,7 @@ mod _ssl {
}
#[pymethod]
fn session_stats(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
fn session_stats(_zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
let dict = vm.ctx.new_dict();
dict.set_item("number", vm.ctx.new_int(0).into(), vm)?;
dict.set_item("connect", vm.ctx.new_int(0).into(), vm)?;
@@ -530,22 +554,30 @@ mod _ssl {
}
#[pymethod]
fn _wrap_socket(&self, _args: FuncArgs, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
fn _wrap_socket(
_zelf: &Py<Self>,
_args: FuncArgs,
vm: &VirtualMachine,
) -> PyResult<PyObjectRef> {
ssl_error(vm, UNAVAILABLE)
}
#[pymethod]
fn _wrap_bio(&self, args: WrapBioArgs, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
fn _wrap_bio(
zelf: &Py<Self>,
args: WrapBioArgs,
vm: &VirtualMachine,
) -> PyResult<PyObjectRef> {
if let Some(hostname) = args.server_hostname {
validate_hostname(hostname.as_str(), vm)?;
}
if args.server_side.unwrap_or(false) && self.protocol == PROTOCOL_TLS_CLIENT {
if args.server_side.unwrap_or(false) && zelf.protocol == PROTOCOL_TLS_CLIENT {
return ssl_error(
vm,
"Cannot create a server socket with a PROTOCOL_TLS_CLIENT context",
);
}
if !args.server_side.unwrap_or(false) && self.protocol == PROTOCOL_TLS_SERVER {
if !args.server_side.unwrap_or(false) && zelf.protocol == PROTOCOL_TLS_SERVER {
return ssl_error(
vm,
"Cannot create a client socket with a PROTOCOL_TLS_SERVER context",
@@ -674,8 +706,12 @@ mod _ssl {
#[pyclass(with(Constructor, Representable), flags(BASETYPE))]
impl PyMemoryBIO {
#[pymethod]
fn read(&self, len: OptionalArg<i32>, vm: &VirtualMachine) -> PyResult<PyBytesRef> {
let mut bio = self.inner.lock();
fn read(
zelf: &Py<Self>,
len: OptionalArg<i32>,
vm: &VirtualMachine,
) -> PyResult<PyBytesRef> {
let mut bio = zelf.inner.lock();
let read_len = match len {
OptionalArg::Present(n) if n >= 0 => n as usize,
OptionalArg::Present(_) | OptionalArg::Missing => bio.pending(),
@@ -684,7 +720,7 @@ mod _ssl {
}
#[pymethod]
fn write(&self, buf: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
fn write(zelf: &Py<Self>, buf: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
if let Ok(mem_view) = buf.get_attr("c_contiguous", vm) {
let is_contiguous: bool = mem_view.try_to_bool(vm)?;
if !is_contiguous {
@@ -693,7 +729,7 @@ mod _ssl {
}
let bytes_like = ArgBytesLike::try_from_object(vm, buf)?;
let data = bytes_like.borrow_buf();
self.inner.lock().write(&data).map_err(|err| {
zelf.inner.lock().write(&data).map_err(|err| {
vm.new_os_subtype_error(
PySSLError::class(&vm.ctx).to_owned(),
None,
@@ -704,18 +740,18 @@ mod _ssl {
}
#[pymethod]
fn write_eof(&self, _vm: &VirtualMachine) {
self.inner.lock().write_eof();
fn write_eof(zelf: &Py<Self>, _vm: &VirtualMachine) {
zelf.inner.lock().write_eof();
}
#[pygetset]
fn pending(&self) -> i32 {
self.inner.lock().pending() as i32
fn pending(zelf: &Py<Self>) -> i32 {
zelf.inner.lock().pending() as i32
}
#[pygetset]
fn eof(&self) -> bool {
self.inner.lock().eof()
fn eof(zelf: &Py<Self>) -> bool {
zelf.inner.lock().eof()
}
}
@@ -748,28 +784,28 @@ mod _ssl {
#[pyclass(flags(BASETYPE), with(Comparable, Representable))]
impl PySSLSession {
#[pygetset]
fn time(&self) -> i64 {
fn time(_zelf: &Py<Self>) -> i64 {
0
}
#[pygetset]
fn timeout(&self) -> i64 {
self.lifetime as i64
fn timeout(zelf: &Py<Self>) -> i64 {
zelf.lifetime as i64
}
#[pygetset]
fn ticket_lifetime_hint(&self) -> i64 {
self.lifetime as i64
fn ticket_lifetime_hint(zelf: &Py<Self>) -> i64 {
zelf.lifetime as i64
}
#[pygetset]
fn id(&self, vm: &VirtualMachine) -> PyBytesRef {
vm.ctx.new_bytes(self.session_id.clone())
fn id(zelf: &Py<Self>, vm: &VirtualMachine) -> PyBytesRef {
vm.ctx.new_bytes(zelf.session_id.clone())
}
#[pygetset]
fn has_ticket(&self) -> bool {
self.has_ticket
fn has_ticket(zelf: &Py<Self>) -> bool {
zelf.has_ticket
}
}
+18 -10
View File
@@ -322,19 +322,23 @@ mod _tkinter {
}
#[pymethod]
fn getvar(&self, args: TkAppGetVarArgs, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
self.var_invoke();
self.inner_getvar(args, tk_sys::TCL_LEAVE_ERR_MSG, vm)
fn getvar(
zelf: &Py<Self>,
args: TkAppGetVarArgs,
vm: &VirtualMachine,
) -> PyResult<PyObjectRef> {
zelf.var_invoke();
zelf.inner_getvar(args, tk_sys::TCL_LEAVE_ERR_MSG, vm)
}
#[pymethod]
fn globalgetvar(
&self,
zelf: &Py<Self>,
args: TkAppGetVarArgs,
vm: &VirtualMachine,
) -> PyResult<PyObjectRef> {
self.var_invoke();
self.inner_getvar(
zelf.var_invoke();
zelf.inner_getvar(
args,
tk_sys::TCL_LEAVE_ERR_MSG | tk_sys::TCL_GLOBAL_ONLY,
vm,
@@ -342,7 +346,11 @@ mod _tkinter {
}
#[pymethod]
fn getint(&self, arg: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
fn getint(
_zelf: &Py<Self>,
arg: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<PyObjectRef> {
if let Some(int) = arg.downcast_ref::<PyInt>() {
return Ok(PyObjectRef::from(vm.ctx.new_int(int.as_bigint().clone())));
}
@@ -357,7 +365,7 @@ mod _tkinter {
}
// TODO: Fix arguments
#[pymethod]
fn mainloop(&self, threshold: Option<i32>) -> PyResult<()> {
fn mainloop(zelf: &Py<Self>, threshold: Option<i32>) -> PyResult<()> {
let threshold = threshold.unwrap_or(0);
// self.dispatching = true;
QUIT_MAIN_LOOP.store(false, Ordering::Relaxed);
@@ -365,7 +373,7 @@ mod _tkinter {
&& !QUIT_MAIN_LOOP.load(Ordering::Relaxed)
&& !ERROR_IN_CMD.load(Ordering::Relaxed)
{
if self.threaded {
if zelf.threaded {
unsafe { tk_sys::Tcl_DoOneEvent(0 as _) };
} else {
unsafe { tk_sys::Tcl_DoOneEvent(tk_sys::TCL_DONT_WAIT as _) };
@@ -377,7 +385,7 @@ mod _tkinter {
}
#[pymethod]
fn quit(&self) {
fn quit(_zelf: &Py<Self>) {
QUIT_MAIN_LOOP.store(true, Ordering::Relaxed);
}
}
+39 -31
View File
@@ -110,14 +110,14 @@ mod unicodedata {
#[pyclass(flags(DISALLOW_INSTANTIATION))]
impl Ucd {
#[pymethod]
fn category(&self, chr: PyStrRef, vm: &VirtualMachine) -> PyResult<&'static str> {
self.extract_char(&chr, vm).map(|c| self.inner.category(c))
fn category(zelf: &Py<Self>, chr: PyStrRef, vm: &VirtualMachine) -> PyResult<&'static str> {
zelf.extract_char(&chr, vm).map(|c| zelf.inner.category(c))
}
#[pymethod]
fn lookup(&self, name: PyStrRef, vm: &VirtualMachine) -> PyResult<String> {
fn lookup(zelf: &Py<Self>, name: PyStrRef, vm: &VirtualMachine) -> PyResult<String> {
if let Some(name_str) = name.to_str()
&& let Some(found) = self.inner.lookup(name_str)
&& let Some(found) = zelf.inner.lookup(name_str)
{
return Ok(match found {
unicode_core::LookupResult::Character(ch) => ch.to_string(),
@@ -133,13 +133,13 @@ mod unicodedata {
#[pymethod]
fn name(
&self,
zelf: &Py<Self>,
chr: PyStrRef,
default: OptionalArg<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult {
if let Some(name) = self.extract_char(&chr, vm)?.to_char().and_then(|ch| {
self.inner
if let Some(name) = zelf.extract_char(&chr, vm)?.to_char().and_then(|ch| {
zelf.inner
.membership(ch)
.then(|| unicode_core::character_name(ch))
.flatten()
@@ -150,52 +150,60 @@ mod unicodedata {
}
#[pymethod]
fn bidirectional(&self, chr: PyStrRef, vm: &VirtualMachine) -> PyResult<&'static str> {
self.extract_char(&chr, vm)
.map(|c| self.inner.bidirectional(c))
fn bidirectional(
zelf: &Py<Self>,
chr: PyStrRef,
vm: &VirtualMachine,
) -> PyResult<&'static str> {
zelf.extract_char(&chr, vm)
.map(|c| zelf.inner.bidirectional(c))
}
#[pymethod]
fn east_asian_width(&self, chr: PyStrRef, vm: &VirtualMachine) -> PyResult<&'static str> {
self.extract_char(&chr, vm)
.map(|c| self.inner.east_asian_width(c))
fn east_asian_width(
zelf: &Py<Self>,
chr: PyStrRef,
vm: &VirtualMachine,
) -> PyResult<&'static str> {
zelf.extract_char(&chr, vm)
.map(|c| zelf.inner.east_asian_width(c))
}
#[pymethod]
fn normalize(&self, form: NormalizeFormArg, unistr: PyStrRef) -> Wtf8Buf {
fn normalize(_zelf: &Py<Self>, form: NormalizeFormArg, unistr: PyStrRef) -> Wtf8Buf {
unicode_core::normalize(form.0, unistr.as_wtf8())
}
#[pymethod]
fn is_normalized(&self, form: NormalizeFormArg, unistr: PyStrRef) -> bool {
fn is_normalized(_zelf: &Py<Self>, form: NormalizeFormArg, unistr: PyStrRef) -> bool {
unicode_core::is_normalized(form.0, unistr.as_wtf8())
}
#[pymethod]
fn mirrored(&self, chr: PyStrRef, vm: &VirtualMachine) -> PyResult<i32> {
self.extract_char(&chr, vm).map(|c| self.inner.mirrored(c))
fn mirrored(zelf: &Py<Self>, chr: PyStrRef, vm: &VirtualMachine) -> PyResult<i32> {
zelf.extract_char(&chr, vm).map(|c| zelf.inner.mirrored(c))
}
#[pymethod]
fn combining(&self, chr: PyStrRef, vm: &VirtualMachine) -> PyResult<u8> {
self.extract_char(&chr, vm).map(|c| self.inner.combining(c))
fn combining(zelf: &Py<Self>, chr: PyStrRef, vm: &VirtualMachine) -> PyResult<u8> {
zelf.extract_char(&chr, vm).map(|c| zelf.inner.combining(c))
}
#[pymethod]
fn decomposition(&self, chr: PyStrRef, vm: &VirtualMachine) -> PyResult<String> {
self.extract_char(&chr, vm)
.map(|c| self.inner.decomposition(c))
fn decomposition(zelf: &Py<Self>, chr: PyStrRef, vm: &VirtualMachine) -> PyResult<String> {
zelf.extract_char(&chr, vm)
.map(|c| zelf.inner.decomposition(c))
}
#[pymethod]
fn digit(
&self,
zelf: &Py<Self>,
chr: PyStrRef,
default: OptionalArg<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<Option<PyObjectRef>> {
let ch = self.extract_char(&chr, vm)?;
self.inner
let ch = zelf.extract_char(&chr, vm)?;
zelf.inner
.digit(ch)
.map(|value| vm.ctx.new_int(value).into())
.or_else(|| default.present())
@@ -205,13 +213,13 @@ mod unicodedata {
#[pymethod]
fn decimal(
&self,
zelf: &Py<Self>,
chr: PyStrRef,
default: OptionalArg<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<Option<PyObjectRef>> {
let ch = self.extract_char(&chr, vm)?;
self.inner
let ch = zelf.extract_char(&chr, vm)?;
zelf.inner
.decimal(ch)
.map(|value| vm.ctx.new_int(value).into())
.or_else(|| default.present())
@@ -221,13 +229,13 @@ mod unicodedata {
#[pymethod]
fn numeric(
&self,
zelf: &Py<Self>,
chr: PyStrRef,
default: OptionalArg<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<Option<PyObjectRef>> {
let ch = self.extract_char(&chr, vm)?;
self.inner
let ch = zelf.extract_char(&chr, vm)?;
zelf.inner
.numeric(ch)
.map(|value| vm.ctx.new_float(value).into())
.or_else(|| default.present())
+48 -32
View File
@@ -204,22 +204,26 @@ mod zlib {
}
#[pygetset]
fn eof(&self) -> bool {
self.inner.lock().decompress.eof()
fn eof(zelf: &Py<Self>) -> bool {
zelf.inner.lock().decompress.eof()
}
#[pygetset]
fn unused_data(&self) -> PyBytesRef {
self.inner.lock().unused_data.clone()
fn unused_data(zelf: &Py<Self>) -> PyBytesRef {
zelf.inner.lock().unused_data.clone()
}
#[pygetset]
fn unconsumed_tail(&self) -> PyBytesRef {
self.inner.lock().unconsumed_tail.clone()
fn unconsumed_tail(zelf: &Py<Self>) -> PyBytesRef {
zelf.inner.lock().unconsumed_tail.clone()
}
#[pymethod]
fn decompress(&self, args: DecompressArgs, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
fn decompress(
zelf: &Py<Self>,
args: DecompressArgs,
vm: &VirtualMachine,
) -> PyResult<Vec<u8>> {
let max_length: usize = args
.raw_max_length()
.unwrap_or(0)
@@ -228,14 +232,18 @@ mod zlib {
let max_length = (max_length != 0).then_some(max_length);
let data = &*args.data();
let mut inner = self.inner.lock();
let mut inner = zelf.inner.lock();
let result = inner.decompress.decompress(data, max_length);
inner.sync_visible_state(vm);
result.map_err(|err| new_zlib_error(err, vm))
}
#[pymethod]
fn flush(&self, length: OptionalArg<PySsize>, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
fn flush(
zelf: &Py<Self>,
length: OptionalArg<PySsize>,
vm: &VirtualMachine,
) -> PyResult<Vec<u8>> {
let length = match length {
OptionalArg::Present(value) if value <= 0 => {
return Err(vm.new_value_error("length must be greater than zero"));
@@ -244,25 +252,25 @@ mod zlib {
OptionalArg::Missing => DEF_BUF_SIZE,
};
let mut inner = self.inner.lock();
let mut inner = zelf.inner.lock();
let result = inner.decompress.flush(length);
inner.sync_visible_state(vm);
result.map_err(|err| new_zlib_error(err, vm))
}
#[pymethod]
fn copy(&self, vm: &VirtualMachine) -> PyResult<Self> {
self.copy_inner(vm)
fn copy(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<Self> {
zelf.copy_inner(vm)
}
#[pymethod(name = "__copy__")]
fn copy_dunder(&self, vm: &VirtualMachine) -> PyResult<Self> {
self.copy_inner(vm)
fn copy_dunder(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<Self> {
zelf.copy_inner(vm)
}
#[pymethod(name = "__deepcopy__")]
fn deepcopy(&self, _memo: PyObjectRef, vm: &VirtualMachine) -> PyResult<Self> {
self.copy_inner(vm)
fn deepcopy(zelf: &Py<Self>, _memo: PyObjectRef, vm: &VirtualMachine) -> PyResult<Self> {
zelf.copy_inner(vm)
}
}
@@ -339,32 +347,36 @@ mod zlib {
}
#[pymethod]
fn compress(&self, data: ArgBytesLike, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
data.with_ref(|data| self.inner.lock().compress(data))
fn compress(zelf: &Py<Self>, data: ArgBytesLike, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
data.with_ref(|data| zelf.inner.lock().compress(data))
.map_err(|err| new_zlib_error(err, vm))
}
#[pymethod]
fn flush(&self, mode: OptionalArg<i32>, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
self.inner
fn flush(
zelf: &Py<Self>,
mode: OptionalArg<i32>,
vm: &VirtualMachine,
) -> PyResult<Vec<u8>> {
zelf.inner
.lock()
.flush(mode.unwrap_or(Z_FINISH))
.map_err(|err| new_zlib_error(err, vm))
}
#[pymethod]
fn copy(&self, vm: &VirtualMachine) -> PyResult<Self> {
self.copy_inner(vm)
fn copy(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<Self> {
zelf.copy_inner(vm)
}
#[pymethod(name = "__copy__")]
fn copy_dunder(&self, vm: &VirtualMachine) -> PyResult<Self> {
self.copy_inner(vm)
fn copy_dunder(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<Self> {
zelf.copy_inner(vm)
}
#[pymethod(name = "__deepcopy__")]
fn deepcopy(&self, _memo: PyObjectRef, vm: &VirtualMachine) -> PyResult<Self> {
self.copy_inner(vm)
fn deepcopy(zelf: &Py<Self>, _memo: PyObjectRef, vm: &VirtualMachine) -> PyResult<Self> {
zelf.copy_inner(vm)
}
}
@@ -470,22 +482,26 @@ mod zlib {
#[pyclass(with(Constructor))]
impl ZlibDecompressor {
#[pymethod]
fn decompress(&self, args: DecompressorArgs, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
fn decompress(
zelf: &Py<Self>,
args: DecompressorArgs,
vm: &VirtualMachine,
) -> PyResult<Vec<u8>> {
let max_length = args.max_length();
let data = &*args.data();
let mut inner = self.inner.lock();
let mut inner = zelf.inner.lock();
let result = inner.decompress.decompress(data, max_length);
self.eof.store(inner.decompress.eof(), Ordering::Relaxed);
self.needs_input
zelf.eof.store(inner.decompress.eof(), Ordering::Relaxed);
zelf.needs_input
.store(inner.decompress.needs_input(), Ordering::Relaxed);
let stale = self.unused_data.deref().is_none_or(|obj| {
let stale = zelf.unused_data.deref().is_none_or(|obj| {
obj.downcast_ref::<PyBytes>()
.is_none_or(|bytes| bytes.as_bytes() != inner.decompress.unused_data())
});
if stale {
let bytes = vm.ctx.new_bytes(inner.decompress.unused_data().to_vec());
let _previous = unsafe { self.unused_data.swap(Some(bytes.into())) };
let _previous = unsafe { zelf.unused_data.swap(Some(bytes.into())) };
}
result.map_err(|err| match err {
backend::DecompressError::Zlib(err) => new_zlib_error(err, vm),
+2 -2
View File
@@ -3295,8 +3295,8 @@ mod tests {
#[pyclass]
impl LayoutDerived {
#[pygetset]
fn extra(&self) -> Option<u64> {
self.extra
fn extra(zelf: &Py<Self>) -> Option<u64> {
zelf.extra
}
}
+12 -7
View File
@@ -5,7 +5,7 @@ mod _browser {
use crate::{convert, js_module::PyPromise, vm_class::weak_vm, wasm_builtins::window};
use js_sys::Promise;
use rustpython_vm::{
PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
builtins::{PyDictRef, PyStrRef},
class::PyClassImpl,
convert::ToPyObject,
@@ -166,8 +166,8 @@ mod _browser {
#[pyclass]
impl Document {
#[pymethod]
fn query(&self, query: PyStrRef, vm: &VirtualMachine) -> PyResult {
let elem = self
fn query(zelf: &Py<Self>, query: PyStrRef, vm: &VirtualMachine) -> PyResult {
let elem = zelf
.doc
.query_selector(query.expect_str())
.map_err(|err| convert::js_py_typeerror(vm, err))?
@@ -199,20 +199,25 @@ mod _browser {
impl Element {
#[pymethod]
fn get_attr(
&self,
zelf: &Py<Self>,
attr: PyStrRef,
default: OptionalArg<PyObjectRef>,
vm: &VirtualMachine,
) -> PyObjectRef {
match self.elem.get_attribute(attr.expect_str()) {
match zelf.elem.get_attribute(attr.expect_str()) {
Some(s) => vm.ctx.new_str(s).into(),
None => default.unwrap_or_none(vm),
}
}
#[pymethod]
fn set_attr(&self, attr: PyStrRef, value: PyStrRef, vm: &VirtualMachine) -> PyResult<()> {
self.elem
fn set_attr(
zelf: &Py<Self>,
attr: PyStrRef,
value: PyStrRef,
vm: &VirtualMachine,
) -> PyResult<()> {
zelf.elem
.set_attribute(attr.expect_str(), value.expect_str())
.map_err(|err| convert::js_py_typeerror(vm, err))
}
+72 -55
View File
@@ -106,37 +106,49 @@ mod _js {
}
#[pymethod]
fn null(&self) -> Self {
fn null(_zelf: &Py<Self>) -> Self {
Self::new(JsValue::NULL)
}
#[pymethod]
fn undefined(&self) -> Self {
fn undefined(_zelf: &Py<Self>) -> Self {
Self::new(JsValue::UNDEFINED)
}
#[pymethod]
fn new_from_str(&self, s: PyStrRef) -> Self {
fn new_from_str(_zelf: &Py<Self>, s: PyStrRef) -> Self {
Self::new(s.expect_str())
}
#[pymethod]
fn new_from_float(&self, n: PyRef<PyFloat>) -> Self {
fn new_from_float(_zelf: &Py<Self>, n: PyRef<PyFloat>) -> Self {
Self::new(n.to_f64())
}
#[pymethod]
fn new_closure(&self, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<JsClosure> {
fn new_closure(
_zelf: &Py<Self>,
obj: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<JsClosure> {
JsClosure::new(obj, false, vm)
}
#[pymethod]
fn new_closure_once(&self, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<JsClosure> {
fn new_closure_once(
_zelf: &Py<Self>,
obj: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<JsClosure> {
JsClosure::new(obj, true, vm)
}
#[pymethod]
fn new_object(&self, opts: NewObjectOptions, vm: &VirtualMachine) -> PyResult<Self> {
fn new_object(
_zelf: &Py<Self>,
opts: NewObjectOptions,
vm: &VirtualMachine,
) -> PyResult<Self> {
let value = if let Some(proto) = opts.prototype {
if let Some(proto) = proto.value.dyn_ref::<Object>() {
Object::create(proto)
@@ -153,15 +165,15 @@ mod _js {
}
#[pymethod]
fn has_prop(&self, name: JsProperty, vm: &VirtualMachine) -> PyResult<bool> {
has_prop(&self.value, &name.into_js_value()).map_err(|err| new_js_error(vm, err))
fn has_prop(zelf: &Py<Self>, name: JsProperty, vm: &VirtualMachine) -> PyResult<bool> {
has_prop(&zelf.value, &name.into_js_value()).map_err(|err| new_js_error(vm, err))
}
#[pymethod]
fn get_prop(&self, name: JsProperty, vm: &VirtualMachine) -> PyResult<Self> {
fn get_prop(zelf: &Py<Self>, name: JsProperty, vm: &VirtualMachine) -> PyResult<Self> {
let name = &name.into_js_value();
if has_prop(&self.value, name).map_err(|err| new_js_error(vm, err))? {
get_prop(&self.value, name)
if has_prop(&zelf.value, name).map_err(|err| new_js_error(vm, err))? {
get_prop(&zelf.value, name)
.map(Self::new)
.map_err(|err| new_js_error(vm, err))
} else {
@@ -171,23 +183,23 @@ mod _js {
#[pymethod]
fn set_prop(
&self,
zelf: &Py<Self>,
name: JsProperty,
value: PyJsValueRef,
vm: &VirtualMachine,
) -> PyResult<()> {
set_prop(&self.value, &name.into_js_value(), &value.value)
set_prop(&zelf.value, &name.into_js_value(), &value.value)
.map_err(|err| new_js_error(vm, err))
}
#[pymethod]
fn call(
&self,
zelf: &Py<Self>,
args: PosArgs<PyJsValueRef>,
opts: CallOptions,
vm: &VirtualMachine,
) -> PyResult<Self> {
let func = self
let func = zelf
.value
.dyn_ref::<js_sys::Function>()
.ok_or_else(|| vm.new_type_error("JS value is not callable"))?;
@@ -201,25 +213,25 @@ mod _js {
#[pymethod]
fn call_method(
&self,
zelf: &Py<Self>,
name: JsProperty,
args: PosArgs<PyJsValueRef>,
vm: &VirtualMachine,
) -> PyResult<Self> {
let js_args = args.iter().map(|x| -> &Self { x }).collect::<Array>();
call_method(&self.value, &name.into_js_value(), &js_args)
call_method(&zelf.value, &name.into_js_value(), &js_args)
.map(Self::new)
.map_err(|err| new_js_error(vm, err))
}
#[pymethod]
fn construct(
&self,
zelf: &Py<Self>,
args: PosArgs<PyJsValueRef>,
opts: NewObjectOptions,
vm: &VirtualMachine,
) -> PyResult<Self> {
let ctor = self
let ctor = zelf
.value
.dyn_ref::<js_sys::Function>()
.ok_or_else(|| vm.new_type_error("JS value is not callable"))?;
@@ -240,35 +252,35 @@ mod _js {
}
#[pymethod]
fn as_str(&self) -> Option<String> {
self.value.as_string()
fn as_str(zelf: &Py<Self>) -> Option<String> {
zelf.value.as_string()
}
#[pymethod]
fn as_float(&self) -> Option<f64> {
self.value.as_f64()
fn as_float(zelf: &Py<Self>) -> Option<f64> {
zelf.value.as_f64()
}
#[pymethod]
fn as_bool(&self) -> Option<bool> {
self.value.as_bool()
fn as_bool(zelf: &Py<Self>) -> Option<bool> {
zelf.value.as_bool()
}
#[pymethod(name = "typeof")]
fn type_of(&self) -> String {
type_of(&self.value)
fn type_of(zelf: &Py<Self>) -> String {
type_of(&zelf.value)
}
// Checks that `typeof self == "object" && self !== null`. Use instead
// of `value.typeof() == "object"`
#[pymethod]
fn is_object(&self) -> bool {
self.value.is_object()
fn is_object(zelf: &Py<Self>) -> bool {
zelf.value.is_object()
}
#[pymethod]
fn instanceof(&self, rhs: PyJsValueRef, vm: &VirtualMachine) -> PyResult<bool> {
instance_of(&self.value, &rhs.value).map_err(|err| new_js_error(vm, err))
fn instanceof(zelf: &Py<Self>, rhs: PyJsValueRef, vm: &VirtualMachine) -> PyResult<bool> {
instance_of(&zelf.value, &rhs.value).map_err(|err| new_js_error(vm, err))
}
}
@@ -349,40 +361,40 @@ mod _js {
}
#[pygetset]
fn value(&self) -> Option<PyJsValueRef> {
self.closure
fn value(zelf: &Py<Self>) -> Option<PyJsValueRef> {
zelf.closure
.borrow()
.as_ref()
.map(|(_, js_val)| js_val.clone())
}
#[pygetset]
fn destroyed(&self) -> bool {
self.destroyed.get()
fn destroyed(zelf: &Py<Self>) -> bool {
zelf.destroyed.get()
}
#[pygetset]
fn detached(&self) -> bool {
self.detached.get()
fn detached(zelf: &Py<Self>) -> bool {
zelf.detached.get()
}
#[pymethod]
fn destroy(&self, vm: &VirtualMachine) -> PyResult<()> {
let (closure, _) = self.closure.replace(None).ok_or_else(|| {
fn destroy(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
let (closure, _) = zelf.closure.replace(None).ok_or_else(|| {
vm.new_value_error("can't destroy closure has already been destroyed or detached")
})?;
drop(closure);
self.destroyed.set(true);
zelf.destroyed.set(true);
Ok(())
}
#[pymethod]
fn detach(&self, vm: &VirtualMachine) -> PyResult<PyJsValueRef> {
let (closure, js_val) = self.closure.replace(None).ok_or_else(|| {
fn detach(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyJsValueRef> {
let (closure, js_val) = zelf.closure.replace(None).ok_or_else(|| {
vm.new_value_error("can't detach closure has already been detached or destroyed")
})?;
closure.forget();
self.detached.set(true);
zelf.detached.set(true);
Ok(js_val)
}
}
@@ -496,15 +508,15 @@ mod _js {
}
#[pymethod]
fn then(&self, args: ThenArgs, vm: &VirtualMachine) -> PyResult<Self> {
fn then(zelf: &Py<Self>, args: ThenArgs, vm: &VirtualMachine) -> PyResult<Self> {
let ThenArgs {
on_fulfill,
on_reject,
} = args;
if on_fulfill.is_none() && on_reject.is_none() {
return Ok(self.clone());
return Ok(<Self as Clone>::clone(zelf));
}
match &self.value {
match &zelf.value {
PromiseKind::Js(prom) => {
let weak_vm = weak_vm(vm);
let prom = JsFuture::from(prom.clone());
@@ -548,18 +560,19 @@ mod _js {
),
PromiseKind::PyResolved(res) => match on_fulfill {
Some(resolve) => Self::cast_result(resolve.invoke((res.clone(),), vm), vm),
None => Ok(self.clone()),
None => Ok(<Self as Clone>::clone(zelf)),
},
PromiseKind::PyRejected(err) => match on_reject {
Some(reject) => Self::cast_result(reject.invoke((err.clone(),), vm), vm),
None => Ok(self.clone()),
None => Ok(<Self as Clone>::clone(zelf)),
},
}
}
#[pymethod]
fn catch(&self, args: CatchArgs, vm: &VirtualMachine) -> PyResult<Self> {
self.then(
fn catch(zelf: &Py<Self>, args: CatchArgs, vm: &VirtualMachine) -> PyResult<Self> {
Self::then(
zelf,
ThenArgs {
on_fulfill: None,
on_reject: args.on_reject,
@@ -591,8 +604,12 @@ mod _js {
#[pyclass(with(IterNext))]
impl AwaitPromise {
#[pymethod]
fn send(&self, val: Option<PyObjectRef>, vm: &VirtualMachine) -> PyResult<PyIterReturn> {
match self.obj.take() {
fn send(
zelf: &Py<Self>,
val: Option<PyObjectRef>,
vm: &VirtualMachine,
) -> PyResult<PyIterReturn> {
match zelf.obj.take() {
Some(prom) => {
if val.is_some() {
Err(vm.new_type_error("can't send non-None value to an AwaitPromise"))
@@ -606,7 +623,7 @@ mod _js {
#[pymethod]
fn throw(
&self,
_zelf: &Py<Self>,
exc_type: PyObjectRef,
exc_val: OptionalArg,
exc_tb: OptionalArg,
@@ -625,7 +642,7 @@ mod _js {
impl IterNext for AwaitPromise {
fn next(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyIterReturn> {
zelf.send(None, vm)
Self::send(zelf, None, vm)
}
}
+108 -92
View File
@@ -252,8 +252,12 @@ mod _ssl {
#[pyclass(with(Constructor), flags(BASETYPE))]
impl PyMemoryBIO {
#[pymethod]
fn read(&self, args: MemoryBioReadArgs, vm: &VirtualMachine) -> PyResult<PyBytesRef> {
let mut bio = self.inner.lock();
fn read(
zelf: &Py<Self>,
args: MemoryBioReadArgs,
vm: &VirtualMachine,
) -> PyResult<PyBytesRef> {
let mut bio = zelf.inner.lock();
let read_len = match args.len {
OptionalArg::Present(n) if n >= 0 => n as usize,
OptionalArg::Present(n) => {
@@ -265,26 +269,26 @@ mod _ssl {
}
#[pymethod]
fn write(&self, buf: ArgBytesLike, vm: &VirtualMachine) -> PyResult<usize> {
self.inner
fn write(zelf: &Py<Self>, buf: ArgBytesLike, vm: &VirtualMachine) -> PyResult<usize> {
zelf.inner
.lock()
.write(&buf.borrow_buf())
.map_err(|err| ssl_error(vm, err.to_string()).upcast())
}
#[pymethod]
fn write_eof(&self) {
self.inner.lock().write_eof();
fn write_eof(zelf: &Py<Self>) {
zelf.inner.lock().write_eof();
}
#[pygetset]
fn pending(&self) -> i32 {
self.inner.lock().pending() as i32
fn pending(zelf: &Py<Self>) -> i32 {
zelf.inner.lock().pending() as i32
}
#[pygetset]
fn eof(&self) -> bool {
self.inner.lock().eof()
fn eof(zelf: &Py<Self>) -> bool {
zelf.inner.lock().eof()
}
}
@@ -306,27 +310,27 @@ mod _ssl {
#[pyclass(flags(BASETYPE))]
impl PySSLSession {
#[pygetset]
fn id(&self) -> Vec<u8> {
fn id(_zelf: &Py<Self>) -> Vec<u8> {
Vec::new()
}
#[pygetset]
fn time(&self) -> i32 {
fn time(_zelf: &Py<Self>) -> i32 {
0
}
#[pygetset]
fn timeout(&self) -> i32 {
fn timeout(_zelf: &Py<Self>) -> i32 {
0
}
#[pygetset]
fn ticket_lifetime_hint(&self) -> i32 {
fn ticket_lifetime_hint(_zelf: &Py<Self>) -> i32 {
0
}
#[pygetset]
fn has_ticket(&self) -> bool {
fn has_ticket(_zelf: &Py<Self>) -> bool {
false
}
}
@@ -374,134 +378,146 @@ mod _ssl {
#[pyclass(with(Constructor), flags(BASETYPE))]
impl PySSLContext {
#[pygetset]
fn check_hostname(&self) -> bool {
*self.check_hostname.read()
fn check_hostname(zelf: &Py<Self>) -> bool {
*zelf.check_hostname.read()
}
#[pygetset(setter)]
fn set_check_hostname(&self, value: bool) {
*self.check_hostname.write() = value;
fn set_check_hostname(zelf: &Py<Self>, value: bool) {
*zelf.check_hostname.write() = value;
}
#[pygetset]
fn verify_mode(&self) -> i32 {
*self.verify_mode.read()
fn verify_mode(zelf: &Py<Self>) -> i32 {
*zelf.verify_mode.read()
}
#[pygetset(setter)]
fn set_verify_mode(&self, mode: i32, vm: &VirtualMachine) -> PyResult<()> {
fn set_verify_mode(zelf: &Py<Self>, mode: i32, vm: &VirtualMachine) -> PyResult<()> {
if !(CERT_NONE..=CERT_REQUIRED).contains(&mode) {
return Err(vm.new_value_error(format!("invalid value for verify_mode")));
}
if mode == CERT_NONE && *self.check_hostname.read() {
if mode == CERT_NONE && *zelf.check_hostname.read() {
return Err(vm.new_value_error(
"Cannot set verify_mode to CERT_NONE when check_hostname is enabled",
));
}
*self.verify_mode.write() = mode;
*zelf.verify_mode.write() = mode;
Ok(())
}
#[pygetset]
fn verify_flags(&self) -> i32 {
*self.verify_flags.read()
fn verify_flags(zelf: &Py<Self>) -> i32 {
*zelf.verify_flags.read()
}
#[pygetset(setter)]
fn set_verify_flags(&self, flags: i32) {
*self.verify_flags.write() = flags;
fn set_verify_flags(zelf: &Py<Self>, flags: i32) {
*zelf.verify_flags.write() = flags;
}
#[pygetset]
fn options(&self) -> i32 {
*self.options.read()
fn options(zelf: &Py<Self>) -> i32 {
*zelf.options.read()
}
#[pygetset(setter)]
fn set_options(&self, options: i32) {
*self.options.write() = options;
fn set_options(zelf: &Py<Self>, options: i32) {
*zelf.options.write() = options;
}
#[pygetset]
fn minimum_version(&self) -> i32 {
*self.minimum_version.read()
fn minimum_version(zelf: &Py<Self>) -> i32 {
*zelf.minimum_version.read()
}
#[pygetset(setter)]
fn set_minimum_version(&self, value: i32) {
*self.minimum_version.write() = value;
fn set_minimum_version(zelf: &Py<Self>, value: i32) {
*zelf.minimum_version.write() = value;
}
#[pygetset]
fn maximum_version(&self) -> i32 {
*self.maximum_version.read()
fn maximum_version(zelf: &Py<Self>) -> i32 {
*zelf.maximum_version.read()
}
#[pygetset(setter)]
fn set_maximum_version(&self, value: i32) {
*self.maximum_version.write() = value;
fn set_maximum_version(zelf: &Py<Self>, value: i32) {
*zelf.maximum_version.write() = value;
}
#[pygetset]
fn _host_flags(&self) -> i32 {
*self.host_flags.read()
fn _host_flags(zelf: &Py<Self>) -> i32 {
*zelf.host_flags.read()
}
#[pygetset(setter)]
fn set__host_flags(&self, flags: i32) {
*self.host_flags.write() = flags;
fn set__host_flags(zelf: &Py<Self>, flags: i32) {
*zelf.host_flags.write() = flags;
}
#[pygetset]
fn protocol(&self) -> i32 {
self.protocol
fn protocol(zelf: &Py<Self>) -> i32 {
zelf.protocol
}
#[pygetset]
fn security_level(&self) -> i32 {
fn security_level(_zelf: &Py<Self>) -> i32 {
2
}
#[pymethod]
fn set_ciphers(&self, _ciphers: PyUtf8StrRef) {}
fn set_ciphers(_zelf: &Py<Self>, _ciphers: PyUtf8StrRef) {}
#[pymethod]
fn _set_alpn_protocols(&self, protos: ArgBytesLike, vm: &VirtualMachine) -> PyResult<()> {
fn _set_alpn_protocols(
zelf: &Py<Self>,
protos: ArgBytesLike,
vm: &VirtualMachine,
) -> PyResult<()> {
let parsed = rustpython_host_env::ssl::parse_length_prefixed_alpn(&protos.borrow_buf())
.map_err(|err| vm.new_value_error(err.0))?;
*self.alpn_protocols.write() = parsed;
*zelf.alpn_protocols.write() = parsed;
Ok(())
}
#[pymethod]
fn set_default_verify_paths(&self) {}
fn set_default_verify_paths(_zelf: &Py<Self>) {}
#[pymethod]
fn load_verify_locations(&self, args: LoadVerifyLocationsArgs) {
fn load_verify_locations(_zelf: &Py<Self>, args: LoadVerifyLocationsArgs) {
let _ = (args.cafile, args.capath, args.cadata);
}
#[pymethod]
fn load_cert_chain(&self, args: LoadCertChainArgs, vm: &VirtualMachine) -> PyResult<()> {
fn load_cert_chain(
_zelf: &Py<Self>,
args: LoadCertChainArgs,
vm: &VirtualMachine,
) -> PyResult<()> {
let _ = (args.certfile, args.keyfile, args.password);
Err(ssl_error(vm, "certificate files are unavailable").upcast())
}
#[pymethod]
fn load_dh_params(&self, _path: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
fn load_dh_params(
_zelf: &Py<Self>,
_path: PyObjectRef,
vm: &VirtualMachine,
) -> PyResult<()> {
Err(ssl_error(vm, "DH parameters are unavailable").upcast())
}
#[pymethod]
fn set_ecdh_curve(&self, _name: PyObjectRef) {}
fn set_ecdh_curve(_zelf: &Py<Self>, _name: PyObjectRef) {}
#[pymethod]
fn cert_store_stats(&self, vm: &VirtualMachine) -> PyObjectRef {
fn cert_store_stats(_zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
vm.ctx.new_dict().into()
}
#[pymethod]
fn get_ca_certs(&self, args: CaCertsArgs, vm: &VirtualMachine) -> PyResult {
fn get_ca_certs(_zelf: &Py<Self>, args: CaCertsArgs, vm: &VirtualMachine) -> PyResult {
let _ = args.binary_form;
Ok(vm.ctx.new_list(Vec::new()).into())
}
@@ -721,9 +737,9 @@ mod _ssl {
}
#[pymethod]
fn do_handshake(&self, vm: &VirtualMachine) -> PyResult<()> {
self.pump(vm)?;
let connected = self
fn do_handshake(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
zelf.pump(vm)?;
let connected = zelf
.connection
.lock()
.as_ref()
@@ -736,13 +752,13 @@ mod _ssl {
}
#[pymethod]
fn read(&self, len: OptionalArg<i32>, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
fn read(zelf: &Py<Self>, len: OptionalArg<i32>, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
let size = len.unwrap_or(1024);
if size < 0 {
return Err(vm.new_value_error("size should not be negative"));
}
self.pump(vm)?;
let mut connection = self.connection.lock();
zelf.pump(vm)?;
let mut connection = zelf.connection.lock();
let conn = connection
.as_mut()
.ok_or_else(|| ssl_error(vm, "SSL connection is closed").upcast())?;
@@ -761,78 +777,78 @@ mod _ssl {
}
#[pymethod]
fn write(&self, data: ArgBytesLike, vm: &VirtualMachine) -> PyResult<usize> {
self.ensure_conn(vm)?;
fn write(zelf: &Py<Self>, data: ArgBytesLike, vm: &VirtualMachine) -> PyResult<usize> {
zelf.ensure_conn(vm)?;
let bytes = data.borrow_buf();
let mut connection = self.connection.lock();
let mut connection = zelf.connection.lock();
let conn = connection
.as_mut()
.ok_or_else(|| ssl_error(vm, "SSL connection is closed").upcast())?;
let n = std::io::Write::write(&mut conn.inner_mut().writer(), &bytes)
.map_err(|err| ssl_error(vm, err.to_string()).upcast())?;
drop(connection);
self.pump(vm)?;
zelf.pump(vm)?;
Ok(n)
}
#[pymethod]
fn pending(&self) -> usize {
self.connection
fn pending(zelf: &Py<Self>) -> usize {
zelf.connection
.lock()
.as_mut()
.map_or(0, TlsConnection::pending_plaintext)
}
#[pymethod]
fn shutdown(&self, vm: &VirtualMachine) -> PyResult<()> {
if let Some(conn) = self.connection.lock().as_mut() {
fn shutdown(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
if let Some(conn) = zelf.connection.lock().as_mut() {
conn.send_close_notify();
}
self.pump(vm)
zelf.pump(vm)
}
#[pygetset]
fn context(&self) -> PyRef<PySSLContext> {
self.context.read().clone()
fn context(zelf: &Py<Self>) -> PyRef<PySSLContext> {
zelf.context.read().clone()
}
#[pygetset(setter)]
fn set_context(&self, ctx: PyRef<PySSLContext>) {
*self.context.write() = ctx;
fn set_context(zelf: &Py<Self>, ctx: PyRef<PySSLContext>) {
*zelf.context.write() = ctx;
}
#[pygetset]
fn server_hostname(&self) -> Option<String> {
self.server_hostname.clone()
fn server_hostname(zelf: &Py<Self>) -> Option<String> {
zelf.server_hostname.clone()
}
#[pygetset]
fn server_side(&self) -> bool {
self.server_side
fn server_side(zelf: &Py<Self>) -> bool {
zelf.server_side
}
#[pygetset]
fn session(&self, vm: &VirtualMachine) -> PyObjectRef {
fn session(_zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
vm.ctx.none()
}
#[pygetset(setter)]
fn set_session(&self, _session: PyObjectRef) {}
fn set_session(_zelf: &Py<Self>, _session: PyObjectRef) {}
#[pygetset]
fn session_reused(&self) -> bool {
fn session_reused(_zelf: &Py<Self>) -> bool {
false
}
#[pymethod]
fn getpeercert(
&self,
zelf: &Py<Self>,
args: GetCertArgs,
vm: &VirtualMachine,
) -> PyResult<Option<PyObjectRef>> {
let binary = args.der;
let der = {
let guard = self.connection.lock();
let guard = zelf.connection.lock();
let Some(conn) = guard.as_ref() else {
return Err(vm.new_value_error("handshake not done yet"));
};
@@ -852,23 +868,23 @@ mod _ssl {
}
#[pymethod]
fn cipher(&self, vm: &VirtualMachine) -> PyObjectRef {
fn cipher(_zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
vm.ctx.none()
}
#[pymethod]
fn shared_ciphers(&self, vm: &VirtualMachine) -> PyObjectRef {
fn shared_ciphers(_zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
vm.ctx.none()
}
#[pymethod]
fn compression(&self, vm: &VirtualMachine) -> PyObjectRef {
fn compression(_zelf: &Py<Self>, vm: &VirtualMachine) -> PyObjectRef {
vm.ctx.none()
}
#[pymethod]
fn version(&self) -> Option<&'static str> {
match self
fn version(zelf: &Py<Self>) -> Option<&'static str> {
match zelf
.connection
.lock()
.as_ref()
@@ -881,8 +897,8 @@ mod _ssl {
}
#[pymethod]
fn selected_alpn_protocol(&self) -> Option<String> {
self.connection.lock().as_ref().and_then(|conn| {
fn selected_alpn_protocol(zelf: &Py<Self>) -> Option<String> {
zelf.connection.lock().as_ref().and_then(|conn| {
conn.alpn_protocol()
.map(|proto| String::from_utf8_lossy(proto).into_owned())
})
+4 -4
View File
@@ -1,6 +1,6 @@
use rustpython::InterpreterBuilderExt;
use rustpython::vm::{
PyObject, PyPayload, PyResult, TryFromBorrowedObject, VirtualMachine, pyclass, pymodule,
Py, PyObject, PyPayload, PyResult, TryFromBorrowedObject, VirtualMachine, pyclass, pymodule,
};
pub fn main() {
@@ -67,12 +67,12 @@ python_person.name: {}",
#[pyclass]
impl RustStruct {
#[pygetset]
fn numbers(&self) -> NumVec {
self.numbers.clone()
fn numbers(zelf: &Py<Self>) -> NumVec {
zelf.numbers.clone()
}
#[pymethod]
fn print_in_rust_from_python(&self) {
fn print_in_rust_from_python(_zelf: &Py<Self>) {
println!("Calling a rust method from python");
}
}