1#[cfg(feature = "doc")]
5#[doc(hidden)]
6#[macro_export]
7macro_rules! __cfg_doc {
8 ({ $($doc:tt)* } else { $($no_doc:tt)* }) => { $($doc)* };
9}
10
11#[cfg(not(feature = "doc"))]
12#[doc(hidden)]
13#[macro_export]
14macro_rules! __cfg_doc {
15 ({ $($doc:tt)* } else { $($no_doc:tt)* }) => { $($no_doc)* };
16}
17
18#[macro_export]
19macro_rules! extend_module {
20 ( $vm:expr, $module:expr, { $($name:expr => $value:expr),* $(,)? }) => {{
21 $(
22 $vm.__module_set_attr($module, $vm.ctx.intern_str($name), $value).unwrap();
23 )*
24 }};
25}
26
27#[macro_export]
28macro_rules! py_class {
29 ( $ctx:expr, $class_name:expr, $class_base:expr, { $($name:tt => $value:expr),* $(,)* }) => {
30 py_class!($ctx, $class_name, $class_base, $crate::types::PyTypeFlags::from_element($crate::types::PyTypeFlags::BASETYPE), { $($name => $value),* })
31 };
32 ( $ctx:expr, $class_name:expr, $class_base:expr, $flags:expr, { $($name:tt => $value:expr),* $(,)* }) => {
33 {
34 #[allow(unused_mut)]
35 let mut slots = $crate::types::PyTypeSlots::heap_default();
36 slots.flags = $crate::types::AtomicPyTypeFlags::from_plain($flags);
37 $($crate::py_class!(@extract_slots($ctx, &mut slots, $name, $value));)*
38 let py_class = $ctx.new_class(None, $class_name, $class_base, slots);
39 $($crate::py_class!(@extract_attrs($ctx, &py_class, $name, $value));)*
40 py_class
41 }
42 };
43 (@extract_slots($ctx:expr, $slots:expr, (slot $slot_name:ident), $value:expr)) => {
44 $slots.$slot_name.store(Some($value));
45 };
46 (@extract_slots($ctx:expr, $class:expr, $name:expr, $value:expr)) => {};
47 (@extract_attrs($ctx:expr, $slots:expr, (slot $slot_name:ident), $value:expr)) => {};
48 (@extract_attrs($ctx:expr, $class:expr, $name:expr, $value:expr)) => {
49 $class.set_attr($name, $value);
50 };
51}
52
53#[macro_export]
54macro_rules! extend_class {
55 ( $ctx:expr, $class:expr, { $($name:expr => $value:expr),* $(,)* }) => {
56 $(
57 $class.set_attr($ctx.intern_str($name), $value.into());
58 )*
59 };
60}
61
62#[macro_export]
63macro_rules! py_namespace {
64 ( $vm:expr, { $($name:expr => $value:expr),* $(,)* }) => {
65 {
66 let namespace = $crate::object::PyPayload::into_ref($crate::builtins::PyNamespace {}, &$vm.ctx);
67 let obj = $crate::object::AsObject::as_object(&namespace);
68 $(
69 obj.generic_setattr($vm.ctx.intern_str($name), $crate::function::PySetterValue::Assign($value.into()), $vm).unwrap();
70 )*
71 namespace
72 }
73 }
74}
75
76#[macro_export]
126macro_rules! match_class {
127 (match ($obj:expr) { _ => $default:expr $(,)? }) => {
129 $default
130 };
131
132 (match ($obj:expr) { $binding:ident => $default:expr $(,)? }) => {{
134 #[allow(clippy::redundant_locals, reason = "macro arm intentionally binds expression once to a local")]
135 let $binding = $obj;
136 $default
137 }};
138 (match ($obj:expr) { ref $binding:ident => $default:expr $(,)? }) => {{
139 #[allow(clippy::redundant_locals, reason = "macro arm intentionally binds expression once to a local reference")]
140 let $binding = &$obj;
141 $default
142 }};
143
144 (match ($obj:expr) { $binding:ident @ $class:ty => $expr:block $($rest:tt)* }) => {
148 $crate::match_class!(match ($obj) { $binding @ $class => ($expr), $($rest)* })
149 };
150 (match ($obj:expr) { ref $binding:ident @ $class:ty => $expr:block $($rest:tt)* }) => {
151 $crate::match_class!(match ($obj) { ref $binding @ $class => ($expr), $($rest)* })
152 };
153
154 (match ($obj:expr) { $binding:ident @ $class:ty => $expr:expr, $($rest:tt)* }) => {
157 match $obj.downcast::<$class>() {
158 Ok($binding) => $expr,
159 Err(_obj) => $crate::match_class!(match (_obj) { $($rest)* }),
160 }
161 };
162 (match ($obj:expr) { ref $binding:ident @ $class:ty => $expr:expr, $($rest:tt)* }) => {
163 match $obj.downcast_ref::<$class>() {
164 core::option::Option::Some($binding) => $expr,
165 core::option::Option::None => $crate::match_class!(match ($obj) { $($rest)* }),
166 }
167 };
168
169 (match ($obj:expr) { $class:ty => $expr:block $($rest:tt)* }) => {
172 $crate::match_class!(match ($obj) { $class => ($expr), $($rest)* })
173 };
174
175 (match ($obj:expr) { $class:ty => $expr:expr, $($rest:tt)* }) => {
178 if $obj.downcastable::<$class>() {
179 $expr
180 } else {
181 $crate::match_class!(match ($obj) { $($rest)* })
182 }
183 };
184
185 (match $($rest:tt)*) => {
187 $crate::match_class!(@parse_match () ($($rest)*))
188 };
189 (@parse_match ($($target:tt)*) ({ $($inner:tt)* })) => {
190 $crate::match_class!(match ($($target)*) { $($inner)* })
191 };
192 (@parse_match ($($target:tt)*) ($next:tt $($rest:tt)*)) => {
193 $crate::match_class!(@parse_match ($($target)* $next) ($($rest)*))
194 };
195}
196
197#[macro_export]
198macro_rules! identifier(
199 ($as_ctx:expr, $name:ident) => {
200 $as_ctx.as_ref().names.$name
201 };
202);
203
204#[macro_export]
205macro_rules! identifier_utf8(
206 ($as_ctx:expr, $name:ident) => {{
207 let interned = $as_ctx.as_ref().names.$name;
209 unsafe { $crate::builtins::PyUtf8StrInterned::from_str_interned_unchecked(interned) }
210 }};
211);
212
213macro_rules! vm_trace {
217 ($($arg:tt)+) => {
218 #[cfg(feature = "vm-tracing-logging")]
219 trace!($($arg)+);
220 }
221}
222
223macro_rules! flame_guard {
224 ($name:expr) => {
225 #[cfg(feature = "flame-it")]
226 let _guard = ::flame::start_guard($name);
227 };
228}
229
230#[macro_export]
231macro_rules! class_or_notimplemented {
232 ($t:ty, $obj:expr) => {{
233 let a: &$crate::PyObject = &*$obj;
234 match $crate::PyObject::downcast_ref::<$t>(&a) {
235 Some(pyref) => pyref,
236 None => return Ok($crate::function::PyArithmeticValue::NotImplemented),
237 }
238 }};
239}
240
241#[macro_export]
242macro_rules! named_function {
243 ($ctx:expr, $module:ident, $func:ident) => {{
244 #[allow(unused_variables)] let ctx: &$crate::Context = &$ctx;
246 $crate::__exports::paste::expr! {
247 ctx.new_method_def(
248 stringify!($func),
249 [<$module _ $func>],
250 ::rustpython_vm::function::PyMethodFlags::empty(),
251 ::rustpython_vm::function::ItemDoc::NONE,
252 )
253 .to_function()
254 .with_module(ctx.intern_str(stringify!($module)).into())
255 .into_ref(ctx)
256 }
257 }};
258}
259
260macro_rules! py_dyn_fn {
263 (dyn Fn($($arg:ty),*$(,)*) -> $ret:ty) => {
264 cfg_select! {
265 feature = "threading" => {
266 dyn Fn($($arg),*) -> $ret + Send + Sync + 'static
267 }
268 _ => {
269 dyn Fn($($arg),*) -> $ret + 'static
270 }
271 }
272 };
273}