mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
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:
1 parent
536737f4a0
commit
100dac0bbe
37 files changed
+2150
-1808
No files matched your search
@@ -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
@@ -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),
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
@@ -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
@@ -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>()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
+192
-177
File diff suppressed because it is too large.
Load diff
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
File diff suppressed because it is too large.
Load diff
+131
-95
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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),
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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
@@ -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())
|
||||
})
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user