@@ -12,6 +12,124 @@ pub fn derive_from_args(input: TokenStream) -> TokenStream {
12
12
derive_impl:: derive_from_args ( input) . into ( )
13
13
}
14
14
15
+ /// The attribute can be applied either to a struct, trait, or impl.
16
+ /// # Struct
17
+ /// This implements `MaybeTraverse`, `PyClassDef`, and `StaticType` for the struct.
18
+ /// Consider deriving `Traverse` to implement it.
19
+ /// ## Arguments
20
+ /// - `module`: the module which contains the class -- can be omitted if in a `#[pymodule]`.
21
+ /// - `name`: the name of the Python class, by default it is the name of the struct.
22
+ /// - `base`: the base class of the Python class.
23
+ /// This does not cause inheritance of functions or attributes that must be done by a separate trait.
24
+ /// # Impl
25
+ /// This part implements `PyClassImpl` for the struct.
26
+ /// This includes methods, getters/setters, etc.; only annotated methods will be included.
27
+ /// Common functions and abilities like instantiation and `__call__` are often implemented by
28
+ /// traits rather than in the `impl` itself; see `Constructor` and `Callable` respectively for those.
29
+ /// ## Arguments
30
+ /// - `name`: the name of the Python class, when no name is provided the struct name is used.
31
+ /// - `flags`: the flags of the class, see `PyTypeFlags`.
32
+ /// - `BASETYPE`: allows the class to be inheritable.
33
+ /// - `IMMUTABLETYPE`: class attributes are immutable.
34
+ /// - `with`: which trait implementations are to be included in the python class.
35
+ /// ```rust, ignore
36
+ /// #[pyclass(module = "mymodule", name = "MyClass", base = "BaseClass")]
37
+ /// struct MyStruct {
38
+ /// x: i32,
39
+ /// }
40
+ ///
41
+ /// impl Constructor for MyStruct {
42
+ /// ...
43
+ /// }
44
+ ///
45
+ /// #[pyclass(with(Constructor))]
46
+ /// impl MyStruct {
47
+ /// ...
48
+ /// }
49
+ /// ```
50
+ /// ## Inner markers
51
+ /// ### pymethod/pyclassmethod/pystaticmethod
52
+ /// `pymethod` is used to mark a method of the Python class.
53
+ /// `pyclassmethod` is used to mark a class method.
54
+ /// `pystaticmethod` is used to mark a static method.
55
+ /// #### Method signature
56
+ /// The first parameter can be either `&self` or `<var>: PyRef<Self>` for `pymethod`.
57
+ /// The first parameter can be `cls: PyTypeRef` for `pyclassmethod`.
58
+ /// There is no mandatory parameter for `pystaticmethod`.
59
+ /// Both are valid and essentially the same, but the latter can yield more control.
60
+ /// The last parameter can optionally be of the type `&VirtualMachine` to access the VM.
61
+ /// All other values must implement `IntoPyResult`.
62
+ /// Numeric types, `String`, `bool`, and `PyObjectRef` implement this trait,
63
+ /// but so does any object that implements `PyValue`.
64
+ /// Consider using `OptionalArg` for optional arguments.
65
+ /// #### Arguments
66
+ /// - `magic`: marks the method as a magic method: the method name is surrounded with double underscores.
67
+ /// ```rust, ignore
68
+ /// #[pyclass]
69
+ /// impl MyStruct {
70
+ /// // This will be called as the `__add__` method in Python.
71
+ /// #[pymethod(magic)]
72
+ /// fn add(&self, other: &Self) -> PyResult<i32> {
73
+ /// ...
74
+ /// }
75
+ /// }
76
+ /// ```
77
+ /// - `name`: the name of the method in Python,
78
+ /// by default it is the same as the Rust method, or surrounded by double underscores if magic is present.
79
+ /// This overrides `magic` and the default name and cannot be used with `magic` to prevent ambiguity.
80
+ /// ### pygetset
81
+ /// This is used to mark a getter/setter pair.
82
+ /// #### Arguments
83
+ /// - `setter`: marks the method as a setter, it acts as a getter by default.
84
+ /// Setter method names should be prefixed with `set_`.
85
+ /// - `name`: the name of the attribute in Python, by default it is the same as the Rust method.
86
+ /// - `magic`: marks the method as a magic method: the method name is surrounded with double underscores.
87
+ /// This cannot be used with `name` to prevent ambiguity.
88
+ ///
89
+ /// Ensure both the getter and setter are marked with `name` and `magic` in the same manner.
90
+ /// #### Examples
91
+ /// ```rust, ignore
92
+ /// #[pyclass]
93
+ /// impl MyStruct {
94
+ /// #[pygetset]
95
+ /// fn x(&self) -> PyResult<i32> {
96
+ /// Ok(self.x.lock())
97
+ /// }
98
+ /// #[pygetset(setter)]
99
+ /// fn set_x(&mut self, value: i32) -> PyResult<()> {
100
+ /// self.x.set(value);
101
+ /// Ok(())
102
+ /// }
103
+ /// }
104
+ /// ```
105
+ /// ### pyslot
106
+ /// This is used to mark a slot method it should be marked by prefixing the method in rust with `slot_`.
107
+ /// #### Arguments
108
+ /// - name: the name of the slot method.
109
+ /// ### pyattr
110
+ /// ### extend_class
111
+ /// This helps inherit attributes from a parent class.
112
+ /// The method this is applied on should be called `extend_class_with_fields`.
113
+ /// #### Examples
114
+ /// ```rust, ignore
115
+ /// #[extend_class]
116
+ /// fn extend_class_with_fields(ctx: &Context, class: &'static Py<PyType>) {
117
+ /// class.set_attr(
118
+ /// identifier!(ctx, _fields),
119
+ /// ctx.new_tuple(vec![
120
+ /// ctx.new_str(ascii!("body")).into(),
121
+ /// ctx.new_str(ascii!("type_ignores")).into(),
122
+ /// ])
123
+ /// .into(),
124
+ /// );
125
+ /// class.set_attr(identifier!(ctx, _attributes), ctx.new_list(vec![]).into());
126
+ /// }
127
+ /// ```
128
+ /// ### pymember
129
+ /// # Trait
130
+ /// `#[pyclass]` on traits functions a lot like `#[pyclass]` on `impl` blocks.
131
+ /// Note that associated functions that are annotated with `#[pymethod]` or similar **must**
132
+ /// have a body, abstract functions should be wrapped before applying an annotation.
15
133
#[ proc_macro_attribute]
16
134
pub fn pyclass ( attr : TokenStream , item : TokenStream ) -> TokenStream {
17
135
let attr = parse_macro_input ! ( attr) ;
@@ -34,6 +152,71 @@ pub fn pyexception(attr: TokenStream, item: TokenStream) -> TokenStream {
34
152
derive_impl:: pyexception ( attr, item) . into ( )
35
153
}
36
154
155
+ /// This attribute must be applied to an inline module.
156
+ /// It defines a Python module in the form a `make_module` function in the module;
157
+ /// this has to be used in a `get_module_inits` to properly register the module.
158
+ /// Additionally, this macro defines 'MODULE_NAME' and 'DOC' in the module.
159
+ /// # Arguments
160
+ /// - `name`: the name of the python module,
161
+ /// by default, it is the name of the module, but this can be configured.
162
+ /// ```rust, ignore
163
+ /// // This will create a module named `mymodule`
164
+ /// #[pymodule(name = "mymodule")]
165
+ /// mod module {
166
+ /// }
167
+ /// ```
168
+ /// - `sub`: declare the module as a submodule of another module.
169
+ /// ```rust, ignore
170
+ /// #[pymodule(sub)]
171
+ /// mod submodule {
172
+ /// }
173
+ ///
174
+ /// #[pymodule(with(submodule))]
175
+ /// mod mymodule {
176
+ /// }
177
+ /// ```
178
+ /// - `with`: declare the list of submodules that this module contains (see `sub` for example).
179
+ /// ## Inner markers
180
+ /// ### pyattr
181
+ /// `pyattr` is a multipurpose marker that can be used in a pymodule.
182
+ /// The most common use is to mark a function or class as a part of the module.
183
+ /// This can be done by applying it to a function or struct prior to the `#[pyfunction]` or `#[pyclass]` macro.
184
+ /// If applied to a constant, it will be added to the module as an attribute.
185
+ /// If applied to a function not marked with `pyfunction`,
186
+ /// it will also be added to the module as an attribute but the value is the result of the function.
187
+ /// If `#[pyattr(once)]` is used in this case, the function will be called once
188
+ /// and the result will be stored using a `static_cell`.
189
+ /// #### Examples
190
+ /// ```rust, ignore
191
+ /// #[pymodule]
192
+ /// mod mymodule {
193
+ /// #[pyattr]
194
+ /// const MY_CONSTANT: i32 = 42;
195
+ /// #[pyattr]
196
+ /// fn another_constant() -> PyResult<i32> {
197
+ /// Ok(42)
198
+ /// }
199
+ /// #[pyattr(once)]
200
+ /// fn once() -> PyResult<i32> {
201
+ /// // This will only be called once and the result will be stored.
202
+ /// Ok(2 ** 24)
203
+ /// }
204
+ ///
205
+ /// #[pyattr]
206
+ /// #[pyfunction]
207
+ /// fn my_function(vm: &VirtualMachine) -> PyResult<()> {
208
+ /// ...
209
+ /// }
210
+ /// }
211
+ /// ```
212
+ /// ### pyfunction
213
+ /// This is used to create a python function.
214
+ /// #### Function signature
215
+ /// The last argument can optionally be of the type `&VirtualMachine` to access the VM.
216
+ /// Refer to the `pymethod` documentation (located in the `pyclass` macro documentation)
217
+ /// for more information on what regular argument types are permitted.
218
+ /// #### Arguments
219
+ /// - `name`: the name of the function in Python, by default it is the same as the associated Rust function.
37
220
#[ proc_macro_attribute]
38
221
pub fn pymodule ( attr : TokenStream , item : TokenStream ) -> TokenStream {
39
222
let attr = parse_macro_input ! ( attr) ;
0 commit comments