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
c50f90ec
Unverified
Commit
c50f90ec
authored
Oct 16, 2020
by
Henry Schreiner
Committed by
GitHub
Oct 16, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
style: use Black everywhere (#2594)
* style: use Black everywhere * style: minor touchup from review
parent
2e31e466
Hide whitespace changes
Inline
Side-by-side
Showing
38 changed files
with
1656 additions
and
944 deletions
+1656
-944
.pre-commit-config.yaml
+1
-2
docs/benchmark.py
+20
-17
docs/conf.py
+94
-94
tests/conftest.py
+17
-9
tests/test_buffers.py
+9
-9
tests/test_builtin_casters.py
+85
-54
tests/test_call_policies.py
+39
-12
tests/test_callbacks.py
+21
-10
tests/test_chrono.py
+23
-17
tests/test_class.py
+82
-35
tests/test_copy_move.py
+16
-4
tests/test_custom_type_casters.py
+36
-10
tests/test_docstring_options.py
+5
-5
tests/test_eigen.py
+182
-109
tests/test_enum.py
+18
-10
tests/test_eval_call.py
+1
-1
tests/test_exceptions.py
+15
-8
tests/test_factory_constructors.py
+75
-35
tests/test_gil_scoped.py
+4
-1
tests/test_iostream.py
+25
-22
tests/test_kwargs_and_defaults.py
+70
-25
tests/test_local_bindings.py
+40
-12
tests/test_methods_and_attributes.py
+49
-30
tests/test_modules.py
+7
-3
tests/test_multiple_inheritance.py
+11
-6
tests/test_numpy_array.py
+140
-94
tests/test_numpy_dtypes.py
+161
-96
tests/test_numpy_vectorize.py
+105
-44
tests/test_opaque_types.py
+4
-1
tests/test_operator_overloading.py
+17
-17
tests/test_pickling.py
+1
-0
tests/test_pytypes.py
+99
-45
tests/test_sequences_and_iterators.py
+19
-15
tests/test_smart_ptr.py
+34
-15
tests/test_stl.py
+36
-22
tests/test_stl_binders.py
+40
-34
tests/test_tagbased_polymorphic.py
+11
-3
tests/test_virtual_functions.py
+44
-18
No files found.
.pre-commit-config.yaml
View file @
c50f90ec
...
@@ -36,8 +36,7 @@ repos:
...
@@ -36,8 +36,7 @@ repos:
-
id
:
black
-
id
:
black
# By default, this ignores pyi files, though black supports them
# By default, this ignores pyi files, though black supports them
types
:
[
text
]
types
:
[
text
]
# Not all Python files are Blacked, yet
files
:
\.pyi?$
files
:
^(setup.py|pybind11|tests/extra|tools).*\.pyi?$
# Changes tabs to spaces
# Changes tabs to spaces
-
repo
:
https://github.com/Lucas-C/pre-commit-hooks
-
repo
:
https://github.com/Lucas-C/pre-commit-hooks
...
...
docs/benchmark.py
View file @
c50f90ec
...
@@ -14,7 +14,7 @@ def generate_dummy_code_pybind11(nclasses=10):
...
@@ -14,7 +14,7 @@ def generate_dummy_code_pybind11(nclasses=10):
for
cl
in
range
(
nclasses
):
for
cl
in
range
(
nclasses
):
decl
+=
"class cl
%03
i;
\n
"
%
cl
decl
+=
"class cl
%03
i;
\n
"
%
cl
decl
+=
'
\n
'
decl
+=
"
\n
"
for
cl
in
range
(
nclasses
):
for
cl
in
range
(
nclasses
):
decl
+=
"class cl
%03
i {
\n
"
%
cl
decl
+=
"class cl
%03
i {
\n
"
%
cl
...
@@ -22,18 +22,17 @@ def generate_dummy_code_pybind11(nclasses=10):
...
@@ -22,18 +22,17 @@ def generate_dummy_code_pybind11(nclasses=10):
bindings
+=
' py::class_<cl
%03
i>(m, "cl
%03
i")
\n
'
%
(
cl
,
cl
)
bindings
+=
' py::class_<cl
%03
i>(m, "cl
%03
i")
\n
'
%
(
cl
,
cl
)
for
fn
in
range
(
nfns
):
for
fn
in
range
(
nfns
):
ret
=
random
.
randint
(
0
,
nclasses
-
1
)
ret
=
random
.
randint
(
0
,
nclasses
-
1
)
params
=
[
random
.
randint
(
0
,
nclasses
-
1
)
for
i
in
range
(
nargs
)]
params
=
[
random
.
randint
(
0
,
nclasses
-
1
)
for
i
in
range
(
nargs
)]
decl
+=
" cl
%03
i *fn_
%03
i("
%
(
ret
,
fn
)
decl
+=
" cl
%03
i *fn_
%03
i("
%
(
ret
,
fn
)
decl
+=
", "
.
join
(
"cl
%03
i *"
%
p
for
p
in
params
)
decl
+=
", "
.
join
(
"cl
%03
i *"
%
p
for
p
in
params
)
decl
+=
");
\n
"
decl
+=
");
\n
"
bindings
+=
' .def("fn_
%03
i", &cl
%03
i::fn_
%03
i)
\n
'
%
\
bindings
+=
' .def("fn_
%03
i", &cl
%03
i::fn_
%03
i)
\n
'
%
(
fn
,
cl
,
fn
)
(
fn
,
cl
,
fn
)
decl
+=
"};
\n\n
"
decl
+=
"};
\n\n
"
bindings
+=
' ;
\n
'
bindings
+=
" ;
\n
"
result
=
"#include <pybind11/pybind11.h>
\n\n
"
result
=
"#include <pybind11/pybind11.h>
\n\n
"
result
+=
"namespace py = pybind11;
\n\n
"
result
+=
"namespace py = pybind11;
\n\n
"
result
+=
decl
+
'
\n
'
result
+=
decl
+
"
\n
"
result
+=
"PYBIND11_MODULE(example, m) {
\n
"
result
+=
"PYBIND11_MODULE(example, m) {
\n
"
result
+=
bindings
result
+=
bindings
result
+=
"}"
result
+=
"}"
...
@@ -46,7 +45,7 @@ def generate_dummy_code_boost(nclasses=10):
...
@@ -46,7 +45,7 @@ def generate_dummy_code_boost(nclasses=10):
for
cl
in
range
(
nclasses
):
for
cl
in
range
(
nclasses
):
decl
+=
"class cl
%03
i;
\n
"
%
cl
decl
+=
"class cl
%03
i;
\n
"
%
cl
decl
+=
'
\n
'
decl
+=
"
\n
"
for
cl
in
range
(
nclasses
):
for
cl
in
range
(
nclasses
):
decl
+=
"class cl
%03
i {
\n
"
%
cl
decl
+=
"class cl
%03
i {
\n
"
%
cl
...
@@ -54,18 +53,20 @@ def generate_dummy_code_boost(nclasses=10):
...
@@ -54,18 +53,20 @@ def generate_dummy_code_boost(nclasses=10):
bindings
+=
' py::class_<cl
%03
i>("cl
%03
i")
\n
'
%
(
cl
,
cl
)
bindings
+=
' py::class_<cl
%03
i>("cl
%03
i")
\n
'
%
(
cl
,
cl
)
for
fn
in
range
(
nfns
):
for
fn
in
range
(
nfns
):
ret
=
random
.
randint
(
0
,
nclasses
-
1
)
ret
=
random
.
randint
(
0
,
nclasses
-
1
)
params
=
[
random
.
randint
(
0
,
nclasses
-
1
)
for
i
in
range
(
nargs
)]
params
=
[
random
.
randint
(
0
,
nclasses
-
1
)
for
i
in
range
(
nargs
)]
decl
+=
" cl
%03
i *fn_
%03
i("
%
(
ret
,
fn
)
decl
+=
" cl
%03
i *fn_
%03
i("
%
(
ret
,
fn
)
decl
+=
", "
.
join
(
"cl
%03
i *"
%
p
for
p
in
params
)
decl
+=
", "
.
join
(
"cl
%03
i *"
%
p
for
p
in
params
)
decl
+=
");
\n
"
decl
+=
");
\n
"
bindings
+=
' .def("fn_
%03
i", &cl
%03
i::fn_
%03
i, py::return_value_policy<py::manage_new_object>())
\n
'
%
\
bindings
+=
(
(
fn
,
cl
,
fn
)
' .def("fn_
%03
i", &cl
%03
i::fn_
%03
i, py::return_value_policy<py::manage_new_object>())
\n
'
%
(
fn
,
cl
,
fn
)
)
decl
+=
"};
\n\n
"
decl
+=
"};
\n\n
"
bindings
+=
' ;
\n
'
bindings
+=
" ;
\n
"
result
=
"#include <boost/python.hpp>
\n\n
"
result
=
"#include <boost/python.hpp>
\n\n
"
result
+=
"namespace py = boost::python;
\n\n
"
result
+=
"namespace py = boost::python;
\n\n
"
result
+=
decl
+
'
\n
'
result
+=
decl
+
"
\n
"
result
+=
"BOOST_PYTHON_MODULE(example) {
\n
"
result
+=
"BOOST_PYTHON_MODULE(example) {
\n
"
result
+=
bindings
result
+=
bindings
result
+=
"}"
result
+=
"}"
...
@@ -73,17 +74,19 @@ def generate_dummy_code_boost(nclasses=10):
...
@@ -73,17 +74,19 @@ def generate_dummy_code_boost(nclasses=10):
for
codegen
in
[
generate_dummy_code_pybind11
,
generate_dummy_code_boost
]:
for
codegen
in
[
generate_dummy_code_pybind11
,
generate_dummy_code_boost
]:
print
(
"{"
)
print
(
"{"
)
for
i
in
range
(
0
,
10
):
for
i
in
range
(
0
,
10
):
nclasses
=
2
**
i
nclasses
=
2
**
i
with
open
(
"test.cpp"
,
"w"
)
as
f
:
with
open
(
"test.cpp"
,
"w"
)
as
f
:
f
.
write
(
codegen
(
nclasses
))
f
.
write
(
codegen
(
nclasses
))
n1
=
dt
.
datetime
.
now
()
n1
=
dt
.
datetime
.
now
()
os
.
system
(
"g++ -Os -shared -rdynamic -undefined dynamic_lookup "
os
.
system
(
"g++ -Os -shared -rdynamic -undefined dynamic_lookup "
"-fvisibility=hidden -std=c++14 test.cpp -I include "
"-fvisibility=hidden -std=c++14 test.cpp -I include "
"-I /System/Library/Frameworks/Python.framework/Headers -o test.so"
)
"-I /System/Library/Frameworks/Python.framework/Headers -o test.so"
)
n2
=
dt
.
datetime
.
now
()
n2
=
dt
.
datetime
.
now
()
elapsed
=
(
n2
-
n1
)
.
total_seconds
()
elapsed
=
(
n2
-
n1
)
.
total_seconds
()
size
=
os
.
stat
(
'test.so'
)
.
st_size
size
=
os
.
stat
(
"test.so"
)
.
st_size
print
(
" {
%
i,
%
f,
%
i},"
%
(
nclasses
*
nfns
,
elapsed
,
size
))
print
(
" {
%
i,
%
f,
%
i},"
%
(
nclasses
*
nfns
,
elapsed
,
size
))
print
(
"}"
)
print
(
"}"
)
docs/conf.py
View file @
c50f90ec
...
@@ -21,40 +21,44 @@ import subprocess
...
@@ -21,40 +21,44 @@ import subprocess
# If extensions (or modules to document with autodoc) are in another directory,
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
#
sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
#
needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
# ones.
extensions
=
[
'breathe'
,
'sphinxcontrib.rsvgconverter'
,
'sphinxcontrib.moderncmakedomain'
]
extensions
=
[
"breathe"
,
"sphinxcontrib.rsvgconverter"
,
"sphinxcontrib.moderncmakedomain"
,
]
breathe_projects
=
{
'pybind11'
:
'.build/doxygenxml/'
}
breathe_projects
=
{
"pybind11"
:
".build/doxygenxml/"
}
breathe_default_project
=
'pybind11'
breathe_default_project
=
"pybind11"
breathe_domain_by_extension
=
{
'h'
:
'cpp'
}
breathe_domain_by_extension
=
{
"h"
:
"cpp"
}
# Add any paths that contain templates here, relative to this directory.
# Add any paths that contain templates here, relative to this directory.
templates_path
=
[
'.templates'
]
templates_path
=
[
".templates"
]
# The suffix(es) of source filenames.
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
# You can specify multiple suffix as a list of string:
# source_suffix = ['.rst', '.md']
# source_suffix = ['.rst', '.md']
source_suffix
=
'.rst'
source_suffix
=
".rst"
# The encoding of source files.
# The encoding of source files.
#source_encoding = 'utf-8-sig'
#
source_encoding = 'utf-8-sig'
# The master toctree document.
# The master toctree document.
master_doc
=
'index'
master_doc
=
"index"
# General information about the project.
# General information about the project.
project
=
'pybind11'
project
=
"pybind11"
copyright
=
'2017, Wenzel Jakob'
copyright
=
"2017, Wenzel Jakob"
author
=
'Wenzel Jakob'
author
=
"Wenzel Jakob"
# The version info for the project you're documenting, acts as replacement for
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# |version| and |release|, also used in various other places throughout the
...
@@ -78,37 +82,37 @@ language = None
...
@@ -78,37 +82,37 @@ language = None
# There are two options for replacing |today|: either, you set today to some
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
# non-false value, then it is used:
#today = ''
#
today = ''
# Else, today_fmt is used as the format for a strftime call.
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
#
today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# directories to ignore when looking for source files.
exclude_patterns
=
[
'.build'
,
'release.rst'
]
exclude_patterns
=
[
".build"
,
"release.rst"
]
# The reST default role (used for this markup: `text`) to use for all
# The reST default role (used for this markup: `text`) to use for all
# documents.
# documents.
default_role
=
'any'
default_role
=
"any"
# If true, '()' will be appended to :func: etc. cross-reference text.
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
#
add_function_parentheses = True
# If true, the current module name will be prepended to all description
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
# unit titles (such as .. function::).
#add_module_names = True
#
add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
# output. They are ignored by default.
#show_authors = False
#
show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
# The name of the Pygments (syntax highlighting) style to use.
#pygments_style = 'monokai'
#
pygments_style = 'monokai'
# A list of ignored prefixes for module index sorting.
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
#
modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
#
keep_warnings = False
# If true, `todo` and `todoList` produce output, else they produce nothing.
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos
=
False
todo_include_todos
=
False
...
@@ -119,144 +123,137 @@ todo_include_todos = False
...
@@ -119,144 +123,137 @@ todo_include_todos = False
# The theme to use for HTML and HTML Help pages. See the documentation for
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
# a list of builtin themes.
on_rtd
=
os
.
environ
.
get
(
'READTHEDOCS'
,
None
)
==
'True'
on_rtd
=
os
.
environ
.
get
(
"READTHEDOCS"
,
None
)
==
"True"
if
not
on_rtd
:
# only import and set the theme if we're building docs locally
if
not
on_rtd
:
# only import and set the theme if we're building docs locally
import
sphinx_rtd_theme
import
sphinx_rtd_theme
html_theme
=
'sphinx_rtd_theme'
html_theme
=
"sphinx_rtd_theme"
html_theme_path
=
[
sphinx_rtd_theme
.
get_html_theme_path
()]
html_theme_path
=
[
sphinx_rtd_theme
.
get_html_theme_path
()]
html_context
=
{
html_context
=
{
"css_files"
:
[
"_static/theme_overrides.css"
]}
'css_files'
:
[
'_static/theme_overrides.css'
]
}
else
:
else
:
html_context
=
{
html_context
=
{
'css_files'
:
[
"css_files"
:
[
'//media.readthedocs.org/css/sphinx_rtd_theme.css'
,
"//media.readthedocs.org/css/sphinx_rtd_theme.css"
,
'//media.readthedocs.org/css/readthedocs-doc-embed.css'
,
"//media.readthedocs.org/css/readthedocs-doc-embed.css"
,
'_static/theme_overrides.css'
"_static/theme_overrides.css"
,
]
]
}
}
# Theme options are theme-specific and customize the look and feel of a theme
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# further. For a list of options available for each theme, see the
# documentation.
# documentation.
#html_theme_options = {}
#
html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
#
html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<version> documentation".
# "<project> v<version> documentation".
#html_title = None
#
html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
#
html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
# of the sidebar.
#html_logo = None
#
html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
# pixels large.
#html_favicon = None
#
html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path
=
[
'_static'
]
html_static_path
=
[
"_static"
]
# Add any extra paths that contain custom files (such as robots.txt or
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
# directly to the root of the documentation.
#html_extra_path = []
#
html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
#
html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
# typographically correct entities.
#html_use_smartypants = True
#
html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
#
html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# Additional templates that should be rendered to pages, maps page names to
# template names.
# template names.
#html_additional_pages = {}
#
html_additional_pages = {}
# If false, no module index is generated.
# If false, no module index is generated.
#html_domain_indices = True
#
html_domain_indices = True
# If false, no index is generated.
# If false, no index is generated.
#html_use_index = True
#
html_use_index = True
# If true, the index is split into individual pages for each letter.
# If true, the index is split into individual pages for each letter.
#html_split_index = False
#
html_split_index = False
# If true, links to the reST sources are added to the pages.
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
#
html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
#
html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
#
html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
#
html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
#
html_file_suffix = None
# Language to be used for generating the HTML full-text search index.
# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
# Sphinx supports the following languages:
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'
# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr'
# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr'
#html_search_language = 'en'
#
html_search_language = 'en'
# A dictionary with options for the search language support, empty by default.
# A dictionary with options for the search language support, empty by default.
# Now only 'ja' uses this config value
# Now only 'ja' uses this config value
#html_search_options = {'type': 'default'}
#
html_search_options = {'type': 'default'}
# The name of a javascript file (relative to the configuration directory) that
# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
# implements a search results scorer. If empty, the default will be used.
#html_search_scorer = 'scorer.js'
#
html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
# Output file base name for HTML help builder.
htmlhelp_basename
=
'pybind11doc'
htmlhelp_basename
=
"pybind11doc"
# -- Options for LaTeX output ---------------------------------------------
# -- Options for LaTeX output ---------------------------------------------
latex_elements
=
{
latex_elements
=
{
# The paper size ('letterpaper' or 'a4paper').
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
# The font size ('10pt', '11pt' or '12pt').
# 'pointsize': '10pt',
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
"preamble"
:
r"""
# Additional stuff for the LaTeX preamble.
'preamble'
:
r'''
\DeclareUnicodeCharacter{00A0}{}
\DeclareUnicodeCharacter{00A0}{}
\DeclareUnicodeCharacter{2194}{<->}
\DeclareUnicodeCharacter{2194}{<->}
'''
,
"""
,
# Latex figure (float) alignment
# Latex figure (float) alignment
# 'figure_align': 'htbp',
#'figure_align': 'htbp',
}
}
# Grouping the document tree into LaTeX files. List of tuples
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
# author, documentclass [howto, manual, or own class]).
latex_documents
=
[
latex_documents
=
[
(
master_doc
,
'pybind11.tex'
,
'pybind11 Documentation'
,
(
master_doc
,
"pybind11.tex"
,
"pybind11 Documentation"
,
"Wenzel Jakob"
,
"manual"
),
'Wenzel Jakob'
,
'manual'
),
]
]
# The name of an image file (relative to this directory) to place at the top of
# The name of an image file (relative to this directory) to place at the top of
...
@@ -265,32 +262,29 @@ latex_documents = [
...
@@ -265,32 +262,29 @@ latex_documents = [
# For "manual" documents, if this is true, then toplevel headings are parts,
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
# not chapters.
#latex_use_parts = False
#
latex_use_parts = False
# If true, show page references after internal links.
# If true, show page references after internal links.
#latex_show_pagerefs = False
#
latex_show_pagerefs = False
# If true, show URL addresses after external links.
# If true, show URL addresses after external links.
#latex_show_urls = False
#
latex_show_urls = False
# Documents to append as an appendix to all manuals.
# Documents to append as an appendix to all manuals.
#latex_appendices = []
#
latex_appendices = []
# If false, no module index is generated.
# If false, no module index is generated.
#latex_domain_indices = True
#
latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
# (source start file, name, description, authors, manual section).
man_pages
=
[
man_pages
=
[(
master_doc
,
"pybind11"
,
"pybind11 Documentation"
,
[
author
],
1
)]
(
master_doc
,
'pybind11'
,
'pybind11 Documentation'
,
[
author
],
1
)
]
# If true, show URL addresses after external links.
# If true, show URL addresses after external links.
#man_show_urls = False
#
man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# -- Options for Texinfo output -------------------------------------------
...
@@ -299,35 +293,41 @@ man_pages = [
...
@@ -299,35 +293,41 @@ man_pages = [
# (source start file, target name, title, author,
# (source start file, target name, title, author,
# dir menu entry, description, category)
# dir menu entry, description, category)
texinfo_documents
=
[
texinfo_documents
=
[
(
master_doc
,
'pybind11'
,
'pybind11 Documentation'
,
(
author
,
'pybind11'
,
'One line description of project.'
,
master_doc
,
'Miscellaneous'
),
"pybind11"
,
"pybind11 Documentation"
,
author
,
"pybind11"
,
"One line description of project."
,
"Miscellaneous"
,
),
]
]
# Documents to append as an appendix to all manuals.
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
#
texinfo_appendices = []
# If false, no module index is generated.
# If false, no module index is generated.
#texinfo_domain_indices = True
#
texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
#
texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
#
texinfo_no_detailmenu = False
primary_domain
=
'cpp'
primary_domain
=
"cpp"
highlight_language
=
'cpp'
highlight_language
=
"cpp"
def
generate_doxygen_xml
(
app
):
def
generate_doxygen_xml
(
app
):
build_dir
=
os
.
path
.
join
(
app
.
confdir
,
'.build'
)
build_dir
=
os
.
path
.
join
(
app
.
confdir
,
".build"
)
if
not
os
.
path
.
exists
(
build_dir
):
if
not
os
.
path
.
exists
(
build_dir
):
os
.
mkdir
(
build_dir
)
os
.
mkdir
(
build_dir
)
try
:
try
:
subprocess
.
call
([
'doxygen'
,
'--version'
])
subprocess
.
call
([
"doxygen"
,
"--version"
])
retcode
=
subprocess
.
call
([
'doxygen'
],
cwd
=
app
.
confdir
)
retcode
=
subprocess
.
call
([
"doxygen"
],
cwd
=
app
.
confdir
)
if
retcode
<
0
:
if
retcode
<
0
:
sys
.
stderr
.
write
(
"doxygen error code: {}
\n
"
.
format
(
-
retcode
))
sys
.
stderr
.
write
(
"doxygen error code: {}
\n
"
.
format
(
-
retcode
))
except
OSError
as
e
:
except
OSError
as
e
:
...
...
tests/conftest.py
View file @
c50f90ec
...
@@ -18,9 +18,9 @@ import env
...
@@ -18,9 +18,9 @@ import env
# Early diagnostic for failed imports
# Early diagnostic for failed imports
import
pybind11_tests
# noqa: F401
import
pybind11_tests
# noqa: F401
_unicode_marker
=
re
.
compile
(
r
'u(\'[^\']*\')'
)
_unicode_marker
=
re
.
compile
(
r
"u(\'[^\']*\')"
)
_long_marker
=
re
.
compile
(
r
'([0-9])L'
)
_long_marker
=
re
.
compile
(
r
"([0-9])L"
)
_hexadecimal
=
re
.
compile
(
r
'0x[0-9a-fA-F]+'
)
_hexadecimal
=
re
.
compile
(
r
"0x[0-9a-fA-F]+"
)
# Avoid collecting Python3 only files
# Avoid collecting Python3 only files
collect_ignore
=
[]
collect_ignore
=
[]
...
@@ -30,7 +30,7 @@ if env.PY2:
...
@@ -30,7 +30,7 @@ if env.PY2:
def
_strip_and_dedent
(
s
):
def
_strip_and_dedent
(
s
):
"""For triple-quote strings"""
"""For triple-quote strings"""
return
textwrap
.
dedent
(
s
.
lstrip
(
'
\n
'
)
.
rstrip
())
return
textwrap
.
dedent
(
s
.
lstrip
(
"
\n
"
)
.
rstrip
())
def
_split_and_sort
(
s
):
def
_split_and_sort
(
s
):
...
@@ -40,11 +40,14 @@ def _split_and_sort(s):
...
@@ -40,11 +40,14 @@ def _split_and_sort(s):
def
_make_explanation
(
a
,
b
):
def
_make_explanation
(
a
,
b
):
"""Explanation for a failed assert -- the a and b arguments are List[str]"""
"""Explanation for a failed assert -- the a and b arguments are List[str]"""
return
[
"--- actual / +++ expected"
]
+
[
line
.
strip
(
'
\n
'
)
for
line
in
difflib
.
ndiff
(
a
,
b
)]
return
[
"--- actual / +++ expected"
]
+
[
line
.
strip
(
"
\n
"
)
for
line
in
difflib
.
ndiff
(
a
,
b
)
]
class
Output
(
object
):
class
Output
(
object
):
"""Basic output post-processing and comparison"""
"""Basic output post-processing and comparison"""
def
__init__
(
self
,
string
):
def
__init__
(
self
,
string
):
self
.
string
=
string
self
.
string
=
string
self
.
explanation
=
[]
self
.
explanation
=
[]
...
@@ -54,7 +57,11 @@ class Output(object):
...
@@ -54,7 +57,11 @@ class Output(object):
def
__eq__
(
self
,
other
):
def
__eq__
(
self
,
other
):
# Ignore constructor/destructor output which is prefixed with "###"
# Ignore constructor/destructor output which is prefixed with "###"
a
=
[
line
for
line
in
self
.
string
.
strip
()
.
splitlines
()
if
not
line
.
startswith
(
"###"
)]
a
=
[
line
for
line
in
self
.
string
.
strip
()
.
splitlines
()
if
not
line
.
startswith
(
"###"
)
]
b
=
_strip_and_dedent
(
other
)
.
splitlines
()
b
=
_strip_and_dedent
(
other
)
.
splitlines
()
if
a
==
b
:
if
a
==
b
:
return
True
return
True
...
@@ -65,6 +72,7 @@ class Output(object):
...
@@ -65,6 +72,7 @@ class Output(object):
class
Unordered
(
Output
):
class
Unordered
(
Output
):
"""Custom comparison for output without strict line ordering"""
"""Custom comparison for output without strict line ordering"""
def
__eq__
(
self
,
other
):
def
__eq__
(
self
,
other
):
a
=
_split_and_sort
(
self
.
string
)
a
=
_split_and_sort
(
self
.
string
)
b
=
_split_and_sort
(
other
)
b
=
_split_and_sort
(
other
)
...
@@ -175,7 +183,7 @@ def msg():
...
@@ -175,7 +183,7 @@ def msg():
# noinspection PyUnusedLocal
# noinspection PyUnusedLocal
def
pytest_assertrepr_compare
(
op
,
left
,
right
):
def
pytest_assertrepr_compare
(
op
,
left
,
right
):
"""Hook to insert custom failure explanation"""
"""Hook to insert custom failure explanation"""
if
hasattr
(
left
,
'explanation'
):
if
hasattr
(
left
,
"explanation"
):
return
left
.
explanation
return
left
.
explanation
...
@@ -189,8 +197,8 @@ def suppress(exception):
...
@@ -189,8 +197,8 @@ def suppress(exception):
def
gc_collect
():
def
gc_collect
():
'''
Run the garbage collector twice (needed when running
"""
Run the garbage collector twice (needed when running
reference counting tests with PyPy)
'''
reference counting tests with PyPy)
"""
gc
.
collect
()
gc
.
collect
()
gc
.
collect
()
gc
.
collect
()
...
...
tests/test_buffers.py
View file @
c50f90ec
...
@@ -46,8 +46,8 @@ def test_to_python():
...
@@ -46,8 +46,8 @@ def test_to_python():
mat
[
3
,
2
]
=
7.0
mat
[
3
,
2
]
=
7.0
assert
mat
[
2
,
3
]
==
4
assert
mat
[
2
,
3
]
==
4
assert
mat
[
3
,
2
]
==
7
assert
mat
[
3
,
2
]
==
7
assert
struct
.
unpack_from
(
'f'
,
mat
,
(
3
*
4
+
2
)
*
4
)
==
(
7
,
)
assert
struct
.
unpack_from
(
"f"
,
mat
,
(
3
*
4
+
2
)
*
4
)
==
(
7
,
)
assert
struct
.
unpack_from
(
'f'
,
mat
,
(
2
*
4
+
3
)
*
4
)
==
(
4
,
)
assert
struct
.
unpack_from
(
"f"
,
mat
,
(
2
*
4
+
3
)
*
4
)
==
(
4
,
)
mat2
=
np
.
array
(
mat
,
copy
=
False
)
mat2
=
np
.
array
(
mat
,
copy
=
False
)
assert
mat2
.
shape
==
(
5
,
4
)
assert
mat2
.
shape
==
(
5
,
4
)
...
@@ -83,31 +83,31 @@ def test_pointer_to_member_fn():
...
@@ -83,31 +83,31 @@ def test_pointer_to_member_fn():
for
cls
in
[
m
.
Buffer
,
m
.
ConstBuffer
,
m
.
DerivedBuffer
]:
for
cls
in
[
m
.
Buffer
,
m
.
ConstBuffer
,
m
.
DerivedBuffer
]:
buf
=
cls
()
buf
=
cls
()
buf
.
value
=
0x12345678
buf
.
value
=
0x12345678
value
=
struct
.
unpack
(
'i'
,
bytearray
(
buf
))[
0
]
value
=
struct
.
unpack
(
"i"
,
bytearray
(
buf
))[
0
]
assert
value
==
0x12345678
assert
value
==
0x12345678
def
test_readonly_buffer
():
def
test_readonly_buffer
():
buf
=
m
.
BufferReadOnly
(
0x64
)
buf
=
m
.
BufferReadOnly
(
0x64
)
view
=
memoryview
(
buf
)
view
=
memoryview
(
buf
)
assert
view
[
0
]
==
b
'd'
if
env
.
PY2
else
0x64
assert
view
[
0
]
==
b
"d"
if
env
.
PY2
else
0x64
assert
view
.
readonly
assert
view
.
readonly
def
test_selective_readonly_buffer
():
def
test_selective_readonly_buffer
():
buf
=
m
.
BufferReadOnlySelect
()
buf
=
m
.
BufferReadOnlySelect
()
memoryview
(
buf
)[
0
]
=
b
'd'
if
env
.
PY2
else
0x64
memoryview
(
buf
)[
0
]
=
b
"d"
if
env
.
PY2
else
0x64
assert
buf
.
value
==
0x64
assert
buf
.
value
==
0x64
io
.
BytesIO
(
b
'A'
)
.
readinto
(
buf
)
io
.
BytesIO
(
b
"A"
)
.
readinto
(
buf
)
assert
buf
.
value
==
ord
(
b
'A'
)
assert
buf
.
value
==
ord
(
b
"A"
)
buf
.
readonly
=
True
buf
.
readonly
=
True
with
pytest
.
raises
(
TypeError
):
with
pytest
.
raises
(
TypeError
):
memoryview
(
buf
)[
0
]
=
b
'
\0
'
if
env
.
PY2
else
0
memoryview
(
buf
)[
0
]
=
b
"
\0
"
if
env
.
PY2
else
0
with
pytest
.
raises
(
TypeError
):
with
pytest
.
raises
(
TypeError
):
io
.
BytesIO
(
b
'1'
)
.
readinto
(
buf
)
io
.
BytesIO
(
b
"1"
)
.
readinto
(
buf
)
def
test_ctypes_array_1d
():
def
test_ctypes_array_1d
():
...
...
tests/test_builtin_casters.py
View file @
c50f90ec
...
@@ -37,79 +37,85 @@ def test_unicode_conversion():
...
@@ -37,79 +37,85 @@ def test_unicode_conversion():
with
pytest
.
raises
(
UnicodeDecodeError
):
with
pytest
.
raises
(
UnicodeDecodeError
):
m
.
bad_utf8_u8string
()
m
.
bad_utf8_u8string
()
assert
m
.
u8_Z
()
==
'Z'
assert
m
.
u8_Z
()
==
"Z"
assert
m
.
u8_eacute
()
==
u
'é'
assert
m
.
u8_eacute
()
==
u
"é"
assert
m
.
u16_ibang
()
==
u
'‽'
assert
m
.
u16_ibang
()
==
u
"‽"
assert
m
.
u32_mathbfA
()
==
u
'𝐀'
assert
m
.
u32_mathbfA
()
==
u
"𝐀"
assert
m
.
wchar_heart
()
==
u
'♥'
assert
m
.
wchar_heart
()
==
u
"♥"
if
hasattr
(
m
,
"has_u8string"
):
if
hasattr
(
m
,
"has_u8string"
):
assert
m
.
u8_char8_Z
()
==
'Z'
assert
m
.
u8_char8_Z
()
==
"Z"
def
test_single_char_arguments
():
def
test_single_char_arguments
():
"""Tests failures for passing invalid inputs to char-accepting functions"""
"""Tests failures for passing invalid inputs to char-accepting functions"""
def
toobig_message
(
r
):
def
toobig_message
(
r
):
return
"Character code point not in range({0:#x})"
.
format
(
r
)
return
"Character code point not in range({0:#x})"
.
format
(
r
)
toolong_message
=
"Expected a character, but multi-character string found"
toolong_message
=
"Expected a character, but multi-character string found"
assert
m
.
ord_char
(
u'a'
)
==
0x61
# simple ASCII
assert
m
.
ord_char
(
u"a"
)
==
0x61
# simple ASCII
assert
m
.
ord_char_lv
(
u'b'
)
==
0x62
assert
m
.
ord_char_lv
(
u"b"
)
==
0x62
assert
m
.
ord_char
(
u'é'
)
==
0xE9
# requires 2 bytes in utf-8, but can be stuffed in a char
assert
(
m
.
ord_char
(
u"é"
)
==
0xE9
)
# requires 2 bytes in utf-8, but can be stuffed in a char
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
assert
m
.
ord_char
(
u
'Ā'
)
==
0x100
# requires 2 bytes, doesn't fit in a char
assert
m
.
ord_char
(
u
"Ā"
)
==
0x100
# requires 2 bytes, doesn't fit in a char
assert
str
(
excinfo
.
value
)
==
toobig_message
(
0x100
)
assert
str
(
excinfo
.
value
)
==
toobig_message
(
0x100
)
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
assert
m
.
ord_char
(
u
'ab'
)
assert
m
.
ord_char
(
u
"ab"
)
assert
str
(
excinfo
.
value
)
==
toolong_message
assert
str
(
excinfo
.
value
)
==
toolong_message
assert
m
.
ord_char16
(
u
'a'
)
==
0x61
assert
m
.
ord_char16
(
u
"a"
)
==
0x61
assert
m
.
ord_char16
(
u
'é'
)
==
0xE9
assert
m
.
ord_char16
(
u
"é"
)
==
0xE9
assert
m
.
ord_char16_lv
(
u
'ê'
)
==
0xEA
assert
m
.
ord_char16_lv
(
u
"ê"
)
==
0xEA
assert
m
.
ord_char16
(
u
'Ā'
)
==
0x100
assert
m
.
ord_char16
(
u
"Ā"
)
==
0x100
assert
m
.
ord_char16
(
u
'‽'
)
==
0x203d
assert
m
.
ord_char16
(
u
"‽"
)
==
0x203D
assert
m
.
ord_char16
(
u
'♥'
)
==
0x2665
assert
m
.
ord_char16
(
u
"♥"
)
==
0x2665
assert
m
.
ord_char16_lv
(
u
'♡'
)
==
0x2661
assert
m
.
ord_char16_lv
(
u
"♡"
)
==
0x2661
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
assert
m
.
ord_char16
(
u
'🎂'
)
==
0x1F382
# requires surrogate pair
assert
m
.
ord_char16
(
u
"🎂"
)
==
0x1F382
# requires surrogate pair
assert
str
(
excinfo
.
value
)
==
toobig_message
(
0x10000
)
assert
str
(
excinfo
.
value
)
==
toobig_message
(
0x10000
)
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
assert
m
.
ord_char16
(
u
'aa'
)
assert
m
.
ord_char16
(
u
"aa"
)
assert
str
(
excinfo
.
value
)
==
toolong_message
assert
str
(
excinfo
.
value
)
==
toolong_message
assert
m
.
ord_char32
(
u
'a'
)
==
0x61
assert
m
.
ord_char32
(
u
"a"
)
==
0x61
assert
m
.
ord_char32
(
u
'é'
)
==
0xE9
assert
m
.
ord_char32
(
u
"é"
)
==
0xE9
assert
m
.
ord_char32
(
u
'Ā'
)
==
0x100
assert
m
.
ord_char32
(
u
"Ā"
)
==
0x100
assert
m
.
ord_char32
(
u
'‽'
)
==
0x203d
assert
m
.
ord_char32
(
u
"‽"
)
==
0x203D
assert
m
.
ord_char32
(
u
'♥'
)
==
0x2665
assert
m
.
ord_char32
(
u
"♥"
)
==
0x2665
assert
m
.
ord_char32
(
u
'🎂'
)
==
0x1F382
assert
m
.
ord_char32
(
u
"🎂"
)
==
0x1F382
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
assert
m
.
ord_char32
(
u
'aa'
)
assert
m
.
ord_char32
(
u
"aa"
)
assert
str
(
excinfo
.
value
)
==
toolong_message
assert
str
(
excinfo
.
value
)
==
toolong_message
assert
m
.
ord_wchar
(
u
'a'
)
==
0x61
assert
m
.
ord_wchar
(
u
"a"
)
==
0x61
assert
m
.
ord_wchar
(
u
'é'
)
==
0xE9
assert
m
.
ord_wchar
(
u
"é"
)
==
0xE9
assert
m
.
ord_wchar
(
u
'Ā'
)
==
0x100
assert
m
.
ord_wchar
(
u
"Ā"
)
==
0x100
assert
m
.
ord_wchar
(
u
'‽'
)
==
0x203d
assert
m
.
ord_wchar
(
u
"‽"
)
==
0x203D
assert
m
.
ord_wchar
(
u
'♥'
)
==
0x2665
assert
m
.
ord_wchar
(
u
"♥"
)
==
0x2665
if
m
.
wchar_size
==
2
:
if
m
.
wchar_size
==
2
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
assert
m
.
ord_wchar
(
u
'🎂'
)
==
0x1F382
# requires surrogate pair
assert
m
.
ord_wchar
(
u
"🎂"
)
==
0x1F382
# requires surrogate pair
assert
str
(
excinfo
.
value
)
==
toobig_message
(
0x10000
)
assert
str
(
excinfo
.
value
)
==
toobig_message
(
0x10000
)
else
:
else
:
assert
m
.
ord_wchar
(
u
'🎂'
)
==
0x1F382
assert
m
.
ord_wchar
(
u
"🎂"
)
==
0x1F382
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
assert
m
.
ord_wchar
(
u
'aa'
)
assert
m
.
ord_wchar
(
u
"aa"
)
assert
str
(
excinfo
.
value
)
==
toolong_message
assert
str
(
excinfo
.
value
)
==
toolong_message
if
hasattr
(
m
,
"has_u8string"
):
if
hasattr
(
m
,
"has_u8string"
):
assert
m
.
ord_char8
(
u'a'
)
==
0x61
# simple ASCII
assert
m
.
ord_char8
(
u"a"
)
==
0x61
# simple ASCII
assert
m
.
ord_char8_lv
(
u'b'
)
==
0x62
assert
m
.
ord_char8_lv
(
u"b"
)
==
0x62
assert
m
.
ord_char8
(
u'é'
)
==
0xE9
# requires 2 bytes in utf-8, but can be stuffed in a char
assert
(
m
.
ord_char8
(
u"é"
)
==
0xE9
)
# requires 2 bytes in utf-8, but can be stuffed in a char
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
assert
m
.
ord_char8
(
u
'Ā'
)
==
0x100
# requires 2 bytes, doesn't fit in a char
assert
m
.
ord_char8
(
u
"Ā"
)
==
0x100
# requires 2 bytes, doesn't fit in a char
assert
str
(
excinfo
.
value
)
==
toobig_message
(
0x100
)
assert
str
(
excinfo
.
value
)
==
toobig_message
(
0x100
)
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
assert
m
.
ord_char8
(
u
'ab'
)
assert
m
.
ord_char8
(
u
"ab"
)
assert
str
(
excinfo
.
value
)
==
toolong_message
assert
str
(
excinfo
.
value
)
==
toolong_message
...
@@ -129,19 +135,19 @@ def test_bytes_to_string():
...
@@ -129,19 +135,19 @@ def test_bytes_to_string():
assert
m
.
strlen
(
to_bytes
(
"a
\x00
b"
))
==
1
# C-string limitation
assert
m
.
strlen
(
to_bytes
(
"a
\x00
b"
))
==
1
# C-string limitation
# passing in a utf8 encoded string should work
# passing in a utf8 encoded string should work
assert
m
.
string_length
(
u
'💩'
.
encode
(
"utf8"
))
==
4
assert
m
.
string_length
(
u
"💩"
.
encode
(
"utf8"
))
==
4
@pytest.mark.skipif
(
not
hasattr
(
m
,
"has_string_view"
),
reason
=
"no <string_view>"
)
@pytest.mark.skipif
(
not
hasattr
(
m
,
"has_string_view"
),
reason
=
"no <string_view>"
)
def
test_string_view
(
capture
):
def
test_string_view
(
capture
):
"""Tests support for C++17 string_view arguments and return values"""
"""Tests support for C++17 string_view arguments and return values"""
assert
m
.
string_view_chars
(
"Hi"
)
==
[
72
,
105
]
assert
m
.
string_view_chars
(
"Hi"
)
==
[
72
,
105
]
assert
m
.
string_view_chars
(
"Hi 🎂"
)
==
[
72
,
105
,
32
,
0x
f0
,
0x9f
,
0x8e
,
0x82
]
assert
m
.
string_view_chars
(
"Hi 🎂"
)
==
[
72
,
105
,
32
,
0x
F0
,
0x9F
,
0x8E
,
0x82
]
assert
m
.
string_view16_chars
(
u"Hi 🎂"
)
==
[
72
,
105
,
32
,
0x
d83c
,
0xdf
82
]
assert
m
.
string_view16_chars
(
u"Hi 🎂"
)
==
[
72
,
105
,
32
,
0x
D83C
,
0xDF
82
]
assert
m
.
string_view32_chars
(
u"Hi 🎂"
)
==
[
72
,
105
,
32
,
127874
]
assert
m
.
string_view32_chars
(
u"Hi 🎂"
)
==
[
72
,
105
,
32
,
127874
]
if
hasattr
(
m
,
"has_u8string"
):
if
hasattr
(
m
,
"has_u8string"
):
assert
m
.
string_view8_chars
(
"Hi"
)
==
[
72
,
105
]
assert
m
.
string_view8_chars
(
"Hi"
)
==
[
72
,
105
]
assert
m
.
string_view8_chars
(
u"Hi 🎂"
)
==
[
72
,
105
,
32
,
0x
f0
,
0x9f
,
0x8e
,
0x82
]
assert
m
.
string_view8_chars
(
u"Hi 🎂"
)
==
[
72
,
105
,
32
,
0x
F0
,
0x9F
,
0x8E
,
0x82
]
assert
m
.
string_view_return
()
==
u"utf8 secret 🎂"
assert
m
.
string_view_return
()
==
u"utf8 secret 🎂"
assert
m
.
string_view16_return
()
==
u"utf16 secret 🎂"
assert
m
.
string_view16_return
()
==
u"utf16 secret 🎂"
...
@@ -154,40 +160,52 @@ def test_string_view(capture):
...
@@ -154,40 +160,52 @@ def test_string_view(capture):
m
.
string_view_print
(
"utf8 🎂"
)
m
.
string_view_print
(
"utf8 🎂"
)
m
.
string_view16_print
(
u"utf16 🎂"
)
m
.
string_view16_print
(
u"utf16 🎂"
)
m
.
string_view32_print
(
u"utf32 🎂"
)
m
.
string_view32_print
(
u"utf32 🎂"
)
assert
capture
==
u"""
assert
(
capture
==
u"""
Hi 2
Hi 2
utf8 🎂 9
utf8 🎂 9
utf16 🎂 8
utf16 🎂 8
utf32 🎂 7
utf32 🎂 7
"""
"""
)
if
hasattr
(
m
,
"has_u8string"
):
if
hasattr
(
m
,
"has_u8string"
):
with
capture
:
with
capture
:
m
.
string_view8_print
(
"Hi"
)
m
.
string_view8_print
(
"Hi"
)
m
.
string_view8_print
(
u"utf8 🎂"
)
m
.
string_view8_print
(
u"utf8 🎂"
)
assert
capture
==
u"""
assert
(
capture
==
u"""
Hi 2
Hi 2
utf8 🎂 9
utf8 🎂 9
"""
"""
)
with
capture
:
with
capture
:
m
.
string_view_print
(
"Hi, ascii"
)
m
.
string_view_print
(
"Hi, ascii"
)
m
.
string_view_print
(
"Hi, utf8 🎂"
)
m
.
string_view_print
(
"Hi, utf8 🎂"
)
m
.
string_view16_print
(
u"Hi, utf16 🎂"
)
m
.
string_view16_print
(
u"Hi, utf16 🎂"
)
m
.
string_view32_print
(
u"Hi, utf32 🎂"
)
m
.
string_view32_print
(
u"Hi, utf32 🎂"
)
assert
capture
==
u"""
assert
(
capture
==
u"""
Hi, ascii 9
Hi, ascii 9
Hi, utf8 🎂 13
Hi, utf8 🎂 13
Hi, utf16 🎂 12
Hi, utf16 🎂 12
Hi, utf32 🎂 11
Hi, utf32 🎂 11
"""
"""
)
if
hasattr
(
m
,
"has_u8string"
):
if
hasattr
(
m
,
"has_u8string"
):
with
capture
:
with
capture
:
m
.
string_view8_print
(
"Hi, ascii"
)
m
.
string_view8_print
(
"Hi, ascii"
)
m
.
string_view8_print
(
u"Hi, utf8 🎂"
)
m
.
string_view8_print
(
u"Hi, utf8 🎂"
)
assert
capture
==
u"""
assert
(
capture
==
u"""
Hi, ascii 9
Hi, ascii 9
Hi, utf8 🎂 13
Hi, utf8 🎂 13
"""
"""
)
def
test_integer_casting
():
def
test_integer_casting
():
...
@@ -199,8 +217,14 @@ def test_integer_casting():
...
@@ -199,8 +217,14 @@ def test_integer_casting():
if
env
.
PY2
:
if
env
.
PY2
:
assert
m
.
i32_str
(
long
(
-
1
))
==
"-1"
# noqa: F821 undefined name 'long'
assert
m
.
i32_str
(
long
(
-
1
))
==
"-1"
# noqa: F821 undefined name 'long'
assert
m
.
i64_str
(
long
(
-
1
))
==
"-1"
# noqa: F821 undefined name 'long'
assert
m
.
i64_str
(
long
(
-
1
))
==
"-1"
# noqa: F821 undefined name 'long'
assert
m
.
i64_str
(
long
(
-
999999999999
))
==
"-999999999999"
# noqa: F821 undefined name
assert
(
assert
m
.
u64_str
(
long
(
999999999999
))
==
"999999999999"
# noqa: F821 undefined name 'long'
m
.
i64_str
(
long
(
-
999999999999
))
# noqa: F821 undefined name 'long'
==
"-999999999999"
)
assert
(
m
.
u64_str
(
long
(
999999999999
))
# noqa: F821 undefined name 'long'
==
"999999999999"
)
else
:
else
:
assert
m
.
i64_str
(
-
999999999999
)
==
"-999999999999"
assert
m
.
i64_str
(
-
999999999999
)
==
"-999999999999"
assert
m
.
u64_str
(
999999999999
)
==
"999999999999"
assert
m
.
u64_str
(
999999999999
)
==
"999999999999"
...
@@ -236,16 +260,22 @@ def test_tuple(doc):
...
@@ -236,16 +260,22 @@ def test_tuple(doc):
assert
m
.
tuple_passthrough
([
True
,
"test"
,
5
])
==
(
5
,
"test"
,
True
)
assert
m
.
tuple_passthrough
([
True
,
"test"
,
5
])
==
(
5
,
"test"
,
True
)
assert
m
.
empty_tuple
()
==
()
assert
m
.
empty_tuple
()
==
()
assert
doc
(
m
.
pair_passthrough
)
==
"""
assert
(
doc
(
m
.
pair_passthrough
)
==
"""
pair_passthrough(arg0: Tuple[bool, str]) -> Tuple[str, bool]
pair_passthrough(arg0: Tuple[bool, str]) -> Tuple[str, bool]
Return a pair in reversed order
Return a pair in reversed order
"""
"""
assert
doc
(
m
.
tuple_passthrough
)
==
"""
)
assert
(
doc
(
m
.
tuple_passthrough
)
==
"""
tuple_passthrough(arg0: Tuple[bool, str, int]) -> Tuple[int, str, bool]
tuple_passthrough(arg0: Tuple[bool, str, int]) -> Tuple[int, str, bool]
Return a triple in reversed order
Return a triple in reversed order
"""
"""
)
assert
m
.
rvalue_pair
()
==
(
"rvalue"
,
"rvalue"
)
assert
m
.
rvalue_pair
()
==
(
"rvalue"
,
"rvalue"
)
assert
m
.
lvalue_pair
()
==
(
"lvalue"
,
"lvalue"
)
assert
m
.
lvalue_pair
()
==
(
"lvalue"
,
"lvalue"
)
...
@@ -372,7 +402,7 @@ def test_numpy_bool():
...
@@ -372,7 +402,7 @@ def test_numpy_bool():
assert
convert
(
np
.
bool_
(
False
))
is
False
assert
convert
(
np
.
bool_
(
False
))
is
False
assert
noconvert
(
np
.
bool_
(
True
))
is
True
assert
noconvert
(
np
.
bool_
(
True
))
is
True
assert
noconvert
(
np
.
bool_
(
False
))
is
False
assert
noconvert
(
np
.
bool_
(
False
))
is
False
cant_convert
(
np
.
zeros
(
2
,
dtype
=
'int'
))
cant_convert
(
np
.
zeros
(
2
,
dtype
=
"int"
))
def
test_int_long
():
def
test_int_long
():
...
@@ -382,7 +412,8 @@ def test_int_long():
...
@@ -382,7 +412,8 @@ def test_int_long():
long."""
long."""
import
sys
import
sys
must_be_long
=
type
(
getattr
(
sys
,
'maxint'
,
1
)
+
1
)
must_be_long
=
type
(
getattr
(
sys
,
"maxint"
,
1
)
+
1
)
assert
isinstance
(
m
.
int_cast
(),
int
)
assert
isinstance
(
m
.
int_cast
(),
int
)
assert
isinstance
(
m
.
long_cast
(),
int
)
assert
isinstance
(
m
.
long_cast
(),
int
)
assert
isinstance
(
m
.
longlong_cast
(),
must_be_long
)
assert
isinstance
(
m
.
longlong_cast
(),
must_be_long
)
...
...
tests/test_call_policies.py
View file @
c50f90ec
...
@@ -16,10 +16,13 @@ def test_keep_alive_argument(capture):
...
@@ -16,10 +16,13 @@ def test_keep_alive_argument(capture):
with
capture
:
with
capture
:
p
.
addChild
(
m
.
Child
())
p
.
addChild
(
m
.
Child
())
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
+
1
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
+
1
assert
capture
==
"""
assert
(
capture
==
"""
Allocating child.
Allocating child.
Releasing child.
Releasing child.
"""
"""
)
with
capture
:
with
capture
:
del
p
del
p
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
...
@@ -35,10 +38,13 @@ def test_keep_alive_argument(capture):
...
@@ -35,10 +38,13 @@ def test_keep_alive_argument(capture):
with
capture
:
with
capture
:
del
p
del
p
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
assert
capture
==
"""
assert
(
capture
==
"""
Releasing parent.
Releasing parent.
Releasing child.
Releasing child.
"""
"""
)
def
test_keep_alive_return_value
(
capture
):
def
test_keep_alive_return_value
(
capture
):
...
@@ -49,10 +55,13 @@ def test_keep_alive_return_value(capture):
...
@@ -49,10 +55,13 @@ def test_keep_alive_return_value(capture):
with
capture
:
with
capture
:
p
.
returnChild
()
p
.
returnChild
()
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
+
1
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
+
1
assert
capture
==
"""
assert
(
capture
==
"""
Allocating child.
Allocating child.
Releasing child.
Releasing child.
"""
"""
)
with
capture
:
with
capture
:
del
p
del
p
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
...
@@ -68,10 +77,13 @@ def test_keep_alive_return_value(capture):
...
@@ -68,10 +77,13 @@ def test_keep_alive_return_value(capture):
with
capture
:
with
capture
:
del
p
del
p
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
assert
capture
==
"""
assert
(
capture
==
"""
Releasing parent.
Releasing parent.
Releasing child.
Releasing child.
"""
"""
)
# https://foss.heptapod.net/pypy/pypy/-/issues/2447
# https://foss.heptapod.net/pypy/pypy/-/issues/2447
...
@@ -82,14 +94,17 @@ def test_alive_gc(capture):
...
@@ -82,14 +94,17 @@ def test_alive_gc(capture):
p
.
addChildKeepAlive
(
m
.
Child
())
p
.
addChildKeepAlive
(
m
.
Child
())
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
+
2
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
+
2
lst
=
[
p
]
lst
=
[
p
]
lst
.
append
(
lst
)
# creates a circular reference
lst
.
append
(
lst
)
# creates a circular reference
with
capture
:
with
capture
:
del
p
,
lst
del
p
,
lst
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
assert
capture
==
"""
assert
(
capture
==
"""
Releasing parent.
Releasing parent.
Releasing child.
Releasing child.
"""
"""
)
def
test_alive_gc_derived
(
capture
):
def
test_alive_gc_derived
(
capture
):
...
@@ -101,14 +116,17 @@ def test_alive_gc_derived(capture):
...
@@ -101,14 +116,17 @@ def test_alive_gc_derived(capture):
p
.
addChildKeepAlive
(
m
.
Child
())
p
.
addChildKeepAlive
(
m
.
Child
())
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
+
2
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
+
2
lst
=
[
p
]
lst
=
[
p
]
lst
.
append
(
lst
)
# creates a circular reference
lst
.
append
(
lst
)
# creates a circular reference
with
capture
:
with
capture
:
del
p
,
lst
del
p
,
lst
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
assert
capture
==
"""
assert
(
capture
==
"""
Releasing parent.
Releasing parent.
Releasing child.
Releasing child.
"""
"""
)
def
test_alive_gc_multi_derived
(
capture
):
def
test_alive_gc_multi_derived
(
capture
):
...
@@ -123,15 +141,18 @@ def test_alive_gc_multi_derived(capture):
...
@@ -123,15 +141,18 @@ def test_alive_gc_multi_derived(capture):
# +3 rather than +2 because Derived corresponds to two registered instances
# +3 rather than +2 because Derived corresponds to two registered instances
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
+
3
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
+
3
lst
=
[
p
]
lst
=
[
p
]
lst
.
append
(
lst
)
# creates a circular reference
lst
.
append
(
lst
)
# creates a circular reference
with
capture
:
with
capture
:
del
p
,
lst
del
p
,
lst
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
assert
capture
==
"""
assert
(
capture
==
"""
Releasing parent.
Releasing parent.
Releasing child.
Releasing child.
Releasing child.
Releasing child.
"""
"""
)
def
test_return_none
(
capture
):
def
test_return_none
(
capture
):
...
@@ -167,17 +188,23 @@ def test_keep_alive_constructor(capture):
...
@@ -167,17 +188,23 @@ def test_keep_alive_constructor(capture):
with
capture
:
with
capture
:
p
=
m
.
Parent
(
m
.
Child
())
p
=
m
.
Parent
(
m
.
Child
())
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
+
2
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
+
2
assert
capture
==
"""
assert
(
capture
==
"""
Allocating child.
Allocating child.
Allocating parent.
Allocating parent.
"""
"""
)
with
capture
:
with
capture
:
del
p
del
p
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
assert
capture
==
"""
assert
(
capture
==
"""
Releasing parent.
Releasing parent.
Releasing child.
Releasing child.
"""
"""
)
def
test_call_guard
():
def
test_call_guard
():
...
...
tests/test_callbacks.py
View file @
c50f90ec
...
@@ -42,17 +42,19 @@ def test_bound_method_callback():
...
@@ -42,17 +42,19 @@ def test_bound_method_callback():
def
test_keyword_args_and_generalized_unpacking
():
def
test_keyword_args_and_generalized_unpacking
():
def
f
(
*
args
,
**
kwargs
):
def
f
(
*
args
,
**
kwargs
):
return
args
,
kwargs
return
args
,
kwargs
assert
m
.
test_tuple_unpacking
(
f
)
==
((
"positional"
,
1
,
2
,
3
,
4
,
5
,
6
),
{})
assert
m
.
test_tuple_unpacking
(
f
)
==
((
"positional"
,
1
,
2
,
3
,
4
,
5
,
6
),
{})
assert
m
.
test_dict_unpacking
(
f
)
==
((
"positional"
,
1
),
{
"key"
:
"value"
,
"a"
:
1
,
"b"
:
2
})
assert
m
.
test_dict_unpacking
(
f
)
==
(
(
"positional"
,
1
),
{
"key"
:
"value"
,
"a"
:
1
,
"b"
:
2
},
)
assert
m
.
test_keyword_args
(
f
)
==
((),
{
"x"
:
10
,
"y"
:
20
})
assert
m
.
test_keyword_args
(
f
)
==
((),
{
"x"
:
10
,
"y"
:
20
})
assert
m
.
test_unpacking_and_keywords1
(
f
)
==
((
1
,
2
),
{
"c"
:
3
,
"d"
:
4
})
assert
m
.
test_unpacking_and_keywords1
(
f
)
==
((
1
,
2
),
{
"c"
:
3
,
"d"
:
4
})
assert
m
.
test_unpacking_and_keywords2
(
f
)
==
(
assert
m
.
test_unpacking_and_keywords2
(
f
)
==
(
(
"positional"
,
1
,
2
,
3
,
4
,
5
),
(
"positional"
,
1
,
2
,
3
,
4
,
5
),
{
"key"
:
"value"
,
"a"
:
1
,
"b"
:
2
,
"c"
:
3
,
"d"
:
4
,
"e"
:
5
}
{
"key"
:
"value"
,
"a"
:
1
,
"b"
:
2
,
"c"
:
3
,
"d"
:
4
,
"e"
:
5
}
,
)
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
...
@@ -83,12 +85,18 @@ def test_lambda_closure_cleanup():
...
@@ -83,12 +85,18 @@ def test_lambda_closure_cleanup():
def
test_cpp_function_roundtrip
():
def
test_cpp_function_roundtrip
():
"""Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer"""
"""Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer"""
assert
m
.
test_dummy_function
(
m
.
dummy_function
)
==
"matches dummy_function: eval(1) = 2"
assert
(
assert
(
m
.
test_dummy_function
(
m
.
roundtrip
(
m
.
dummy_function
))
==
m
.
test_dummy_function
(
m
.
dummy_function
)
==
"matches dummy_function: eval(1) = 2"
"matches dummy_function: eval(1) = 2"
)
)
assert
(
m
.
test_dummy_function
(
m
.
roundtrip
(
m
.
dummy_function
))
==
"matches dummy_function: eval(1) = 2"
)
assert
m
.
roundtrip
(
None
,
expect_none
=
True
)
is
None
assert
m
.
roundtrip
(
None
,
expect_none
=
True
)
is
None
assert
(
m
.
test_dummy_function
(
lambda
x
:
x
+
2
)
==
assert
(
"can't convert to function pointer: eval(1) = 3"
)
m
.
test_dummy_function
(
lambda
x
:
x
+
2
)
==
"can't convert to function pointer: eval(1) = 3"
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
test_dummy_function
(
m
.
dummy_function2
)
m
.
test_dummy_function
(
m
.
dummy_function2
)
...
@@ -96,8 +104,10 @@ def test_cpp_function_roundtrip():
...
@@ -96,8 +104,10 @@ def test_cpp_function_roundtrip():
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
test_dummy_function
(
lambda
x
,
y
:
x
+
y
)
m
.
test_dummy_function
(
lambda
x
,
y
:
x
+
y
)
assert
any
(
s
in
str
(
excinfo
.
value
)
for
s
in
(
"missing 1 required positional argument"
,
assert
any
(
"takes exactly 2 arguments"
))
s
in
str
(
excinfo
.
value
)
for
s
in
(
"missing 1 required positional argument"
,
"takes exactly 2 arguments"
)
)
def
test_function_signatures
(
doc
):
def
test_function_signatures
(
doc
):
...
@@ -127,6 +137,7 @@ def test_async_callbacks():
...
@@ -127,6 +137,7 @@ def test_async_callbacks():
m
.
test_async_callback
(
gen_f
(),
work
)
m
.
test_async_callback
(
gen_f
(),
work
)
# wait until work is done
# wait until work is done
from
time
import
sleep
from
time
import
sleep
sleep
(
0.5
)
sleep
(
0.5
)
assert
sum
(
res
)
==
sum
([
x
+
3
for
x
in
work
])
assert
sum
(
res
)
==
sum
([
x
+
3
for
x
in
work
])
...
...
tests/test_chrono.py
View file @
c50f90ec
...
@@ -80,22 +80,28 @@ SKIP_TZ_ENV_ON_WIN = pytest.mark.skipif(
...
@@ -80,22 +80,28 @@ SKIP_TZ_ENV_ON_WIN = pytest.mark.skipif(
)
)
@pytest.mark.parametrize
(
"time1"
,
[
@pytest.mark.parametrize
(
datetime
.
datetime
.
today
()
.
time
(),
"time1"
,
datetime
.
time
(
0
,
0
,
0
),
[
datetime
.
time
(
0
,
0
,
0
,
1
),
datetime
.
datetime
.
today
()
.
time
(),
datetime
.
time
(
0
,
28
,
45
,
109827
),
datetime
.
time
(
0
,
0
,
0
),
datetime
.
time
(
0
,
59
,
59
,
999999
),
datetime
.
time
(
0
,
0
,
0
,
1
),
datetime
.
time
(
1
,
0
,
0
),
datetime
.
time
(
0
,
28
,
45
,
109827
),
datetime
.
time
(
5
,
59
,
59
,
0
),
datetime
.
time
(
0
,
59
,
59
,
999999
),
datetime
.
time
(
5
,
59
,
59
,
1
),
datetime
.
time
(
1
,
0
,
0
),
])
datetime
.
time
(
5
,
59
,
59
,
0
),
@pytest.mark.parametrize
(
"tz"
,
[
datetime
.
time
(
5
,
59
,
59
,
1
),
None
,
],
pytest
.
param
(
"Europe/Brussels"
,
marks
=
SKIP_TZ_ENV_ON_WIN
),
)
pytest
.
param
(
"Asia/Pyongyang"
,
marks
=
SKIP_TZ_ENV_ON_WIN
),
@pytest.mark.parametrize
(
pytest
.
param
(
"America/New_York"
,
marks
=
SKIP_TZ_ENV_ON_WIN
),
"tz"
,
])
[
None
,
pytest
.
param
(
"Europe/Brussels"
,
marks
=
SKIP_TZ_ENV_ON_WIN
),
pytest
.
param
(
"Asia/Pyongyang"
,
marks
=
SKIP_TZ_ENV_ON_WIN
),
pytest
.
param
(
"America/New_York"
,
marks
=
SKIP_TZ_ENV_ON_WIN
),
],
)
def
test_chrono_system_clock_roundtrip_time
(
time1
,
tz
,
monkeypatch
):
def
test_chrono_system_clock_roundtrip_time
(
time1
,
tz
,
monkeypatch
):
if
tz
is
not
None
:
if
tz
is
not
None
:
monkeypatch
.
setenv
(
"TZ"
,
"/usr/share/zoneinfo/{}"
.
format
(
tz
))
monkeypatch
.
setenv
(
"TZ"
,
"/usr/share/zoneinfo/{}"
.
format
(
tz
))
...
@@ -199,7 +205,7 @@ def test_floating_point_duration():
...
@@ -199,7 +205,7 @@ def test_floating_point_duration():
def
test_nano_timepoint
():
def
test_nano_timepoint
():
time
=
datetime
.
datetime
.
now
()
time
=
datetime
.
datetime
.
now
()
time1
=
m
.
test_nano_timepoint
(
time
,
datetime
.
timedelta
(
seconds
=
60
))
time1
=
m
.
test_nano_timepoint
(
time
,
datetime
.
timedelta
(
seconds
=
60
))
assert
(
time1
==
time
+
datetime
.
timedelta
(
seconds
=
60
)
)
assert
time1
==
time
+
datetime
.
timedelta
(
seconds
=
60
)
def
test_chrono_different_resolutions
():
def
test_chrono_different_resolutions
():
...
...
tests/test_class.py
View file @
c50f90ec
...
@@ -31,8 +31,10 @@ def test_type():
...
@@ -31,8 +31,10 @@ def test_type():
with
pytest
.
raises
(
RuntimeError
)
as
execinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
execinfo
:
m
.
check_type
(
0
)
m
.
check_type
(
0
)
assert
'pybind11::detail::get_type_info: unable to find type info'
in
str
(
execinfo
.
value
)
assert
"pybind11::detail::get_type_info: unable to find type info"
in
str
(
assert
'Invalid'
in
str
(
execinfo
.
value
)
execinfo
.
value
)
assert
"Invalid"
in
str
(
execinfo
.
value
)
# Currently not supported
# Currently not supported
# See https://github.com/pybind/pybind11/issues/2486
# See https://github.com/pybind/pybind11/issues/2486
...
@@ -73,18 +75,24 @@ def test_docstrings(doc):
...
@@ -73,18 +75,24 @@ def test_docstrings(doc):
assert
UserType
.
get_value
.
__name__
==
"get_value"
assert
UserType
.
get_value
.
__name__
==
"get_value"
assert
UserType
.
get_value
.
__module__
==
"pybind11_tests"
assert
UserType
.
get_value
.
__module__
==
"pybind11_tests"
assert
doc
(
UserType
.
get_value
)
==
"""
assert
(
doc
(
UserType
.
get_value
)
==
"""
get_value(self: m.UserType) -> int
get_value(self: m.UserType) -> int
Get value using a method
Get value using a method
"""
"""
)
assert
doc
(
UserType
.
value
)
==
"Get/set value using a property"
assert
doc
(
UserType
.
value
)
==
"Get/set value using a property"
assert
doc
(
m
.
NoConstructor
.
new_instance
)
==
"""
assert
(
doc
(
m
.
NoConstructor
.
new_instance
)
==
"""
new_instance() -> m.class_.NoConstructor
new_instance() -> m.class_.NoConstructor
Return an instance
Return an instance
"""
"""
)
def
test_qualname
(
doc
):
def
test_qualname
(
doc
):
...
@@ -93,51 +101,69 @@ def test_qualname(doc):
...
@@ -93,51 +101,69 @@ def test_qualname(doc):
assert
m
.
NestBase
.
__qualname__
==
"NestBase"
assert
m
.
NestBase
.
__qualname__
==
"NestBase"
assert
m
.
NestBase
.
Nested
.
__qualname__
==
"NestBase.Nested"
assert
m
.
NestBase
.
Nested
.
__qualname__
==
"NestBase.Nested"
assert
doc
(
m
.
NestBase
.
__init__
)
==
"""
assert
(
doc
(
m
.
NestBase
.
__init__
)
==
"""
__init__(self: m.class_.NestBase) -> None
__init__(self: m.class_.NestBase) -> None
"""
"""
assert
doc
(
m
.
NestBase
.
g
)
==
"""
)
assert
(
doc
(
m
.
NestBase
.
g
)
==
"""
g(self: m.class_.NestBase, arg0: m.class_.NestBase.Nested) -> None
g(self: m.class_.NestBase, arg0: m.class_.NestBase.Nested) -> None
"""
"""
assert
doc
(
m
.
NestBase
.
Nested
.
__init__
)
==
"""
)
assert
(
doc
(
m
.
NestBase
.
Nested
.
__init__
)
==
"""
__init__(self: m.class_.NestBase.Nested) -> None
__init__(self: m.class_.NestBase.Nested) -> None
"""
"""
assert
doc
(
m
.
NestBase
.
Nested
.
fn
)
==
"""
)
assert
(
doc
(
m
.
NestBase
.
Nested
.
fn
)
==
"""
fn(self: m.class_.NestBase.Nested, arg0: int, arg1: m.class_.NestBase, arg2: m.class_.NestBase.Nested) -> None
fn(self: m.class_.NestBase.Nested, arg0: int, arg1: m.class_.NestBase, arg2: m.class_.NestBase.Nested) -> None
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
assert
doc
(
m
.
NestBase
.
Nested
.
fa
)
==
"""
)
assert
(
doc
(
m
.
NestBase
.
Nested
.
fa
)
==
"""
fa(self: m.class_.NestBase.Nested, a: int, b: m.class_.NestBase, c: m.class_.NestBase.Nested) -> None
fa(self: m.class_.NestBase.Nested, a: int, b: m.class_.NestBase, c: m.class_.NestBase.Nested) -> None
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
assert
m
.
NestBase
.
__module__
==
"pybind11_tests.class_"
assert
m
.
NestBase
.
__module__
==
"pybind11_tests.class_"
assert
m
.
NestBase
.
Nested
.
__module__
==
"pybind11_tests.class_"
assert
m
.
NestBase
.
Nested
.
__module__
==
"pybind11_tests.class_"
def
test_inheritance
(
msg
):
def
test_inheritance
(
msg
):
roger
=
m
.
Rabbit
(
'Rabbit'
)
roger
=
m
.
Rabbit
(
"Rabbit"
)
assert
roger
.
name
()
+
" is a "
+
roger
.
species
()
==
"Rabbit is a parrot"
assert
roger
.
name
()
+
" is a "
+
roger
.
species
()
==
"Rabbit is a parrot"
assert
m
.
pet_name_species
(
roger
)
==
"Rabbit is a parrot"
assert
m
.
pet_name_species
(
roger
)
==
"Rabbit is a parrot"
polly
=
m
.
Pet
(
'Polly'
,
'parrot'
)
polly
=
m
.
Pet
(
"Polly"
,
"parrot"
)
assert
polly
.
name
()
+
" is a "
+
polly
.
species
()
==
"Polly is a parrot"
assert
polly
.
name
()
+
" is a "
+
polly
.
species
()
==
"Polly is a parrot"
assert
m
.
pet_name_species
(
polly
)
==
"Polly is a parrot"
assert
m
.
pet_name_species
(
polly
)
==
"Polly is a parrot"
molly
=
m
.
Dog
(
'Molly'
)
molly
=
m
.
Dog
(
"Molly"
)
assert
molly
.
name
()
+
" is a "
+
molly
.
species
()
==
"Molly is a dog"
assert
molly
.
name
()
+
" is a "
+
molly
.
species
()
==
"Molly is a dog"
assert
m
.
pet_name_species
(
molly
)
==
"Molly is a dog"
assert
m
.
pet_name_species
(
molly
)
==
"Molly is a dog"
fred
=
m
.
Hamster
(
'Fred'
)
fred
=
m
.
Hamster
(
"Fred"
)
assert
fred
.
name
()
+
" is a "
+
fred
.
species
()
==
"Fred is a rodent"
assert
fred
.
name
()
+
" is a "
+
fred
.
species
()
==
"Fred is a rodent"
assert
m
.
dog_bark
(
molly
)
==
"Woof!"
assert
m
.
dog_bark
(
molly
)
==
"Woof!"
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
dog_bark
(
polly
)
m
.
dog_bark
(
polly
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
dog_bark(): incompatible function arguments. The following argument types are supported:
dog_bark(): incompatible function arguments. The following argument types are supported:
1. (arg0: m.class_.Dog) -> str
1. (arg0: m.class_.Dog) -> str
Invoked with: <m.class_.Pet object at 0>
Invoked with: <m.class_.Pet object at 0>
"""
"""
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
Chimera
(
"lion"
,
"goat"
)
m
.
Chimera
(
"lion"
,
"goat"
)
...
@@ -150,6 +176,7 @@ def test_inheritance_init(msg):
...
@@ -150,6 +176,7 @@ def test_inheritance_init(msg):
class
Python
(
m
.
Pet
):
class
Python
(
m
.
Pet
):
def
__init__
(
self
):
def
__init__
(
self
):
pass
pass
with
pytest
.
raises
(
TypeError
)
as
exc_info
:
with
pytest
.
raises
(
TypeError
)
as
exc_info
:
Python
()
Python
()
expected
=
"m.class_.Pet.__init__() must be called when overriding __init__"
expected
=
"m.class_.Pet.__init__() must be called when overriding __init__"
...
@@ -191,13 +218,19 @@ def test_mismatched_holder():
...
@@ -191,13 +218,19 @@ def test_mismatched_holder():
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
mismatched_holder_1
()
m
.
mismatched_holder_1
()
assert
re
.
match
(
'generic_type: type ".*MismatchDerived1" does not have a non-default '
assert
re
.
match
(
'holder type while its base ".*MismatchBase1" does'
,
str
(
excinfo
.
value
))
'generic_type: type ".*MismatchDerived1" does not have a non-default '
'holder type while its base ".*MismatchBase1" does'
,
str
(
excinfo
.
value
),
)
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
mismatched_holder_2
()
m
.
mismatched_holder_2
()
assert
re
.
match
(
'generic_type: type ".*MismatchDerived2" has a non-default holder type '
assert
re
.
match
(
'while its base ".*MismatchBase2" does not'
,
str
(
excinfo
.
value
))
'generic_type: type ".*MismatchDerived2" has a non-default holder type '
'while its base ".*MismatchBase2" does not'
,
str
(
excinfo
.
value
),
)
def
test_override_static
():
def
test_override_static
():
...
@@ -229,20 +262,20 @@ def test_operator_new_delete(capture):
...
@@ -229,20 +262,20 @@ def test_operator_new_delete(capture):
a
=
m
.
HasOpNewDel
()
a
=
m
.
HasOpNewDel
()
b
=
m
.
HasOpNewDelSize
()
b
=
m
.
HasOpNewDelSize
()
d
=
m
.
HasOpNewDelBoth
()
d
=
m
.
HasOpNewDelBoth
()
assert
capture
==
"""
assert
(
capture
==
"""
A new 8
A new 8
B new 4
B new 4
D new 32
D new 32
"""
"""
)
sz_alias
=
str
(
m
.
AliasedHasOpNewDelSize
.
size_alias
)
sz_alias
=
str
(
m
.
AliasedHasOpNewDelSize
.
size_alias
)
sz_noalias
=
str
(
m
.
AliasedHasOpNewDelSize
.
size_noalias
)
sz_noalias
=
str
(
m
.
AliasedHasOpNewDelSize
.
size_noalias
)
with
capture
:
with
capture
:
c
=
m
.
AliasedHasOpNewDelSize
()
c
=
m
.
AliasedHasOpNewDelSize
()
c2
=
SubAliased
()
c2
=
SubAliased
()
assert
capture
==
(
assert
capture
==
(
"C new "
+
sz_noalias
+
"
\n
"
+
"C new "
+
sz_alias
+
"
\n
"
)
"C new "
+
sz_noalias
+
"
\n
"
+
"C new "
+
sz_alias
+
"
\n
"
)
with
capture
:
with
capture
:
del
a
del
a
...
@@ -251,21 +284,21 @@ def test_operator_new_delete(capture):
...
@@ -251,21 +284,21 @@ def test_operator_new_delete(capture):
pytest
.
gc_collect
()
pytest
.
gc_collect
()
del
d
del
d
pytest
.
gc_collect
()
pytest
.
gc_collect
()
assert
capture
==
"""
assert
(
capture
==
"""
A delete
A delete
B delete 4
B delete 4
D delete
D delete
"""
"""
)
with
capture
:
with
capture
:
del
c
del
c
pytest
.
gc_collect
()
pytest
.
gc_collect
()
del
c2
del
c2
pytest
.
gc_collect
()
pytest
.
gc_collect
()
assert
capture
==
(
assert
capture
==
(
"C delete "
+
sz_noalias
+
"
\n
"
+
"C delete "
+
sz_alias
+
"
\n
"
)
"C delete "
+
sz_noalias
+
"
\n
"
+
"C delete "
+
sz_alias
+
"
\n
"
)
def
test_bind_protected_functions
():
def
test_bind_protected_functions
():
...
@@ -325,19 +358,23 @@ def test_reentrant_implicit_conversion_failure(msg):
...
@@ -325,19 +358,23 @@ def test_reentrant_implicit_conversion_failure(msg):
# ensure that there is no runaway reentrant implicit conversion (#1035)
# ensure that there is no runaway reentrant implicit conversion (#1035)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
BogusImplicitConversion
(
0
)
m
.
BogusImplicitConversion
(
0
)
assert
msg
(
excinfo
.
value
)
==
'''
assert
(
msg
(
excinfo
.
value
)
==
"""
__init__(): incompatible constructor arguments. The following argument types are supported:
__init__(): incompatible constructor arguments. The following argument types are supported:
1. m.class_.BogusImplicitConversion(arg0: m.class_.BogusImplicitConversion)
1. m.class_.BogusImplicitConversion(arg0: m.class_.BogusImplicitConversion)
Invoked with: 0
Invoked with: 0
'''
"""
)
def
test_error_after_conversions
():
def
test_error_after_conversions
():
with
pytest
.
raises
(
TypeError
)
as
exc_info
:
with
pytest
.
raises
(
TypeError
)
as
exc_info
:
m
.
test_error_after_conversions
(
"hello"
)
m
.
test_error_after_conversions
(
"hello"
)
assert
str
(
exc_info
.
value
)
.
startswith
(
assert
str
(
exc_info
.
value
)
.
startswith
(
"Unable to convert function return value to a Python type!"
)
"Unable to convert function return value to a Python type!"
)
def
test_aligned
():
def
test_aligned
():
...
@@ -350,8 +387,10 @@ def test_aligned():
...
@@ -350,8 +387,10 @@ def test_aligned():
@pytest.mark.xfail
(
"env.PYPY"
)
@pytest.mark.xfail
(
"env.PYPY"
)
def
test_final
():
def
test_final
():
with
pytest
.
raises
(
TypeError
)
as
exc_info
:
with
pytest
.
raises
(
TypeError
)
as
exc_info
:
class
PyFinalChild
(
m
.
IsFinal
):
class
PyFinalChild
(
m
.
IsFinal
):
pass
pass
assert
str
(
exc_info
.
value
)
.
endswith
(
"is not an acceptable base type"
)
assert
str
(
exc_info
.
value
)
.
endswith
(
"is not an acceptable base type"
)
...
@@ -359,8 +398,10 @@ def test_final():
...
@@ -359,8 +398,10 @@ def test_final():
@pytest.mark.xfail
(
"env.PYPY"
)
@pytest.mark.xfail
(
"env.PYPY"
)
def
test_non_final_final
():
def
test_non_final_final
():
with
pytest
.
raises
(
TypeError
)
as
exc_info
:
with
pytest
.
raises
(
TypeError
)
as
exc_info
:
class
PyNonFinalFinalChild
(
m
.
IsNonFinalFinal
):
class
PyNonFinalFinalChild
(
m
.
IsNonFinalFinal
):
pass
pass
assert
str
(
exc_info
.
value
)
.
endswith
(
"is not an acceptable base type"
)
assert
str
(
exc_info
.
value
)
.
endswith
(
"is not an acceptable base type"
)
...
@@ -396,11 +437,14 @@ def test_base_and_derived_nested_scope():
...
@@ -396,11 +437,14 @@ def test_base_and_derived_nested_scope():
@pytest.mark.skip
(
"See https://github.com/pybind/pybind11/pull/2564"
)
@pytest.mark.skip
(
"See https://github.com/pybind/pybind11/pull/2564"
)
def
test_register_duplicate_class
():
def
test_register_duplicate_class
():
import
types
import
types
module_scope
=
types
.
ModuleType
(
"module_scope"
)
module_scope
=
types
.
ModuleType
(
"module_scope"
)
with
pytest
.
raises
(
RuntimeError
)
as
exc_info
:
with
pytest
.
raises
(
RuntimeError
)
as
exc_info
:
m
.
register_duplicate_class_name
(
module_scope
)
m
.
register_duplicate_class_name
(
module_scope
)
expected
=
(
'generic_type: cannot initialize type "Duplicate": '
expected
=
(
'an object with that name is already defined'
)
'generic_type: cannot initialize type "Duplicate": '
"an object with that name is already defined"
)
assert
str
(
exc_info
.
value
)
==
expected
assert
str
(
exc_info
.
value
)
==
expected
with
pytest
.
raises
(
RuntimeError
)
as
exc_info
:
with
pytest
.
raises
(
RuntimeError
)
as
exc_info
:
m
.
register_duplicate_class_type
(
module_scope
)
m
.
register_duplicate_class_type
(
module_scope
)
...
@@ -409,10 +453,13 @@ def test_register_duplicate_class():
...
@@ -409,10 +453,13 @@ def test_register_duplicate_class():
class
ClassScope
:
class
ClassScope
:
pass
pass
with
pytest
.
raises
(
RuntimeError
)
as
exc_info
:
with
pytest
.
raises
(
RuntimeError
)
as
exc_info
:
m
.
register_duplicate_nested_class_name
(
ClassScope
)
m
.
register_duplicate_nested_class_name
(
ClassScope
)
expected
=
(
'generic_type: cannot initialize type "DuplicateNested": '
expected
=
(
'an object with that name is already defined'
)
'generic_type: cannot initialize type "DuplicateNested": '
"an object with that name is already defined"
)
assert
str
(
exc_info
.
value
)
==
expected
assert
str
(
exc_info
.
value
)
==
expected
with
pytest
.
raises
(
RuntimeError
)
as
exc_info
:
with
pytest
.
raises
(
RuntimeError
)
as
exc_info
:
m
.
register_duplicate_nested_class_type
(
ClassScope
)
m
.
register_duplicate_nested_class_type
(
ClassScope
)
...
...
tests/test_copy_move.py
View file @
c50f90ec
...
@@ -19,7 +19,11 @@ def test_move_and_copy_casts():
...
@@ -19,7 +19,11 @@ def test_move_and_copy_casts():
"""Cast some values in C++ via custom type casters and count the number of moves/copies."""
"""Cast some values in C++ via custom type casters and count the number of moves/copies."""
cstats
=
m
.
move_and_copy_cstats
()
cstats
=
m
.
move_and_copy_cstats
()
c_m
,
c_mc
,
c_c
=
cstats
[
"MoveOnlyInt"
],
cstats
[
"MoveOrCopyInt"
],
cstats
[
"CopyOnlyInt"
]
c_m
,
c_mc
,
c_c
=
(
cstats
[
"MoveOnlyInt"
],
cstats
[
"MoveOrCopyInt"
],
cstats
[
"CopyOnlyInt"
],
)
# The type move constructions/assignments below each get incremented: the move assignment comes
# The type move constructions/assignments below each get incremented: the move assignment comes
# from the type_caster load; the move construction happens when extracting that via a cast or
# from the type_caster load; the move construction happens when extracting that via a cast or
...
@@ -43,7 +47,11 @@ def test_move_and_copy_loads():
...
@@ -43,7 +47,11 @@ def test_move_and_copy_loads():
moves/copies."""
moves/copies."""
cstats
=
m
.
move_and_copy_cstats
()
cstats
=
m
.
move_and_copy_cstats
()
c_m
,
c_mc
,
c_c
=
cstats
[
"MoveOnlyInt"
],
cstats
[
"MoveOrCopyInt"
],
cstats
[
"CopyOnlyInt"
]
c_m
,
c_mc
,
c_c
=
(
cstats
[
"MoveOnlyInt"
],
cstats
[
"MoveOrCopyInt"
],
cstats
[
"CopyOnlyInt"
],
)
assert
m
.
move_only
(
10
)
==
10
# 1 move, c_m
assert
m
.
move_only
(
10
)
==
10
# 1 move, c_m
assert
m
.
move_or_copy
(
11
)
==
11
# 1 move, c_mc
assert
m
.
move_or_copy
(
11
)
==
11
# 1 move, c_mc
...
@@ -66,12 +74,16 @@ def test_move_and_copy_loads():
...
@@ -66,12 +74,16 @@ def test_move_and_copy_loads():
assert
c_m
.
alive
()
+
c_mc
.
alive
()
+
c_c
.
alive
()
==
0
assert
c_m
.
alive
()
+
c_mc
.
alive
()
+
c_c
.
alive
()
==
0
@pytest.mark.skipif
(
not
m
.
has_optional
,
reason
=
'no <optional>'
)
@pytest.mark.skipif
(
not
m
.
has_optional
,
reason
=
"no <optional>"
)
def
test_move_and_copy_load_optional
():
def
test_move_and_copy_load_optional
():
"""Tests move/copy loads of std::optional arguments"""
"""Tests move/copy loads of std::optional arguments"""
cstats
=
m
.
move_and_copy_cstats
()
cstats
=
m
.
move_and_copy_cstats
()
c_m
,
c_mc
,
c_c
=
cstats
[
"MoveOnlyInt"
],
cstats
[
"MoveOrCopyInt"
],
cstats
[
"CopyOnlyInt"
]
c_m
,
c_mc
,
c_c
=
(
cstats
[
"MoveOnlyInt"
],
cstats
[
"MoveOrCopyInt"
],
cstats
[
"CopyOnlyInt"
],
)
# The extra move/copy constructions below come from the std::optional move (which has to move
# The extra move/copy constructions below come from the std::optional move (which has to move
# its arguments):
# its arguments):
...
...
tests/test_custom_type_casters.py
View file @
c50f90ec
...
@@ -5,65 +5,91 @@ from pybind11_tests import custom_type_casters as m
...
@@ -5,65 +5,91 @@ from pybind11_tests import custom_type_casters as m
def
test_noconvert_args
(
msg
):
def
test_noconvert_args
(
msg
):
a
=
m
.
ArgInspector
()
a
=
m
.
ArgInspector
()
assert
msg
(
a
.
f
(
"hi"
))
==
"""
assert
(
msg
(
a
.
f
(
"hi"
))
==
"""
loading ArgInspector1 argument WITH conversion allowed. Argument value = hi
loading ArgInspector1 argument WITH conversion allowed. Argument value = hi
"""
"""
assert
msg
(
a
.
g
(
"this is a"
,
"this is b"
))
==
"""
)
assert
(
msg
(
a
.
g
(
"this is a"
,
"this is b"
))
==
"""
loading ArgInspector1 argument WITHOUT conversion allowed. Argument value = this is a
loading ArgInspector1 argument WITHOUT conversion allowed. Argument value = this is a
loading ArgInspector1 argument WITH conversion allowed. Argument value = this is b
loading ArgInspector1 argument WITH conversion allowed. Argument value = this is b
13
13
loading ArgInspector2 argument WITH conversion allowed. Argument value = (default arg inspector 2)
loading ArgInspector2 argument WITH conversion allowed. Argument value = (default arg inspector 2)
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
assert
msg
(
a
.
g
(
"this is a"
,
"this is b"
,
42
))
==
"""
)
assert
(
msg
(
a
.
g
(
"this is a"
,
"this is b"
,
42
))
==
"""
loading ArgInspector1 argument WITHOUT conversion allowed. Argument value = this is a
loading ArgInspector1 argument WITHOUT conversion allowed. Argument value = this is a
loading ArgInspector1 argument WITH conversion allowed. Argument value = this is b
loading ArgInspector1 argument WITH conversion allowed. Argument value = this is b
42
42
loading ArgInspector2 argument WITH conversion allowed. Argument value = (default arg inspector 2)
loading ArgInspector2 argument WITH conversion allowed. Argument value = (default arg inspector 2)
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
assert
msg
(
a
.
g
(
"this is a"
,
"this is b"
,
42
,
"this is d"
))
==
"""
)
assert
(
msg
(
a
.
g
(
"this is a"
,
"this is b"
,
42
,
"this is d"
))
==
"""
loading ArgInspector1 argument WITHOUT conversion allowed. Argument value = this is a
loading ArgInspector1 argument WITHOUT conversion allowed. Argument value = this is a
loading ArgInspector1 argument WITH conversion allowed. Argument value = this is b
loading ArgInspector1 argument WITH conversion allowed. Argument value = this is b
42
42
loading ArgInspector2 argument WITH conversion allowed. Argument value = this is d
loading ArgInspector2 argument WITH conversion allowed. Argument value = this is d
"""
"""
assert
(
a
.
h
(
"arg 1"
)
==
)
"loading ArgInspector2 argument WITHOUT conversion allowed. Argument value = arg 1"
)
assert
(
assert
msg
(
m
.
arg_inspect_func
(
"A1"
,
"A2"
))
==
"""
a
.
h
(
"arg 1"
)
==
"loading ArgInspector2 argument WITHOUT conversion allowed. Argument value = arg 1"
)
assert
(
msg
(
m
.
arg_inspect_func
(
"A1"
,
"A2"
))
==
"""
loading ArgInspector2 argument WITH conversion allowed. Argument value = A1
loading ArgInspector2 argument WITH conversion allowed. Argument value = A1
loading ArgInspector1 argument WITHOUT conversion allowed. Argument value = A2
loading ArgInspector1 argument WITHOUT conversion allowed. Argument value = A2
"""
"""
)
assert
m
.
floats_preferred
(
4
)
==
2.0
assert
m
.
floats_preferred
(
4
)
==
2.0
assert
m
.
floats_only
(
4.0
)
==
2.0
assert
m
.
floats_only
(
4.0
)
==
2.0
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
floats_only
(
4
)
m
.
floats_only
(
4
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
floats_only(): incompatible function arguments. The following argument types are supported:
floats_only(): incompatible function arguments. The following argument types are supported:
1. (f: float) -> float
1. (f: float) -> float
Invoked with: 4
Invoked with: 4
"""
"""
)
assert
m
.
ints_preferred
(
4
)
==
2
assert
m
.
ints_preferred
(
4
)
==
2
assert
m
.
ints_preferred
(
True
)
==
0
assert
m
.
ints_preferred
(
True
)
==
0
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
ints_preferred
(
4.0
)
m
.
ints_preferred
(
4.0
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
ints_preferred(): incompatible function arguments. The following argument types are supported:
ints_preferred(): incompatible function arguments. The following argument types are supported:
1. (i: int) -> int
1. (i: int) -> int
Invoked with: 4.0
Invoked with: 4.0
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
assert
m
.
ints_only
(
4
)
==
2
assert
m
.
ints_only
(
4
)
==
2
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
ints_only
(
4.0
)
m
.
ints_only
(
4.0
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
ints_only(): incompatible function arguments. The following argument types are supported:
ints_only(): incompatible function arguments. The following argument types are supported:
1. (i: int) -> int
1. (i: int) -> int
Invoked with: 4.0
Invoked with: 4.0
"""
"""
)
def
test_custom_caster_destruction
():
def
test_custom_caster_destruction
():
...
...
tests/test_docstring_options.py
View file @
c50f90ec
...
@@ -18,10 +18,10 @@ def test_docstring_options():
...
@@ -18,10 +18,10 @@ def test_docstring_options():
assert
m
.
test_overloaded3
.
__doc__
==
"Overload docstr"
assert
m
.
test_overloaded3
.
__doc__
==
"Overload docstr"
# options.enable_function_signatures()
# options.enable_function_signatures()
assert
m
.
test_function3
.
__doc__
.
startswith
(
"test_function3(a: int, b: int) -> None"
)
assert
m
.
test_function3
.
__doc__
.
startswith
(
"test_function3(a: int, b: int) -> None"
)
assert
m
.
test_function4
.
__doc__
.
startswith
(
"test_function4(a: int, b: int) -> None"
)
assert
m
.
test_function4
.
__doc__
.
startswith
(
"test_function4(a: int, b: int) -> None"
)
assert
m
.
test_function4
.
__doc__
.
endswith
(
"A custom docstring
\n
"
)
assert
m
.
test_function4
.
__doc__
.
endswith
(
"A custom docstring
\n
"
)
# options.disable_function_signatures()
# options.disable_function_signatures()
# options.disable_user_defined_docstrings()
# options.disable_user_defined_docstrings()
...
@@ -31,8 +31,8 @@ def test_docstring_options():
...
@@ -31,8 +31,8 @@ def test_docstring_options():
assert
m
.
test_function6
.
__doc__
==
"A custom docstring"
assert
m
.
test_function6
.
__doc__
==
"A custom docstring"
# RAII destructor
# RAII destructor
assert
m
.
test_function7
.
__doc__
.
startswith
(
"test_function7(a: int, b: int) -> None"
)
assert
m
.
test_function7
.
__doc__
.
startswith
(
"test_function7(a: int, b: int) -> None"
)
assert
m
.
test_function7
.
__doc__
.
endswith
(
"A custom docstring
\n
"
)
assert
m
.
test_function7
.
__doc__
.
endswith
(
"A custom docstring
\n
"
)
# Suppression of user-defined docstrings for non-function objects
# Suppression of user-defined docstrings for non-function objects
assert
not
m
.
DocstringTestFoo
.
__doc__
assert
not
m
.
DocstringTestFoo
.
__doc__
...
...
tests/test_eigen.py
View file @
c50f90ec
...
@@ -6,11 +6,15 @@ np = pytest.importorskip("numpy")
...
@@ -6,11 +6,15 @@ np = pytest.importorskip("numpy")
m
=
pytest
.
importorskip
(
"pybind11_tests.eigen"
)
m
=
pytest
.
importorskip
(
"pybind11_tests.eigen"
)
ref
=
np
.
array
([[
0.
,
3
,
0
,
0
,
0
,
11
],
ref
=
np
.
array
(
[
22
,
0
,
0
,
0
,
17
,
11
],
[
[
7
,
5
,
0
,
1
,
0
,
11
],
[
0.0
,
3
,
0
,
0
,
0
,
11
],
[
0
,
0
,
0
,
0
,
0
,
11
],
[
22
,
0
,
0
,
0
,
17
,
11
],
[
0
,
0
,
14
,
0
,
8
,
11
]])
[
7
,
5
,
0
,
1
,
0
,
11
],
[
0
,
0
,
0
,
0
,
0
,
11
],
[
0
,
0
,
14
,
0
,
8
,
11
],
]
)
def
assert_equal_ref
(
mat
):
def
assert_equal_ref
(
mat
):
...
@@ -40,28 +44,37 @@ def test_dense():
...
@@ -40,28 +44,37 @@ def test_dense():
def
test_partially_fixed
():
def
test_partially_fixed
():
ref2
=
np
.
array
([[
0.
,
1
,
2
,
3
],
[
4
,
5
,
6
,
7
],
[
8
,
9
,
10
,
11
],
[
12
,
13
,
14
,
15
]])
ref2
=
np
.
array
([[
0.
0
,
1
,
2
,
3
],
[
4
,
5
,
6
,
7
],
[
8
,
9
,
10
,
11
],
[
12
,
13
,
14
,
15
]])
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_rm_r
(
ref2
),
ref2
)
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_rm_r
(
ref2
),
ref2
)
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_rm_c
(
ref2
),
ref2
)
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_rm_c
(
ref2
),
ref2
)
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_rm_r
(
ref2
[:,
1
]),
ref2
[:,
[
1
]])
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_rm_r
(
ref2
[:,
1
]),
ref2
[:,
[
1
]])
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_rm_c
(
ref2
[
0
,
:]),
ref2
[[
0
],
:])
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_rm_c
(
ref2
[
0
,
:]),
ref2
[[
0
],
:])
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_rm_r
(
ref2
[:,
(
0
,
2
)]),
ref2
[:,
(
0
,
2
)])
np
.
testing
.
assert_array_equal
(
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_rm_c
(
ref2
[(
3
,
1
,
2
),
:]),
ref2
[(
3
,
1
,
2
),
:])
m
.
partial_copy_four_rm_r
(
ref2
[:,
(
0
,
2
)]),
ref2
[:,
(
0
,
2
)]
)
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_rm_c
(
ref2
[(
3
,
1
,
2
),
:]),
ref2
[(
3
,
1
,
2
),
:]
)
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_cm_r
(
ref2
),
ref2
)
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_cm_r
(
ref2
),
ref2
)
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_cm_c
(
ref2
),
ref2
)
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_cm_c
(
ref2
),
ref2
)
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_cm_r
(
ref2
[:,
1
]),
ref2
[:,
[
1
]])
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_cm_r
(
ref2
[:,
1
]),
ref2
[:,
[
1
]])
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_cm_c
(
ref2
[
0
,
:]),
ref2
[[
0
],
:])
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_cm_c
(
ref2
[
0
,
:]),
ref2
[[
0
],
:])
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_cm_r
(
ref2
[:,
(
0
,
2
)]),
ref2
[:,
(
0
,
2
)])
np
.
testing
.
assert_array_equal
(
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_cm_c
(
ref2
[(
3
,
1
,
2
),
:]),
ref2
[(
3
,
1
,
2
),
:])
m
.
partial_copy_four_cm_r
(
ref2
[:,
(
0
,
2
)]),
ref2
[:,
(
0
,
2
)]
)
np
.
testing
.
assert_array_equal
(
m
.
partial_copy_four_cm_c
(
ref2
[(
3
,
1
,
2
),
:]),
ref2
[(
3
,
1
,
2
),
:]
)
# TypeError should be raise for a shape mismatch
# TypeError should be raise for a shape mismatch
functions
=
[
m
.
partial_copy_four_rm_r
,
m
.
partial_copy_four_rm_c
,
functions
=
[
m
.
partial_copy_four_cm_r
,
m
.
partial_copy_four_cm_c
]
m
.
partial_copy_four_rm_r
,
matrix_with_wrong_shape
=
[[
1
,
2
],
m
.
partial_copy_four_rm_c
,
[
3
,
4
]]
m
.
partial_copy_four_cm_r
,
m
.
partial_copy_four_cm_c
,
]
matrix_with_wrong_shape
=
[[
1
,
2
],
[
3
,
4
]]
for
f
in
functions
:
for
f
in
functions
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
f
(
matrix_with_wrong_shape
)
f
(
matrix_with_wrong_shape
)
...
@@ -69,7 +82,7 @@ def test_partially_fixed():
...
@@ -69,7 +82,7 @@ def test_partially_fixed():
def
test_mutator_descriptors
():
def
test_mutator_descriptors
():
zr
=
np
.
arange
(
30
,
dtype
=
'float32'
)
.
reshape
(
5
,
6
)
# row-major
zr
=
np
.
arange
(
30
,
dtype
=
"float32"
)
.
reshape
(
5
,
6
)
# row-major
zc
=
zr
.
reshape
(
6
,
5
)
.
transpose
()
# column-major
zc
=
zr
.
reshape
(
6
,
5
)
.
transpose
()
# column-major
m
.
fixed_mutator_r
(
zr
)
m
.
fixed_mutator_r
(
zr
)
...
@@ -78,18 +91,21 @@ def test_mutator_descriptors():
...
@@ -78,18 +91,21 @@ def test_mutator_descriptors():
m
.
fixed_mutator_a
(
zc
)
m
.
fixed_mutator_a
(
zc
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
fixed_mutator_r
(
zc
)
m
.
fixed_mutator_r
(
zc
)
assert
(
'(arg0: numpy.ndarray[numpy.float32[5, 6],'
assert
(
' flags.writeable, flags.c_contiguous]) -> None'
"(arg0: numpy.ndarray[numpy.float32[5, 6],"
in
str
(
excinfo
.
value
))
" flags.writeable, flags.c_contiguous]) -> None"
in
str
(
excinfo
.
value
)
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
fixed_mutator_c
(
zr
)
m
.
fixed_mutator_c
(
zr
)
assert
(
'(arg0: numpy.ndarray[numpy.float32[5, 6],'
assert
(
' flags.writeable, flags.f_contiguous]) -> None'
"(arg0: numpy.ndarray[numpy.float32[5, 6],"
in
str
(
excinfo
.
value
))
" flags.writeable, flags.f_contiguous]) -> None"
in
str
(
excinfo
.
value
)
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
fixed_mutator_a
(
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
'float32'
))
m
.
fixed_mutator_a
(
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
"float32"
))
assert
(
'(arg0: numpy.ndarray[numpy.float32[5, 6], flags.writeable]) -> None'
assert
"(arg0: numpy.ndarray[numpy.float32[5, 6], flags.writeable]) -> None"
in
str
(
in
str
(
excinfo
.
value
))
excinfo
.
value
)
zr
.
flags
.
writeable
=
False
zr
.
flags
.
writeable
=
False
with
pytest
.
raises
(
TypeError
):
with
pytest
.
raises
(
TypeError
):
m
.
fixed_mutator_r
(
zr
)
m
.
fixed_mutator_r
(
zr
)
...
@@ -98,26 +114,26 @@ def test_mutator_descriptors():
...
@@ -98,26 +114,26 @@ def test_mutator_descriptors():
def
test_cpp_casting
():
def
test_cpp_casting
():
assert
m
.
cpp_copy
(
m
.
fixed_r
())
==
22.
assert
m
.
cpp_copy
(
m
.
fixed_r
())
==
22.
0
assert
m
.
cpp_copy
(
m
.
fixed_c
())
==
22.
assert
m
.
cpp_copy
(
m
.
fixed_c
())
==
22.
0
z
=
np
.
array
([[
5.
,
6
],
[
7
,
8
]])
z
=
np
.
array
([[
5.
0
,
6
],
[
7
,
8
]])
assert
m
.
cpp_copy
(
z
)
==
7.
assert
m
.
cpp_copy
(
z
)
==
7.
0
assert
m
.
cpp_copy
(
m
.
get_cm_ref
())
==
21.
assert
m
.
cpp_copy
(
m
.
get_cm_ref
())
==
21.
0
assert
m
.
cpp_copy
(
m
.
get_rm_ref
())
==
21.
assert
m
.
cpp_copy
(
m
.
get_rm_ref
())
==
21.
0
assert
m
.
cpp_ref_c
(
m
.
get_cm_ref
())
==
21.
assert
m
.
cpp_ref_c
(
m
.
get_cm_ref
())
==
21.
0
assert
m
.
cpp_ref_r
(
m
.
get_rm_ref
())
==
21.
assert
m
.
cpp_ref_r
(
m
.
get_rm_ref
())
==
21.
0
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
# Can't reference m.fixed_c: it contains floats, m.cpp_ref_any wants doubles
# Can't reference m.fixed_c: it contains floats, m.cpp_ref_any wants doubles
m
.
cpp_ref_any
(
m
.
fixed_c
())
m
.
cpp_ref_any
(
m
.
fixed_c
())
assert
'Unable to cast Python instance'
in
str
(
excinfo
.
value
)
assert
"Unable to cast Python instance"
in
str
(
excinfo
.
value
)
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
# Can't reference m.fixed_r: it contains floats, m.cpp_ref_any wants doubles
# Can't reference m.fixed_r: it contains floats, m.cpp_ref_any wants doubles
m
.
cpp_ref_any
(
m
.
fixed_r
())
m
.
cpp_ref_any
(
m
.
fixed_r
())
assert
'Unable to cast Python instance'
in
str
(
excinfo
.
value
)
assert
"Unable to cast Python instance"
in
str
(
excinfo
.
value
)
assert
m
.
cpp_ref_any
(
m
.
ReturnTester
.
create
())
==
1.
assert
m
.
cpp_ref_any
(
m
.
ReturnTester
.
create
())
==
1.
0
assert
m
.
cpp_ref_any
(
m
.
get_cm_ref
())
==
21.
assert
m
.
cpp_ref_any
(
m
.
get_cm_ref
())
==
21.
0
assert
m
.
cpp_ref_any
(
m
.
get_cm_ref
())
==
21.
assert
m
.
cpp_ref_any
(
m
.
get_cm_ref
())
==
21.
0
def
test_pass_readonly_array
():
def
test_pass_readonly_array
():
...
@@ -149,7 +165,7 @@ def test_nonunit_stride_from_python():
...
@@ -149,7 +165,7 @@ def test_nonunit_stride_from_python():
# Mutator:
# Mutator:
m
.
double_threer
(
second_row
)
m
.
double_threer
(
second_row
)
m
.
double_threec
(
second_col
)
m
.
double_threec
(
second_col
)
np
.
testing
.
assert_array_equal
(
counting_mat
,
[[
0.
,
2
,
2
],
[
6
,
16
,
10
],
[
6
,
14
,
8
]])
np
.
testing
.
assert_array_equal
(
counting_mat
,
[[
0.
0
,
2
,
2
],
[
6
,
16
,
10
],
[
6
,
14
,
8
]])
def
test_negative_stride_from_python
(
msg
):
def
test_negative_stride_from_python
(
msg
):
...
@@ -178,26 +194,36 @@ def test_negative_stride_from_python(msg):
...
@@ -178,26 +194,36 @@ def test_negative_stride_from_python(msg):
# Mutator:
# Mutator:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
double_threer
(
second_row
)
m
.
double_threer
(
second_row
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
double_threer(): incompatible function arguments. The following argument types are supported:
double_threer(): incompatible function arguments. The following argument types are supported:
1. (arg0: numpy.ndarray[numpy.float32[1, 3], flags.writeable]) -> None
1. (arg0: numpy.ndarray[numpy.float32[1, 3], flags.writeable]) -> None
Invoked with: """
+
repr
(
np
.
array
([
5.
,
4.
,
3.
],
dtype
=
'float32'
))
# noqa: E501 line too long
Invoked with: """
# noqa: E501 line too long
+
repr
(
np
.
array
([
5.0
,
4.0
,
3.0
],
dtype
=
"float32"
))
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
double_threec
(
second_col
)
m
.
double_threec
(
second_col
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
double_threec(): incompatible function arguments. The following argument types are supported:
double_threec(): incompatible function arguments. The following argument types are supported:
1. (arg0: numpy.ndarray[numpy.float32[3, 1], flags.writeable]) -> None
1. (arg0: numpy.ndarray[numpy.float32[3, 1], flags.writeable]) -> None
Invoked with: """
+
repr
(
np
.
array
([
7.
,
4.
,
1.
],
dtype
=
'float32'
))
# noqa: E501 line too long
Invoked with: """
# noqa: E501 line too long
+
repr
(
np
.
array
([
7.0
,
4.0
,
1.0
],
dtype
=
"float32"
))
)
def
test_nonunit_stride_to_python
():
def
test_nonunit_stride_to_python
():
assert
np
.
all
(
m
.
diagonal
(
ref
)
==
ref
.
diagonal
())
assert
np
.
all
(
m
.
diagonal
(
ref
)
==
ref
.
diagonal
())
assert
np
.
all
(
m
.
diagonal_1
(
ref
)
==
ref
.
diagonal
(
1
))
assert
np
.
all
(
m
.
diagonal_1
(
ref
)
==
ref
.
diagonal
(
1
))
for
i
in
range
(
-
5
,
7
):
for
i
in
range
(
-
5
,
7
):
assert
np
.
all
(
m
.
diagonal_n
(
ref
,
i
)
==
ref
.
diagonal
(
i
)),
"m.diagonal_n({})"
.
format
(
i
)
assert
np
.
all
(
m
.
diagonal_n
(
ref
,
i
)
==
ref
.
diagonal
(
i
)
),
"m.diagonal_n({})"
.
format
(
i
)
assert
np
.
all
(
m
.
block
(
ref
,
2
,
1
,
3
,
3
)
==
ref
[
2
:
5
,
1
:
4
])
assert
np
.
all
(
m
.
block
(
ref
,
2
,
1
,
3
,
3
)
==
ref
[
2
:
5
,
1
:
4
])
assert
np
.
all
(
m
.
block
(
ref
,
1
,
4
,
4
,
2
)
==
ref
[
1
:,
4
:])
assert
np
.
all
(
m
.
block
(
ref
,
1
,
4
,
4
,
2
)
==
ref
[
1
:,
4
:])
...
@@ -207,8 +233,10 @@ def test_nonunit_stride_to_python():
...
@@ -207,8 +233,10 @@ def test_nonunit_stride_to_python():
def
test_eigen_ref_to_python
():
def
test_eigen_ref_to_python
():
chols
=
[
m
.
cholesky1
,
m
.
cholesky2
,
m
.
cholesky3
,
m
.
cholesky4
]
chols
=
[
m
.
cholesky1
,
m
.
cholesky2
,
m
.
cholesky3
,
m
.
cholesky4
]
for
i
,
chol
in
enumerate
(
chols
,
start
=
1
):
for
i
,
chol
in
enumerate
(
chols
,
start
=
1
):
mymat
=
chol
(
np
.
array
([[
1.
,
2
,
4
],
[
2
,
13
,
23
],
[
4
,
23
,
77
]]))
mymat
=
chol
(
np
.
array
([[
1.0
,
2
,
4
],
[
2
,
13
,
23
],
[
4
,
23
,
77
]]))
assert
np
.
all
(
mymat
==
np
.
array
([[
1
,
0
,
0
],
[
2
,
3
,
0
],
[
4
,
5
,
6
]])),
"cholesky{}"
.
format
(
i
)
assert
np
.
all
(
mymat
==
np
.
array
([[
1
,
0
,
0
],
[
2
,
3
,
0
],
[
4
,
5
,
6
]])
),
"cholesky{}"
.
format
(
i
)
def
assign_both
(
a1
,
a2
,
r
,
c
,
v
):
def
assign_both
(
a1
,
a2
,
r
,
c
,
v
):
...
@@ -325,8 +353,12 @@ def test_eigen_return_references():
...
@@ -325,8 +353,12 @@ def test_eigen_return_references():
np
.
testing
.
assert_array_equal
(
a_block1
,
master
[
3
:
5
,
3
:
5
])
np
.
testing
.
assert_array_equal
(
a_block1
,
master
[
3
:
5
,
3
:
5
])
np
.
testing
.
assert_array_equal
(
a_block2
,
master
[
2
:
5
,
2
:
4
])
np
.
testing
.
assert_array_equal
(
a_block2
,
master
[
2
:
5
,
2
:
4
])
np
.
testing
.
assert_array_equal
(
a_block3
,
master
[
6
:
10
,
7
:
10
])
np
.
testing
.
assert_array_equal
(
a_block3
,
master
[
6
:
10
,
7
:
10
])
np
.
testing
.
assert_array_equal
(
a_corn1
,
master
[
0
::
master
.
shape
[
0
]
-
1
,
0
::
master
.
shape
[
1
]
-
1
])
np
.
testing
.
assert_array_equal
(
np
.
testing
.
assert_array_equal
(
a_corn2
,
master
[
0
::
master
.
shape
[
0
]
-
1
,
0
::
master
.
shape
[
1
]
-
1
])
a_corn1
,
master
[
0
::
master
.
shape
[
0
]
-
1
,
0
::
master
.
shape
[
1
]
-
1
]
)
np
.
testing
.
assert_array_equal
(
a_corn2
,
master
[
0
::
master
.
shape
[
0
]
-
1
,
0
::
master
.
shape
[
1
]
-
1
]
)
np
.
testing
.
assert_array_equal
(
a_copy1
,
c1want
)
np
.
testing
.
assert_array_equal
(
a_copy1
,
c1want
)
np
.
testing
.
assert_array_equal
(
a_copy2
,
c2want
)
np
.
testing
.
assert_array_equal
(
a_copy2
,
c2want
)
...
@@ -355,16 +387,28 @@ def test_eigen_keepalive():
...
@@ -355,16 +387,28 @@ def test_eigen_keepalive():
cstats
=
ConstructorStats
.
get
(
m
.
ReturnTester
)
cstats
=
ConstructorStats
.
get
(
m
.
ReturnTester
)
assert
cstats
.
alive
()
==
1
assert
cstats
.
alive
()
==
1
unsafe
=
[
a
.
ref
(),
a
.
ref_const
(),
a
.
block
(
1
,
2
,
3
,
4
)]
unsafe
=
[
a
.
ref
(),
a
.
ref_const
(),
a
.
block
(
1
,
2
,
3
,
4
)]
copies
=
[
a
.
copy_get
(),
a
.
copy_view
(),
a
.
copy_ref
(),
a
.
copy_ref_const
(),
copies
=
[
a
.
copy_block
(
4
,
3
,
2
,
1
)]
a
.
copy_get
(),
a
.
copy_view
(),
a
.
copy_ref
(),
a
.
copy_ref_const
(),
a
.
copy_block
(
4
,
3
,
2
,
1
),
]
del
a
del
a
assert
cstats
.
alive
()
==
0
assert
cstats
.
alive
()
==
0
del
unsafe
del
unsafe
del
copies
del
copies
for
meth
in
[
m
.
ReturnTester
.
get
,
m
.
ReturnTester
.
get_ptr
,
m
.
ReturnTester
.
view
,
for
meth
in
[
m
.
ReturnTester
.
view_ptr
,
m
.
ReturnTester
.
ref_safe
,
m
.
ReturnTester
.
ref_const_safe
,
m
.
ReturnTester
.
get
,
m
.
ReturnTester
.
corners
,
m
.
ReturnTester
.
corners_const
]:
m
.
ReturnTester
.
get_ptr
,
m
.
ReturnTester
.
view
,
m
.
ReturnTester
.
view_ptr
,
m
.
ReturnTester
.
ref_safe
,
m
.
ReturnTester
.
ref_const_safe
,
m
.
ReturnTester
.
corners
,
m
.
ReturnTester
.
corners_const
,
]:
assert_keeps_alive
(
m
.
ReturnTester
,
meth
)
assert_keeps_alive
(
m
.
ReturnTester
,
meth
)
for
meth
in
[
m
.
ReturnTester
.
block_safe
,
m
.
ReturnTester
.
block_const
]:
for
meth
in
[
m
.
ReturnTester
.
block_safe
,
m
.
ReturnTester
.
block_const
]:
...
@@ -374,18 +418,18 @@ def test_eigen_keepalive():
...
@@ -374,18 +418,18 @@ def test_eigen_keepalive():
def
test_eigen_ref_mutators
():
def
test_eigen_ref_mutators
():
"""Tests Eigen's ability to mutate numpy values"""
"""Tests Eigen's ability to mutate numpy values"""
orig
=
np
.
array
([[
1.
,
2
,
3
],
[
4
,
5
,
6
],
[
7
,
8
,
9
]])
orig
=
np
.
array
([[
1.
0
,
2
,
3
],
[
4
,
5
,
6
],
[
7
,
8
,
9
]])
zr
=
np
.
array
(
orig
)
zr
=
np
.
array
(
orig
)
zc
=
np
.
array
(
orig
,
order
=
'F'
)
zc
=
np
.
array
(
orig
,
order
=
"F"
)
m
.
add_rm
(
zr
,
1
,
0
,
100
)
m
.
add_rm
(
zr
,
1
,
0
,
100
)
assert
np
.
all
(
zr
==
np
.
array
([[
1.
,
2
,
3
],
[
104
,
5
,
6
],
[
7
,
8
,
9
]]))
assert
np
.
all
(
zr
==
np
.
array
([[
1.
0
,
2
,
3
],
[
104
,
5
,
6
],
[
7
,
8
,
9
]]))
m
.
add_cm
(
zc
,
1
,
0
,
200
)
m
.
add_cm
(
zc
,
1
,
0
,
200
)
assert
np
.
all
(
zc
==
np
.
array
([[
1.
,
2
,
3
],
[
204
,
5
,
6
],
[
7
,
8
,
9
]]))
assert
np
.
all
(
zc
==
np
.
array
([[
1.
0
,
2
,
3
],
[
204
,
5
,
6
],
[
7
,
8
,
9
]]))
m
.
add_any
(
zr
,
1
,
0
,
20
)
m
.
add_any
(
zr
,
1
,
0
,
20
)
assert
np
.
all
(
zr
==
np
.
array
([[
1.
,
2
,
3
],
[
124
,
5
,
6
],
[
7
,
8
,
9
]]))
assert
np
.
all
(
zr
==
np
.
array
([[
1.
0
,
2
,
3
],
[
124
,
5
,
6
],
[
7
,
8
,
9
]]))
m
.
add_any
(
zc
,
1
,
0
,
10
)
m
.
add_any
(
zc
,
1
,
0
,
10
)
assert
np
.
all
(
zc
==
np
.
array
([[
1.
,
2
,
3
],
[
214
,
5
,
6
],
[
7
,
8
,
9
]]))
assert
np
.
all
(
zc
==
np
.
array
([[
1.
0
,
2
,
3
],
[
214
,
5
,
6
],
[
7
,
8
,
9
]]))
# Can't reference a col-major array with a row-major Ref, and vice versa:
# Can't reference a col-major array with a row-major Ref, and vice versa:
with
pytest
.
raises
(
TypeError
):
with
pytest
.
raises
(
TypeError
):
...
@@ -406,8 +450,8 @@ def test_eigen_ref_mutators():
...
@@ -406,8 +450,8 @@ def test_eigen_ref_mutators():
cornersr
=
zr
[
0
::
2
,
0
::
2
]
cornersr
=
zr
[
0
::
2
,
0
::
2
]
cornersc
=
zc
[
0
::
2
,
0
::
2
]
cornersc
=
zc
[
0
::
2
,
0
::
2
]
assert
np
.
all
(
cornersr
==
np
.
array
([[
1.
,
3
],
[
7
,
9
]]))
assert
np
.
all
(
cornersr
==
np
.
array
([[
1.
0
,
3
],
[
7
,
9
]]))
assert
np
.
all
(
cornersc
==
np
.
array
([[
1.
,
3
],
[
7
,
9
]]))
assert
np
.
all
(
cornersc
==
np
.
array
([[
1.
0
,
3
],
[
7
,
9
]]))
with
pytest
.
raises
(
TypeError
):
with
pytest
.
raises
(
TypeError
):
m
.
add_rm
(
cornersr
,
0
,
1
,
25
)
m
.
add_rm
(
cornersr
,
0
,
1
,
25
)
...
@@ -419,8 +463,8 @@ def test_eigen_ref_mutators():
...
@@ -419,8 +463,8 @@ def test_eigen_ref_mutators():
m
.
add_cm
(
cornersc
,
0
,
1
,
25
)
m
.
add_cm
(
cornersc
,
0
,
1
,
25
)
m
.
add_any
(
cornersr
,
0
,
1
,
25
)
m
.
add_any
(
cornersr
,
0
,
1
,
25
)
m
.
add_any
(
cornersc
,
0
,
1
,
44
)
m
.
add_any
(
cornersc
,
0
,
1
,
44
)
assert
np
.
all
(
zr
==
np
.
array
([[
1.
,
2
,
28
],
[
4
,
5
,
6
],
[
7
,
8
,
9
]]))
assert
np
.
all
(
zr
==
np
.
array
([[
1.
0
,
2
,
28
],
[
4
,
5
,
6
],
[
7
,
8
,
9
]]))
assert
np
.
all
(
zc
==
np
.
array
([[
1.
,
2
,
47
],
[
4
,
5
,
6
],
[
7
,
8
,
9
]]))
assert
np
.
all
(
zc
==
np
.
array
([[
1.
0
,
2
,
47
],
[
4
,
5
,
6
],
[
7
,
8
,
9
]]))
# You shouldn't be allowed to pass a non-writeable array to a mutating Eigen method:
# You shouldn't be allowed to pass a non-writeable array to a mutating Eigen method:
zro
=
zr
[
0
:
4
,
0
:
4
]
zro
=
zr
[
0
:
4
,
0
:
4
]
...
@@ -458,7 +502,7 @@ def test_numpy_ref_mutators():
...
@@ -458,7 +502,7 @@ def test_numpy_ref_mutators():
assert
not
zrro
.
flags
.
owndata
and
not
zrro
.
flags
.
writeable
assert
not
zrro
.
flags
.
owndata
and
not
zrro
.
flags
.
writeable
zc
[
1
,
2
]
=
99
zc
[
1
,
2
]
=
99
expect
=
np
.
array
([[
11.
,
12
,
13
],
[
21
,
22
,
99
],
[
31
,
32
,
33
]])
expect
=
np
.
array
([[
11.
0
,
12
,
13
],
[
21
,
22
,
99
],
[
31
,
32
,
33
]])
# We should have just changed zc, of course, but also zcro and the original eigen matrix
# We should have just changed zc, of course, but also zcro and the original eigen matrix
assert
np
.
all
(
zc
==
expect
)
assert
np
.
all
(
zc
==
expect
)
assert
np
.
all
(
zcro
==
expect
)
assert
np
.
all
(
zcro
==
expect
)
...
@@ -506,18 +550,20 @@ def test_both_ref_mutators():
...
@@ -506,18 +550,20 @@ def test_both_ref_mutators():
assert
np
.
all
(
z
==
z3
)
assert
np
.
all
(
z
==
z3
)
assert
np
.
all
(
z
==
z4
)
assert
np
.
all
(
z
==
z4
)
assert
np
.
all
(
z
==
z5
)
assert
np
.
all
(
z
==
z5
)
expect
=
np
.
array
([[
0.
,
22
,
20
],
[
31
,
37
,
33
],
[
41
,
42
,
38
]])
expect
=
np
.
array
([[
0.
0
,
22
,
20
],
[
31
,
37
,
33
],
[
41
,
42
,
38
]])
assert
np
.
all
(
z
==
expect
)
assert
np
.
all
(
z
==
expect
)
y
=
np
.
array
(
range
(
100
),
dtype
=
'float64'
)
.
reshape
(
10
,
10
)
y
=
np
.
array
(
range
(
100
),
dtype
=
"float64"
)
.
reshape
(
10
,
10
)
y2
=
m
.
incr_matrix_any
(
y
,
10
)
# np -> eigen -> np
y2
=
m
.
incr_matrix_any
(
y
,
10
)
# np -> eigen -> np
y3
=
m
.
incr_matrix_any
(
y2
[
0
::
2
,
0
::
2
],
-
33
)
# np -> eigen -> np slice -> np -> eigen -> np
y3
=
m
.
incr_matrix_any
(
y2
[
0
::
2
,
0
::
2
],
-
33
)
# np -> eigen -> np slice -> np -> eigen -> np
y4
=
m
.
even_rows
(
y3
)
# numpy -> eigen slice -> (... y3)
y4
=
m
.
even_rows
(
y3
)
# numpy -> eigen slice -> (... y3)
y5
=
m
.
even_cols
(
y4
)
# numpy -> eigen slice -> (... y4)
y5
=
m
.
even_cols
(
y4
)
# numpy -> eigen slice -> (... y4)
y6
=
m
.
incr_matrix_any
(
y5
,
1000
)
# numpy -> eigen -> (... y5)
y6
=
m
.
incr_matrix_any
(
y5
,
1000
)
# numpy -> eigen -> (... y5)
# Apply same mutations using just numpy:
# Apply same mutations using just numpy:
yexpect
=
np
.
array
(
range
(
100
),
dtype
=
'float64'
)
.
reshape
(
10
,
10
)
yexpect
=
np
.
array
(
range
(
100
),
dtype
=
"float64"
)
.
reshape
(
10
,
10
)
yexpect
+=
10
yexpect
+=
10
yexpect
[
0
::
2
,
0
::
2
]
-=
33
yexpect
[
0
::
2
,
0
::
2
]
-=
33
yexpect
[
0
::
4
,
0
::
4
]
+=
1000
yexpect
[
0
::
4
,
0
::
4
]
+=
1000
...
@@ -532,10 +578,14 @@ def test_both_ref_mutators():
...
@@ -532,10 +578,14 @@ def test_both_ref_mutators():
def
test_nocopy_wrapper
():
def
test_nocopy_wrapper
():
# get_elem requires a column-contiguous matrix reference, but should be
# get_elem requires a column-contiguous matrix reference, but should be
# callable with other types of matrix (via copying):
# callable with other types of matrix (via copying):
int_matrix_colmajor
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
],
[
7
,
8
,
9
]],
order
=
'F'
)
int_matrix_colmajor
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
],
[
7
,
8
,
9
]],
order
=
"F"
)
dbl_matrix_colmajor
=
np
.
array
(
int_matrix_colmajor
,
dtype
=
'double'
,
order
=
'F'
,
copy
=
True
)
dbl_matrix_colmajor
=
np
.
array
(
int_matrix_rowmajor
=
np
.
array
(
int_matrix_colmajor
,
order
=
'C'
,
copy
=
True
)
int_matrix_colmajor
,
dtype
=
"double"
,
order
=
"F"
,
copy
=
True
dbl_matrix_rowmajor
=
np
.
array
(
int_matrix_rowmajor
,
dtype
=
'double'
,
order
=
'C'
,
copy
=
True
)
)
int_matrix_rowmajor
=
np
.
array
(
int_matrix_colmajor
,
order
=
"C"
,
copy
=
True
)
dbl_matrix_rowmajor
=
np
.
array
(
int_matrix_rowmajor
,
dtype
=
"double"
,
order
=
"C"
,
copy
=
True
)
# All should be callable via get_elem:
# All should be callable via get_elem:
assert
m
.
get_elem
(
int_matrix_colmajor
)
==
8
assert
m
.
get_elem
(
int_matrix_colmajor
)
==
8
...
@@ -546,32 +596,38 @@ def test_nocopy_wrapper():
...
@@ -546,32 +596,38 @@ def test_nocopy_wrapper():
# All but the second should fail with m.get_elem_nocopy:
# All but the second should fail with m.get_elem_nocopy:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
get_elem_nocopy
(
int_matrix_colmajor
)
m
.
get_elem_nocopy
(
int_matrix_colmajor
)
assert
(
'get_elem_nocopy(): incompatible function arguments.'
in
str
(
excinfo
.
value
)
and
assert
"get_elem_nocopy(): incompatible function arguments."
in
str
(
', flags.f_contiguous'
in
str
(
excinfo
.
value
))
excinfo
.
value
)
and
", flags.f_contiguous"
in
str
(
excinfo
.
value
)
assert
m
.
get_elem_nocopy
(
dbl_matrix_colmajor
)
==
8
assert
m
.
get_elem_nocopy
(
dbl_matrix_colmajor
)
==
8
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
get_elem_nocopy
(
int_matrix_rowmajor
)
m
.
get_elem_nocopy
(
int_matrix_rowmajor
)
assert
(
'get_elem_nocopy(): incompatible function arguments.'
in
str
(
excinfo
.
value
)
and
assert
"get_elem_nocopy(): incompatible function arguments."
in
str
(
', flags.f_contiguous'
in
str
(
excinfo
.
value
))
excinfo
.
value
)
and
", flags.f_contiguous"
in
str
(
excinfo
.
value
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
get_elem_nocopy
(
dbl_matrix_rowmajor
)
m
.
get_elem_nocopy
(
dbl_matrix_rowmajor
)
assert
(
'get_elem_nocopy(): incompatible function arguments.'
in
str
(
excinfo
.
value
)
and
assert
"get_elem_nocopy(): incompatible function arguments."
in
str
(
', flags.f_contiguous'
in
str
(
excinfo
.
value
))
excinfo
.
value
)
and
", flags.f_contiguous"
in
str
(
excinfo
.
value
)
# For the row-major test, we take a long matrix in row-major, so only the third is allowed:
# For the row-major test, we take a long matrix in row-major, so only the third is allowed:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
get_elem_rm_nocopy
(
int_matrix_colmajor
)
m
.
get_elem_rm_nocopy
(
int_matrix_colmajor
)
assert
(
'get_elem_rm_nocopy(): incompatible function arguments.'
in
str
(
excinfo
.
value
)
and
assert
"get_elem_rm_nocopy(): incompatible function arguments."
in
str
(
', flags.c_contiguous'
in
str
(
excinfo
.
value
))
excinfo
.
value
)
and
", flags.c_contiguous"
in
str
(
excinfo
.
value
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
get_elem_rm_nocopy
(
dbl_matrix_colmajor
)
m
.
get_elem_rm_nocopy
(
dbl_matrix_colmajor
)
assert
(
'get_elem_rm_nocopy(): incompatible function arguments.'
in
str
(
excinfo
.
value
)
and
assert
"get_elem_rm_nocopy(): incompatible function arguments."
in
str
(
', flags.c_contiguous'
in
str
(
excinfo
.
value
))
excinfo
.
value
)
and
", flags.c_contiguous"
in
str
(
excinfo
.
value
)
assert
m
.
get_elem_rm_nocopy
(
int_matrix_rowmajor
)
==
8
assert
m
.
get_elem_rm_nocopy
(
int_matrix_rowmajor
)
==
8
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
get_elem_rm_nocopy
(
dbl_matrix_rowmajor
)
m
.
get_elem_rm_nocopy
(
dbl_matrix_rowmajor
)
assert
(
'get_elem_rm_nocopy(): incompatible function arguments.'
in
str
(
excinfo
.
value
)
and
assert
"get_elem_rm_nocopy(): incompatible function arguments."
in
str
(
', flags.c_contiguous'
in
str
(
excinfo
.
value
))
excinfo
.
value
)
and
", flags.c_contiguous"
in
str
(
excinfo
.
value
)
def
test_eigen_ref_life_support
():
def
test_eigen_ref_life_support
():
...
@@ -589,12 +645,9 @@ def test_eigen_ref_life_support():
...
@@ -589,12 +645,9 @@ def test_eigen_ref_life_support():
def
test_special_matrix_objects
():
def
test_special_matrix_objects
():
assert
np
.
all
(
m
.
incr_diag
(
7
)
==
np
.
diag
([
1.
,
2
,
3
,
4
,
5
,
6
,
7
]))
assert
np
.
all
(
m
.
incr_diag
(
7
)
==
np
.
diag
([
1.
0
,
2
,
3
,
4
,
5
,
6
,
7
]))
asymm
=
np
.
array
([[
1.
,
2
,
3
,
4
],
asymm
=
np
.
array
([[
1.0
,
2
,
3
,
4
],
[
5
,
6
,
7
,
8
],
[
9
,
10
,
11
,
12
],
[
13
,
14
,
15
,
16
]])
[
5
,
6
,
7
,
8
],
[
9
,
10
,
11
,
12
],
[
13
,
14
,
15
,
16
]])
symm_lower
=
np
.
array
(
asymm
)
symm_lower
=
np
.
array
(
asymm
)
symm_upper
=
np
.
array
(
asymm
)
symm_upper
=
np
.
array
(
asymm
)
for
i
in
range
(
4
):
for
i
in
range
(
4
):
...
@@ -607,41 +660,51 @@ def test_special_matrix_objects():
...
@@ -607,41 +660,51 @@ def test_special_matrix_objects():
def
test_dense_signature
(
doc
):
def
test_dense_signature
(
doc
):
assert
doc
(
m
.
double_col
)
==
"""
assert
(
doc
(
m
.
double_col
)
==
"""
double_col(arg0: numpy.ndarray[numpy.float32[m, 1]]) -> numpy.ndarray[numpy.float32[m, 1]]
double_col(arg0: numpy.ndarray[numpy.float32[m, 1]]) -> numpy.ndarray[numpy.float32[m, 1]]
"""
"""
assert
doc
(
m
.
double_row
)
==
"""
)
assert
(
doc
(
m
.
double_row
)
==
"""
double_row(arg0: numpy.ndarray[numpy.float32[1, n]]) -> numpy.ndarray[numpy.float32[1, n]]
double_row(arg0: numpy.ndarray[numpy.float32[1, n]]) -> numpy.ndarray[numpy.float32[1, n]]
"""
"""
assert
doc
(
m
.
double_complex
)
==
(
"""
)
assert
doc
(
m
.
double_complex
)
==
(
"""
double_complex(arg0: numpy.ndarray[numpy.complex64[m, 1]])"""
double_complex(arg0: numpy.ndarray[numpy.complex64[m, 1]])"""
""" -> numpy.ndarray[numpy.complex64[m, 1]]
""" -> numpy.ndarray[numpy.complex64[m, 1]]
"""
)
"""
assert
doc
(
m
.
double_mat_rm
)
==
(
"""
)
assert
doc
(
m
.
double_mat_rm
)
==
(
"""
double_mat_rm(arg0: numpy.ndarray[numpy.float32[m, n]])"""
double_mat_rm(arg0: numpy.ndarray[numpy.float32[m, n]])"""
""" -> numpy.ndarray[numpy.float32[m, n]]
""" -> numpy.ndarray[numpy.float32[m, n]]
"""
)
"""
)
def
test_named_arguments
():
def
test_named_arguments
():
a
=
np
.
array
([[
1.0
,
2
],
[
3
,
4
],
[
5
,
6
]])
a
=
np
.
array
([[
1.0
,
2
],
[
3
,
4
],
[
5
,
6
]])
b
=
np
.
ones
((
2
,
1
))
b
=
np
.
ones
((
2
,
1
))
assert
np
.
all
(
m
.
matrix_multiply
(
a
,
b
)
==
np
.
array
([[
3.
],
[
7
],
[
11
]]))
assert
np
.
all
(
m
.
matrix_multiply
(
a
,
b
)
==
np
.
array
([[
3.
0
],
[
7
],
[
11
]]))
assert
np
.
all
(
m
.
matrix_multiply
(
A
=
a
,
B
=
b
)
==
np
.
array
([[
3.
],
[
7
],
[
11
]]))
assert
np
.
all
(
m
.
matrix_multiply
(
A
=
a
,
B
=
b
)
==
np
.
array
([[
3.
0
],
[
7
],
[
11
]]))
assert
np
.
all
(
m
.
matrix_multiply
(
B
=
b
,
A
=
a
)
==
np
.
array
([[
3.
],
[
7
],
[
11
]]))
assert
np
.
all
(
m
.
matrix_multiply
(
B
=
b
,
A
=
a
)
==
np
.
array
([[
3.
0
],
[
7
],
[
11
]]))
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
m
.
matrix_multiply
(
b
,
a
)
m
.
matrix_multiply
(
b
,
a
)
assert
str
(
excinfo
.
value
)
==
'Nonconformable matrices!'
assert
str
(
excinfo
.
value
)
==
"Nonconformable matrices!"
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
m
.
matrix_multiply
(
A
=
b
,
B
=
a
)
m
.
matrix_multiply
(
A
=
b
,
B
=
a
)
assert
str
(
excinfo
.
value
)
==
'Nonconformable matrices!'
assert
str
(
excinfo
.
value
)
==
"Nonconformable matrices!"
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
m
.
matrix_multiply
(
B
=
a
,
A
=
b
)
m
.
matrix_multiply
(
B
=
a
,
A
=
b
)
assert
str
(
excinfo
.
value
)
==
'Nonconformable matrices!'
assert
str
(
excinfo
.
value
)
==
"Nonconformable matrices!"
def
test_sparse
():
def
test_sparse
():
...
@@ -656,21 +719,31 @@ def test_sparse():
...
@@ -656,21 +719,31 @@ def test_sparse():
def
test_sparse_signature
(
doc
):
def
test_sparse_signature
(
doc
):
pytest
.
importorskip
(
"scipy"
)
pytest
.
importorskip
(
"scipy"
)
assert
doc
(
m
.
sparse_copy_r
)
==
"""
assert
(
doc
(
m
.
sparse_copy_r
)
==
"""
sparse_copy_r(arg0: scipy.sparse.csr_matrix[numpy.float32]) -> scipy.sparse.csr_matrix[numpy.float32]
sparse_copy_r(arg0: scipy.sparse.csr_matrix[numpy.float32]) -> scipy.sparse.csr_matrix[numpy.float32]
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
assert
doc
(
m
.
sparse_copy_c
)
==
"""
)
assert
(
doc
(
m
.
sparse_copy_c
)
==
"""
sparse_copy_c(arg0: scipy.sparse.csc_matrix[numpy.float32]) -> scipy.sparse.csc_matrix[numpy.float32]
sparse_copy_c(arg0: scipy.sparse.csc_matrix[numpy.float32]) -> scipy.sparse.csc_matrix[numpy.float32]
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
def
test_issue738
():
def
test_issue738
():
"""Ignore strides on a length-1 dimension (even if they would be incompatible length > 1)"""
"""Ignore strides on a length-1 dimension (even if they would be incompatible length > 1)"""
assert
np
.
all
(
m
.
iss738_f1
(
np
.
array
([[
1.
,
2
,
3
]]))
==
np
.
array
([[
1.
,
102
,
203
]]))
assert
np
.
all
(
m
.
iss738_f1
(
np
.
array
([[
1.0
,
2
,
3
]]))
==
np
.
array
([[
1.0
,
102
,
203
]]))
assert
np
.
all
(
m
.
iss738_f1
(
np
.
array
([[
1.
],
[
2
],
[
3
]]))
==
np
.
array
([[
1.
],
[
12
],
[
23
]]))
assert
np
.
all
(
m
.
iss738_f1
(
np
.
array
([[
1.0
],
[
2
],
[
3
]]))
==
np
.
array
([[
1.0
],
[
12
],
[
23
]])
assert
np
.
all
(
m
.
iss738_f2
(
np
.
array
([[
1.
,
2
,
3
]]))
==
np
.
array
([[
1.
,
102
,
203
]]))
)
assert
np
.
all
(
m
.
iss738_f2
(
np
.
array
([[
1.
],
[
2
],
[
3
]]))
==
np
.
array
([[
1.
],
[
12
],
[
23
]]))
assert
np
.
all
(
m
.
iss738_f2
(
np
.
array
([[
1.0
,
2
,
3
]]))
==
np
.
array
([[
1.0
,
102
,
203
]]))
assert
np
.
all
(
m
.
iss738_f2
(
np
.
array
([[
1.0
],
[
2
],
[
3
]]))
==
np
.
array
([[
1.0
],
[
12
],
[
23
]])
)
def
test_issue1105
():
def
test_issue1105
():
...
...
tests/test_enum.py
View file @
c50f90ec
...
@@ -24,18 +24,24 @@ def test_unscoped_enum():
...
@@ -24,18 +24,24 @@ def test_unscoped_enum():
assert
m
.
UnscopedEnum
.
EOne
.
name
==
"EOne"
assert
m
.
UnscopedEnum
.
EOne
.
name
==
"EOne"
# __members__ property
# __members__ property
assert
m
.
UnscopedEnum
.
__members__
==
\
assert
m
.
UnscopedEnum
.
__members__
==
{
{
"EOne"
:
m
.
UnscopedEnum
.
EOne
,
"ETwo"
:
m
.
UnscopedEnum
.
ETwo
,
"EThree"
:
m
.
UnscopedEnum
.
EThree
}
"EOne"
:
m
.
UnscopedEnum
.
EOne
,
"ETwo"
:
m
.
UnscopedEnum
.
ETwo
,
"EThree"
:
m
.
UnscopedEnum
.
EThree
,
}
# __members__ readonly
# __members__ readonly
with
pytest
.
raises
(
AttributeError
):
with
pytest
.
raises
(
AttributeError
):
m
.
UnscopedEnum
.
__members__
=
{}
m
.
UnscopedEnum
.
__members__
=
{}
# __members__ returns a copy
# __members__ returns a copy
foo
=
m
.
UnscopedEnum
.
__members__
foo
=
m
.
UnscopedEnum
.
__members__
foo
[
"bar"
]
=
"baz"
foo
[
"bar"
]
=
"baz"
assert
m
.
UnscopedEnum
.
__members__
==
\
assert
m
.
UnscopedEnum
.
__members__
==
{
{
"EOne"
:
m
.
UnscopedEnum
.
EOne
,
"ETwo"
:
m
.
UnscopedEnum
.
ETwo
,
"EThree"
:
m
.
UnscopedEnum
.
EThree
}
"EOne"
:
m
.
UnscopedEnum
.
EOne
,
"ETwo"
:
m
.
UnscopedEnum
.
ETwo
,
"EThree"
:
m
.
UnscopedEnum
.
EThree
,
}
for
docstring_line
in
'''
An unscoped enumeration
for
docstring_line
in
"""
An unscoped enumeration
Members:
Members:
...
@@ -43,7 +49,9 @@ Members:
...
@@ -43,7 +49,9 @@ Members:
ETwo : Docstring for ETwo
ETwo : Docstring for ETwo
EThree : Docstring for EThree'''
.
split
(
'
\n
'
):
EThree : Docstring for EThree"""
.
split
(
"
\n
"
):
assert
docstring_line
in
m
.
UnscopedEnum
.
__doc__
assert
docstring_line
in
m
.
UnscopedEnum
.
__doc__
# Unscoped enums will accept ==/!= int comparisons
# Unscoped enums will accept ==/!= int comparisons
...
@@ -53,10 +61,10 @@ Members:
...
@@ -53,10 +61,10 @@ Members:
assert
y
!=
3
assert
y
!=
3
assert
3
!=
y
assert
3
!=
y
# Compare with None
# Compare with None
assert
(
y
!=
None
)
# noqa: E711
assert
y
!=
None
# noqa: E711
assert
not
(
y
==
None
)
# noqa: E711
assert
not
(
y
==
None
)
# noqa: E711
# Compare with an object
# Compare with an object
assert
(
y
!=
object
()
)
assert
y
!=
object
(
)
assert
not
(
y
==
object
())
assert
not
(
y
==
object
())
# Compare with string
# Compare with string
assert
y
!=
"2"
assert
y
!=
"2"
...
@@ -119,10 +127,10 @@ def test_scoped_enum():
...
@@ -119,10 +127,10 @@ def test_scoped_enum():
assert
z
!=
3
assert
z
!=
3
assert
3
!=
z
assert
3
!=
z
# Compare with None
# Compare with None
assert
(
z
!=
None
)
# noqa: E711
assert
z
!=
None
# noqa: E711
assert
not
(
z
==
None
)
# noqa: E711
assert
not
(
z
==
None
)
# noqa: E711
# Compare with an object
# Compare with an object
assert
(
z
!=
object
()
)
assert
z
!=
object
(
)
assert
not
(
z
==
object
())
assert
not
(
z
==
object
())
# Scoped enums will *NOT* accept >, <, >= and <= int comparisons (Will throw exceptions)
# Scoped enums will *NOT* accept >, <, >= and <= int comparisons (Will throw exceptions)
with
pytest
.
raises
(
TypeError
):
with
pytest
.
raises
(
TypeError
):
...
...
tests/test_eval_call.py
View file @
c50f90ec
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
# This file is called from 'test_eval.py'
# This file is called from 'test_eval.py'
if
'call_test2'
in
locals
():
if
"call_test2"
in
locals
():
call_test2
(
y
)
# noqa: F821 undefined name
call_test2
(
y
)
# noqa: F821 undefined name
tests/test_exceptions.py
View file @
c50f90ec
...
@@ -54,27 +54,27 @@ def test_python_alreadyset_in_destructor(monkeypatch, capsys):
...
@@ -54,27 +54,27 @@ def test_python_alreadyset_in_destructor(monkeypatch, capsys):
hooked
=
False
hooked
=
False
triggered
=
[
False
]
# mutable, so Python 2.7 closure can modify it
triggered
=
[
False
]
# mutable, so Python 2.7 closure can modify it
if
hasattr
(
sys
,
'unraisablehook'
):
# Python 3.8+
if
hasattr
(
sys
,
"unraisablehook"
):
# Python 3.8+
hooked
=
True
hooked
=
True
default_hook
=
sys
.
unraisablehook
default_hook
=
sys
.
unraisablehook
def
hook
(
unraisable_hook_args
):
def
hook
(
unraisable_hook_args
):
exc_type
,
exc_value
,
exc_tb
,
err_msg
,
obj
=
unraisable_hook_args
exc_type
,
exc_value
,
exc_tb
,
err_msg
,
obj
=
unraisable_hook_args
if
obj
==
'already_set demo'
:
if
obj
==
"already_set demo"
:
triggered
[
0
]
=
True
triggered
[
0
]
=
True
default_hook
(
unraisable_hook_args
)
default_hook
(
unraisable_hook_args
)
return
return
# Use monkeypatch so pytest can apply and remove the patch as appropriate
# Use monkeypatch so pytest can apply and remove the patch as appropriate
monkeypatch
.
setattr
(
sys
,
'unraisablehook'
,
hook
)
monkeypatch
.
setattr
(
sys
,
"unraisablehook"
,
hook
)
assert
m
.
python_alreadyset_in_destructor
(
'already_set demo'
)
is
True
assert
m
.
python_alreadyset_in_destructor
(
"already_set demo"
)
is
True
if
hooked
:
if
hooked
:
assert
triggered
[
0
]
is
True
assert
triggered
[
0
]
is
True
_
,
captured_stderr
=
capsys
.
readouterr
()
_
,
captured_stderr
=
capsys
.
readouterr
()
# Error message is different in Python 2 and 3, check for words that appear in both
# Error message is different in Python 2 and 3, check for words that appear in both
assert
'ignored'
in
captured_stderr
and
'already_set demo'
in
captured_stderr
assert
"ignored"
in
captured_stderr
and
"already_set demo"
in
captured_stderr
def
test_exception_matches
():
def
test_exception_matches
():
...
@@ -107,7 +107,9 @@ def test_custom(msg):
...
@@ -107,7 +107,9 @@ def test_custom(msg):
# Can we fall-through to the default handler?
# Can we fall-through to the default handler?
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
throws_logic_error
()
m
.
throws_logic_error
()
assert
msg
(
excinfo
.
value
)
==
"this error should fall through to the standard handler"
assert
(
msg
(
excinfo
.
value
)
==
"this error should fall through to the standard handler"
)
# OverFlow error translation.
# OverFlow error translation.
with
pytest
.
raises
(
OverflowError
)
as
excinfo
:
with
pytest
.
raises
(
OverflowError
)
as
excinfo
:
...
@@ -166,7 +168,13 @@ def test_nested_throws(capture):
...
@@ -166,7 +168,13 @@ def test_nested_throws(capture):
# C++ -> Python -> C++ -> Python
# C++ -> Python -> C++ -> Python
with
capture
:
with
capture
:
m
.
try_catch
(
m
.
try_catch
(
m
.
MyException5
,
pycatch
,
m
.
MyException
,
m
.
try_catch
,
m
.
MyException
,
throw_myex5
)
m
.
MyException5
,
pycatch
,
m
.
MyException
,
m
.
try_catch
,
m
.
MyException
,
throw_myex5
,
)
assert
str
(
capture
)
.
startswith
(
"MyException5: nested error 5"
)
assert
str
(
capture
)
.
startswith
(
"MyException5: nested error 5"
)
# C++ -> Python -> C++
# C++ -> Python -> C++
...
@@ -182,7 +190,6 @@ def test_nested_throws(capture):
...
@@ -182,7 +190,6 @@ def test_nested_throws(capture):
# This can often happen if you wrap a pybind11 class in a Python wrapper
# This can often happen if you wrap a pybind11 class in a Python wrapper
def
test_invalid_repr
():
def
test_invalid_repr
():
class
MyRepr
(
object
):
class
MyRepr
(
object
):
def
__repr__
(
self
):
def
__repr__
(
self
):
raise
AttributeError
(
"Example error"
)
raise
AttributeError
(
"Example error"
)
...
...
tests/test_factory_constructors.py
View file @
c50f90ec
...
@@ -12,7 +12,10 @@ from pybind11_tests import ConstructorStats
...
@@ -12,7 +12,10 @@ from pybind11_tests import ConstructorStats
def
test_init_factory_basic
():
def
test_init_factory_basic
():
"""Tests py::init_factory() wrapper around various ways of returning the object"""
"""Tests py::init_factory() wrapper around various ways of returning the object"""
cstats
=
[
ConstructorStats
.
get
(
c
)
for
c
in
[
m
.
TestFactory1
,
m
.
TestFactory2
,
m
.
TestFactory3
]]
cstats
=
[
ConstructorStats
.
get
(
c
)
for
c
in
[
m
.
TestFactory1
,
m
.
TestFactory2
,
m
.
TestFactory3
]
]
cstats
[
0
]
.
alive
()
# force gc
cstats
[
0
]
.
alive
()
# force gc
n_inst
=
ConstructorStats
.
detail_reg_inst
()
n_inst
=
ConstructorStats
.
detail_reg_inst
()
...
@@ -41,12 +44,12 @@ def test_init_factory_basic():
...
@@ -41,12 +44,12 @@ def test_init_factory_basic():
z3
=
m
.
TestFactory3
(
"bye"
)
z3
=
m
.
TestFactory3
(
"bye"
)
assert
z3
.
value
==
"bye"
assert
z3
.
value
==
"bye"
for
null_ptr_kind
in
[
tag
.
null_ptr
,
for
null_ptr_kind
in
[
tag
.
null_ptr
,
tag
.
null_unique_ptr
,
tag
.
null_shared_ptr
]:
tag
.
null_unique_ptr
,
tag
.
null_shared_ptr
]:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
TestFactory3
(
null_ptr_kind
)
m
.
TestFactory3
(
null_ptr_kind
)
assert
str
(
excinfo
.
value
)
==
"pybind11::init(): factory function returned nullptr"
assert
(
str
(
excinfo
.
value
)
==
"pybind11::init(): factory function returned nullptr"
)
assert
[
i
.
alive
()
for
i
in
cstats
]
==
[
3
,
3
,
3
]
assert
[
i
.
alive
()
for
i
in
cstats
]
==
[
3
,
3
,
3
]
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
+
9
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
+
9
...
@@ -61,7 +64,7 @@ def test_init_factory_basic():
...
@@ -61,7 +64,7 @@ def test_init_factory_basic():
assert
[
i
.
values
()
for
i
in
cstats
]
==
[
assert
[
i
.
values
()
for
i
in
cstats
]
==
[
[
"3"
,
"hi!"
],
[
"3"
,
"hi!"
],
[
"7"
,
"hi again"
],
[
"7"
,
"hi again"
],
[
"42"
,
"bye"
]
[
"42"
,
"bye"
]
,
]
]
assert
[
i
.
default_constructions
for
i
in
cstats
]
==
[
1
,
1
,
1
]
assert
[
i
.
default_constructions
for
i
in
cstats
]
==
[
1
,
1
,
1
]
...
@@ -69,7 +72,9 @@ def test_init_factory_basic():
...
@@ -69,7 +72,9 @@ def test_init_factory_basic():
def
test_init_factory_signature
(
msg
):
def
test_init_factory_signature
(
msg
):
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
TestFactory1
(
"invalid"
,
"constructor"
,
"arguments"
)
m
.
TestFactory1
(
"invalid"
,
"constructor"
,
"arguments"
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
__init__(): incompatible constructor arguments. The following argument types are supported:
__init__(): incompatible constructor arguments. The following argument types are supported:
1. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: int)
1. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: int)
2. m.factory_constructors.TestFactory1(arg0: str)
2. m.factory_constructors.TestFactory1(arg0: str)
...
@@ -78,8 +83,11 @@ def test_init_factory_signature(msg):
...
@@ -78,8 +83,11 @@ def test_init_factory_signature(msg):
Invoked with: 'invalid', 'constructor', 'arguments'
Invoked with: 'invalid', 'constructor', 'arguments'
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
assert
msg
(
m
.
TestFactory1
.
__init__
.
__doc__
)
==
"""
assert
(
msg
(
m
.
TestFactory1
.
__init__
.
__doc__
)
==
"""
__init__(*args, **kwargs)
__init__(*args, **kwargs)
Overloaded function.
Overloaded function.
...
@@ -91,12 +99,16 @@ def test_init_factory_signature(msg):
...
@@ -91,12 +99,16 @@ def test_init_factory_signature(msg):
4. __init__(self: m.factory_constructors.TestFactory1, arg0: handle, arg1: int, arg2: handle) -> None
4. __init__(self: m.factory_constructors.TestFactory1, arg0: handle, arg1: int, arg2: handle) -> None
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
def
test_init_factory_casting
():
def
test_init_factory_casting
():
"""Tests py::init_factory() wrapper with various upcasting and downcasting returns"""
"""Tests py::init_factory() wrapper with various upcasting and downcasting returns"""
cstats
=
[
ConstructorStats
.
get
(
c
)
for
c
in
[
m
.
TestFactory3
,
m
.
TestFactory4
,
m
.
TestFactory5
]]
cstats
=
[
ConstructorStats
.
get
(
c
)
for
c
in
[
m
.
TestFactory3
,
m
.
TestFactory4
,
m
.
TestFactory5
]
]
cstats
[
0
]
.
alive
()
# force gc
cstats
[
0
]
.
alive
()
# force gc
n_inst
=
ConstructorStats
.
detail_reg_inst
()
n_inst
=
ConstructorStats
.
detail_reg_inst
()
...
@@ -134,7 +146,7 @@ def test_init_factory_casting():
...
@@ -134,7 +146,7 @@ def test_init_factory_casting():
assert
[
i
.
values
()
for
i
in
cstats
]
==
[
assert
[
i
.
values
()
for
i
in
cstats
]
==
[
[
"4"
,
"5"
,
"6"
,
"7"
,
"8"
],
[
"4"
,
"5"
,
"6"
,
"7"
,
"8"
],
[
"4"
,
"5"
,
"8"
],
[
"4"
,
"5"
,
"8"
],
[
"6"
,
"7"
]
[
"6"
,
"7"
]
,
]
]
...
@@ -204,7 +216,7 @@ def test_init_factory_alias():
...
@@ -204,7 +216,7 @@ def test_init_factory_alias():
assert
[
i
.
values
()
for
i
in
cstats
]
==
[
assert
[
i
.
values
()
for
i
in
cstats
]
==
[
[
"1"
,
"8"
,
"3"
,
"4"
,
"5"
,
"6"
,
"123"
,
"10"
,
"47"
],
[
"1"
,
"8"
,
"3"
,
"4"
,
"5"
,
"6"
,
"123"
,
"10"
,
"47"
],
[
"hi there"
,
"3"
,
"4"
,
"6"
,
"move"
,
"123"
,
"why hello!"
,
"move"
,
"47"
]
[
"hi there"
,
"3"
,
"4"
,
"6"
,
"move"
,
"123"
,
"why hello!"
,
"move"
,
"47"
]
,
]
]
...
@@ -268,9 +280,11 @@ def test_init_factory_dual():
...
@@ -268,9 +280,11 @@ def test_init_factory_dual():
assert
not
g1
.
has_alias
()
assert
not
g1
.
has_alias
()
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
PythFactory7
(
tag
.
shared_ptr
,
tag
.
invalid_base
,
14
)
PythFactory7
(
tag
.
shared_ptr
,
tag
.
invalid_base
,
14
)
assert
(
str
(
excinfo
.
value
)
==
assert
(
"pybind11::init(): construction failed: returned holder-wrapped instance is not an "
str
(
excinfo
.
value
)
"alias instance"
)
==
"pybind11::init(): construction failed: returned holder-wrapped instance is not an "
"alias instance"
)
assert
[
i
.
alive
()
for
i
in
cstats
]
==
[
13
,
7
]
assert
[
i
.
alive
()
for
i
in
cstats
]
==
[
13
,
7
]
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
+
13
assert
ConstructorStats
.
detail_reg_inst
()
==
n_inst
+
13
...
@@ -284,7 +298,7 @@ def test_init_factory_dual():
...
@@ -284,7 +298,7 @@ def test_init_factory_dual():
assert
[
i
.
values
()
for
i
in
cstats
]
==
[
assert
[
i
.
values
()
for
i
in
cstats
]
==
[
[
"1"
,
"2"
,
"3"
,
"4"
,
"5"
,
"6"
,
"7"
,
"8"
,
"9"
,
"100"
,
"11"
,
"12"
,
"13"
,
"14"
],
[
"1"
,
"2"
,
"3"
,
"4"
,
"5"
,
"6"
,
"7"
,
"8"
,
"9"
,
"100"
,
"11"
,
"12"
,
"13"
,
"14"
],
[
"2"
,
"4"
,
"6"
,
"8"
,
"9"
,
"100"
,
"12"
]
[
"2"
,
"4"
,
"6"
,
"8"
,
"9"
,
"100"
,
"12"
]
,
]
]
...
@@ -294,7 +308,7 @@ def test_no_placement_new(capture):
...
@@ -294,7 +308,7 @@ def test_no_placement_new(capture):
with
capture
:
with
capture
:
a
=
m
.
NoPlacementNew
(
123
)
a
=
m
.
NoPlacementNew
(
123
)
found
=
re
.
search
(
r
'^operator new called, returning (\d+)\n$'
,
str
(
capture
))
found
=
re
.
search
(
r
"^operator new called, returning (\d+)\n$"
,
str
(
capture
))
assert
found
assert
found
assert
a
.
i
==
123
assert
a
.
i
==
123
with
capture
:
with
capture
:
...
@@ -305,7 +319,7 @@ def test_no_placement_new(capture):
...
@@ -305,7 +319,7 @@ def test_no_placement_new(capture):
with
capture
:
with
capture
:
b
=
m
.
NoPlacementNew
()
b
=
m
.
NoPlacementNew
()
found
=
re
.
search
(
r
'^operator new called, returning (\d+)\n$'
,
str
(
capture
))
found
=
re
.
search
(
r
"^operator new called, returning (\d+)\n$"
,
str
(
capture
))
assert
found
assert
found
assert
b
.
i
==
100
assert
b
.
i
==
100
with
capture
:
with
capture
:
...
@@ -333,7 +347,7 @@ def create_and_destroy(*args):
...
@@ -333,7 +347,7 @@ def create_and_destroy(*args):
def
strip_comments
(
s
):
def
strip_comments
(
s
):
return
re
.
sub
(
r
'\s+#.*'
,
''
,
s
)
return
re
.
sub
(
r
"\s+#.*"
,
""
,
s
)
def
test_reallocation_a
(
capture
,
msg
):
def
test_reallocation_a
(
capture
,
msg
):
...
@@ -345,7 +359,9 @@ def test_reallocation_a(capture, msg):
...
@@ -345,7 +359,9 @@ def test_reallocation_a(capture, msg):
with
capture
:
with
capture
:
create_and_destroy
(
1
)
create_and_destroy
(
1
)
assert
msg
(
capture
)
==
"""
assert
(
msg
(
capture
)
==
"""
noisy new
noisy new
noisy placement new
noisy placement new
NoisyAlloc(int 1)
NoisyAlloc(int 1)
...
@@ -353,12 +369,14 @@ def test_reallocation_a(capture, msg):
...
@@ -353,12 +369,14 @@ def test_reallocation_a(capture, msg):
~NoisyAlloc()
~NoisyAlloc()
noisy delete
noisy delete
"""
"""
)
def
test_reallocation_b
(
capture
,
msg
):
def
test_reallocation_b
(
capture
,
msg
):
with
capture
:
with
capture
:
create_and_destroy
(
1.5
)
create_and_destroy
(
1.5
)
assert
msg
(
capture
)
==
strip_comments
(
"""
assert
msg
(
capture
)
==
strip_comments
(
"""
noisy new # allocation required to attempt first overload
noisy new # allocation required to attempt first overload
noisy delete # have to dealloc before considering factory init overload
noisy delete # have to dealloc before considering factory init overload
noisy new # pointer factory calling "new", part 1: allocation
noisy new # pointer factory calling "new", part 1: allocation
...
@@ -366,51 +384,59 @@ def test_reallocation_b(capture, msg):
...
@@ -366,51 +384,59 @@ def test_reallocation_b(capture, msg):
---
---
~NoisyAlloc() # Destructor
~NoisyAlloc() # Destructor
noisy delete # operator delete
noisy delete # operator delete
"""
)
"""
)
def
test_reallocation_c
(
capture
,
msg
):
def
test_reallocation_c
(
capture
,
msg
):
with
capture
:
with
capture
:
create_and_destroy
(
2
,
3
)
create_and_destroy
(
2
,
3
)
assert
msg
(
capture
)
==
strip_comments
(
"""
assert
msg
(
capture
)
==
strip_comments
(
"""
noisy new # pointer factory calling "new", allocation
noisy new # pointer factory calling "new", allocation
NoisyAlloc(int 2) # constructor
NoisyAlloc(int 2) # constructor
---
---
~NoisyAlloc() # Destructor
~NoisyAlloc() # Destructor
noisy delete # operator delete
noisy delete # operator delete
"""
)
"""
)
def
test_reallocation_d
(
capture
,
msg
):
def
test_reallocation_d
(
capture
,
msg
):
with
capture
:
with
capture
:
create_and_destroy
(
2.5
,
3
)
create_and_destroy
(
2.5
,
3
)
assert
msg
(
capture
)
==
strip_comments
(
"""
assert
msg
(
capture
)
==
strip_comments
(
"""
NoisyAlloc(double 2.5) # construction (local func variable: operator_new not called)
NoisyAlloc(double 2.5) # construction (local func variable: operator_new not called)
noisy new # return-by-value "new" part 1: allocation
noisy new # return-by-value "new" part 1: allocation
~NoisyAlloc() # moved-away local func variable destruction
~NoisyAlloc() # moved-away local func variable destruction
---
---
~NoisyAlloc() # Destructor
~NoisyAlloc() # Destructor
noisy delete # operator delete
noisy delete # operator delete
"""
)
"""
)
def
test_reallocation_e
(
capture
,
msg
):
def
test_reallocation_e
(
capture
,
msg
):
with
capture
:
with
capture
:
create_and_destroy
(
3.5
,
4.5
)
create_and_destroy
(
3.5
,
4.5
)
assert
msg
(
capture
)
==
strip_comments
(
"""
assert
msg
(
capture
)
==
strip_comments
(
"""
noisy new # preallocation needed before invoking placement-new overload
noisy new # preallocation needed before invoking placement-new overload
noisy placement new # Placement new
noisy placement new # Placement new
NoisyAlloc(double 3.5) # construction
NoisyAlloc(double 3.5) # construction
---
---
~NoisyAlloc() # Destructor
~NoisyAlloc() # Destructor
noisy delete # operator delete
noisy delete # operator delete
"""
)
"""
)
def
test_reallocation_f
(
capture
,
msg
):
def
test_reallocation_f
(
capture
,
msg
):
with
capture
:
with
capture
:
create_and_destroy
(
4
,
0.5
)
create_and_destroy
(
4
,
0.5
)
assert
msg
(
capture
)
==
strip_comments
(
"""
assert
msg
(
capture
)
==
strip_comments
(
"""
noisy new # preallocation needed before invoking placement-new overload
noisy new # preallocation needed before invoking placement-new overload
noisy delete # deallocation of preallocated storage
noisy delete # deallocation of preallocated storage
noisy new # Factory pointer allocation
noisy new # Factory pointer allocation
...
@@ -418,13 +444,15 @@ def test_reallocation_f(capture, msg):
...
@@ -418,13 +444,15 @@ def test_reallocation_f(capture, msg):
---
---
~NoisyAlloc() # Destructor
~NoisyAlloc() # Destructor
noisy delete # operator delete
noisy delete # operator delete
"""
)
"""
)
def
test_reallocation_g
(
capture
,
msg
):
def
test_reallocation_g
(
capture
,
msg
):
with
capture
:
with
capture
:
create_and_destroy
(
5
,
"hi"
)
create_and_destroy
(
5
,
"hi"
)
assert
msg
(
capture
)
==
strip_comments
(
"""
assert
msg
(
capture
)
==
strip_comments
(
"""
noisy new # preallocation needed before invoking first placement new
noisy new # preallocation needed before invoking first placement new
noisy delete # delete before considering new-style constructor
noisy delete # delete before considering new-style constructor
noisy new # preallocation for second placement new
noisy new # preallocation for second placement new
...
@@ -433,13 +461,15 @@ def test_reallocation_g(capture, msg):
...
@@ -433,13 +461,15 @@ def test_reallocation_g(capture, msg):
---
---
~NoisyAlloc() # Destructor
~NoisyAlloc() # Destructor
noisy delete # operator delete
noisy delete # operator delete
"""
)
"""
)
@pytest.mark.skipif
(
"env.PY2"
)
@pytest.mark.skipif
(
"env.PY2"
)
def
test_invalid_self
():
def
test_invalid_self
():
"""Tests invocation of the pybind-registered base class with an invalid `self` argument. You
"""Tests invocation of the pybind-registered base class with an invalid `self` argument. You
can only actually do this on Python 3: Python 2 raises an exception itself if you try."""
can only actually do this on Python 3: Python 2 raises an exception itself if you try."""
class
NotPybindDerived
(
object
):
class
NotPybindDerived
(
object
):
pass
pass
...
@@ -463,16 +493,26 @@ def test_invalid_self():
...
@@ -463,16 +493,26 @@ def test_invalid_self():
a
=
m
.
TestFactory2
(
tag
.
pointer
,
1
)
a
=
m
.
TestFactory2
(
tag
.
pointer
,
1
)
m
.
TestFactory6
.
__init__
(
a
,
tag
.
alias
,
1
)
m
.
TestFactory6
.
__init__
(
a
,
tag
.
alias
,
1
)
elif
bad
==
3
:
elif
bad
==
3
:
m
.
TestFactory6
.
__init__
(
NotPybindDerived
.
__new__
(
NotPybindDerived
),
tag
.
base
,
1
)
m
.
TestFactory6
.
__init__
(
NotPybindDerived
.
__new__
(
NotPybindDerived
),
tag
.
base
,
1
)
elif
bad
==
4
:
elif
bad
==
4
:
m
.
TestFactory6
.
__init__
(
NotPybindDerived
.
__new__
(
NotPybindDerived
),
tag
.
alias
,
1
)
m
.
TestFactory6
.
__init__
(
NotPybindDerived
.
__new__
(
NotPybindDerived
),
tag
.
alias
,
1
)
for
arg
in
(
1
,
2
):
for
arg
in
(
1
,
2
):
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
BrokenTF1
(
arg
)
BrokenTF1
(
arg
)
assert
str
(
excinfo
.
value
)
==
"__init__(self, ...) called with invalid `self` argument"
assert
(
str
(
excinfo
.
value
)
==
"__init__(self, ...) called with invalid `self` argument"
)
for
arg
in
(
1
,
2
,
3
,
4
):
for
arg
in
(
1
,
2
,
3
,
4
):
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
BrokenTF6
(
arg
)
BrokenTF6
(
arg
)
assert
str
(
excinfo
.
value
)
==
"__init__(self, ...) called with invalid `self` argument"
assert
(
str
(
excinfo
.
value
)
==
"__init__(self, ...) called with invalid `self` argument"
)
tests/test_gil_scoped.py
View file @
c50f90ec
...
@@ -21,6 +21,7 @@ def _run_in_process(target, *args, **kwargs):
...
@@ -21,6 +21,7 @@ def _run_in_process(target, *args, **kwargs):
def
_python_to_cpp_to_python
():
def
_python_to_cpp_to_python
():
"""Calls different C++ functions that come back to Python."""
"""Calls different C++ functions that come back to Python."""
class
ExtendedVirtClass
(
m
.
VirtClass
):
class
ExtendedVirtClass
(
m
.
VirtClass
):
def
virtual_func
(
self
):
def
virtual_func
(
self
):
pass
pass
...
@@ -74,7 +75,9 @@ def test_python_to_cpp_to_python_from_thread_multiple_sequential():
...
@@ -74,7 +75,9 @@ def test_python_to_cpp_to_python_from_thread_multiple_sequential():
It runs in a separate process to be able to stop and assert if it deadlocks.
It runs in a separate process to be able to stop and assert if it deadlocks.
"""
"""
assert
_run_in_process
(
_python_to_cpp_to_python_from_threads
,
8
,
parallel
=
False
)
==
0
assert
(
_run_in_process
(
_python_to_cpp_to_python_from_threads
,
8
,
parallel
=
False
)
==
0
)
# TODO: FIXME on macOS Python 3.9
# TODO: FIXME on macOS Python 3.9
...
...
tests/test_iostream.py
View file @
c50f90ec
...
@@ -18,6 +18,7 @@ try:
...
@@ -18,6 +18,7 @@ try:
# Python 3.4
# Python 3.4
from
contextlib
import
redirect_stdout
from
contextlib
import
redirect_stdout
except
ImportError
:
except
ImportError
:
@contextmanager
@contextmanager
def
redirect_stdout
(
target
):
def
redirect_stdout
(
target
):
original
=
sys
.
stdout
original
=
sys
.
stdout
...
@@ -25,10 +26,12 @@ except ImportError:
...
@@ -25,10 +26,12 @@ except ImportError:
yield
yield
sys
.
stdout
=
original
sys
.
stdout
=
original
try
:
try
:
# Python 3.5
# Python 3.5
from
contextlib
import
redirect_stderr
from
contextlib
import
redirect_stderr
except
ImportError
:
except
ImportError
:
@contextmanager
@contextmanager
def
redirect_stderr
(
target
):
def
redirect_stderr
(
target
):
original
=
sys
.
stderr
original
=
sys
.
stderr
...
@@ -42,16 +45,16 @@ def test_captured(capsys):
...
@@ -42,16 +45,16 @@ def test_captured(capsys):
m
.
captured_output
(
msg
)
m
.
captured_output
(
msg
)
stdout
,
stderr
=
capsys
.
readouterr
()
stdout
,
stderr
=
capsys
.
readouterr
()
assert
stdout
==
msg
assert
stdout
==
msg
assert
stderr
==
''
assert
stderr
==
""
m
.
captured_output_default
(
msg
)
m
.
captured_output_default
(
msg
)
stdout
,
stderr
=
capsys
.
readouterr
()
stdout
,
stderr
=
capsys
.
readouterr
()
assert
stdout
==
msg
assert
stdout
==
msg
assert
stderr
==
''
assert
stderr
==
""
m
.
captured_err
(
msg
)
m
.
captured_err
(
msg
)
stdout
,
stderr
=
capsys
.
readouterr
()
stdout
,
stderr
=
capsys
.
readouterr
()
assert
stdout
==
''
assert
stdout
==
""
assert
stderr
==
msg
assert
stderr
==
msg
...
@@ -63,7 +66,7 @@ def test_captured_large_string(capsys):
...
@@ -63,7 +66,7 @@ def test_captured_large_string(capsys):
m
.
captured_output_default
(
msg
)
m
.
captured_output_default
(
msg
)
stdout
,
stderr
=
capsys
.
readouterr
()
stdout
,
stderr
=
capsys
.
readouterr
()
assert
stdout
==
msg
assert
stdout
==
msg
assert
stderr
==
''
assert
stderr
==
""
def
test_guard_capture
(
capsys
):
def
test_guard_capture
(
capsys
):
...
@@ -71,7 +74,7 @@ def test_guard_capture(capsys):
...
@@ -71,7 +74,7 @@ def test_guard_capture(capsys):
m
.
guard_output
(
msg
)
m
.
guard_output
(
msg
)
stdout
,
stderr
=
capsys
.
readouterr
()
stdout
,
stderr
=
capsys
.
readouterr
()
assert
stdout
==
msg
assert
stdout
==
msg
assert
stderr
==
''
assert
stderr
==
""
def
test_series_captured
(
capture
):
def
test_series_captured
(
capture
):
...
@@ -88,7 +91,7 @@ def test_flush(capfd):
...
@@ -88,7 +91,7 @@ def test_flush(capfd):
with
m
.
ostream_redirect
():
with
m
.
ostream_redirect
():
m
.
noisy_function
(
msg
,
flush
=
False
)
m
.
noisy_function
(
msg
,
flush
=
False
)
stdout
,
stderr
=
capfd
.
readouterr
()
stdout
,
stderr
=
capfd
.
readouterr
()
assert
stdout
==
''
assert
stdout
==
""
m
.
noisy_function
(
msg2
,
flush
=
True
)
m
.
noisy_function
(
msg2
,
flush
=
True
)
stdout
,
stderr
=
capfd
.
readouterr
()
stdout
,
stderr
=
capfd
.
readouterr
()
...
@@ -107,15 +110,15 @@ def test_not_captured(capfd):
...
@@ -107,15 +110,15 @@ def test_not_captured(capfd):
m
.
raw_output
(
msg
)
m
.
raw_output
(
msg
)
stdout
,
stderr
=
capfd
.
readouterr
()
stdout
,
stderr
=
capfd
.
readouterr
()
assert
stdout
==
msg
assert
stdout
==
msg
assert
stderr
==
''
assert
stderr
==
""
assert
stream
.
getvalue
()
==
''
assert
stream
.
getvalue
()
==
""
stream
=
StringIO
()
stream
=
StringIO
()
with
redirect_stdout
(
stream
):
with
redirect_stdout
(
stream
):
m
.
captured_output
(
msg
)
m
.
captured_output
(
msg
)
stdout
,
stderr
=
capfd
.
readouterr
()
stdout
,
stderr
=
capfd
.
readouterr
()
assert
stdout
==
''
assert
stdout
==
""
assert
stderr
==
''
assert
stderr
==
""
assert
stream
.
getvalue
()
==
msg
assert
stream
.
getvalue
()
==
msg
...
@@ -125,16 +128,16 @@ def test_err(capfd):
...
@@ -125,16 +128,16 @@ def test_err(capfd):
with
redirect_stderr
(
stream
):
with
redirect_stderr
(
stream
):
m
.
raw_err
(
msg
)
m
.
raw_err
(
msg
)
stdout
,
stderr
=
capfd
.
readouterr
()
stdout
,
stderr
=
capfd
.
readouterr
()
assert
stdout
==
''
assert
stdout
==
""
assert
stderr
==
msg
assert
stderr
==
msg
assert
stream
.
getvalue
()
==
''
assert
stream
.
getvalue
()
==
""
stream
=
StringIO
()
stream
=
StringIO
()
with
redirect_stderr
(
stream
):
with
redirect_stderr
(
stream
):
m
.
captured_err
(
msg
)
m
.
captured_err
(
msg
)
stdout
,
stderr
=
capfd
.
readouterr
()
stdout
,
stderr
=
capfd
.
readouterr
()
assert
stdout
==
''
assert
stdout
==
""
assert
stderr
==
''
assert
stderr
==
""
assert
stream
.
getvalue
()
==
msg
assert
stream
.
getvalue
()
==
msg
...
@@ -146,8 +149,8 @@ def test_multi_captured(capfd):
...
@@ -146,8 +149,8 @@ def test_multi_captured(capfd):
m
.
captured_output
(
"c"
)
m
.
captured_output
(
"c"
)
m
.
raw_output
(
"d"
)
m
.
raw_output
(
"d"
)
stdout
,
stderr
=
capfd
.
readouterr
()
stdout
,
stderr
=
capfd
.
readouterr
()
assert
stdout
==
'bd'
assert
stdout
==
"bd"
assert
stream
.
getvalue
()
==
'ac'
assert
stream
.
getvalue
()
==
"ac"
def
test_dual
(
capsys
):
def
test_dual
(
capsys
):
...
@@ -164,14 +167,14 @@ def test_redirect(capfd):
...
@@ -164,14 +167,14 @@ def test_redirect(capfd):
m
.
raw_output
(
msg
)
m
.
raw_output
(
msg
)
stdout
,
stderr
=
capfd
.
readouterr
()
stdout
,
stderr
=
capfd
.
readouterr
()
assert
stdout
==
msg
assert
stdout
==
msg
assert
stream
.
getvalue
()
==
''
assert
stream
.
getvalue
()
==
""
stream
=
StringIO
()
stream
=
StringIO
()
with
redirect_stdout
(
stream
):
with
redirect_stdout
(
stream
):
with
m
.
ostream_redirect
():
with
m
.
ostream_redirect
():
m
.
raw_output
(
msg
)
m
.
raw_output
(
msg
)
stdout
,
stderr
=
capfd
.
readouterr
()
stdout
,
stderr
=
capfd
.
readouterr
()
assert
stdout
==
''
assert
stdout
==
""
assert
stream
.
getvalue
()
==
msg
assert
stream
.
getvalue
()
==
msg
stream
=
StringIO
()
stream
=
StringIO
()
...
@@ -179,7 +182,7 @@ def test_redirect(capfd):
...
@@ -179,7 +182,7 @@ def test_redirect(capfd):
m
.
raw_output
(
msg
)
m
.
raw_output
(
msg
)
stdout
,
stderr
=
capfd
.
readouterr
()
stdout
,
stderr
=
capfd
.
readouterr
()
assert
stdout
==
msg
assert
stdout
==
msg
assert
stream
.
getvalue
()
==
''
assert
stream
.
getvalue
()
==
""
def
test_redirect_err
(
capfd
):
def
test_redirect_err
(
capfd
):
...
@@ -193,7 +196,7 @@ def test_redirect_err(capfd):
...
@@ -193,7 +196,7 @@ def test_redirect_err(capfd):
m
.
raw_err
(
msg2
)
m
.
raw_err
(
msg2
)
stdout
,
stderr
=
capfd
.
readouterr
()
stdout
,
stderr
=
capfd
.
readouterr
()
assert
stdout
==
msg
assert
stdout
==
msg
assert
stderr
==
''
assert
stderr
==
""
assert
stream
.
getvalue
()
==
msg2
assert
stream
.
getvalue
()
==
msg2
...
@@ -209,7 +212,7 @@ def test_redirect_both(capfd):
...
@@ -209,7 +212,7 @@ def test_redirect_both(capfd):
m
.
raw_output
(
msg
)
m
.
raw_output
(
msg
)
m
.
raw_err
(
msg2
)
m
.
raw_err
(
msg2
)
stdout
,
stderr
=
capfd
.
readouterr
()
stdout
,
stderr
=
capfd
.
readouterr
()
assert
stdout
==
''
assert
stdout
==
""
assert
stderr
==
''
assert
stderr
==
""
assert
stream
.
getvalue
()
==
msg
assert
stream
.
getvalue
()
==
msg
assert
stream2
.
getvalue
()
==
msg2
assert
stream2
.
getvalue
()
==
msg2
tests/test_kwargs_and_defaults.py
View file @
c50f90ec
...
@@ -15,11 +15,17 @@ def test_function_signatures(doc):
...
@@ -15,11 +15,17 @@ def test_function_signatures(doc):
assert
doc
(
m
.
kw_func_udl
)
==
"kw_func_udl(x: int, y: int = 300) -> str"
assert
doc
(
m
.
kw_func_udl
)
==
"kw_func_udl(x: int, y: int = 300) -> str"
assert
doc
(
m
.
kw_func_udl_z
)
==
"kw_func_udl_z(x: int, y: int = 0) -> str"
assert
doc
(
m
.
kw_func_udl_z
)
==
"kw_func_udl_z(x: int, y: int = 0) -> str"
assert
doc
(
m
.
args_function
)
==
"args_function(*args) -> tuple"
assert
doc
(
m
.
args_function
)
==
"args_function(*args) -> tuple"
assert
doc
(
m
.
args_kwargs_function
)
==
"args_kwargs_function(*args, **kwargs) -> tuple"
assert
(
assert
doc
(
m
.
KWClass
.
foo0
)
==
\
doc
(
m
.
args_kwargs_function
)
==
"args_kwargs_function(*args, **kwargs) -> tuple"
"foo0(self: m.kwargs_and_defaults.KWClass, arg0: int, arg1: float) -> None"
)
assert
doc
(
m
.
KWClass
.
foo1
)
==
\
assert
(
"foo1(self: m.kwargs_and_defaults.KWClass, x: int, y: float) -> None"
doc
(
m
.
KWClass
.
foo0
)
==
"foo0(self: m.kwargs_and_defaults.KWClass, arg0: int, arg1: float) -> None"
)
assert
(
doc
(
m
.
KWClass
.
foo1
)
==
"foo1(self: m.kwargs_and_defaults.KWClass, x: int, y: float) -> None"
)
def
test_named_arguments
(
msg
):
def
test_named_arguments
(
msg
):
...
@@ -40,7 +46,9 @@ def test_named_arguments(msg):
...
@@ -40,7 +46,9 @@ def test_named_arguments(msg):
# noinspection PyArgumentList
# noinspection PyArgumentList
m
.
kw_func2
(
x
=
5
,
y
=
10
,
z
=
12
)
m
.
kw_func2
(
x
=
5
,
y
=
10
,
z
=
12
)
assert
excinfo
.
match
(
assert
excinfo
.
match
(
r'(?s)^kw_func2\(\): incompatible.*Invoked with: kwargs: ((x=5|y=10|z=12)(, |$))'
+
'{3}$'
)
r"(?s)^kw_func2\(\): incompatible.*Invoked with: kwargs: ((x=5|y=10|z=12)(, |$))"
+
"{3}$"
)
assert
m
.
kw_func4
()
==
"{13 17}"
assert
m
.
kw_func4
()
==
"{13 17}"
assert
m
.
kw_func4
(
myList
=
[
1
,
2
,
3
])
==
"{1 2 3}"
assert
m
.
kw_func4
(
myList
=
[
1
,
2
,
3
])
==
"{1 2 3}"
...
@@ -50,11 +58,11 @@ def test_named_arguments(msg):
...
@@ -50,11 +58,11 @@ def test_named_arguments(msg):
def
test_arg_and_kwargs
():
def
test_arg_and_kwargs
():
args
=
'arg1_value'
,
'arg2_value'
,
3
args
=
"arg1_value"
,
"arg2_value"
,
3
assert
m
.
args_function
(
*
args
)
==
args
assert
m
.
args_function
(
*
args
)
==
args
args
=
'a1'
,
'a2'
args
=
"a1"
,
"a2"
kwargs
=
dict
(
arg3
=
'a3'
,
arg4
=
4
)
kwargs
=
dict
(
arg3
=
"a3"
,
arg4
=
4
)
assert
m
.
args_kwargs_function
(
*
args
,
**
kwargs
)
==
(
args
,
kwargs
)
assert
m
.
args_kwargs_function
(
*
args
,
**
kwargs
)
==
(
args
,
kwargs
)
...
@@ -68,47 +76,71 @@ def test_mixed_args_and_kwargs(msg):
...
@@ -68,47 +76,71 @@ def test_mixed_args_and_kwargs(msg):
assert
mpa
(
1
,
2.5
)
==
(
1
,
2.5
,
())
assert
mpa
(
1
,
2.5
)
==
(
1
,
2.5
,
())
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
assert
mpa
(
1
)
assert
mpa
(
1
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
mixed_plus_args(): incompatible function arguments. The following argument types are supported:
mixed_plus_args(): incompatible function arguments. The following argument types are supported:
1. (arg0: int, arg1: float, *args) -> tuple
1. (arg0: int, arg1: float, *args) -> tuple
Invoked with: 1
Invoked with: 1
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
assert
mpa
()
assert
mpa
()
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
mixed_plus_args(): incompatible function arguments. The following argument types are supported:
mixed_plus_args(): incompatible function arguments. The following argument types are supported:
1. (arg0: int, arg1: float, *args) -> tuple
1. (arg0: int, arg1: float, *args) -> tuple
Invoked with:
Invoked with:
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
assert
mpk
(
-
2
,
3.5
,
pi
=
3.14159
,
e
=
2.71828
)
==
(
-
2
,
3.5
,
{
'e'
:
2.71828
,
'pi'
:
3.14159
})
assert
mpk
(
-
2
,
3.5
,
pi
=
3.14159
,
e
=
2.71828
)
==
(
-
2
,
3.5
,
{
"e"
:
2.71828
,
"pi"
:
3.14159
},
)
assert
mpak
(
7
,
7.7
,
7.77
,
7.777
,
7.7777
,
minusseven
=-
7
)
==
(
assert
mpak
(
7
,
7.7
,
7.77
,
7.777
,
7.7777
,
minusseven
=-
7
)
==
(
7
,
7.7
,
(
7.77
,
7.777
,
7.7777
),
{
'minusseven'
:
-
7
})
7
,
7.7
,
(
7.77
,
7.777
,
7.7777
),
{
"minusseven"
:
-
7
},
)
assert
mpakd
()
==
(
1
,
3.14159
,
(),
{})
assert
mpakd
()
==
(
1
,
3.14159
,
(),
{})
assert
mpakd
(
3
)
==
(
3
,
3.14159
,
(),
{})
assert
mpakd
(
3
)
==
(
3
,
3.14159
,
(),
{})
assert
mpakd
(
j
=
2.71828
)
==
(
1
,
2.71828
,
(),
{})
assert
mpakd
(
j
=
2.71828
)
==
(
1
,
2.71828
,
(),
{})
assert
mpakd
(
k
=
42
)
==
(
1
,
3.14159
,
(),
{
'k'
:
42
})
assert
mpakd
(
k
=
42
)
==
(
1
,
3.14159
,
(),
{
"k"
:
42
})
assert
mpakd
(
1
,
1
,
2
,
3
,
5
,
8
,
then
=
13
,
followedby
=
21
)
==
(
assert
mpakd
(
1
,
1
,
2
,
3
,
5
,
8
,
then
=
13
,
followedby
=
21
)
==
(
1
,
1
,
(
2
,
3
,
5
,
8
),
{
'then'
:
13
,
'followedby'
:
21
})
1
,
1
,
(
2
,
3
,
5
,
8
),
{
"then"
:
13
,
"followedby"
:
21
},
)
# Arguments specified both positionally and via kwargs should fail:
# Arguments specified both positionally and via kwargs should fail:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
assert
mpakd
(
1
,
i
=
1
)
assert
mpakd
(
1
,
i
=
1
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
mixed_plus_args_kwargs_defaults(): incompatible function arguments. The following argument types are supported:
mixed_plus_args_kwargs_defaults(): incompatible function arguments. The following argument types are supported:
1. (i: int = 1, j: float = 3.14159, *args, **kwargs) -> tuple
1. (i: int = 1, j: float = 3.14159, *args, **kwargs) -> tuple
Invoked with: 1; kwargs: i=1
Invoked with: 1; kwargs: i=1
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
assert
mpakd
(
1
,
2
,
j
=
1
)
assert
mpakd
(
1
,
2
,
j
=
1
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
mixed_plus_args_kwargs_defaults(): incompatible function arguments. The following argument types are supported:
mixed_plus_args_kwargs_defaults(): incompatible function arguments. The following argument types are supported:
1. (i: int = 1, j: float = 3.14159, *args, **kwargs) -> tuple
1. (i: int = 1, j: float = 3.14159, *args, **kwargs) -> tuple
Invoked with: 1, 2; kwargs: j=1
Invoked with: 1, 2; kwargs: j=1
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
def
test_keyword_only_args
(
msg
):
def
test_keyword_only_args
(
msg
):
...
@@ -134,9 +166,9 @@ def test_keyword_only_args(msg):
...
@@ -134,9 +166,9 @@ def test_keyword_only_args(msg):
assert
m
.
kw_only_mixed
(
j
=
2
,
i
=
3
)
==
(
3
,
2
)
assert
m
.
kw_only_mixed
(
j
=
2
,
i
=
3
)
==
(
3
,
2
)
assert
m
.
kw_only_mixed
(
i
=
2
,
j
=
3
)
==
(
2
,
3
)
assert
m
.
kw_only_mixed
(
i
=
2
,
j
=
3
)
==
(
2
,
3
)
assert
m
.
kw_only_plus_more
(
4
,
5
,
k
=
6
,
extra
=
7
)
==
(
4
,
5
,
6
,
{
'extra'
:
7
})
assert
m
.
kw_only_plus_more
(
4
,
5
,
k
=
6
,
extra
=
7
)
==
(
4
,
5
,
6
,
{
"extra"
:
7
})
assert
m
.
kw_only_plus_more
(
3
,
k
=
5
,
j
=
4
,
extra
=
6
)
==
(
3
,
4
,
5
,
{
'extra'
:
6
})
assert
m
.
kw_only_plus_more
(
3
,
k
=
5
,
j
=
4
,
extra
=
6
)
==
(
3
,
4
,
5
,
{
"extra"
:
6
})
assert
m
.
kw_only_plus_more
(
2
,
k
=
3
,
extra
=
4
)
==
(
2
,
-
1
,
3
,
{
'extra'
:
4
})
assert
m
.
kw_only_plus_more
(
2
,
k
=
3
,
extra
=
4
)
==
(
2
,
-
1
,
3
,
{
"extra"
:
4
})
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
assert
m
.
kw_only_mixed
(
i
=
1
)
==
(
1
,)
assert
m
.
kw_only_mixed
(
i
=
1
)
==
(
1
,)
...
@@ -144,9 +176,12 @@ def test_keyword_only_args(msg):
...
@@ -144,9 +176,12 @@ def test_keyword_only_args(msg):
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
register_invalid_kw_only
(
m
)
m
.
register_invalid_kw_only
(
m
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
arg(): cannot specify an unnamed argument after an kw_only() annotation
arg(): cannot specify an unnamed argument after an kw_only() annotation
"""
"""
)
def
test_positional_only_args
(
msg
):
def
test_positional_only_args
(
msg
):
...
@@ -194,7 +229,10 @@ def test_signatures():
...
@@ -194,7 +229,10 @@ def test_signatures():
assert
"kw_only_mixed(i: int, *, j: int) -> tuple
\n
"
==
m
.
kw_only_mixed
.
__doc__
assert
"kw_only_mixed(i: int, *, j: int) -> tuple
\n
"
==
m
.
kw_only_mixed
.
__doc__
assert
"pos_only_all(i: int, j: int, /) -> tuple
\n
"
==
m
.
pos_only_all
.
__doc__
assert
"pos_only_all(i: int, j: int, /) -> tuple
\n
"
==
m
.
pos_only_all
.
__doc__
assert
"pos_only_mix(i: int, /, j: int) -> tuple
\n
"
==
m
.
pos_only_mix
.
__doc__
assert
"pos_only_mix(i: int, /, j: int) -> tuple
\n
"
==
m
.
pos_only_mix
.
__doc__
assert
"pos_kw_only_mix(i: int, /, j: int, *, k: int) -> tuple
\n
"
==
m
.
pos_kw_only_mix
.
__doc__
assert
(
"pos_kw_only_mix(i: int, /, j: int, *, k: int) -> tuple
\n
"
==
m
.
pos_kw_only_mix
.
__doc__
)
@pytest.mark.xfail
(
"env.PYPY and env.PY2"
,
reason
=
"PyPy2 doesn't double count"
)
@pytest.mark.xfail
(
"env.PYPY and env.PY2"
,
reason
=
"PyPy2 doesn't double count"
)
...
@@ -219,11 +257,18 @@ def test_args_refcount():
...
@@ -219,11 +257,18 @@ def test_args_refcount():
assert
m
.
args_function
(
-
1
,
myval
)
==
(
-
1
,
myval
)
assert
m
.
args_function
(
-
1
,
myval
)
==
(
-
1
,
myval
)
assert
refcount
(
myval
)
==
expected
assert
refcount
(
myval
)
==
expected
assert
m
.
mixed_plus_args_kwargs
(
5
,
6.0
,
myval
,
a
=
myval
)
==
(
5
,
6.0
,
(
myval
,),
{
"a"
:
myval
})
assert
m
.
mixed_plus_args_kwargs
(
5
,
6.0
,
myval
,
a
=
myval
)
==
(
5
,
6.0
,
(
myval
,),
{
"a"
:
myval
},
)
assert
refcount
(
myval
)
==
expected
assert
refcount
(
myval
)
==
expected
assert
m
.
args_kwargs_function
(
7
,
8
,
myval
,
a
=
1
,
b
=
myval
)
==
\
assert
m
.
args_kwargs_function
(
7
,
8
,
myval
,
a
=
1
,
b
=
myval
)
==
(
((
7
,
8
,
myval
),
{
"a"
:
1
,
"b"
:
myval
})
(
7
,
8
,
myval
),
{
"a"
:
1
,
"b"
:
myval
},
)
assert
refcount
(
myval
)
==
expected
assert
refcount
(
myval
)
==
expected
exp3
=
refcount
(
myval
,
myval
,
myval
)
exp3
=
refcount
(
myval
,
myval
,
myval
)
...
...
tests/test_local_bindings.py
View file @
c50f90ec
...
@@ -36,8 +36,8 @@ def test_local_bindings():
...
@@ -36,8 +36,8 @@ def test_local_bindings():
assert
i2
.
get
()
==
11
assert
i2
.
get
()
==
11
assert
i2
.
get2
()
==
12
assert
i2
.
get2
()
==
12
assert
not
hasattr
(
i1
,
'get2'
)
assert
not
hasattr
(
i1
,
"get2"
)
assert
not
hasattr
(
i2
,
'get3'
)
assert
not
hasattr
(
i2
,
"get3"
)
# Loading within the local module
# Loading within the local module
assert
m
.
local_value
(
i1
)
==
5
assert
m
.
local_value
(
i1
)
==
5
...
@@ -55,7 +55,9 @@ def test_nonlocal_failure():
...
@@ -55,7 +55,9 @@ def test_nonlocal_failure():
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
cm
.
register_nonlocal
()
cm
.
register_nonlocal
()
assert
str
(
excinfo
.
value
)
==
'generic_type: type "NonLocalType" is already registered!'
assert
(
str
(
excinfo
.
value
)
==
'generic_type: type "NonLocalType" is already registered!'
)
def
test_duplicate_local
():
def
test_duplicate_local
():
...
@@ -63,9 +65,12 @@ def test_duplicate_local():
...
@@ -63,9 +65,12 @@ def test_duplicate_local():
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
register_local_external
()
m
.
register_local_external
()
import
pybind11_tests
import
pybind11_tests
assert
str
(
excinfo
.
value
)
==
(
assert
str
(
excinfo
.
value
)
==
(
'generic_type: type "LocalExternal" is already registered!'
'generic_type: type "LocalExternal" is already registered!'
if
hasattr
(
pybind11_tests
,
'class_'
)
else
'test_class not enabled'
)
if
hasattr
(
pybind11_tests
,
"class_"
)
else
"test_class not enabled"
)
def
test_stl_bind_local
():
def
test_stl_bind_local
():
...
@@ -98,8 +103,8 @@ def test_stl_bind_local():
...
@@ -98,8 +103,8 @@ def test_stl_bind_local():
d1
[
"b"
]
=
v1
[
1
]
d1
[
"b"
]
=
v1
[
1
]
d2
[
"c"
]
=
v2
[
0
]
d2
[
"c"
]
=
v2
[
0
]
d2
[
"d"
]
=
v2
[
1
]
d2
[
"d"
]
=
v2
[
1
]
assert
{
i
:
d1
[
i
]
.
get
()
for
i
in
d1
}
==
{
'a'
:
0
,
'b'
:
1
}
assert
{
i
:
d1
[
i
]
.
get
()
for
i
in
d1
}
==
{
"a"
:
0
,
"b"
:
1
}
assert
{
i
:
d2
[
i
]
.
get
()
for
i
in
d2
}
==
{
'c'
:
2
,
'd'
:
3
}
assert
{
i
:
d2
[
i
]
.
get
()
for
i
in
d2
}
==
{
"c"
:
2
,
"d"
:
3
}
def
test_stl_bind_global
():
def
test_stl_bind_global
():
...
@@ -107,15 +112,21 @@ def test_stl_bind_global():
...
@@ -107,15 +112,21 @@ def test_stl_bind_global():
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
cm
.
register_nonlocal_map
()
cm
.
register_nonlocal_map
()
assert
str
(
excinfo
.
value
)
==
'generic_type: type "NonLocalMap" is already registered!'
assert
(
str
(
excinfo
.
value
)
==
'generic_type: type "NonLocalMap" is already registered!'
)
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
cm
.
register_nonlocal_vec
()
cm
.
register_nonlocal_vec
()
assert
str
(
excinfo
.
value
)
==
'generic_type: type "NonLocalVec" is already registered!'
assert
(
str
(
excinfo
.
value
)
==
'generic_type: type "NonLocalVec" is already registered!'
)
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
cm
.
register_nonlocal_map2
()
cm
.
register_nonlocal_map2
()
assert
str
(
excinfo
.
value
)
==
'generic_type: type "NonLocalMap2" is already registered!'
assert
(
str
(
excinfo
.
value
)
==
'generic_type: type "NonLocalMap2" is already registered!'
)
def
test_mixed_local_global
():
def
test_mixed_local_global
():
...
@@ -123,6 +134,7 @@ def test_mixed_local_global():
...
@@ -123,6 +134,7 @@ def test_mixed_local_global():
type can be registered even if the type is already registered globally. With the module,
type can be registered even if the type is already registered globally. With the module,
casting will go to the local type; outside the module casting goes to the global type."""
casting will go to the local type; outside the module casting goes to the global type."""
import
pybind11_cross_module_tests
as
cm
import
pybind11_cross_module_tests
as
cm
m
.
register_mixed_global
()
m
.
register_mixed_global
()
m
.
register_mixed_local
()
m
.
register_mixed_local
()
...
@@ -145,13 +157,26 @@ def test_mixed_local_global():
...
@@ -145,13 +157,26 @@ def test_mixed_local_global():
a
.
append
(
cm
.
get_mixed_gl
(
11
))
a
.
append
(
cm
.
get_mixed_gl
(
11
))
a
.
append
(
cm
.
get_mixed_lg
(
12
))
a
.
append
(
cm
.
get_mixed_lg
(
12
))
assert
[
x
.
get
()
for
x
in
a
]
==
\
assert
[
x
.
get
()
for
x
in
a
]
==
[
[
101
,
1002
,
103
,
1004
,
105
,
1006
,
207
,
2008
,
109
,
1010
,
211
,
2012
]
101
,
1002
,
103
,
1004
,
105
,
1006
,
207
,
2008
,
109
,
1010
,
211
,
2012
,
]
def
test_internal_locals_differ
():
def
test_internal_locals_differ
():
"""Makes sure the internal local type map differs across the two modules"""
"""Makes sure the internal local type map differs across the two modules"""
import
pybind11_cross_module_tests
as
cm
import
pybind11_cross_module_tests
as
cm
assert
m
.
local_cpp_types_addr
()
!=
cm
.
local_cpp_types_addr
()
assert
m
.
local_cpp_types_addr
()
!=
cm
.
local_cpp_types_addr
()
...
@@ -169,12 +194,15 @@ def test_stl_caster_vs_stl_bind(msg):
...
@@ -169,12 +194,15 @@ def test_stl_caster_vs_stl_bind(msg):
assert
m
.
load_vector_via_caster
(
v2
)
==
6
assert
m
.
load_vector_via_caster
(
v2
)
==
6
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
cm
.
load_vector_via_binding
(
v2
)
==
6
cm
.
load_vector_via_binding
(
v2
)
==
6
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
load_vector_via_binding(): incompatible function arguments. The following argument types are supported:
load_vector_via_binding(): incompatible function arguments. The following argument types are supported:
1. (arg0: pybind11_cross_module_tests.VectorInt) -> int
1. (arg0: pybind11_cross_module_tests.VectorInt) -> int
Invoked with: [1, 2, 3]
Invoked with: [1, 2, 3]
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
def
test_cross_module_calls
():
def
test_cross_module_calls
():
...
...
tests/test_methods_and_attributes.py
View file @
c50f90ec
...
@@ -40,17 +40,17 @@ def test_methods_and_attributes():
...
@@ -40,17 +40,17 @@ def test_methods_and_attributes():
assert
instance1
.
overloaded
(
0
)
==
"(int)"
assert
instance1
.
overloaded
(
0
)
==
"(int)"
assert
instance1
.
overloaded
(
1
,
1.0
)
==
"(int, float)"
assert
instance1
.
overloaded
(
1
,
1.0
)
==
"(int, float)"
assert
instance1
.
overloaded
(
2.0
,
2
)
==
"(float, int)"
assert
instance1
.
overloaded
(
2.0
,
2
)
==
"(float, int)"
assert
instance1
.
overloaded
(
3
,
3
)
==
"(int, int)"
assert
instance1
.
overloaded
(
3
,
3
)
==
"(int, int)"
assert
instance1
.
overloaded
(
4.
,
4.
)
==
"(float, float)"
assert
instance1
.
overloaded
(
4.
0
,
4.0
)
==
"(float, float)"
assert
instance1
.
overloaded_const
(
-
3
)
==
"(int) const"
assert
instance1
.
overloaded_const
(
-
3
)
==
"(int) const"
assert
instance1
.
overloaded_const
(
5
,
5.0
)
==
"(int, float) const"
assert
instance1
.
overloaded_const
(
5
,
5.0
)
==
"(int, float) const"
assert
instance1
.
overloaded_const
(
6.0
,
6
)
==
"(float, int) const"
assert
instance1
.
overloaded_const
(
6.0
,
6
)
==
"(float, int) const"
assert
instance1
.
overloaded_const
(
7
,
7
)
==
"(int, int) const"
assert
instance1
.
overloaded_const
(
7
,
7
)
==
"(int, int) const"
assert
instance1
.
overloaded_const
(
8.
,
8.
)
==
"(float, float) const"
assert
instance1
.
overloaded_const
(
8.
0
,
8.0
)
==
"(float, float) const"
assert
instance1
.
overloaded_float
(
1
,
1
)
==
"(float, float)"
assert
instance1
.
overloaded_float
(
1
,
1
)
==
"(float, float)"
assert
instance1
.
overloaded_float
(
1
,
1.
)
==
"(float, float)"
assert
instance1
.
overloaded_float
(
1
,
1.
0
)
==
"(float, float)"
assert
instance1
.
overloaded_float
(
1.
,
1
)
==
"(float, float)"
assert
instance1
.
overloaded_float
(
1.
0
,
1
)
==
"(float, float)"
assert
instance1
.
overloaded_float
(
1.
,
1.
)
==
"(float, float)"
assert
instance1
.
overloaded_float
(
1.
0
,
1.0
)
==
"(float, float)"
assert
instance1
.
value
==
320
assert
instance1
.
value
==
320
instance1
.
value
=
100
instance1
.
value
=
100
...
@@ -193,7 +193,10 @@ def test_metaclass_override():
...
@@ -193,7 +193,10 @@ def test_metaclass_override():
assert
type
(
m
.
MetaclassOverride
)
.
__name__
==
"type"
assert
type
(
m
.
MetaclassOverride
)
.
__name__
==
"type"
assert
m
.
MetaclassOverride
.
readonly
==
1
assert
m
.
MetaclassOverride
.
readonly
==
1
assert
type
(
m
.
MetaclassOverride
.
__dict__
[
"readonly"
])
.
__name__
==
"pybind11_static_property"
assert
(
type
(
m
.
MetaclassOverride
.
__dict__
[
"readonly"
])
.
__name__
==
"pybind11_static_property"
)
# Regular `type` replaces the property instead of calling `__set__()`
# Regular `type` replaces the property instead of calling `__set__()`
m
.
MetaclassOverride
.
readonly
=
2
m
.
MetaclassOverride
.
readonly
=
2
...
@@ -206,22 +209,26 @@ def test_no_mixed_overloads():
...
@@ -206,22 +209,26 @@ def test_no_mixed_overloads():
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
ExampleMandA
.
add_mixed_overloads1
()
m
.
ExampleMandA
.
add_mixed_overloads1
()
assert
(
str
(
excinfo
.
value
)
==
assert
str
(
"overloading a method with both static and instance methods is not supported; "
+
excinfo
.
value
(
"compile in debug mode for more details"
if
not
debug_enabled
else
)
==
"overloading a method with both static and instance methods is not supported; "
+
(
"error while attempting to bind static method ExampleMandA.overload_mixed1"
"compile in debug mode for more details"
"(arg0: float) -> str"
)
if
not
debug_enabled
)
else
"error while attempting to bind static method ExampleMandA.overload_mixed1"
"(arg0: float) -> str"
)
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
ExampleMandA
.
add_mixed_overloads2
()
m
.
ExampleMandA
.
add_mixed_overloads2
()
assert
(
str
(
excinfo
.
value
)
==
assert
str
(
"overloading a method with both static and instance methods is not supported; "
+
excinfo
.
value
(
"compile in debug mode for more details"
if
not
debug_enabled
else
)
==
"overloading a method with both static and instance methods is not supported; "
+
(
"error while attempting to bind instance method ExampleMandA.overload_mixed2"
"compile in debug mode for more details"
"(self: pybind11_tests.methods_and_attributes.ExampleMandA, arg0: int, arg1: int)"
if
not
debug_enabled
" -> str"
)
else
"error while attempting to bind instance method ExampleMandA.overload_mixed2"
)
"(self: pybind11_tests.methods_and_attributes.ExampleMandA, arg0: int, arg1: int)"
" -> str"
)
@pytest.mark.parametrize
(
"access"
,
[
"ro"
,
"rw"
,
"static_ro"
,
"static_rw"
])
@pytest.mark.parametrize
(
"access"
,
[
"ro"
,
"rw"
,
"static_ro"
,
"static_rw"
])
...
@@ -333,8 +340,8 @@ def test_bad_arg_default(msg):
...
@@ -333,8 +340,8 @@ def test_bad_arg_default(msg):
assert
msg
(
excinfo
.
value
)
==
(
assert
msg
(
excinfo
.
value
)
==
(
"arg(): could not convert default argument 'a: UnregisteredType' in function "
"arg(): could not convert default argument 'a: UnregisteredType' in function "
"'should_fail' into a Python object (type not registered yet?)"
"'should_fail' into a Python object (type not registered yet?)"
if
debug_enabled
else
if
debug_enabled
"arg(): could not convert default argument into a Python object (type not registered "
else
"arg(): could not convert default argument into a Python object (type not registered "
"yet?). Compile in debug mode for more information."
"yet?). Compile in debug mode for more information."
)
)
...
@@ -343,8 +350,8 @@ def test_bad_arg_default(msg):
...
@@ -343,8 +350,8 @@ def test_bad_arg_default(msg):
assert
msg
(
excinfo
.
value
)
==
(
assert
msg
(
excinfo
.
value
)
==
(
"arg(): could not convert default argument 'UnregisteredType' in function "
"arg(): could not convert default argument 'UnregisteredType' in function "
"'should_fail' into a Python object (type not registered yet?)"
"'should_fail' into a Python object (type not registered yet?)"
if
debug_enabled
else
if
debug_enabled
"arg(): could not convert default argument into a Python object (type not registered "
else
"arg(): could not convert default argument into a Python object (type not registered "
"yet?). Compile in debug mode for more information."
"yet?). Compile in debug mode for more information."
)
)
...
@@ -381,12 +388,15 @@ def test_accepts_none(msg):
...
@@ -381,12 +388,15 @@ def test_accepts_none(msg):
# The first one still raises because you can't pass None as a lvalue reference arg:
# The first one still raises because you can't pass None as a lvalue reference arg:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
assert
m
.
ok_none1
(
None
)
==
-
1
assert
m
.
ok_none1
(
None
)
==
-
1
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
ok_none1(): incompatible function arguments. The following argument types are supported:
ok_none1(): incompatible function arguments. The following argument types are supported:
1. (arg0: m.methods_and_attributes.NoneTester) -> int
1. (arg0: m.methods_and_attributes.NoneTester) -> int
Invoked with: None
Invoked with: None
"""
"""
)
# The rest take the argument as pointer or holder, and accept None:
# The rest take the argument as pointer or holder, and accept None:
assert
m
.
ok_none2
(
None
)
==
-
1
assert
m
.
ok_none2
(
None
)
==
-
1
...
@@ -402,13 +412,16 @@ def test_str_issue(msg):
...
@@ -402,13 +412,16 @@ def test_str_issue(msg):
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
str
(
m
.
StrIssue
(
"no"
,
"such"
,
"constructor"
))
str
(
m
.
StrIssue
(
"no"
,
"such"
,
"constructor"
))
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
__init__(): incompatible constructor arguments. The following argument types are supported:
__init__(): incompatible constructor arguments. The following argument types are supported:
1. m.methods_and_attributes.StrIssue(arg0: int)
1. m.methods_and_attributes.StrIssue(arg0: int)
2. m.methods_and_attributes.StrIssue()
2. m.methods_and_attributes.StrIssue()
Invoked with: 'no', 'such', 'constructor'
Invoked with: 'no', 'such', 'constructor'
"""
"""
)
def
test_unregistered_base_implementations
():
def
test_unregistered_base_implementations
():
...
@@ -441,7 +454,7 @@ def test_ref_qualified():
...
@@ -441,7 +454,7 @@ def test_ref_qualified():
def
test_overload_ordering
():
def
test_overload_ordering
():
'Check to see if the normal overload order (first defined) and prepend overload order works'
"Check to see if the normal overload order (first defined) and prepend overload order works"
assert
m
.
overload_order
(
"string"
)
==
1
assert
m
.
overload_order
(
"string"
)
==
1
assert
m
.
overload_order
(
0
)
==
4
assert
m
.
overload_order
(
0
)
==
4
...
@@ -449,8 +462,14 @@ def test_overload_ordering():
...
@@ -449,8 +462,14 @@ def test_overload_ordering():
uni_name
=
type
(
u""
)
.
__name__
uni_name
=
type
(
u""
)
.
__name__
assert
"1. overload_order(arg0: int) -> int"
in
m
.
overload_order
.
__doc__
assert
"1. overload_order(arg0: int) -> int"
in
m
.
overload_order
.
__doc__
assert
"2. overload_order(arg0: {}) -> int"
.
format
(
uni_name
)
in
m
.
overload_order
.
__doc__
assert
(
assert
"3. overload_order(arg0: {}) -> int"
.
format
(
uni_name
)
in
m
.
overload_order
.
__doc__
"2. overload_order(arg0: {}) -> int"
.
format
(
uni_name
)
in
m
.
overload_order
.
__doc__
)
assert
(
"3. overload_order(arg0: {}) -> int"
.
format
(
uni_name
)
in
m
.
overload_order
.
__doc__
)
assert
"4. overload_order(arg0: int) -> int"
in
m
.
overload_order
.
__doc__
assert
"4. overload_order(arg0: int) -> int"
in
m
.
overload_order
.
__doc__
with
pytest
.
raises
(
TypeError
)
as
err
:
with
pytest
.
raises
(
TypeError
)
as
err
:
...
...
tests/test_modules.py
View file @
c50f90ec
...
@@ -6,9 +6,13 @@ from pybind11_tests import ConstructorStats
...
@@ -6,9 +6,13 @@ from pybind11_tests import ConstructorStats
def
test_nested_modules
():
def
test_nested_modules
():
import
pybind11_tests
import
pybind11_tests
assert
pybind11_tests
.
__name__
==
"pybind11_tests"
assert
pybind11_tests
.
__name__
==
"pybind11_tests"
assert
pybind11_tests
.
modules
.
__name__
==
"pybind11_tests.modules"
assert
pybind11_tests
.
modules
.
__name__
==
"pybind11_tests.modules"
assert
pybind11_tests
.
modules
.
subsubmodule
.
__name__
==
"pybind11_tests.modules.subsubmodule"
assert
(
pybind11_tests
.
modules
.
subsubmodule
.
__name__
==
"pybind11_tests.modules.subsubmodule"
)
assert
m
.
__name__
==
"pybind11_tests.modules"
assert
m
.
__name__
==
"pybind11_tests.modules"
assert
ms
.
__name__
==
"pybind11_tests.modules.subsubmodule"
assert
ms
.
__name__
==
"pybind11_tests.modules.subsubmodule"
...
@@ -35,7 +39,7 @@ def test_reference_internal():
...
@@ -35,7 +39,7 @@ def test_reference_internal():
del
b
del
b
assert
astats
.
alive
()
==
0
assert
astats
.
alive
()
==
0
assert
bstats
.
alive
()
==
0
assert
bstats
.
alive
()
==
0
assert
astats
.
values
()
==
[
'1'
,
'2'
,
'42'
,
'43'
]
assert
astats
.
values
()
==
[
"1"
,
"2"
,
"42"
,
"43"
]
assert
bstats
.
values
()
==
[]
assert
bstats
.
values
()
==
[]
assert
astats
.
default_constructions
==
0
assert
astats
.
default_constructions
==
0
assert
bstats
.
default_constructions
==
1
assert
bstats
.
default_constructions
==
1
...
@@ -54,7 +58,7 @@ def test_importing():
...
@@ -54,7 +58,7 @@ def test_importing():
from
collections
import
OrderedDict
from
collections
import
OrderedDict
assert
OD
is
OrderedDict
assert
OD
is
OrderedDict
assert
str
(
OD
([(
1
,
'a'
),
(
2
,
'b'
)]))
==
"OrderedDict([(1, 'a'), (2, 'b')])"
assert
str
(
OD
([(
1
,
"a"
),
(
2
,
"b"
)]))
==
"OrderedDict([(1, 'a'), (2, 'b')])"
def
test_pydoc
():
def
test_pydoc
():
...
...
tests/test_multiple_inheritance.py
View file @
c50f90ec
...
@@ -57,7 +57,6 @@ def test_multiple_inheritance_mix2():
...
@@ -57,7 +57,6 @@ def test_multiple_inheritance_mix2():
@pytest.mark.skipif
(
"env.PYPY and env.PY2"
)
@pytest.mark.skipif
(
"env.PYPY and env.PY2"
)
@pytest.mark.xfail
(
"env.PYPY and not env.PY2"
)
@pytest.mark.xfail
(
"env.PYPY and not env.PY2"
)
def
test_multiple_inheritance_python
():
def
test_multiple_inheritance_python
():
class
MI1
(
m
.
Base1
,
m
.
Base2
):
class
MI1
(
m
.
Base1
,
m
.
Base2
):
def
__init__
(
self
,
i
,
j
):
def
__init__
(
self
,
i
,
j
):
m
.
Base1
.
__init__
(
self
,
i
)
m
.
Base1
.
__init__
(
self
,
i
)
...
@@ -163,7 +162,6 @@ def test_multiple_inheritance_python():
...
@@ -163,7 +162,6 @@ def test_multiple_inheritance_python():
def
test_multiple_inheritance_python_many_bases
():
def
test_multiple_inheritance_python_many_bases
():
class
MIMany14
(
m
.
BaseN1
,
m
.
BaseN2
,
m
.
BaseN3
,
m
.
BaseN4
):
class
MIMany14
(
m
.
BaseN1
,
m
.
BaseN2
,
m
.
BaseN3
,
m
.
BaseN4
):
def
__init__
(
self
):
def
__init__
(
self
):
m
.
BaseN1
.
__init__
(
self
,
1
)
m
.
BaseN1
.
__init__
(
self
,
1
)
...
@@ -178,8 +176,16 @@ def test_multiple_inheritance_python_many_bases():
...
@@ -178,8 +176,16 @@ def test_multiple_inheritance_python_many_bases():
m
.
BaseN7
.
__init__
(
self
,
7
)
m
.
BaseN7
.
__init__
(
self
,
7
)
m
.
BaseN8
.
__init__
(
self
,
8
)
m
.
BaseN8
.
__init__
(
self
,
8
)
class
MIMany916
(
m
.
BaseN9
,
m
.
BaseN10
,
m
.
BaseN11
,
m
.
BaseN12
,
m
.
BaseN13
,
m
.
BaseN14
,
m
.
BaseN15
,
class
MIMany916
(
m
.
BaseN16
):
m
.
BaseN9
,
m
.
BaseN10
,
m
.
BaseN11
,
m
.
BaseN12
,
m
.
BaseN13
,
m
.
BaseN14
,
m
.
BaseN15
,
m
.
BaseN16
,
):
def
__init__
(
self
):
def
__init__
(
self
):
m
.
BaseN9
.
__init__
(
self
,
9
)
m
.
BaseN9
.
__init__
(
self
,
9
)
m
.
BaseN10
.
__init__
(
self
,
10
)
m
.
BaseN10
.
__init__
(
self
,
10
)
...
@@ -225,7 +231,6 @@ def test_multiple_inheritance_python_many_bases():
...
@@ -225,7 +231,6 @@ def test_multiple_inheritance_python_many_bases():
def
test_multiple_inheritance_virtbase
():
def
test_multiple_inheritance_virtbase
():
class
MITypePy
(
m
.
Base12a
):
class
MITypePy
(
m
.
Base12a
):
def
__init__
(
self
,
i
,
j
):
def
__init__
(
self
,
i
,
j
):
m
.
Base12a
.
__init__
(
self
,
i
,
j
)
m
.
Base12a
.
__init__
(
self
,
i
,
j
)
...
@@ -238,7 +243,7 @@ def test_multiple_inheritance_virtbase():
...
@@ -238,7 +243,7 @@ def test_multiple_inheritance_virtbase():
def
test_mi_static_properties
():
def
test_mi_static_properties
():
"""Mixing bases with and without static properties should be possible
"""Mixing bases with and without static properties should be possible
and the result should be independent of base definition order"""
and the result should be independent of base definition order"""
for
d
in
(
m
.
VanillaStaticMix1
(),
m
.
VanillaStaticMix2
()):
for
d
in
(
m
.
VanillaStaticMix1
(),
m
.
VanillaStaticMix2
()):
assert
d
.
vanilla
()
==
"Vanilla"
assert
d
.
vanilla
()
==
"Vanilla"
...
...
tests/test_numpy_array.py
View file @
c50f90ec
...
@@ -19,33 +19,36 @@ def test_dtypes():
...
@@ -19,33 +19,36 @@ def test_dtypes():
print
(
check
)
print
(
check
)
assert
check
.
numpy
==
check
.
pybind11
,
check
assert
check
.
numpy
==
check
.
pybind11
,
check
if
check
.
numpy
.
num
!=
check
.
pybind11
.
num
:
if
check
.
numpy
.
num
!=
check
.
pybind11
.
num
:
print
(
"NOTE: typenum mismatch for {}: {} != {}"
.
format
(
print
(
check
,
check
.
numpy
.
num
,
check
.
pybind11
.
num
))
"NOTE: typenum mismatch for {}: {} != {}"
.
format
(
check
,
check
.
numpy
.
num
,
check
.
pybind11
.
num
)
)
@pytest.fixture
(
scope
=
'function'
)
@pytest.fixture
(
scope
=
"function"
)
def
arr
():
def
arr
():
return
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]],
'=u2'
)
return
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]],
"=u2"
)
def
test_array_attributes
():
def
test_array_attributes
():
a
=
np
.
array
(
0
,
'f8'
)
a
=
np
.
array
(
0
,
"f8"
)
assert
m
.
ndim
(
a
)
==
0
assert
m
.
ndim
(
a
)
==
0
assert
all
(
m
.
shape
(
a
)
==
[])
assert
all
(
m
.
shape
(
a
)
==
[])
assert
all
(
m
.
strides
(
a
)
==
[])
assert
all
(
m
.
strides
(
a
)
==
[])
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
m
.
shape
(
a
,
0
)
m
.
shape
(
a
,
0
)
assert
str
(
excinfo
.
value
)
==
'invalid axis: 0 (ndim = 0)'
assert
str
(
excinfo
.
value
)
==
"invalid axis: 0 (ndim = 0)"
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
m
.
strides
(
a
,
0
)
m
.
strides
(
a
,
0
)
assert
str
(
excinfo
.
value
)
==
'invalid axis: 0 (ndim = 0)'
assert
str
(
excinfo
.
value
)
==
"invalid axis: 0 (ndim = 0)"
assert
m
.
writeable
(
a
)
assert
m
.
writeable
(
a
)
assert
m
.
size
(
a
)
==
1
assert
m
.
size
(
a
)
==
1
assert
m
.
itemsize
(
a
)
==
8
assert
m
.
itemsize
(
a
)
==
8
assert
m
.
nbytes
(
a
)
==
8
assert
m
.
nbytes
(
a
)
==
8
assert
m
.
owndata
(
a
)
assert
m
.
owndata
(
a
)
a
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]],
'u2'
)
.
view
()
a
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]],
"u2"
)
.
view
()
a
.
flags
.
writeable
=
False
a
.
flags
.
writeable
=
False
assert
m
.
ndim
(
a
)
==
2
assert
m
.
ndim
(
a
)
==
2
assert
all
(
m
.
shape
(
a
)
==
[
2
,
3
])
assert
all
(
m
.
shape
(
a
)
==
[
2
,
3
])
...
@@ -56,10 +59,10 @@ def test_array_attributes():
...
@@ -56,10 +59,10 @@ def test_array_attributes():
assert
m
.
strides
(
a
,
1
)
==
2
assert
m
.
strides
(
a
,
1
)
==
2
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
m
.
shape
(
a
,
2
)
m
.
shape
(
a
,
2
)
assert
str
(
excinfo
.
value
)
==
'invalid axis: 2 (ndim = 2)'
assert
str
(
excinfo
.
value
)
==
"invalid axis: 2 (ndim = 2)"
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
m
.
strides
(
a
,
2
)
m
.
strides
(
a
,
2
)
assert
str
(
excinfo
.
value
)
==
'invalid axis: 2 (ndim = 2)'
assert
str
(
excinfo
.
value
)
==
"invalid axis: 2 (ndim = 2)"
assert
not
m
.
writeable
(
a
)
assert
not
m
.
writeable
(
a
)
assert
m
.
size
(
a
)
==
6
assert
m
.
size
(
a
)
==
6
assert
m
.
itemsize
(
a
)
==
2
assert
m
.
itemsize
(
a
)
==
2
...
@@ -67,7 +70,9 @@ def test_array_attributes():
...
@@ -67,7 +70,9 @@ def test_array_attributes():
assert
not
m
.
owndata
(
a
)
assert
not
m
.
owndata
(
a
)
@pytest.mark.parametrize
(
'args, ret'
,
[([],
0
),
([
0
],
0
),
([
1
],
3
),
([
0
,
1
],
1
),
([
1
,
2
],
5
)])
@pytest.mark.parametrize
(
"args, ret"
,
[([],
0
),
([
0
],
0
),
([
1
],
3
),
([
0
,
1
],
1
),
([
1
,
2
],
5
)]
)
def
test_index_offset
(
arr
,
args
,
ret
):
def
test_index_offset
(
arr
,
args
,
ret
):
assert
m
.
index_at
(
arr
,
*
args
)
==
ret
assert
m
.
index_at
(
arr
,
*
args
)
==
ret
assert
m
.
index_at_t
(
arr
,
*
args
)
==
ret
assert
m
.
index_at_t
(
arr
,
*
args
)
==
ret
...
@@ -76,31 +81,46 @@ def test_index_offset(arr, args, ret):
...
@@ -76,31 +81,46 @@ def test_index_offset(arr, args, ret):
def
test_dim_check_fail
(
arr
):
def
test_dim_check_fail
(
arr
):
for
func
in
(
m
.
index_at
,
m
.
index_at_t
,
m
.
offset_at
,
m
.
offset_at_t
,
m
.
data
,
m
.
data_t
,
for
func
in
(
m
.
mutate_data
,
m
.
mutate_data_t
):
m
.
index_at
,
m
.
index_at_t
,
m
.
offset_at
,
m
.
offset_at_t
,
m
.
data
,
m
.
data_t
,
m
.
mutate_data
,
m
.
mutate_data_t
,
):
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
func
(
arr
,
1
,
2
,
3
)
func
(
arr
,
1
,
2
,
3
)
assert
str
(
excinfo
.
value
)
==
'too many indices for an array: 3 (ndim = 2)'
assert
str
(
excinfo
.
value
)
==
"too many indices for an array: 3 (ndim = 2)"
@pytest.mark.parametrize
(
'args, ret'
,
@pytest.mark.parametrize
(
[([],
[
1
,
2
,
3
,
4
,
5
,
6
]),
"args, ret"
,
([
1
],
[
4
,
5
,
6
]),
[
([
0
,
1
],
[
2
,
3
,
4
,
5
,
6
]),
([],
[
1
,
2
,
3
,
4
,
5
,
6
]),
([
1
,
2
],
[
6
])])
([
1
],
[
4
,
5
,
6
]),
([
0
,
1
],
[
2
,
3
,
4
,
5
,
6
]),
([
1
,
2
],
[
6
]),
],
)
def
test_data
(
arr
,
args
,
ret
):
def
test_data
(
arr
,
args
,
ret
):
from
sys
import
byteorder
from
sys
import
byteorder
assert
all
(
m
.
data_t
(
arr
,
*
args
)
==
ret
)
assert
all
(
m
.
data_t
(
arr
,
*
args
)
==
ret
)
assert
all
(
m
.
data
(
arr
,
*
args
)[(
0
if
byteorder
==
'little'
else
1
)::
2
]
==
ret
)
assert
all
(
m
.
data
(
arr
,
*
args
)[(
0
if
byteorder
==
"little"
else
1
)
::
2
]
==
ret
)
assert
all
(
m
.
data
(
arr
,
*
args
)[(
1
if
byteorder
==
'little'
else
0
)::
2
]
==
0
)
assert
all
(
m
.
data
(
arr
,
*
args
)[(
1
if
byteorder
==
"little"
else
0
)
::
2
]
==
0
)
@pytest.mark.parametrize
(
'dim'
,
[
0
,
1
,
3
])
@pytest.mark.parametrize
(
"dim"
,
[
0
,
1
,
3
])
def
test_at_fail
(
arr
,
dim
):
def
test_at_fail
(
arr
,
dim
):
for
func
in
m
.
at_t
,
m
.
mutate_at_t
:
for
func
in
m
.
at_t
,
m
.
mutate_at_t
:
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
func
(
arr
,
*
([
0
]
*
dim
))
func
(
arr
,
*
([
0
]
*
dim
))
assert
str
(
excinfo
.
value
)
==
'index dimension mismatch: {} (ndim = 2)'
.
format
(
dim
)
assert
str
(
excinfo
.
value
)
==
"index dimension mismatch: {} (ndim = 2)"
.
format
(
dim
)
def
test_at
(
arr
):
def
test_at
(
arr
):
...
@@ -113,10 +133,14 @@ def test_at(arr):
...
@@ -113,10 +133,14 @@ def test_at(arr):
def
test_mutate_readonly
(
arr
):
def
test_mutate_readonly
(
arr
):
arr
.
flags
.
writeable
=
False
arr
.
flags
.
writeable
=
False
for
func
,
args
in
(
m
.
mutate_data
,
()),
(
m
.
mutate_data_t
,
()),
(
m
.
mutate_at_t
,
(
0
,
0
)):
for
func
,
args
in
(
(
m
.
mutate_data
,
()),
(
m
.
mutate_data_t
,
()),
(
m
.
mutate_at_t
,
(
0
,
0
)),
):
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
func
(
arr
,
*
args
)
func
(
arr
,
*
args
)
assert
str
(
excinfo
.
value
)
==
'array is not writeable'
assert
str
(
excinfo
.
value
)
==
"array is not writeable"
def
test_mutate_data
(
arr
):
def
test_mutate_data
(
arr
):
...
@@ -134,14 +158,22 @@ def test_mutate_data(arr):
...
@@ -134,14 +158,22 @@ def test_mutate_data(arr):
def
test_bounds_check
(
arr
):
def
test_bounds_check
(
arr
):
for
func
in
(
m
.
index_at
,
m
.
index_at_t
,
m
.
data
,
m
.
data_t
,
for
func
in
(
m
.
mutate_data
,
m
.
mutate_data_t
,
m
.
at_t
,
m
.
mutate_at_t
):
m
.
index_at
,
m
.
index_at_t
,
m
.
data
,
m
.
data_t
,
m
.
mutate_data
,
m
.
mutate_data_t
,
m
.
at_t
,
m
.
mutate_at_t
,
):
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
func
(
arr
,
2
,
0
)
func
(
arr
,
2
,
0
)
assert
str
(
excinfo
.
value
)
==
'index 2 is out of bounds for axis 0 with size 2'
assert
str
(
excinfo
.
value
)
==
"index 2 is out of bounds for axis 0 with size 2"
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
with
pytest
.
raises
(
IndexError
)
as
excinfo
:
func
(
arr
,
0
,
4
)
func
(
arr
,
0
,
4
)
assert
str
(
excinfo
.
value
)
==
'index 4 is out of bounds for axis 1 with size 3'
assert
str
(
excinfo
.
value
)
==
"index 4 is out of bounds for axis 1 with size 3"
def
test_make_c_f_array
():
def
test_make_c_f_array
():
...
@@ -163,10 +195,11 @@ def test_make_empty_shaped_array():
...
@@ -163,10 +195,11 @@ def test_make_empty_shaped_array():
def
test_wrap
():
def
test_wrap
():
def
assert_references
(
a
,
b
,
base
=
None
):
def
assert_references
(
a
,
b
,
base
=
None
):
from
distutils.version
import
LooseVersion
from
distutils.version
import
LooseVersion
if
base
is
None
:
if
base
is
None
:
base
=
a
base
=
a
assert
a
is
not
b
assert
a
is
not
b
assert
a
.
__array_interface__
[
'data'
][
0
]
==
b
.
__array_interface__
[
'data'
][
0
]
assert
a
.
__array_interface__
[
"data"
][
0
]
==
b
.
__array_interface__
[
"data"
][
0
]
assert
a
.
shape
==
b
.
shape
assert
a
.
shape
==
b
.
shape
assert
a
.
strides
==
b
.
strides
assert
a
.
strides
==
b
.
strides
assert
a
.
flags
.
c_contiguous
==
b
.
flags
.
c_contiguous
assert
a
.
flags
.
c_contiguous
==
b
.
flags
.
c_contiguous
...
@@ -189,12 +222,12 @@ def test_wrap():
...
@@ -189,12 +222,12 @@ def test_wrap():
a2
=
m
.
wrap
(
a1
)
a2
=
m
.
wrap
(
a1
)
assert_references
(
a1
,
a2
)
assert_references
(
a1
,
a2
)
a1
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
np
.
float32
,
order
=
'F'
)
a1
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
np
.
float32
,
order
=
"F"
)
assert
a1
.
flags
.
owndata
and
a1
.
base
is
None
assert
a1
.
flags
.
owndata
and
a1
.
base
is
None
a2
=
m
.
wrap
(
a1
)
a2
=
m
.
wrap
(
a1
)
assert_references
(
a1
,
a2
)
assert_references
(
a1
,
a2
)
a1
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
np
.
float32
,
order
=
'C'
)
a1
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
np
.
float32
,
order
=
"C"
)
a1
.
flags
.
writeable
=
False
a1
.
flags
.
writeable
=
False
a2
=
m
.
wrap
(
a1
)
a2
=
m
.
wrap
(
a1
)
assert_references
(
a1
,
a2
)
assert_references
(
a1
,
a2
)
...
@@ -224,11 +257,14 @@ def test_numpy_view(capture):
...
@@ -224,11 +257,14 @@ def test_numpy_view(capture):
assert
np
.
all
(
ac_view_1
==
np
.
array
([
1
,
2
],
dtype
=
np
.
int32
))
assert
np
.
all
(
ac_view_1
==
np
.
array
([
1
,
2
],
dtype
=
np
.
int32
))
del
ac
del
ac
pytest
.
gc_collect
()
pytest
.
gc_collect
()
assert
capture
==
"""
assert
(
capture
==
"""
ArrayClass()
ArrayClass()
ArrayClass::numpy_view()
ArrayClass::numpy_view()
ArrayClass::numpy_view()
ArrayClass::numpy_view()
"""
"""
)
ac_view_1
[
0
]
=
4
ac_view_1
[
0
]
=
4
ac_view_1
[
1
]
=
3
ac_view_1
[
1
]
=
3
assert
ac_view_2
[
0
]
==
4
assert
ac_view_2
[
0
]
==
4
...
@@ -238,9 +274,12 @@ def test_numpy_view(capture):
...
@@ -238,9 +274,12 @@ def test_numpy_view(capture):
del
ac_view_2
del
ac_view_2
pytest
.
gc_collect
()
pytest
.
gc_collect
()
pytest
.
gc_collect
()
pytest
.
gc_collect
()
assert
capture
==
"""
assert
(
capture
==
"""
~ArrayClass()
~ArrayClass()
"""
"""
)
def
test_cast_numpy_int64_to_uint64
():
def
test_cast_numpy_int64_to_uint64
():
...
@@ -271,20 +310,22 @@ def test_constructors():
...
@@ -271,20 +310,22 @@ def test_constructors():
def
test_overload_resolution
(
msg
):
def
test_overload_resolution
(
msg
):
# Exact overload matches:
# Exact overload matches:
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
'float64'
))
==
'double'
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
"float64"
))
==
"double"
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
'float32'
))
==
'float'
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
"float32"
))
==
"float"
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
'ushort'
))
==
'unsigned short'
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
"ushort"
))
==
"unsigned short"
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
'intc'
))
==
'int'
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
"intc"
))
==
"int"
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
'longlong'
))
==
'long long'
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
"longlong"
))
==
"long long"
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
'complex'
))
==
'double complex'
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
"complex"
))
==
"double complex"
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
'csingle'
))
==
'float complex'
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
"csingle"
))
==
"float complex"
# No exact match, should call first convertible version:
# No exact match, should call first convertible version:
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
'uint8'
))
==
'double'
assert
m
.
overloaded
(
np
.
array
([
1
],
dtype
=
"uint8"
))
==
"double"
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
overloaded
(
"not an array"
)
m
.
overloaded
(
"not an array"
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
overloaded(): incompatible function arguments. The following argument types are supported:
overloaded(): incompatible function arguments. The following argument types are supported:
1. (arg0: numpy.ndarray[numpy.float64]) -> str
1. (arg0: numpy.ndarray[numpy.float64]) -> str
2. (arg0: numpy.ndarray[numpy.float32]) -> str
2. (arg0: numpy.ndarray[numpy.float32]) -> str
...
@@ -296,15 +337,16 @@ def test_overload_resolution(msg):
...
@@ -296,15 +337,16 @@ def test_overload_resolution(msg):
Invoked with: 'not an array'
Invoked with: 'not an array'
"""
"""
)
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
'float64'
))
==
'double'
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
"float64"
))
==
"double"
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
'float32'
))
==
'float'
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
"float32"
))
==
"float"
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
'complex64'
))
==
'float complex'
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
"complex64"
))
==
"float complex"
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
'complex128'
))
==
'double complex'
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
"complex128"
))
==
"double complex"
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
'float32'
))
==
'float'
assert
m
.
overloaded2
(
np
.
array
([
1
],
dtype
=
"float32"
))
==
"float"
assert
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
'float64'
))
==
'double'
assert
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
"float64"
))
==
"double"
assert
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
'intc'
))
==
'int'
assert
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
"intc"
))
==
"int"
expected_exc
=
"""
expected_exc
=
"""
overloaded3(): incompatible function arguments. The following argument types are supported:
overloaded3(): incompatible function arguments. The following argument types are supported:
1. (arg0: numpy.ndarray[numpy.int32]) -> str
1. (arg0: numpy.ndarray[numpy.int32]) -> str
...
@@ -313,47 +355,49 @@ def test_overload_resolution(msg):
...
@@ -313,47 +355,49 @@ def test_overload_resolution(msg):
Invoked with: """
Invoked with: """
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
'uintc'
))
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
"uintc"
))
assert
msg
(
excinfo
.
value
)
==
expected_exc
+
repr
(
np
.
array
([
1
],
dtype
=
'uint32'
))
assert
msg
(
excinfo
.
value
)
==
expected_exc
+
repr
(
np
.
array
([
1
],
dtype
=
"uint32"
))
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
'float32'
))
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
"float32"
))
assert
msg
(
excinfo
.
value
)
==
expected_exc
+
repr
(
np
.
array
([
1.
],
dtype
=
'float32'
))
assert
msg
(
excinfo
.
value
)
==
expected_exc
+
repr
(
np
.
array
([
1.
0
],
dtype
=
"float32"
))
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
'complex'
))
m
.
overloaded3
(
np
.
array
([
1
],
dtype
=
"complex"
))
assert
msg
(
excinfo
.
value
)
==
expected_exc
+
repr
(
np
.
array
([
1.
+
0.
j
]))
assert
msg
(
excinfo
.
value
)
==
expected_exc
+
repr
(
np
.
array
([
1.
0
+
0.0
j
]))
# Exact matches:
# Exact matches:
assert
m
.
overloaded4
(
np
.
array
([
1
],
dtype
=
'double'
))
==
'double'
assert
m
.
overloaded4
(
np
.
array
([
1
],
dtype
=
"double"
))
==
"double"
assert
m
.
overloaded4
(
np
.
array
([
1
],
dtype
=
'longlong'
))
==
'long long'
assert
m
.
overloaded4
(
np
.
array
([
1
],
dtype
=
"longlong"
))
==
"long long"
# Non-exact matches requiring conversion. Since float to integer isn't a
# Non-exact matches requiring conversion. Since float to integer isn't a
# save conversion, it should go to the double overload, but short can go to
# save conversion, it should go to the double overload, but short can go to
# either (and so should end up on the first-registered, the long long).
# either (and so should end up on the first-registered, the long long).
assert
m
.
overloaded4
(
np
.
array
([
1
],
dtype
=
'float32'
))
==
'double'
assert
m
.
overloaded4
(
np
.
array
([
1
],
dtype
=
"float32"
))
==
"double"
assert
m
.
overloaded4
(
np
.
array
([
1
],
dtype
=
'short'
))
==
'long long'
assert
m
.
overloaded4
(
np
.
array
([
1
],
dtype
=
"short"
))
==
"long long"
assert
m
.
overloaded5
(
np
.
array
([
1
],
dtype
=
'double'
))
==
'double'
assert
m
.
overloaded5
(
np
.
array
([
1
],
dtype
=
"double"
))
==
"double"
assert
m
.
overloaded5
(
np
.
array
([
1
],
dtype
=
'uintc'
))
==
'unsigned int'
assert
m
.
overloaded5
(
np
.
array
([
1
],
dtype
=
"uintc"
))
==
"unsigned int"
assert
m
.
overloaded5
(
np
.
array
([
1
],
dtype
=
'float32'
))
==
'unsigned int'
assert
m
.
overloaded5
(
np
.
array
([
1
],
dtype
=
"float32"
))
==
"unsigned int"
def
test_greedy_string_overload
():
def
test_greedy_string_overload
():
"""Tests fix for #685 - ndarray shouldn't go to std::string overload"""
"""Tests fix for #685 - ndarray shouldn't go to std::string overload"""
assert
m
.
issue685
(
"abc"
)
==
"string"
assert
m
.
issue685
(
"abc"
)
==
"string"
assert
m
.
issue685
(
np
.
array
([
97
,
98
,
99
],
dtype
=
'b'
))
==
"array"
assert
m
.
issue685
(
np
.
array
([
97
,
98
,
99
],
dtype
=
"b"
))
==
"array"
assert
m
.
issue685
(
123
)
==
"other"
assert
m
.
issue685
(
123
)
==
"other"
def
test_array_unchecked_fixed_dims
(
msg
):
def
test_array_unchecked_fixed_dims
(
msg
):
z1
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
'float64'
)
z1
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
"float64"
)
m
.
proxy_add2
(
z1
,
10
)
m
.
proxy_add2
(
z1
,
10
)
assert
np
.
all
(
z1
==
[[
11
,
12
],
[
13
,
14
]])
assert
np
.
all
(
z1
==
[[
11
,
12
],
[
13
,
14
]])
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
m
.
proxy_add2
(
np
.
array
([
1.
,
2
,
3
]),
5.0
)
m
.
proxy_add2
(
np
.
array
([
1.0
,
2
,
3
]),
5.0
)
assert
msg
(
excinfo
.
value
)
==
"array has incorrect number of dimensions: 1; expected 2"
assert
(
msg
(
excinfo
.
value
)
==
"array has incorrect number of dimensions: 1; expected 2"
)
expect_c
=
np
.
ndarray
(
shape
=
(
3
,
3
,
3
),
buffer
=
np
.
array
(
range
(
3
,
30
)),
dtype
=
'int'
)
expect_c
=
np
.
ndarray
(
shape
=
(
3
,
3
,
3
),
buffer
=
np
.
array
(
range
(
3
,
30
)),
dtype
=
"int"
)
assert
np
.
all
(
m
.
proxy_init3
(
3.0
)
==
expect_c
)
assert
np
.
all
(
m
.
proxy_init3
(
3.0
)
==
expect_c
)
expect_f
=
np
.
transpose
(
expect_c
)
expect_f
=
np
.
transpose
(
expect_c
)
assert
np
.
all
(
m
.
proxy_init3F
(
3.0
)
==
expect_f
)
assert
np
.
all
(
m
.
proxy_init3F
(
3.0
)
==
expect_f
)
...
@@ -369,11 +413,11 @@ def test_array_unchecked_fixed_dims(msg):
...
@@ -369,11 +413,11 @@ def test_array_unchecked_fixed_dims(msg):
def
test_array_unchecked_dyn_dims
(
msg
):
def
test_array_unchecked_dyn_dims
(
msg
):
z1
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
'float64'
)
z1
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
dtype
=
"float64"
)
m
.
proxy_add2_dyn
(
z1
,
10
)
m
.
proxy_add2_dyn
(
z1
,
10
)
assert
np
.
all
(
z1
==
[[
11
,
12
],
[
13
,
14
]])
assert
np
.
all
(
z1
==
[[
11
,
12
],
[
13
,
14
]])
expect_c
=
np
.
ndarray
(
shape
=
(
3
,
3
,
3
),
buffer
=
np
.
array
(
range
(
3
,
30
)),
dtype
=
'int'
)
expect_c
=
np
.
ndarray
(
shape
=
(
3
,
3
,
3
),
buffer
=
np
.
array
(
range
(
3
,
30
)),
dtype
=
"int"
)
assert
np
.
all
(
m
.
proxy_init3_dyn
(
3.0
)
==
expect_c
)
assert
np
.
all
(
m
.
proxy_init3_dyn
(
3.0
)
==
expect_c
)
assert
m
.
proxy_auxiliaries2_dyn
(
z1
)
==
[
11
,
11
,
True
,
2
,
8
,
2
,
2
,
4
,
32
]
assert
m
.
proxy_auxiliaries2_dyn
(
z1
)
==
[
11
,
11
,
True
,
2
,
8
,
2
,
2
,
4
,
32
]
...
@@ -383,15 +427,15 @@ def test_array_unchecked_dyn_dims(msg):
...
@@ -383,15 +427,15 @@ def test_array_unchecked_dyn_dims(msg):
def
test_array_failure
():
def
test_array_failure
():
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
m
.
array_fail_test
()
m
.
array_fail_test
()
assert
str
(
excinfo
.
value
)
==
'cannot create a pybind11::array from a nullptr'
assert
str
(
excinfo
.
value
)
==
"cannot create a pybind11::array from a nullptr"
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
m
.
array_t_fail_test
()
m
.
array_t_fail_test
()
assert
str
(
excinfo
.
value
)
==
'cannot create a pybind11::array_t from a nullptr'
assert
str
(
excinfo
.
value
)
==
"cannot create a pybind11::array_t from a nullptr"
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
m
.
array_fail_test_negative_size
()
m
.
array_fail_test_negative_size
()
assert
str
(
excinfo
.
value
)
==
'negative dimensions are not allowed'
assert
str
(
excinfo
.
value
)
==
"negative dimensions are not allowed"
def
test_initializer_list
():
def
test_initializer_list
():
...
@@ -402,35 +446,35 @@ def test_initializer_list():
...
@@ -402,35 +446,35 @@ def test_initializer_list():
def
test_array_resize
(
msg
):
def
test_array_resize
(
msg
):
a
=
np
.
array
([
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
],
dtype
=
'float64'
)
a
=
np
.
array
([
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
],
dtype
=
"float64"
)
m
.
array_reshape2
(
a
)
m
.
array_reshape2
(
a
)
assert
(
a
.
size
==
9
)
assert
a
.
size
==
9
assert
(
np
.
all
(
a
==
[[
1
,
2
,
3
],
[
4
,
5
,
6
],
[
7
,
8
,
9
]])
)
assert
np
.
all
(
a
==
[[
1
,
2
,
3
],
[
4
,
5
,
6
],
[
7
,
8
,
9
]]
)
# total size change should succced with refcheck off
# total size change should succced with refcheck off
m
.
array_resize3
(
a
,
4
,
False
)
m
.
array_resize3
(
a
,
4
,
False
)
assert
(
a
.
size
==
64
)
assert
a
.
size
==
64
# ... and fail with refcheck on
# ... and fail with refcheck on
try
:
try
:
m
.
array_resize3
(
a
,
3
,
True
)
m
.
array_resize3
(
a
,
3
,
True
)
except
ValueError
as
e
:
except
ValueError
as
e
:
assert
(
str
(
e
)
.
startswith
(
"cannot resize an array"
)
)
assert
str
(
e
)
.
startswith
(
"cannot resize an array"
)
# transposed array doesn't own data
# transposed array doesn't own data
b
=
a
.
transpose
()
b
=
a
.
transpose
()
try
:
try
:
m
.
array_resize3
(
b
,
3
,
False
)
m
.
array_resize3
(
b
,
3
,
False
)
except
ValueError
as
e
:
except
ValueError
as
e
:
assert
(
str
(
e
)
.
startswith
(
"cannot resize this array: it does not own its data"
)
)
assert
str
(
e
)
.
startswith
(
"cannot resize this array: it does not own its data"
)
# ... but reshape should be fine
# ... but reshape should be fine
m
.
array_reshape2
(
b
)
m
.
array_reshape2
(
b
)
assert
(
b
.
shape
==
(
8
,
8
)
)
assert
b
.
shape
==
(
8
,
8
)
@pytest.mark.xfail
(
"env.PYPY"
)
@pytest.mark.xfail
(
"env.PYPY"
)
def
test_array_create_and_resize
(
msg
):
def
test_array_create_and_resize
(
msg
):
a
=
m
.
create_and_resize
(
2
)
a
=
m
.
create_and_resize
(
2
)
assert
(
a
.
size
==
4
)
assert
a
.
size
==
4
assert
(
np
.
all
(
a
==
42.
)
)
assert
np
.
all
(
a
==
42.0
)
def
test_index_using_ellipsis
():
def
test_index_using_ellipsis
():
...
@@ -439,16 +483,16 @@ def test_index_using_ellipsis():
...
@@ -439,16 +483,16 @@ def test_index_using_ellipsis():
@pytest.mark.parametrize
(
"forcecast"
,
[
False
,
True
])
@pytest.mark.parametrize
(
"forcecast"
,
[
False
,
True
])
@pytest.mark.parametrize
(
"contiguity"
,
[
None
,
'C'
,
'F'
])
@pytest.mark.parametrize
(
"contiguity"
,
[
None
,
"C"
,
"F"
])
@pytest.mark.parametrize
(
"noconvert"
,
[
False
,
True
])
@pytest.mark.parametrize
(
"noconvert"
,
[
False
,
True
])
@pytest.mark.filterwarnings
(
@pytest.mark.filterwarnings
(
"ignore:Casting complex values to real discards the imaginary part:numpy.ComplexWarning"
"ignore:Casting complex values to real discards the imaginary part:numpy.ComplexWarning"
)
)
def
test_argument_conversions
(
forcecast
,
contiguity
,
noconvert
):
def
test_argument_conversions
(
forcecast
,
contiguity
,
noconvert
):
function_name
=
"accept_double"
function_name
=
"accept_double"
if
contiguity
==
'C'
:
if
contiguity
==
"C"
:
function_name
+=
"_c_style"
function_name
+=
"_c_style"
elif
contiguity
==
'F'
:
elif
contiguity
==
"F"
:
function_name
+=
"_f_style"
function_name
+=
"_f_style"
if
forcecast
:
if
forcecast
:
function_name
+=
"_forcecast"
function_name
+=
"_forcecast"
...
@@ -456,37 +500,39 @@ def test_argument_conversions(forcecast, contiguity, noconvert):
...
@@ -456,37 +500,39 @@ def test_argument_conversions(forcecast, contiguity, noconvert):
function_name
+=
"_noconvert"
function_name
+=
"_noconvert"
function
=
getattr
(
m
,
function_name
)
function
=
getattr
(
m
,
function_name
)
for
dtype
in
[
np
.
dtype
(
'float32'
),
np
.
dtype
(
'float64'
),
np
.
dtype
(
'complex128'
)]:
for
dtype
in
[
np
.
dtype
(
"float32"
),
np
.
dtype
(
"float64"
),
np
.
dtype
(
"complex128"
)]:
for
order
in
[
'C'
,
'F'
]:
for
order
in
[
"C"
,
"F"
]:
for
shape
in
[(
2
,
2
),
(
1
,
3
,
1
,
1
),
(
1
,
1
,
1
),
(
0
,)]:
for
shape
in
[(
2
,
2
),
(
1
,
3
,
1
,
1
),
(
1
,
1
,
1
),
(
0
,)]:
if
not
noconvert
:
if
not
noconvert
:
# If noconvert is not passed, only complex128 needs to be truncated and
# If noconvert is not passed, only complex128 needs to be truncated and
# "cannot be safely obtained". So without `forcecast`, the argument shouldn't
# "cannot be safely obtained". So without `forcecast`, the argument shouldn't
# be accepted.
# be accepted.
should_raise
=
dtype
.
name
==
'complex128'
and
not
forcecast
should_raise
=
dtype
.
name
==
"complex128"
and
not
forcecast
else
:
else
:
# If noconvert is passed, only float64 and the matching order is accepted.
# If noconvert is passed, only float64 and the matching order is accepted.
# If at most one dimension has a size greater than 1, the array is also
# If at most one dimension has a size greater than 1, the array is also
# trivially contiguous.
# trivially contiguous.
trivially_contiguous
=
sum
(
1
for
d
in
shape
if
d
>
1
)
<=
1
trivially_contiguous
=
sum
(
1
for
d
in
shape
if
d
>
1
)
<=
1
should_raise
=
(
should_raise
=
dtype
.
name
!=
"float64"
or
(
dtype
.
name
!=
'float64'
or
contiguity
is
not
None
(
contiguity
is
not
None
and
and
contiguity
!=
order
contiguity
!=
order
and
and
not
trivially_contiguous
not
trivially_contiguous
)
)
)
array
=
np
.
zeros
(
shape
,
dtype
=
dtype
,
order
=
order
)
array
=
np
.
zeros
(
shape
,
dtype
=
dtype
,
order
=
order
)
if
not
should_raise
:
if
not
should_raise
:
function
(
array
)
function
(
array
)
else
:
else
:
with
pytest
.
raises
(
TypeError
,
match
=
"incompatible function arguments"
):
with
pytest
.
raises
(
TypeError
,
match
=
"incompatible function arguments"
):
function
(
array
)
function
(
array
)
@pytest.mark.xfail
(
"env.PYPY"
)
@pytest.mark.xfail
(
"env.PYPY"
)
def
test_dtype_refcount_leak
():
def
test_dtype_refcount_leak
():
from
sys
import
getrefcount
from
sys
import
getrefcount
dtype
=
np
.
dtype
(
np
.
float_
)
dtype
=
np
.
dtype
(
np
.
float_
)
a
=
np
.
array
([
1
],
dtype
=
dtype
)
a
=
np
.
array
([
1
],
dtype
=
dtype
)
before
=
getrefcount
(
dtype
)
before
=
getrefcount
(
dtype
)
...
...
tests/test_numpy_dtypes.py
View file @
c50f90ec
...
@@ -10,57 +10,71 @@ from pybind11_tests import numpy_dtypes as m
...
@@ -10,57 +10,71 @@ from pybind11_tests import numpy_dtypes as m
np
=
pytest
.
importorskip
(
"numpy"
)
np
=
pytest
.
importorskip
(
"numpy"
)
@pytest.fixture
(
scope
=
'module'
)
@pytest.fixture
(
scope
=
"module"
)
def
simple_dtype
():
def
simple_dtype
():
ld
=
np
.
dtype
(
'longdouble'
)
ld
=
np
.
dtype
(
"longdouble"
)
return
np
.
dtype
({
'names'
:
[
'bool_'
,
'uint_'
,
'float_'
,
'ldbl_'
],
return
np
.
dtype
(
'formats'
:
[
'?'
,
'u4'
,
'f4'
,
'f{}'
.
format
(
ld
.
itemsize
)],
{
'offsets'
:
[
0
,
4
,
8
,
(
16
if
ld
.
alignment
>
4
else
12
)]})
"names"
:
[
"bool_"
,
"uint_"
,
"float_"
,
"ldbl_"
],
"formats"
:
[
"?"
,
"u4"
,
"f4"
,
"f{}"
.
format
(
ld
.
itemsize
)],
"offsets"
:
[
0
,
4
,
8
,
(
16
if
ld
.
alignment
>
4
else
12
)],
}
)
@pytest.fixture
(
scope
=
'module'
)
@pytest.fixture
(
scope
=
"module"
)
def
packed_dtype
():
def
packed_dtype
():
return
np
.
dtype
([(
'bool_'
,
'?'
),
(
'uint_'
,
'u4'
),
(
'float_'
,
'f4'
),
(
'ldbl_'
,
'g'
)])
return
np
.
dtype
([(
"bool_"
,
"?"
),
(
"uint_"
,
"u4"
),
(
"float_"
,
"f4"
),
(
"ldbl_"
,
"g"
)])
def
dt_fmt
():
def
dt_fmt
():
from
sys
import
byteorder
from
sys
import
byteorder
e
=
'<'
if
byteorder
==
'little'
else
'>'
return
(
"{{'names':['bool_','uint_','float_','ldbl_'],"
e
=
"<"
if
byteorder
==
"little"
else
">"
" 'formats':['?','"
+
e
+
"u4','"
+
e
+
"f4','"
+
e
+
"f{}'],"
return
(
" 'offsets':[0,4,8,{}], 'itemsize':{}}}"
)
"{{'names':['bool_','uint_','float_','ldbl_'],"
" 'formats':['?','"
+
e
+
"u4','"
+
e
+
"f4','"
+
e
+
"f{}'],"
" 'offsets':[0,4,8,{}], 'itemsize':{}}}"
)
def
simple_dtype_fmt
():
def
simple_dtype_fmt
():
ld
=
np
.
dtype
(
'longdouble'
)
ld
=
np
.
dtype
(
"longdouble"
)
simple_ld_off
=
12
+
4
*
(
ld
.
alignment
>
4
)
simple_ld_off
=
12
+
4
*
(
ld
.
alignment
>
4
)
return
dt_fmt
()
.
format
(
ld
.
itemsize
,
simple_ld_off
,
simple_ld_off
+
ld
.
itemsize
)
return
dt_fmt
()
.
format
(
ld
.
itemsize
,
simple_ld_off
,
simple_ld_off
+
ld
.
itemsize
)
def
packed_dtype_fmt
():
def
packed_dtype_fmt
():
from
sys
import
byteorder
from
sys
import
byteorder
return
"[('bool_', '?'), ('uint_', '{e}u4'), ('float_', '{e}f4'), ('ldbl_', '{e}f{}')]"
.
format
(
return
"[('bool_', '?'), ('uint_', '{e}u4'), ('float_', '{e}f4'), ('ldbl_', '{e}f{}')]"
.
format
(
np
.
dtype
(
'longdouble'
)
.
itemsize
,
e
=
'<'
if
byteorder
==
'little'
else
'>'
)
np
.
dtype
(
"longdouble"
)
.
itemsize
,
e
=
"<"
if
byteorder
==
"little"
else
">"
)
def
partial_ld_offset
():
def
partial_ld_offset
():
return
12
+
4
*
(
np
.
dtype
(
'uint64'
)
.
alignment
>
4
)
+
8
+
8
*
(
return
(
np
.
dtype
(
'longdouble'
)
.
alignment
>
8
)
12
+
4
*
(
np
.
dtype
(
"uint64"
)
.
alignment
>
4
)
+
8
+
8
*
(
np
.
dtype
(
"longdouble"
)
.
alignment
>
8
)
)
def
partial_dtype_fmt
():
def
partial_dtype_fmt
():
ld
=
np
.
dtype
(
'longdouble'
)
ld
=
np
.
dtype
(
"longdouble"
)
partial_ld_off
=
partial_ld_offset
()
partial_ld_off
=
partial_ld_offset
()
return
dt_fmt
()
.
format
(
ld
.
itemsize
,
partial_ld_off
,
partial_ld_off
+
ld
.
itemsize
)
return
dt_fmt
()
.
format
(
ld
.
itemsize
,
partial_ld_off
,
partial_ld_off
+
ld
.
itemsize
)
def
partial_nested_fmt
():
def
partial_nested_fmt
():
ld
=
np
.
dtype
(
'longdouble'
)
ld
=
np
.
dtype
(
"longdouble"
)
partial_nested_off
=
8
+
8
*
(
ld
.
alignment
>
8
)
partial_nested_off
=
8
+
8
*
(
ld
.
alignment
>
8
)
partial_ld_off
=
partial_ld_offset
()
partial_ld_off
=
partial_ld_offset
()
partial_nested_size
=
partial_nested_off
*
2
+
partial_ld_off
+
ld
.
itemsize
partial_nested_size
=
partial_nested_off
*
2
+
partial_ld_off
+
ld
.
itemsize
return
"{{'names':['a'], 'formats':[{}], 'offsets':[{}], 'itemsize':{}}}"
.
format
(
return
"{{'names':['a'], 'formats':[{}], 'offsets':[{}], 'itemsize':{}}}"
.
format
(
partial_dtype_fmt
(),
partial_nested_off
,
partial_nested_size
)
partial_dtype_fmt
(),
partial_nested_off
,
partial_nested_size
)
def
assert_equal
(
actual
,
expected_data
,
expected_dtype
):
def
assert_equal
(
actual
,
expected_data
,
expected_dtype
):
...
@@ -70,15 +84,19 @@ def assert_equal(actual, expected_data, expected_dtype):
...
@@ -70,15 +84,19 @@ def assert_equal(actual, expected_data, expected_dtype):
def
test_format_descriptors
():
def
test_format_descriptors
():
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
get_format_unbound
()
m
.
get_format_unbound
()
assert
re
.
match
(
'^NumPy type info missing for .*UnboundStruct.*$'
,
str
(
excinfo
.
value
))
assert
re
.
match
(
"^NumPy type info missing for .*UnboundStruct.*$"
,
str
(
excinfo
.
value
)
)
ld
=
np
.
dtype
(
'longdouble'
)
ld
=
np
.
dtype
(
"longdouble"
)
ldbl_fmt
=
(
'4x'
if
ld
.
alignment
>
4
else
''
)
+
ld
.
char
ldbl_fmt
=
(
"4x"
if
ld
.
alignment
>
4
else
""
)
+
ld
.
char
ss_fmt
=
"^T{?:bool_:3xI:uint_:f:float_:"
+
ldbl_fmt
+
":ldbl_:}"
ss_fmt
=
"^T{?:bool_:3xI:uint_:f:float_:"
+
ldbl_fmt
+
":ldbl_:}"
dbl
=
np
.
dtype
(
'double'
)
dbl
=
np
.
dtype
(
"double"
)
partial_fmt
=
(
"^T{?:bool_:3xI:uint_:f:float_:"
+
partial_fmt
=
(
str
(
4
*
(
dbl
.
alignment
>
4
)
+
dbl
.
itemsize
+
8
*
(
ld
.
alignment
>
8
))
+
"^T{?:bool_:3xI:uint_:f:float_:"
"xg:ldbl_:}"
)
+
str
(
4
*
(
dbl
.
alignment
>
4
)
+
dbl
.
itemsize
+
8
*
(
ld
.
alignment
>
8
))
+
"xg:ldbl_:}"
)
nested_extra
=
str
(
max
(
8
,
ld
.
alignment
))
nested_extra
=
str
(
max
(
8
,
ld
.
alignment
))
assert
m
.
print_format_descriptors
()
==
[
assert
m
.
print_format_descriptors
()
==
[
ss_fmt
,
ss_fmt
,
...
@@ -88,14 +106,15 @@ def test_format_descriptors():
...
@@ -88,14 +106,15 @@ def test_format_descriptors():
"^T{"
+
nested_extra
+
"x"
+
partial_fmt
+
":a:"
+
nested_extra
+
"x}"
,
"^T{"
+
nested_extra
+
"x"
+
partial_fmt
+
":a:"
+
nested_extra
+
"x}"
,
"^T{3s:a:3s:b:}"
,
"^T{3s:a:3s:b:}"
,
"^T{(3)4s:a:(2)i:b:(3)B:c:1x(4, 2)f:d:}"
,
"^T{(3)4s:a:(2)i:b:(3)B:c:1x(4, 2)f:d:}"
,
'^T{q:e1:B:e2:}'
,
"^T{q:e1:B:e2:}"
,
'^T{Zf:cflt:Zd:cdbl:}'
"^T{Zf:cflt:Zd:cdbl:}"
,
]
]
def
test_dtype
(
simple_dtype
):
def
test_dtype
(
simple_dtype
):
from
sys
import
byteorder
from
sys
import
byteorder
e
=
'<'
if
byteorder
==
'little'
else
'>'
e
=
"<"
if
byteorder
==
"little"
else
">"
assert
m
.
print_dtypes
()
==
[
assert
m
.
print_dtypes
()
==
[
simple_dtype_fmt
(),
simple_dtype_fmt
(),
...
@@ -104,30 +123,60 @@ def test_dtype(simple_dtype):
...
@@ -104,30 +123,60 @@ def test_dtype(simple_dtype):
partial_dtype_fmt
(),
partial_dtype_fmt
(),
partial_nested_fmt
(),
partial_nested_fmt
(),
"[('a', 'S3'), ('b', 'S3')]"
,
"[('a', 'S3'), ('b', 'S3')]"
,
(
"{{'names':['a','b','c','d'], "
+
(
"'formats':[('S4', (3,)),('"
+
e
+
"i4', (2,)),('u1', (3,)),('"
+
e
+
"f4', (4, 2))], "
+
"{{'names':['a','b','c','d'], "
"'offsets':[0,12,20,24], 'itemsize':56}}"
)
.
format
(
e
=
e
),
+
"'formats':[('S4', (3,)),('"
+
e
+
"i4', (2,)),('u1', (3,)),('"
+
e
+
"f4', (4, 2))], "
+
"'offsets':[0,12,20,24], 'itemsize':56}}"
)
.
format
(
e
=
e
),
"[('e1', '"
+
e
+
"i8'), ('e2', 'u1')]"
,
"[('e1', '"
+
e
+
"i8'), ('e2', 'u1')]"
,
"[('x', 'i1'), ('y', '"
+
e
+
"u8')]"
,
"[('x', 'i1'), ('y', '"
+
e
+
"u8')]"
,
"[('cflt', '"
+
e
+
"c8'), ('cdbl', '"
+
e
+
"c16')]"
"[('cflt', '"
+
e
+
"c8'), ('cdbl', '"
+
e
+
"c16')]"
,
]
]
d1
=
np
.
dtype
({
'names'
:
[
'a'
,
'b'
],
'formats'
:
[
'int32'
,
'float64'
],
d1
=
np
.
dtype
(
'offsets'
:
[
1
,
10
],
'itemsize'
:
20
})
{
d2
=
np
.
dtype
([(
'a'
,
'i4'
),
(
'b'
,
'f4'
)])
"names"
:
[
"a"
,
"b"
],
assert
m
.
test_dtype_ctors
()
==
[
np
.
dtype
(
'int32'
),
np
.
dtype
(
'float64'
),
"formats"
:
[
"int32"
,
"float64"
],
np
.
dtype
(
'bool'
),
d1
,
d1
,
np
.
dtype
(
'uint32'
),
d2
]
"offsets"
:
[
1
,
10
],
"itemsize"
:
20
,
}
)
d2
=
np
.
dtype
([(
"a"
,
"i4"
),
(
"b"
,
"f4"
)])
assert
m
.
test_dtype_ctors
()
==
[
np
.
dtype
(
"int32"
),
np
.
dtype
(
"float64"
),
np
.
dtype
(
"bool"
),
d1
,
d1
,
np
.
dtype
(
"uint32"
),
d2
,
]
assert
m
.
test_dtype_methods
()
==
[
np
.
dtype
(
'int32'
),
simple_dtype
,
False
,
True
,
assert
m
.
test_dtype_methods
()
==
[
np
.
dtype
(
'int32'
)
.
itemsize
,
simple_dtype
.
itemsize
]
np
.
dtype
(
"int32"
),
simple_dtype
,
False
,
True
,
np
.
dtype
(
"int32"
)
.
itemsize
,
simple_dtype
.
itemsize
,
]
assert
m
.
trailing_padding_dtype
()
==
m
.
buffer_to_dtype
(
np
.
zeros
(
1
,
m
.
trailing_padding_dtype
()))
assert
m
.
trailing_padding_dtype
()
==
m
.
buffer_to_dtype
(
np
.
zeros
(
1
,
m
.
trailing_padding_dtype
())
)
def
test_recarray
(
simple_dtype
,
packed_dtype
):
def
test_recarray
(
simple_dtype
,
packed_dtype
):
elements
=
[(
False
,
0
,
0.0
,
-
0.0
),
(
True
,
1
,
1.5
,
-
2.5
),
(
False
,
2
,
3.0
,
-
5.0
)]
elements
=
[(
False
,
0
,
0.0
,
-
0.0
),
(
True
,
1
,
1.5
,
-
2.5
),
(
False
,
2
,
3.0
,
-
5.0
)]
for
func
,
dtype
in
[(
m
.
create_rec_simple
,
simple_dtype
),
(
m
.
create_rec_packed
,
packed_dtype
)]:
for
func
,
dtype
in
[
(
m
.
create_rec_simple
,
simple_dtype
),
(
m
.
create_rec_packed
,
packed_dtype
),
]:
arr
=
func
(
0
)
arr
=
func
(
0
)
assert
arr
.
dtype
==
dtype
assert
arr
.
dtype
==
dtype
assert_equal
(
arr
,
[],
simple_dtype
)
assert_equal
(
arr
,
[],
simple_dtype
)
...
@@ -146,16 +195,16 @@ def test_recarray(simple_dtype, packed_dtype):
...
@@ -146,16 +195,16 @@ def test_recarray(simple_dtype, packed_dtype):
assert
m
.
print_rec_simple
(
arr
)
==
[
assert
m
.
print_rec_simple
(
arr
)
==
[
"s:0,0,0,-0"
,
"s:0,0,0,-0"
,
"s:1,1,1.5,-2.5"
,
"s:1,1,1.5,-2.5"
,
"s:0,2,3,-5"
"s:0,2,3,-5"
,
]
]
else
:
else
:
assert
m
.
print_rec_packed
(
arr
)
==
[
assert
m
.
print_rec_packed
(
arr
)
==
[
"p:0,0,0,-0"
,
"p:0,0,0,-0"
,
"p:1,1,1.5,-2.5"
,
"p:1,1,1.5,-2.5"
,
"p:0,2,3,-5"
"p:0,2,3,-5"
,
]
]
nested_dtype
=
np
.
dtype
([(
'a'
,
simple_dtype
),
(
'b'
,
packed_dtype
)])
nested_dtype
=
np
.
dtype
([(
"a"
,
simple_dtype
),
(
"b"
,
packed_dtype
)])
arr
=
m
.
create_rec_nested
(
0
)
arr
=
m
.
create_rec_nested
(
0
)
assert
arr
.
dtype
==
nested_dtype
assert
arr
.
dtype
==
nested_dtype
...
@@ -163,33 +212,39 @@ def test_recarray(simple_dtype, packed_dtype):
...
@@ -163,33 +212,39 @@ def test_recarray(simple_dtype, packed_dtype):
arr
=
m
.
create_rec_nested
(
3
)
arr
=
m
.
create_rec_nested
(
3
)
assert
arr
.
dtype
==
nested_dtype
assert
arr
.
dtype
==
nested_dtype
assert_equal
(
arr
,
[((
False
,
0
,
0.0
,
-
0.0
),
(
True
,
1
,
1.5
,
-
2.5
)),
assert_equal
(
((
True
,
1
,
1.5
,
-
2.5
),
(
False
,
2
,
3.0
,
-
5.0
)),
arr
,
((
False
,
2
,
3.0
,
-
5.0
),
(
True
,
3
,
4.5
,
-
7.5
))],
nested_dtype
)
[
((
False
,
0
,
0.0
,
-
0.0
),
(
True
,
1
,
1.5
,
-
2.5
)),
((
True
,
1
,
1.5
,
-
2.5
),
(
False
,
2
,
3.0
,
-
5.0
)),
((
False
,
2
,
3.0
,
-
5.0
),
(
True
,
3
,
4.5
,
-
7.5
)),
],
nested_dtype
,
)
assert
m
.
print_rec_nested
(
arr
)
==
[
assert
m
.
print_rec_nested
(
arr
)
==
[
"n:a=s:0,0,0,-0;b=p:1,1,1.5,-2.5"
,
"n:a=s:0,0,0,-0;b=p:1,1,1.5,-2.5"
,
"n:a=s:1,1,1.5,-2.5;b=p:0,2,3,-5"
,
"n:a=s:1,1,1.5,-2.5;b=p:0,2,3,-5"
,
"n:a=s:0,2,3,-5;b=p:1,3,4.5,-7.5"
"n:a=s:0,2,3,-5;b=p:1,3,4.5,-7.5"
,
]
]
arr
=
m
.
create_rec_partial
(
3
)
arr
=
m
.
create_rec_partial
(
3
)
assert
str
(
arr
.
dtype
)
==
partial_dtype_fmt
()
assert
str
(
arr
.
dtype
)
==
partial_dtype_fmt
()
partial_dtype
=
arr
.
dtype
partial_dtype
=
arr
.
dtype
assert
''
not
in
arr
.
dtype
.
fields
assert
""
not
in
arr
.
dtype
.
fields
assert
partial_dtype
.
itemsize
>
simple_dtype
.
itemsize
assert
partial_dtype
.
itemsize
>
simple_dtype
.
itemsize
assert_equal
(
arr
,
elements
,
simple_dtype
)
assert_equal
(
arr
,
elements
,
simple_dtype
)
assert_equal
(
arr
,
elements
,
packed_dtype
)
assert_equal
(
arr
,
elements
,
packed_dtype
)
arr
=
m
.
create_rec_partial_nested
(
3
)
arr
=
m
.
create_rec_partial_nested
(
3
)
assert
str
(
arr
.
dtype
)
==
partial_nested_fmt
()
assert
str
(
arr
.
dtype
)
==
partial_nested_fmt
()
assert
''
not
in
arr
.
dtype
.
fields
assert
""
not
in
arr
.
dtype
.
fields
assert
''
not
in
arr
.
dtype
.
fields
[
'a'
][
0
]
.
fields
assert
""
not
in
arr
.
dtype
.
fields
[
"a"
][
0
]
.
fields
assert
arr
.
dtype
.
itemsize
>
partial_dtype
.
itemsize
assert
arr
.
dtype
.
itemsize
>
partial_dtype
.
itemsize
np
.
testing
.
assert_equal
(
arr
[
'a'
],
m
.
create_rec_partial
(
3
))
np
.
testing
.
assert_equal
(
arr
[
"a"
],
m
.
create_rec_partial
(
3
))
def
test_array_constructors
():
def
test_array_constructors
():
data
=
np
.
arange
(
1
,
7
,
dtype
=
'int32'
)
data
=
np
.
arange
(
1
,
7
,
dtype
=
"int32"
)
for
i
in
range
(
8
):
for
i
in
range
(
8
):
np
.
testing
.
assert_array_equal
(
m
.
test_array_ctors
(
10
+
i
),
data
.
reshape
((
3
,
2
)))
np
.
testing
.
assert_array_equal
(
m
.
test_array_ctors
(
10
+
i
),
data
.
reshape
((
3
,
2
)))
np
.
testing
.
assert_array_equal
(
m
.
test_array_ctors
(
20
+
i
),
data
.
reshape
((
3
,
2
)))
np
.
testing
.
assert_array_equal
(
m
.
test_array_ctors
(
20
+
i
),
data
.
reshape
((
3
,
2
)))
...
@@ -205,82 +260,92 @@ def test_string_array():
...
@@ -205,82 +260,92 @@ def test_string_array():
"a='',b=''"
,
"a='',b=''"
,
"a='a',b='a'"
,
"a='a',b='a'"
,
"a='ab',b='ab'"
,
"a='ab',b='ab'"
,
"a='abc',b='abc'"
"a='abc',b='abc'"
,
]
]
dtype
=
arr
.
dtype
dtype
=
arr
.
dtype
assert
arr
[
'a'
]
.
tolist
()
==
[
b
''
,
b
'a'
,
b
'ab'
,
b
'abc'
]
assert
arr
[
"a"
]
.
tolist
()
==
[
b
""
,
b
"a"
,
b
"ab"
,
b
"abc"
]
assert
arr
[
'b'
]
.
tolist
()
==
[
b
''
,
b
'a'
,
b
'ab'
,
b
'abc'
]
assert
arr
[
"b"
]
.
tolist
()
==
[
b
""
,
b
"a"
,
b
"ab"
,
b
"abc"
]
arr
=
m
.
create_string_array
(
False
)
arr
=
m
.
create_string_array
(
False
)
assert
dtype
==
arr
.
dtype
assert
dtype
==
arr
.
dtype
def
test_array_array
():
def
test_array_array
():
from
sys
import
byteorder
from
sys
import
byteorder
e
=
'<'
if
byteorder
==
'little'
else
'>'
e
=
"<"
if
byteorder
==
"little"
else
">"
arr
=
m
.
create_array_array
(
3
)
arr
=
m
.
create_array_array
(
3
)
assert
str
(
arr
.
dtype
)
==
(
assert
str
(
arr
.
dtype
)
==
(
"{{'names':['a','b','c','d'], "
+
"{{'names':['a','b','c','d'], "
"'formats':[('S4', (3,)),('"
+
e
+
"i4', (2,)),('u1', (3,)),('{e}f4', (4, 2))], "
+
+
"'formats':[('S4', (3,)),('"
"'offsets':[0,12,20,24], 'itemsize':56}}"
)
.
format
(
e
=
e
)
+
e
+
"i4', (2,)),('u1', (3,)),('{e}f4', (4, 2))], "
+
"'offsets':[0,12,20,24], 'itemsize':56}}"
)
.
format
(
e
=
e
)
assert
m
.
print_array_array
(
arr
)
==
[
assert
m
.
print_array_array
(
arr
)
==
[
"a={{A,B,C,D},{K,L,M,N},{U,V,W,X}},b={0,1},"
+
"a={{A,B,C,D},{K,L,M,N},{U,V,W,X}},b={0,1},"
"c={0,1,2},d={{0,1},{10,11},{20,21},{30,31}}"
,
+
"c={0,1,2},d={{0,1},{10,11},{20,21},{30,31}}"
,
"a={{W,X,Y,Z},{G,H,I,J},{Q,R,S,T}},b={1000,1001},"
+
"a={{W,X,Y,Z},{G,H,I,J},{Q,R,S,T}},b={1000,1001},"
"c={10,11,12},d={{100,101},{110,111},{120,121},{130,131}}"
,
+
"c={10,11,12},d={{100,101},{110,111},{120,121},{130,131}}"
,
"a={{S,T,U,V},{C,D,E,F},{M,N,O,P}},b={2000,2001},"
+
"a={{S,T,U,V},{C,D,E,F},{M,N,O,P}},b={2000,2001},"
"c={20,21,22},d={{200,201},{210,211},{220,221},{230,231}}"
,
+
"c={20,21,22},d={{200,201},{210,211},{220,221},{230,231}}"
,
]
]
assert
arr
[
'a'
]
.
tolist
()
==
[[
b
'ABCD'
,
b
'KLMN'
,
b
'UVWX'
],
assert
arr
[
"a"
]
.
tolist
()
==
[
[
b
'WXYZ'
,
b
'GHIJ'
,
b
'QRST'
],
[
b
"ABCD"
,
b
"KLMN"
,
b
"UVWX"
],
[
b
'STUV'
,
b
'CDEF'
,
b
'MNOP'
]]
[
b
"WXYZ"
,
b
"GHIJ"
,
b
"QRST"
],
assert
arr
[
'b'
]
.
tolist
()
==
[[
0
,
1
],
[
1000
,
1001
],
[
2000
,
2001
]]
[
b
"STUV"
,
b
"CDEF"
,
b
"MNOP"
],
]
assert
arr
[
"b"
]
.
tolist
()
==
[[
0
,
1
],
[
1000
,
1001
],
[
2000
,
2001
]]
assert
m
.
create_array_array
(
0
)
.
dtype
==
arr
.
dtype
assert
m
.
create_array_array
(
0
)
.
dtype
==
arr
.
dtype
def
test_enum_array
():
def
test_enum_array
():
from
sys
import
byteorder
from
sys
import
byteorder
e
=
'<'
if
byteorder
==
'little'
else
'>'
e
=
"<"
if
byteorder
==
"little"
else
">"
arr
=
m
.
create_enum_array
(
3
)
arr
=
m
.
create_enum_array
(
3
)
dtype
=
arr
.
dtype
dtype
=
arr
.
dtype
assert
dtype
==
np
.
dtype
([(
'e1'
,
e
+
'i8'
),
(
'e2'
,
'u1'
)])
assert
dtype
==
np
.
dtype
([(
"e1"
,
e
+
"i8"
),
(
"e2"
,
"u1"
)])
assert
m
.
print_enum_array
(
arr
)
==
[
assert
m
.
print_enum_array
(
arr
)
==
[
"e1=A,e2=X"
,
"e1=B,e2=Y"
,
"e1=A,e2=X"
]
"e1=A,e2=X"
,
assert
arr
[
"e1"
]
.
tolist
()
==
[
-
1
,
1
,
-
1
]
"e1=B,e2=Y"
,
assert
arr
[
"e2"
]
.
tolist
()
==
[
1
,
2
,
1
]
"e1=A,e2=X"
]
assert
arr
[
'e1'
]
.
tolist
()
==
[
-
1
,
1
,
-
1
]
assert
arr
[
'e2'
]
.
tolist
()
==
[
1
,
2
,
1
]
assert
m
.
create_enum_array
(
0
)
.
dtype
==
dtype
assert
m
.
create_enum_array
(
0
)
.
dtype
==
dtype
def
test_complex_array
():
def
test_complex_array
():
from
sys
import
byteorder
from
sys
import
byteorder
e
=
'<'
if
byteorder
==
'little'
else
'>'
e
=
"<"
if
byteorder
==
"little"
else
">"
arr
=
m
.
create_complex_array
(
3
)
arr
=
m
.
create_complex_array
(
3
)
dtype
=
arr
.
dtype
dtype
=
arr
.
dtype
assert
dtype
==
np
.
dtype
([(
'cflt'
,
e
+
'c8'
),
(
'cdbl'
,
e
+
'c16'
)])
assert
dtype
==
np
.
dtype
([(
"cflt"
,
e
+
"c8"
),
(
"cdbl"
,
e
+
"c16"
)])
assert
m
.
print_complex_array
(
arr
)
==
[
assert
m
.
print_complex_array
(
arr
)
==
[
"c:(0,0.25),(0.5,0.75)"
,
"c:(0,0.25),(0.5,0.75)"
,
"c:(1,1.25),(1.5,1.75)"
,
"c:(1,1.25),(1.5,1.75)"
,
"c:(2,2.25),(2.5,2.75)"
"c:(2,2.25),(2.5,2.75)"
,
]
]
assert
arr
[
'cflt'
]
.
tolist
()
==
[
0.0
+
0.25
j
,
1.0
+
1.25
j
,
2.0
+
2.25
j
]
assert
arr
[
"cflt"
]
.
tolist
()
==
[
0.0
+
0.25
j
,
1.0
+
1.25
j
,
2.0
+
2.25
j
]
assert
arr
[
'cdbl'
]
.
tolist
()
==
[
0.5
+
0.75
j
,
1.5
+
1.75
j
,
2.5
+
2.75
j
]
assert
arr
[
"cdbl"
]
.
tolist
()
==
[
0.5
+
0.75
j
,
1.5
+
1.75
j
,
2.5
+
2.75
j
]
assert
m
.
create_complex_array
(
0
)
.
dtype
==
dtype
assert
m
.
create_complex_array
(
0
)
.
dtype
==
dtype
def
test_signature
(
doc
):
def
test_signature
(
doc
):
assert
doc
(
m
.
create_rec_nested
)
==
\
assert
(
"create_rec_nested(arg0: int) -> numpy.ndarray[NestedStruct]"
doc
(
m
.
create_rec_nested
)
==
"create_rec_nested(arg0: int) -> numpy.ndarray[NestedStruct]"
)
def
test_scalar_conversion
():
def
test_scalar_conversion
():
n
=
3
n
=
3
arrays
=
[
m
.
create_rec_simple
(
n
),
m
.
create_rec_packed
(
n
),
arrays
=
[
m
.
create_rec_nested
(
n
),
m
.
create_enum_array
(
n
)]
m
.
create_rec_simple
(
n
),
m
.
create_rec_packed
(
n
),
m
.
create_rec_nested
(
n
),
m
.
create_enum_array
(
n
),
]
funcs
=
[
m
.
f_simple
,
m
.
f_packed
,
m
.
f_nested
]
funcs
=
[
m
.
f_simple
,
m
.
f_packed
,
m
.
f_nested
]
for
i
,
func
in
enumerate
(
funcs
):
for
i
,
func
in
enumerate
(
funcs
):
...
@@ -290,7 +355,7 @@ def test_scalar_conversion():
...
@@ -290,7 +355,7 @@ def test_scalar_conversion():
else
:
else
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
func
(
arr
[
0
])
func
(
arr
[
0
])
assert
'incompatible function arguments'
in
str
(
excinfo
.
value
)
assert
"incompatible function arguments"
in
str
(
excinfo
.
value
)
def
test_vectorize
():
def
test_vectorize
():
...
@@ -304,14 +369,14 @@ def test_vectorize():
...
@@ -304,14 +369,14 @@ def test_vectorize():
def
test_cls_and_dtype_conversion
(
simple_dtype
):
def
test_cls_and_dtype_conversion
(
simple_dtype
):
s
=
m
.
SimpleStruct
()
s
=
m
.
SimpleStruct
()
assert
s
.
astuple
()
==
(
False
,
0
,
0.
,
0.
)
assert
s
.
astuple
()
==
(
False
,
0
,
0.
0
,
0.0
)
assert
m
.
SimpleStruct
.
fromtuple
(
s
.
astuple
())
.
astuple
()
==
s
.
astuple
()
assert
m
.
SimpleStruct
.
fromtuple
(
s
.
astuple
())
.
astuple
()
==
s
.
astuple
()
s
.
uint_
=
2
s
.
uint_
=
2
assert
m
.
f_simple
(
s
)
==
20
assert
m
.
f_simple
(
s
)
==
20
# Try as recarray of shape==(1,).
# Try as recarray of shape==(1,).
s_recarray
=
np
.
array
([(
False
,
2
,
0.
,
0.
)],
dtype
=
simple_dtype
)
s_recarray
=
np
.
array
([(
False
,
2
,
0.
0
,
0.0
)],
dtype
=
simple_dtype
)
# Show that this will work for vectorized case.
# Show that this will work for vectorized case.
np
.
testing
.
assert_array_equal
(
m
.
f_simple_vectorized
(
s_recarray
),
[
20
])
np
.
testing
.
assert_array_equal
(
m
.
f_simple_vectorized
(
s_recarray
),
[
20
])
...
@@ -327,17 +392,16 @@ def test_cls_and_dtype_conversion(simple_dtype):
...
@@ -327,17 +392,16 @@ def test_cls_and_dtype_conversion(simple_dtype):
assert
s_recarray_scalar
.
dtype
==
simple_dtype
assert
s_recarray_scalar
.
dtype
==
simple_dtype
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
f_simple
(
s_recarray_scalar
)
m
.
f_simple
(
s_recarray_scalar
)
assert
'incompatible function arguments'
in
str
(
excinfo
.
value
)
assert
"incompatible function arguments"
in
str
(
excinfo
.
value
)
# Explicitly convert to m.SimpleStruct.
# Explicitly convert to m.SimpleStruct.
assert
m
.
f_simple
(
assert
m
.
f_simple
(
m
.
SimpleStruct
.
fromtuple
(
s_recarray_scalar
.
item
()))
==
20
m
.
SimpleStruct
.
fromtuple
(
s_recarray_scalar
.
item
()))
==
20
# Show that an array of dtype=object does *not* convert.
# Show that an array of dtype=object does *not* convert.
s_array_object
=
np
.
array
([
s
])
s_array_object
=
np
.
array
([
s
])
assert
s_array_object
.
dtype
==
object
assert
s_array_object
.
dtype
==
object
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
f_simple_vectorized
(
s_array_object
)
m
.
f_simple_vectorized
(
s_array_object
)
assert
'incompatible function arguments'
in
str
(
excinfo
.
value
)
assert
"incompatible function arguments"
in
str
(
excinfo
.
value
)
# Explicitly convert to `np.array(..., dtype=simple_dtype)`
# Explicitly convert to `np.array(..., dtype=simple_dtype)`
s_array
=
np
.
array
([
s
.
astuple
()],
dtype
=
simple_dtype
)
s_array
=
np
.
array
([
s
.
astuple
()],
dtype
=
simple_dtype
)
np
.
testing
.
assert_array_equal
(
m
.
f_simple_vectorized
(
s_array
),
[
20
])
np
.
testing
.
assert_array_equal
(
m
.
f_simple_vectorized
(
s_array
),
[
20
])
...
@@ -346,12 +410,13 @@ def test_cls_and_dtype_conversion(simple_dtype):
...
@@ -346,12 +410,13 @@ def test_cls_and_dtype_conversion(simple_dtype):
def
test_register_dtype
():
def
test_register_dtype
():
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
register_dtype
()
m
.
register_dtype
()
assert
'dtype is already registered'
in
str
(
excinfo
.
value
)
assert
"dtype is already registered"
in
str
(
excinfo
.
value
)
@pytest.mark.xfail
(
"env.PYPY"
)
@pytest.mark.xfail
(
"env.PYPY"
)
def
test_str_leak
():
def
test_str_leak
():
from
sys
import
getrefcount
from
sys
import
getrefcount
fmt
=
"f4"
fmt
=
"f4"
pytest
.
gc_collect
()
pytest
.
gc_collect
()
start
=
getrefcount
(
fmt
)
start
=
getrefcount
(
fmt
)
...
...
tests/test_numpy_vectorize.py
View file @
c50f90ec
...
@@ -17,28 +17,40 @@ def test_vectorize(capture):
...
@@ -17,28 +17,40 @@ def test_vectorize(capture):
assert
capture
==
"my_func(x:int=1, y:float=2, z:float=3)"
assert
capture
==
"my_func(x:int=1, y:float=2, z:float=3)"
with
capture
:
with
capture
:
assert
np
.
allclose
(
f
(
np
.
array
([
1
,
3
]),
np
.
array
([
2
,
4
]),
3
),
[
6
,
36
])
assert
np
.
allclose
(
f
(
np
.
array
([
1
,
3
]),
np
.
array
([
2
,
4
]),
3
),
[
6
,
36
])
assert
capture
==
"""
assert
(
capture
==
"""
my_func(x:int=1, y:float=2, z:float=3)
my_func(x:int=1, y:float=2, z:float=3)
my_func(x:int=3, y:float=4, z:float=3)
my_func(x:int=3, y:float=4, z:float=3)
"""
"""
)
with
capture
:
with
capture
:
a
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
order
=
'F'
)
a
=
np
.
array
([[
1
,
2
],
[
3
,
4
]],
order
=
"F"
)
b
=
np
.
array
([[
10
,
20
],
[
30
,
40
]],
order
=
'F'
)
b
=
np
.
array
([[
10
,
20
],
[
30
,
40
]],
order
=
"F"
)
c
=
3
c
=
3
result
=
f
(
a
,
b
,
c
)
result
=
f
(
a
,
b
,
c
)
assert
np
.
allclose
(
result
,
a
*
b
*
c
)
assert
np
.
allclose
(
result
,
a
*
b
*
c
)
assert
result
.
flags
.
f_contiguous
assert
result
.
flags
.
f_contiguous
# All inputs are F order and full or singletons, so we the result is in col-major order:
# All inputs are F order and full or singletons, so we the result is in col-major order:
assert
capture
==
"""
assert
(
capture
==
"""
my_func(x:int=1, y:float=10, z:float=3)
my_func(x:int=1, y:float=10, z:float=3)
my_func(x:int=3, y:float=30, z:float=3)
my_func(x:int=3, y:float=30, z:float=3)
my_func(x:int=2, y:float=20, z:float=3)
my_func(x:int=2, y:float=20, z:float=3)
my_func(x:int=4, y:float=40, z:float=3)
my_func(x:int=4, y:float=40, z:float=3)
"""
"""
)
with
capture
:
with
capture
:
a
,
b
,
c
=
np
.
array
([[
1
,
3
,
5
],
[
7
,
9
,
11
]]),
np
.
array
([[
2
,
4
,
6
],
[
8
,
10
,
12
]]),
3
a
,
b
,
c
=
(
np
.
array
([[
1
,
3
,
5
],
[
7
,
9
,
11
]]),
np
.
array
([[
2
,
4
,
6
],
[
8
,
10
,
12
]]),
3
,
)
assert
np
.
allclose
(
f
(
a
,
b
,
c
),
a
*
b
*
c
)
assert
np
.
allclose
(
f
(
a
,
b
,
c
),
a
*
b
*
c
)
assert
capture
==
"""
assert
(
capture
==
"""
my_func(x:int=1, y:float=2, z:float=3)
my_func(x:int=1, y:float=2, z:float=3)
my_func(x:int=3, y:float=4, z:float=3)
my_func(x:int=3, y:float=4, z:float=3)
my_func(x:int=5, y:float=6, z:float=3)
my_func(x:int=5, y:float=6, z:float=3)
...
@@ -46,10 +58,13 @@ def test_vectorize(capture):
...
@@ -46,10 +58,13 @@ def test_vectorize(capture):
my_func(x:int=9, y:float=10, z:float=3)
my_func(x:int=9, y:float=10, z:float=3)
my_func(x:int=11, y:float=12, z:float=3)
my_func(x:int=11, y:float=12, z:float=3)
"""
"""
)
with
capture
:
with
capture
:
a
,
b
,
c
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]]),
np
.
array
([
2
,
3
,
4
]),
2
a
,
b
,
c
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]]),
np
.
array
([
2
,
3
,
4
]),
2
assert
np
.
allclose
(
f
(
a
,
b
,
c
),
a
*
b
*
c
)
assert
np
.
allclose
(
f
(
a
,
b
,
c
),
a
*
b
*
c
)
assert
capture
==
"""
assert
(
capture
==
"""
my_func(x:int=1, y:float=2, z:float=2)
my_func(x:int=1, y:float=2, z:float=2)
my_func(x:int=2, y:float=3, z:float=2)
my_func(x:int=2, y:float=3, z:float=2)
my_func(x:int=3, y:float=4, z:float=2)
my_func(x:int=3, y:float=4, z:float=2)
...
@@ -57,10 +72,13 @@ def test_vectorize(capture):
...
@@ -57,10 +72,13 @@ def test_vectorize(capture):
my_func(x:int=5, y:float=3, z:float=2)
my_func(x:int=5, y:float=3, z:float=2)
my_func(x:int=6, y:float=4, z:float=2)
my_func(x:int=6, y:float=4, z:float=2)
"""
"""
)
with
capture
:
with
capture
:
a
,
b
,
c
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]]),
np
.
array
([[
2
],
[
3
]]),
2
a
,
b
,
c
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]]),
np
.
array
([[
2
],
[
3
]]),
2
assert
np
.
allclose
(
f
(
a
,
b
,
c
),
a
*
b
*
c
)
assert
np
.
allclose
(
f
(
a
,
b
,
c
),
a
*
b
*
c
)
assert
capture
==
"""
assert
(
capture
==
"""
my_func(x:int=1, y:float=2, z:float=2)
my_func(x:int=1, y:float=2, z:float=2)
my_func(x:int=2, y:float=2, z:float=2)
my_func(x:int=2, y:float=2, z:float=2)
my_func(x:int=3, y:float=2, z:float=2)
my_func(x:int=3, y:float=2, z:float=2)
...
@@ -68,10 +86,17 @@ def test_vectorize(capture):
...
@@ -68,10 +86,17 @@ def test_vectorize(capture):
my_func(x:int=5, y:float=3, z:float=2)
my_func(x:int=5, y:float=3, z:float=2)
my_func(x:int=6, y:float=3, z:float=2)
my_func(x:int=6, y:float=3, z:float=2)
"""
"""
)
with
capture
:
with
capture
:
a
,
b
,
c
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]],
order
=
'F'
),
np
.
array
([[
2
],
[
3
]]),
2
a
,
b
,
c
=
(
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]],
order
=
"F"
),
np
.
array
([[
2
],
[
3
]]),
2
,
)
assert
np
.
allclose
(
f
(
a
,
b
,
c
),
a
*
b
*
c
)
assert
np
.
allclose
(
f
(
a
,
b
,
c
),
a
*
b
*
c
)
assert
capture
==
"""
assert
(
capture
==
"""
my_func(x:int=1, y:float=2, z:float=2)
my_func(x:int=1, y:float=2, z:float=2)
my_func(x:int=2, y:float=2, z:float=2)
my_func(x:int=2, y:float=2, z:float=2)
my_func(x:int=3, y:float=2, z:float=2)
my_func(x:int=3, y:float=2, z:float=2)
...
@@ -79,36 +104,53 @@ def test_vectorize(capture):
...
@@ -79,36 +104,53 @@ def test_vectorize(capture):
my_func(x:int=5, y:float=3, z:float=2)
my_func(x:int=5, y:float=3, z:float=2)
my_func(x:int=6, y:float=3, z:float=2)
my_func(x:int=6, y:float=3, z:float=2)
"""
"""
)
with
capture
:
with
capture
:
a
,
b
,
c
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]])[::,
::
2
],
np
.
array
([[
2
],
[
3
]]),
2
a
,
b
,
c
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]])[::,
::
2
],
np
.
array
([[
2
],
[
3
]]),
2
assert
np
.
allclose
(
f
(
a
,
b
,
c
),
a
*
b
*
c
)
assert
np
.
allclose
(
f
(
a
,
b
,
c
),
a
*
b
*
c
)
assert
capture
==
"""
assert
(
capture
==
"""
my_func(x:int=1, y:float=2, z:float=2)
my_func(x:int=1, y:float=2, z:float=2)
my_func(x:int=3, y:float=2, z:float=2)
my_func(x:int=3, y:float=2, z:float=2)
my_func(x:int=4, y:float=3, z:float=2)
my_func(x:int=4, y:float=3, z:float=2)
my_func(x:int=6, y:float=3, z:float=2)
my_func(x:int=6, y:float=3, z:float=2)
"""
"""
)
with
capture
:
with
capture
:
a
,
b
,
c
=
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]],
order
=
'F'
)[::,
::
2
],
np
.
array
([[
2
],
[
3
]]),
2
a
,
b
,
c
=
(
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]],
order
=
"F"
)[::,
::
2
],
np
.
array
([[
2
],
[
3
]]),
2
,
)
assert
np
.
allclose
(
f
(
a
,
b
,
c
),
a
*
b
*
c
)
assert
np
.
allclose
(
f
(
a
,
b
,
c
),
a
*
b
*
c
)
assert
capture
==
"""
assert
(
capture
==
"""
my_func(x:int=1, y:float=2, z:float=2)
my_func(x:int=1, y:float=2, z:float=2)
my_func(x:int=3, y:float=2, z:float=2)
my_func(x:int=3, y:float=2, z:float=2)
my_func(x:int=4, y:float=3, z:float=2)
my_func(x:int=4, y:float=3, z:float=2)
my_func(x:int=6, y:float=3, z:float=2)
my_func(x:int=6, y:float=3, z:float=2)
"""
"""
)
def
test_type_selection
():
def
test_type_selection
():
assert
m
.
selective_func
(
np
.
array
([
1
],
dtype
=
np
.
int32
))
==
"Int branch taken."
assert
m
.
selective_func
(
np
.
array
([
1
],
dtype
=
np
.
int32
))
==
"Int branch taken."
assert
m
.
selective_func
(
np
.
array
([
1.0
],
dtype
=
np
.
float32
))
==
"Float branch taken."
assert
m
.
selective_func
(
np
.
array
([
1.0
],
dtype
=
np
.
float32
))
==
"Float branch taken."
assert
m
.
selective_func
(
np
.
array
([
1.0
j
],
dtype
=
np
.
complex64
))
==
"Complex float branch taken."
assert
(
m
.
selective_func
(
np
.
array
([
1.0
j
],
dtype
=
np
.
complex64
))
==
"Complex float branch taken."
)
def
test_docs
(
doc
):
def
test_docs
(
doc
):
assert
doc
(
m
.
vectorized_func
)
==
"""
assert
(
doc
(
m
.
vectorized_func
)
==
"""
vectorized_func(arg0: numpy.ndarray[numpy.int32], arg1: numpy.ndarray[numpy.float32], arg2: numpy.ndarray[numpy.float64]) -> object
vectorized_func(arg0: numpy.ndarray[numpy.int32], arg1: numpy.ndarray[numpy.float32], arg2: numpy.ndarray[numpy.float64]) -> object
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
def
test_trivial_broadcasting
():
def
test_trivial_broadcasting
():
...
@@ -116,16 +158,24 @@ def test_trivial_broadcasting():
...
@@ -116,16 +158,24 @@ def test_trivial_broadcasting():
assert
vectorized_is_trivial
(
1
,
2
,
3
)
==
trivial
.
c_trivial
assert
vectorized_is_trivial
(
1
,
2
,
3
)
==
trivial
.
c_trivial
assert
vectorized_is_trivial
(
np
.
array
(
1
),
np
.
array
(
2
),
3
)
==
trivial
.
c_trivial
assert
vectorized_is_trivial
(
np
.
array
(
1
),
np
.
array
(
2
),
3
)
==
trivial
.
c_trivial
assert
vectorized_is_trivial
(
np
.
array
([
1
,
3
]),
np
.
array
([
2
,
4
]),
3
)
==
trivial
.
c_trivial
assert
(
vectorized_is_trivial
(
np
.
array
([
1
,
3
]),
np
.
array
([
2
,
4
]),
3
)
==
trivial
.
c_trivial
)
assert
trivial
.
c_trivial
==
vectorized_is_trivial
(
assert
trivial
.
c_trivial
==
vectorized_is_trivial
(
np
.
array
([[
1
,
3
,
5
],
[
7
,
9
,
11
]]),
np
.
array
([[
2
,
4
,
6
],
[
8
,
10
,
12
]]),
3
)
np
.
array
([[
1
,
3
,
5
],
[
7
,
9
,
11
]]),
np
.
array
([[
2
,
4
,
6
],
[
8
,
10
,
12
]]),
3
assert
vectorized_is_trivial
(
)
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]]),
np
.
array
([
2
,
3
,
4
]),
2
)
==
trivial
.
non_trivial
assert
(
assert
vectorized_is_trivial
(
vectorized_is_trivial
(
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]]),
np
.
array
([
2
,
3
,
4
]),
2
)
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]]),
np
.
array
([[
2
],
[
3
]]),
2
)
==
trivial
.
non_trivial
==
trivial
.
non_trivial
z1
=
np
.
array
([[
1
,
2
,
3
,
4
],
[
5
,
6
,
7
,
8
]],
dtype
=
'int32'
)
)
z2
=
np
.
array
(
z1
,
dtype
=
'float32'
)
assert
(
z3
=
np
.
array
(
z1
,
dtype
=
'float64'
)
vectorized_is_trivial
(
np
.
array
([[
1
,
2
,
3
],
[
4
,
5
,
6
]]),
np
.
array
([[
2
],
[
3
]]),
2
)
==
trivial
.
non_trivial
)
z1
=
np
.
array
([[
1
,
2
,
3
,
4
],
[
5
,
6
,
7
,
8
]],
dtype
=
"int32"
)
z2
=
np
.
array
(
z1
,
dtype
=
"float32"
)
z3
=
np
.
array
(
z1
,
dtype
=
"float64"
)
assert
vectorized_is_trivial
(
z1
,
z2
,
z3
)
==
trivial
.
c_trivial
assert
vectorized_is_trivial
(
z1
,
z2
,
z3
)
==
trivial
.
c_trivial
assert
vectorized_is_trivial
(
1
,
z2
,
z3
)
==
trivial
.
c_trivial
assert
vectorized_is_trivial
(
1
,
z2
,
z3
)
==
trivial
.
c_trivial
assert
vectorized_is_trivial
(
z1
,
1
,
z3
)
==
trivial
.
c_trivial
assert
vectorized_is_trivial
(
z1
,
1
,
z3
)
==
trivial
.
c_trivial
...
@@ -135,7 +185,7 @@ def test_trivial_broadcasting():
...
@@ -135,7 +185,7 @@ def test_trivial_broadcasting():
assert
vectorized_is_trivial
(
1
,
1
,
z3
[::
2
,
::
2
])
==
trivial
.
non_trivial
assert
vectorized_is_trivial
(
1
,
1
,
z3
[::
2
,
::
2
])
==
trivial
.
non_trivial
assert
vectorized_is_trivial
(
z1
,
1
,
z3
[
1
::
4
,
1
::
4
])
==
trivial
.
c_trivial
assert
vectorized_is_trivial
(
z1
,
1
,
z3
[
1
::
4
,
1
::
4
])
==
trivial
.
c_trivial
y1
=
np
.
array
(
z1
,
order
=
'F'
)
y1
=
np
.
array
(
z1
,
order
=
"F"
)
y2
=
np
.
array
(
y1
)
y2
=
np
.
array
(
y1
)
y3
=
np
.
array
(
y1
)
y3
=
np
.
array
(
y1
)
assert
vectorized_is_trivial
(
y1
,
y2
,
y3
)
==
trivial
.
f_trivial
assert
vectorized_is_trivial
(
y1
,
y2
,
y3
)
==
trivial
.
f_trivial
...
@@ -156,30 +206,41 @@ def test_trivial_broadcasting():
...
@@ -156,30 +206,41 @@ def test_trivial_broadcasting():
def
test_passthrough_arguments
(
doc
):
def
test_passthrough_arguments
(
doc
):
assert
doc
(
m
.
vec_passthrough
)
==
(
assert
doc
(
m
.
vec_passthrough
)
==
(
"vec_passthrough("
+
", "
.
join
([
"vec_passthrough("
"arg0: float"
,
+
", "
.
join
(
"arg1: numpy.ndarray[numpy.float64]"
,
[
"arg2: numpy.ndarray[numpy.float64]"
,
"arg0: float"
,
"arg3: numpy.ndarray[numpy.int32]"
,
"arg1: numpy.ndarray[numpy.float64]"
,
"arg4: int"
,
"arg2: numpy.ndarray[numpy.float64]"
,
"arg5: m.numpy_vectorize.NonPODClass"
,
"arg3: numpy.ndarray[numpy.int32]"
,
"arg6: numpy.ndarray[numpy.float64]"
])
+
") -> object"
)
"arg4: int"
,
"arg5: m.numpy_vectorize.NonPODClass"
,
b
=
np
.
array
([[
10
,
20
,
30
]],
dtype
=
'float64'
)
"arg6: numpy.ndarray[numpy.float64]"
,
]
)
+
") -> object"
)
b
=
np
.
array
([[
10
,
20
,
30
]],
dtype
=
"float64"
)
c
=
np
.
array
([
100
,
200
])
# NOT a vectorized argument
c
=
np
.
array
([
100
,
200
])
# NOT a vectorized argument
d
=
np
.
array
([[
1000
],
[
2000
],
[
3000
]],
dtype
=
'int'
)
d
=
np
.
array
([[
1000
],
[
2000
],
[
3000
]],
dtype
=
"int"
)
g
=
np
.
array
([[
1000000
,
2000000
,
3000000
]],
dtype
=
'int'
)
# requires casting
g
=
np
.
array
([[
1000000
,
2000000
,
3000000
]],
dtype
=
"int"
)
# requires casting
assert
np
.
all
(
assert
np
.
all
(
m
.
vec_passthrough
(
1
,
b
,
c
,
d
,
10000
,
m
.
NonPODClass
(
100000
),
g
)
==
m
.
vec_passthrough
(
1
,
b
,
c
,
d
,
10000
,
m
.
NonPODClass
(
100000
),
g
)
np
.
array
([[
1111111
,
2111121
,
3111131
],
==
np
.
array
(
[
1112111
,
2112121
,
3112131
],
[
[
1113111
,
2113121
,
3113131
]]))
[
1111111
,
2111121
,
3111131
],
[
1112111
,
2112121
,
3112131
],
[
1113111
,
2113121
,
3113131
],
]
)
)
def
test_method_vectorization
():
def
test_method_vectorization
():
o
=
m
.
VectorizeTestClass
(
3
)
o
=
m
.
VectorizeTestClass
(
3
)
x
=
np
.
array
([
1
,
2
],
dtype
=
'int'
)
x
=
np
.
array
([
1
,
2
],
dtype
=
"int"
)
y
=
np
.
array
([[
10
],
[
20
]],
dtype
=
'float32'
)
y
=
np
.
array
([[
10
],
[
20
]],
dtype
=
"float32"
)
assert
np
.
all
(
o
.
method
(
x
,
y
)
==
[[
14
,
15
],
[
24
,
25
]])
assert
np
.
all
(
o
.
method
(
x
,
y
)
==
[[
14
,
15
],
[
24
,
25
]])
...
@@ -188,7 +249,7 @@ def test_array_collapse():
...
@@ -188,7 +249,7 @@ def test_array_collapse():
assert
not
isinstance
(
m
.
vectorized_func
(
np
.
array
(
1
),
2
,
3
),
np
.
ndarray
)
assert
not
isinstance
(
m
.
vectorized_func
(
np
.
array
(
1
),
2
,
3
),
np
.
ndarray
)
z
=
m
.
vectorized_func
([
1
],
2
,
3
)
z
=
m
.
vectorized_func
([
1
],
2
,
3
)
assert
isinstance
(
z
,
np
.
ndarray
)
assert
isinstance
(
z
,
np
.
ndarray
)
assert
z
.
shape
==
(
1
,
)
assert
z
.
shape
==
(
1
,)
z
=
m
.
vectorized_func
(
1
,
[[[
2
]]],
3
)
z
=
m
.
vectorized_func
(
1
,
[[[
2
]]],
3
)
assert
isinstance
(
z
,
np
.
ndarray
)
assert
isinstance
(
z
,
np
.
ndarray
)
assert
z
.
shape
==
(
1
,
1
,
1
)
assert
z
.
shape
==
(
1
,
1
,
1
)
...
...
tests/test_opaque_types.py
View file @
c50f90ec
...
@@ -32,12 +32,15 @@ def test_pointers(msg):
...
@@ -32,12 +32,15 @@ def test_pointers(msg):
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
get_void_ptr_value
([
1
,
2
,
3
])
# This should not work
m
.
get_void_ptr_value
([
1
,
2
,
3
])
# This should not work
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
get_void_ptr_value(): incompatible function arguments. The following argument types are supported:
get_void_ptr_value(): incompatible function arguments. The following argument types are supported:
1. (arg0: capsule) -> int
1. (arg0: capsule) -> int
Invoked with: [1, 2, 3]
Invoked with: [1, 2, 3]
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
assert
m
.
return_null_str
()
is
None
assert
m
.
return_null_str
()
is
None
assert
m
.
get_null_str_value
(
m
.
return_null_str
())
is
not
None
assert
m
.
get_null_str_value
(
m
.
return_null_str
())
is
not
None
...
...
tests/test_operator_overloading.py
View file @
c50f90ec
...
@@ -56,23 +56,23 @@ def test_operator_overloading():
...
@@ -56,23 +56,23 @@ def test_operator_overloading():
del
v3
del
v3
assert
cstats
.
alive
()
==
0
assert
cstats
.
alive
()
==
0
assert
cstats
.
values
()
==
[
assert
cstats
.
values
()
==
[
'[1.000000, 2.000000]'
,
"[1.000000, 2.000000]"
,
'[3.000000, -1.000000]'
,
"[3.000000, -1.000000]"
,
'[1.000000, 2.000000]'
,
"[1.000000, 2.000000]"
,
'[-3.000000, 1.000000]'
,
"[-3.000000, 1.000000]"
,
'[4.000000, 1.000000]'
,
"[4.000000, 1.000000]"
,
'[-2.000000, 3.000000]'
,
"[-2.000000, 3.000000]"
,
'[-7.000000, -6.000000]'
,
"[-7.000000, -6.000000]"
,
'[9.000000, 10.000000]'
,
"[9.000000, 10.000000]"
,
'[8.000000, 16.000000]'
,
"[8.000000, 16.000000]"
,
'[0.125000, 0.250000]'
,
"[0.125000, 0.250000]"
,
'[7.000000, 6.000000]'
,
"[7.000000, 6.000000]"
,
'[9.000000, 10.000000]'
,
"[9.000000, 10.000000]"
,
'[8.000000, 16.000000]'
,
"[8.000000, 16.000000]"
,
'[8.000000, 4.000000]'
,
"[8.000000, 4.000000]"
,
'[3.000000, -2.000000]'
,
"[3.000000, -2.000000]"
,
'[3.000000, -0.500000]'
,
"[3.000000, -0.500000]"
,
'[6.000000, -2.000000]'
,
"[6.000000, -2.000000]"
,
]
]
assert
cstats
.
default_constructions
==
0
assert
cstats
.
default_constructions
==
0
assert
cstats
.
copy_constructions
==
0
assert
cstats
.
copy_constructions
==
0
...
...
tests/test_pickling.py
View file @
c50f90ec
...
@@ -42,5 +42,6 @@ def test_roundtrip_with_dict(cls_name):
...
@@ -42,5 +42,6 @@ def test_roundtrip_with_dict(cls_name):
def
test_enum_pickle
():
def
test_enum_pickle
():
from
pybind11_tests
import
enums
as
e
from
pybind11_tests
import
enums
as
e
data
=
pickle
.
dumps
(
e
.
EOne
,
2
)
data
=
pickle
.
dumps
(
e
.
EOne
,
2
)
assert
e
.
EOne
==
pickle
.
loads
(
data
)
assert
e
.
EOne
==
pickle
.
loads
(
data
)
tests/test_pytypes.py
View file @
c50f90ec
...
@@ -28,13 +28,16 @@ def test_list(capture, doc):
...
@@ -28,13 +28,16 @@ def test_list(capture, doc):
lst
.
append
(
"value2"
)
lst
.
append
(
"value2"
)
m
.
print_list
(
lst
)
m
.
print_list
(
lst
)
assert
capture
.
unordered
==
"""
assert
(
capture
.
unordered
==
"""
Entry at position 0: value
Entry at position 0: value
list item 0: inserted-0
list item 0: inserted-0
list item 1: overwritten
list item 1: overwritten
list item 2: inserted-2
list item 2: inserted-2
list item 3: value2
list item 3: value2
"""
"""
)
assert
doc
(
m
.
get_list
)
==
"get_list() -> list"
assert
doc
(
m
.
get_list
)
==
"get_list() -> list"
assert
doc
(
m
.
print_list
)
==
"print_list(arg0: list) -> None"
assert
doc
(
m
.
print_list
)
==
"print_list(arg0: list) -> None"
...
@@ -52,12 +55,15 @@ def test_set(capture, doc):
...
@@ -52,12 +55,15 @@ def test_set(capture, doc):
with
capture
:
with
capture
:
s
.
add
(
"key4"
)
s
.
add
(
"key4"
)
m
.
print_set
(
s
)
m
.
print_set
(
s
)
assert
capture
.
unordered
==
"""
assert
(
capture
.
unordered
==
"""
key: key1
key: key1
key: key2
key: key2
key: key3
key: key3
key: key4
key: key4
"""
"""
)
assert
not
m
.
set_contains
(
set
([]),
42
)
assert
not
m
.
set_contains
(
set
([]),
42
)
assert
m
.
set_contains
({
42
},
42
)
assert
m
.
set_contains
({
42
},
42
)
...
@@ -74,10 +80,13 @@ def test_dict(capture, doc):
...
@@ -74,10 +80,13 @@ def test_dict(capture, doc):
with
capture
:
with
capture
:
d
[
"key2"
]
=
"value2"
d
[
"key2"
]
=
"value2"
m
.
print_dict
(
d
)
m
.
print_dict
(
d
)
assert
capture
.
unordered
==
"""
assert
(
capture
.
unordered
==
"""
key: key, value=value
key: key, value=value
key: key2, value=value2
key: key2, value=value2
"""
"""
)
assert
not
m
.
dict_contains
({},
42
)
assert
not
m
.
dict_contains
({},
42
)
assert
m
.
dict_contains
({
42
:
None
},
42
)
assert
m
.
dict_contains
({
42
:
None
},
42
)
...
@@ -137,28 +146,37 @@ def test_capsule(capture):
...
@@ -137,28 +146,37 @@ def test_capsule(capture):
a
=
m
.
return_capsule_with_destructor
()
a
=
m
.
return_capsule_with_destructor
()
del
a
del
a
pytest
.
gc_collect
()
pytest
.
gc_collect
()
assert
capture
.
unordered
==
"""
assert
(
capture
.
unordered
==
"""
creating capsule
creating capsule
destructing capsule
destructing capsule
"""
"""
)
with
capture
:
with
capture
:
a
=
m
.
return_capsule_with_destructor_2
()
a
=
m
.
return_capsule_with_destructor_2
()
del
a
del
a
pytest
.
gc_collect
()
pytest
.
gc_collect
()
assert
capture
.
unordered
==
"""
assert
(
capture
.
unordered
==
"""
creating capsule
creating capsule
destructing capsule: 1234
destructing capsule: 1234
"""
"""
)
with
capture
:
with
capture
:
a
=
m
.
return_capsule_with_name_and_destructor
()
a
=
m
.
return_capsule_with_name_and_destructor
()
del
a
del
a
pytest
.
gc_collect
()
pytest
.
gc_collect
()
assert
capture
.
unordered
==
"""
assert
(
capture
.
unordered
==
"""
created capsule (1234, 'pointer type description')
created capsule (1234, 'pointer type description')
destructing capsule (1234, 'pointer type description')
destructing capsule (1234, 'pointer type description')
"""
"""
)
def
test_accessors
():
def
test_accessors
():
...
@@ -212,7 +230,7 @@ def test_constructors():
...
@@ -212,7 +230,7 @@ def test_constructors():
assert
m
.
default_constructors
()
==
expected
assert
m
.
default_constructors
()
==
expected
data
=
{
data
=
{
bytes
:
b
'41'
,
# Currently no supported or working conversions.
bytes
:
b
"41"
,
# Currently no supported or working conversions.
str
:
42
,
str
:
42
,
bool
:
"Not empty"
,
bool
:
"Not empty"
,
int
:
"42"
,
int
:
"42"
,
...
@@ -221,14 +239,14 @@ def test_constructors():
...
@@ -221,14 +239,14 @@ def test_constructors():
list
:
range
(
3
),
list
:
range
(
3
),
dict
:
[(
"two"
,
2
),
(
"one"
,
1
),
(
"three"
,
3
)],
dict
:
[(
"two"
,
2
),
(
"one"
,
1
),
(
"three"
,
3
)],
set
:
[
4
,
4
,
5
,
6
,
6
,
6
],
set
:
[
4
,
4
,
5
,
6
,
6
,
6
],
memoryview
:
b
'abc'
memoryview
:
b
"abc"
,
}
}
inputs
=
{
k
.
__name__
:
v
for
k
,
v
in
data
.
items
()}
inputs
=
{
k
.
__name__
:
v
for
k
,
v
in
data
.
items
()}
expected
=
{
k
.
__name__
:
k
(
v
)
for
k
,
v
in
data
.
items
()}
expected
=
{
k
.
__name__
:
k
(
v
)
for
k
,
v
in
data
.
items
()}
if
env
.
PY2
:
# Similar to the above. See comments above.
if
env
.
PY2
:
# Similar to the above. See comments above.
inputs
[
"bytes"
]
=
b
'41'
inputs
[
"bytes"
]
=
b
"41"
inputs
[
"str"
]
=
42
inputs
[
"str"
]
=
42
expected
[
"bytes"
]
=
b
'41'
expected
[
"bytes"
]
=
b
"41"
expected
[
"str"
]
=
u"42"
expected
[
"str"
]
=
u"42"
assert
m
.
converting_constructors
(
inputs
)
==
expected
assert
m
.
converting_constructors
(
inputs
)
==
expected
...
@@ -255,7 +273,8 @@ def test_non_converting_constructors():
...
@@ -255,7 +273,8 @@ def test_non_converting_constructors():
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
nonconverting_constructor
(
t
,
v
)
m
.
nonconverting_constructor
(
t
,
v
)
expected_error
=
"Object of type '{}' is not an instance of '{}'"
.
format
(
expected_error
=
"Object of type '{}' is not an instance of '{}'"
.
format
(
type
(
v
)
.
__name__
,
t
)
type
(
v
)
.
__name__
,
t
)
assert
str
(
excinfo
.
value
)
==
expected_error
assert
str
(
excinfo
.
value
)
==
expected_error
...
@@ -263,12 +282,12 @@ def test_pybind11_str_raw_str():
...
@@ -263,12 +282,12 @@ def test_pybind11_str_raw_str():
# specifically to exercise pybind11::str::raw_str
# specifically to exercise pybind11::str::raw_str
cvt
=
m
.
convert_to_pybind11_str
cvt
=
m
.
convert_to_pybind11_str
assert
cvt
(
u"Str"
)
==
u"Str"
assert
cvt
(
u"Str"
)
==
u"Str"
assert
cvt
(
b
'Bytes'
)
==
u"Bytes"
if
env
.
PY2
else
"b'Bytes'"
assert
cvt
(
b
"Bytes"
)
==
u"Bytes"
if
env
.
PY2
else
"b'Bytes'"
assert
cvt
(
None
)
==
u"None"
assert
cvt
(
None
)
==
u"None"
assert
cvt
(
False
)
==
u"False"
assert
cvt
(
False
)
==
u"False"
assert
cvt
(
True
)
==
u"True"
assert
cvt
(
True
)
==
u"True"
assert
cvt
(
42
)
==
u"42"
assert
cvt
(
42
)
==
u"42"
assert
cvt
(
2
**
65
)
==
u"36893488147419103232"
assert
cvt
(
2
**
65
)
==
u"36893488147419103232"
assert
cvt
(
-
1.50
)
==
u"-1.5"
assert
cvt
(
-
1.50
)
==
u"-1.5"
assert
cvt
(())
==
u"()"
assert
cvt
(())
==
u"()"
assert
cvt
((
18
,))
==
u"(18,)"
assert
cvt
((
18
,))
==
u"(18,)"
...
@@ -283,29 +302,40 @@ def test_pybind11_str_raw_str():
...
@@ -283,29 +302,40 @@ def test_pybind11_str_raw_str():
valid_utf8
=
valid_orig
.
encode
(
"utf-8"
)
valid_utf8
=
valid_orig
.
encode
(
"utf-8"
)
valid_cvt
=
cvt
(
valid_utf8
)
valid_cvt
=
cvt
(
valid_utf8
)
assert
type
(
valid_cvt
)
==
bytes
# Probably surprising.
assert
type
(
valid_cvt
)
==
bytes
# Probably surprising.
assert
valid_cvt
==
b
'
\xc7\xb1
'
assert
valid_cvt
==
b
"
\xc7\xb1
"
malformed_utf8
=
b
'
\x80
'
malformed_utf8
=
b
"
\x80
"
malformed_cvt
=
cvt
(
malformed_utf8
)
malformed_cvt
=
cvt
(
malformed_utf8
)
assert
type
(
malformed_cvt
)
==
bytes
# Probably surprising.
assert
type
(
malformed_cvt
)
==
bytes
# Probably surprising.
assert
malformed_cvt
==
b
'
\x80
'
assert
malformed_cvt
==
b
"
\x80
"
def
test_implicit_casting
():
def
test_implicit_casting
():
"""Tests implicit casting when assigning or appending to dicts and lists."""
"""Tests implicit casting when assigning or appending to dicts and lists."""
z
=
m
.
get_implicit_casting
()
z
=
m
.
get_implicit_casting
()
assert
z
[
'd'
]
==
{
assert
z
[
"d"
]
==
{
'char*_i1'
:
'abc'
,
'char*_i2'
:
'abc'
,
'char*_e'
:
'abc'
,
'char*_p'
:
'abc'
,
"char*_i1"
:
"abc"
,
'str_i1'
:
'str'
,
'str_i2'
:
'str1'
,
'str_e'
:
'str2'
,
'str_p'
:
'str3'
,
"char*_i2"
:
"abc"
,
'int_i1'
:
42
,
'int_i2'
:
42
,
'int_e'
:
43
,
'int_p'
:
44
"char*_e"
:
"abc"
,
"char*_p"
:
"abc"
,
"str_i1"
:
"str"
,
"str_i2"
:
"str1"
,
"str_e"
:
"str2"
,
"str_p"
:
"str3"
,
"int_i1"
:
42
,
"int_i2"
:
42
,
"int_e"
:
43
,
"int_p"
:
44
,
}
}
assert
z
[
'l'
]
==
[
3
,
6
,
9
,
12
,
15
]
assert
z
[
"l"
]
==
[
3
,
6
,
9
,
12
,
15
]
def
test_print
(
capture
):
def
test_print
(
capture
):
with
capture
:
with
capture
:
m
.
print_function
()
m
.
print_function
()
assert
capture
==
"""
assert
(
capture
==
"""
Hello, World!
Hello, World!
1 2.0 three True -- multiple args
1 2.0 three True -- multiple args
*args-and-a-custom-separator
*args-and-a-custom-separator
...
@@ -313,14 +343,15 @@ def test_print(capture):
...
@@ -313,14 +343,15 @@ def test_print(capture):
flush
flush
py::print + str.format = this
py::print + str.format = this
"""
"""
)
assert
capture
.
stderr
==
"this goes to stderr"
assert
capture
.
stderr
==
"this goes to stderr"
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
print_failure
()
m
.
print_failure
()
assert
str
(
excinfo
.
value
)
==
"make_tuple(): unable to convert "
+
(
assert
str
(
excinfo
.
value
)
==
"make_tuple(): unable to convert "
+
(
"argument of type 'UnregisteredType' to Python object"
"argument of type 'UnregisteredType' to Python object"
if
debug_enabled
else
if
debug_enabled
"arguments to Python object (compile in debug mode for details)"
else
"arguments to Python object (compile in debug mode for details)"
)
)
...
@@ -342,8 +373,23 @@ def test_hash():
...
@@ -342,8 +373,23 @@ def test_hash():
def
test_number_protocol
():
def
test_number_protocol
():
for
a
,
b
in
[(
1
,
1
),
(
3
,
5
)]:
for
a
,
b
in
[(
1
,
1
),
(
3
,
5
)]:
li
=
[
a
==
b
,
a
!=
b
,
a
<
b
,
a
<=
b
,
a
>
b
,
a
>=
b
,
a
+
b
,
li
=
[
a
-
b
,
a
*
b
,
a
/
b
,
a
|
b
,
a
&
b
,
a
^
b
,
a
>>
b
,
a
<<
b
]
a
==
b
,
a
!=
b
,
a
<
b
,
a
<=
b
,
a
>
b
,
a
>=
b
,
a
+
b
,
a
-
b
,
a
*
b
,
a
/
b
,
a
|
b
,
a
&
b
,
a
^
b
,
a
>>
b
,
a
<<
b
,
]
assert
m
.
test_number_protocol
(
a
,
b
)
==
li
assert
m
.
test_number_protocol
(
a
,
b
)
==
li
...
@@ -360,13 +406,16 @@ def test_issue2361():
...
@@ -360,13 +406,16 @@ def test_issue2361():
assert
"'NoneType' object is not iterable"
in
str
(
excinfo
.
value
)
assert
"'NoneType' object is not iterable"
in
str
(
excinfo
.
value
)
@pytest.mark.parametrize
(
'method, args, fmt, expected_view'
,
[
@pytest.mark.parametrize
(
(
m
.
test_memoryview_object
,
(
b
'red'
,),
'B'
,
b
'red'
),
"method, args, fmt, expected_view"
,
(
m
.
test_memoryview_buffer_info
,
(
b
'green'
,),
'B'
,
b
'green'
),
[
(
m
.
test_memoryview_from_buffer
,
(
False
,),
'h'
,
[
3
,
1
,
4
,
1
,
5
]),
(
m
.
test_memoryview_object
,
(
b
"red"
,),
"B"
,
b
"red"
),
(
m
.
test_memoryview_from_buffer
,
(
True
,),
'H'
,
[
2
,
7
,
1
,
8
]),
(
m
.
test_memoryview_buffer_info
,
(
b
"green"
,),
"B"
,
b
"green"
),
(
m
.
test_memoryview_from_buffer_nativeformat
,
(),
'@i'
,
[
4
,
7
,
5
]),
(
m
.
test_memoryview_from_buffer
,
(
False
,),
"h"
,
[
3
,
1
,
4
,
1
,
5
]),
])
(
m
.
test_memoryview_from_buffer
,
(
True
,),
"H"
,
[
2
,
7
,
1
,
8
]),
(
m
.
test_memoryview_from_buffer_nativeformat
,
(),
"@i"
,
[
4
,
7
,
5
]),
],
)
def
test_memoryview
(
method
,
args
,
fmt
,
expected_view
):
def
test_memoryview
(
method
,
args
,
fmt
,
expected_view
):
view
=
method
(
*
args
)
view
=
method
(
*
args
)
assert
isinstance
(
view
,
memoryview
)
assert
isinstance
(
view
,
memoryview
)
...
@@ -380,12 +429,15 @@ def test_memoryview(method, args, fmt, expected_view):
...
@@ -380,12 +429,15 @@ def test_memoryview(method, args, fmt, expected_view):
@pytest.mark.xfail
(
"env.PYPY"
,
reason
=
"getrefcount is not available"
)
@pytest.mark.xfail
(
"env.PYPY"
,
reason
=
"getrefcount is not available"
)
@pytest.mark.parametrize
(
'method'
,
[
@pytest.mark.parametrize
(
m
.
test_memoryview_object
,
"method"
,
m
.
test_memoryview_buffer_info
,
[
])
m
.
test_memoryview_object
,
m
.
test_memoryview_buffer_info
,
],
)
def
test_memoryview_refcount
(
method
):
def
test_memoryview_refcount
(
method
):
buf
=
b
'
\x0a\x0b\x0c\x0d
'
buf
=
b
"
\x0a\x0b\x0c\x0d
"
ref_before
=
sys
.
getrefcount
(
buf
)
ref_before
=
sys
.
getrefcount
(
buf
)
view
=
method
(
buf
)
view
=
method
(
buf
)
ref_after
=
sys
.
getrefcount
(
buf
)
ref_after
=
sys
.
getrefcount
(
buf
)
...
@@ -396,13 +448,13 @@ def test_memoryview_refcount(method):
...
@@ -396,13 +448,13 @@ def test_memoryview_refcount(method):
def
test_memoryview_from_buffer_empty_shape
():
def
test_memoryview_from_buffer_empty_shape
():
view
=
m
.
test_memoryview_from_buffer_empty_shape
()
view
=
m
.
test_memoryview_from_buffer_empty_shape
()
assert
isinstance
(
view
,
memoryview
)
assert
isinstance
(
view
,
memoryview
)
assert
view
.
format
==
'B'
assert
view
.
format
==
"B"
if
env
.
PY2
:
if
env
.
PY2
:
# Python 2 behavior is weird, but Python 3 (the future) is fine.
# Python 2 behavior is weird, but Python 3 (the future) is fine.
# PyPy3 has <memoryview, while CPython 2 has <memory
# PyPy3 has <memoryview, while CPython 2 has <memory
assert
bytes
(
view
)
.
startswith
(
b
'<memory'
)
assert
bytes
(
view
)
.
startswith
(
b
"<memory"
)
else
:
else
:
assert
bytes
(
view
)
==
b
''
assert
bytes
(
view
)
==
b
""
def
test_test_memoryview_from_buffer_invalid_strides
():
def
test_test_memoryview_from_buffer_invalid_strides
():
...
@@ -422,13 +474,15 @@ def test_test_memoryview_from_buffer_nullptr():
...
@@ -422,13 +474,15 @@ def test_test_memoryview_from_buffer_nullptr():
def
test_memoryview_from_memory
():
def
test_memoryview_from_memory
():
view
=
m
.
test_memoryview_from_memory
()
view
=
m
.
test_memoryview_from_memory
()
assert
isinstance
(
view
,
memoryview
)
assert
isinstance
(
view
,
memoryview
)
assert
view
.
format
==
'B'
assert
view
.
format
==
"B"
assert
bytes
(
view
)
==
b
'
\xff\xe1\xab\x37
'
assert
bytes
(
view
)
==
b
"
\xff\xe1\xab\x37
"
def
test_builtin_functions
():
def
test_builtin_functions
():
assert
m
.
get_len
([
i
for
i
in
range
(
42
)])
==
42
assert
m
.
get_len
([
i
for
i
in
range
(
42
)])
==
42
with
pytest
.
raises
(
TypeError
)
as
exc_info
:
with
pytest
.
raises
(
TypeError
)
as
exc_info
:
m
.
get_len
(
i
for
i
in
range
(
42
))
m
.
get_len
(
i
for
i
in
range
(
42
))
assert
str
(
exc_info
.
value
)
in
[
"object of type 'generator' has no len()"
,
assert
str
(
exc_info
.
value
)
in
[
"'generator' has no length"
]
# PyPy
"object of type 'generator' has no len()"
,
"'generator' has no length"
,
]
# PyPy
tests/test_sequences_and_iterators.py
View file @
c50f90ec
...
@@ -10,7 +10,9 @@ def isclose(a, b, rel_tol=1e-05, abs_tol=0.0):
...
@@ -10,7 +10,9 @@ def isclose(a, b, rel_tol=1e-05, abs_tol=0.0):
def
allclose
(
a_list
,
b_list
,
rel_tol
=
1e-05
,
abs_tol
=
0.0
):
def
allclose
(
a_list
,
b_list
,
rel_tol
=
1e-05
,
abs_tol
=
0.0
):
return
all
(
isclose
(
a
,
b
,
rel_tol
=
rel_tol
,
abs_tol
=
abs_tol
)
for
a
,
b
in
zip
(
a_list
,
b_list
))
return
all
(
isclose
(
a
,
b
,
rel_tol
=
rel_tol
,
abs_tol
=
abs_tol
)
for
a
,
b
in
zip
(
a_list
,
b_list
)
)
def
test_generalized_iterators
():
def
test_generalized_iterators
():
...
@@ -51,7 +53,7 @@ def test_sequence():
...
@@ -51,7 +53,7 @@ def test_sequence():
cstats
=
ConstructorStats
.
get
(
m
.
Sequence
)
cstats
=
ConstructorStats
.
get
(
m
.
Sequence
)
s
=
m
.
Sequence
(
5
)
s
=
m
.
Sequence
(
5
)
assert
cstats
.
values
()
==
[
'of size'
,
'5'
]
assert
cstats
.
values
()
==
[
"of size"
,
"5"
]
assert
"Sequence"
in
repr
(
s
)
assert
"Sequence"
in
repr
(
s
)
assert
len
(
s
)
==
5
assert
len
(
s
)
==
5
...
@@ -62,16 +64,16 @@ def test_sequence():
...
@@ -62,16 +64,16 @@ def test_sequence():
assert
isclose
(
s
[
0
],
12.34
)
and
isclose
(
s
[
3
],
56.78
)
assert
isclose
(
s
[
0
],
12.34
)
and
isclose
(
s
[
3
],
56.78
)
rev
=
reversed
(
s
)
rev
=
reversed
(
s
)
assert
cstats
.
values
()
==
[
'of size'
,
'5'
]
assert
cstats
.
values
()
==
[
"of size"
,
"5"
]
rev2
=
s
[::
-
1
]
rev2
=
s
[::
-
1
]
assert
cstats
.
values
()
==
[
'of size'
,
'5'
]
assert
cstats
.
values
()
==
[
"of size"
,
"5"
]
it
=
iter
(
m
.
Sequence
(
0
))
it
=
iter
(
m
.
Sequence
(
0
))
for
_
in
range
(
3
):
# __next__ must continue to raise StopIteration
for
_
in
range
(
3
):
# __next__ must continue to raise StopIteration
with
pytest
.
raises
(
StopIteration
):
with
pytest
.
raises
(
StopIteration
):
next
(
it
)
next
(
it
)
assert
cstats
.
values
()
==
[
'of size'
,
'0'
]
assert
cstats
.
values
()
==
[
"of size"
,
"0"
]
expected
=
[
0
,
56.78
,
0
,
0
,
12.34
]
expected
=
[
0
,
56.78
,
0
,
0
,
12.34
]
assert
allclose
(
rev
,
expected
)
assert
allclose
(
rev
,
expected
)
...
@@ -79,7 +81,7 @@ def test_sequence():
...
@@ -79,7 +81,7 @@ def test_sequence():
assert
rev
==
rev2
assert
rev
==
rev2
rev
[
0
::
2
]
=
m
.
Sequence
([
2.0
,
2.0
,
2.0
])
rev
[
0
::
2
]
=
m
.
Sequence
([
2.0
,
2.0
,
2.0
])
assert
cstats
.
values
()
==
[
'of size'
,
'3'
,
'from std::vector'
]
assert
cstats
.
values
()
==
[
"of size"
,
"3"
,
"from std::vector"
]
assert
allclose
(
rev
,
[
2
,
56.78
,
2
,
0
,
2
])
assert
allclose
(
rev
,
[
2
,
56.78
,
2
,
0
,
2
])
...
@@ -103,10 +105,11 @@ def test_sequence():
...
@@ -103,10 +105,11 @@ def test_sequence():
def
test_sequence_length
():
def
test_sequence_length
():
"""#2076: Exception raised by len(arg) should be propagated """
"""#2076: Exception raised by len(arg) should be propagated """
class
BadLen
(
RuntimeError
):
class
BadLen
(
RuntimeError
):
pass
pass
class
SequenceLike
()
:
class
SequenceLike
:
def
__getitem__
(
self
,
i
):
def
__getitem__
(
self
,
i
):
return
None
return
None
...
@@ -121,17 +124,17 @@ def test_sequence_length():
...
@@ -121,17 +124,17 @@ def test_sequence_length():
def
test_map_iterator
():
def
test_map_iterator
():
sm
=
m
.
StringMap
({
'hi'
:
'bye'
,
'black'
:
'white'
})
sm
=
m
.
StringMap
({
"hi"
:
"bye"
,
"black"
:
"white"
})
assert
sm
[
'hi'
]
==
'bye'
assert
sm
[
"hi"
]
==
"bye"
assert
len
(
sm
)
==
2
assert
len
(
sm
)
==
2
assert
sm
[
'black'
]
==
'white'
assert
sm
[
"black"
]
==
"white"
with
pytest
.
raises
(
KeyError
):
with
pytest
.
raises
(
KeyError
):
assert
sm
[
'orange'
]
assert
sm
[
"orange"
]
sm
[
'orange'
]
=
'banana'
sm
[
"orange"
]
=
"banana"
assert
sm
[
'orange'
]
==
'banana'
assert
sm
[
"orange"
]
==
"banana"
expected
=
{
'hi'
:
'bye'
,
'black'
:
'white'
,
'orange'
:
'banana'
}
expected
=
{
"hi"
:
"bye"
,
"black"
:
"white"
,
"orange"
:
"banana"
}
for
k
in
sm
:
for
k
in
sm
:
assert
sm
[
k
]
==
expected
[
k
]
assert
sm
[
k
]
==
expected
[
k
]
for
k
,
v
in
sm
.
items
():
for
k
,
v
in
sm
.
items
():
...
@@ -179,7 +182,8 @@ def test_iterator_passthrough():
...
@@ -179,7 +182,8 @@ def test_iterator_passthrough():
"""#181: iterator passthrough did not compile"""
"""#181: iterator passthrough did not compile"""
from
pybind11_tests.sequences_and_iterators
import
iterator_passthrough
from
pybind11_tests.sequences_and_iterators
import
iterator_passthrough
assert
list
(
iterator_passthrough
(
iter
([
3
,
5
,
7
,
9
,
11
,
13
,
15
])))
==
[
3
,
5
,
7
,
9
,
11
,
13
,
15
]
values
=
[
3
,
5
,
7
,
9
,
11
,
13
,
15
]
assert
list
(
iterator_passthrough
(
iter
(
values
)))
==
values
def
test_iterator_rvp
():
def
test_iterator_rvp
():
...
...
tests/test_smart_ptr.py
View file @
c50f90ec
...
@@ -7,7 +7,9 @@ from pybind11_tests import ConstructorStats # noqa: E402
...
@@ -7,7 +7,9 @@ from pybind11_tests import ConstructorStats # noqa: E402
def
test_smart_ptr
(
capture
):
def
test_smart_ptr
(
capture
):
# Object1
# Object1
for
i
,
o
in
enumerate
([
m
.
make_object_1
(),
m
.
make_object_2
(),
m
.
MyObject1
(
3
)],
start
=
1
):
for
i
,
o
in
enumerate
(
[
m
.
make_object_1
(),
m
.
make_object_2
(),
m
.
MyObject1
(
3
)],
start
=
1
):
assert
o
.
getRefCount
()
==
1
assert
o
.
getRefCount
()
==
1
with
capture
:
with
capture
:
m
.
print_object_1
(
o
)
m
.
print_object_1
(
o
)
...
@@ -16,8 +18,9 @@ def test_smart_ptr(capture):
...
@@ -16,8 +18,9 @@ def test_smart_ptr(capture):
m
.
print_object_4
(
o
)
m
.
print_object_4
(
o
)
assert
capture
==
"MyObject1[{i}]
\n
"
.
format
(
i
=
i
)
*
4
assert
capture
==
"MyObject1[{i}]
\n
"
.
format
(
i
=
i
)
*
4
for
i
,
o
in
enumerate
([
m
.
make_myobject1_1
(),
m
.
make_myobject1_2
(),
m
.
MyObject1
(
6
),
7
],
for
i
,
o
in
enumerate
(
start
=
4
):
[
m
.
make_myobject1_1
(),
m
.
make_myobject1_2
(),
m
.
MyObject1
(
6
),
7
],
start
=
4
):
print
(
o
)
print
(
o
)
with
capture
:
with
capture
:
if
not
isinstance
(
o
,
int
):
if
not
isinstance
(
o
,
int
):
...
@@ -29,11 +32,15 @@ def test_smart_ptr(capture):
...
@@ -29,11 +32,15 @@ def test_smart_ptr(capture):
m
.
print_myobject1_2
(
o
)
m
.
print_myobject1_2
(
o
)
m
.
print_myobject1_3
(
o
)
m
.
print_myobject1_3
(
o
)
m
.
print_myobject1_4
(
o
)
m
.
print_myobject1_4
(
o
)
assert
capture
==
"MyObject1[{i}]
\n
"
.
format
(
i
=
i
)
*
(
4
if
isinstance
(
o
,
int
)
else
8
)
times
=
4
if
isinstance
(
o
,
int
)
else
8
assert
capture
==
"MyObject1[{i}]
\n
"
.
format
(
i
=
i
)
*
times
cstats
=
ConstructorStats
.
get
(
m
.
MyObject1
)
cstats
=
ConstructorStats
.
get
(
m
.
MyObject1
)
assert
cstats
.
alive
()
==
0
assert
cstats
.
alive
()
==
0
expected_values
=
[
'MyObject1[{}]'
.
format
(
i
)
for
i
in
range
(
1
,
7
)]
+
[
'MyObject1[7]'
]
*
4
expected_values
=
[
"MyObject1[{}]"
.
format
(
i
)
for
i
in
range
(
1
,
7
)]
+
[
"MyObject1[7]"
]
*
4
assert
cstats
.
values
()
==
expected_values
assert
cstats
.
values
()
==
expected_values
assert
cstats
.
default_constructions
==
0
assert
cstats
.
default_constructions
==
0
assert
cstats
.
copy_constructions
==
0
assert
cstats
.
copy_constructions
==
0
...
@@ -42,7 +49,9 @@ def test_smart_ptr(capture):
...
@@ -42,7 +49,9 @@ def test_smart_ptr(capture):
assert
cstats
.
move_assignments
==
0
assert
cstats
.
move_assignments
==
0
# Object2
# Object2
for
i
,
o
in
zip
([
8
,
6
,
7
],
[
m
.
MyObject2
(
8
),
m
.
make_myobject2_1
(),
m
.
make_myobject2_2
()]):
for
i
,
o
in
zip
(
[
8
,
6
,
7
],
[
m
.
MyObject2
(
8
),
m
.
make_myobject2_1
(),
m
.
make_myobject2_2
()]
):
print
(
o
)
print
(
o
)
with
capture
:
with
capture
:
m
.
print_myobject2_1
(
o
)
m
.
print_myobject2_1
(
o
)
...
@@ -55,7 +64,7 @@ def test_smart_ptr(capture):
...
@@ -55,7 +64,7 @@ def test_smart_ptr(capture):
assert
cstats
.
alive
()
==
1
assert
cstats
.
alive
()
==
1
o
=
None
o
=
None
assert
cstats
.
alive
()
==
0
assert
cstats
.
alive
()
==
0
assert
cstats
.
values
()
==
[
'MyObject2[8]'
,
'MyObject2[6]'
,
'MyObject2[7]'
]
assert
cstats
.
values
()
==
[
"MyObject2[8]"
,
"MyObject2[6]"
,
"MyObject2[7]"
]
assert
cstats
.
default_constructions
==
0
assert
cstats
.
default_constructions
==
0
assert
cstats
.
copy_constructions
==
0
assert
cstats
.
copy_constructions
==
0
# assert cstats.move_constructions >= 0 # Doesn't invoke any
# assert cstats.move_constructions >= 0 # Doesn't invoke any
...
@@ -63,7 +72,9 @@ def test_smart_ptr(capture):
...
@@ -63,7 +72,9 @@ def test_smart_ptr(capture):
assert
cstats
.
move_assignments
==
0
assert
cstats
.
move_assignments
==
0
# Object3
# Object3
for
i
,
o
in
zip
([
9
,
8
,
9
],
[
m
.
MyObject3
(
9
),
m
.
make_myobject3_1
(),
m
.
make_myobject3_2
()]):
for
i
,
o
in
zip
(
[
9
,
8
,
9
],
[
m
.
MyObject3
(
9
),
m
.
make_myobject3_1
(),
m
.
make_myobject3_2
()]
):
print
(
o
)
print
(
o
)
with
capture
:
with
capture
:
m
.
print_myobject3_1
(
o
)
m
.
print_myobject3_1
(
o
)
...
@@ -76,7 +87,7 @@ def test_smart_ptr(capture):
...
@@ -76,7 +87,7 @@ def test_smart_ptr(capture):
assert
cstats
.
alive
()
==
1
assert
cstats
.
alive
()
==
1
o
=
None
o
=
None
assert
cstats
.
alive
()
==
0
assert
cstats
.
alive
()
==
0
assert
cstats
.
values
()
==
[
'MyObject3[9]'
,
'MyObject3[8]'
,
'MyObject3[9]'
]
assert
cstats
.
values
()
==
[
"MyObject3[9]"
,
"MyObject3[8]"
,
"MyObject3[9]"
]
assert
cstats
.
default_constructions
==
0
assert
cstats
.
default_constructions
==
0
assert
cstats
.
copy_constructions
==
0
assert
cstats
.
copy_constructions
==
0
# assert cstats.move_constructions >= 0 # Doesn't invoke any
# assert cstats.move_constructions >= 0 # Doesn't invoke any
...
@@ -96,7 +107,7 @@ def test_smart_ptr(capture):
...
@@ -96,7 +107,7 @@ def test_smart_ptr(capture):
# ref<>
# ref<>
cstats
=
m
.
cstats_ref
()
cstats
=
m
.
cstats_ref
()
assert
cstats
.
alive
()
==
0
assert
cstats
.
alive
()
==
0
assert
cstats
.
values
()
==
[
'from pointer'
]
*
10
assert
cstats
.
values
()
==
[
"from pointer"
]
*
10
assert
cstats
.
default_constructions
==
30
assert
cstats
.
default_constructions
==
30
assert
cstats
.
copy_constructions
==
12
assert
cstats
.
copy_constructions
==
12
# assert cstats.move_constructions >= 0 # Doesn't invoke any
# assert cstats.move_constructions >= 0 # Doesn't invoke any
...
@@ -186,7 +197,9 @@ def test_shared_ptr_from_this_and_references():
...
@@ -186,7 +197,9 @@ def test_shared_ptr_from_this_and_references():
ref
=
s
.
ref
# init_holder_helper(holder_ptr=false, owned=false, bad_wp=false)
ref
=
s
.
ref
# init_holder_helper(holder_ptr=false, owned=false, bad_wp=false)
assert
stats
.
alive
()
==
2
assert
stats
.
alive
()
==
2
assert
s
.
set_ref
(
ref
)
assert
s
.
set_ref
(
ref
)
assert
s
.
set_holder
(
ref
)
# std::enable_shared_from_this can create a holder from a reference
assert
s
.
set_holder
(
ref
)
# std::enable_shared_from_this can create a holder from a reference
bad_wp
=
s
.
bad_wp
# init_holder_helper(holder_ptr=false, owned=false, bad_wp=true)
bad_wp
=
s
.
bad_wp
# init_holder_helper(holder_ptr=false, owned=false, bad_wp=true)
assert
stats
.
alive
()
==
2
assert
stats
.
alive
()
==
2
...
@@ -200,12 +213,16 @@ def test_shared_ptr_from_this_and_references():
...
@@ -200,12 +213,16 @@ def test_shared_ptr_from_this_and_references():
assert
s
.
set_ref
(
copy
)
assert
s
.
set_ref
(
copy
)
assert
s
.
set_holder
(
copy
)
assert
s
.
set_holder
(
copy
)
holder_ref
=
s
.
holder_ref
# init_holder_helper(holder_ptr=true, owned=false, bad_wp=false)
holder_ref
=
(
s
.
holder_ref
)
# init_holder_helper(holder_ptr=true, owned=false, bad_wp=false)
assert
stats
.
alive
()
==
3
assert
stats
.
alive
()
==
3
assert
s
.
set_ref
(
holder_ref
)
assert
s
.
set_ref
(
holder_ref
)
assert
s
.
set_holder
(
holder_ref
)
assert
s
.
set_holder
(
holder_ref
)
holder_copy
=
s
.
holder_copy
# init_holder_helper(holder_ptr=true, owned=true, bad_wp=false)
holder_copy
=
(
s
.
holder_copy
)
# init_holder_helper(holder_ptr=true, owned=true, bad_wp=false)
assert
stats
.
alive
()
==
3
assert
stats
.
alive
()
==
3
assert
s
.
set_ref
(
holder_copy
)
assert
s
.
set_ref
(
holder_copy
)
assert
s
.
set_holder
(
holder_copy
)
assert
s
.
set_holder
(
holder_copy
)
...
@@ -277,8 +294,10 @@ def test_smart_ptr_from_default():
...
@@ -277,8 +294,10 @@ def test_smart_ptr_from_default():
instance
=
m
.
HeldByDefaultHolder
()
instance
=
m
.
HeldByDefaultHolder
()
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
HeldByDefaultHolder
.
load_shared_ptr
(
instance
)
m
.
HeldByDefaultHolder
.
load_shared_ptr
(
instance
)
assert
"Unable to load a custom holder type from a "
\
assert
(
"default-holder instance"
in
str
(
excinfo
.
value
)
"Unable to load a custom holder type from a "
"default-holder instance"
in
str
(
excinfo
.
value
)
)
def
test_shared_ptr_gc
():
def
test_shared_ptr_gc
():
...
...
tests/test_stl.py
View file @
c50f90ec
...
@@ -88,7 +88,7 @@ def test_recursive_casting():
...
@@ -88,7 +88,7 @@ def test_recursive_casting():
assert
m
.
cast_rv_nested
()
==
[[[{
"b"
:
"rvalue"
,
"c"
:
"rvalue"
}],
[{
"a"
:
"rvalue"
}]]]
assert
m
.
cast_rv_nested
()
==
[[[{
"b"
:
"rvalue"
,
"c"
:
"rvalue"
}],
[{
"a"
:
"rvalue"
}]]]
assert
m
.
cast_lv_nested
()
==
{
assert
m
.
cast_lv_nested
()
==
{
"a"
:
[[[
"lvalue"
,
"lvalue"
]],
[[
"lvalue"
,
"lvalue"
]]],
"a"
:
[[[
"lvalue"
,
"lvalue"
]],
[[
"lvalue"
,
"lvalue"
]]],
"b"
:
[[[
"lvalue"
,
"lvalue"
],
[
"lvalue"
,
"lvalue"
]]]
"b"
:
[[[
"lvalue"
,
"lvalue"
],
[
"lvalue"
,
"lvalue"
]]]
,
}
}
# Issue #853 test case:
# Issue #853 test case:
...
@@ -106,15 +106,15 @@ def test_move_out_container():
...
@@ -106,15 +106,15 @@ def test_move_out_container():
assert
[
x
.
value
for
x
in
moved_out_list
]
==
[
0
,
1
,
2
]
assert
[
x
.
value
for
x
in
moved_out_list
]
==
[
0
,
1
,
2
]
@pytest.mark.skipif
(
not
hasattr
(
m
,
"has_optional"
),
reason
=
'no <optional>'
)
@pytest.mark.skipif
(
not
hasattr
(
m
,
"has_optional"
),
reason
=
"no <optional>"
)
def
test_optional
():
def
test_optional
():
assert
m
.
double_or_zero
(
None
)
==
0
assert
m
.
double_or_zero
(
None
)
==
0
assert
m
.
double_or_zero
(
42
)
==
84
assert
m
.
double_or_zero
(
42
)
==
84
pytest
.
raises
(
TypeError
,
m
.
double_or_zero
,
'foo'
)
pytest
.
raises
(
TypeError
,
m
.
double_or_zero
,
"foo"
)
assert
m
.
half_or_none
(
0
)
is
None
assert
m
.
half_or_none
(
0
)
is
None
assert
m
.
half_or_none
(
42
)
==
21
assert
m
.
half_or_none
(
42
)
==
21
pytest
.
raises
(
TypeError
,
m
.
half_or_none
,
'foo'
)
pytest
.
raises
(
TypeError
,
m
.
half_or_none
,
"foo"
)
assert
m
.
test_nullopt
()
==
42
assert
m
.
test_nullopt
()
==
42
assert
m
.
test_nullopt
(
None
)
==
42
assert
m
.
test_nullopt
(
None
)
==
42
...
@@ -134,15 +134,17 @@ def test_optional():
...
@@ -134,15 +134,17 @@ def test_optional():
assert
holder
.
member_initialized
()
assert
holder
.
member_initialized
()
@pytest.mark.skipif
(
not
hasattr
(
m
,
"has_exp_optional"
),
reason
=
'no <experimental/optional>'
)
@pytest.mark.skipif
(
not
hasattr
(
m
,
"has_exp_optional"
),
reason
=
"no <experimental/optional>"
)
def
test_exp_optional
():
def
test_exp_optional
():
assert
m
.
double_or_zero_exp
(
None
)
==
0
assert
m
.
double_or_zero_exp
(
None
)
==
0
assert
m
.
double_or_zero_exp
(
42
)
==
84
assert
m
.
double_or_zero_exp
(
42
)
==
84
pytest
.
raises
(
TypeError
,
m
.
double_or_zero_exp
,
'foo'
)
pytest
.
raises
(
TypeError
,
m
.
double_or_zero_exp
,
"foo"
)
assert
m
.
half_or_none_exp
(
0
)
is
None
assert
m
.
half_or_none_exp
(
0
)
is
None
assert
m
.
half_or_none_exp
(
42
)
==
21
assert
m
.
half_or_none_exp
(
42
)
==
21
pytest
.
raises
(
TypeError
,
m
.
half_or_none_exp
,
'foo'
)
pytest
.
raises
(
TypeError
,
m
.
half_or_none_exp
,
"foo"
)
assert
m
.
test_nullopt_exp
()
==
42
assert
m
.
test_nullopt_exp
()
==
42
assert
m
.
test_nullopt_exp
(
None
)
==
42
assert
m
.
test_nullopt_exp
(
None
)
==
42
...
@@ -160,7 +162,7 @@ def test_exp_optional():
...
@@ -160,7 +162,7 @@ def test_exp_optional():
assert
holder
.
member_initialized
()
assert
holder
.
member_initialized
()
@pytest.mark.skipif
(
not
hasattr
(
m
,
"load_variant"
),
reason
=
'no <variant>'
)
@pytest.mark.skipif
(
not
hasattr
(
m
,
"load_variant"
),
reason
=
"no <variant>"
)
def
test_variant
(
doc
):
def
test_variant
(
doc
):
assert
m
.
load_variant
(
1
)
==
"int"
assert
m
.
load_variant
(
1
)
==
"int"
assert
m
.
load_variant
(
"1"
)
==
"std::string"
assert
m
.
load_variant
(
"1"
)
==
"std::string"
...
@@ -172,34 +174,44 @@ def test_variant(doc):
...
@@ -172,34 +174,44 @@ def test_variant(doc):
assert
m
.
cast_variant
()
==
(
5
,
"Hello"
)
assert
m
.
cast_variant
()
==
(
5
,
"Hello"
)
assert
doc
(
m
.
load_variant
)
==
"load_variant(arg0: Union[int, str, float, None]) -> str"
assert
(
doc
(
m
.
load_variant
)
==
"load_variant(arg0: Union[int, str, float, None]) -> str"
)
def
test_vec_of_reference_wrapper
():
def
test_vec_of_reference_wrapper
():
"""#171: Can't return reference wrappers (or STL structures containing them)"""
"""#171: Can't return reference wrappers (or STL structures containing them)"""
assert
str
(
m
.
return_vec_of_reference_wrapper
(
UserType
(
4
)))
==
\
assert
(
"[UserType(1), UserType(2), UserType(3), UserType(4)]"
str
(
m
.
return_vec_of_reference_wrapper
(
UserType
(
4
)))
==
"[UserType(1), UserType(2), UserType(3), UserType(4)]"
)
def
test_stl_pass_by_pointer
(
msg
):
def
test_stl_pass_by_pointer
(
msg
):
"""Passing nullptr or None to an STL container pointer is not expected to work"""
"""Passing nullptr or None to an STL container pointer is not expected to work"""
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
stl_pass_by_pointer
()
# default value is `nullptr`
m
.
stl_pass_by_pointer
()
# default value is `nullptr`
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:
stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:
1. (v: List[int] = None) -> List[int]
1. (v: List[int] = None) -> List[int]
Invoked with:
Invoked with:
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
m
.
stl_pass_by_pointer
(
None
)
m
.
stl_pass_by_pointer
(
None
)
assert
msg
(
excinfo
.
value
)
==
"""
assert
(
msg
(
excinfo
.
value
)
==
"""
stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:
stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:
1. (v: List[int] = None) -> List[int]
1. (v: List[int] = None) -> List[int]
Invoked with: None
Invoked with: None
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
assert
m
.
stl_pass_by_pointer
([
1
,
2
,
3
])
==
[
1
,
2
,
3
]
assert
m
.
stl_pass_by_pointer
([
1
,
2
,
3
])
==
[
1
,
2
,
3
]
...
@@ -209,10 +221,12 @@ def test_missing_header_message():
...
@@ -209,10 +221,12 @@ def test_missing_header_message():
<pybind11/stl.h> should result in a helpful suggestion in the error message"""
<pybind11/stl.h> should result in a helpful suggestion in the error message"""
import
pybind11_cross_module_tests
as
cm
import
pybind11_cross_module_tests
as
cm
expected_message
=
(
"Did you forget to `#include <pybind11/stl.h>`? Or <pybind11/complex.h>,
\n
"
expected_message
=
(
"<pybind11/functional.h>, <pybind11/chrono.h>, etc. Some automatic
\n
"
"Did you forget to `#include <pybind11/stl.h>`? Or <pybind11/complex.h>,
\n
"
"conversions are optional and require extra headers to be included
\n
"
"<pybind11/functional.h>, <pybind11/chrono.h>, etc. Some automatic
\n
"
"when compiling your pybind11 module."
)
"conversions are optional and require extra headers to be included
\n
"
"when compiling your pybind11 module."
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
cm
.
missing_header_arg
([
1.0
,
2.0
,
3.0
])
cm
.
missing_header_arg
([
1.0
,
2.0
,
3.0
])
...
@@ -226,9 +240,9 @@ def test_missing_header_message():
...
@@ -226,9 +240,9 @@ def test_missing_header_message():
def
test_function_with_string_and_vector_string_arg
():
def
test_function_with_string_and_vector_string_arg
():
"""Check if a string is NOT implicitly converted to a list, which was the
"""Check if a string is NOT implicitly converted to a list, which was the
behavior before fix of issue #1258"""
behavior before fix of issue #1258"""
assert
m
.
func_with_string_or_vector_string_arg_overload
((
'A'
,
'B'
,
))
==
2
assert
m
.
func_with_string_or_vector_string_arg_overload
((
"A"
,
"B"
))
==
2
assert
m
.
func_with_string_or_vector_string_arg_overload
([
'A'
,
'B'
])
==
2
assert
m
.
func_with_string_or_vector_string_arg_overload
([
"A"
,
"B"
])
==
2
assert
m
.
func_with_string_or_vector_string_arg_overload
(
'A'
)
==
3
assert
m
.
func_with_string_or_vector_string_arg_overload
(
"A"
)
==
3
def
test_stl_ownership
():
def
test_stl_ownership
():
...
@@ -247,6 +261,6 @@ def test_array_cast_sequence():
...
@@ -247,6 +261,6 @@ def test_array_cast_sequence():
def
test_issue_1561
():
def
test_issue_1561
():
""" check fix for issue #1561 """
""" check fix for issue #1561 """
bar
=
m
.
Issue1561Outer
()
bar
=
m
.
Issue1561Outer
()
bar
.
list
=
[
m
.
Issue1561Inner
(
'bar'
)]
bar
.
list
=
[
m
.
Issue1561Inner
(
"bar"
)]
bar
.
list
bar
.
list
assert
bar
.
list
[
0
]
.
data
==
'bar'
assert
bar
.
list
[
0
]
.
data
==
"bar"
tests/test_stl_binders.py
View file @
c50f90ec
...
@@ -45,7 +45,7 @@ def test_vector_int():
...
@@ -45,7 +45,7 @@ def test_vector_int():
# test error handling, and that the vector is unchanged
# test error handling, and that the vector is unchanged
with
pytest
.
raises
(
RuntimeError
):
with
pytest
.
raises
(
RuntimeError
):
v_int2
.
extend
([
8
,
'a'
])
v_int2
.
extend
([
8
,
"a"
])
assert
v_int2
==
m
.
VectorInt
([
0
,
99
,
2
,
3
,
4
,
5
,
6
,
7
])
assert
v_int2
==
m
.
VectorInt
([
0
,
99
,
2
,
3
,
4
,
5
,
6
,
7
])
...
@@ -79,8 +79,8 @@ def test_vector_buffer():
...
@@ -79,8 +79,8 @@ def test_vector_buffer():
assert
mv
[
2
]
==
5
assert
mv
[
2
]
==
5
mv
[
2
]
=
6
mv
[
2
]
=
6
else
:
else
:
assert
mv
[
2
]
==
'
\x05
'
assert
mv
[
2
]
==
"
\x05
"
mv
[
2
]
=
'
\x06
'
mv
[
2
]
=
"
\x06
"
assert
v
[
2
]
==
6
assert
v
[
2
]
==
6
if
not
env
.
PY2
:
if
not
env
.
PY2
:
...
@@ -114,11 +114,17 @@ def test_vector_buffer_numpy():
...
@@ -114,11 +114,17 @@ def test_vector_buffer_numpy():
v
=
m
.
get_vectorstruct
()
v
=
m
.
get_vectorstruct
()
assert
v
[
0
]
.
x
==
5
assert
v
[
0
]
.
x
==
5
ma
=
np
.
asarray
(
v
)
ma
=
np
.
asarray
(
v
)
ma
[
1
][
'x'
]
=
99
ma
[
1
][
"x"
]
=
99
assert
v
[
1
]
.
x
==
99
assert
v
[
1
]
.
x
==
99
v
=
m
.
VectorStruct
(
np
.
zeros
(
3
,
dtype
=
np
.
dtype
([(
'w'
,
'bool'
),
(
'x'
,
'I'
),
v
=
m
.
VectorStruct
(
(
'y'
,
'float64'
),
(
'z'
,
'bool'
)],
align
=
True
)))
np
.
zeros
(
3
,
dtype
=
np
.
dtype
(
[(
"w"
,
"bool"
),
(
"x"
,
"I"
),
(
"y"
,
"float64"
),
(
"z"
,
"bool"
)],
align
=
True
),
)
)
assert
len
(
v
)
==
3
assert
len
(
v
)
==
3
b
=
np
.
array
([
1
,
2
,
3
,
4
],
dtype
=
np
.
uint8
)
b
=
np
.
array
([
1
,
2
,
3
,
4
],
dtype
=
np
.
uint8
)
...
@@ -151,31 +157,31 @@ def test_vector_custom():
...
@@ -151,31 +157,31 @@ def test_vector_custom():
def
test_map_string_double
():
def
test_map_string_double
():
mm
=
m
.
MapStringDouble
()
mm
=
m
.
MapStringDouble
()
mm
[
'a'
]
=
1
mm
[
"a"
]
=
1
mm
[
'b'
]
=
2.5
mm
[
"b"
]
=
2.5
assert
list
(
mm
)
==
[
'a'
,
'b'
]
assert
list
(
mm
)
==
[
"a"
,
"b"
]
assert
list
(
mm
.
items
())
==
[(
'a'
,
1
),
(
'b'
,
2.5
)]
assert
list
(
mm
.
items
())
==
[(
"a"
,
1
),
(
"b"
,
2.5
)]
assert
str
(
mm
)
==
"MapStringDouble{a: 1, b: 2.5}"
assert
str
(
mm
)
==
"MapStringDouble{a: 1, b: 2.5}"
um
=
m
.
UnorderedMapStringDouble
()
um
=
m
.
UnorderedMapStringDouble
()
um
[
'ua'
]
=
1.1
um
[
"ua"
]
=
1.1
um
[
'ub'
]
=
2.6
um
[
"ub"
]
=
2.6
assert
sorted
(
list
(
um
))
==
[
'ua'
,
'ub'
]
assert
sorted
(
list
(
um
))
==
[
"ua"
,
"ub"
]
assert
sorted
(
list
(
um
.
items
()))
==
[(
'ua'
,
1.1
),
(
'ub'
,
2.6
)]
assert
sorted
(
list
(
um
.
items
()))
==
[(
"ua"
,
1.1
),
(
"ub"
,
2.6
)]
assert
"UnorderedMapStringDouble"
in
str
(
um
)
assert
"UnorderedMapStringDouble"
in
str
(
um
)
def
test_map_string_double_const
():
def
test_map_string_double_const
():
mc
=
m
.
MapStringDoubleConst
()
mc
=
m
.
MapStringDoubleConst
()
mc
[
'a'
]
=
10
mc
[
"a"
]
=
10
mc
[
'b'
]
=
20.5
mc
[
"b"
]
=
20.5
assert
str
(
mc
)
==
"MapStringDoubleConst{a: 10, b: 20.5}"
assert
str
(
mc
)
==
"MapStringDoubleConst{a: 10, b: 20.5}"
umc
=
m
.
UnorderedMapStringDoubleConst
()
umc
=
m
.
UnorderedMapStringDoubleConst
()
umc
[
'a'
]
=
11
umc
[
"a"
]
=
11
umc
[
'b'
]
=
21.5
umc
[
"b"
]
=
21.5
str
(
umc
)
str
(
umc
)
...
@@ -196,7 +202,7 @@ def test_noncopyable_containers():
...
@@ -196,7 +202,7 @@ def test_noncopyable_containers():
i
=
1
i
=
1
for
j
in
dnc
:
for
j
in
dnc
:
assert
(
j
.
value
==
i
)
assert
j
.
value
==
i
i
+=
1
i
+=
1
# std::map
# std::map
...
@@ -265,21 +271,21 @@ def test_noncopyable_containers():
...
@@ -265,21 +271,21 @@ def test_noncopyable_containers():
def
test_map_delitem
():
def
test_map_delitem
():
mm
=
m
.
MapStringDouble
()
mm
=
m
.
MapStringDouble
()
mm
[
'a'
]
=
1
mm
[
"a"
]
=
1
mm
[
'b'
]
=
2.5
mm
[
"b"
]
=
2.5
assert
list
(
mm
)
==
[
'a'
,
'b'
]
assert
list
(
mm
)
==
[
"a"
,
"b"
]
assert
list
(
mm
.
items
())
==
[(
'a'
,
1
),
(
'b'
,
2.5
)]
assert
list
(
mm
.
items
())
==
[(
"a"
,
1
),
(
"b"
,
2.5
)]
del
mm
[
'a'
]
del
mm
[
"a"
]
assert
list
(
mm
)
==
[
'b'
]
assert
list
(
mm
)
==
[
"b"
]
assert
list
(
mm
.
items
())
==
[(
'b'
,
2.5
)]
assert
list
(
mm
.
items
())
==
[(
"b"
,
2.5
)]
um
=
m
.
UnorderedMapStringDouble
()
um
=
m
.
UnorderedMapStringDouble
()
um
[
'ua'
]
=
1.1
um
[
"ua"
]
=
1.1
um
[
'ub'
]
=
2.6
um
[
"ub"
]
=
2.6
assert
sorted
(
list
(
um
))
==
[
'ua'
,
'ub'
]
assert
sorted
(
list
(
um
))
==
[
"ua"
,
"ub"
]
assert
sorted
(
list
(
um
.
items
()))
==
[(
'ua'
,
1.1
),
(
'ub'
,
2.6
)]
assert
sorted
(
list
(
um
.
items
()))
==
[(
"ua"
,
1.1
),
(
"ub"
,
2.6
)]
del
um
[
'ua'
]
del
um
[
"ua"
]
assert
sorted
(
list
(
um
))
==
[
'ub'
]
assert
sorted
(
list
(
um
))
==
[
"ub"
]
assert
sorted
(
list
(
um
.
items
()))
==
[(
'ub'
,
2.6
)]
assert
sorted
(
list
(
um
.
items
()))
==
[(
"ub"
,
2.6
)]
tests/test_tagbased_polymorphic.py
View file @
c50f90ec
...
@@ -5,16 +5,24 @@ from pybind11_tests import tagbased_polymorphic as m
...
@@ -5,16 +5,24 @@ from pybind11_tests import tagbased_polymorphic as m
def
test_downcast
():
def
test_downcast
():
zoo
=
m
.
create_zoo
()
zoo
=
m
.
create_zoo
()
assert
[
type
(
animal
)
for
animal
in
zoo
]
==
[
assert
[
type
(
animal
)
for
animal
in
zoo
]
==
[
m
.
Labrador
,
m
.
Dog
,
m
.
Chihuahua
,
m
.
Cat
,
m
.
Panther
m
.
Labrador
,
m
.
Dog
,
m
.
Chihuahua
,
m
.
Cat
,
m
.
Panther
,
]
]
assert
[
animal
.
name
for
animal
in
zoo
]
==
[
assert
[
animal
.
name
for
animal
in
zoo
]
==
[
"Fido"
,
"Ginger"
,
"Hertzl"
,
"Tiger"
,
"Leo"
"Fido"
,
"Ginger"
,
"Hertzl"
,
"Tiger"
,
"Leo"
,
]
]
zoo
[
1
]
.
sound
=
"woooooo"
zoo
[
1
]
.
sound
=
"woooooo"
assert
[
dog
.
bark
()
for
dog
in
zoo
[:
3
]]
==
[
assert
[
dog
.
bark
()
for
dog
in
zoo
[:
3
]]
==
[
"Labrador Fido goes WOOF!"
,
"Labrador Fido goes WOOF!"
,
"Dog Ginger goes woooooo"
,
"Dog Ginger goes woooooo"
,
"Chihuahua Hertzl goes iyiyiyiyiyi and runs in circles"
"Chihuahua Hertzl goes iyiyiyiyiyi and runs in circles"
,
]
]
assert
[
cat
.
purr
()
for
cat
in
zoo
[
3
:]]
==
[
"mrowr"
,
"mrrrRRRRRR"
]
assert
[
cat
.
purr
()
for
cat
in
zoo
[
3
:]]
==
[
"mrowr"
,
"mrrrRRRRRR"
]
zoo
[
0
]
.
excitement
-=
1000
zoo
[
0
]
.
excitement
-=
1000
...
...
tests/test_virtual_functions.py
View file @
c50f90ec
...
@@ -14,18 +14,18 @@ def test_override(capture, msg):
...
@@ -14,18 +14,18 @@ def test_override(capture, msg):
self
.
data
=
"Hello world"
self
.
data
=
"Hello world"
def
run
(
self
,
value
):
def
run
(
self
,
value
):
print
(
'ExtendedExampleVirt::run(
%
i), calling parent..'
%
value
)
print
(
"ExtendedExampleVirt::run(
%
i), calling parent.."
%
value
)
return
super
(
ExtendedExampleVirt
,
self
)
.
run
(
value
+
1
)
return
super
(
ExtendedExampleVirt
,
self
)
.
run
(
value
+
1
)
def
run_bool
(
self
):
def
run_bool
(
self
):
print
(
'ExtendedExampleVirt::run_bool()'
)
print
(
"ExtendedExampleVirt::run_bool()"
)
return
False
return
False
def
get_string1
(
self
):
def
get_string1
(
self
):
return
"override1"
return
"override1"
def
pure_virtual
(
self
):
def
pure_virtual
(
self
):
print
(
'ExtendedExampleVirt::pure_virtual():
%
s'
%
self
.
data
)
print
(
"ExtendedExampleVirt::pure_virtual():
%
s"
%
self
.
data
)
class
ExtendedExampleVirt2
(
ExtendedExampleVirt
):
class
ExtendedExampleVirt2
(
ExtendedExampleVirt
):
def
__init__
(
self
,
state
):
def
__init__
(
self
,
state
):
...
@@ -37,21 +37,30 @@ def test_override(capture, msg):
...
@@ -37,21 +37,30 @@ def test_override(capture, msg):
ex12
=
m
.
ExampleVirt
(
10
)
ex12
=
m
.
ExampleVirt
(
10
)
with
capture
:
with
capture
:
assert
m
.
runExampleVirt
(
ex12
,
20
)
==
30
assert
m
.
runExampleVirt
(
ex12
,
20
)
==
30
assert
capture
==
"""
assert
(
capture
==
"""
Original implementation of ExampleVirt::run(state=10, value=20, str1=default1, str2=default2)
Original implementation of ExampleVirt::run(state=10, value=20, str1=default1, str2=default2)
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
m
.
runExampleVirtVirtual
(
ex12
)
m
.
runExampleVirtVirtual
(
ex12
)
assert
msg
(
excinfo
.
value
)
==
'Tried to call pure virtual function "ExampleVirt::pure_virtual"'
assert
(
msg
(
excinfo
.
value
)
==
'Tried to call pure virtual function "ExampleVirt::pure_virtual"'
)
ex12p
=
ExtendedExampleVirt
(
10
)
ex12p
=
ExtendedExampleVirt
(
10
)
with
capture
:
with
capture
:
assert
m
.
runExampleVirt
(
ex12p
,
20
)
==
32
assert
m
.
runExampleVirt
(
ex12p
,
20
)
==
32
assert
capture
==
"""
assert
(
capture
==
"""
ExtendedExampleVirt::run(20), calling parent..
ExtendedExampleVirt::run(20), calling parent..
Original implementation of ExampleVirt::run(state=11, value=21, str1=override1, str2=default2)
Original implementation of ExampleVirt::run(state=11, value=21, str1=override1, str2=default2)
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
with
capture
:
with
capture
:
assert
m
.
runExampleVirtBool
(
ex12p
)
is
False
assert
m
.
runExampleVirtBool
(
ex12p
)
is
False
assert
capture
==
"ExtendedExampleVirt::run_bool()"
assert
capture
==
"ExtendedExampleVirt::run_bool()"
...
@@ -62,16 +71,19 @@ def test_override(capture, msg):
...
@@ -62,16 +71,19 @@ def test_override(capture, msg):
ex12p2
=
ExtendedExampleVirt2
(
15
)
ex12p2
=
ExtendedExampleVirt2
(
15
)
with
capture
:
with
capture
:
assert
m
.
runExampleVirt
(
ex12p2
,
50
)
==
68
assert
m
.
runExampleVirt
(
ex12p2
,
50
)
==
68
assert
capture
==
"""
assert
(
capture
==
"""
ExtendedExampleVirt::run(50), calling parent..
ExtendedExampleVirt::run(50), calling parent..
Original implementation of ExampleVirt::run(state=17, value=51, str1=override1, str2=override2)
Original implementation of ExampleVirt::run(state=17, value=51, str1=override1, str2=override2)
"""
# noqa: E501 line too long
"""
# noqa: E501 line too long
)
cstats
=
ConstructorStats
.
get
(
m
.
ExampleVirt
)
cstats
=
ConstructorStats
.
get
(
m
.
ExampleVirt
)
assert
cstats
.
alive
()
==
3
assert
cstats
.
alive
()
==
3
del
ex12
,
ex12p
,
ex12p2
del
ex12
,
ex12p
,
ex12p2
assert
cstats
.
alive
()
==
0
assert
cstats
.
alive
()
==
0
assert
cstats
.
values
()
==
[
'10'
,
'11'
,
'17'
]
assert
cstats
.
values
()
==
[
"10"
,
"11"
,
"17"
]
assert
cstats
.
copy_constructions
==
0
assert
cstats
.
copy_constructions
==
0
assert
cstats
.
move_constructions
>=
0
assert
cstats
.
move_constructions
>=
0
...
@@ -82,6 +94,7 @@ def test_alias_delay_initialization1(capture):
...
@@ -82,6 +94,7 @@ def test_alias_delay_initialization1(capture):
If we just create and use an A instance directly, the trampoline initialization is
If we just create and use an A instance directly, the trampoline initialization is
bypassed and we only initialize an A() instead (for performance reasons).
bypassed and we only initialize an A() instead (for performance reasons).
"""
"""
class
B
(
m
.
A
):
class
B
(
m
.
A
):
def
__init__
(
self
):
def
__init__
(
self
):
super
(
B
,
self
)
.
__init__
()
super
(
B
,
self
)
.
__init__
()
...
@@ -103,12 +116,15 @@ def test_alias_delay_initialization1(capture):
...
@@ -103,12 +116,15 @@ def test_alias_delay_initialization1(capture):
m
.
call_f
(
b
)
m
.
call_f
(
b
)
del
b
del
b
pytest
.
gc_collect
()
pytest
.
gc_collect
()
assert
capture
==
"""
assert
(
capture
==
"""
PyA.PyA()
PyA.PyA()
PyA.f()
PyA.f()
In python f()
In python f()
PyA.~PyA()
PyA.~PyA()
"""
"""
)
def
test_alias_delay_initialization2
(
capture
):
def
test_alias_delay_initialization2
(
capture
):
...
@@ -118,6 +134,7 @@ def test_alias_delay_initialization2(capture):
...
@@ -118,6 +134,7 @@ def test_alias_delay_initialization2(capture):
performance penalty, it also allows us to do more things with the trampoline
performance penalty, it also allows us to do more things with the trampoline
class such as defining local variables and performing construction/destruction.
class such as defining local variables and performing construction/destruction.
"""
"""
class
B2
(
m
.
A2
):
class
B2
(
m
.
A2
):
def
__init__
(
self
):
def
__init__
(
self
):
super
(
B2
,
self
)
.
__init__
()
super
(
B2
,
self
)
.
__init__
()
...
@@ -135,7 +152,9 @@ def test_alias_delay_initialization2(capture):
...
@@ -135,7 +152,9 @@ def test_alias_delay_initialization2(capture):
m
.
call_f
(
a3
)
m
.
call_f
(
a3
)
del
a3
del
a3
pytest
.
gc_collect
()
pytest
.
gc_collect
()
assert
capture
==
"""
assert
(
capture
==
"""
PyA2.PyA2()
PyA2.PyA2()
PyA2.f()
PyA2.f()
A2.f()
A2.f()
...
@@ -145,6 +164,7 @@ def test_alias_delay_initialization2(capture):
...
@@ -145,6 +164,7 @@ def test_alias_delay_initialization2(capture):
A2.f()
A2.f()
PyA2.~PyA2()
PyA2.~PyA2()
"""
"""
)
# Python subclass version
# Python subclass version
with
capture
:
with
capture
:
...
@@ -152,20 +172,22 @@ def test_alias_delay_initialization2(capture):
...
@@ -152,20 +172,22 @@ def test_alias_delay_initialization2(capture):
m
.
call_f
(
b2
)
m
.
call_f
(
b2
)
del
b2
del
b2
pytest
.
gc_collect
()
pytest
.
gc_collect
()
assert
capture
==
"""
assert
(
capture
==
"""
PyA2.PyA2()
PyA2.PyA2()
PyA2.f()
PyA2.f()
In python B2.f()
In python B2.f()
PyA2.~PyA2()
PyA2.~PyA2()
"""
"""
)
# PyPy: Reference count > 1 causes call with noncopyable instance
# PyPy: Reference count > 1 causes call with noncopyable instance
# to fail in ncv1.print_nc()
# to fail in ncv1.print_nc()
@pytest.mark.xfail
(
"env.PYPY"
)
@pytest.mark.xfail
(
"env.PYPY"
)
@pytest.mark.skipif
(
@pytest.mark.skipif
(
not
hasattr
(
m
,
"NCVirt"
),
not
hasattr
(
m
,
"NCVirt"
),
reason
=
"NCVirt does not work on Intel/PGI/NVCC compilers"
reason
=
"NCVirt does not work on Intel/PGI/NVCC compilers"
)
)
def
test_move_support
():
def
test_move_support
():
class
NCVirtExt
(
m
.
NCVirt
):
class
NCVirtExt
(
m
.
NCVirt
):
...
@@ -205,8 +227,8 @@ def test_move_support():
...
@@ -205,8 +227,8 @@ def test_move_support():
del
ncv1
,
ncv2
del
ncv1
,
ncv2
assert
nc_stats
.
alive
()
==
0
assert
nc_stats
.
alive
()
==
0
assert
mv_stats
.
alive
()
==
0
assert
mv_stats
.
alive
()
==
0
assert
nc_stats
.
values
()
==
[
'4'
,
'9'
,
'9'
,
'9'
]
assert
nc_stats
.
values
()
==
[
"4"
,
"9"
,
"9"
,
"9"
]
assert
mv_stats
.
values
()
==
[
'4'
,
'5'
,
'7'
,
'7'
]
assert
mv_stats
.
values
()
==
[
"4"
,
"5"
,
"7"
,
"7"
]
assert
nc_stats
.
copy_constructions
==
0
assert
nc_stats
.
copy_constructions
==
0
assert
mv_stats
.
copy_constructions
==
1
assert
mv_stats
.
copy_constructions
==
1
assert
nc_stats
.
move_constructions
>=
0
assert
nc_stats
.
move_constructions
>=
0
...
@@ -215,6 +237,7 @@ def test_move_support():
...
@@ -215,6 +237,7 @@ def test_move_support():
def
test_dispatch_issue
(
msg
):
def
test_dispatch_issue
(
msg
):
"""#159: virtual function dispatch has problems with similar-named functions"""
"""#159: virtual function dispatch has problems with similar-named functions"""
class
PyClass1
(
m
.
DispatchIssue
):
class
PyClass1
(
m
.
DispatchIssue
):
def
dispatch
(
self
):
def
dispatch
(
self
):
return
"Yay.."
return
"Yay.."
...
@@ -223,7 +246,10 @@ def test_dispatch_issue(msg):
...
@@ -223,7 +246,10 @@ def test_dispatch_issue(msg):
def
dispatch
(
self
):
def
dispatch
(
self
):
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
with
pytest
.
raises
(
RuntimeError
)
as
excinfo
:
super
(
PyClass2
,
self
)
.
dispatch
()
super
(
PyClass2
,
self
)
.
dispatch
()
assert
msg
(
excinfo
.
value
)
==
'Tried to call pure virtual function "Base::dispatch"'
assert
(
msg
(
excinfo
.
value
)
==
'Tried to call pure virtual function "Base::dispatch"'
)
p
=
PyClass1
()
p
=
PyClass1
()
return
m
.
dispatch_issue_go
(
p
)
return
m
.
dispatch_issue_go
(
p
)
...
@@ -339,7 +365,7 @@ def test_inherited_virtuals():
...
@@ -339,7 +365,7 @@ def test_inherited_virtuals():
class
DT
(
m
.
D_Tpl
):
class
DT
(
m
.
D_Tpl
):
def
say_something
(
self
,
times
):
def
say_something
(
self
,
times
):
return
"DT says:"
+
(
' quack'
*
times
)
return
"DT says:"
+
(
" quack"
*
times
)
def
unlucky_number
(
self
):
def
unlucky_number
(
self
):
return
1234
return
1234
...
@@ -355,7 +381,7 @@ def test_inherited_virtuals():
...
@@ -355,7 +381,7 @@ def test_inherited_virtuals():
class
DT2
(
DT
):
class
DT2
(
DT
):
def
say_something
(
self
,
times
):
def
say_something
(
self
,
times
):
return
"DT2: "
+
(
'QUACK'
*
times
)
return
"DT2: "
+
(
"QUACK"
*
times
)
def
unlucky_number
(
self
):
def
unlucky_number
(
self
):
return
-
3
return
-
3
...
...
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