Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pybind11
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
pybind11
Commits
a86ac538
Commit
a86ac538
authored
Apr 14, 2020
by
Sebastian Koslowski
Committed by
Wenzel Jakob
Apr 26, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rename args_kw_only to kwonly
parent
be0d8045
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
26 additions
and
26 deletions
+26
-26
docs/advanced/functions.rst
+2
-2
include/pybind11/attr.h
+9
-9
include/pybind11/cast.h
+1
-1
include/pybind11/pybind11.h
+3
-3
tests/test_kwargs_and_defaults.cpp
+10
-10
tests/test_kwargs_and_defaults.py
+1
-1
No files found.
docs/advanced/functions.rst
View file @
a86ac538
...
@@ -378,14 +378,14 @@ argument in a function definition:
...
@@ -378,14 +378,14 @@ argument in a function definition:
f(1, b=2) # good
f(1, b=2) # good
f(1, 2) # TypeError: f() takes 1 positional argument but 2 were given
f(1, 2) # TypeError: f() takes 1 positional argument but 2 were given
Pybind11 provides a ``py::
args_kw_
only`` object that allows you to implement
Pybind11 provides a ``py::
kw
only`` object that allows you to implement
the same behaviour by specifying the object between positional and keyword-only
the same behaviour by specifying the object between positional and keyword-only
argument annotations when registering the function:
argument annotations when registering the function:
.. code-block:: cpp
.. code-block:: cpp
m.def("f", [](int a, int b) { /* ... */ },
m.def("f", [](int a, int b) { /* ... */ },
py::arg("a"), py::
args_kw_
only(), py::arg("b"));
py::arg("a"), py::
kw
only(), py::arg("b"));
Note that, as in Python, you cannot combine this with a ``py::args`` argument.
Note that, as in Python, you cannot combine this with a ``py::args`` argument.
This feature does *not* require Python 3 to work.
This feature does *not* require Python 3 to work.
...
...
include/pybind11/attr.h
View file @
a86ac538
...
@@ -138,7 +138,7 @@ struct function_record {
...
@@ -138,7 +138,7 @@ struct function_record {
function_record
()
function_record
()
:
is_constructor
(
false
),
is_new_style_constructor
(
false
),
is_stateless
(
false
),
:
is_constructor
(
false
),
is_new_style_constructor
(
false
),
is_stateless
(
false
),
is_operator
(
false
),
is_method
(
false
),
is_operator
(
false
),
is_method
(
false
),
has_args
(
false
),
has_kwargs
(
false
),
has_kw
_
only_args
(
false
)
{
}
has_args
(
false
),
has_kwargs
(
false
),
has_kwonly_args
(
false
)
{
}
/// Function name
/// Function name
char
*
name
=
nullptr
;
/* why no C++ strings? They generate heavier code.. */
char
*
name
=
nullptr
;
/* why no C++ strings? They generate heavier code.. */
...
@@ -185,8 +185,8 @@ struct function_record {
...
@@ -185,8 +185,8 @@ struct function_record {
/// True if the function has a '**kwargs' argument
/// True if the function has a '**kwargs' argument
bool
has_kwargs
:
1
;
bool
has_kwargs
:
1
;
/// True once a 'py::
args_kw_
only' is encountered (any following args are keyword-only)
/// True once a 'py::
kw
only' is encountered (any following args are keyword-only)
bool
has_kw
_
only_args
:
1
;
bool
has_kwonly_args
:
1
;
/// Number of arguments (including py::args and/or py::kwargs, if present)
/// Number of arguments (including py::args and/or py::kwargs, if present)
std
::
uint16_t
nargs
;
std
::
uint16_t
nargs
;
...
@@ -368,7 +368,7 @@ template <> struct process_attribute<is_new_style_constructor> : process_attribu
...
@@ -368,7 +368,7 @@ template <> struct process_attribute<is_new_style_constructor> : process_attribu
inline
void
process_kwonly_arg
(
const
arg
&
a
,
function_record
*
r
)
{
inline
void
process_kwonly_arg
(
const
arg
&
a
,
function_record
*
r
)
{
if
(
!
a
.
name
||
strlen
(
a
.
name
)
==
0
)
if
(
!
a
.
name
||
strlen
(
a
.
name
)
==
0
)
pybind11_fail
(
"arg(): cannot specify an unnamed argument after an
args_kw_
only() annotation"
);
pybind11_fail
(
"arg(): cannot specify an unnamed argument after an
kw
only() annotation"
);
++
r
->
nargs_kwonly
;
++
r
->
nargs_kwonly
;
}
}
...
@@ -379,7 +379,7 @@ template <> struct process_attribute<arg> : process_attribute_default<arg> {
...
@@ -379,7 +379,7 @@ template <> struct process_attribute<arg> : process_attribute_default<arg> {
r
->
args
.
emplace_back
(
"self"
,
nullptr
,
handle
(),
true
/*convert*/
,
false
/*none not allowed*/
);
r
->
args
.
emplace_back
(
"self"
,
nullptr
,
handle
(),
true
/*convert*/
,
false
/*none not allowed*/
);
r
->
args
.
emplace_back
(
a
.
name
,
nullptr
,
handle
(),
!
a
.
flag_noconvert
,
a
.
flag_none
);
r
->
args
.
emplace_back
(
a
.
name
,
nullptr
,
handle
(),
!
a
.
flag_noconvert
,
a
.
flag_none
);
if
(
r
->
has_kw
_
only_args
)
process_kwonly_arg
(
a
,
r
);
if
(
r
->
has_kwonly_args
)
process_kwonly_arg
(
a
,
r
);
}
}
};
};
...
@@ -412,14 +412,14 @@ template <> struct process_attribute<arg_v> : process_attribute_default<arg_v> {
...
@@ -412,14 +412,14 @@ template <> struct process_attribute<arg_v> : process_attribute_default<arg_v> {
}
}
r
->
args
.
emplace_back
(
a
.
name
,
a
.
descr
,
a
.
value
.
inc_ref
(),
!
a
.
flag_noconvert
,
a
.
flag_none
);
r
->
args
.
emplace_back
(
a
.
name
,
a
.
descr
,
a
.
value
.
inc_ref
(),
!
a
.
flag_noconvert
,
a
.
flag_none
);
if
(
r
->
has_kw
_
only_args
)
process_kwonly_arg
(
a
,
r
);
if
(
r
->
has_kwonly_args
)
process_kwonly_arg
(
a
,
r
);
}
}
};
};
/// Process a keyword-only-arguments-follow pseudo argument
/// Process a keyword-only-arguments-follow pseudo argument
template
<>
struct
process_attribute
<
args_kw_only
>
:
process_attribute_default
<
args_kw_
only
>
{
template
<>
struct
process_attribute
<
kwonly
>
:
process_attribute_default
<
kw
only
>
{
static
void
init
(
const
args_kw_
only
&
,
function_record
*
r
)
{
static
void
init
(
const
kw
only
&
,
function_record
*
r
)
{
r
->
has_kw
_
only_args
=
true
;
r
->
has_kwonly_args
=
true
;
}
}
};
};
...
...
include/pybind11/cast.h
View file @
a86ac538
...
@@ -1890,7 +1890,7 @@ public:
...
@@ -1890,7 +1890,7 @@ public:
/// \ingroup annotations
/// \ingroup annotations
/// Annotation indicating that all following arguments are keyword-only; the is the equivalent of an
/// Annotation indicating that all following arguments are keyword-only; the is the equivalent of an
/// unnamed '*' argument (in Python 3)
/// unnamed '*' argument (in Python 3)
struct
args_kw_
only
{};
struct
kw
only
{};
template
<
typename
T
>
template
<
typename
T
>
arg_v
arg
::
operator
=
(
T
&&
value
)
const
{
return
{
std
::
move
(
*
this
),
std
::
forward
<
T
>
(
value
)};
}
arg_v
arg
::
operator
=
(
T
&&
value
)
const
{
return
{
std
::
move
(
*
this
),
std
::
forward
<
T
>
(
value
)};
}
...
...
include/pybind11/pybind11.h
View file @
a86ac538
...
@@ -169,11 +169,11 @@ protected:
...
@@ -169,11 +169,11 @@ protected:
process_attributes
<
Extra
...
>::
init
(
extra
...,
rec
);
process_attributes
<
Extra
...
>::
init
(
extra
...,
rec
);
{
{
constexpr
bool
has_kw
_only_args
=
any_of
<
std
::
is_same
<
args_kw_
only
,
Extra
>
...
>::
value
,
constexpr
bool
has_kw
only_args
=
any_of
<
std
::
is_same
<
kw
only
,
Extra
>
...
>::
value
,
has_args
=
any_of
<
std
::
is_same
<
args
,
Args
>
...
>::
value
,
has_args
=
any_of
<
std
::
is_same
<
args
,
Args
>
...
>::
value
,
has_arg_annotations
=
any_of
<
is_keyword
<
Extra
>
...
>::
value
;
has_arg_annotations
=
any_of
<
is_keyword
<
Extra
>
...
>::
value
;
static_assert
(
has_arg_annotations
||
!
has_kw
_only_args
,
"py::args_kw_
only requires the use of argument annotations"
);
static_assert
(
has_arg_annotations
||
!
has_kw
only_args
,
"py::kw
only requires the use of argument annotations"
);
static_assert
(
!
(
has_args
&&
has_kw
_only_args
),
"py::args_kw_
only cannot be combined with a py::args argument"
);
static_assert
(
!
(
has_args
&&
has_kw
only_args
),
"py::kw
only cannot be combined with a py::args argument"
);
}
}
/* Generate a readable signature describing the function's arguments and return value types */
/* Generate a readable signature describing the function's arguments and return value types */
...
...
tests/test_kwargs_and_defaults.cpp
View file @
a86ac538
...
@@ -96,27 +96,27 @@ TEST_SUBMODULE(kwargs_and_defaults, m) {
...
@@ -96,27 +96,27 @@ TEST_SUBMODULE(kwargs_and_defaults, m) {
// test_keyword_only_args
// test_keyword_only_args
m
.
def
(
"kwonly_all"
,
[](
int
i
,
int
j
)
{
return
py
::
make_tuple
(
i
,
j
);
},
m
.
def
(
"kwonly_all"
,
[](
int
i
,
int
j
)
{
return
py
::
make_tuple
(
i
,
j
);
},
py
::
args_kw_
only
(),
py
::
arg
(
"i"
),
py
::
arg
(
"j"
));
py
::
kw
only
(),
py
::
arg
(
"i"
),
py
::
arg
(
"j"
));
m
.
def
(
"kwonly_some"
,
[](
int
i
,
int
j
,
int
k
)
{
return
py
::
make_tuple
(
i
,
j
,
k
);
},
m
.
def
(
"kwonly_some"
,
[](
int
i
,
int
j
,
int
k
)
{
return
py
::
make_tuple
(
i
,
j
,
k
);
},
py
::
arg
(),
py
::
args_kw_
only
(),
py
::
arg
(
"j"
),
py
::
arg
(
"k"
));
py
::
arg
(),
py
::
kw
only
(),
py
::
arg
(
"j"
),
py
::
arg
(
"k"
));
m
.
def
(
"kwonly_with_defaults"
,
[](
int
i
,
int
j
,
int
k
,
int
z
)
{
return
py
::
make_tuple
(
i
,
j
,
k
,
z
);
},
m
.
def
(
"kwonly_with_defaults"
,
[](
int
i
,
int
j
,
int
k
,
int
z
)
{
return
py
::
make_tuple
(
i
,
j
,
k
,
z
);
},
py
::
arg
()
=
3
,
"j"
_a
=
4
,
py
::
args_kw_
only
(),
"k"
_a
=
5
,
"z"
_a
);
py
::
arg
()
=
3
,
"j"
_a
=
4
,
py
::
kw
only
(),
"k"
_a
=
5
,
"z"
_a
);
m
.
def
(
"kwonly_mixed"
,
[](
int
i
,
int
j
)
{
return
py
::
make_tuple
(
i
,
j
);
},
m
.
def
(
"kwonly_mixed"
,
[](
int
i
,
int
j
)
{
return
py
::
make_tuple
(
i
,
j
);
},
"i"
_a
,
py
::
args_kw_
only
(),
"j"
_a
);
"i"
_a
,
py
::
kw
only
(),
"j"
_a
);
m
.
def
(
"kwonly_plus_more"
,
[](
int
i
,
int
j
,
int
k
,
py
::
kwargs
kwargs
)
{
m
.
def
(
"kwonly_plus_more"
,
[](
int
i
,
int
j
,
int
k
,
py
::
kwargs
kwargs
)
{
return
py
::
make_tuple
(
i
,
j
,
k
,
kwargs
);
},
return
py
::
make_tuple
(
i
,
j
,
k
,
kwargs
);
},
py
::
arg
()
/* positional */
,
py
::
arg
(
"j"
)
=
-
1
/* both */
,
py
::
args_kw_
only
(),
py
::
arg
(
"k"
)
/* kw-only */
);
py
::
arg
()
/* positional */
,
py
::
arg
(
"j"
)
=
-
1
/* both */
,
py
::
kw
only
(),
py
::
arg
(
"k"
)
/* kw-only */
);
m
.
def
(
"register_invalid_kwonly"
,
[](
py
::
module
m
)
{
m
.
def
(
"register_invalid_kwonly"
,
[](
py
::
module
m
)
{
m
.
def
(
"bad_kwonly"
,
[](
int
i
,
int
j
)
{
return
py
::
make_tuple
(
i
,
j
);
},
m
.
def
(
"bad_kwonly"
,
[](
int
i
,
int
j
)
{
return
py
::
make_tuple
(
i
,
j
);
},
py
::
args_kw_
only
(),
py
::
arg
()
/* invalid unnamed argument */
,
"j"
_a
);
py
::
kw
only
(),
py
::
arg
()
/* invalid unnamed argument */
,
"j"
_a
);
});
});
// These should fail to compile:
// These should fail to compile:
// argument annotations are required when using
args_kw_
only
// argument annotations are required when using
kw
only
// m.def("bad_kwonly1", [](int) {}, py::
args_kw_
only());
// m.def("bad_kwonly1", [](int) {}, py::
kw
only());
// can't specify both `py::
args_kw_
only` and a `py::args` argument
// can't specify both `py::
kw
only` and a `py::args` argument
// m.def("bad_kwonly2", [](int i, py::args) {}, py::
args_kw_
only(), "i"_a);
// m.def("bad_kwonly2", [](int i, py::args) {}, py::
kw
only(), "i"_a);
// test_function_signatures (along with most of the above)
// test_function_signatures (along with most of the above)
struct
KWClass
{
void
foo
(
int
,
float
)
{}
};
struct
KWClass
{
void
foo
(
int
,
float
)
{}
};
...
...
tests/test_kwargs_and_defaults.py
View file @
a86ac538
...
@@ -141,7 +141,7 @@ def test_keyword_only_args(msg):
...
@@ -141,7 +141,7 @@ def test_keyword_only_args(msg):
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
register_invalid_kwonly
(
m
)
m
.
register_invalid_kwonly
(
m
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
msg
(
excinfo
.
value
)
==
"""
arg(): cannot specify an unnamed argument after an
args_kw_
only() annotation
arg(): cannot specify an unnamed argument after an
kw
only() annotation
"""
"""
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment