mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Merge pull request #3402 from Snowapril/refactor_exceptions
Refactor duplicated codes in exception creations
This commit is contained in:
10 files changed
+156
-185
No files matched your search
+33
-11
@@ -1,7 +1,7 @@
|
||||
use crate::error::Diagnostic;
|
||||
use crate::util::{
|
||||
iter_use_idents, pyclass_ident_and_attrs, text_signature, AttributeExt, ClassItemMeta,
|
||||
ContentItem, ContentItemInner, ErrorVec, ItemMeta, ItemNursery, SimpleItemMeta,
|
||||
iter_use_idents, pyclass_ident_and_attrs, text_signature, AttrItemMeta, AttributeExt,
|
||||
ClassItemMeta, ContentItem, ContentItemInner, ErrorVec, ItemMeta, ItemNursery, SimpleItemMeta,
|
||||
ALL_ALLOWED_NAMES,
|
||||
};
|
||||
use proc_macro2::TokenStream;
|
||||
@@ -241,7 +241,7 @@ impl ContentItem for AttributeItem {
|
||||
}
|
||||
|
||||
struct ModuleItemArgs<'a> {
|
||||
item: &'a Item,
|
||||
item: &'a mut Item,
|
||||
attrs: &'a mut Vec<Attribute>,
|
||||
context: &'a mut ModuleContext,
|
||||
cfgs: &'a [Attribute],
|
||||
@@ -370,15 +370,36 @@ impl ModuleItem for AttributeItem {
|
||||
fn gen_module_item(&self, args: ModuleItemArgs<'_>) -> Result<()> {
|
||||
let cfgs = args.cfgs.to_vec();
|
||||
let attr = args.attrs.remove(self.index());
|
||||
let get_py_name = |attr: &Attribute, ident: &Ident| -> Result<_> {
|
||||
let item_meta = SimpleItemMeta::from_attr(ident.clone(), attr)?;
|
||||
let py_name = item_meta.simple_name()?;
|
||||
Ok(py_name)
|
||||
};
|
||||
let (py_name, tokens) = match args.item {
|
||||
Item::Fn(syn::ItemFn { sig, .. }) => {
|
||||
Item::Fn(syn::ItemFn { sig, block, .. }) => {
|
||||
let ident = &sig.ident;
|
||||
let py_name = get_py_name(&attr, ident)?;
|
||||
// If `once` keyword is in #[pyattr],
|
||||
// wrapping it with static_cell for preventing it from using it as function
|
||||
let attr_meta = AttrItemMeta::from_attr(ident.clone(), &attr)?;
|
||||
if attr_meta.inner()._bool("once")? {
|
||||
let stmts = &block.stmts;
|
||||
let return_type = match &sig.output {
|
||||
syn::ReturnType::Default => {
|
||||
unreachable!("#[pyattr] attached function must have return type.")
|
||||
}
|
||||
syn::ReturnType::Type(_, ty) => ty,
|
||||
};
|
||||
let stmt: syn::Stmt = parse_quote! {
|
||||
{
|
||||
rustpython_common::static_cell! {
|
||||
static ERROR: #return_type;
|
||||
}
|
||||
ERROR
|
||||
.get_or_init(|| {
|
||||
#(#stmts)*
|
||||
})
|
||||
.clone()
|
||||
}
|
||||
};
|
||||
block.stmts = vec![stmt];
|
||||
}
|
||||
|
||||
let py_name = attr_meta.simple_name()?;
|
||||
(
|
||||
py_name.clone(),
|
||||
quote_spanned! { ident.span() =>
|
||||
@@ -387,7 +408,8 @@ impl ModuleItem for AttributeItem {
|
||||
)
|
||||
}
|
||||
Item::Const(syn::ItemConst { ident, .. }) => {
|
||||
let py_name = get_py_name(&attr, ident)?;
|
||||
let item_meta = SimpleItemMeta::from_attr(ident.clone(), &attr)?;
|
||||
let py_name = item_meta.simple_name()?;
|
||||
(
|
||||
py_name.clone(),
|
||||
quote_spanned! { ident.span() =>
|
||||
|
||||
@@ -236,6 +236,19 @@ impl ItemMeta for SimpleItemMeta {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct AttrItemMeta(pub ItemMetaInner);
|
||||
|
||||
impl ItemMeta for AttrItemMeta {
|
||||
const ALLOWED_NAMES: &'static [&'static str] = &["name", "once"];
|
||||
|
||||
fn from_inner(inner: ItemMetaInner) -> Self {
|
||||
Self(inner)
|
||||
}
|
||||
fn inner(&self) -> &ItemMetaInner {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct ClassItemMeta(ItemMetaInner);
|
||||
|
||||
impl ItemMeta for ClassItemMeta {
|
||||
|
||||
+8
-28
@@ -11,38 +11,18 @@ mod decl {
|
||||
};
|
||||
use itertools::Itertools;
|
||||
|
||||
#[pyattr(name = "Error")]
|
||||
#[pyattr(name = "Error", once)]
|
||||
fn error_type(vm: &VirtualMachine) -> PyTypeRef {
|
||||
rustpython_common::static_cell! {
|
||||
static BINASCII_ERROR: PyTypeRef;
|
||||
}
|
||||
BINASCII_ERROR
|
||||
.get_or_init(|| {
|
||||
vm.ctx.new_class(
|
||||
Some("binascii"),
|
||||
"Error",
|
||||
&vm.ctx.exceptions.value_error,
|
||||
Default::default(),
|
||||
)
|
||||
})
|
||||
.clone()
|
||||
vm.ctx.new_exception_type(
|
||||
"binascii",
|
||||
"Error",
|
||||
Some(vec![vm.ctx.exceptions.value_error.clone()]),
|
||||
)
|
||||
}
|
||||
|
||||
#[pyattr(name = "Incomplete")]
|
||||
#[pyattr(name = "Incomplete", once)]
|
||||
fn incomplete_type(vm: &VirtualMachine) -> PyTypeRef {
|
||||
rustpython_common::static_cell! {
|
||||
static BINASCII_INCOMPLTE: PyTypeRef;
|
||||
}
|
||||
BINASCII_INCOMPLTE
|
||||
.get_or_init(|| {
|
||||
vm.ctx.new_class(
|
||||
Some("binascii"),
|
||||
"Incomplete",
|
||||
&vm.ctx.exceptions.exception_type,
|
||||
Default::default(),
|
||||
)
|
||||
})
|
||||
.clone()
|
||||
vm.ctx.new_exception_type("binascii", "Incomplete", None)
|
||||
}
|
||||
|
||||
fn hex_nibble(n: u8) -> u8 {
|
||||
|
||||
+7
-3
@@ -11,7 +11,7 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
mod _csv {
|
||||
use crate::common::lock::PyMutex;
|
||||
use crate::vm::{
|
||||
builtins::{PyStr, PyStrRef, PyType, PyTypeRef},
|
||||
builtins::{PyStr, PyStrRef, PyTypeRef},
|
||||
function::{ArgIterable, ArgumentError, FromArgs, FuncArgs},
|
||||
match_class,
|
||||
protocol::{PyIter, PyIterReturn},
|
||||
@@ -30,9 +30,13 @@ mod _csv {
|
||||
#[pyattr]
|
||||
const QUOTE_NONE: i32 = QuoteStyle::None as i32;
|
||||
|
||||
#[pyattr(name = "Error")]
|
||||
#[pyattr(name = "Error", once)]
|
||||
fn error(vm: &VirtualMachine) -> PyTypeRef {
|
||||
PyType::new_simple_ref("_csv.Error", &vm.ctx.exceptions.exception_type).unwrap()
|
||||
vm.ctx.new_exception_type(
|
||||
"_csv",
|
||||
"Error",
|
||||
Some(vec![vm.ctx.exceptions.exception_type.clone()]),
|
||||
)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
||||
+18
-42
@@ -80,53 +80,29 @@ mod _socket {
|
||||
vm.ctx.exceptions.os_error.clone()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
#[pyattr(once)]
|
||||
fn timeout(vm: &VirtualMachine) -> PyTypeRef {
|
||||
rustpython_common::static_cell! {
|
||||
static ERROR: PyTypeRef;
|
||||
}
|
||||
ERROR
|
||||
.get_or_init(|| {
|
||||
vm.ctx.new_class(
|
||||
Some("socket"),
|
||||
"timeout",
|
||||
&vm.ctx.exceptions.os_error,
|
||||
Default::default(),
|
||||
)
|
||||
})
|
||||
.clone()
|
||||
vm.ctx.new_exception_type(
|
||||
"socket",
|
||||
"timeout",
|
||||
Some(vec![vm.ctx.exceptions.os_error.clone()]),
|
||||
)
|
||||
}
|
||||
#[pyattr]
|
||||
#[pyattr(once)]
|
||||
fn herror(vm: &VirtualMachine) -> PyTypeRef {
|
||||
rustpython_common::static_cell! {
|
||||
static ERROR: PyTypeRef;
|
||||
}
|
||||
ERROR
|
||||
.get_or_init(|| {
|
||||
vm.ctx.new_class(
|
||||
Some("socket"),
|
||||
"herror",
|
||||
&vm.ctx.exceptions.os_error,
|
||||
Default::default(),
|
||||
)
|
||||
})
|
||||
.clone()
|
||||
vm.ctx.new_exception_type(
|
||||
"socket",
|
||||
"herror",
|
||||
Some(vec![vm.ctx.exceptions.os_error.clone()]),
|
||||
)
|
||||
}
|
||||
#[pyattr]
|
||||
#[pyattr(once)]
|
||||
fn gaierror(vm: &VirtualMachine) -> PyTypeRef {
|
||||
rustpython_common::static_cell! {
|
||||
static ERROR: PyTypeRef;
|
||||
}
|
||||
ERROR
|
||||
.get_or_init(|| {
|
||||
vm.ctx.new_class(
|
||||
Some("socket"),
|
||||
"gaierror",
|
||||
&vm.ctx.exceptions.os_error,
|
||||
Default::default(),
|
||||
)
|
||||
})
|
||||
.clone()
|
||||
vm.ctx.new_exception_type(
|
||||
"socket",
|
||||
"gaierror",
|
||||
Some(vec![vm.ctx.exceptions.os_error.clone()]),
|
||||
)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
||||
+35
-67
@@ -30,7 +30,7 @@ mod _ssl {
|
||||
},
|
||||
socket::{self, PySocket},
|
||||
vm::{
|
||||
builtins::{PyBaseException, PyBaseExceptionRef, PyStrRef, PyType, PyTypeRef, PyWeak},
|
||||
builtins::{PyBaseExceptionRef, PyStrRef, PyType, PyTypeRef, PyWeak},
|
||||
exceptions,
|
||||
function::{
|
||||
ArgBytesLike, ArgCallable, ArgMemoryBuffer, ArgStrOrBytesLike, IntoPyException,
|
||||
@@ -39,7 +39,7 @@ mod _ssl {
|
||||
stdlib::os::PyPathLike,
|
||||
types::Constructor,
|
||||
utils::{Either, ToCString},
|
||||
ItemProtocol, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
ItemProtocol, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
},
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
@@ -174,90 +174,58 @@ mod _ssl {
|
||||
parse_version_info(openssl_api_version)
|
||||
}
|
||||
|
||||
#[pyattr(name = "SSLError")]
|
||||
/// An error occurred in the SSL implementation.
|
||||
#[pyattr(name = "SSLError", once)]
|
||||
fn ssl_error(vm: &VirtualMachine) -> PyTypeRef {
|
||||
rustpython_common::static_cell! {
|
||||
static ERROR: PyTypeRef;
|
||||
}
|
||||
ERROR
|
||||
.get_or_init(|| {
|
||||
PyType::new_simple_ref("ssl.SSLError", &vm.ctx.exceptions.os_error).unwrap()
|
||||
})
|
||||
.clone()
|
||||
vm.ctx.new_exception_type(
|
||||
"ssl",
|
||||
"SSLError",
|
||||
Some(vec![vm.ctx.exceptions.os_error.clone()]),
|
||||
)
|
||||
}
|
||||
|
||||
#[pyattr(name = "SSLCertVerificationError")]
|
||||
/// A certificate could not be verified.
|
||||
#[pyattr(name = "SSLCertVerificationError", once)]
|
||||
fn ssl_cert_verification_error(vm: &VirtualMachine) -> PyTypeRef {
|
||||
rustpython_common::static_cell! {
|
||||
static ERROR: PyTypeRef;
|
||||
}
|
||||
ERROR
|
||||
.get_or_init(|| {
|
||||
let ssl_error = ssl_error(vm);
|
||||
PyType::new_ref(
|
||||
"ssl.SSLCertVerificationError",
|
||||
vec![ssl_error, vm.ctx.exceptions.value_error.clone()],
|
||||
Default::default(),
|
||||
PyBaseException::make_slots(),
|
||||
vm.ctx.types.type_type.clone(),
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
.clone()
|
||||
vm.ctx.new_exception_type(
|
||||
"ssl",
|
||||
"SSLCertVerificationError",
|
||||
Some(vec![ssl_error(vm), vm.ctx.exceptions.value_error.clone()]),
|
||||
)
|
||||
}
|
||||
|
||||
#[pyattr(name = "SSLZeroReturnError")]
|
||||
/// SSL/TLS session closed cleanly.
|
||||
#[pyattr(name = "SSLZeroReturnError", once)]
|
||||
fn ssl_zero_return_error(vm: &VirtualMachine) -> PyTypeRef {
|
||||
rustpython_common::static_cell! {
|
||||
static ERROR: PyTypeRef;
|
||||
}
|
||||
ERROR
|
||||
.get_or_init(|| {
|
||||
PyType::new_simple_ref("ssl.SSLZeroReturnError", &ssl_error(vm)).unwrap()
|
||||
})
|
||||
.clone()
|
||||
vm.ctx
|
||||
.new_exception_type("ssl", "SSLZeroReturnError", Some(vec![ssl_error(vm)]))
|
||||
}
|
||||
|
||||
#[pyattr(name = "SSLWantReadError")]
|
||||
/// Non-blocking SSL socket needs to read more data before the requested operation can be completed.
|
||||
#[pyattr(name = "SSLWantReadError", once)]
|
||||
fn ssl_want_read_error(vm: &VirtualMachine) -> PyTypeRef {
|
||||
rustpython_common::static_cell! {
|
||||
static ERROR: PyTypeRef;
|
||||
}
|
||||
ERROR
|
||||
.get_or_init(|| PyType::new_simple_ref("ssl.SSLWantReadError", &ssl_error(vm)).unwrap())
|
||||
.clone()
|
||||
vm.ctx
|
||||
.new_exception_type("ssl", "SSLWantReadError", Some(vec![ssl_error(vm)]))
|
||||
}
|
||||
|
||||
#[pyattr(name = "SSLWantWriteError")]
|
||||
/// Non-blocking SSL socket needs to write more data before the requested operation can be completed.
|
||||
#[pyattr(name = "SSLWantWriteError", once)]
|
||||
fn ssl_want_write_error(vm: &VirtualMachine) -> PyTypeRef {
|
||||
rustpython_common::static_cell! {
|
||||
static ERROR: PyTypeRef;
|
||||
}
|
||||
ERROR
|
||||
.get_or_init(|| {
|
||||
PyType::new_simple_ref("ssl.SSLWantWriteError", &ssl_error(vm)).unwrap()
|
||||
})
|
||||
.clone()
|
||||
vm.ctx
|
||||
.new_exception_type("ssl", "SSLWantWriteError", Some(vec![ssl_error(vm)]))
|
||||
}
|
||||
|
||||
#[pyattr(name = "SSLSyscallError")]
|
||||
/// System error when attempting SSL operation.
|
||||
#[pyattr(name = "SSLSyscallError", once)]
|
||||
fn ssl_syscall_error(vm: &VirtualMachine) -> PyTypeRef {
|
||||
rustpython_common::static_cell! {
|
||||
static ERROR: PyTypeRef;
|
||||
}
|
||||
ERROR
|
||||
.get_or_init(|| PyType::new_simple_ref("ssl.SSLSyscallError", &ssl_error(vm)).unwrap())
|
||||
.clone()
|
||||
vm.ctx
|
||||
.new_exception_type("ssl", "SSLSyscallError", Some(vec![ssl_error(vm)]))
|
||||
}
|
||||
|
||||
#[pyattr(name = "SSLEOFError")]
|
||||
/// SSL/TLS connection terminated abruptly.
|
||||
#[pyattr(name = "SSLEOFError", once)]
|
||||
fn ssl_eof_error(vm: &VirtualMachine) -> PyTypeRef {
|
||||
rustpython_common::static_cell! {
|
||||
static ERROR: PyTypeRef;
|
||||
}
|
||||
ERROR
|
||||
.get_or_init(|| PyType::new_simple_ref("ssl.SSLEOFError", &ssl_error(vm)).unwrap())
|
||||
.clone()
|
||||
PyType::new_simple_ref("ssl.SSLEOFError", &ssl_error(vm)).unwrap()
|
||||
}
|
||||
|
||||
type OpensslVersionInfo = (u8, u8, u8, u8, u8);
|
||||
|
||||
+6
-14
@@ -100,20 +100,12 @@ mod termios {
|
||||
)
|
||||
}
|
||||
|
||||
#[pyattr(name = "error")]
|
||||
#[pyattr(name = "error", once)]
|
||||
fn error_type(vm: &VirtualMachine) -> PyTypeRef {
|
||||
rustpython_common::static_cell! {
|
||||
static TERMIOS_ERROR: PyTypeRef;
|
||||
}
|
||||
TERMIOS_ERROR
|
||||
.get_or_init(|| {
|
||||
vm.ctx.new_class(
|
||||
Some("termios"),
|
||||
"error",
|
||||
&vm.ctx.exceptions.os_error,
|
||||
Default::default(),
|
||||
)
|
||||
})
|
||||
.clone()
|
||||
vm.ctx.new_exception_type(
|
||||
"termios",
|
||||
"error",
|
||||
Some(vec![vm.ctx.exceptions.os_error.clone()]),
|
||||
)
|
||||
}
|
||||
}
|
||||
+7
-3
@@ -4,7 +4,7 @@ pub(crate) use zlib::make_module;
|
||||
mod zlib {
|
||||
use crate::common::lock::PyMutex;
|
||||
use crate::vm::{
|
||||
builtins::{PyBaseExceptionRef, PyBytes, PyBytesRef, PyIntRef, PyType, PyTypeRef},
|
||||
builtins::{PyBaseExceptionRef, PyBytes, PyBytesRef, PyIntRef, PyTypeRef},
|
||||
function::{ArgBytesLike, OptionalArg},
|
||||
IntoPyRef, PyResult, PyValue, VirtualMachine,
|
||||
};
|
||||
@@ -53,9 +53,13 @@ mod zlib {
|
||||
#[pyattr]
|
||||
const DEF_MEM_LEVEL: u8 = 8;
|
||||
|
||||
#[pyattr]
|
||||
#[pyattr(once)]
|
||||
fn error(vm: &VirtualMachine) -> PyTypeRef {
|
||||
PyType::new_simple_ref("zlib.error", &vm.ctx.exceptions.exception_type).unwrap()
|
||||
vm.ctx.new_exception_type(
|
||||
"zlib",
|
||||
"error",
|
||||
Some(vec![vm.ctx.exceptions.exception_type.clone()]),
|
||||
)
|
||||
}
|
||||
|
||||
/// Compute an Adler-32 checksum of data.
|
||||
|
||||
+27
-3
@@ -12,9 +12,9 @@ use crate::{
|
||||
builtinfunc::{PyBuiltinFunction, PyBuiltinMethod, PyNativeFuncDef},
|
||||
bytes,
|
||||
getset::{IntoPyGetterFunc, IntoPySetterFunc, PyGetSet},
|
||||
object, pystr, PyBaseExceptionRef, PyBoundMethod, PyDict, PyDictRef, PyEllipsis, PyFloat,
|
||||
PyFrozenSet, PyGenericAlias, PyInt, PyIntRef, PyList, PyListRef, PyNone, PyNotImplemented,
|
||||
PyStr, PyTuple, PyTupleRef, PyType, PyTypeRef,
|
||||
object, pystr, PyBaseException, PyBaseExceptionRef, PyBoundMethod, PyDict, PyDictRef,
|
||||
PyEllipsis, PyFloat, PyFrozenSet, PyGenericAlias, PyInt, PyIntRef, PyList, PyListRef,
|
||||
PyNone, PyNotImplemented, PyStr, PyTuple, PyTupleRef, PyType, PyTypeRef,
|
||||
},
|
||||
dictdatatype::Dict,
|
||||
exceptions,
|
||||
@@ -242,6 +242,30 @@ impl PyContext {
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn new_exception_type(
|
||||
&self,
|
||||
module: &str,
|
||||
name: &str,
|
||||
bases: Option<Vec<PyTypeRef>>,
|
||||
) -> PyTypeRef {
|
||||
let bases = if let Some(bases) = bases {
|
||||
bases
|
||||
} else {
|
||||
vec![self.exceptions.exception_type.clone()]
|
||||
};
|
||||
let mut attrs = PyAttributes::default();
|
||||
attrs.insert("__module__".to_string(), self.new_str(module).into());
|
||||
|
||||
PyType::new_ref(
|
||||
name,
|
||||
bases,
|
||||
attrs,
|
||||
PyBaseException::make_slots(),
|
||||
self.types.type_type.clone(),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn make_funcdef<F, FKind>(&self, name: impl Into<PyStr>, f: F) -> PyNativeFuncDef
|
||||
where
|
||||
|
||||
@@ -960,21 +960,9 @@ pub(crate) mod _struct {
|
||||
#[pyfunction]
|
||||
fn _clearcache() {}
|
||||
|
||||
#[pyattr(name = "error")]
|
||||
#[pyattr(name = "error", once)]
|
||||
fn error_type(vm: &VirtualMachine) -> PyTypeRef {
|
||||
rustpython_common::static_cell! {
|
||||
static STRUCT_ERROR: PyTypeRef;
|
||||
}
|
||||
STRUCT_ERROR
|
||||
.get_or_init(|| {
|
||||
vm.ctx.new_class(
|
||||
Some("struct"),
|
||||
"error",
|
||||
&vm.ctx.exceptions.exception_type,
|
||||
Default::default(),
|
||||
)
|
||||
})
|
||||
.clone()
|
||||
vm.ctx.new_exception_type("struct", "error", None)
|
||||
}
|
||||
|
||||
fn new_struct_error(vm: &VirtualMachine, msg: String) -> PyBaseExceptionRef {
|
||||
|
||||
Reference in new issue
Block a user