Merge pull request #3402 from Snowapril/refactor_exceptions

Refactor duplicated codes in exception creations
This commit is contained in:
Jeong YunWon authored and GitHub committed 2021-11-16 02:45:30 +09:00
commit e7fa32c687
10 files changed
+156 -185

No files matched your search

+33 -11
View File
@@ -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() =>
+13
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+2 -14
View File
@@ -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 {