mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Merge pull request #4849 from haxelion/feature/tp_repr_stdlib
Implemented tp_repr slots for more types
This commit is contained in:
16 files changed
+389
-336
No files matched your search
+29
-19
@@ -62,7 +62,7 @@ mod array {
|
||||
},
|
||||
types::{
|
||||
AsBuffer, AsMapping, AsSequence, Comparable, Constructor, IterNext,
|
||||
IterNextIterable, Iterable, PyComparisonOp,
|
||||
IterNextIterable, Iterable, PyComparisonOp, Representable,
|
||||
},
|
||||
AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
|
||||
},
|
||||
@@ -721,7 +721,15 @@ mod array {
|
||||
|
||||
#[pyclass(
|
||||
flags(BASETYPE),
|
||||
with(Comparable, AsBuffer, AsMapping, AsSequence, Iterable, Constructor)
|
||||
with(
|
||||
Comparable,
|
||||
AsBuffer,
|
||||
AsMapping,
|
||||
AsSequence,
|
||||
Iterable,
|
||||
Constructor,
|
||||
Representable
|
||||
)
|
||||
)]
|
||||
impl PyArray {
|
||||
fn read(&self) -> PyRwLockReadGuard<'_, ArrayContentType> {
|
||||
@@ -1113,23 +1121,6 @@ mod array {
|
||||
Ok(zelf)
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let class = zelf.class();
|
||||
let class_name = class.name();
|
||||
if zelf.read().typecode() == 'u' {
|
||||
if zelf.len() == 0 {
|
||||
return Ok(format!("{class_name}('u')"));
|
||||
}
|
||||
return Ok(format!(
|
||||
"{}('u', {})",
|
||||
class_name,
|
||||
crate::common::str::repr(&zelf.tounicode(vm)?)
|
||||
));
|
||||
}
|
||||
zelf.read().repr(&class_name, vm)
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
pub(crate) fn len(&self) -> usize {
|
||||
self.read().len()
|
||||
@@ -1292,6 +1283,25 @@ mod array {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for PyArray {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let class = zelf.class();
|
||||
let class_name = class.name();
|
||||
if zelf.read().typecode() == 'u' {
|
||||
if zelf.len() == 0 {
|
||||
return Ok(format!("{class_name}('u')"));
|
||||
}
|
||||
return Ok(format!(
|
||||
"{}('u', {})",
|
||||
class_name,
|
||||
crate::common::str::repr(&zelf.tounicode(vm)?)
|
||||
));
|
||||
}
|
||||
zelf.read().repr(&class_name, vm)
|
||||
}
|
||||
}
|
||||
|
||||
static BUFFER_METHODS: BufferMethods = BufferMethods {
|
||||
obj_bytes: |buffer| buffer.obj_as::<PyArray>().get_bytes().into(),
|
||||
obj_bytes_mut: |buffer| buffer.obj_as::<PyArray>().get_bytes_mut().into(),
|
||||
|
||||
+24
-20
@@ -5,8 +5,8 @@ mod _contextvars {
|
||||
use crate::vm::{
|
||||
builtins::{PyFunction, PyStrRef, PyTypeRef},
|
||||
function::{ArgCallable, FuncArgs, OptionalArg},
|
||||
types::Initializer,
|
||||
PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
|
||||
types::{Initializer, Representable},
|
||||
Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
|
||||
};
|
||||
|
||||
#[pyattr]
|
||||
@@ -99,7 +99,7 @@ mod _contextvars {
|
||||
default: OptionalArg<PyObjectRef>,
|
||||
}
|
||||
|
||||
#[pyclass(with(Initializer))]
|
||||
#[pyclass(with(Initializer, Representable))]
|
||||
impl ContextVar {
|
||||
#[pygetset]
|
||||
fn name(&self) -> String {
|
||||
@@ -133,17 +133,6 @@ mod _contextvars {
|
||||
fn class_getitem(_cls: PyTypeRef, _key: PyStrRef, _vm: &VirtualMachine) -> PyResult<()> {
|
||||
unimplemented!("ContextVar.__class_getitem__() is currently under construction")
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(_zelf: PyRef<Self>, _vm: &VirtualMachine) -> String {
|
||||
unimplemented!("<ContextVar name={{}} default={{}} at {{}}")
|
||||
// format!(
|
||||
// "<ContextVar name={} default={:?} at {:#x}>",
|
||||
// zelf.name.as_str(),
|
||||
// zelf.default.map_or("", |x| PyStr::from(*x).as_str()),
|
||||
// zelf.get_id()
|
||||
// )
|
||||
}
|
||||
}
|
||||
|
||||
impl Initializer for ContextVar {
|
||||
@@ -154,6 +143,19 @@ mod _contextvars {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for ContextVar {
|
||||
#[inline]
|
||||
fn repr_str(_zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<String> {
|
||||
unimplemented!("<ContextVar name={{}} default={{}} at {{}}")
|
||||
// format!(
|
||||
// "<ContextVar name={} default={:?} at {:#x}>",
|
||||
// zelf.name.as_str(),
|
||||
// zelf.default.map_or("", |x| PyStr::from(*x).as_str()),
|
||||
// zelf.get_id()
|
||||
// )
|
||||
}
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
#[pyclass(name = "Token")]
|
||||
#[derive(Debug, PyPayload)]
|
||||
@@ -172,7 +174,7 @@ mod _contextvars {
|
||||
old_value: PyObjectRef,
|
||||
}
|
||||
|
||||
#[pyclass(with(Initializer))]
|
||||
#[pyclass(with(Initializer, Representable))]
|
||||
impl ContextToken {
|
||||
#[pygetset]
|
||||
fn var(&self, _vm: &VirtualMachine) -> PyObjectRef {
|
||||
@@ -183,11 +185,6 @@ mod _contextvars {
|
||||
fn old_value(&self, _vm: &VirtualMachine) -> PyObjectRef {
|
||||
unimplemented!("Token.old_value() is currently under construction")
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(_zelf: PyRef<Self>, _vm: &VirtualMachine) -> String {
|
||||
unimplemented!("<Token {{}}var={{}} at {{}}>")
|
||||
}
|
||||
}
|
||||
|
||||
impl Initializer for ContextToken {
|
||||
@@ -198,6 +195,13 @@ mod _contextvars {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for ContextToken {
|
||||
#[inline]
|
||||
fn repr_str(_zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<String> {
|
||||
unimplemented!("<Token {{}}var={{}} at {{}}>")
|
||||
}
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn copy_context() {}
|
||||
}
|
||||
+17
-15
@@ -15,9 +15,9 @@ mod _socket {
|
||||
builtins::{PyBaseExceptionRef, PyListRef, PyStrRef, PyTupleRef, PyTypeRef},
|
||||
convert::{IntoPyException, ToPyObject, TryFromBorrowedObject, TryFromObject},
|
||||
function::{ArgBytesLike, ArgMemoryBuffer, Either, FsPath, OptionalArg, OptionalOption},
|
||||
types::{DefaultConstructor, Initializer},
|
||||
types::{DefaultConstructor, Initializer, Representable},
|
||||
utils::ToCString,
|
||||
AsObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
|
||||
AsObject, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use num_traits::ToPrimitive;
|
||||
@@ -1015,7 +1015,21 @@ mod _socket {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(with(DefaultConstructor, Initializer), flags(BASETYPE))]
|
||||
impl Representable for PySocket {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<String> {
|
||||
Ok(format!(
|
||||
"<socket object, fd={}, family={}, type={}, proto={}>",
|
||||
// cast because INVALID_SOCKET is unsigned, so would show usize::MAX instead of -1
|
||||
zelf.fileno() as i64,
|
||||
zelf.family.load(),
|
||||
zelf.kind.load(),
|
||||
zelf.proto.load(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(with(DefaultConstructor, Initializer, Representable), flags(BASETYPE))]
|
||||
impl PySocket {
|
||||
fn _init(
|
||||
zelf: PyRef<Self>,
|
||||
@@ -1463,18 +1477,6 @@ mod _socket {
|
||||
fn proto(&self) -> i32 {
|
||||
self.proto.load()
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(&self) -> String {
|
||||
format!(
|
||||
"<socket object, fd={}, family={}, type={}, proto={}>",
|
||||
// cast because INVALID_SOCKET is unsigned, so would show usize::MAX instead of -1
|
||||
self.fileno() as i64,
|
||||
self.family.load(),
|
||||
self.kind.load(),
|
||||
self.proto.load(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct Address {
|
||||
|
||||
+1
-16
@@ -230,7 +230,7 @@ impl Representable for PyCode {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(with(Py))]
|
||||
#[pyclass(with(Representable))]
|
||||
impl PyCode {
|
||||
#[pyslot]
|
||||
fn slot_new(_cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||
@@ -418,21 +418,6 @@ impl PyCode {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
impl Py<PyCode> {
|
||||
#[pymethod(magic)]
|
||||
fn repr(&self) -> String {
|
||||
let code = &self.code;
|
||||
format!(
|
||||
"<code object {} at {:#x} file {:?}, line {}>",
|
||||
code.obj_name,
|
||||
self.get_id(),
|
||||
code.source_path.as_str(),
|
||||
code.first_line_number
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for PyCode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
(**self).fmt(f)
|
||||
|
||||
+23
-18
@@ -549,25 +549,11 @@ impl PyBoundMethod {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(with(Callable, Comparable, GetAttr, Constructor), flags(HAS_DICT))]
|
||||
#[pyclass(
|
||||
with(Callable, Comparable, GetAttr, Constructor, Representable),
|
||||
flags(HAS_DICT)
|
||||
)]
|
||||
impl PyBoundMethod {
|
||||
#[pymethod(magic)]
|
||||
fn repr(&self, vm: &VirtualMachine) -> PyResult<String> {
|
||||
#[allow(clippy::needless_match)] // False positive on nightly
|
||||
let funcname =
|
||||
if let Some(qname) = vm.get_attribute_opt(self.function.clone(), "__qualname__")? {
|
||||
Some(qname)
|
||||
} else {
|
||||
vm.get_attribute_opt(self.function.clone(), "__name__")?
|
||||
};
|
||||
let funcname: Option<PyStrRef> = funcname.and_then(|o| o.downcast().ok());
|
||||
Ok(format!(
|
||||
"<bound method {} of {}>",
|
||||
funcname.as_ref().map_or("?", |s| s.as_str()),
|
||||
&self.object.repr(vm)?.as_str(),
|
||||
))
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn reduce(
|
||||
&self,
|
||||
@@ -628,6 +614,25 @@ impl PyPayload for PyBoundMethod {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for PyBoundMethod {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
#[allow(clippy::needless_match)] // False positive on nightly
|
||||
let funcname =
|
||||
if let Some(qname) = vm.get_attribute_opt(zelf.function.clone(), "__qualname__")? {
|
||||
Some(qname)
|
||||
} else {
|
||||
vm.get_attribute_opt(zelf.function.clone(), "__name__")?
|
||||
};
|
||||
let funcname: Option<PyStrRef> = funcname.and_then(|o| o.downcast().ok());
|
||||
Ok(format!(
|
||||
"<bound method {} of {}>",
|
||||
funcname.as_ref().map_or("?", |s| s.as_str()),
|
||||
&zelf.object.repr(vm)?.as_str(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(module = false, name = "cell")]
|
||||
#[derive(Debug, Default)]
|
||||
pub(crate) struct PyCell {
|
||||
|
||||
@@ -244,6 +244,7 @@ impl Comparable for PySlice {
|
||||
Ok(PyComparisonValue::Implemented(ret))
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for PySlice {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
|
||||
+14
-9
@@ -11,7 +11,7 @@ use crate::{
|
||||
py_io::{self, Write},
|
||||
stdlib::sys,
|
||||
suggestion::offer_suggestions,
|
||||
types::{Callable, Constructor, Initializer},
|
||||
types::{Callable, Constructor, Initializer, Representable},
|
||||
AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
@@ -430,7 +430,10 @@ impl PyBaseException {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(with(Constructor, Initializer), flags(BASETYPE, HAS_DICT))]
|
||||
#[pyclass(
|
||||
with(Constructor, Initializer, Representable),
|
||||
flags(BASETYPE, HAS_DICT)
|
||||
)]
|
||||
impl PyBaseException {
|
||||
#[pygetset]
|
||||
pub fn args(&self) -> PyTupleRef {
|
||||
@@ -502,13 +505,6 @@ impl PyBaseException {
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> String {
|
||||
let repr_args = vm.exception_args_as_string(zelf.args(), false);
|
||||
let cls = zelf.class();
|
||||
format!("{}({})", cls.name(), repr_args.iter().format(", "))
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn reduce(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyTupleRef {
|
||||
if let Some(dict) = zelf.as_object().dict().filter(|x| !x.is_empty()) {
|
||||
@@ -538,6 +534,15 @@ impl Initializer for PyBaseException {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for PyBaseException {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let repr_args = vm.exception_args_as_string(zelf.args(), false);
|
||||
let cls = zelf.class();
|
||||
Ok(format!("{}({})", cls.name(), repr_args.iter().format(", ")))
|
||||
}
|
||||
}
|
||||
|
||||
impl ExceptionZoo {
|
||||
pub(crate) fn init() -> Self {
|
||||
use self::types::*;
|
||||
|
||||
@@ -17,7 +17,7 @@ mod _collections {
|
||||
sliceable::SequenceIndexOp,
|
||||
types::{
|
||||
AsSequence, Comparable, Constructor, Initializer, IterNext, IterNextIterable, Iterable,
|
||||
PyComparisonOp,
|
||||
PyComparisonOp, Representable,
|
||||
},
|
||||
utils::collection_repr,
|
||||
AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
|
||||
@@ -57,7 +57,14 @@ mod _collections {
|
||||
|
||||
#[pyclass(
|
||||
flags(BASETYPE),
|
||||
with(Constructor, Initializer, AsSequence, Comparable, Iterable)
|
||||
with(
|
||||
Constructor,
|
||||
Initializer,
|
||||
AsSequence,
|
||||
Comparable,
|
||||
Iterable,
|
||||
Representable
|
||||
)
|
||||
)]
|
||||
impl PyDeque {
|
||||
#[pymethod]
|
||||
@@ -295,27 +302,6 @@ mod _collections {
|
||||
.ok_or_else(|| vm.new_index_error("deque index out of range".to_owned()))
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let deque = zelf.borrow_deque().clone();
|
||||
let class = zelf.class();
|
||||
let class_name = class.name();
|
||||
let closing_part = zelf
|
||||
.maxlen
|
||||
.map(|maxlen| format!("], maxlen={maxlen}"))
|
||||
.unwrap_or_else(|| "]".to_owned());
|
||||
|
||||
let s = if zelf.len() == 0 {
|
||||
format!("{class_name}([{closing_part})")
|
||||
} else if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
|
||||
collection_repr(Some(&class_name), "[", &closing_part, deque.iter(), vm)?
|
||||
} else {
|
||||
"[...]".to_owned()
|
||||
};
|
||||
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn contains(&self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult<bool> {
|
||||
self._contains(&needle, vm)
|
||||
@@ -580,6 +566,29 @@ mod _collections {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for PyDeque {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let deque = zelf.borrow_deque().clone();
|
||||
let class = zelf.class();
|
||||
let class_name = class.name();
|
||||
let closing_part = zelf
|
||||
.maxlen
|
||||
.map(|maxlen| format!("], maxlen={maxlen}"))
|
||||
.unwrap_or_else(|| "]".to_owned());
|
||||
|
||||
let s = if zelf.len() == 0 {
|
||||
format!("{class_name}([{closing_part})")
|
||||
} else if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
|
||||
collection_repr(Some(&class_name), "[", &closing_part, deque.iter(), vm)?
|
||||
} else {
|
||||
"[...]".to_owned()
|
||||
};
|
||||
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
#[pyclass(name = "_deque_iterator")]
|
||||
#[derive(Debug, PyPayload)]
|
||||
|
||||
+34
-24
@@ -1525,9 +1525,9 @@ mod _io {
|
||||
vm.call_method(self.lock(vm)?.check_init(vm)?, "isatty", ())
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let name_repr = repr_fileobj_name(&zelf, vm)?;
|
||||
#[pyslot]
|
||||
fn slot_repr(zelf: &PyObject, vm: &VirtualMachine) -> PyResult<PyStrRef> {
|
||||
let name_repr = repr_fileobj_name(zelf, vm)?;
|
||||
let cls = zelf.class();
|
||||
let slot_name = cls.slot_name();
|
||||
let repr = if let Some(name_repr) = name_repr {
|
||||
@@ -1535,7 +1535,12 @@ mod _io {
|
||||
} else {
|
||||
format!("<{slot_name}>")
|
||||
};
|
||||
Ok(repr)
|
||||
Ok(vm.ctx.new_str(repr))
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyStrRef> {
|
||||
Self::slot_repr(&zelf, vm)
|
||||
}
|
||||
|
||||
fn close_strict(&self, vm: &VirtualMachine) -> PyResult {
|
||||
@@ -3709,8 +3714,8 @@ mod fileio {
|
||||
convert::ToPyException,
|
||||
function::{ArgBytesLike, ArgMemoryBuffer, OptionalArg, OptionalOption},
|
||||
stdlib::os,
|
||||
types::{DefaultConstructor, Initializer},
|
||||
AsObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine,
|
||||
types::{DefaultConstructor, Initializer, Representable},
|
||||
AsObject, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use std::io::{Read, Write};
|
||||
@@ -3896,7 +3901,29 @@ mod fileio {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(with(DefaultConstructor, Initializer), flags(BASETYPE, HAS_DICT))]
|
||||
impl Representable for FileIO {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let fd = zelf.fd.load();
|
||||
if fd < 0 {
|
||||
return Ok("<_io.FileIO [closed]>".to_owned());
|
||||
}
|
||||
let name_repr = repr_fileobj_name(zelf.as_object(), vm)?;
|
||||
let mode = zelf.mode();
|
||||
let closefd = if zelf.closefd.load() { "True" } else { "False" };
|
||||
let repr = if let Some(name_repr) = name_repr {
|
||||
format!("<_io.FileIO name={name_repr} mode='{mode}' closefd={closefd}>")
|
||||
} else {
|
||||
format!("<_io.FileIO fd={fd} mode='{mode}' closefd={closefd}>")
|
||||
};
|
||||
Ok(repr)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(
|
||||
with(DefaultConstructor, Initializer, Representable),
|
||||
flags(BASETYPE, HAS_DICT)
|
||||
)]
|
||||
impl FileIO {
|
||||
#[pygetset]
|
||||
fn closed(&self) -> bool {
|
||||
@@ -3956,23 +3983,6 @@ mod fileio {
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let fd = zelf.fd.load();
|
||||
if fd < 0 {
|
||||
return Ok("<_io.FileIO [closed]>".to_owned());
|
||||
}
|
||||
let name_repr = repr_fileobj_name(zelf.as_object(), vm)?;
|
||||
let mode = zelf.mode();
|
||||
let closefd = if zelf.closefd.load() { "True" } else { "False" };
|
||||
let repr = if let Some(name_repr) = name_repr {
|
||||
format!("<_io.FileIO name={name_repr} mode='{mode}' closefd={closefd}>")
|
||||
} else {
|
||||
format!("<_io.FileIO fd={fd} mode='{mode}' closefd={closefd}>")
|
||||
};
|
||||
Ok(repr)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn read(&self, read_byte: OptionalSize, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
|
||||
if !self.mode.load().contains(Mode::READABLE) {
|
||||
|
||||
+27
-23
@@ -16,7 +16,7 @@ mod decl {
|
||||
identifier,
|
||||
protocol::{PyIter, PyIterReturn, PyNumber},
|
||||
stdlib::sys,
|
||||
types::{Constructor, IterNext, IterNextIterable},
|
||||
types::{Constructor, IterNext, IterNextIterable, Representable},
|
||||
AsObject, Py, PyObjectRef, PyPayload, PyRef, PyResult, PyWeakRef, TryFromObject,
|
||||
VirtualMachine,
|
||||
};
|
||||
@@ -258,7 +258,7 @@ mod decl {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(with(IterNext, Constructor))]
|
||||
#[pyclass(with(IterNext, Constructor, Representable))]
|
||||
impl PyItertoolsCount {
|
||||
// TODO: Implement this
|
||||
// if (lz->cnt == PY_SSIZE_T_MAX)
|
||||
@@ -267,16 +267,6 @@ mod decl {
|
||||
fn reduce(zelf: PyRef<Self>) -> (PyTypeRef, (PyObjectRef,)) {
|
||||
(zelf.class().to_owned(), (zelf.cur.read().clone(),))
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(&self, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let cur = format!("{}", self.cur.read().clone().repr(vm)?);
|
||||
let step = &self.step;
|
||||
if vm.bool_eq(step, vm.ctx.new_int(1).as_object())? {
|
||||
return Ok(format!("count({cur})"));
|
||||
}
|
||||
Ok(format!("count({}, {})", cur, step.repr(vm)?))
|
||||
}
|
||||
}
|
||||
impl IterNextIterable for PyItertoolsCount {}
|
||||
impl IterNext for PyItertoolsCount {
|
||||
@@ -289,6 +279,18 @@ mod decl {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for PyItertoolsCount {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let cur = format!("{}", zelf.cur.read().clone().repr(vm)?);
|
||||
let step = &zelf.step;
|
||||
if vm.bool_eq(step, vm.ctx.new_int(1).as_object())? {
|
||||
return Ok(format!("count({cur})"));
|
||||
}
|
||||
Ok(format!("count({}, {})", cur, step.repr(vm)?))
|
||||
}
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
#[pyclass(name = "cycle")]
|
||||
#[derive(Debug, PyPayload)]
|
||||
@@ -376,7 +378,7 @@ mod decl {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(with(IterNext, Constructor), flags(BASETYPE))]
|
||||
#[pyclass(with(IterNext, Constructor, Representable), flags(BASETYPE))]
|
||||
impl PyItertoolsRepeat {
|
||||
#[pymethod(magic)]
|
||||
fn length_hint(&self, vm: &VirtualMachine) -> PyResult<usize> {
|
||||
@@ -396,16 +398,6 @@ mod decl {
|
||||
None => vm.new_tuple((cls, (zelf.object.clone(),))),
|
||||
})
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(&self, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let mut fmt = format!("{}", &self.object.repr(vm)?);
|
||||
if let Some(ref times) = self.times {
|
||||
fmt.push_str(", ");
|
||||
fmt.push_str(×.read().to_string());
|
||||
}
|
||||
Ok(format!("repeat({fmt})"))
|
||||
}
|
||||
}
|
||||
|
||||
impl IterNextIterable for PyItertoolsRepeat {}
|
||||
@@ -422,6 +414,18 @@ mod decl {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for PyItertoolsRepeat {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let mut fmt = format!("{}", &zelf.object.repr(vm)?);
|
||||
if let Some(ref times) = zelf.times {
|
||||
fmt.push_str(", ");
|
||||
fmt.push_str(×.read().to_string());
|
||||
}
|
||||
Ok(format!("repeat({fmt})"))
|
||||
}
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
#[pyclass(name = "starmap")]
|
||||
#[derive(Debug, PyPayload)]
|
||||
|
||||
+67
-61
@@ -10,7 +10,7 @@ mod _operator {
|
||||
identifier,
|
||||
protocol::PyIter,
|
||||
recursion::ReprGuard,
|
||||
types::{Callable, Constructor, PyComparisonOp},
|
||||
types::{Callable, Constructor, PyComparisonOp, Representable},
|
||||
AsObject, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
|
||||
};
|
||||
|
||||
@@ -356,22 +356,8 @@ mod _operator {
|
||||
attrs: Vec<PyStrRef>,
|
||||
}
|
||||
|
||||
#[pyclass(with(Callable, Constructor))]
|
||||
#[pyclass(with(Callable, Constructor, Representable))]
|
||||
impl PyAttrGetter {
|
||||
#[pymethod(magic)]
|
||||
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let fmt = if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
|
||||
let mut parts = Vec::with_capacity(zelf.attrs.len());
|
||||
for part in &zelf.attrs {
|
||||
parts.push(part.as_object().repr(vm)?.as_str().to_owned());
|
||||
}
|
||||
parts.join(", ")
|
||||
} else {
|
||||
"...".to_owned()
|
||||
};
|
||||
Ok(format!("operator.attrgetter({fmt})"))
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn reduce(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<(PyTypeRef, PyTupleRef)> {
|
||||
let attrs = vm
|
||||
@@ -441,6 +427,22 @@ mod _operator {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for PyAttrGetter {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let fmt = if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
|
||||
let mut parts = Vec::with_capacity(zelf.attrs.len());
|
||||
for part in &zelf.attrs {
|
||||
parts.push(part.as_object().repr(vm)?.as_str().to_owned());
|
||||
}
|
||||
parts.join(", ")
|
||||
} else {
|
||||
"...".to_owned()
|
||||
};
|
||||
Ok(format!("operator.attrgetter({fmt})"))
|
||||
}
|
||||
}
|
||||
|
||||
/// itemgetter(item, ...) --> itemgetter object
|
||||
///
|
||||
/// Return a callable object that fetches the given item(s) from its operand.
|
||||
@@ -453,22 +455,8 @@ mod _operator {
|
||||
items: Vec<PyObjectRef>,
|
||||
}
|
||||
|
||||
#[pyclass(with(Callable, Constructor))]
|
||||
#[pyclass(with(Callable, Constructor, Representable))]
|
||||
impl PyItemGetter {
|
||||
#[pymethod(magic)]
|
||||
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let fmt = if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
|
||||
let mut items = Vec::with_capacity(zelf.items.len());
|
||||
for item in &zelf.items {
|
||||
items.push(item.repr(vm)?.as_str().to_owned());
|
||||
}
|
||||
items.join(", ")
|
||||
} else {
|
||||
"...".to_owned()
|
||||
};
|
||||
Ok(format!("operator.itemgetter({fmt})"))
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn reduce(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyObjectRef {
|
||||
let items = vm.ctx.new_tuple(zelf.items.to_vec());
|
||||
@@ -508,6 +496,22 @@ mod _operator {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for PyItemGetter {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let fmt = if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
|
||||
let mut items = Vec::with_capacity(zelf.items.len());
|
||||
for item in &zelf.items {
|
||||
items.push(item.repr(vm)?.as_str().to_owned());
|
||||
}
|
||||
items.join(", ")
|
||||
} else {
|
||||
"...".to_owned()
|
||||
};
|
||||
Ok(format!("operator.itemgetter({fmt})"))
|
||||
}
|
||||
}
|
||||
|
||||
/// methodcaller(name, ...) --> methodcaller object
|
||||
///
|
||||
/// Return a callable object that calls the given method on its operand.
|
||||
@@ -522,37 +526,8 @@ mod _operator {
|
||||
args: FuncArgs,
|
||||
}
|
||||
|
||||
#[pyclass(with(Callable, Constructor))]
|
||||
#[pyclass(with(Callable, Constructor, Representable))]
|
||||
impl PyMethodCaller {
|
||||
#[pymethod(magic)]
|
||||
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let fmt = if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
|
||||
let args = &zelf.args.args;
|
||||
let kwargs = &zelf.args.kwargs;
|
||||
let mut fmt = vec![zelf.name.as_object().repr(vm)?.as_str().to_owned()];
|
||||
if !args.is_empty() {
|
||||
let mut parts = Vec::with_capacity(args.len());
|
||||
for v in args {
|
||||
parts.push(v.repr(vm)?.as_str().to_owned());
|
||||
}
|
||||
fmt.push(parts.join(", "));
|
||||
}
|
||||
// build name=value pairs from KwArgs.
|
||||
if !kwargs.is_empty() {
|
||||
let mut parts = Vec::with_capacity(kwargs.len());
|
||||
for (key, value) in kwargs {
|
||||
let value_repr = value.repr(vm)?;
|
||||
parts.push(format!("{key}={value_repr}"));
|
||||
}
|
||||
fmt.push(parts.join(", "));
|
||||
}
|
||||
fmt.join(", ")
|
||||
} else {
|
||||
"...".to_owned()
|
||||
};
|
||||
Ok(format!("operator.methodcaller({fmt})"))
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn reduce(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyTupleRef> {
|
||||
// With no kwargs, return (type(obj), (name, *args)) tuple.
|
||||
@@ -596,4 +571,35 @@ mod _operator {
|
||||
vm.call_method(&obj, zelf.name.as_str(), zelf.args.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for PyMethodCaller {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let fmt = if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
|
||||
let args = &zelf.args.args;
|
||||
let kwargs = &zelf.args.kwargs;
|
||||
let mut fmt = vec![zelf.name.as_object().repr(vm)?.as_str().to_owned()];
|
||||
if !args.is_empty() {
|
||||
let mut parts = Vec::with_capacity(args.len());
|
||||
for v in args {
|
||||
parts.push(v.repr(vm)?.as_str().to_owned());
|
||||
}
|
||||
fmt.push(parts.join(", "));
|
||||
}
|
||||
// build name=value pairs from KwArgs.
|
||||
if !kwargs.is_empty() {
|
||||
let mut parts = Vec::with_capacity(kwargs.len());
|
||||
for (key, value) in kwargs {
|
||||
let value_repr = value.repr(vm)?;
|
||||
parts.push(format!("{key}={value_repr}"));
|
||||
}
|
||||
fmt.push(parts.join(", "));
|
||||
}
|
||||
fmt.join(", ")
|
||||
} else {
|
||||
"...".to_owned()
|
||||
};
|
||||
Ok(format!("operator.methodcaller({fmt})"))
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
-17
@@ -302,22 +302,20 @@ pub(super) mod _os {
|
||||
errno_err, DirFd, FollowSymlinks, IOErrorBuilder, OsPath, OsPathOrFd, OutputMode,
|
||||
SupportFunc,
|
||||
};
|
||||
use crate::common::lock::{OnceCell, PyRwLock};
|
||||
use crate::{
|
||||
builtins::{
|
||||
PyBytesRef, PyGenericAlias, PyIntRef, PyStrRef, PyTuple, PyTupleRef, PyTypeRef,
|
||||
},
|
||||
common::{
|
||||
crt_fd::{Fd, Offset},
|
||||
suppress_iph,
|
||||
},
|
||||
common::crt_fd::{Fd, Offset},
|
||||
common::lock::{OnceCell, PyRwLock},
|
||||
common::suppress_iph,
|
||||
convert::{IntoPyException, ToPyObject},
|
||||
function::{ArgBytesLike, Either, FsPath, FuncArgs, OptionalArg},
|
||||
protocol::PyIterReturn,
|
||||
recursion::ReprGuard,
|
||||
types::{IterNext, IterNextIterable, PyStructSequence},
|
||||
types::{IterNext, IterNextIterable, PyStructSequence, Representable},
|
||||
vm::VirtualMachine,
|
||||
AsObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject,
|
||||
AsObject, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use itertools::Itertools;
|
||||
@@ -619,7 +617,7 @@ pub(super) mod _os {
|
||||
ino: AtomicCell<Option<u64>>,
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[pyclass(with(Representable))]
|
||||
impl DirEntry {
|
||||
#[pygetset]
|
||||
fn name(&self, vm: &VirtualMachine) -> PyResult {
|
||||
@@ -747,9 +745,16 @@ pub(super) mod _os {
|
||||
self.path(vm)
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let name = match zelf.get_attr("name", vm) {
|
||||
#[pyclassmethod(magic)]
|
||||
fn class_getitem(cls: PyTypeRef, args: PyObjectRef, vm: &VirtualMachine) -> PyGenericAlias {
|
||||
PyGenericAlias::new(cls, args, vm)
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for DirEntry {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let name = match zelf.as_object().get_attr("name", vm) {
|
||||
Ok(name) => Some(name),
|
||||
Err(e)
|
||||
if e.fast_isinstance(vm.ctx.exceptions.attribute_error)
|
||||
@@ -760,7 +765,7 @@ pub(super) mod _os {
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
if let Some(name) = name {
|
||||
if let Some(_guard) = ReprGuard::enter(vm, &zelf) {
|
||||
if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
|
||||
let repr = name.repr(vm)?;
|
||||
Ok(format!("<{} {}>", zelf.class(), repr))
|
||||
} else {
|
||||
@@ -773,11 +778,6 @@ pub(super) mod _os {
|
||||
Ok(format!("<{}>", zelf.class()))
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclassmethod(magic)]
|
||||
fn class_getitem(cls: PyTypeRef, args: PyObjectRef, vm: &VirtualMachine) -> PyGenericAlias {
|
||||
PyGenericAlias::new(cls, args, vm)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
|
||||
+14
-12
@@ -28,9 +28,9 @@ pub mod module {
|
||||
errno_err, DirFd, FollowSymlinks, OsPath, OsPathOrFd, SupportFunc, TargetIsDirectory,
|
||||
_os, fs_metadata, IOErrorBuilder,
|
||||
},
|
||||
types::Constructor,
|
||||
types::{Constructor, Representable},
|
||||
utils::ToCString,
|
||||
AsObject, PyObjectRef, PyPayload, PyResult, VirtualMachine,
|
||||
AsObject, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine,
|
||||
};
|
||||
use bitflags::bitflags;
|
||||
use nix::{
|
||||
@@ -540,22 +540,13 @@ pub mod module {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(with(Constructor))]
|
||||
#[pyclass(with(Constructor, Representable))]
|
||||
impl SchedParam {
|
||||
#[pygetset]
|
||||
fn sched_priority(&self, vm: &VirtualMachine) -> PyObjectRef {
|
||||
self.sched_priority.clone().to_pyobject(vm)
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(&self, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let sched_priority_repr = self.sched_priority.repr(vm)?;
|
||||
Ok(format!(
|
||||
"posix.sched_param(sched_priority = {})",
|
||||
sched_priority_repr.as_str()
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "netbsd",
|
||||
@@ -591,6 +582,17 @@ pub mod module {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for SchedParam {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let sched_priority_repr = zelf.sched_priority.repr(vm)?;
|
||||
Ok(format!(
|
||||
"posix.sched_param(sched_priority = {})",
|
||||
sched_priority_repr.as_str()
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "netbsd",
|
||||
|
||||
+66
-62
@@ -13,9 +13,9 @@ mod _sre {
|
||||
function::{ArgCallable, OptionalArg, PosArgs, PyComparisonValue},
|
||||
protocol::{PyBuffer, PyMappingMethods},
|
||||
stdlib::sys,
|
||||
types::{AsMapping, Comparable, Hashable},
|
||||
PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromBorrowedObject, TryFromObject,
|
||||
VirtualMachine,
|
||||
types::{AsMapping, Comparable, Hashable, Representable},
|
||||
Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromBorrowedObject,
|
||||
TryFromObject, VirtualMachine,
|
||||
};
|
||||
use core::str;
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
@@ -151,7 +151,7 @@ mod _sre {
|
||||
};
|
||||
}
|
||||
|
||||
#[pyclass(with(Hashable, Comparable))]
|
||||
#[pyclass(with(Hashable, Comparable, Representable))]
|
||||
impl Pattern {
|
||||
fn with_str<F, R>(string: &PyObject, vm: &VirtualMachine, f: F) -> PyResult<R>
|
||||
where
|
||||
@@ -336,51 +336,6 @@ mod _sre {
|
||||
})
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(&self, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let flag_names = [
|
||||
("re.TEMPLATE", SreFlag::TEMPLATE),
|
||||
("re.IGNORECASE", SreFlag::IGNORECASE),
|
||||
("re.LOCALE", SreFlag::LOCALE),
|
||||
("re.MULTILINE", SreFlag::MULTILINE),
|
||||
("re.DOTALL", SreFlag::DOTALL),
|
||||
("re.UNICODE", SreFlag::UNICODE),
|
||||
("re.VERBOSE", SreFlag::VERBOSE),
|
||||
("re.DEBUG", SreFlag::DEBUG),
|
||||
("re.ASCII", SreFlag::ASCII),
|
||||
];
|
||||
|
||||
/* Omit re.UNICODE for valid string patterns. */
|
||||
let mut flags = self.flags;
|
||||
if !self.isbytes
|
||||
&& (flags & (SreFlag::LOCALE | SreFlag::UNICODE | SreFlag::ASCII))
|
||||
== SreFlag::UNICODE
|
||||
{
|
||||
flags &= !SreFlag::UNICODE;
|
||||
}
|
||||
|
||||
let flags = flag_names
|
||||
.iter()
|
||||
.filter(|(_, flag)| flags.contains(*flag))
|
||||
.map(|(name, _)| name)
|
||||
.join("|");
|
||||
|
||||
let pattern = self.pattern.repr(vm)?;
|
||||
let truncated: String;
|
||||
let s = if pattern.char_len() > 200 {
|
||||
truncated = pattern.as_str().chars().take(200).collect();
|
||||
&truncated
|
||||
} else {
|
||||
pattern.as_str()
|
||||
};
|
||||
|
||||
if flags.is_empty() {
|
||||
Ok(format!("re.compile({s})"))
|
||||
} else {
|
||||
Ok(format!("re.compile({s}, {flags})"))
|
||||
}
|
||||
}
|
||||
|
||||
#[pygetset]
|
||||
fn flags(&self) -> u16 {
|
||||
self.flags.bits()
|
||||
@@ -512,6 +467,53 @@ mod _sre {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for Pattern {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let flag_names = [
|
||||
("re.TEMPLATE", SreFlag::TEMPLATE),
|
||||
("re.IGNORECASE", SreFlag::IGNORECASE),
|
||||
("re.LOCALE", SreFlag::LOCALE),
|
||||
("re.MULTILINE", SreFlag::MULTILINE),
|
||||
("re.DOTALL", SreFlag::DOTALL),
|
||||
("re.UNICODE", SreFlag::UNICODE),
|
||||
("re.VERBOSE", SreFlag::VERBOSE),
|
||||
("re.DEBUG", SreFlag::DEBUG),
|
||||
("re.ASCII", SreFlag::ASCII),
|
||||
];
|
||||
|
||||
/* Omit re.UNICODE for valid string patterns. */
|
||||
let mut flags = zelf.flags;
|
||||
if !zelf.isbytes
|
||||
&& (flags & (SreFlag::LOCALE | SreFlag::UNICODE | SreFlag::ASCII))
|
||||
== SreFlag::UNICODE
|
||||
{
|
||||
flags &= !SreFlag::UNICODE;
|
||||
}
|
||||
|
||||
let flags = flag_names
|
||||
.iter()
|
||||
.filter(|(_, flag)| flags.contains(*flag))
|
||||
.map(|(name, _)| name)
|
||||
.join("|");
|
||||
|
||||
let pattern = zelf.pattern.repr(vm)?;
|
||||
let truncated: String;
|
||||
let s = if pattern.char_len() > 200 {
|
||||
truncated = pattern.as_str().chars().take(200).collect();
|
||||
&truncated
|
||||
} else {
|
||||
pattern.as_str()
|
||||
};
|
||||
|
||||
if flags.is_empty() {
|
||||
Ok(format!("re.compile({s})"))
|
||||
} else {
|
||||
Ok(format!("re.compile({s}, {flags})"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
#[pyclass(name = "Match")]
|
||||
#[derive(Debug, PyPayload)]
|
||||
@@ -524,7 +526,7 @@ mod _sre {
|
||||
regs: Vec<(isize, isize)>,
|
||||
}
|
||||
|
||||
#[pyclass(with(AsMapping))]
|
||||
#[pyclass(with(AsMapping, Representable))]
|
||||
impl Match {
|
||||
pub(crate) fn new<S: StrDrive>(
|
||||
state: &State<S>,
|
||||
@@ -703,18 +705,6 @@ mod _sre {
|
||||
})
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(&self, vm: &VirtualMachine) -> PyResult<String> {
|
||||
with_sre_str!(self.pattern, &self.string, vm, |str_drive| {
|
||||
Ok(format!(
|
||||
"<re.Match object; span=({}, {}), match={}>",
|
||||
self.regs[0].0,
|
||||
self.regs[0].1,
|
||||
self.get_slice(0, str_drive, vm).unwrap().repr(vm)?
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
fn get_index(&self, group: PyObjectRef, vm: &VirtualMachine) -> Option<usize> {
|
||||
let i = if let Ok(i) = group.try_index(vm) {
|
||||
i
|
||||
@@ -768,6 +758,20 @@ mod _sre {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for Match {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<String> {
|
||||
with_sre_str!(zelf.pattern, &zelf.string, vm, |str_drive| {
|
||||
Ok(format!(
|
||||
"<re.Match object; span=({}, {}), match={}>",
|
||||
zelf.regs[0].0,
|
||||
zelf.regs[0].1,
|
||||
zelf.get_slice(0, str_drive, vm).unwrap().repr(vm)?
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
#[pyclass(name = "SRE_Scanner")]
|
||||
#[derive(Debug, PyPayload)]
|
||||
|
||||
+16
-12
@@ -8,7 +8,7 @@ pub(crate) mod _thread {
|
||||
builtins::{PyDictRef, PyStr, PyTupleRef, PyTypeRef},
|
||||
convert::ToPyException,
|
||||
function::{ArgCallable, Either, FuncArgs, KwArgs, OptionalArg, PySetterValue},
|
||||
types::{Constructor, GetAttr, SetAttr},
|
||||
types::{Constructor, GetAttr, Representable, SetAttr},
|
||||
AsObject, Py, PyPayload, PyRef, PyResult, VirtualMachine,
|
||||
};
|
||||
use parking_lot::{
|
||||
@@ -97,12 +97,12 @@ pub(crate) mod _thread {
|
||||
} else {
|
||||
"unlocked"
|
||||
};
|
||||
format!(
|
||||
Ok(format!(
|
||||
"<{} {} object at {:#x}>",
|
||||
status,
|
||||
$zelf.class().name(),
|
||||
$zelf.get_id()
|
||||
)
|
||||
))
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ pub(crate) mod _thread {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(with(Constructor))]
|
||||
#[pyclass(with(Constructor, Representable))]
|
||||
impl Lock {
|
||||
#[pymethod]
|
||||
#[pymethod(name = "acquire_lock")]
|
||||
@@ -146,11 +146,6 @@ pub(crate) mod _thread {
|
||||
fn locked(&self) -> bool {
|
||||
self.mu.is_locked()
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(zelf: PyRef<Self>) -> String {
|
||||
repr_lock_impl!(zelf)
|
||||
}
|
||||
}
|
||||
|
||||
impl Constructor for Lock {
|
||||
@@ -160,6 +155,13 @@ pub(crate) mod _thread {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for Lock {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<String> {
|
||||
repr_lock_impl!(zelf)
|
||||
}
|
||||
}
|
||||
|
||||
pub type RawRMutex = RawReentrantMutex<RawMutex, RawThreadId>;
|
||||
#[pyattr]
|
||||
#[pyclass(module = "thread", name = "RLock")]
|
||||
@@ -174,7 +176,7 @@ pub(crate) mod _thread {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[pyclass(with(Representable))]
|
||||
impl RLock {
|
||||
#[pyslot]
|
||||
fn slot_new(cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||
@@ -210,9 +212,11 @@ pub(crate) mod _thread {
|
||||
fn exit(&self, _args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
self.release(vm)
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(zelf: PyRef<Self>) -> String {
|
||||
impl Representable for RLock {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<String> {
|
||||
repr_lock_impl!(zelf)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ mod _js {
|
||||
convert::{IntoObject, ToPyObject},
|
||||
function::{ArgCallable, OptionalArg, OptionalOption, PosArgs},
|
||||
protocol::PyIterReturn,
|
||||
types::{IterNext, IterNextIterable},
|
||||
types::{IterNext, IterNextIterable, Representable},
|
||||
Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine,
|
||||
};
|
||||
use std::{cell, fmt, future};
|
||||
@@ -90,7 +90,7 @@ mod _js {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[pyclass(with(Representable))]
|
||||
impl PyJsValue {
|
||||
#[inline]
|
||||
pub fn new(value: impl Into<JsValue>) -> PyJsValue {
|
||||
@@ -265,10 +265,12 @@ mod _js {
|
||||
fn instanceof(&self, rhs: PyJsValueRef, vm: &VirtualMachine) -> PyResult<bool> {
|
||||
instance_of(&self.value, &rhs.value).map_err(|err| new_js_error(vm, err))
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(&self) -> String {
|
||||
format!("{:?}", self.value)
|
||||
impl Representable for PyJsValue {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<String> {
|
||||
Ok(format!("{:?}", zelf.value))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user