mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Cleanup some direct magic method definitions (#7441)
* Migrate direct __repr__ definitions to Representable trait Move legacy #[pymethod] __repr__ to impl Representable for: - PySSLContext, PySSLSocket (ssl.rs) - BufferedReader, BufferedWriter, BufferedRandom (_io.rs) Enable __repr__ guard in derive to prevent future direct definitions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Migrate direct __del__ definition to Destructor trait for PySocket Move #[pymethod] __del__ to impl Destructor for PySocket. Preserves ResourceWarning emission and close behavior. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Remove redundant __iter__ pymethods from PyFuture and PyTask Both types already have impl Iterable, so the direct #[pymethod] __iter__ definitions were duplicates. Enable __iter__/__next__ guards in derive to prevent future direct definitions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Enable derive guards for __get__/__set__/__delete__ descriptor methods All concrete types already use GetDescriptor/SetDescriptor traits. Activate the compile-time guard to prevent future direct definitions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Enable derive guards for AsMapping/AsSequence slot methods Remove redundant #[pymethod(name = "__len__")] from PyStr (already provided via AsMapping/AsSequence trait impls). Enable compile-time guards for __len__, __contains__, __getitem__, __setitem__, __delitem__ to prevent future direct definitions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
065d355248
commit
2117c92b9b
5 files changed
+67
-71
No files matched your search
@@ -917,7 +917,7 @@ where
|
||||
("__new__", "Constructor"),
|
||||
("__init__", "Initializer"),
|
||||
// Representable trait
|
||||
// ("__repr__", "Representable"),
|
||||
("__repr__", "Representable"),
|
||||
// ("__str__", "???"), // allow __str__
|
||||
// Hashable trait
|
||||
("__hash__", "Hashable"),
|
||||
@@ -927,9 +927,9 @@ where
|
||||
// NOTE: __getattribute__, __setattr__, __delattr__ are intentionally NOT forbidden
|
||||
// because they need pymethod for subclass override mechanism to work properly.
|
||||
// GetDescriptor/SetDescriptor traits
|
||||
// ("__get__", "GetDescriptor"),
|
||||
// ("__set__", "SetDescriptor"),
|
||||
// ("__delete__", "SetDescriptor"),
|
||||
("__get__", "GetDescriptor"),
|
||||
("__set__", "SetDescriptor"),
|
||||
("__delete__", "SetDescriptor"),
|
||||
// AsNumber trait
|
||||
("__add__", "AsNumber"),
|
||||
("__radd__", "AsNumber"),
|
||||
@@ -981,15 +981,15 @@ where
|
||||
("__index__", "AsNumber"),
|
||||
("__bool__", "AsNumber"),
|
||||
// AsSequence trait
|
||||
// ("__len__", "AsSequence (or AsMapping)"),
|
||||
// ("__contains__", "AsSequence"),
|
||||
("__len__", "AsSequence (or AsMapping)"),
|
||||
("__contains__", "AsSequence"),
|
||||
// AsMapping trait
|
||||
// ("__getitem__", "AsMapping (or AsSequence)"),
|
||||
// ("__setitem__", "AsMapping (or AsSequence)"),
|
||||
// ("__delitem__", "AsMapping (or AsSequence)"),
|
||||
// IterNext trait
|
||||
// ("__iter__", "IterNext"),
|
||||
// ("__next__", "IterNext"),
|
||||
("__getitem__", "AsMapping (or AsSequence)"),
|
||||
("__setitem__", "AsMapping (or AsSequence)"),
|
||||
("__delitem__", "AsMapping (or AsSequence)"),
|
||||
// Iterable/IterNext traits
|
||||
("__iter__", "Iterable"),
|
||||
("__next__", "IterNext"),
|
||||
// Comparable trait
|
||||
("__eq__", "Comparable"),
|
||||
("__ne__", "Comparable"),
|
||||
|
||||
@@ -764,11 +764,6 @@ pub(crate) mod _asyncio {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn __iter__(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyFutureIter> {
|
||||
Self::__await__(zelf, vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn __await__(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyResult<PyFutureIter> {
|
||||
Ok(PyFutureIter {
|
||||
@@ -1828,13 +1823,6 @@ pub(crate) mod _asyncio {
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn __iter__(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyResult<PyFutureIter> {
|
||||
Ok(PyFutureIter {
|
||||
future: PyRwLock::new(Some(zelf.into())),
|
||||
})
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn __await__(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyResult<PyFutureIter> {
|
||||
Ok(PyFutureIter {
|
||||
|
||||
+39
-34
@@ -20,7 +20,7 @@ mod _socket {
|
||||
ArgBytesLike, ArgIntoFloat, ArgMemoryBuffer, ArgStrOrBytesLike, Either, FsPath,
|
||||
OptionalArg, OptionalOption,
|
||||
},
|
||||
types::{Constructor, DefaultConstructor, Initializer, Representable},
|
||||
types::{Constructor, DefaultConstructor, Destructor, Initializer, Representable},
|
||||
utils::ToCString,
|
||||
};
|
||||
|
||||
@@ -1417,7 +1417,44 @@ mod _socket {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(with(Constructor, Initializer, Representable), flags(BASETYPE))]
|
||||
impl Destructor for PySocket {
|
||||
fn del(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<()> {
|
||||
// Emit ResourceWarning if socket is still open
|
||||
if zelf.sock.read().is_some() {
|
||||
let laddr = if let Ok(sock) = zelf.sock()
|
||||
&& let Ok(addr) = sock.local_addr()
|
||||
&& let Ok(repr) = get_addr_tuple(&addr, vm).repr(vm)
|
||||
{
|
||||
format!(", laddr={}", repr.as_wtf8())
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
let msg = format!(
|
||||
"unclosed <socket.socket fd={}, family={}, type={}, proto={}{}>",
|
||||
zelf.fileno(),
|
||||
zelf.family.load(),
|
||||
zelf.kind.load(),
|
||||
zelf.proto.load(),
|
||||
laddr
|
||||
);
|
||||
let _ = crate::vm::warn::warn(
|
||||
vm.ctx.new_str(msg).into(),
|
||||
Some(vm.ctx.exceptions.resource_warning.to_owned()),
|
||||
1,
|
||||
None,
|
||||
vm,
|
||||
);
|
||||
}
|
||||
let _ = zelf.close();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(
|
||||
with(Constructor, Initializer, Representable, Destructor),
|
||||
flags(BASETYPE)
|
||||
)]
|
||||
impl PySocket {
|
||||
fn _init(
|
||||
zelf: PyRef<Self>,
|
||||
@@ -2139,38 +2176,6 @@ mod _socket {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn __del__(&self, vm: &VirtualMachine) {
|
||||
// Emit ResourceWarning if socket is still open
|
||||
if self.sock.read().is_some() {
|
||||
let laddr = if let Ok(sock) = self.sock()
|
||||
&& let Ok(addr) = sock.local_addr()
|
||||
&& let Ok(repr) = get_addr_tuple(&addr, vm).repr(vm)
|
||||
{
|
||||
format!(", laddr={}", repr.as_wtf8())
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
let msg = format!(
|
||||
"unclosed <socket.socket fd={}, family={}, type={}, proto={}{}>",
|
||||
self.fileno(),
|
||||
self.family.load(),
|
||||
self.kind.load(),
|
||||
self.proto.load(),
|
||||
laddr
|
||||
);
|
||||
let _ = crate::vm::warn::warn(
|
||||
vm.ctx.new_str(msg).into(),
|
||||
Some(vm.ctx.exceptions.resource_warning.to_owned()),
|
||||
1,
|
||||
None,
|
||||
vm,
|
||||
);
|
||||
}
|
||||
let _ = self.close();
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
#[inline]
|
||||
fn detach(&self) -> i64 {
|
||||
|
||||
+16
-12
@@ -857,18 +857,13 @@ mod _ssl {
|
||||
binary_form: OptionalArg<bool>,
|
||||
}
|
||||
|
||||
#[pyclass(with(Constructor), flags(BASETYPE))]
|
||||
#[pyclass(with(Constructor, Representable), flags(BASETYPE))]
|
||||
impl PySSLContext {
|
||||
// Helper method to convert DER certificate bytes to Python dict
|
||||
fn cert_der_to_dict(&self, vm: &VirtualMachine, cert_der: &[u8]) -> PyResult<PyObjectRef> {
|
||||
cert::cert_der_to_dict_helper(vm, cert_der)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn __repr__(&self) -> String {
|
||||
format!("<SSLContext(protocol={})>", self.protocol)
|
||||
}
|
||||
|
||||
#[pygetset]
|
||||
fn check_hostname(&self) -> bool {
|
||||
*self.check_hostname.read()
|
||||
@@ -2191,6 +2186,13 @@ mod _ssl {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for PySSLContext {
|
||||
#[inline]
|
||||
fn repr_str(zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<String> {
|
||||
Ok(format!("<SSLContext(protocol={})>", zelf.protocol))
|
||||
}
|
||||
}
|
||||
|
||||
impl Constructor for PySSLContext {
|
||||
type Args = (i32,);
|
||||
|
||||
@@ -2374,7 +2376,7 @@ mod _ssl {
|
||||
Completed, // unwrap() completed successfully
|
||||
}
|
||||
|
||||
#[pyclass(with(Constructor), flags(BASETYPE))]
|
||||
#[pyclass(with(Constructor, Representable), flags(BASETYPE))]
|
||||
impl PySSLSocket {
|
||||
// Check if this is BIO mode
|
||||
pub(crate) fn is_bio_mode(&self) -> bool {
|
||||
@@ -3021,11 +3023,6 @@ mod _ssl {
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn __repr__(&self) -> String {
|
||||
"<SSLSocket>".to_string()
|
||||
}
|
||||
|
||||
// Helper function to convert Python PROTO_* constants to rustls versions
|
||||
fn get_rustls_versions(
|
||||
minimum: i32,
|
||||
@@ -4562,6 +4559,13 @@ mod _ssl {
|
||||
}
|
||||
}
|
||||
|
||||
impl Representable for PySSLSocket {
|
||||
#[inline]
|
||||
fn repr_str(_zelf: &Py<Self>, _vm: &VirtualMachine) -> PyResult<String> {
|
||||
Ok("<SSLSocket>".to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
impl Constructor for PySSLSocket {
|
||||
type Args = ();
|
||||
|
||||
|
||||
@@ -663,7 +663,6 @@ impl PyStr {
|
||||
self.data.is_empty()
|
||||
}
|
||||
|
||||
#[pymethod(name = "__len__")]
|
||||
#[inline]
|
||||
pub fn char_len(&self) -> usize {
|
||||
self.data.char_len()
|
||||
|
||||
Reference in new issue
Block a user