Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
pybind11
Commits
c50f90ec
Unverified
Commit
c50f90ec
authored
Oct 16, 2020
by
Henry Schreiner
Committed by
GitHub
Oct 16, 2020
Browse files
style: use Black everywhere (#2594)
* style: use Black everywhere * style: minor touchup from review
parent
2e31e466
Changes
38
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
768 additions
and
464 deletions
+768
-464
.pre-commit-config.yaml
.pre-commit-config.yaml
+1
-2
docs/benchmark.py
docs/benchmark.py
+20
-17
docs/conf.py
docs/conf.py
+94
-94
tests/conftest.py
tests/conftest.py
+17
-9
tests/test_buffers.py
tests/test_buffers.py
+9
-9
tests/test_builtin_casters.py
tests/test_builtin_casters.py
+85
-54
tests/test_call_policies.py
tests/test_call_policies.py
+39
-12
tests/test_callbacks.py
tests/test_callbacks.py
+21
-10
tests/test_chrono.py
tests/test_chrono.py
+23
-17
tests/test_class.py
tests/test_class.py
+82
-35
tests/test_copy_move.py
tests/test_copy_move.py
+16
-4
tests/test_custom_type_casters.py
tests/test_custom_type_casters.py
+36
-10
tests/test_docstring_options.py
tests/test_docstring_options.py
+5
-5
tests/test_eigen.py
tests/test_eigen.py
+182
-109
tests/test_enum.py
tests/test_enum.py
+18
-10
tests/test_eval_call.py
tests/test_eval_call.py
+1
-1
tests/test_exceptions.py
tests/test_exceptions.py
+15
-8
tests/test_factory_constructors.py
tests/test_factory_constructors.py
+75
-35
tests/test_gil_scoped.py
tests/test_gil_scoped.py
+4
-1
tests/test_iostream.py
tests/test_iostream.py
+25
-22
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%03i;
\n
"
%
cl
decl
+=
"class cl%03i;
\n
"
%
cl
decl
+=
'
\n
'
decl
+=
"
\n
"
for
cl
in
range
(
nclasses
):
for
cl
in
range
(
nclasses
):
decl
+=
"class cl%03i {
\n
"
%
cl
decl
+=
"class cl%03i {
\n
"
%
cl
...
@@ -26,14 +26,13 @@ def generate_dummy_code_pybind11(nclasses=10):
...
@@ -26,14 +26,13 @@ def generate_dummy_code_pybind11(nclasses=10):
decl
+=
" cl%03i *fn_%03i("
%
(
ret
,
fn
)
decl
+=
" cl%03i *fn_%03i("
%
(
ret
,
fn
)
decl
+=
", "
.
join
(
"cl%03i *"
%
p
for
p
in
params
)
decl
+=
", "
.
join
(
"cl%03i *"
%
p
for
p
in
params
)
decl
+=
");
\n
"
decl
+=
");
\n
"
bindings
+=
' .def("fn_%03i", &cl%03i::fn_%03i)
\n
'
%
\
bindings
+=
' .def("fn_%03i", &cl%03i::fn_%03i)
\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%03i;
\n
"
%
cl
decl
+=
"class cl%03i;
\n
"
%
cl
decl
+=
'
\n
'
decl
+=
"
\n
"
for
cl
in
range
(
nclasses
):
for
cl
in
range
(
nclasses
):
decl
+=
"class cl%03i {
\n
"
%
cl
decl
+=
"class cl%03i {
\n
"
%
cl
...
@@ -58,14 +57,16 @@ def generate_dummy_code_boost(nclasses=10):
...
@@ -58,14 +57,16 @@ def generate_dummy_code_boost(nclasses=10):
decl
+=
" cl%03i *fn_%03i("
%
(
ret
,
fn
)
decl
+=
" cl%03i *fn_%03i("
%
(
ret
,
fn
)
decl
+=
", "
.
join
(
"cl%03i *"
%
p
for
p
in
params
)
decl
+=
", "
.
join
(
"cl%03i *"
%
p
for
p
in
params
)
decl
+=
");
\n
"
decl
+=
");
\n
"
bindings
+=
' .def("fn_%03i", &cl%03i::fn_%03i, py::return_value_policy<py::manage_new_object>())
\n
'
%
\
bindings
+=
(
(
fn
,
cl
,
fn
)
' .def("fn_%03i", &cl%03i::fn_%03i, 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
'‽'
)
==
0x203
d
assert
m
.
ord_char16
(
u
"‽"
)
==
0x203
D
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
'‽'
)
==
0x203
d
assert
m
.
ord_char32
(
u
"‽"
)
==
0x203
D
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
'‽'
)
==
0x203
d
assert
m
.
ord_wchar
(
u
"‽"
)
==
0x203
D
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
f
0
,
0x9
f
,
0x8
e
,
0x82
]
assert
m
.
string_view_chars
(
"Hi 🎂"
)
==
[
72
,
105
,
32
,
0x
F
0
,
0x9
F
,
0x8
E
,
0x82
]
assert
m
.
string_view16_chars
(
u
"Hi 🎂"
)
==
[
72
,
105
,
32
,
0x
d
83
c
,
0x
df
82
]
assert
m
.
string_view16_chars
(
u
"Hi 🎂"
)
==
[
72
,
105
,
32
,
0x
D
83
C
,
0x
DF
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
f
0
,
0x9
f
,
0x8
e
,
0x82
]
assert
m
.
string_view8_chars
(
u
"Hi 🎂"
)
==
[
72
,
105
,
32
,
0x
F
0
,
0x9
F
,
0x8
E
,
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
...
@@ -86,10 +98,13 @@ def test_alive_gc(capture):
...
@@ -86,10 +98,13 @@ def test_alive_gc(capture):
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
):
...
@@ -105,10 +120,13 @@ def test_alive_gc_derived(capture):
...
@@ -105,10 +120,13 @@ def test_alive_gc_derived(capture):
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
):
...
@@ -127,11 +145,14 @@ def test_alive_gc_multi_derived(capture):
...
@@ -127,11 +145,14 @@ def test_alive_gc_multi_derived(capture):
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,7 +80,9 @@ SKIP_TZ_ENV_ON_WIN = pytest.mark.skipif(
...
@@ -80,7 +80,9 @@ SKIP_TZ_ENV_ON_WIN = pytest.mark.skipif(
)
)
@
pytest
.
mark
.
parametrize
(
"time1"
,
[
@
pytest
.
mark
.
parametrize
(
"time1"
,
[
datetime
.
datetime
.
today
().
time
(),
datetime
.
datetime
.
today
().
time
(),
datetime
.
time
(
0
,
0
,
0
),
datetime
.
time
(
0
,
0
,
0
),
datetime
.
time
(
0
,
0
,
0
,
1
),
datetime
.
time
(
0
,
0
,
0
,
1
),
...
@@ -89,13 +91,17 @@ SKIP_TZ_ENV_ON_WIN = pytest.mark.skipif(
...
@@ -89,13 +91,17 @@ SKIP_TZ_ENV_ON_WIN = pytest.mark.skipif(
datetime
.
time
(
1
,
0
,
0
),
datetime
.
time
(
1
,
0
,
0
),
datetime
.
time
(
5
,
59
,
59
,
0
),
datetime
.
time
(
5
,
59
,
59
,
0
),
datetime
.
time
(
5
,
59
,
59
,
1
),
datetime
.
time
(
5
,
59
,
59
,
1
),
])
],
@
pytest
.
mark
.
parametrize
(
"tz"
,
[
)
@
pytest
.
mark
.
parametrize
(
"tz"
,
[
None
,
None
,
pytest
.
param
(
"Europe/Brussels"
,
marks
=
SKIP_TZ_ENV_ON_WIN
),
pytest
.
param
(
"Europe/Brussels"
,
marks
=
SKIP_TZ_ENV_ON_WIN
),
pytest
.
param
(
"Asia/Pyongyang"
,
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
),
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
(
[
[
0.0
,
3
,
0
,
0
,
0
,
11
],
[
22
,
0
,
0
,
0
,
17
,
11
],
[
22
,
0
,
0
,
0
,
17
,
11
],
[
7
,
5
,
0
,
1
,
0
,
11
],
[
7
,
5
,
0
,
1
,
0
,
11
],
[
0
,
0
,
0
,
0
,
0
,
11
],
[
0
,
0
,
0
,
0
,
0
,
11
],
[
0
,
0
,
14
,
0
,
8
,
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
Prev
1
2
Next
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