1212
1313#include " cast.h"
1414
15- NAMESPACE_BEGIN (PYBIND11_NAMESPACE)
15+ PYBIND11_NAMESPACE_BEGIN (PYBIND11_NAMESPACE)
1616
1717// / \addtogroup annotations
1818// / @{
@@ -23,6 +23,9 @@ struct is_method { handle class_; is_method(const handle &c) : class_(c) { } };
2323// / Annotation for operators
2424struct is_operator { };
2525
26+ // / Annotation for classes that cannot be subclassed
27+ struct is_final { };
28+
2629// / Annotation for parent scope
2730struct scope { handle value; scope(const handle &s) : value(s) { } };
2831
@@ -37,8 +40,9 @@ struct sibling { handle value; sibling(const handle &value) : value(value.ptr())
3740
3841// / Annotation indicating that a class derives from another given type
3942template <typename T> struct base {
43+
4044 PYBIND11_DEPRECATED (" base<T>() was deprecated in favor of specifying 'T' as a template argument to class_" )
41- base () { }
45+ base () { } // NOLINT(modernize-use-equals-default): breaks MSVC 2015 when adding an attribute
4246};
4347
4448// / Keep patient alive while nurse lives
@@ -58,7 +62,7 @@ struct metaclass {
5862 handle value;
5963
6064 PYBIND11_DEPRECATED (" py::metaclass() is no longer required. It's turned on by default now." )
61- metaclass () {}
65+ metaclass () { } // NOLINT(modernize-use-equals-default): breaks MSVC 2015 when adding an attribute
6266
6367 // / Override pybind11's default metaclass
6468 explicit metaclass (handle value) : value(value) { }
@@ -70,6 +74,9 @@ struct module_local { const bool value; constexpr module_local(bool v = true) :
7074// / Annotation to mark enums as an arithmetic type
7175struct arithmetic { };
7276
77+ // / Mark a function for addition at the beginning of the existing overload chain instead of the end
78+ struct prepend { };
79+
7380/* * \rst
7481 A call policy which places one or more guard variables (``Ts...``) around the function call.
7582
@@ -110,7 +117,7 @@ struct call_guard<T, Ts...> {
110117
111118// / @} annotations
112119
113- NAMESPACE_BEGIN (detail)
120+ PYBIND11_NAMESPACE_BEGIN (detail)
114121/* Forward declarations */
115122enum op_id : int;
116123enum op_type : int ;
@@ -134,7 +141,8 @@ struct argument_record {
134141struct function_record {
135142 function_record ()
136143 : is_constructor(false ), is_new_style_constructor(false ), is_stateless(false ),
137- is_operator (false ), has_args(false ), has_kwargs(false ), is_method(false ) { }
144+ is_operator (false ), is_method(false ), has_args(false ),
145+ has_kwargs(false ), has_kw_only_args(false ), prepend(false ) { }
138146
139147 // / Function name
140148 char *name = nullptr ; /* why no C++ strings? They generate heavier code.. */
@@ -172,18 +180,30 @@ struct function_record {
172180 // / True if this is an operator (__add__), etc.
173181 bool is_operator : 1 ;
174182
183+ // / True if this is a method
184+ bool is_method : 1 ;
185+
175186 // / True if the function has a '*args' argument
176187 bool has_args : 1 ;
177188
178189 // / True if the function has a '**kwargs' argument
179190 bool has_kwargs : 1 ;
180191
181- // / True if this is a method
182- bool is_method : 1 ;
192+ // / True once a 'py::kw_only' is encountered (any following args are keyword-only)
193+ bool has_kw_only_args : 1 ;
194+
195+ // / True if this function is to be inserted at the beginning of the overload resolution chain
196+ bool prepend : 1 ;
183197
184198 // / Number of arguments (including py::args and/or py::kwargs, if present)
185199 std::uint16_t nargs;
186200
201+ // / Number of trailing arguments (counted in `nargs`) that are keyword-only
202+ std::uint16_t nargs_kw_only = 0 ;
203+
204+ // / Number of leading arguments (counted in `nargs`) that are positional-only
205+ std::uint16_t nargs_pos_only = 0 ;
206+
187207 // / Python method object
188208 PyMethodDef *def = nullptr ;
189209
@@ -201,7 +221,7 @@ struct function_record {
201221struct type_record {
202222 PYBIND11_NOINLINE type_record ()
203223 : multiple_inheritance(false ), dynamic_attr(false ), buffer_protocol(false ),
204- default_holder(true ), module_local(false ) { }
224+ default_holder(true ), module_local(false ), is_final( false ) { }
205225
206226 // / Handle to the parent scope
207227 handle scope;
@@ -254,6 +274,9 @@ struct type_record {
254274 // / Is the class definition local to the module shared object?
255275 bool module_local : 1 ;
256276
277+ // / Is the class inheritable from python classes?
278+ bool is_final : 1 ;
279+
257280 PYBIND11_NOINLINE void add_base (const std::type_info &base, void *(*caster)(void *)) {
258281 auto base_info = detail::get_type_info (base, false );
259282 if (!base_info) {
@@ -353,12 +376,20 @@ template <> struct process_attribute<is_new_style_constructor> : process_attribu
353376 static void init (const is_new_style_constructor &, function_record *r) { r->is_new_style_constructor = true ; }
354377};
355378
379+ inline void process_kw_only_arg (const arg &a, function_record *r) {
380+ if (!a.name || strlen (a.name ) == 0 )
381+ pybind11_fail (" arg(): cannot specify an unnamed argument after an kw_only() annotation" );
382+ ++r->nargs_kw_only ;
383+ }
384+
356385// / Process a keyword argument attribute (*without* a default value)
357386template <> struct process_attribute <arg> : process_attribute_default<arg> {
358387 static void init (const arg &a, function_record *r) {
359388 if (r->is_method && r->args .empty ())
360389 r->args .emplace_back (" self" , nullptr , handle (), true /* convert*/ , false /* none not allowed*/ );
361390 r->args .emplace_back (a.name , nullptr , handle (), !a.flag_noconvert , a.flag_none );
391+
392+ if (r->has_kw_only_args ) process_kw_only_arg (a, r);
362393 }
363394};
364395
@@ -390,6 +421,22 @@ template <> struct process_attribute<arg_v> : process_attribute_default<arg_v> {
390421#endif
391422 }
392423 r->args .emplace_back (a.name , a.descr , a.value .inc_ref (), !a.flag_noconvert , a.flag_none );
424+
425+ if (r->has_kw_only_args ) process_kw_only_arg (a, r);
426+ }
427+ };
428+
429+ // / Process a keyword-only-arguments-follow pseudo argument
430+ template <> struct process_attribute <kw_only> : process_attribute_default<kw_only> {
431+ static void init (const kw_only &, function_record *r) {
432+ r->has_kw_only_args = true ;
433+ }
434+ };
435+
436+ // / Process a positional-only-argument maker
437+ template <> struct process_attribute <pos_only> : process_attribute_default<pos_only> {
438+ static void init (const pos_only &, function_record *r) {
439+ r->nargs_pos_only = static_cast <std::uint16_t >(r->args .size ());
393440 }
394441};
395442
@@ -416,6 +463,11 @@ struct process_attribute<dynamic_attr> : process_attribute_default<dynamic_attr>
416463 static void init (const dynamic_attr &, type_record *r) { r->dynamic_attr = true ; }
417464};
418465
466+ template <>
467+ struct process_attribute <is_final> : process_attribute_default<is_final> {
468+ static void init (const is_final &, type_record *r) { r->is_final = true ; }
469+ };
470+
419471template <>
420472struct process_attribute <buffer_protocol> : process_attribute_default<buffer_protocol> {
421473 static void init (const buffer_protocol &, type_record *r) { r->buffer_protocol = true ; }
@@ -431,6 +483,12 @@ struct process_attribute<module_local> : process_attribute_default<module_local>
431483 static void init (const module_local &l, type_record *r) { r->module_local = l.value ; }
432484};
433485
486+ // / Process a 'prepend' attribute, putting this at the beginning of the overload chain
487+ template <>
488+ struct process_attribute <prepend> : process_attribute_default<prepend> {
489+ static void init (const prepend &, function_record *r) { r->prepend = true ; }
490+ };
491+
434492// / Process an 'arithmetic' attribute for enums (does nothing here)
435493template <>
436494struct process_attribute <arithmetic> : process_attribute_default<arithmetic> {};
@@ -489,5 +547,5 @@ constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) {
489547 return named == 0 || (self + named + has_args + has_kwargs) == nargs;
490548}
491549
492- NAMESPACE_END (detail)
493- NAMESPACE_END (PYBIND11_NAMESPACE)
550+ PYBIND11_NAMESPACE_END (detail)
551+ PYBIND11_NAMESPACE_END (PYBIND11_NAMESPACE)
0 commit comments