#[pyclass] now requires module field

This commit is contained in:
Jeong YunWon
2020-08-22 14:46:49 +09:00
parent c9c1ac9532
commit 9d025b0e4e
44 changed files with 103 additions and 63 deletions

View File

@@ -596,7 +596,7 @@ pub fn impl_pystruct_sequence(attr: AttributeArgs, item: Item) -> Result<TokenSt
let class_meta =
ClassItemMeta::from_nested("pystruct_sequence", &struc.ident, attr.into_iter())?;
let class_name = class_meta.class_name()?;
let module_name = class_meta.module()?.unwrap();
let module_name = class_meta.mandatory_module()?;
let class_def =
generate_class_def(&struc.ident, &class_name, Some(&module_name), &struc.attrs)?;

View File

@@ -243,7 +243,47 @@ impl ClassItemMeta {
}
pub fn module(&self) -> Result<Option<String>> {
self.inner()._optional_str("module")
const KEY: &str = "module";
let inner = self.inner();
let value = if let Some((_, meta)) = inner.meta.get(KEY) {
match meta {
Meta::NameValue(syn::MetaNameValue {
lit: syn::Lit::Str(lit),
..
}) => Ok(Some(lit.value())),
Meta::NameValue(syn::MetaNameValue {
lit: syn::Lit::Bool(lit),
..
}) => if lit.value {
Err(lit.span())
} else {
Ok(None)
}
other => Err(other.span()),
}
} else {
Err(inner.ident.span())
}.map_err(|span| syn::Error::new(
span,
format!(
"#[{attr_name}(module = ...)] must exist as a string or false. Try #[{attr_name}(module=false)] for built-in types.",
attr_name=inner.parent_type
),
))?;
Ok(value)
}
pub fn mandatory_module(&self) -> Result<String> {
let inner = self.inner();
let value = self.module().ok().flatten().
ok_or_else(|| syn::Error::new_spanned(
&inner.ident,
format!(
"#[{attr_name}(module = ...)] must exist as a string. Built-in module is not allowed here.",
attr_name=inner.parent_type
),
))?;
Ok(value)
}
}

View File

@@ -21,7 +21,7 @@ use std::io::{self, BufRead, BufReader};
use crossbeam_utils::atomic::AtomicCell;
#[pyclass(name = "BaseException")]
#[pyclass(module = false, name = "BaseException")]
pub struct PyBaseException {
traceback: PyRwLock<Option<PyTracebackRef>>,
cause: PyRwLock<Option<PyBaseExceptionRef>>,

View File

@@ -87,7 +87,7 @@ struct FrameState {
blocks: Vec<Block>,
}
#[pyclass(name = "frame")]
#[pyclass(module = false, name = "frame")]
pub struct Frame {
pub code: PyCodeRef,
pub scope: Scope,

View File

@@ -9,7 +9,7 @@ use crate::vm::VirtualMachine;
use crossbeam_utils::atomic::AtomicCell;
#[pyclass(name = "async_generator")]
#[pyclass(name = "async_generator", module = false)]
#[derive(Debug)]
pub struct PyAsyncGen {
inner: Coro,
@@ -114,7 +114,7 @@ impl PyAsyncGen {
}
}
#[pyclass(name = "async_generator_wrapped_value")]
#[pyclass(module = false, name = "async_generator_wrapped_value")]
#[derive(Debug)]
pub(crate) struct PyAsyncGenWrappedValue(pub PyObjectRef);
impl PyValue for PyAsyncGenWrappedValue {
@@ -158,7 +158,7 @@ enum AwaitableState {
Closed,
}
#[pyclass(name = "async_generator_asend")]
#[pyclass(module = false, name = "async_generator_asend")]
#[derive(Debug)]
pub(crate) struct PyAsyncGenASend {
ag: PyAsyncGenRef,
@@ -253,7 +253,7 @@ impl PyAsyncGenASend {
}
}
#[pyclass(name = "async_generator_athrow")]
#[pyclass(module = false, name = "async_generator_athrow")]
#[derive(Debug)]
pub(crate) struct PyAsyncGenAThrow {
ag: PyAsyncGenRef,

View File

@@ -81,7 +81,7 @@ pub fn boolval(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<bool> {
/// Returns True when the argument x is true, False otherwise.
/// The builtins True and False are the only two instances of the class bool.
/// The class bool is a subclass of the class int, and cannot be subclassed.
#[pyclass(name = "bool")]
#[pyclass(name = "bool", module = false)]
pub(crate) struct PyBool;
#[pyimpl]

View File

@@ -9,7 +9,7 @@ use crate::pyobject::{
use crate::slots::{SlotCall, SlotDescriptor};
use crate::vm::VirtualMachine;
#[pyclass(name = "builtin_function_or_method")]
#[pyclass(name = "builtin_function_or_method", module = false)]
pub struct PyBuiltinFunction {
value: PyNativeFunc,
module: Option<PyStringRef>,
@@ -70,7 +70,7 @@ impl PyBuiltinFunction {
}
}
#[pyclass(name = "method_descriptor")]
#[pyclass(module = false, name = "method_descriptor")]
pub struct PyBuiltinMethod {
function: PyBuiltinFunction,
}

View File

@@ -33,7 +33,7 @@ use crate::vm::VirtualMachine;
/// - a bytes or a buffer object\n \
/// - any object implementing the buffer API.\n \
/// - an integer";
#[pyclass(name = "bytearray")]
#[pyclass(module = false, name = "bytearray")]
#[derive(Debug)]
pub struct PyByteArray {
inner: PyRwLock<PyBytesInner>,
@@ -606,7 +606,7 @@ impl PyByteArray {
// obj.borrow_mut().kind = PyObjectPayload::Bytes { value };
// }
#[pyclass(name = "bytearray_iterator")]
#[pyclass(module = false, name = "bytearray_iterator")]
#[derive(Debug)]
pub struct PyByteArrayIterator {
position: AtomicCell<usize>,

View File

@@ -32,7 +32,7 @@ use rustpython_common::hash::PyHash;
/// - a text string encoded using the specified encoding\n \
/// - any object implementing the buffer API.\n \
/// - an integer";
#[pyclass(name = "bytes")]
#[pyclass(module = false, name = "bytes")]
#[derive(Clone, Debug)]
pub struct PyBytes {
inner: PyBytesInner,
@@ -488,7 +488,7 @@ impl PyBytes {
}
}
#[pyclass(name = "bytes_iterator")]
#[pyclass(module = false, name = "bytes_iterator")]
#[derive(Debug)]
pub struct PyBytesIterator {
position: AtomicCell<usize>,

View File

@@ -26,7 +26,7 @@ use crate::vm::VirtualMachine;
///
/// Class methods are different than C++ or Java static methods.
/// If you want those, see the staticmethod builtin.
#[pyclass(name = "classmethod")]
#[pyclass(module = false, name = "classmethod")]
#[derive(Clone, Debug)]
pub struct PyClassMethod {
callable: PyObjectRef,

View File

@@ -12,7 +12,7 @@ use crate::vm::VirtualMachine;
pub type PyCodeRef = PyRef<PyCode>;
#[pyclass(name = "code")]
#[pyclass(module = false, name = "code")]
pub struct PyCode {
pub code: bytecode::CodeObject,
}

View File

@@ -14,7 +14,7 @@ use rustpython_common::{float_ops, hash};
/// Create a complex number from a real part and an optional imaginary part.
///
/// This is equivalent to (real + imag*1j) where imag defaults to 0.
#[pyclass(name = "complex")]
#[pyclass(module = false, name = "complex")]
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct PyComplex {
value: Complex64,

View File

@@ -9,7 +9,7 @@ use crate::vm::VirtualMachine;
pub type PyCoroutineRef = PyRef<PyCoroutine>;
#[pyclass(name = "coroutine")]
#[pyclass(module = false, name = "coroutine")]
#[derive(Debug)]
pub struct PyCoroutine {
inner: Coro,
@@ -95,7 +95,7 @@ impl PyCoroutine {
}
}
#[pyclass(name = "coroutine_wrapper")]
#[pyclass(module = false, name = "coroutine_wrapper")]
#[derive(Debug)]
pub struct PyCoroutineWrapper {
coro: PyCoroutineRef,

View File

@@ -18,7 +18,7 @@ use std::mem::size_of;
pub type DictContentType = dictdatatype::Dict;
#[pyclass(name = "dict")]
#[pyclass(module = false, name = "dict")]
#[derive(Default)]
pub struct PyDict {
entries: DictContentType,
@@ -553,7 +553,7 @@ impl Iterator for DictIter {
macro_rules! dict_iterator {
( $name: ident, $iter_name: ident, $class: ident, $iter_class: ident, $class_name: literal, $iter_class_name: literal, $result_fn: expr) => {
#[pyclass(name = $class_name)]
#[pyclass(module=false,name = $class_name)]
#[derive(Debug)]
pub(crate) struct $name {
pub dict: PyDictRef,
@@ -598,7 +598,7 @@ macro_rules! dict_iterator {
}
}
#[pyclass(name = $iter_class_name)]
#[pyclass(module=false,name = $iter_class_name)]
#[derive(Debug)]
pub(crate) struct $iter_name {
pub dict: PyDictRef,

View File

@@ -6,7 +6,7 @@ pub(crate) fn init(context: &PyContext) {
PyEllipsis::extend_class(context, &context.ellipsis_type());
}
#[pyclass(name = "EllipsisType")]
#[pyclass(module = false, name = "EllipsisType")]
#[derive(Debug)]
pub struct PyEllipsis;

View File

@@ -11,7 +11,7 @@ use crate::function::OptionalArg;
use crate::pyobject::{BorrowValue, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
use crate::vm::VirtualMachine;
#[pyclass(name = "enumerate")]
#[pyclass(module = false, name = "enumerate")]
#[derive(Debug)]
pub struct PyEnumerate {
counter: PyRwLock<BigInt>,

View File

@@ -10,7 +10,7 @@ pub type PyFilterRef = PyRef<PyFilter>;
///
/// Return an iterator yielding those items of iterable for which function(item)
/// is true. If function is None, return the items that are true.
#[pyclass(name = "filter")]
#[pyclass(module = false, name = "filter")]
#[derive(Debug)]
pub struct PyFilter {
predicate: PyObjectRef,

View File

@@ -19,7 +19,7 @@ use crate::vm::VirtualMachine;
use rustpython_common::{float_ops, hash};
/// Convert a string or number to a floating point number, if possible.
#[pyclass(name = "float")]
#[pyclass(module = false, name = "float")]
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct PyFloat {
value: f64,

View File

@@ -20,7 +20,7 @@ use itertools::Itertools;
pub type PyFunctionRef = PyRef<PyFunction>;
#[pyclass(name = "function")]
#[pyclass(module = false, name = "function")]
#[derive(Debug)]
pub struct PyFunction {
code: PyCodeRef,
@@ -287,7 +287,7 @@ impl PyFunction {
}
}
#[pyclass(name = "method")]
#[pyclass(module = false, name = "method")]
#[derive(Debug)]
pub struct PyBoundMethod {
// TODO: these shouldn't be public

View File

@@ -12,7 +12,7 @@ use crate::vm::VirtualMachine;
pub type PyGeneratorRef = PyRef<PyGenerator>;
#[pyclass(name = "generator")]
#[pyclass(module = false, name = "generator")]
#[derive(Debug)]
pub struct PyGenerator {
inner: Coro,

View File

@@ -144,7 +144,7 @@ where
}
}
#[pyclass(name = "getset_descriptor")]
#[pyclass(module = false, name = "getset_descriptor")]
pub struct PyGetSet {
name: String,
getter: Option<PyGetterFunc>,

View File

@@ -40,7 +40,7 @@ use rustpython_common::hash;
/// Base 0 means to interpret the base from the string as an integer literal.
/// >>> int('0b100', base=0)
/// 4
#[pyclass(name = "int")]
#[pyclass(module = false, name = "int")]
#[derive(Debug)]
pub struct PyInt {
value: BigInt,

View File

@@ -149,7 +149,7 @@ pub fn length_hint(vm: &VirtualMachine, iter: PyObjectRef) -> PyResult<Option<us
Ok(Some(hint))
}
#[pyclass(name = "iter")]
#[pyclass(module = false, name = "iter")]
#[derive(Debug)]
pub struct PySequenceIterator {
pub position: AtomicCell<isize>,
@@ -222,7 +222,7 @@ pub fn seq_iter_method(obj: PyObjectRef) -> PySequenceIterator {
PySequenceIterator::new_forward(obj)
}
#[pyclass(name = "callable_iterator")]
#[pyclass(module = false, name = "callable_iterator")]
#[derive(Debug)]
pub struct PyCallableIterator {
callable: PyCallable,

View File

@@ -27,7 +27,7 @@ use crate::vm::{ReprGuard, VirtualMachine};
///
/// If no argument is given, the constructor creates a new empty list.
/// The argument must be an iterable if specified.
#[pyclass(name = "list")]
#[pyclass(module = false, name = "list")]
#[derive(Default)]
pub struct PyList {
elements: PyRwLock<Vec<PyObjectRef>>,
@@ -825,7 +825,7 @@ fn do_sort(
Ok(())
}
#[pyclass(name = "list_iterator")]
#[pyclass(module = false, name = "list_iterator")]
#[derive(Debug)]
pub struct PyListIterator {
pub position: AtomicCell<usize>,
@@ -864,7 +864,7 @@ impl PyListIterator {
}
}
#[pyclass(name = "list_reverseiterator")]
#[pyclass(module = false, name = "list_reverseiterator")]
#[derive(Debug)]
pub struct PyListReverseIterator {
pub position: AtomicCell<isize>,

View File

@@ -8,7 +8,7 @@ use crate::vm::VirtualMachine;
///
/// Make an iterator that computes the function using arguments from
/// each of the iterables. Stops when the shortest iterable is exhausted.
#[pyclass(name = "map")]
#[pyclass(module = false, name = "map")]
#[derive(Debug)]
pub struct PyMap {
mapper: PyObjectRef,

View File

@@ -9,7 +9,7 @@ use crate::pyobject::{
};
use crate::vm::VirtualMachine;
#[pyclass(name = "mappingproxy")]
#[pyclass(module = false, name = "mappingproxy")]
#[derive(Debug)]
pub struct PyMappingProxy {
mapping: MappingProxyInner,

View File

@@ -6,7 +6,7 @@ use crate::pyobject::{
use crate::stdlib::array::PyArray;
use crate::vm::VirtualMachine;
#[pyclass(name = "memoryview")]
#[pyclass(module = false, name = "memoryview")]
#[derive(Debug)]
pub struct PyMemoryView {
obj_ref: PyObjectRef,

View File

@@ -7,7 +7,7 @@ use crate::pyobject::{
};
use crate::vm::VirtualMachine;
#[pyclass(name = "module")]
#[pyclass(module = false, name = "module")]
#[derive(Debug)]
pub struct PyModule {}
pub type PyModuleRef = PyRef<PyModule>;

View File

@@ -6,7 +6,7 @@ use crate::vm::VirtualMachine;
/// A simple attribute-based namespace.
///
/// SimpleNamespace(**kwargs)
#[pyclass(name = "SimpleNamespace")]
#[pyclass(module = false, name = "SimpleNamespace")]
#[derive(Debug)]
pub struct PyNamespace;

View File

@@ -4,7 +4,7 @@ use crate::pyobject::{
};
use crate::vm::VirtualMachine;
#[pyclass(name = "NoneType")]
#[pyclass(module = false, name = "NoneType")]
#[derive(Debug)]
pub struct PyNone;
pub type PyNoneRef = PyRef<PyNone>;

View File

@@ -13,7 +13,7 @@ use crate::pyobject::{
use crate::vm::VirtualMachine;
/// The most base type
#[pyclass(name = "object")]
#[pyclass(module = false, name = "object")]
#[derive(Debug)]
pub struct PyBaseObject;

View File

@@ -43,7 +43,7 @@ use crate::vm::VirtualMachine;
/// @x.deleter
/// def x(self):
/// del self._x
#[pyclass(name = "property")]
#[pyclass(module = false, name = "property")]
#[derive(Debug)]
pub struct PyProperty {
getter: Option<PyObjectRef>,

View File

@@ -25,7 +25,7 @@ use rustpython_common::hash::PyHash;
/// start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.
/// These are exactly the valid indices for a list of 4 elements.
/// When step is given, it specifies the increment (or decrement).
#[pyclass(name = "range")]
#[pyclass(module = false, name = "range")]
#[derive(Debug, Clone)]
pub struct PyRange {
pub start: PyIntRef,
@@ -400,7 +400,7 @@ impl PyRange {
}
}
#[pyclass(name = "range_iterator")]
#[pyclass(module = false, name = "range_iterator")]
#[derive(Debug)]
pub struct PyRangeIterator {
position: AtomicCell<usize>,

View File

@@ -21,7 +21,7 @@ pub type SetContentType = dictdatatype::Dict<()>;
/// set(iterable) -> new set object
///
/// Build an unordered collection of unique elements.
#[pyclass(name = "set")]
#[pyclass(module = false, name = "set")]
#[derive(Default)]
pub struct PySet {
inner: PySetInner,
@@ -32,7 +32,7 @@ pub type PySetRef = PyRef<PySet>;
/// frozenset(iterable) -> frozenset object
///
/// Build an immutable unordered collection of unique elements.
#[pyclass(name = "frozenset")]
#[pyclass(module = false, name = "frozenset")]
#[derive(Default)]
pub struct PyFrozenSet {
inner: PySetInner,
@@ -824,7 +824,7 @@ struct SetSizeInfo {
position: usize,
}
#[pyclass(name = "set_iterator")]
#[pyclass(module = false, name = "set_iterator")]
pub(crate) struct PySetIterator {
dict: PyRc<SetContentType>,
size_info: crossbeam_utils::atomic::AtomicCell<SetSizeInfo>,

View File

@@ -9,7 +9,7 @@ use crate::vm::VirtualMachine;
use num_bigint::{BigInt, ToBigInt};
use num_traits::{One, Signed, Zero};
#[pyclass(name = "slice")]
#[pyclass(module = false, name = "slice")]
#[derive(Debug)]
pub struct PySlice {
pub start: Option<PyObjectRef>,

View File

@@ -4,7 +4,7 @@ use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyVa
use crate::slots::SlotDescriptor;
use crate::vm::VirtualMachine;
#[pyclass(name = "staticmethod")]
#[pyclass(module = false, name = "staticmethod")]
#[derive(Clone, Debug)]
pub struct PyStaticMethod {
pub callable: PyObjectRef,

View File

@@ -41,7 +41,7 @@ use rustpython_common::hash;
/// or repr(object).
/// encoding defaults to sys.getdefaultencoding().
/// errors defaults to 'strict'."
#[pyclass(name = "str")]
#[pyclass(module = false, name = "str")]
#[derive(Debug)]
pub struct PyString {
value: String,
@@ -102,7 +102,7 @@ impl TryIntoRef<PyString> for &str {
}
}
#[pyclass(name = "str_iterator")]
#[pyclass(module = false, name = "str_iterator")]
#[derive(Debug)]
pub struct PyStringIterator {
pub string: PyStringRef,
@@ -135,7 +135,7 @@ impl PyStringIterator {
}
}
#[pyclass(name = "str_reverseiterator")]
#[pyclass(module = false, name = "str_reverseiterator")]
#[derive(Debug)]
pub struct PyStringReverseIterator {
pub position: AtomicCell<isize>,

View File

@@ -21,7 +21,7 @@ use itertools::Itertools;
pub type PySuperRef = PyRef<PySuper>;
#[pyclass(name = "super")]
#[pyclass(module = false, name = "super")]
#[derive(Debug)]
pub struct PySuper {
typ: PyClassRef,

View File

@@ -3,7 +3,7 @@ use crate::obj::objtype::PyClassRef;
use crate::pyobject::{PyClassImpl, PyContext, PyRef, PyValue};
use crate::vm::VirtualMachine;
#[pyclass(name = "traceback")]
#[pyclass(module = false, name = "traceback")]
#[derive(Debug)]
pub struct PyTraceback {
pub next: Option<PyTracebackRef>, // TODO: Make mutable

View File

@@ -18,7 +18,7 @@ use rustpython_common::hash::PyHash;
/// tuple(iterable) -> tuple initialized from iterable's items
///
/// If the argument is a tuple, the return value is the same object.
#[pyclass(name = "tuple")]
#[pyclass(module = false, name = "tuple")]
pub struct PyTuple {
elements: Vec<PyObjectRef>,
}
@@ -255,7 +255,7 @@ impl PyTuple {
}
}
#[pyclass(name = "tuple_iterator")]
#[pyclass(module = false, name = "tuple_iterator")]
#[derive(Debug)]
pub struct PyTupleIterator {
position: AtomicCell<usize>,

View File

@@ -24,7 +24,7 @@ use std::ops::Deref;
/// type(object_or_name, bases, dict)
/// type(object) -> the object's type
/// type(name, bases, dict) -> a new type
#[pyclass(name = "type")]
#[pyclass(module = false, name = "type")]
pub struct PyClass {
pub name: String,
pub base: Option<PyClassRef>,

View File

@@ -4,7 +4,7 @@ use crate::function::OptionalArg;
use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
use crate::vm::VirtualMachine;
#[pyclass(name = "weakproxy")]
#[pyclass(module = false, name = "weakproxy")]
#[derive(Debug)]
pub struct PyWeakProxy {
weak: PyWeak,

View File

@@ -11,7 +11,7 @@ use rustpython_common::rc::{PyRc, PyWeak as Weak};
use crossbeam_utils::atomic::AtomicCell;
#[pyclass(name = "ref")]
#[pyclass(module = false, name = "ref")]
#[derive(Debug)]
pub struct PyWeak {
referent: Weak<PyObject<dyn PyObjectPayload>>,

View File

@@ -6,7 +6,7 @@ use crate::vm::VirtualMachine;
pub type PyZipRef = PyRef<PyZip>;
#[pyclass(name = "zip")]
#[pyclass(module = false, name = "zip")]
#[derive(Debug)]
pub struct PyZip {
iterators: Vec<PyObjectRef>,