├── .appveyor.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── MANIFEST.in ├── README.md ├── docs ├── Makefile ├── conf.py ├── index.rst ├── make.bat └── python_example.rst ├── pybind11 ├── LICENSE ├── attr.h ├── buffer_info.h ├── cast.h ├── chrono.h ├── common.h ├── complex.h ├── detail │ ├── class.h │ ├── common.h │ ├── descr.h │ ├── init.h │ ├── internals.h │ └── typeid.h ├── eigen.h ├── embed.h ├── eval.h ├── functional.h ├── iostream.h ├── numpy.h ├── operators.h ├── options.h ├── pybind11.h ├── pytypes.h ├── stl.h └── stl_bind.h ├── setup.cfg ├── setup.py ├── setup.rst └── tensorstore.cc /.appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '{build}' 2 | image: Visual Studio 2015 3 | 4 | platform: 5 | - x86 6 | - x64 7 | 8 | environment: 9 | global: 10 | DISTUTILS_USE_SDK: 1 11 | MSSdk: 1 12 | matrix: 13 | - PYTHON: 27 14 | - PYTHON: 36 15 | 16 | install: 17 | - cmd: '"%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" %PLATFORM%' 18 | - ps: | 19 | if ($env:PYTHON) { 20 | if ($env:PLATFORM -eq "x64") { $env:PYTHON = "$env:PYTHON-x64" } 21 | $env:PATH = "C:\Python$env:PYTHON\;C:\Python$env:PYTHON\Scripts\;$env:PATH" 22 | pip install --disable-pip-version-check --user --upgrade pip setuptools 23 | } 24 | 25 | build_script: 26 | - ps: | 27 | if ($env:PYTHON) { 28 | python setup.py sdist 29 | pip install --verbose dist\tensorstore-0.0.1a1.tar.gz 30 | } 31 | 32 | test_script: 33 | - ps: python -c "import tensorstore" 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.egg-info 2 | *.py[cod] 3 | *.so 4 | .DS_Store 5 | /.idea 6 | /bazel-* 7 | /build 8 | /dist 9 | /docs/.build 10 | MANIFEST 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ### Contributor License Agreements 2 | 3 | We'd love to accept your patches! Before we can take them, we have to jump a 4 | couple of legal hurdles. 5 | 6 | Please fill out either the individual or corporate Contributor License Agreement 7 | (CLA). 8 | 9 | * If you are an individual writing original source code and you're sure you 10 | own the intellectual property, then you'll need to sign an 11 | [individual CLA](http://code.google.com/legal/individual-cla-v1.0.html). 12 | * If you work for a company that wants to allow you to contribute your work, 13 | then you'll need to sign a 14 | [corporate CLA](http://code.google.com/legal/corporate-cla-v1.0.html). 15 | 16 | Follow either of the two links above to access the appropriate CLA and 17 | instructions for how to sign and return it. Once we receive it, we'll be able to 18 | accept your pull requests. 19 | 20 | ***NOTE***: Only original source code from you and other people that have signed 21 | the CLA can be accepted into the main repository. 22 | 23 | 24 | ### Working with the team 25 | 26 | If you're planning a larger contribution, please get in touch with the team 27 | through a GitHub issue before starting work - we can help guide you, and 28 | coordinating up front will make the process smoother. 29 | 30 | If you want to add a major feature, it may be a good candidate for adding a 31 | plugin. Let us know via a GitHub issue, and we can guide you in the process. 32 | 33 | ### Code reviews 34 | 35 | All submissions, including submissions by project members, require review. We 36 | use GitHub pull requests for this purpose. 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2017, The TensorFlow Authors. 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include setup.rst 3 | graft tensorstore 4 | graft pybind11 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TensorStore 2 | 3 | This project is a placeholder for TensorBoard storage code. 4 | 5 | This is not an official Google product. 6 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 21 | 22 | .PHONY: help 23 | help: 24 | @echo "Please use \`make ' where is one of" 25 | @echo " html to make standalone HTML files" 26 | @echo " dirhtml to make HTML files named index.html in directories" 27 | @echo " singlehtml to make a single large HTML file" 28 | @echo " pickle to make pickle files" 29 | @echo " json to make JSON files" 30 | @echo " htmlhelp to make HTML files and a HTML help project" 31 | @echo " qthelp to make HTML files and a qthelp project" 32 | @echo " applehelp to make an Apple Help Book" 33 | @echo " devhelp to make HTML files and a Devhelp project" 34 | @echo " epub to make an epub" 35 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 36 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 37 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 38 | @echo " text to make text files" 39 | @echo " man to make manual pages" 40 | @echo " texinfo to make Texinfo files" 41 | @echo " info to make Texinfo files and run them through makeinfo" 42 | @echo " gettext to make PO message catalogs" 43 | @echo " changes to make an overview of all changed/added/deprecated items" 44 | @echo " xml to make Docutils-native XML files" 45 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 46 | @echo " linkcheck to check all external links for integrity" 47 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 48 | @echo " coverage to run coverage check of the documentation (if enabled)" 49 | 50 | .PHONY: clean 51 | clean: 52 | rm -rf $(BUILDDIR)/* 53 | 54 | .PHONY: html 55 | html: 56 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 57 | @echo 58 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 59 | 60 | .PHONY: dirhtml 61 | dirhtml: 62 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 63 | @echo 64 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 65 | 66 | .PHONY: singlehtml 67 | singlehtml: 68 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 69 | @echo 70 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 71 | 72 | .PHONY: pickle 73 | pickle: 74 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 75 | @echo 76 | @echo "Build finished; now you can process the pickle files." 77 | 78 | .PHONY: json 79 | json: 80 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 81 | @echo 82 | @echo "Build finished; now you can process the JSON files." 83 | 84 | .PHONY: htmlhelp 85 | htmlhelp: 86 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 87 | @echo 88 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 89 | ".hhp project file in $(BUILDDIR)/htmlhelp." 90 | 91 | .PHONY: qthelp 92 | qthelp: 93 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 94 | @echo 95 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 96 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 97 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/tensorstore.qhcp" 98 | @echo "To view the help file:" 99 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/tensorstore.qhc" 100 | 101 | .PHONY: applehelp 102 | applehelp: 103 | $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp 104 | @echo 105 | @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." 106 | @echo "N.B. You won't be able to view it unless you put it in" \ 107 | "~/Library/Documentation/Help or install it in your application" \ 108 | "bundle." 109 | 110 | .PHONY: devhelp 111 | devhelp: 112 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 113 | @echo 114 | @echo "Build finished." 115 | @echo "To view the help file:" 116 | @echo "# mkdir -p $$HOME/.local/share/devhelp/tensorstore" 117 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/tensorstore" 118 | @echo "# devhelp" 119 | 120 | .PHONY: epub 121 | epub: 122 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 123 | @echo 124 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 125 | 126 | .PHONY: latex 127 | latex: 128 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 129 | @echo 130 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 131 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 132 | "(use \`make latexpdf' here to do that automatically)." 133 | 134 | .PHONY: latexpdf 135 | latexpdf: 136 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 137 | @echo "Running LaTeX files through pdflatex..." 138 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 139 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 140 | 141 | .PHONY: latexpdfja 142 | latexpdfja: 143 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 144 | @echo "Running LaTeX files through platex and dvipdfmx..." 145 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 146 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 147 | 148 | .PHONY: text 149 | text: 150 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 151 | @echo 152 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 153 | 154 | .PHONY: man 155 | man: 156 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 157 | @echo 158 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 159 | 160 | .PHONY: texinfo 161 | texinfo: 162 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 163 | @echo 164 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 165 | @echo "Run \`make' in that directory to run these through makeinfo" \ 166 | "(use \`make info' here to do that automatically)." 167 | 168 | .PHONY: info 169 | info: 170 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 171 | @echo "Running Texinfo files through makeinfo..." 172 | make -C $(BUILDDIR)/texinfo info 173 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 174 | 175 | .PHONY: gettext 176 | gettext: 177 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 178 | @echo 179 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 180 | 181 | .PHONY: changes 182 | changes: 183 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 184 | @echo 185 | @echo "The overview file is in $(BUILDDIR)/changes." 186 | 187 | .PHONY: linkcheck 188 | linkcheck: 189 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 190 | @echo 191 | @echo "Link check complete; look for any errors in the above output " \ 192 | "or in $(BUILDDIR)/linkcheck/output.txt." 193 | 194 | .PHONY: doctest 195 | doctest: 196 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 197 | @echo "Testing of doctests in the sources finished, look at the " \ 198 | "results in $(BUILDDIR)/doctest/output.txt." 199 | 200 | .PHONY: coverage 201 | coverage: 202 | $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage 203 | @echo "Testing of coverage in the sources finished, look at the " \ 204 | "results in $(BUILDDIR)/coverage/python.txt." 205 | 206 | .PHONY: xml 207 | xml: 208 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 209 | @echo 210 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 211 | 212 | .PHONY: pseudoxml 213 | pseudoxml: 214 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 215 | @echo 216 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 217 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # python_exameple documentation build configuration file, created by 4 | # sphinx-quickstart on Fri Feb 26 00:29:33 2016. 5 | # 6 | # This file is execfile()d with the current directory set to its 7 | # containing dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | import sys 16 | import os 17 | 18 | # If extensions (or modules to document with autodoc) are in another directory, 19 | # add these directories to sys.path here. If the directory is relative to the 20 | # documentation root, use os.path.abspath to make it absolute, like shown here. 21 | #sys.path.insert(0, os.path.abspath('.')) 22 | 23 | # -- General configuration ------------------------------------------------ 24 | 25 | # If your documentation needs a minimal Sphinx version, state it here. 26 | #needs_sphinx = '1.0' 27 | 28 | # Add any Sphinx extension module names here, as strings. They can be 29 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 30 | # ones. 31 | extensions = [ 32 | 'sphinx.ext.autodoc', 33 | 'sphinx.ext.intersphinx', 34 | 'sphinx.ext.autosummary', 35 | 'sphinx.ext.napoleon', 36 | ] 37 | 38 | autosummary_generate = True 39 | 40 | # Add any paths that contain templates here, relative to this directory. 41 | templates_path = ['_templates'] 42 | 43 | # The suffix(es) of source filenames. 44 | # You can specify multiple suffix as a list of string: 45 | # source_suffix = ['.rst', '.md'] 46 | source_suffix = '.rst' 47 | 48 | # The encoding of source files. 49 | #source_encoding = 'utf-8-sig' 50 | 51 | # The master toctree document. 52 | master_doc = 'index' 53 | 54 | # General information about the project. 55 | project = u'tensorstore' 56 | copyright = u'2018 Google LLC' 57 | author = u'Justine Tunney' 58 | 59 | # The version info for the project you're documenting, acts as replacement for 60 | # |version| and |release|, also used in various other places throughout the 61 | # built documents. 62 | # 63 | # The short X.Y version. 64 | version = u'0.0.1' 65 | # The full version, including alpha/beta/rc tags. 66 | release = u'0.0.1' 67 | 68 | # The language for content autogenerated by Sphinx. Refer to documentation 69 | # for a list of supported languages. 70 | # 71 | # This is also used if you do content translation via gettext catalogs. 72 | # Usually you set "language" from the command line for these cases. 73 | language = None 74 | 75 | # There are two options for replacing |today|: either, you set today to some 76 | # non-false value, then it is used: 77 | #today = '' 78 | # Else, today_fmt is used as the format for a strftime call. 79 | #today_fmt = '%B %d, %Y' 80 | 81 | # List of patterns, relative to source directory, that match files and 82 | # directories to ignore when looking for source files. 83 | exclude_patterns = ['.build'] 84 | 85 | # The reST default role (used for this markup: `text`) to use for all 86 | # documents. 87 | #default_role = None 88 | 89 | # If true, '()' will be appended to :func: etc. cross-reference text. 90 | #add_function_parentheses = True 91 | 92 | # If true, the current module name will be prepended to all description 93 | # unit titles (such as .. function::). 94 | #add_module_names = True 95 | 96 | # If true, sectionauthor and moduleauthor directives will be shown in the 97 | # output. They are ignored by default. 98 | #show_authors = False 99 | 100 | # The name of the Pygments (syntax highlighting) style to use. 101 | pygments_style = 'sphinx' 102 | 103 | # A list of ignored prefixes for module index sorting. 104 | #modindex_common_prefix = [] 105 | 106 | # If true, keep warnings as "system message" paragraphs in the built documents. 107 | #keep_warnings = False 108 | 109 | # If true, `todo` and `todoList` produce output, else they produce nothing. 110 | todo_include_todos = False 111 | 112 | 113 | # -- Options for HTML output ---------------------------------------------- 114 | 115 | # The theme to use for HTML and HTML Help pages. See the documentation for 116 | # a list of builtin themes. 117 | html_theme = 'alabaster' 118 | 119 | # Theme options are theme-specific and customize the look and feel of a theme 120 | # further. For a list of options available for each theme, see the 121 | # documentation. 122 | #html_theme_options = {} 123 | 124 | # Add any paths that contain custom themes here, relative to this directory. 125 | #html_theme_path = [] 126 | 127 | # The name for this set of Sphinx documents. If None, it defaults to 128 | # " v documentation". 129 | #html_title = None 130 | 131 | # A shorter title for the navigation bar. Default is the same as html_title. 132 | #html_short_title = None 133 | 134 | # The name of an image file (relative to this directory) to place at the top 135 | # of the sidebar. 136 | #html_logo = None 137 | 138 | # The name of an image file (within the static path) to use as favicon of the 139 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 140 | # pixels large. 141 | #html_favicon = None 142 | 143 | # Add any paths that contain custom static files (such as style sheets) here, 144 | # relative to this directory. They are copied after the builtin static files, 145 | # so a file named "default.css" will overwrite the builtin "default.css". 146 | html_static_path = ['_static'] 147 | 148 | # Add any extra paths that contain custom files (such as robots.txt or 149 | # .htaccess) here, relative to this directory. These files are copied 150 | # directly to the root of the documentation. 151 | #html_extra_path = [] 152 | 153 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 154 | # using the given strftime format. 155 | #html_last_updated_fmt = '%b %d, %Y' 156 | 157 | # If true, SmartyPants will be used to convert quotes and dashes to 158 | # typographically correct entities. 159 | #html_use_smartypants = True 160 | 161 | # Custom sidebar templates, maps document names to template names. 162 | #html_sidebars = {} 163 | 164 | # Additional templates that should be rendered to pages, maps page names to 165 | # template names. 166 | #html_additional_pages = {} 167 | 168 | # If false, no module index is generated. 169 | #html_domain_indices = True 170 | 171 | # If false, no index is generated. 172 | #html_use_index = True 173 | 174 | # If true, the index is split into individual pages for each letter. 175 | #html_split_index = False 176 | 177 | # If true, links to the reST sources are added to the pages. 178 | #html_show_sourcelink = True 179 | 180 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 181 | #html_show_sphinx = True 182 | 183 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 184 | #html_show_copyright = True 185 | 186 | # If true, an OpenSearch description file will be output, and all pages will 187 | # contain a tag referring to it. The value of this option must be the 188 | # base URL from which the finished HTML is served. 189 | #html_use_opensearch = '' 190 | 191 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 192 | #html_file_suffix = None 193 | 194 | # Language to be used for generating the HTML full-text search index. 195 | # Sphinx supports the following languages: 196 | # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' 197 | # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' 198 | #html_search_language = 'en' 199 | 200 | # A dictionary with options for the search language support, empty by default. 201 | # Now only 'ja' uses this config value 202 | #html_search_options = {'type': 'default'} 203 | 204 | # The name of a javascript file (relative to the configuration directory) that 205 | # implements a search results scorer. If empty, the default will be used. 206 | #html_search_scorer = 'scorer.js' 207 | 208 | # Output file base name for HTML help builder. 209 | htmlhelp_basename = 'tensorstoredoc' 210 | 211 | # -- Options for LaTeX output --------------------------------------------- 212 | 213 | latex_elements = { 214 | # The paper size ('letterpaper' or 'a4paper'). 215 | #'papersize': 'letterpaper', 216 | 217 | # The font size ('10pt', '11pt' or '12pt'). 218 | #'pointsize': '10pt', 219 | 220 | # Additional stuff for the LaTeX preamble. 221 | #'preamble': '', 222 | 223 | # Latex figure (float) alignment 224 | #'figure_align': 'htbp', 225 | } 226 | 227 | # Grouping the document tree into LaTeX files. List of tuples 228 | # (source start file, target name, title, 229 | # author, documentclass [howto, manual, or own class]). 230 | latex_documents = [ 231 | (master_doc, 'tensorstore.tex', u'TensorStore Documentation', 232 | author, 'manual'), 233 | ] 234 | 235 | # The name of an image file (relative to this directory) to place at the top of 236 | # the title page. 237 | #latex_logo = None 238 | 239 | # For "manual" documents, if this is true, then toplevel headings are parts, 240 | # not chapters. 241 | #latex_use_parts = False 242 | 243 | # If true, show page references after internal links. 244 | #latex_show_pagerefs = False 245 | 246 | # If true, show URL addresses after external links. 247 | #latex_show_urls = False 248 | 249 | # Documents to append as an appendix to all manuals. 250 | #latex_appendices = [] 251 | 252 | # If false, no module index is generated. 253 | #latex_domain_indices = True 254 | 255 | 256 | # -- Options for manual page output --------------------------------------- 257 | 258 | # One entry per manual page. List of tuples 259 | # (source start file, name, description, authors, manual section). 260 | man_pages = [ 261 | (master_doc, 'tensorstore', u'TensorStore Documentation', 262 | [author], 1) 263 | ] 264 | 265 | # If true, show URL addresses after external links. 266 | #man_show_urls = False 267 | 268 | 269 | # -- Options for Texinfo output ------------------------------------------- 270 | 271 | # Grouping the document tree into Texinfo files. List of tuples 272 | # (source start file, target name, title, author, 273 | # dir menu entry, description, category) 274 | texinfo_documents = [ 275 | (master_doc, 'tensorstore', u'TensorStore Documentation', 276 | author, 'tensorstore', 'A TensorBoard storage system.', 277 | 'Miscellaneous'), 278 | ] 279 | 280 | # Documents to append as an appendix to all manuals. 281 | #texinfo_appendices = [] 282 | 283 | # If false, no module index is generated. 284 | #texinfo_domain_indices = True 285 | 286 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 287 | #texinfo_show_urls = 'footnote' 288 | 289 | # If true, do not generate a @detailmenu in the "Top" node's menu. 290 | #texinfo_no_detailmenu = False 291 | 292 | 293 | # Example configuration for intersphinx: refer to the Python standard library. 294 | intersphinx_mapping = {'https://docs.python.org/': None} 295 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | TensorStore Documentation 2 | ========================= 3 | 4 | Contents: 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | tensorstore 10 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=_build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . 10 | set I18NSPHINXOPTS=%SPHINXOPTS% . 11 | if NOT "%PAPER%" == "" ( 12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% 14 | ) 15 | 16 | if "%1" == "" goto help 17 | 18 | if "%1" == "help" ( 19 | :help 20 | echo.Please use `make ^` where ^ is one of 21 | echo. html to make standalone HTML files 22 | echo. dirhtml to make HTML files named index.html in directories 23 | echo. singlehtml to make a single large HTML file 24 | echo. pickle to make pickle files 25 | echo. json to make JSON files 26 | echo. htmlhelp to make HTML files and a HTML help project 27 | echo. qthelp to make HTML files and a qthelp project 28 | echo. devhelp to make HTML files and a Devhelp project 29 | echo. epub to make an epub 30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 31 | echo. text to make text files 32 | echo. man to make manual pages 33 | echo. texinfo to make Texinfo files 34 | echo. gettext to make PO message catalogs 35 | echo. changes to make an overview over all changed/added/deprecated items 36 | echo. xml to make Docutils-native XML files 37 | echo. pseudoxml to make pseudoxml-XML files for display purposes 38 | echo. linkcheck to check all external links for integrity 39 | echo. doctest to run all doctests embedded in the documentation if enabled 40 | echo. coverage to run coverage check of the documentation if enabled 41 | goto end 42 | ) 43 | 44 | if "%1" == "clean" ( 45 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 46 | del /q /s %BUILDDIR%\* 47 | goto end 48 | ) 49 | 50 | 51 | REM Check if sphinx-build is available and fallback to Python version if any 52 | %SPHINXBUILD% 1>NUL 2>NUL 53 | if errorlevel 9009 goto sphinx_python 54 | goto sphinx_ok 55 | 56 | :sphinx_python 57 | 58 | set SPHINXBUILD=python -m sphinx.__init__ 59 | %SPHINXBUILD% 2> nul 60 | if errorlevel 9009 ( 61 | echo. 62 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 63 | echo.installed, then set the SPHINXBUILD environment variable to point 64 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 65 | echo.may add the Sphinx directory to PATH. 66 | echo. 67 | echo.If you don't have Sphinx installed, grab it from 68 | echo.http://sphinx-doc.org/ 69 | exit /b 1 70 | ) 71 | 72 | :sphinx_ok 73 | 74 | 75 | if "%1" == "html" ( 76 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 77 | if errorlevel 1 exit /b 1 78 | echo. 79 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 80 | goto end 81 | ) 82 | 83 | if "%1" == "dirhtml" ( 84 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 85 | if errorlevel 1 exit /b 1 86 | echo. 87 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 88 | goto end 89 | ) 90 | 91 | if "%1" == "singlehtml" ( 92 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 93 | if errorlevel 1 exit /b 1 94 | echo. 95 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 96 | goto end 97 | ) 98 | 99 | if "%1" == "pickle" ( 100 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 101 | if errorlevel 1 exit /b 1 102 | echo. 103 | echo.Build finished; now you can process the pickle files. 104 | goto end 105 | ) 106 | 107 | if "%1" == "json" ( 108 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 109 | if errorlevel 1 exit /b 1 110 | echo. 111 | echo.Build finished; now you can process the JSON files. 112 | goto end 113 | ) 114 | 115 | if "%1" == "htmlhelp" ( 116 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 117 | if errorlevel 1 exit /b 1 118 | echo. 119 | echo.Build finished; now you can run HTML Help Workshop with the ^ 120 | .hhp project file in %BUILDDIR%/htmlhelp. 121 | goto end 122 | ) 123 | 124 | if "%1" == "qthelp" ( 125 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 126 | if errorlevel 1 exit /b 1 127 | echo. 128 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 129 | .qhcp project file in %BUILDDIR%/qthelp, like this: 130 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\tensorstore.qhcp 131 | echo.To view the help file: 132 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\tensorstore.ghc 133 | goto end 134 | ) 135 | 136 | if "%1" == "devhelp" ( 137 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 138 | if errorlevel 1 exit /b 1 139 | echo. 140 | echo.Build finished. 141 | goto end 142 | ) 143 | 144 | if "%1" == "epub" ( 145 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 146 | if errorlevel 1 exit /b 1 147 | echo. 148 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 149 | goto end 150 | ) 151 | 152 | if "%1" == "latex" ( 153 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 154 | if errorlevel 1 exit /b 1 155 | echo. 156 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 157 | goto end 158 | ) 159 | 160 | if "%1" == "latexpdf" ( 161 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 162 | cd %BUILDDIR%/latex 163 | make all-pdf 164 | cd %~dp0 165 | echo. 166 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 167 | goto end 168 | ) 169 | 170 | if "%1" == "latexpdfja" ( 171 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 172 | cd %BUILDDIR%/latex 173 | make all-pdf-ja 174 | cd %~dp0 175 | echo. 176 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 177 | goto end 178 | ) 179 | 180 | if "%1" == "text" ( 181 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 182 | if errorlevel 1 exit /b 1 183 | echo. 184 | echo.Build finished. The text files are in %BUILDDIR%/text. 185 | goto end 186 | ) 187 | 188 | if "%1" == "man" ( 189 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 190 | if errorlevel 1 exit /b 1 191 | echo. 192 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 193 | goto end 194 | ) 195 | 196 | if "%1" == "texinfo" ( 197 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo 198 | if errorlevel 1 exit /b 1 199 | echo. 200 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. 201 | goto end 202 | ) 203 | 204 | if "%1" == "gettext" ( 205 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale 206 | if errorlevel 1 exit /b 1 207 | echo. 208 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale. 209 | goto end 210 | ) 211 | 212 | if "%1" == "changes" ( 213 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 214 | if errorlevel 1 exit /b 1 215 | echo. 216 | echo.The overview file is in %BUILDDIR%/changes. 217 | goto end 218 | ) 219 | 220 | if "%1" == "linkcheck" ( 221 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 222 | if errorlevel 1 exit /b 1 223 | echo. 224 | echo.Link check complete; look for any errors in the above output ^ 225 | or in %BUILDDIR%/linkcheck/output.txt. 226 | goto end 227 | ) 228 | 229 | if "%1" == "doctest" ( 230 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 231 | if errorlevel 1 exit /b 1 232 | echo. 233 | echo.Testing of doctests in the sources finished, look at the ^ 234 | results in %BUILDDIR%/doctest/output.txt. 235 | goto end 236 | ) 237 | 238 | if "%1" == "coverage" ( 239 | %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage 240 | if errorlevel 1 exit /b 1 241 | echo. 242 | echo.Testing of coverage in the sources finished, look at the ^ 243 | results in %BUILDDIR%/coverage/python.txt. 244 | goto end 245 | ) 246 | 247 | if "%1" == "xml" ( 248 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml 249 | if errorlevel 1 exit /b 1 250 | echo. 251 | echo.Build finished. The XML files are in %BUILDDIR%/xml. 252 | goto end 253 | ) 254 | 255 | if "%1" == "pseudoxml" ( 256 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml 257 | if errorlevel 1 exit /b 1 258 | echo. 259 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. 260 | goto end 261 | ) 262 | 263 | :end 264 | -------------------------------------------------------------------------------- /docs/python_example.rst: -------------------------------------------------------------------------------- 1 | .. automodule:: tensorstore 2 | -------------------------------------------------------------------------------- /pybind11/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Wenzel Jakob , All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | 3. Neither the name of the copyright holder nor the names of its contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | Please also refer to the file CONTRIBUTING.md, which clarifies licensing of 29 | external contributions to this project including patches, pull requests, etc. 30 | -------------------------------------------------------------------------------- /pybind11/attr.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/attr.h: Infrastructure for processing custom 3 | type and function attributes 4 | 5 | Copyright (c) 2016 Wenzel Jakob 6 | 7 | All rights reserved. Use of this source code is governed by a 8 | BSD-style license that can be found in the LICENSE file. 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "cast.h" 14 | 15 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 16 | 17 | /// \addtogroup annotations 18 | /// @{ 19 | 20 | /// Annotation for methods 21 | struct is_method { handle class_; is_method(const handle &c) : class_(c) { } }; 22 | 23 | /// Annotation for operators 24 | struct is_operator { }; 25 | 26 | /// Annotation for parent scope 27 | struct scope { handle value; scope(const handle &s) : value(s) { } }; 28 | 29 | /// Annotation for documentation 30 | struct doc { const char *value; doc(const char *value) : value(value) { } }; 31 | 32 | /// Annotation for function names 33 | struct name { const char *value; name(const char *value) : value(value) { } }; 34 | 35 | /// Annotation indicating that a function is an overload associated with a given "sibling" 36 | struct sibling { handle value; sibling(const handle &value) : value(value.ptr()) { } }; 37 | 38 | /// Annotation indicating that a class derives from another given type 39 | template struct base { 40 | PYBIND11_DEPRECATED("base() was deprecated in favor of specifying 'T' as a template argument to class_") 41 | base() { } 42 | }; 43 | 44 | /// Keep patient alive while nurse lives 45 | template struct keep_alive { }; 46 | 47 | /// Annotation indicating that a class is involved in a multiple inheritance relationship 48 | struct multiple_inheritance { }; 49 | 50 | /// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class 51 | struct dynamic_attr { }; 52 | 53 | /// Annotation which enables the buffer protocol for a type 54 | struct buffer_protocol { }; 55 | 56 | /// Annotation which requests that a special metaclass is created for a type 57 | struct metaclass { 58 | handle value; 59 | 60 | PYBIND11_DEPRECATED("py::metaclass() is no longer required. It's turned on by default now.") 61 | metaclass() {} 62 | 63 | /// Override pybind11's default metaclass 64 | explicit metaclass(handle value) : value(value) { } 65 | }; 66 | 67 | /// Annotation that marks a class as local to the module: 68 | struct module_local { const bool value; constexpr module_local(bool v = true) : value(v) { } }; 69 | 70 | /// Annotation to mark enums as an arithmetic type 71 | struct arithmetic { }; 72 | 73 | /** \rst 74 | A call policy which places one or more guard variables (``Ts...``) around the function call. 75 | 76 | For example, this definition: 77 | 78 | .. code-block:: cpp 79 | 80 | m.def("foo", foo, py::call_guard()); 81 | 82 | is equivalent to the following pseudocode: 83 | 84 | .. code-block:: cpp 85 | 86 | m.def("foo", [](args...) { 87 | T scope_guard; 88 | return foo(args...); // forwarded arguments 89 | }); 90 | \endrst */ 91 | template struct call_guard; 92 | 93 | template <> struct call_guard<> { using type = detail::void_type; }; 94 | 95 | template 96 | struct call_guard { 97 | static_assert(std::is_default_constructible::value, 98 | "The guard type must be default constructible"); 99 | 100 | using type = T; 101 | }; 102 | 103 | template 104 | struct call_guard { 105 | struct type { 106 | T guard{}; // Compose multiple guard types with left-to-right default-constructor order 107 | typename call_guard::type next{}; 108 | }; 109 | }; 110 | 111 | /// @} annotations 112 | 113 | NAMESPACE_BEGIN(detail) 114 | /* Forward declarations */ 115 | enum op_id : int; 116 | enum op_type : int; 117 | struct undefined_t; 118 | template struct op_; 119 | inline void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret); 120 | 121 | /// Internal data structure which holds metadata about a keyword argument 122 | struct argument_record { 123 | const char *name; ///< Argument name 124 | const char *descr; ///< Human-readable version of the argument value 125 | handle value; ///< Associated Python object 126 | bool convert : 1; ///< True if the argument is allowed to convert when loading 127 | bool none : 1; ///< True if None is allowed when loading 128 | 129 | argument_record(const char *name, const char *descr, handle value, bool convert, bool none) 130 | : name(name), descr(descr), value(value), convert(convert), none(none) { } 131 | }; 132 | 133 | /// Internal data structure which holds metadata about a bound function (signature, overloads, etc.) 134 | struct function_record { 135 | function_record() 136 | : is_constructor(false), is_new_style_constructor(false), is_stateless(false), 137 | is_operator(false), has_args(false), has_kwargs(false), is_method(false) { } 138 | 139 | /// Function name 140 | char *name = nullptr; /* why no C++ strings? They generate heavier code.. */ 141 | 142 | // User-specified documentation string 143 | char *doc = nullptr; 144 | 145 | /// Human-readable version of the function signature 146 | char *signature = nullptr; 147 | 148 | /// List of registered keyword arguments 149 | std::vector args; 150 | 151 | /// Pointer to lambda function which converts arguments and performs the actual call 152 | handle (*impl) (function_call &) = nullptr; 153 | 154 | /// Storage for the wrapped function pointer and captured data, if any 155 | void *data[3] = { }; 156 | 157 | /// Pointer to custom destructor for 'data' (if needed) 158 | void (*free_data) (function_record *ptr) = nullptr; 159 | 160 | /// Return value policy associated with this function 161 | return_value_policy policy = return_value_policy::automatic; 162 | 163 | /// True if name == '__init__' 164 | bool is_constructor : 1; 165 | 166 | /// True if this is a new-style `__init__` defined in `detail/init.h` 167 | bool is_new_style_constructor : 1; 168 | 169 | /// True if this is a stateless function pointer 170 | bool is_stateless : 1; 171 | 172 | /// True if this is an operator (__add__), etc. 173 | bool is_operator : 1; 174 | 175 | /// True if the function has a '*args' argument 176 | bool has_args : 1; 177 | 178 | /// True if the function has a '**kwargs' argument 179 | bool has_kwargs : 1; 180 | 181 | /// True if this is a method 182 | bool is_method : 1; 183 | 184 | /// Number of arguments (including py::args and/or py::kwargs, if present) 185 | std::uint16_t nargs; 186 | 187 | /// Python method object 188 | PyMethodDef *def = nullptr; 189 | 190 | /// Python handle to the parent scope (a class or a module) 191 | handle scope; 192 | 193 | /// Python handle to the sibling function representing an overload chain 194 | handle sibling; 195 | 196 | /// Pointer to next overload 197 | function_record *next = nullptr; 198 | }; 199 | 200 | /// Special data structure which (temporarily) holds metadata about a bound class 201 | struct type_record { 202 | PYBIND11_NOINLINE type_record() 203 | : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false), module_local(false) { } 204 | 205 | /// Handle to the parent scope 206 | handle scope; 207 | 208 | /// Name of the class 209 | const char *name = nullptr; 210 | 211 | // Pointer to RTTI type_info data structure 212 | const std::type_info *type = nullptr; 213 | 214 | /// How large is the underlying C++ type? 215 | size_t type_size = 0; 216 | 217 | /// How large is the type's holder? 218 | size_t holder_size = 0; 219 | 220 | /// The global operator new can be overridden with a class-specific variant 221 | void *(*operator_new)(size_t) = ::operator new; 222 | 223 | /// Function pointer to class_<..>::init_instance 224 | void (*init_instance)(instance *, const void *) = nullptr; 225 | 226 | /// Function pointer to class_<..>::dealloc 227 | void (*dealloc)(detail::value_and_holder &) = nullptr; 228 | 229 | /// List of base classes of the newly created type 230 | list bases; 231 | 232 | /// Optional docstring 233 | const char *doc = nullptr; 234 | 235 | /// Custom metaclass (optional) 236 | handle metaclass; 237 | 238 | /// Multiple inheritance marker 239 | bool multiple_inheritance : 1; 240 | 241 | /// Does the class manage a __dict__? 242 | bool dynamic_attr : 1; 243 | 244 | /// Does the class implement the buffer protocol? 245 | bool buffer_protocol : 1; 246 | 247 | /// Is the default (unique_ptr) holder type used? 248 | bool default_holder : 1; 249 | 250 | /// Is the class definition local to the module shared object? 251 | bool module_local : 1; 252 | 253 | PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *)) { 254 | auto base_info = detail::get_type_info(base, false); 255 | if (!base_info) { 256 | std::string tname(base.name()); 257 | detail::clean_type_id(tname); 258 | pybind11_fail("generic_type: type \"" + std::string(name) + 259 | "\" referenced unknown base type \"" + tname + "\""); 260 | } 261 | 262 | if (default_holder != base_info->default_holder) { 263 | std::string tname(base.name()); 264 | detail::clean_type_id(tname); 265 | pybind11_fail("generic_type: type \"" + std::string(name) + "\" " + 266 | (default_holder ? "does not have" : "has") + 267 | " a non-default holder type while its base \"" + tname + "\" " + 268 | (base_info->default_holder ? "does not" : "does")); 269 | } 270 | 271 | bases.append((PyObject *) base_info->type); 272 | 273 | if (base_info->type->tp_dictoffset != 0) 274 | dynamic_attr = true; 275 | 276 | if (caster) 277 | base_info->implicit_casts.emplace_back(type, caster); 278 | } 279 | }; 280 | 281 | inline function_call::function_call(function_record &f, handle p) : 282 | func(f), parent(p) { 283 | args.reserve(f.nargs); 284 | args_convert.reserve(f.nargs); 285 | } 286 | 287 | /// Tag for a new-style `__init__` defined in `detail/init.h` 288 | struct is_new_style_constructor { }; 289 | 290 | /** 291 | * Partial template specializations to process custom attributes provided to 292 | * cpp_function_ and class_. These are either used to initialize the respective 293 | * fields in the type_record and function_record data structures or executed at 294 | * runtime to deal with custom call policies (e.g. keep_alive). 295 | */ 296 | template struct process_attribute; 297 | 298 | template struct process_attribute_default { 299 | /// Default implementation: do nothing 300 | static void init(const T &, function_record *) { } 301 | static void init(const T &, type_record *) { } 302 | static void precall(function_call &) { } 303 | static void postcall(function_call &, handle) { } 304 | }; 305 | 306 | /// Process an attribute specifying the function's name 307 | template <> struct process_attribute : process_attribute_default { 308 | static void init(const name &n, function_record *r) { r->name = const_cast(n.value); } 309 | }; 310 | 311 | /// Process an attribute specifying the function's docstring 312 | template <> struct process_attribute : process_attribute_default { 313 | static void init(const doc &n, function_record *r) { r->doc = const_cast(n.value); } 314 | }; 315 | 316 | /// Process an attribute specifying the function's docstring (provided as a C-style string) 317 | template <> struct process_attribute : process_attribute_default { 318 | static void init(const char *d, function_record *r) { r->doc = const_cast(d); } 319 | static void init(const char *d, type_record *r) { r->doc = const_cast(d); } 320 | }; 321 | template <> struct process_attribute : process_attribute { }; 322 | 323 | /// Process an attribute indicating the function's return value policy 324 | template <> struct process_attribute : process_attribute_default { 325 | static void init(const return_value_policy &p, function_record *r) { r->policy = p; } 326 | }; 327 | 328 | /// Process an attribute which indicates that this is an overloaded function associated with a given sibling 329 | template <> struct process_attribute : process_attribute_default { 330 | static void init(const sibling &s, function_record *r) { r->sibling = s.value; } 331 | }; 332 | 333 | /// Process an attribute which indicates that this function is a method 334 | template <> struct process_attribute : process_attribute_default { 335 | static void init(const is_method &s, function_record *r) { r->is_method = true; r->scope = s.class_; } 336 | }; 337 | 338 | /// Process an attribute which indicates the parent scope of a method 339 | template <> struct process_attribute : process_attribute_default { 340 | static void init(const scope &s, function_record *r) { r->scope = s.value; } 341 | }; 342 | 343 | /// Process an attribute which indicates that this function is an operator 344 | template <> struct process_attribute : process_attribute_default { 345 | static void init(const is_operator &, function_record *r) { r->is_operator = true; } 346 | }; 347 | 348 | template <> struct process_attribute : process_attribute_default { 349 | static void init(const is_new_style_constructor &, function_record *r) { r->is_new_style_constructor = true; } 350 | }; 351 | 352 | /// Process a keyword argument attribute (*without* a default value) 353 | template <> struct process_attribute : process_attribute_default { 354 | static void init(const arg &a, function_record *r) { 355 | if (r->is_method && r->args.empty()) 356 | r->args.emplace_back("self", nullptr, handle(), true /*convert*/, false /*none not allowed*/); 357 | r->args.emplace_back(a.name, nullptr, handle(), !a.flag_noconvert, a.flag_none); 358 | } 359 | }; 360 | 361 | /// Process a keyword argument attribute (*with* a default value) 362 | template <> struct process_attribute : process_attribute_default { 363 | static void init(const arg_v &a, function_record *r) { 364 | if (r->is_method && r->args.empty()) 365 | r->args.emplace_back("self", nullptr /*descr*/, handle() /*parent*/, true /*convert*/, false /*none not allowed*/); 366 | 367 | if (!a.value) { 368 | #if !defined(NDEBUG) 369 | std::string descr("'"); 370 | if (a.name) descr += std::string(a.name) + ": "; 371 | descr += a.type + "'"; 372 | if (r->is_method) { 373 | if (r->name) 374 | descr += " in method '" + (std::string) str(r->scope) + "." + (std::string) r->name + "'"; 375 | else 376 | descr += " in method of '" + (std::string) str(r->scope) + "'"; 377 | } else if (r->name) { 378 | descr += " in function '" + (std::string) r->name + "'"; 379 | } 380 | pybind11_fail("arg(): could not convert default argument " 381 | + descr + " into a Python object (type not registered yet?)"); 382 | #else 383 | pybind11_fail("arg(): could not convert default argument " 384 | "into a Python object (type not registered yet?). " 385 | "Compile in debug mode for more information."); 386 | #endif 387 | } 388 | r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none); 389 | } 390 | }; 391 | 392 | /// Process a parent class attribute. Single inheritance only (class_ itself already guarantees that) 393 | template 394 | struct process_attribute::value>> : process_attribute_default { 395 | static void init(const handle &h, type_record *r) { r->bases.append(h); } 396 | }; 397 | 398 | /// Process a parent class attribute (deprecated, does not support multiple inheritance) 399 | template 400 | struct process_attribute> : process_attribute_default> { 401 | static void init(const base &, type_record *r) { r->add_base(typeid(T), nullptr); } 402 | }; 403 | 404 | /// Process a multiple inheritance attribute 405 | template <> 406 | struct process_attribute : process_attribute_default { 407 | static void init(const multiple_inheritance &, type_record *r) { r->multiple_inheritance = true; } 408 | }; 409 | 410 | template <> 411 | struct process_attribute : process_attribute_default { 412 | static void init(const dynamic_attr &, type_record *r) { r->dynamic_attr = true; } 413 | }; 414 | 415 | template <> 416 | struct process_attribute : process_attribute_default { 417 | static void init(const buffer_protocol &, type_record *r) { r->buffer_protocol = true; } 418 | }; 419 | 420 | template <> 421 | struct process_attribute : process_attribute_default { 422 | static void init(const metaclass &m, type_record *r) { r->metaclass = m.value; } 423 | }; 424 | 425 | template <> 426 | struct process_attribute : process_attribute_default { 427 | static void init(const module_local &l, type_record *r) { r->module_local = l.value; } 428 | }; 429 | 430 | /// Process an 'arithmetic' attribute for enums (does nothing here) 431 | template <> 432 | struct process_attribute : process_attribute_default {}; 433 | 434 | template 435 | struct process_attribute> : process_attribute_default> { }; 436 | 437 | /** 438 | * Process a keep_alive call policy -- invokes keep_alive_impl during the 439 | * pre-call handler if both Nurse, Patient != 0 and use the post-call handler 440 | * otherwise 441 | */ 442 | template struct process_attribute> : public process_attribute_default> { 443 | template = 0> 444 | static void precall(function_call &call) { keep_alive_impl(Nurse, Patient, call, handle()); } 445 | template = 0> 446 | static void postcall(function_call &, handle) { } 447 | template = 0> 448 | static void precall(function_call &) { } 449 | template = 0> 450 | static void postcall(function_call &call, handle ret) { keep_alive_impl(Nurse, Patient, call, ret); } 451 | }; 452 | 453 | /// Recursively iterate over variadic template arguments 454 | template struct process_attributes { 455 | static void init(const Args&... args, function_record *r) { 456 | int unused[] = { 0, (process_attribute::type>::init(args, r), 0) ... }; 457 | ignore_unused(unused); 458 | } 459 | static void init(const Args&... args, type_record *r) { 460 | int unused[] = { 0, (process_attribute::type>::init(args, r), 0) ... }; 461 | ignore_unused(unused); 462 | } 463 | static void precall(function_call &call) { 464 | int unused[] = { 0, (process_attribute::type>::precall(call), 0) ... }; 465 | ignore_unused(unused); 466 | } 467 | static void postcall(function_call &call, handle fn_ret) { 468 | int unused[] = { 0, (process_attribute::type>::postcall(call, fn_ret), 0) ... }; 469 | ignore_unused(unused); 470 | } 471 | }; 472 | 473 | template 474 | using is_call_guard = is_instantiation; 475 | 476 | /// Extract the ``type`` from the first `call_guard` in `Extras...` (or `void_type` if none found) 477 | template 478 | using extract_guard_t = typename exactly_one_t, Extra...>::type; 479 | 480 | /// Check the number of named arguments at compile time 481 | template ::value...), 483 | size_t self = constexpr_sum(std::is_same::value...)> 484 | constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) { 485 | return named == 0 || (self + named + has_args + has_kwargs) == nargs; 486 | } 487 | 488 | NAMESPACE_END(detail) 489 | NAMESPACE_END(PYBIND11_NAMESPACE) 490 | -------------------------------------------------------------------------------- /pybind11/buffer_info.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/buffer_info.h: Python buffer object interface 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "detail/common.h" 13 | 14 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 15 | 16 | /// Information record describing a Python buffer object 17 | struct buffer_info { 18 | void *ptr = nullptr; // Pointer to the underlying storage 19 | ssize_t itemsize = 0; // Size of individual items in bytes 20 | ssize_t size = 0; // Total number of entries 21 | std::string format; // For homogeneous buffers, this should be set to format_descriptor::format() 22 | ssize_t ndim = 0; // Number of dimensions 23 | std::vector shape; // Shape of the tensor (1 entry per dimension) 24 | std::vector strides; // Number of entries between adjacent entries (for each per dimension) 25 | 26 | buffer_info() { } 27 | 28 | buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, 29 | detail::any_container shape_in, detail::any_container strides_in) 30 | : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim), 31 | shape(std::move(shape_in)), strides(std::move(strides_in)) { 32 | if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size()) 33 | pybind11_fail("buffer_info: ndim doesn't match shape and/or strides length"); 34 | for (size_t i = 0; i < (size_t) ndim; ++i) 35 | size *= shape[i]; 36 | } 37 | 38 | template 39 | buffer_info(T *ptr, detail::any_container shape_in, detail::any_container strides_in) 40 | : buffer_info(private_ctr_tag(), ptr, sizeof(T), format_descriptor::format(), static_cast(shape_in->size()), std::move(shape_in), std::move(strides_in)) { } 41 | 42 | buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t size) 43 | : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}) { } 44 | 45 | template 46 | buffer_info(T *ptr, ssize_t size) 47 | : buffer_info(ptr, sizeof(T), format_descriptor::format(), size) { } 48 | 49 | explicit buffer_info(Py_buffer *view, bool ownview = true) 50 | : buffer_info(view->buf, view->itemsize, view->format, view->ndim, 51 | {view->shape, view->shape + view->ndim}, {view->strides, view->strides + view->ndim}) { 52 | this->view = view; 53 | this->ownview = ownview; 54 | } 55 | 56 | buffer_info(const buffer_info &) = delete; 57 | buffer_info& operator=(const buffer_info &) = delete; 58 | 59 | buffer_info(buffer_info &&other) { 60 | (*this) = std::move(other); 61 | } 62 | 63 | buffer_info& operator=(buffer_info &&rhs) { 64 | ptr = rhs.ptr; 65 | itemsize = rhs.itemsize; 66 | size = rhs.size; 67 | format = std::move(rhs.format); 68 | ndim = rhs.ndim; 69 | shape = std::move(rhs.shape); 70 | strides = std::move(rhs.strides); 71 | std::swap(view, rhs.view); 72 | std::swap(ownview, rhs.ownview); 73 | return *this; 74 | } 75 | 76 | ~buffer_info() { 77 | if (view && ownview) { PyBuffer_Release(view); delete view; } 78 | } 79 | 80 | private: 81 | struct private_ctr_tag { }; 82 | 83 | buffer_info(private_ctr_tag, void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, 84 | detail::any_container &&shape_in, detail::any_container &&strides_in) 85 | : buffer_info(ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in)) { } 86 | 87 | Py_buffer *view = nullptr; 88 | bool ownview = false; 89 | }; 90 | 91 | NAMESPACE_BEGIN(detail) 92 | 93 | template struct compare_buffer_info { 94 | static bool compare(const buffer_info& b) { 95 | return b.format == format_descriptor::format() && b.itemsize == (ssize_t) sizeof(T); 96 | } 97 | }; 98 | 99 | template struct compare_buffer_info::value>> { 100 | static bool compare(const buffer_info& b) { 101 | return (size_t) b.itemsize == sizeof(T) && (b.format == format_descriptor::value || 102 | ((sizeof(T) == sizeof(long)) && b.format == (std::is_unsigned::value ? "L" : "l")) || 103 | ((sizeof(T) == sizeof(size_t)) && b.format == (std::is_unsigned::value ? "N" : "n"))); 104 | } 105 | }; 106 | 107 | NAMESPACE_END(detail) 108 | NAMESPACE_END(PYBIND11_NAMESPACE) 109 | -------------------------------------------------------------------------------- /pybind11/chrono.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/chrono.h: Transparent conversion between std::chrono and python's datetime 3 | 4 | Copyright (c) 2016 Trent Houliston and 5 | Wenzel Jakob 6 | 7 | All rights reserved. Use of this source code is governed by a 8 | BSD-style license that can be found in the LICENSE file. 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "pybind11.h" 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | // Backport the PyDateTime_DELTA functions from Python3.3 if required 20 | #ifndef PyDateTime_DELTA_GET_DAYS 21 | #define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days) 22 | #endif 23 | #ifndef PyDateTime_DELTA_GET_SECONDS 24 | #define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds) 25 | #endif 26 | #ifndef PyDateTime_DELTA_GET_MICROSECONDS 27 | #define PyDateTime_DELTA_GET_MICROSECONDS(o) (((PyDateTime_Delta*)o)->microseconds) 28 | #endif 29 | 30 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 31 | NAMESPACE_BEGIN(detail) 32 | 33 | template class duration_caster { 34 | public: 35 | typedef typename type::rep rep; 36 | typedef typename type::period period; 37 | 38 | typedef std::chrono::duration> days; 39 | 40 | bool load(handle src, bool) { 41 | using namespace std::chrono; 42 | 43 | // Lazy initialise the PyDateTime import 44 | if (!PyDateTimeAPI) { PyDateTime_IMPORT; } 45 | 46 | if (!src) return false; 47 | // If invoked with datetime.delta object 48 | if (PyDelta_Check(src.ptr())) { 49 | value = type(duration_cast>( 50 | days(PyDateTime_DELTA_GET_DAYS(src.ptr())) 51 | + seconds(PyDateTime_DELTA_GET_SECONDS(src.ptr())) 52 | + microseconds(PyDateTime_DELTA_GET_MICROSECONDS(src.ptr())))); 53 | return true; 54 | } 55 | // If invoked with a float we assume it is seconds and convert 56 | else if (PyFloat_Check(src.ptr())) { 57 | value = type(duration_cast>(duration(PyFloat_AsDouble(src.ptr())))); 58 | return true; 59 | } 60 | else return false; 61 | } 62 | 63 | // If this is a duration just return it back 64 | static const std::chrono::duration& get_duration(const std::chrono::duration &src) { 65 | return src; 66 | } 67 | 68 | // If this is a time_point get the time_since_epoch 69 | template static std::chrono::duration get_duration(const std::chrono::time_point> &src) { 70 | return src.time_since_epoch(); 71 | } 72 | 73 | static handle cast(const type &src, return_value_policy /* policy */, handle /* parent */) { 74 | using namespace std::chrono; 75 | 76 | // Use overloaded function to get our duration from our source 77 | // Works out if it is a duration or time_point and get the duration 78 | auto d = get_duration(src); 79 | 80 | // Lazy initialise the PyDateTime import 81 | if (!PyDateTimeAPI) { PyDateTime_IMPORT; } 82 | 83 | // Declare these special duration types so the conversions happen with the correct primitive types (int) 84 | using dd_t = duration>; 85 | using ss_t = duration>; 86 | using us_t = duration; 87 | 88 | auto dd = duration_cast(d); 89 | auto subd = d - dd; 90 | auto ss = duration_cast(subd); 91 | auto us = duration_cast(subd - ss); 92 | return PyDelta_FromDSU(dd.count(), ss.count(), us.count()); 93 | } 94 | 95 | PYBIND11_TYPE_CASTER(type, _("datetime.timedelta")); 96 | }; 97 | 98 | // This is for casting times on the system clock into datetime.datetime instances 99 | template class type_caster> { 100 | public: 101 | typedef std::chrono::time_point type; 102 | bool load(handle src, bool) { 103 | using namespace std::chrono; 104 | 105 | // Lazy initialise the PyDateTime import 106 | if (!PyDateTimeAPI) { PyDateTime_IMPORT; } 107 | 108 | if (!src) return false; 109 | if (PyDateTime_Check(src.ptr())) { 110 | std::tm cal; 111 | cal.tm_sec = PyDateTime_DATE_GET_SECOND(src.ptr()); 112 | cal.tm_min = PyDateTime_DATE_GET_MINUTE(src.ptr()); 113 | cal.tm_hour = PyDateTime_DATE_GET_HOUR(src.ptr()); 114 | cal.tm_mday = PyDateTime_GET_DAY(src.ptr()); 115 | cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1; 116 | cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900; 117 | cal.tm_isdst = -1; 118 | 119 | value = system_clock::from_time_t(std::mktime(&cal)) + microseconds(PyDateTime_DATE_GET_MICROSECOND(src.ptr())); 120 | return true; 121 | } 122 | else return false; 123 | } 124 | 125 | static handle cast(const std::chrono::time_point &src, return_value_policy /* policy */, handle /* parent */) { 126 | using namespace std::chrono; 127 | 128 | // Lazy initialise the PyDateTime import 129 | if (!PyDateTimeAPI) { PyDateTime_IMPORT; } 130 | 131 | std::time_t tt = system_clock::to_time_t(src); 132 | // this function uses static memory so it's best to copy it out asap just in case 133 | // otherwise other code that is using localtime may break this (not just python code) 134 | std::tm localtime = *std::localtime(&tt); 135 | 136 | // Declare these special duration types so the conversions happen with the correct primitive types (int) 137 | using us_t = duration; 138 | 139 | return PyDateTime_FromDateAndTime(localtime.tm_year + 1900, 140 | localtime.tm_mon + 1, 141 | localtime.tm_mday, 142 | localtime.tm_hour, 143 | localtime.tm_min, 144 | localtime.tm_sec, 145 | (duration_cast(src.time_since_epoch() % seconds(1))).count()); 146 | } 147 | PYBIND11_TYPE_CASTER(type, _("datetime.datetime")); 148 | }; 149 | 150 | // Other clocks that are not the system clock are not measured as datetime.datetime objects 151 | // since they are not measured on calendar time. So instead we just make them timedeltas 152 | // Or if they have passed us a time as a float we convert that 153 | template class type_caster> 154 | : public duration_caster> { 155 | }; 156 | 157 | template class type_caster> 158 | : public duration_caster> { 159 | }; 160 | 161 | NAMESPACE_END(detail) 162 | NAMESPACE_END(PYBIND11_NAMESPACE) 163 | -------------------------------------------------------------------------------- /pybind11/common.h: -------------------------------------------------------------------------------- 1 | #include "detail/common.h" 2 | #warning "Including 'common.h' is deprecated. It will be removed in v3.0. Use 'pybind11.h'." 3 | -------------------------------------------------------------------------------- /pybind11/complex.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/complex.h: Complex number support 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | #include 14 | 15 | /// glibc defines I as a macro which breaks things, e.g., boost template names 16 | #ifdef I 17 | # undef I 18 | #endif 19 | 20 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 21 | 22 | template struct format_descriptor, detail::enable_if_t::value>> { 23 | static constexpr const char c = format_descriptor::c; 24 | static constexpr const char value[3] = { 'Z', c, '\0' }; 25 | static std::string format() { return std::string(value); } 26 | }; 27 | 28 | #ifndef PYBIND11_CPP17 29 | 30 | template constexpr const char format_descriptor< 31 | std::complex, detail::enable_if_t::value>>::value[3]; 32 | 33 | #endif 34 | 35 | NAMESPACE_BEGIN(detail) 36 | 37 | template struct is_fmt_numeric, detail::enable_if_t::value>> { 38 | static constexpr bool value = true; 39 | static constexpr int index = is_fmt_numeric::index + 3; 40 | }; 41 | 42 | template class type_caster> { 43 | public: 44 | bool load(handle src, bool convert) { 45 | if (!src) 46 | return false; 47 | if (!convert && !PyComplex_Check(src.ptr())) 48 | return false; 49 | Py_complex result = PyComplex_AsCComplex(src.ptr()); 50 | if (result.real == -1.0 && PyErr_Occurred()) { 51 | PyErr_Clear(); 52 | return false; 53 | } 54 | value = std::complex((T) result.real, (T) result.imag); 55 | return true; 56 | } 57 | 58 | static handle cast(const std::complex &src, return_value_policy /* policy */, handle /* parent */) { 59 | return PyComplex_FromDoubles((double) src.real(), (double) src.imag()); 60 | } 61 | 62 | PYBIND11_TYPE_CASTER(std::complex, _("complex")); 63 | }; 64 | NAMESPACE_END(detail) 65 | NAMESPACE_END(PYBIND11_NAMESPACE) 66 | -------------------------------------------------------------------------------- /pybind11/detail/class.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/detail/class.h: Python C API implementation details for py::class_ 3 | 4 | Copyright (c) 2017 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "../attr.h" 13 | 14 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 15 | NAMESPACE_BEGIN(detail) 16 | 17 | #if PY_VERSION_HEX >= 0x03030000 18 | # define PYBIND11_BUILTIN_QUALNAME 19 | # define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj) 20 | #else 21 | // In pre-3.3 Python, we still set __qualname__ so that we can produce reliable function type 22 | // signatures; in 3.3+ this macro expands to nothing: 23 | # define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj) setattr((PyObject *) obj, "__qualname__", nameobj) 24 | #endif 25 | 26 | inline PyTypeObject *type_incref(PyTypeObject *type) { 27 | Py_INCREF(type); 28 | return type; 29 | } 30 | 31 | #if !defined(PYPY_VERSION) 32 | 33 | /// `pybind11_static_property.__get__()`: Always pass the class instead of the instance. 34 | extern "C" inline PyObject *pybind11_static_get(PyObject *self, PyObject * /*ob*/, PyObject *cls) { 35 | return PyProperty_Type.tp_descr_get(self, cls, cls); 36 | } 37 | 38 | /// `pybind11_static_property.__set__()`: Just like the above `__get__()`. 39 | extern "C" inline int pybind11_static_set(PyObject *self, PyObject *obj, PyObject *value) { 40 | PyObject *cls = PyType_Check(obj) ? obj : (PyObject *) Py_TYPE(obj); 41 | return PyProperty_Type.tp_descr_set(self, cls, value); 42 | } 43 | 44 | /** A `static_property` is the same as a `property` but the `__get__()` and `__set__()` 45 | methods are modified to always use the object type instead of a concrete instance. 46 | Return value: New reference. */ 47 | inline PyTypeObject *make_static_property_type() { 48 | constexpr auto *name = "pybind11_static_property"; 49 | auto name_obj = reinterpret_steal(PYBIND11_FROM_STRING(name)); 50 | 51 | /* Danger zone: from now (and until PyType_Ready), make sure to 52 | issue no Python C API calls which could potentially invoke the 53 | garbage collector (the GC will call type_traverse(), which will in 54 | turn find the newly constructed type in an invalid state) */ 55 | auto heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0); 56 | if (!heap_type) 57 | pybind11_fail("make_static_property_type(): error allocating type!"); 58 | 59 | heap_type->ht_name = name_obj.inc_ref().ptr(); 60 | #ifdef PYBIND11_BUILTIN_QUALNAME 61 | heap_type->ht_qualname = name_obj.inc_ref().ptr(); 62 | #endif 63 | 64 | auto type = &heap_type->ht_type; 65 | type->tp_name = name; 66 | type->tp_base = type_incref(&PyProperty_Type); 67 | type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; 68 | type->tp_descr_get = pybind11_static_get; 69 | type->tp_descr_set = pybind11_static_set; 70 | 71 | if (PyType_Ready(type) < 0) 72 | pybind11_fail("make_static_property_type(): failure in PyType_Ready()!"); 73 | 74 | setattr((PyObject *) type, "__module__", str("pybind11_builtins")); 75 | PYBIND11_SET_OLDPY_QUALNAME(type, name_obj); 76 | 77 | return type; 78 | } 79 | 80 | #else // PYPY 81 | 82 | /** PyPy has some issues with the above C API, so we evaluate Python code instead. 83 | This function will only be called once so performance isn't really a concern. 84 | Return value: New reference. */ 85 | inline PyTypeObject *make_static_property_type() { 86 | auto d = dict(); 87 | PyObject *result = PyRun_String(R"(\ 88 | class pybind11_static_property(property): 89 | def __get__(self, obj, cls): 90 | return property.__get__(self, cls, cls) 91 | 92 | def __set__(self, obj, value): 93 | cls = obj if isinstance(obj, type) else type(obj) 94 | property.__set__(self, cls, value) 95 | )", Py_file_input, d.ptr(), d.ptr() 96 | ); 97 | if (result == nullptr) 98 | throw error_already_set(); 99 | Py_DECREF(result); 100 | return (PyTypeObject *) d["pybind11_static_property"].cast().release().ptr(); 101 | } 102 | 103 | #endif // PYPY 104 | 105 | /** Types with static properties need to handle `Type.static_prop = x` in a specific way. 106 | By default, Python replaces the `static_property` itself, but for wrapped C++ types 107 | we need to call `static_property.__set__()` in order to propagate the new value to 108 | the underlying C++ data structure. */ 109 | extern "C" inline int pybind11_meta_setattro(PyObject* obj, PyObject* name, PyObject* value) { 110 | // Use `_PyType_Lookup()` instead of `PyObject_GetAttr()` in order to get the raw 111 | // descriptor (`property`) instead of calling `tp_descr_get` (`property.__get__()`). 112 | PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name); 113 | 114 | // The following assignment combinations are possible: 115 | // 1. `Type.static_prop = value` --> descr_set: `Type.static_prop.__set__(value)` 116 | // 2. `Type.static_prop = other_static_prop` --> setattro: replace existing `static_prop` 117 | // 3. `Type.regular_attribute = value` --> setattro: regular attribute assignment 118 | const auto static_prop = (PyObject *) get_internals().static_property_type; 119 | const auto call_descr_set = descr && PyObject_IsInstance(descr, static_prop) 120 | && !PyObject_IsInstance(value, static_prop); 121 | if (call_descr_set) { 122 | // Call `static_property.__set__()` instead of replacing the `static_property`. 123 | #if !defined(PYPY_VERSION) 124 | return Py_TYPE(descr)->tp_descr_set(descr, obj, value); 125 | #else 126 | if (PyObject *result = PyObject_CallMethod(descr, "__set__", "OO", obj, value)) { 127 | Py_DECREF(result); 128 | return 0; 129 | } else { 130 | return -1; 131 | } 132 | #endif 133 | } else { 134 | // Replace existing attribute. 135 | return PyType_Type.tp_setattro(obj, name, value); 136 | } 137 | } 138 | 139 | #if PY_MAJOR_VERSION >= 3 140 | /** 141 | * Python 3's PyInstanceMethod_Type hides itself via its tp_descr_get, which prevents aliasing 142 | * methods via cls.attr("m2") = cls.attr("m1"): instead the tp_descr_get returns a plain function, 143 | * when called on a class, or a PyMethod, when called on an instance. Override that behaviour here 144 | * to do a special case bypass for PyInstanceMethod_Types. 145 | */ 146 | extern "C" inline PyObject *pybind11_meta_getattro(PyObject *obj, PyObject *name) { 147 | PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name); 148 | if (descr && PyInstanceMethod_Check(descr)) { 149 | Py_INCREF(descr); 150 | return descr; 151 | } 152 | else { 153 | return PyType_Type.tp_getattro(obj, name); 154 | } 155 | } 156 | #endif 157 | 158 | /** This metaclass is assigned by default to all pybind11 types and is required in order 159 | for static properties to function correctly. Users may override this using `py::metaclass`. 160 | Return value: New reference. */ 161 | inline PyTypeObject* make_default_metaclass() { 162 | constexpr auto *name = "pybind11_type"; 163 | auto name_obj = reinterpret_steal(PYBIND11_FROM_STRING(name)); 164 | 165 | /* Danger zone: from now (and until PyType_Ready), make sure to 166 | issue no Python C API calls which could potentially invoke the 167 | garbage collector (the GC will call type_traverse(), which will in 168 | turn find the newly constructed type in an invalid state) */ 169 | auto heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0); 170 | if (!heap_type) 171 | pybind11_fail("make_default_metaclass(): error allocating metaclass!"); 172 | 173 | heap_type->ht_name = name_obj.inc_ref().ptr(); 174 | #ifdef PYBIND11_BUILTIN_QUALNAME 175 | heap_type->ht_qualname = name_obj.inc_ref().ptr(); 176 | #endif 177 | 178 | auto type = &heap_type->ht_type; 179 | type->tp_name = name; 180 | type->tp_base = type_incref(&PyType_Type); 181 | type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; 182 | 183 | type->tp_setattro = pybind11_meta_setattro; 184 | #if PY_MAJOR_VERSION >= 3 185 | type->tp_getattro = pybind11_meta_getattro; 186 | #endif 187 | 188 | if (PyType_Ready(type) < 0) 189 | pybind11_fail("make_default_metaclass(): failure in PyType_Ready()!"); 190 | 191 | setattr((PyObject *) type, "__module__", str("pybind11_builtins")); 192 | PYBIND11_SET_OLDPY_QUALNAME(type, name_obj); 193 | 194 | return type; 195 | } 196 | 197 | /// For multiple inheritance types we need to recursively register/deregister base pointers for any 198 | /// base classes with pointers that are difference from the instance value pointer so that we can 199 | /// correctly recognize an offset base class pointer. This calls a function with any offset base ptrs. 200 | inline void traverse_offset_bases(void *valueptr, const detail::type_info *tinfo, instance *self, 201 | bool (*f)(void * /*parentptr*/, instance * /*self*/)) { 202 | for (handle h : reinterpret_borrow(tinfo->type->tp_bases)) { 203 | if (auto parent_tinfo = get_type_info((PyTypeObject *) h.ptr())) { 204 | for (auto &c : parent_tinfo->implicit_casts) { 205 | if (c.first == tinfo->cpptype) { 206 | auto *parentptr = c.second(valueptr); 207 | if (parentptr != valueptr) 208 | f(parentptr, self); 209 | traverse_offset_bases(parentptr, parent_tinfo, self, f); 210 | break; 211 | } 212 | } 213 | } 214 | } 215 | } 216 | 217 | inline bool register_instance_impl(void *ptr, instance *self) { 218 | get_internals().registered_instances.emplace(ptr, self); 219 | return true; // unused, but gives the same signature as the deregister func 220 | } 221 | inline bool deregister_instance_impl(void *ptr, instance *self) { 222 | auto ®istered_instances = get_internals().registered_instances; 223 | auto range = registered_instances.equal_range(ptr); 224 | for (auto it = range.first; it != range.second; ++it) { 225 | if (Py_TYPE(self) == Py_TYPE(it->second)) { 226 | registered_instances.erase(it); 227 | return true; 228 | } 229 | } 230 | return false; 231 | } 232 | 233 | inline void register_instance(instance *self, void *valptr, const type_info *tinfo) { 234 | register_instance_impl(valptr, self); 235 | if (!tinfo->simple_ancestors) 236 | traverse_offset_bases(valptr, tinfo, self, register_instance_impl); 237 | } 238 | 239 | inline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo) { 240 | bool ret = deregister_instance_impl(valptr, self); 241 | if (!tinfo->simple_ancestors) 242 | traverse_offset_bases(valptr, tinfo, self, deregister_instance_impl); 243 | return ret; 244 | } 245 | 246 | /// Instance creation function for all pybind11 types. It allocates the internal instance layout for 247 | /// holding C++ objects and holders. Allocation is done lazily (the first time the instance is cast 248 | /// to a reference or pointer), and initialization is done by an `__init__` function. 249 | inline PyObject *make_new_instance(PyTypeObject *type) { 250 | #if defined(PYPY_VERSION) 251 | // PyPy gets tp_basicsize wrong (issue 2482) under multiple inheritance when the first inherited 252 | // object is a a plain Python type (i.e. not derived from an extension type). Fix it. 253 | ssize_t instance_size = static_cast(sizeof(instance)); 254 | if (type->tp_basicsize < instance_size) { 255 | type->tp_basicsize = instance_size; 256 | } 257 | #endif 258 | PyObject *self = type->tp_alloc(type, 0); 259 | auto inst = reinterpret_cast(self); 260 | // Allocate the value/holder internals: 261 | inst->allocate_layout(); 262 | 263 | inst->owned = true; 264 | 265 | return self; 266 | } 267 | 268 | /// Instance creation function for all pybind11 types. It only allocates space for the 269 | /// C++ object, but doesn't call the constructor -- an `__init__` function must do that. 270 | extern "C" inline PyObject *pybind11_object_new(PyTypeObject *type, PyObject *, PyObject *) { 271 | return make_new_instance(type); 272 | } 273 | 274 | /// An `__init__` function constructs the C++ object. Users should provide at least one 275 | /// of these using `py::init` or directly with `.def(__init__, ...)`. Otherwise, the 276 | /// following default function will be used which simply throws an exception. 277 | extern "C" inline int pybind11_object_init(PyObject *self, PyObject *, PyObject *) { 278 | PyTypeObject *type = Py_TYPE(self); 279 | std::string msg; 280 | #if defined(PYPY_VERSION) 281 | msg += handle((PyObject *) type).attr("__module__").cast() + "."; 282 | #endif 283 | msg += type->tp_name; 284 | msg += ": No constructor defined!"; 285 | PyErr_SetString(PyExc_TypeError, msg.c_str()); 286 | return -1; 287 | } 288 | 289 | inline void add_patient(PyObject *nurse, PyObject *patient) { 290 | auto &internals = get_internals(); 291 | auto instance = reinterpret_cast(nurse); 292 | instance->has_patients = true; 293 | Py_INCREF(patient); 294 | internals.patients[nurse].push_back(patient); 295 | } 296 | 297 | inline void clear_patients(PyObject *self) { 298 | auto instance = reinterpret_cast(self); 299 | auto &internals = get_internals(); 300 | auto pos = internals.patients.find(self); 301 | assert(pos != internals.patients.end()); 302 | // Clearing the patients can cause more Python code to run, which 303 | // can invalidate the iterator. Extract the vector of patients 304 | // from the unordered_map first. 305 | auto patients = std::move(pos->second); 306 | internals.patients.erase(pos); 307 | instance->has_patients = false; 308 | for (PyObject *&patient : patients) 309 | Py_CLEAR(patient); 310 | } 311 | 312 | /// Clears all internal data from the instance and removes it from registered instances in 313 | /// preparation for deallocation. 314 | inline void clear_instance(PyObject *self) { 315 | auto instance = reinterpret_cast(self); 316 | 317 | // Deallocate any values/holders, if present: 318 | for (auto &v_h : values_and_holders(instance)) { 319 | if (v_h) { 320 | 321 | // We have to deregister before we call dealloc because, for virtual MI types, we still 322 | // need to be able to get the parent pointers. 323 | if (v_h.instance_registered() && !deregister_instance(instance, v_h.value_ptr(), v_h.type)) 324 | pybind11_fail("pybind11_object_dealloc(): Tried to deallocate unregistered instance!"); 325 | 326 | if (instance->owned || v_h.holder_constructed()) 327 | v_h.type->dealloc(v_h); 328 | } 329 | } 330 | // Deallocate the value/holder layout internals: 331 | instance->deallocate_layout(); 332 | 333 | if (instance->weakrefs) 334 | PyObject_ClearWeakRefs(self); 335 | 336 | PyObject **dict_ptr = _PyObject_GetDictPtr(self); 337 | if (dict_ptr) 338 | Py_CLEAR(*dict_ptr); 339 | 340 | if (instance->has_patients) 341 | clear_patients(self); 342 | } 343 | 344 | /// Instance destructor function for all pybind11 types. It calls `type_info.dealloc` 345 | /// to destroy the C++ object itself, while the rest is Python bookkeeping. 346 | extern "C" inline void pybind11_object_dealloc(PyObject *self) { 347 | clear_instance(self); 348 | 349 | auto type = Py_TYPE(self); 350 | type->tp_free(self); 351 | 352 | // `type->tp_dealloc != pybind11_object_dealloc` means that we're being called 353 | // as part of a derived type's dealloc, in which case we're not allowed to decref 354 | // the type here. For cross-module compatibility, we shouldn't compare directly 355 | // with `pybind11_object_dealloc`, but with the common one stashed in internals. 356 | auto pybind11_object_type = (PyTypeObject *) get_internals().instance_base; 357 | if (type->tp_dealloc == pybind11_object_type->tp_dealloc) 358 | Py_DECREF(type); 359 | } 360 | 361 | /** Create the type which can be used as a common base for all classes. This is 362 | needed in order to satisfy Python's requirements for multiple inheritance. 363 | Return value: New reference. */ 364 | inline PyObject *make_object_base_type(PyTypeObject *metaclass) { 365 | constexpr auto *name = "pybind11_object"; 366 | auto name_obj = reinterpret_steal(PYBIND11_FROM_STRING(name)); 367 | 368 | /* Danger zone: from now (and until PyType_Ready), make sure to 369 | issue no Python C API calls which could potentially invoke the 370 | garbage collector (the GC will call type_traverse(), which will in 371 | turn find the newly constructed type in an invalid state) */ 372 | auto heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0); 373 | if (!heap_type) 374 | pybind11_fail("make_object_base_type(): error allocating type!"); 375 | 376 | heap_type->ht_name = name_obj.inc_ref().ptr(); 377 | #ifdef PYBIND11_BUILTIN_QUALNAME 378 | heap_type->ht_qualname = name_obj.inc_ref().ptr(); 379 | #endif 380 | 381 | auto type = &heap_type->ht_type; 382 | type->tp_name = name; 383 | type->tp_base = type_incref(&PyBaseObject_Type); 384 | type->tp_basicsize = static_cast(sizeof(instance)); 385 | type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; 386 | 387 | type->tp_new = pybind11_object_new; 388 | type->tp_init = pybind11_object_init; 389 | type->tp_dealloc = pybind11_object_dealloc; 390 | 391 | /* Support weak references (needed for the keep_alive feature) */ 392 | type->tp_weaklistoffset = offsetof(instance, weakrefs); 393 | 394 | if (PyType_Ready(type) < 0) 395 | pybind11_fail("PyType_Ready failed in make_object_base_type():" + error_string()); 396 | 397 | setattr((PyObject *) type, "__module__", str("pybind11_builtins")); 398 | PYBIND11_SET_OLDPY_QUALNAME(type, name_obj); 399 | 400 | assert(!PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC)); 401 | return (PyObject *) heap_type; 402 | } 403 | 404 | /// dynamic_attr: Support for `d = instance.__dict__`. 405 | extern "C" inline PyObject *pybind11_get_dict(PyObject *self, void *) { 406 | PyObject *&dict = *_PyObject_GetDictPtr(self); 407 | if (!dict) 408 | dict = PyDict_New(); 409 | Py_XINCREF(dict); 410 | return dict; 411 | } 412 | 413 | /// dynamic_attr: Support for `instance.__dict__ = dict()`. 414 | extern "C" inline int pybind11_set_dict(PyObject *self, PyObject *new_dict, void *) { 415 | if (!PyDict_Check(new_dict)) { 416 | PyErr_Format(PyExc_TypeError, "__dict__ must be set to a dictionary, not a '%.200s'", 417 | Py_TYPE(new_dict)->tp_name); 418 | return -1; 419 | } 420 | PyObject *&dict = *_PyObject_GetDictPtr(self); 421 | Py_INCREF(new_dict); 422 | Py_CLEAR(dict); 423 | dict = new_dict; 424 | return 0; 425 | } 426 | 427 | /// dynamic_attr: Allow the garbage collector to traverse the internal instance `__dict__`. 428 | extern "C" inline int pybind11_traverse(PyObject *self, visitproc visit, void *arg) { 429 | PyObject *&dict = *_PyObject_GetDictPtr(self); 430 | Py_VISIT(dict); 431 | return 0; 432 | } 433 | 434 | /// dynamic_attr: Allow the GC to clear the dictionary. 435 | extern "C" inline int pybind11_clear(PyObject *self) { 436 | PyObject *&dict = *_PyObject_GetDictPtr(self); 437 | Py_CLEAR(dict); 438 | return 0; 439 | } 440 | 441 | /// Give instances of this type a `__dict__` and opt into garbage collection. 442 | inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) { 443 | auto type = &heap_type->ht_type; 444 | #if defined(PYPY_VERSION) 445 | pybind11_fail(std::string(type->tp_name) + ": dynamic attributes are " 446 | "currently not supported in " 447 | "conjunction with PyPy!"); 448 | #endif 449 | type->tp_flags |= Py_TPFLAGS_HAVE_GC; 450 | type->tp_dictoffset = type->tp_basicsize; // place dict at the end 451 | type->tp_basicsize += (ssize_t)sizeof(PyObject *); // and allocate enough space for it 452 | type->tp_traverse = pybind11_traverse; 453 | type->tp_clear = pybind11_clear; 454 | 455 | static PyGetSetDef getset[] = { 456 | {const_cast("__dict__"), pybind11_get_dict, pybind11_set_dict, nullptr, nullptr}, 457 | {nullptr, nullptr, nullptr, nullptr, nullptr} 458 | }; 459 | type->tp_getset = getset; 460 | } 461 | 462 | /// buffer_protocol: Fill in the view as specified by flags. 463 | extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int flags) { 464 | // Look for a `get_buffer` implementation in this type's info or any bases (following MRO). 465 | type_info *tinfo = nullptr; 466 | for (auto type : reinterpret_borrow(Py_TYPE(obj)->tp_mro)) { 467 | tinfo = get_type_info((PyTypeObject *) type.ptr()); 468 | if (tinfo && tinfo->get_buffer) 469 | break; 470 | } 471 | if (view == nullptr || obj == nullptr || !tinfo || !tinfo->get_buffer) { 472 | if (view) 473 | view->obj = nullptr; 474 | PyErr_SetString(PyExc_BufferError, "pybind11_getbuffer(): Internal error"); 475 | return -1; 476 | } 477 | std::memset(view, 0, sizeof(Py_buffer)); 478 | buffer_info *info = tinfo->get_buffer(obj, tinfo->get_buffer_data); 479 | view->obj = obj; 480 | view->ndim = 1; 481 | view->internal = info; 482 | view->buf = info->ptr; 483 | view->itemsize = info->itemsize; 484 | view->len = view->itemsize; 485 | for (auto s : info->shape) 486 | view->len *= s; 487 | if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) 488 | view->format = const_cast(info->format.c_str()); 489 | if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) { 490 | view->ndim = (int) info->ndim; 491 | view->strides = &info->strides[0]; 492 | view->shape = &info->shape[0]; 493 | } 494 | Py_INCREF(view->obj); 495 | return 0; 496 | } 497 | 498 | /// buffer_protocol: Release the resources of the buffer. 499 | extern "C" inline void pybind11_releasebuffer(PyObject *, Py_buffer *view) { 500 | delete (buffer_info *) view->internal; 501 | } 502 | 503 | /// Give this type a buffer interface. 504 | inline void enable_buffer_protocol(PyHeapTypeObject *heap_type) { 505 | heap_type->ht_type.tp_as_buffer = &heap_type->as_buffer; 506 | #if PY_MAJOR_VERSION < 3 507 | heap_type->ht_type.tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER; 508 | #endif 509 | 510 | heap_type->as_buffer.bf_getbuffer = pybind11_getbuffer; 511 | heap_type->as_buffer.bf_releasebuffer = pybind11_releasebuffer; 512 | } 513 | 514 | /** Create a brand new Python type according to the `type_record` specification. 515 | Return value: New reference. */ 516 | inline PyObject* make_new_python_type(const type_record &rec) { 517 | auto name = reinterpret_steal(PYBIND11_FROM_STRING(rec.name)); 518 | 519 | auto qualname = name; 520 | if (rec.scope && !PyModule_Check(rec.scope.ptr()) && hasattr(rec.scope, "__qualname__")) { 521 | #if PY_MAJOR_VERSION >= 3 522 | qualname = reinterpret_steal( 523 | PyUnicode_FromFormat("%U.%U", rec.scope.attr("__qualname__").ptr(), name.ptr())); 524 | #else 525 | qualname = str(rec.scope.attr("__qualname__").cast() + "." + rec.name); 526 | #endif 527 | } 528 | 529 | object module; 530 | if (rec.scope) { 531 | if (hasattr(rec.scope, "__module__")) 532 | module = rec.scope.attr("__module__"); 533 | else if (hasattr(rec.scope, "__name__")) 534 | module = rec.scope.attr("__name__"); 535 | } 536 | 537 | auto full_name = c_str( 538 | #if !defined(PYPY_VERSION) 539 | module ? str(module).cast() + "." + rec.name : 540 | #endif 541 | rec.name); 542 | 543 | char *tp_doc = nullptr; 544 | if (rec.doc && options::show_user_defined_docstrings()) { 545 | /* Allocate memory for docstring (using PyObject_MALLOC, since 546 | Python will free this later on) */ 547 | size_t size = strlen(rec.doc) + 1; 548 | tp_doc = (char *) PyObject_MALLOC(size); 549 | memcpy((void *) tp_doc, rec.doc, size); 550 | } 551 | 552 | auto &internals = get_internals(); 553 | auto bases = tuple(rec.bases); 554 | auto base = (bases.size() == 0) ? internals.instance_base 555 | : bases[0].ptr(); 556 | 557 | /* Danger zone: from now (and until PyType_Ready), make sure to 558 | issue no Python C API calls which could potentially invoke the 559 | garbage collector (the GC will call type_traverse(), which will in 560 | turn find the newly constructed type in an invalid state) */ 561 | auto metaclass = rec.metaclass.ptr() ? (PyTypeObject *) rec.metaclass.ptr() 562 | : internals.default_metaclass; 563 | 564 | auto heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0); 565 | if (!heap_type) 566 | pybind11_fail(std::string(rec.name) + ": Unable to create type object!"); 567 | 568 | heap_type->ht_name = name.release().ptr(); 569 | #ifdef PYBIND11_BUILTIN_QUALNAME 570 | heap_type->ht_qualname = qualname.inc_ref().ptr(); 571 | #endif 572 | 573 | auto type = &heap_type->ht_type; 574 | type->tp_name = full_name; 575 | type->tp_doc = tp_doc; 576 | type->tp_base = type_incref((PyTypeObject *)base); 577 | type->tp_basicsize = static_cast(sizeof(instance)); 578 | if (bases.size() > 0) 579 | type->tp_bases = bases.release().ptr(); 580 | 581 | /* Don't inherit base __init__ */ 582 | type->tp_init = pybind11_object_init; 583 | 584 | /* Supported protocols */ 585 | type->tp_as_number = &heap_type->as_number; 586 | type->tp_as_sequence = &heap_type->as_sequence; 587 | type->tp_as_mapping = &heap_type->as_mapping; 588 | 589 | /* Flags */ 590 | type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; 591 | #if PY_MAJOR_VERSION < 3 592 | type->tp_flags |= Py_TPFLAGS_CHECKTYPES; 593 | #endif 594 | 595 | if (rec.dynamic_attr) 596 | enable_dynamic_attributes(heap_type); 597 | 598 | if (rec.buffer_protocol) 599 | enable_buffer_protocol(heap_type); 600 | 601 | if (PyType_Ready(type) < 0) 602 | pybind11_fail(std::string(rec.name) + ": PyType_Ready failed (" + error_string() + ")!"); 603 | 604 | assert(rec.dynamic_attr ? PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC) 605 | : !PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC)); 606 | 607 | /* Register type with the parent scope */ 608 | if (rec.scope) 609 | setattr(rec.scope, rec.name, (PyObject *) type); 610 | else 611 | Py_INCREF(type); // Keep it alive forever (reference leak) 612 | 613 | if (module) // Needed by pydoc 614 | setattr((PyObject *) type, "__module__", module); 615 | 616 | PYBIND11_SET_OLDPY_QUALNAME(type, qualname); 617 | 618 | return (PyObject *) type; 619 | } 620 | 621 | NAMESPACE_END(detail) 622 | NAMESPACE_END(PYBIND11_NAMESPACE) 623 | -------------------------------------------------------------------------------- /pybind11/detail/descr.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/detail/descr.h: Helper type for concatenating type signatures at compile time 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "common.h" 13 | 14 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 15 | NAMESPACE_BEGIN(detail) 16 | 17 | #if !defined(_MSC_VER) 18 | # define PYBIND11_DESCR_CONSTEXPR static constexpr 19 | #else 20 | # define PYBIND11_DESCR_CONSTEXPR const 21 | #endif 22 | 23 | /* Concatenate type signatures at compile time */ 24 | template 25 | struct descr { 26 | char text[N + 1]; 27 | 28 | constexpr descr() : text{'\0'} { } 29 | constexpr descr(char const (&s)[N+1]) : descr(s, make_index_sequence()) { } 30 | 31 | template 32 | constexpr descr(char const (&s)[N+1], index_sequence) : text{s[Is]..., '\0'} { } 33 | 34 | template 35 | constexpr descr(char c, Chars... cs) : text{c, static_cast(cs)..., '\0'} { } 36 | 37 | static constexpr std::array types() { 38 | return {{&typeid(Ts)..., nullptr}}; 39 | } 40 | }; 41 | 42 | template 43 | constexpr descr plus_impl(const descr &a, const descr &b, 44 | index_sequence, index_sequence) { 45 | return {a.text[Is1]..., b.text[Is2]...}; 46 | } 47 | 48 | template 49 | constexpr descr operator+(const descr &a, const descr &b) { 50 | return plus_impl(a, b, make_index_sequence(), make_index_sequence()); 51 | } 52 | 53 | template 54 | constexpr descr _(char const(&text)[N]) { return descr(text); } 55 | constexpr descr<0> _(char const(&)[1]) { return {}; } 56 | 57 | template struct int_to_str : int_to_str { }; 58 | template struct int_to_str<0, Digits...> { 59 | static constexpr auto digits = descr(('0' + Digits)...); 60 | }; 61 | 62 | // Ternary description (like std::conditional) 63 | template 64 | constexpr enable_if_t> _(char const(&text1)[N1], char const(&)[N2]) { 65 | return _(text1); 66 | } 67 | template 68 | constexpr enable_if_t> _(char const(&)[N1], char const(&text2)[N2]) { 69 | return _(text2); 70 | } 71 | 72 | template 73 | constexpr enable_if_t _(const T1 &d, const T2 &) { return d; } 74 | template 75 | constexpr enable_if_t _(const T1 &, const T2 &d) { return d; } 76 | 77 | template auto constexpr _() -> decltype(int_to_str::digits) { 78 | return int_to_str::digits; 79 | } 80 | 81 | template constexpr descr<1, Type> _() { return {'%'}; } 82 | 83 | constexpr descr<0> concat() { return {}; } 84 | 85 | template 86 | constexpr descr concat(const descr &descr) { return descr; } 87 | 88 | template 89 | constexpr auto concat(const descr &d, const Args &...args) 90 | -> decltype(std::declval>() + concat(args...)) { 91 | return d + _(", ") + concat(args...); 92 | } 93 | 94 | template 95 | constexpr descr type_descr(const descr &descr) { 96 | return _("{") + descr + _("}"); 97 | } 98 | 99 | NAMESPACE_END(detail) 100 | NAMESPACE_END(PYBIND11_NAMESPACE) 101 | -------------------------------------------------------------------------------- /pybind11/detail/init.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/detail/init.h: init factory function implementation and support code. 3 | 4 | Copyright (c) 2017 Jason Rhinelander 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "class.h" 13 | 14 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 15 | NAMESPACE_BEGIN(detail) 16 | 17 | template <> 18 | class type_caster { 19 | public: 20 | bool load(handle h, bool) { 21 | value = reinterpret_cast(h.ptr()); 22 | return true; 23 | } 24 | 25 | template using cast_op_type = value_and_holder &; 26 | operator value_and_holder &() { return *value; } 27 | static constexpr auto name = _(); 28 | 29 | private: 30 | value_and_holder *value = nullptr; 31 | }; 32 | 33 | NAMESPACE_BEGIN(initimpl) 34 | 35 | inline void no_nullptr(void *ptr) { 36 | if (!ptr) throw type_error("pybind11::init(): factory function returned nullptr"); 37 | } 38 | 39 | // Implementing functions for all forms of py::init<...> and py::init(...) 40 | template using Cpp = typename Class::type; 41 | template using Alias = typename Class::type_alias; 42 | template using Holder = typename Class::holder_type; 43 | 44 | template using is_alias_constructible = std::is_constructible, Cpp &&>; 45 | 46 | // Takes a Cpp pointer and returns true if it actually is a polymorphic Alias instance. 47 | template = 0> 48 | bool is_alias(Cpp *ptr) { 49 | return dynamic_cast *>(ptr) != nullptr; 50 | } 51 | // Failing fallback version of the above for a no-alias class (always returns false) 52 | template 53 | constexpr bool is_alias(void *) { return false; } 54 | 55 | // Constructs and returns a new object; if the given arguments don't map to a constructor, we fall 56 | // back to brace aggregate initiailization so that for aggregate initialization can be used with 57 | // py::init, e.g. `py::init` to initialize a `struct T { int a; int b; }`. For 58 | // non-aggregate types, we need to use an ordinary T(...) constructor (invoking as `T{...}` usually 59 | // works, but will not do the expected thing when `T` has an `initializer_list` constructor). 60 | template ::value, int> = 0> 61 | inline Class *construct_or_initialize(Args &&...args) { return new Class(std::forward(args)...); } 62 | template ::value, int> = 0> 63 | inline Class *construct_or_initialize(Args &&...args) { return new Class{std::forward(args)...}; } 64 | 65 | // Attempts to constructs an alias using a `Alias(Cpp &&)` constructor. This allows types with 66 | // an alias to provide only a single Cpp factory function as long as the Alias can be 67 | // constructed from an rvalue reference of the base Cpp type. This means that Alias classes 68 | // can, when appropriate, simply define a `Alias(Cpp &&)` constructor rather than needing to 69 | // inherit all the base class constructors. 70 | template 71 | void construct_alias_from_cpp(std::true_type /*is_alias_constructible*/, 72 | value_and_holder &v_h, Cpp &&base) { 73 | v_h.value_ptr() = new Alias(std::move(base)); 74 | } 75 | template 76 | [[noreturn]] void construct_alias_from_cpp(std::false_type /*!is_alias_constructible*/, 77 | value_and_holder &, Cpp &&) { 78 | throw type_error("pybind11::init(): unable to convert returned instance to required " 79 | "alias class: no `Alias(Class &&)` constructor available"); 80 | } 81 | 82 | // Error-generating fallback for factories that don't match one of the below construction 83 | // mechanisms. 84 | template 85 | void construct(...) { 86 | static_assert(!std::is_same::value /* always false */, 87 | "pybind11::init(): init function must return a compatible pointer, " 88 | "holder, or value"); 89 | } 90 | 91 | // Pointer return v1: the factory function returns a class pointer for a registered class. 92 | // If we don't need an alias (because this class doesn't have one, or because the final type is 93 | // inherited on the Python side) we can simply take over ownership. Otherwise we need to try to 94 | // construct an Alias from the returned base instance. 95 | template 96 | void construct(value_and_holder &v_h, Cpp *ptr, bool need_alias) { 97 | no_nullptr(ptr); 98 | if (Class::has_alias && need_alias && !is_alias(ptr)) { 99 | // We're going to try to construct an alias by moving the cpp type. Whether or not 100 | // that succeeds, we still need to destroy the original cpp pointer (either the 101 | // moved away leftover, if the alias construction works, or the value itself if we 102 | // throw an error), but we can't just call `delete ptr`: it might have a special 103 | // deleter, or might be shared_from_this. So we construct a holder around it as if 104 | // it was a normal instance, then steal the holder away into a local variable; thus 105 | // the holder and destruction happens when we leave the C++ scope, and the holder 106 | // class gets to handle the destruction however it likes. 107 | v_h.value_ptr() = ptr; 108 | v_h.set_instance_registered(true); // To prevent init_instance from registering it 109 | v_h.type->init_instance(v_h.inst, nullptr); // Set up the holder 110 | Holder temp_holder(std::move(v_h.holder>())); // Steal the holder 111 | v_h.type->dealloc(v_h); // Destroys the moved-out holder remains, resets value ptr to null 112 | v_h.set_instance_registered(false); 113 | 114 | construct_alias_from_cpp(is_alias_constructible{}, v_h, std::move(*ptr)); 115 | } else { 116 | // Otherwise the type isn't inherited, so we don't need an Alias 117 | v_h.value_ptr() = ptr; 118 | } 119 | } 120 | 121 | // Pointer return v2: a factory that always returns an alias instance ptr. We simply take over 122 | // ownership of the pointer. 123 | template = 0> 124 | void construct(value_and_holder &v_h, Alias *alias_ptr, bool) { 125 | no_nullptr(alias_ptr); 126 | v_h.value_ptr() = static_cast *>(alias_ptr); 127 | } 128 | 129 | // Holder return: copy its pointer, and move or copy the returned holder into the new instance's 130 | // holder. This also handles types like std::shared_ptr and std::unique_ptr where T is a 131 | // derived type (through those holder's implicit conversion from derived class holder constructors). 132 | template 133 | void construct(value_and_holder &v_h, Holder holder, bool need_alias) { 134 | auto *ptr = holder_helper>::get(holder); 135 | // If we need an alias, check that the held pointer is actually an alias instance 136 | if (Class::has_alias && need_alias && !is_alias(ptr)) 137 | throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance " 138 | "is not an alias instance"); 139 | 140 | v_h.value_ptr() = ptr; 141 | v_h.type->init_instance(v_h.inst, &holder); 142 | } 143 | 144 | // return-by-value version 1: returning a cpp class by value. If the class has an alias and an 145 | // alias is required the alias must have an `Alias(Cpp &&)` constructor so that we can construct 146 | // the alias from the base when needed (i.e. because of Python-side inheritance). When we don't 147 | // need it, we simply move-construct the cpp value into a new instance. 148 | template 149 | void construct(value_and_holder &v_h, Cpp &&result, bool need_alias) { 150 | static_assert(std::is_move_constructible>::value, 151 | "pybind11::init() return-by-value factory function requires a movable class"); 152 | if (Class::has_alias && need_alias) 153 | construct_alias_from_cpp(is_alias_constructible{}, v_h, std::move(result)); 154 | else 155 | v_h.value_ptr() = new Cpp(std::move(result)); 156 | } 157 | 158 | // return-by-value version 2: returning a value of the alias type itself. We move-construct an 159 | // Alias instance (even if no the python-side inheritance is involved). The is intended for 160 | // cases where Alias initialization is always desired. 161 | template 162 | void construct(value_and_holder &v_h, Alias &&result, bool) { 163 | static_assert(std::is_move_constructible>::value, 164 | "pybind11::init() return-by-alias-value factory function requires a movable alias class"); 165 | v_h.value_ptr() = new Alias(std::move(result)); 166 | } 167 | 168 | // Implementing class for py::init<...>() 169 | template 170 | struct constructor { 171 | template = 0> 172 | static void execute(Class &cl, const Extra&... extra) { 173 | cl.def("__init__", [](value_and_holder &v_h, Args... args) { 174 | v_h.value_ptr() = construct_or_initialize>(std::forward(args)...); 175 | }, is_new_style_constructor(), extra...); 176 | } 177 | 178 | template , Args...>::value, int> = 0> 181 | static void execute(Class &cl, const Extra&... extra) { 182 | cl.def("__init__", [](value_and_holder &v_h, Args... args) { 183 | if (Py_TYPE(v_h.inst) == v_h.type->type) 184 | v_h.value_ptr() = construct_or_initialize>(std::forward(args)...); 185 | else 186 | v_h.value_ptr() = construct_or_initialize>(std::forward(args)...); 187 | }, is_new_style_constructor(), extra...); 188 | } 189 | 190 | template , Args...>::value, int> = 0> 193 | static void execute(Class &cl, const Extra&... extra) { 194 | cl.def("__init__", [](value_and_holder &v_h, Args... args) { 195 | v_h.value_ptr() = construct_or_initialize>(std::forward(args)...); 196 | }, is_new_style_constructor(), extra...); 197 | } 198 | }; 199 | 200 | // Implementing class for py::init_alias<...>() 201 | template struct alias_constructor { 202 | template , Args...>::value, int> = 0> 204 | static void execute(Class &cl, const Extra&... extra) { 205 | cl.def("__init__", [](value_and_holder &v_h, Args... args) { 206 | v_h.value_ptr() = construct_or_initialize>(std::forward(args)...); 207 | }, is_new_style_constructor(), extra...); 208 | } 209 | }; 210 | 211 | // Implementation class for py::init(Func) and py::init(Func, AliasFunc) 212 | template , typename = function_signature_t> 214 | struct factory; 215 | 216 | // Specialization for py::init(Func) 217 | template 218 | struct factory { 219 | remove_reference_t class_factory; 220 | 221 | factory(Func &&f) : class_factory(std::forward(f)) { } 222 | 223 | // The given class either has no alias or has no separate alias factory; 224 | // this always constructs the class itself. If the class is registered with an alias 225 | // type and an alias instance is needed (i.e. because the final type is a Python class 226 | // inheriting from the C++ type) the returned value needs to either already be an alias 227 | // instance, or the alias needs to be constructible from a `Class &&` argument. 228 | template 229 | void execute(Class &cl, const Extra &...extra) && { 230 | #if defined(PYBIND11_CPP14) 231 | cl.def("__init__", [func = std::move(class_factory)] 232 | #else 233 | auto &func = class_factory; 234 | cl.def("__init__", [func] 235 | #endif 236 | (value_and_holder &v_h, Args... args) { 237 | construct(v_h, func(std::forward(args)...), 238 | Py_TYPE(v_h.inst) != v_h.type->type); 239 | }, is_new_style_constructor(), extra...); 240 | } 241 | }; 242 | 243 | // Specialization for py::init(Func, AliasFunc) 244 | template 246 | struct factory { 247 | static_assert(sizeof...(CArgs) == sizeof...(AArgs), 248 | "pybind11::init(class_factory, alias_factory): class and alias factories " 249 | "must have identical argument signatures"); 250 | static_assert(all_of...>::value, 251 | "pybind11::init(class_factory, alias_factory): class and alias factories " 252 | "must have identical argument signatures"); 253 | 254 | remove_reference_t class_factory; 255 | remove_reference_t alias_factory; 256 | 257 | factory(CFunc &&c, AFunc &&a) 258 | : class_factory(std::forward(c)), alias_factory(std::forward(a)) { } 259 | 260 | // The class factory is called when the `self` type passed to `__init__` is the direct 261 | // class (i.e. not inherited), the alias factory when `self` is a Python-side subtype. 262 | template 263 | void execute(Class &cl, const Extra&... extra) && { 264 | static_assert(Class::has_alias, "The two-argument version of `py::init()` can " 265 | "only be used if the class has an alias"); 266 | #if defined(PYBIND11_CPP14) 267 | cl.def("__init__", [class_func = std::move(class_factory), alias_func = std::move(alias_factory)] 268 | #else 269 | auto &class_func = class_factory; 270 | auto &alias_func = alias_factory; 271 | cl.def("__init__", [class_func, alias_func] 272 | #endif 273 | (value_and_holder &v_h, CArgs... args) { 274 | if (Py_TYPE(v_h.inst) == v_h.type->type) 275 | // If the instance type equals the registered type we don't have inheritance, so 276 | // don't need the alias and can construct using the class function: 277 | construct(v_h, class_func(std::forward(args)...), false); 278 | else 279 | construct(v_h, alias_func(std::forward(args)...), true); 280 | }, is_new_style_constructor(), extra...); 281 | } 282 | }; 283 | 284 | /// Set just the C++ state. Same as `__init__`. 285 | template 286 | void setstate(value_and_holder &v_h, T &&result, bool need_alias) { 287 | construct(v_h, std::forward(result), need_alias); 288 | } 289 | 290 | /// Set both the C++ and Python states 291 | template ::value, int> = 0> 293 | void setstate(value_and_holder &v_h, std::pair &&result, bool need_alias) { 294 | construct(v_h, std::move(result.first), need_alias); 295 | setattr((PyObject *) v_h.inst, "__dict__", result.second); 296 | } 297 | 298 | /// Implementation for py::pickle(GetState, SetState) 299 | template , typename = function_signature_t> 301 | struct pickle_factory; 302 | 303 | template 305 | struct pickle_factory { 306 | static_assert(std::is_same, intrinsic_t>::value, 307 | "The type returned by `__getstate__` must be the same " 308 | "as the argument accepted by `__setstate__`"); 309 | 310 | remove_reference_t get; 311 | remove_reference_t set; 312 | 313 | pickle_factory(Get get, Set set) 314 | : get(std::forward(get)), set(std::forward(set)) { } 315 | 316 | template 317 | void execute(Class &cl, const Extra &...extra) && { 318 | cl.def("__getstate__", std::move(get)); 319 | 320 | #if defined(PYBIND11_CPP14) 321 | cl.def("__setstate__", [func = std::move(set)] 322 | #else 323 | auto &func = set; 324 | cl.def("__setstate__", [func] 325 | #endif 326 | (value_and_holder &v_h, ArgState state) { 327 | setstate(v_h, func(std::forward(state)), 328 | Py_TYPE(v_h.inst) != v_h.type->type); 329 | }, is_new_style_constructor(), extra...); 330 | } 331 | }; 332 | 333 | NAMESPACE_END(initimpl) 334 | NAMESPACE_END(detail) 335 | NAMESPACE_END(pybind11) 336 | -------------------------------------------------------------------------------- /pybind11/detail/internals.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/detail/internals.h: Internal data structure and related functions 3 | 4 | Copyright (c) 2017 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "../pytypes.h" 13 | 14 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 15 | NAMESPACE_BEGIN(detail) 16 | // Forward declarations 17 | inline PyTypeObject *make_static_property_type(); 18 | inline PyTypeObject *make_default_metaclass(); 19 | inline PyObject *make_object_base_type(PyTypeObject *metaclass); 20 | 21 | // Python loads modules by default with dlopen with the RTLD_LOCAL flag; under libc++ and possibly 22 | // other STLs, this means `typeid(A)` from one module won't equal `typeid(A)` from another module 23 | // even when `A` is the same, non-hidden-visibility type (e.g. from a common include). Under 24 | // libstdc++, this doesn't happen: equality and the type_index hash are based on the type name, 25 | // which works. If not under a known-good stl, provide our own name-based hash and equality 26 | // functions that use the type name. 27 | #if defined(__GLIBCXX__) 28 | inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; } 29 | using type_hash = std::hash; 30 | using type_equal_to = std::equal_to; 31 | #else 32 | inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { 33 | return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0; 34 | } 35 | 36 | struct type_hash { 37 | size_t operator()(const std::type_index &t) const { 38 | size_t hash = 5381; 39 | const char *ptr = t.name(); 40 | while (auto c = static_cast(*ptr++)) 41 | hash = (hash * 33) ^ c; 42 | return hash; 43 | } 44 | }; 45 | 46 | struct type_equal_to { 47 | bool operator()(const std::type_index &lhs, const std::type_index &rhs) const { 48 | return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0; 49 | } 50 | }; 51 | #endif 52 | 53 | template 54 | using type_map = std::unordered_map; 55 | 56 | struct overload_hash { 57 | inline size_t operator()(const std::pair& v) const { 58 | size_t value = std::hash()(v.first); 59 | value ^= std::hash()(v.second) + 0x9e3779b9 + (value<<6) + (value>>2); 60 | return value; 61 | } 62 | }; 63 | 64 | /// Internal data structure used to track registered instances and types. 65 | /// Whenever binary incompatible changes are made to this structure, 66 | /// `PYBIND11_INTERNALS_VERSION` must be incremented. 67 | struct internals { 68 | type_map registered_types_cpp; // std::type_index -> pybind11's type information 69 | std::unordered_map> registered_types_py; // PyTypeObject* -> base type_info(s) 70 | std::unordered_multimap registered_instances; // void * -> instance* 71 | std::unordered_set, overload_hash> inactive_overload_cache; 72 | type_map> direct_conversions; 73 | std::unordered_map> patients; 74 | std::forward_list registered_exception_translators; 75 | std::unordered_map shared_data; // Custom data to be shared across extensions 76 | std::vector loader_patient_stack; // Used by `loader_life_support` 77 | std::forward_list static_strings; // Stores the std::strings backing detail::c_str() 78 | PyTypeObject *static_property_type; 79 | PyTypeObject *default_metaclass; 80 | PyObject *instance_base; 81 | #if defined(WITH_THREAD) 82 | decltype(PyThread_create_key()) tstate = 0; // Usually an int but a long on Cygwin64 with Python 3.x 83 | PyInterpreterState *istate = nullptr; 84 | #endif 85 | }; 86 | 87 | /// Additional type information which does not fit into the PyTypeObject. 88 | /// Changes to this struct also require bumping `PYBIND11_INTERNALS_VERSION`. 89 | struct type_info { 90 | PyTypeObject *type; 91 | const std::type_info *cpptype; 92 | size_t type_size, holder_size_in_ptrs; 93 | void *(*operator_new)(size_t); 94 | void (*init_instance)(instance *, const void *); 95 | void (*dealloc)(value_and_holder &v_h); 96 | std::vector implicit_conversions; 97 | std::vector> implicit_casts; 98 | std::vector *direct_conversions; 99 | buffer_info *(*get_buffer)(PyObject *, void *) = nullptr; 100 | void *get_buffer_data = nullptr; 101 | void *(*module_local_load)(PyObject *, const type_info *) = nullptr; 102 | /* A simple type never occurs as a (direct or indirect) parent 103 | * of a class that makes use of multiple inheritance */ 104 | bool simple_type : 1; 105 | /* True if there is no multiple inheritance in this type's inheritance tree */ 106 | bool simple_ancestors : 1; 107 | /* for base vs derived holder_type checks */ 108 | bool default_holder : 1; 109 | /* true if this is a type registered with py::module_local */ 110 | bool module_local : 1; 111 | }; 112 | 113 | /// Tracks the `internals` and `type_info` ABI version independent of the main library version 114 | #define PYBIND11_INTERNALS_VERSION 1 115 | 116 | #if defined(WITH_THREAD) 117 | # define PYBIND11_INTERNALS_KIND "" 118 | #else 119 | # define PYBIND11_INTERNALS_KIND "_without_thread" 120 | #endif 121 | 122 | #define PYBIND11_INTERNALS_ID "__pybind11_internals_v" \ 123 | PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) PYBIND11_INTERNALS_KIND "__" 124 | 125 | #define PYBIND11_MODULE_LOCAL_ID "__pybind11_module_local_v" \ 126 | PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) PYBIND11_INTERNALS_KIND "__" 127 | 128 | /// Each module locally stores a pointer to the `internals` data. The data 129 | /// itself is shared among modules with the same `PYBIND11_INTERNALS_ID`. 130 | inline internals **&get_internals_pp() { 131 | static internals **internals_pp = nullptr; 132 | return internals_pp; 133 | } 134 | 135 | /// Return a reference to the current `internals` data 136 | PYBIND11_NOINLINE inline internals &get_internals() { 137 | auto **&internals_pp = get_internals_pp(); 138 | if (internals_pp && *internals_pp) 139 | return **internals_pp; 140 | 141 | constexpr auto *id = PYBIND11_INTERNALS_ID; 142 | auto builtins = handle(PyEval_GetBuiltins()); 143 | if (builtins.contains(id) && isinstance(builtins[id])) { 144 | internals_pp = static_cast(capsule(builtins[id])); 145 | 146 | // We loaded builtins through python's builtins, which means that our `error_already_set` 147 | // and `builtin_exception` may be different local classes than the ones set up in the 148 | // initial exception translator, below, so add another for our local exception classes. 149 | // 150 | // libstdc++ doesn't require this (types there are identified only by name) 151 | #if !defined(__GLIBCXX__) 152 | (*internals_pp)->registered_exception_translators.push_front( 153 | [](std::exception_ptr p) -> void { 154 | try { 155 | if (p) std::rethrow_exception(p); 156 | } catch (error_already_set &e) { e.restore(); return; 157 | } catch (const builtin_exception &e) { e.set_error(); return; 158 | } 159 | } 160 | ); 161 | #endif 162 | } else { 163 | if (!internals_pp) internals_pp = new internals*(); 164 | auto *&internals_ptr = *internals_pp; 165 | internals_ptr = new internals(); 166 | #if defined(WITH_THREAD) 167 | PyEval_InitThreads(); 168 | PyThreadState *tstate = PyThreadState_Get(); 169 | internals_ptr->tstate = PyThread_create_key(); 170 | PyThread_set_key_value(internals_ptr->tstate, tstate); 171 | internals_ptr->istate = tstate->interp; 172 | #endif 173 | builtins[id] = capsule(internals_pp); 174 | internals_ptr->registered_exception_translators.push_front( 175 | [](std::exception_ptr p) -> void { 176 | try { 177 | if (p) std::rethrow_exception(p); 178 | } catch (error_already_set &e) { e.restore(); return; 179 | } catch (const builtin_exception &e) { e.set_error(); return; 180 | } catch (const std::bad_alloc &e) { PyErr_SetString(PyExc_MemoryError, e.what()); return; 181 | } catch (const std::domain_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; 182 | } catch (const std::invalid_argument &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; 183 | } catch (const std::length_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; 184 | } catch (const std::out_of_range &e) { PyErr_SetString(PyExc_IndexError, e.what()); return; 185 | } catch (const std::range_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; 186 | } catch (const std::exception &e) { PyErr_SetString(PyExc_RuntimeError, e.what()); return; 187 | } catch (...) { 188 | PyErr_SetString(PyExc_RuntimeError, "Caught an unknown exception!"); 189 | return; 190 | } 191 | } 192 | ); 193 | internals_ptr->static_property_type = make_static_property_type(); 194 | internals_ptr->default_metaclass = make_default_metaclass(); 195 | internals_ptr->instance_base = make_object_base_type(internals_ptr->default_metaclass); 196 | } 197 | return **internals_pp; 198 | } 199 | 200 | /// Works like `internals.registered_types_cpp`, but for module-local registered types: 201 | inline type_map ®istered_local_types_cpp() { 202 | static type_map locals{}; 203 | return locals; 204 | } 205 | 206 | /// Constructs a std::string with the given arguments, stores it in `internals`, and returns its 207 | /// `c_str()`. Such strings objects have a long storage duration -- the internal strings are only 208 | /// cleared when the program exits or after interpreter shutdown (when embedding), and so are 209 | /// suitable for c-style strings needed by Python internals (such as PyTypeObject's tp_name). 210 | template 211 | const char *c_str(Args &&...args) { 212 | auto &strings = get_internals().static_strings; 213 | strings.emplace_front(std::forward(args)...); 214 | return strings.front().c_str(); 215 | } 216 | 217 | NAMESPACE_END(detail) 218 | 219 | /// Returns a named pointer that is shared among all extension modules (using the same 220 | /// pybind11 version) running in the current interpreter. Names starting with underscores 221 | /// are reserved for internal usage. Returns `nullptr` if no matching entry was found. 222 | inline PYBIND11_NOINLINE void *get_shared_data(const std::string &name) { 223 | auto &internals = detail::get_internals(); 224 | auto it = internals.shared_data.find(name); 225 | return it != internals.shared_data.end() ? it->second : nullptr; 226 | } 227 | 228 | /// Set the shared data that can be later recovered by `get_shared_data()`. 229 | inline PYBIND11_NOINLINE void *set_shared_data(const std::string &name, void *data) { 230 | detail::get_internals().shared_data[name] = data; 231 | return data; 232 | } 233 | 234 | /// Returns a typed reference to a shared data entry (by using `get_shared_data()`) if 235 | /// such entry exists. Otherwise, a new object of default-constructible type `T` is 236 | /// added to the shared data under the given name and a reference to it is returned. 237 | template 238 | T &get_or_create_shared_data(const std::string &name) { 239 | auto &internals = detail::get_internals(); 240 | auto it = internals.shared_data.find(name); 241 | T *ptr = (T *) (it != internals.shared_data.end() ? it->second : nullptr); 242 | if (!ptr) { 243 | ptr = new T(); 244 | internals.shared_data[name] = ptr; 245 | } 246 | return *ptr; 247 | } 248 | 249 | NAMESPACE_END(PYBIND11_NAMESPACE) 250 | -------------------------------------------------------------------------------- /pybind11/detail/typeid.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/detail/typeid.h: Compiler-independent access to type identifiers 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | #if defined(__GNUG__) 16 | #include 17 | #endif 18 | 19 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 20 | NAMESPACE_BEGIN(detail) 21 | /// Erase all occurrences of a substring 22 | inline void erase_all(std::string &string, const std::string &search) { 23 | for (size_t pos = 0;;) { 24 | pos = string.find(search, pos); 25 | if (pos == std::string::npos) break; 26 | string.erase(pos, search.length()); 27 | } 28 | } 29 | 30 | PYBIND11_NOINLINE inline void clean_type_id(std::string &name) { 31 | #if defined(__GNUG__) 32 | int status = 0; 33 | std::unique_ptr res { 34 | abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status), std::free }; 35 | if (status == 0) 36 | name = res.get(); 37 | #else 38 | detail::erase_all(name, "class "); 39 | detail::erase_all(name, "struct "); 40 | detail::erase_all(name, "enum "); 41 | #endif 42 | detail::erase_all(name, "pybind11::"); 43 | } 44 | NAMESPACE_END(detail) 45 | 46 | /// Return a string representation of a C++ type 47 | template static std::string type_id() { 48 | std::string name(typeid(T).name()); 49 | detail::clean_type_id(name); 50 | return name; 51 | } 52 | 53 | NAMESPACE_END(PYBIND11_NAMESPACE) 54 | -------------------------------------------------------------------------------- /pybind11/embed.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/embed.h: Support for embedding the interpreter 3 | 4 | Copyright (c) 2017 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | #include "eval.h" 14 | 15 | #if defined(PYPY_VERSION) 16 | # error Embedding the interpreter is not supported with PyPy 17 | #endif 18 | 19 | #if PY_MAJOR_VERSION >= 3 20 | # define PYBIND11_EMBEDDED_MODULE_IMPL(name) \ 21 | extern "C" PyObject *pybind11_init_impl_##name() { \ 22 | return pybind11_init_wrapper_##name(); \ 23 | } 24 | #else 25 | # define PYBIND11_EMBEDDED_MODULE_IMPL(name) \ 26 | extern "C" void pybind11_init_impl_##name() { \ 27 | pybind11_init_wrapper_##name(); \ 28 | } 29 | #endif 30 | 31 | /** \rst 32 | Add a new module to the table of builtins for the interpreter. Must be 33 | defined in global scope. The first macro parameter is the name of the 34 | module (without quotes). The second parameter is the variable which will 35 | be used as the interface to add functions and classes to the module. 36 | 37 | .. code-block:: cpp 38 | 39 | PYBIND11_EMBEDDED_MODULE(example, m) { 40 | // ... initialize functions and classes here 41 | m.def("foo", []() { 42 | return "Hello, World!"; 43 | }); 44 | } 45 | \endrst */ 46 | #define PYBIND11_EMBEDDED_MODULE(name, variable) \ 47 | static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \ 48 | static PyObject PYBIND11_CONCAT(*pybind11_init_wrapper_, name)() { \ 49 | auto m = pybind11::module(PYBIND11_TOSTRING(name)); \ 50 | try { \ 51 | PYBIND11_CONCAT(pybind11_init_, name)(m); \ 52 | return m.ptr(); \ 53 | } catch (pybind11::error_already_set &e) { \ 54 | PyErr_SetString(PyExc_ImportError, e.what()); \ 55 | return nullptr; \ 56 | } catch (const std::exception &e) { \ 57 | PyErr_SetString(PyExc_ImportError, e.what()); \ 58 | return nullptr; \ 59 | } \ 60 | } \ 61 | PYBIND11_EMBEDDED_MODULE_IMPL(name) \ 62 | pybind11::detail::embedded_module name(PYBIND11_TOSTRING(name), \ 63 | PYBIND11_CONCAT(pybind11_init_impl_, name)); \ 64 | void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &variable) 65 | 66 | 67 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 68 | NAMESPACE_BEGIN(detail) 69 | 70 | /// Python 2.7/3.x compatible version of `PyImport_AppendInittab` and error checks. 71 | struct embedded_module { 72 | #if PY_MAJOR_VERSION >= 3 73 | using init_t = PyObject *(*)(); 74 | #else 75 | using init_t = void (*)(); 76 | #endif 77 | embedded_module(const char *name, init_t init) { 78 | if (Py_IsInitialized()) 79 | pybind11_fail("Can't add new modules after the interpreter has been initialized"); 80 | 81 | auto result = PyImport_AppendInittab(name, init); 82 | if (result == -1) 83 | pybind11_fail("Insufficient memory to add a new module"); 84 | } 85 | }; 86 | 87 | NAMESPACE_END(detail) 88 | 89 | /** \rst 90 | Initialize the Python interpreter. No other pybind11 or CPython API functions can be 91 | called before this is done; with the exception of `PYBIND11_EMBEDDED_MODULE`. The 92 | optional parameter can be used to skip the registration of signal handlers (see the 93 | Python documentation for details). Calling this function again after the interpreter 94 | has already been initialized is a fatal error. 95 | \endrst */ 96 | inline void initialize_interpreter(bool init_signal_handlers = true) { 97 | if (Py_IsInitialized()) 98 | pybind11_fail("The interpreter is already running"); 99 | 100 | Py_InitializeEx(init_signal_handlers ? 1 : 0); 101 | 102 | // Make .py files in the working directory available by default 103 | module::import("sys").attr("path").cast().append("."); 104 | } 105 | 106 | /** \rst 107 | Shut down the Python interpreter. No pybind11 or CPython API functions can be called 108 | after this. In addition, pybind11 objects must not outlive the interpreter: 109 | 110 | .. code-block:: cpp 111 | 112 | { // BAD 113 | py::initialize_interpreter(); 114 | auto hello = py::str("Hello, World!"); 115 | py::finalize_interpreter(); 116 | } // <-- BOOM, hello's destructor is called after interpreter shutdown 117 | 118 | { // GOOD 119 | py::initialize_interpreter(); 120 | { // scoped 121 | auto hello = py::str("Hello, World!"); 122 | } // <-- OK, hello is cleaned up properly 123 | py::finalize_interpreter(); 124 | } 125 | 126 | { // BETTER 127 | py::scoped_interpreter guard{}; 128 | auto hello = py::str("Hello, World!"); 129 | } 130 | 131 | .. warning:: 132 | 133 | The interpreter can be restarted by calling `initialize_interpreter` again. 134 | Modules created using pybind11 can be safely re-initialized. However, Python 135 | itself cannot completely unload binary extension modules and there are several 136 | caveats with regard to interpreter restarting. All the details can be found 137 | in the CPython documentation. In short, not all interpreter memory may be 138 | freed, either due to reference cycles or user-created global data. 139 | 140 | \endrst */ 141 | inline void finalize_interpreter() { 142 | handle builtins(PyEval_GetBuiltins()); 143 | const char *id = PYBIND11_INTERNALS_ID; 144 | 145 | // Get the internals pointer (without creating it if it doesn't exist). It's possible for the 146 | // internals to be created during Py_Finalize() (e.g. if a py::capsule calls `get_internals()` 147 | // during destruction), so we get the pointer-pointer here and check it after Py_Finalize(). 148 | detail::internals **internals_ptr_ptr = detail::get_internals_pp(); 149 | // It could also be stashed in builtins, so look there too: 150 | if (builtins.contains(id) && isinstance(builtins[id])) 151 | internals_ptr_ptr = capsule(builtins[id]); 152 | 153 | Py_Finalize(); 154 | 155 | if (internals_ptr_ptr) { 156 | delete *internals_ptr_ptr; 157 | *internals_ptr_ptr = nullptr; 158 | } 159 | } 160 | 161 | /** \rst 162 | Scope guard version of `initialize_interpreter` and `finalize_interpreter`. 163 | This a move-only guard and only a single instance can exist. 164 | 165 | .. code-block:: cpp 166 | 167 | #include 168 | 169 | int main() { 170 | py::scoped_interpreter guard{}; 171 | py::print(Hello, World!); 172 | } // <-- interpreter shutdown 173 | \endrst */ 174 | class scoped_interpreter { 175 | public: 176 | scoped_interpreter(bool init_signal_handlers = true) { 177 | initialize_interpreter(init_signal_handlers); 178 | } 179 | 180 | scoped_interpreter(const scoped_interpreter &) = delete; 181 | scoped_interpreter(scoped_interpreter &&other) noexcept { other.is_valid = false; } 182 | scoped_interpreter &operator=(const scoped_interpreter &) = delete; 183 | scoped_interpreter &operator=(scoped_interpreter &&) = delete; 184 | 185 | ~scoped_interpreter() { 186 | if (is_valid) 187 | finalize_interpreter(); 188 | } 189 | 190 | private: 191 | bool is_valid = true; 192 | }; 193 | 194 | NAMESPACE_END(PYBIND11_NAMESPACE) 195 | -------------------------------------------------------------------------------- /pybind11/eval.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/exec.h: Support for evaluating Python expressions and statements 3 | from strings and files 4 | 5 | Copyright (c) 2016 Klemens Morgenstern and 6 | Wenzel Jakob 7 | 8 | All rights reserved. Use of this source code is governed by a 9 | BSD-style license that can be found in the LICENSE file. 10 | */ 11 | 12 | #pragma once 13 | 14 | #include "pybind11.h" 15 | 16 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 17 | 18 | enum eval_mode { 19 | /// Evaluate a string containing an isolated expression 20 | eval_expr, 21 | 22 | /// Evaluate a string containing a single statement. Returns \c none 23 | eval_single_statement, 24 | 25 | /// Evaluate a string containing a sequence of statement. Returns \c none 26 | eval_statements 27 | }; 28 | 29 | template 30 | object eval(str expr, object global = globals(), object local = object()) { 31 | if (!local) 32 | local = global; 33 | 34 | /* PyRun_String does not accept a PyObject / encoding specifier, 35 | this seems to be the only alternative */ 36 | std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr; 37 | 38 | int start; 39 | switch (mode) { 40 | case eval_expr: start = Py_eval_input; break; 41 | case eval_single_statement: start = Py_single_input; break; 42 | case eval_statements: start = Py_file_input; break; 43 | default: pybind11_fail("invalid evaluation mode"); 44 | } 45 | 46 | PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr()); 47 | if (!result) 48 | throw error_already_set(); 49 | return reinterpret_steal(result); 50 | } 51 | 52 | template 53 | object eval(const char (&s)[N], object global = globals(), object local = object()) { 54 | /* Support raw string literals by removing common leading whitespace */ 55 | auto expr = (s[0] == '\n') ? str(module::import("textwrap").attr("dedent")(s)) 56 | : str(s); 57 | return eval(expr, global, local); 58 | } 59 | 60 | inline void exec(str expr, object global = globals(), object local = object()) { 61 | eval(expr, global, local); 62 | } 63 | 64 | template 65 | void exec(const char (&s)[N], object global = globals(), object local = object()) { 66 | eval(s, global, local); 67 | } 68 | 69 | template 70 | object eval_file(str fname, object global = globals(), object local = object()) { 71 | if (!local) 72 | local = global; 73 | 74 | int start; 75 | switch (mode) { 76 | case eval_expr: start = Py_eval_input; break; 77 | case eval_single_statement: start = Py_single_input; break; 78 | case eval_statements: start = Py_file_input; break; 79 | default: pybind11_fail("invalid evaluation mode"); 80 | } 81 | 82 | int closeFile = 1; 83 | std::string fname_str = (std::string) fname; 84 | #if PY_VERSION_HEX >= 0x03040000 85 | FILE *f = _Py_fopen_obj(fname.ptr(), "r"); 86 | #elif PY_VERSION_HEX >= 0x03000000 87 | FILE *f = _Py_fopen(fname.ptr(), "r"); 88 | #else 89 | /* No unicode support in open() :( */ 90 | auto fobj = reinterpret_steal(PyFile_FromString( 91 | const_cast(fname_str.c_str()), 92 | const_cast("r"))); 93 | FILE *f = nullptr; 94 | if (fobj) 95 | f = PyFile_AsFile(fobj.ptr()); 96 | closeFile = 0; 97 | #endif 98 | if (!f) { 99 | PyErr_Clear(); 100 | pybind11_fail("File \"" + fname_str + "\" could not be opened!"); 101 | } 102 | 103 | #if PY_VERSION_HEX < 0x03000000 && defined(PYPY_VERSION) 104 | PyObject *result = PyRun_File(f, fname_str.c_str(), start, global.ptr(), 105 | local.ptr()); 106 | (void) closeFile; 107 | #else 108 | PyObject *result = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(), 109 | local.ptr(), closeFile); 110 | #endif 111 | 112 | if (!result) 113 | throw error_already_set(); 114 | return reinterpret_steal(result); 115 | } 116 | 117 | NAMESPACE_END(PYBIND11_NAMESPACE) 118 | -------------------------------------------------------------------------------- /pybind11/functional.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/functional.h: std::function<> support 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | #include 14 | 15 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 16 | NAMESPACE_BEGIN(detail) 17 | 18 | template 19 | struct type_caster> { 20 | using type = std::function; 21 | using retval_type = conditional_t::value, void_type, Return>; 22 | using function_type = Return (*) (Args...); 23 | 24 | public: 25 | bool load(handle src, bool convert) { 26 | if (src.is_none()) { 27 | // Defer accepting None to other overloads (if we aren't in convert mode): 28 | if (!convert) return false; 29 | return true; 30 | } 31 | 32 | if (!isinstance(src)) 33 | return false; 34 | 35 | auto func = reinterpret_borrow(src); 36 | 37 | /* 38 | When passing a C++ function as an argument to another C++ 39 | function via Python, every function call would normally involve 40 | a full C++ -> Python -> C++ roundtrip, which can be prohibitive. 41 | Here, we try to at least detect the case where the function is 42 | stateless (i.e. function pointer or lambda function without 43 | captured variables), in which case the roundtrip can be avoided. 44 | */ 45 | if (auto cfunc = func.cpp_function()) { 46 | auto c = reinterpret_borrow(PyCFunction_GET_SELF(cfunc.ptr())); 47 | auto rec = (function_record *) c; 48 | 49 | if (rec && rec->is_stateless && 50 | same_type(typeid(function_type), *reinterpret_cast(rec->data[1]))) { 51 | struct capture { function_type f; }; 52 | value = ((capture *) &rec->data)->f; 53 | return true; 54 | } 55 | } 56 | 57 | value = [func](Args... args) -> Return { 58 | gil_scoped_acquire acq; 59 | object retval(func(std::forward(args)...)); 60 | /* Visual studio 2015 parser issue: need parentheses around this expression */ 61 | return (retval.template cast()); 62 | }; 63 | return true; 64 | } 65 | 66 | template 67 | static handle cast(Func &&f_, return_value_policy policy, handle /* parent */) { 68 | if (!f_) 69 | return none().inc_ref(); 70 | 71 | auto result = f_.template target(); 72 | if (result) 73 | return cpp_function(*result, policy).release(); 74 | else 75 | return cpp_function(std::forward(f_), policy).release(); 76 | } 77 | 78 | PYBIND11_TYPE_CASTER(type, _("Callable[[") + concat(make_caster::name...) + _("], ") 79 | + make_caster::name + _("]")); 80 | }; 81 | 82 | NAMESPACE_END(detail) 83 | NAMESPACE_END(PYBIND11_NAMESPACE) 84 | -------------------------------------------------------------------------------- /pybind11/iostream.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/iostream.h -- Tools to assist with redirecting cout and cerr to Python 3 | 4 | Copyright (c) 2017 Henry F. Schreiner 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 21 | NAMESPACE_BEGIN(detail) 22 | 23 | // Buffer that writes to Python instead of C++ 24 | class pythonbuf : public std::streambuf { 25 | private: 26 | using traits_type = std::streambuf::traits_type; 27 | 28 | char d_buffer[1024]; 29 | object pywrite; 30 | object pyflush; 31 | 32 | int overflow(int c) { 33 | if (!traits_type::eq_int_type(c, traits_type::eof())) { 34 | *pptr() = traits_type::to_char_type(c); 35 | pbump(1); 36 | } 37 | return sync() ? traits_type::not_eof(c) : traits_type::eof(); 38 | } 39 | 40 | int sync() { 41 | if (pbase() != pptr()) { 42 | // This subtraction cannot be negative, so dropping the sign 43 | str line(pbase(), static_cast(pptr() - pbase())); 44 | 45 | pywrite(line); 46 | pyflush(); 47 | 48 | setp(pbase(), epptr()); 49 | } 50 | return 0; 51 | } 52 | 53 | public: 54 | pythonbuf(object pyostream) 55 | : pywrite(pyostream.attr("write")), 56 | pyflush(pyostream.attr("flush")) { 57 | setp(d_buffer, d_buffer + sizeof(d_buffer) - 1); 58 | } 59 | 60 | /// Sync before destroy 61 | ~pythonbuf() { 62 | sync(); 63 | } 64 | }; 65 | 66 | NAMESPACE_END(detail) 67 | 68 | 69 | /** \rst 70 | This a move-only guard that redirects output. 71 | 72 | .. code-block:: cpp 73 | 74 | #include 75 | 76 | ... 77 | 78 | { 79 | py::scoped_ostream_redirect output; 80 | std::cout << "Hello, World!"; // Python stdout 81 | } // <-- return std::cout to normal 82 | 83 | You can explicitly pass the c++ stream and the python object, 84 | for example to guard stderr instead. 85 | 86 | .. code-block:: cpp 87 | 88 | { 89 | py::scoped_ostream_redirect output{std::cerr, py::module::import("sys").attr("stderr")}; 90 | std::cerr << "Hello, World!"; 91 | } 92 | \endrst */ 93 | class scoped_ostream_redirect { 94 | protected: 95 | std::streambuf *old; 96 | std::ostream &costream; 97 | detail::pythonbuf buffer; 98 | 99 | public: 100 | scoped_ostream_redirect( 101 | std::ostream &costream = std::cout, 102 | object pyostream = module::import("sys").attr("stdout")) 103 | : costream(costream), buffer(pyostream) { 104 | old = costream.rdbuf(&buffer); 105 | } 106 | 107 | ~scoped_ostream_redirect() { 108 | costream.rdbuf(old); 109 | } 110 | 111 | scoped_ostream_redirect(const scoped_ostream_redirect &) = delete; 112 | scoped_ostream_redirect(scoped_ostream_redirect &&other) = default; 113 | scoped_ostream_redirect &operator=(const scoped_ostream_redirect &) = delete; 114 | scoped_ostream_redirect &operator=(scoped_ostream_redirect &&) = delete; 115 | }; 116 | 117 | 118 | /** \rst 119 | Like `scoped_ostream_redirect`, but redirects cerr by default. This class 120 | is provided primary to make ``py::call_guard`` easier to make. 121 | 122 | .. code-block:: cpp 123 | 124 | m.def("noisy_func", &noisy_func, 125 | py::call_guard()); 127 | 128 | \endrst */ 129 | class scoped_estream_redirect : public scoped_ostream_redirect { 130 | public: 131 | scoped_estream_redirect( 132 | std::ostream &costream = std::cerr, 133 | object pyostream = module::import("sys").attr("stderr")) 134 | : scoped_ostream_redirect(costream,pyostream) {} 135 | }; 136 | 137 | 138 | NAMESPACE_BEGIN(detail) 139 | 140 | // Class to redirect output as a context manager. C++ backend. 141 | class OstreamRedirect { 142 | bool do_stdout_; 143 | bool do_stderr_; 144 | std::unique_ptr redirect_stdout; 145 | std::unique_ptr redirect_stderr; 146 | 147 | public: 148 | OstreamRedirect(bool do_stdout = true, bool do_stderr = true) 149 | : do_stdout_(do_stdout), do_stderr_(do_stderr) {} 150 | 151 | void enter() { 152 | if (do_stdout_) 153 | redirect_stdout.reset(new scoped_ostream_redirect()); 154 | if (do_stderr_) 155 | redirect_stderr.reset(new scoped_estream_redirect()); 156 | } 157 | 158 | void exit() { 159 | redirect_stdout.reset(); 160 | redirect_stderr.reset(); 161 | } 162 | }; 163 | 164 | NAMESPACE_END(detail) 165 | 166 | /** \rst 167 | This is a helper function to add a C++ redirect context manager to Python 168 | instead of using a C++ guard. To use it, add the following to your binding code: 169 | 170 | .. code-block:: cpp 171 | 172 | #include 173 | 174 | ... 175 | 176 | py::add_ostream_redirect(m, "ostream_redirect"); 177 | 178 | You now have a Python context manager that redirects your output: 179 | 180 | .. code-block:: python 181 | 182 | with m.ostream_redirect(): 183 | m.print_to_cout_function() 184 | 185 | This manager can optionally be told which streams to operate on: 186 | 187 | .. code-block:: python 188 | 189 | with m.ostream_redirect(stdout=true, stderr=true): 190 | m.noisy_function_with_error_printing() 191 | 192 | \endrst */ 193 | inline class_ add_ostream_redirect(module m, std::string name = "ostream_redirect") { 194 | return class_(m, name.c_str(), module_local()) 195 | .def(init(), arg("stdout")=true, arg("stderr")=true) 196 | .def("__enter__", &detail::OstreamRedirect::enter) 197 | .def("__exit__", [](detail::OstreamRedirect &self, args) { self.exit(); }); 198 | } 199 | 200 | NAMESPACE_END(PYBIND11_NAMESPACE) 201 | -------------------------------------------------------------------------------- /pybind11/operators.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/operator.h: Metatemplates for operator overloading 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | 14 | #if defined(__clang__) && !defined(__INTEL_COMPILER) 15 | # pragma clang diagnostic ignored "-Wunsequenced" // multiple unsequenced modifications to 'self' (when using def(py::self OP Type())) 16 | #elif defined(_MSC_VER) 17 | # pragma warning(push) 18 | # pragma warning(disable: 4127) // warning C4127: Conditional expression is constant 19 | #endif 20 | 21 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 22 | NAMESPACE_BEGIN(detail) 23 | 24 | /// Enumeration with all supported operator types 25 | enum op_id : int { 26 | op_add, op_sub, op_mul, op_div, op_mod, op_divmod, op_pow, op_lshift, 27 | op_rshift, op_and, op_xor, op_or, op_neg, op_pos, op_abs, op_invert, 28 | op_int, op_long, op_float, op_str, op_cmp, op_gt, op_ge, op_lt, op_le, 29 | op_eq, op_ne, op_iadd, op_isub, op_imul, op_idiv, op_imod, op_ilshift, 30 | op_irshift, op_iand, op_ixor, op_ior, op_complex, op_bool, op_nonzero, 31 | op_repr, op_truediv, op_itruediv, op_hash 32 | }; 33 | 34 | enum op_type : int { 35 | op_l, /* base type on left */ 36 | op_r, /* base type on right */ 37 | op_u /* unary operator */ 38 | }; 39 | 40 | struct self_t { }; 41 | static const self_t self = self_t(); 42 | 43 | /// Type for an unused type slot 44 | struct undefined_t { }; 45 | 46 | /// Don't warn about an unused variable 47 | inline self_t __self() { return self; } 48 | 49 | /// base template of operator implementations 50 | template struct op_impl { }; 51 | 52 | /// Operator implementation generator 53 | template struct op_ { 54 | template void execute(Class &cl, const Extra&... extra) const { 55 | using Base = typename Class::type; 56 | using L_type = conditional_t::value, Base, L>; 57 | using R_type = conditional_t::value, Base, R>; 58 | using op = op_impl; 59 | cl.def(op::name(), &op::execute, is_operator(), extra...); 60 | #if PY_MAJOR_VERSION < 3 61 | if (id == op_truediv || id == op_itruediv) 62 | cl.def(id == op_itruediv ? "__idiv__" : ot == op_l ? "__div__" : "__rdiv__", 63 | &op::execute, is_operator(), extra...); 64 | #endif 65 | } 66 | template void execute_cast(Class &cl, const Extra&... extra) const { 67 | using Base = typename Class::type; 68 | using L_type = conditional_t::value, Base, L>; 69 | using R_type = conditional_t::value, Base, R>; 70 | using op = op_impl; 71 | cl.def(op::name(), &op::execute_cast, is_operator(), extra...); 72 | #if PY_MAJOR_VERSION < 3 73 | if (id == op_truediv || id == op_itruediv) 74 | cl.def(id == op_itruediv ? "__idiv__" : ot == op_l ? "__div__" : "__rdiv__", 75 | &op::execute, is_operator(), extra...); 76 | #endif 77 | } 78 | }; 79 | 80 | #define PYBIND11_BINARY_OPERATOR(id, rid, op, expr) \ 81 | template struct op_impl { \ 82 | static char const* name() { return "__" #id "__"; } \ 83 | static auto execute(const L &l, const R &r) -> decltype(expr) { return (expr); } \ 84 | static B execute_cast(const L &l, const R &r) { return B(expr); } \ 85 | }; \ 86 | template struct op_impl { \ 87 | static char const* name() { return "__" #rid "__"; } \ 88 | static auto execute(const R &r, const L &l) -> decltype(expr) { return (expr); } \ 89 | static B execute_cast(const R &r, const L &l) { return B(expr); } \ 90 | }; \ 91 | inline op_ op(const self_t &, const self_t &) { \ 92 | return op_(); \ 93 | } \ 94 | template op_ op(const self_t &, const T &) { \ 95 | return op_(); \ 96 | } \ 97 | template op_ op(const T &, const self_t &) { \ 98 | return op_(); \ 99 | } 100 | 101 | #define PYBIND11_INPLACE_OPERATOR(id, op, expr) \ 102 | template struct op_impl { \ 103 | static char const* name() { return "__" #id "__"; } \ 104 | static auto execute(L &l, const R &r) -> decltype(expr) { return expr; } \ 105 | static B execute_cast(L &l, const R &r) { return B(expr); } \ 106 | }; \ 107 | template op_ op(const self_t &, const T &) { \ 108 | return op_(); \ 109 | } 110 | 111 | #define PYBIND11_UNARY_OPERATOR(id, op, expr) \ 112 | template struct op_impl { \ 113 | static char const* name() { return "__" #id "__"; } \ 114 | static auto execute(const L &l) -> decltype(expr) { return expr; } \ 115 | static B execute_cast(const L &l) { return B(expr); } \ 116 | }; \ 117 | inline op_ op(const self_t &) { \ 118 | return op_(); \ 119 | } 120 | 121 | PYBIND11_BINARY_OPERATOR(sub, rsub, operator-, l - r) 122 | PYBIND11_BINARY_OPERATOR(add, radd, operator+, l + r) 123 | PYBIND11_BINARY_OPERATOR(mul, rmul, operator*, l * r) 124 | PYBIND11_BINARY_OPERATOR(truediv, rtruediv, operator/, l / r) 125 | PYBIND11_BINARY_OPERATOR(mod, rmod, operator%, l % r) 126 | PYBIND11_BINARY_OPERATOR(lshift, rlshift, operator<<, l << r) 127 | PYBIND11_BINARY_OPERATOR(rshift, rrshift, operator>>, l >> r) 128 | PYBIND11_BINARY_OPERATOR(and, rand, operator&, l & r) 129 | PYBIND11_BINARY_OPERATOR(xor, rxor, operator^, l ^ r) 130 | PYBIND11_BINARY_OPERATOR(eq, eq, operator==, l == r) 131 | PYBIND11_BINARY_OPERATOR(ne, ne, operator!=, l != r) 132 | PYBIND11_BINARY_OPERATOR(or, ror, operator|, l | r) 133 | PYBIND11_BINARY_OPERATOR(gt, lt, operator>, l > r) 134 | PYBIND11_BINARY_OPERATOR(ge, le, operator>=, l >= r) 135 | PYBIND11_BINARY_OPERATOR(lt, gt, operator<, l < r) 136 | PYBIND11_BINARY_OPERATOR(le, ge, operator<=, l <= r) 137 | //PYBIND11_BINARY_OPERATOR(pow, rpow, pow, std::pow(l, r)) 138 | PYBIND11_INPLACE_OPERATOR(iadd, operator+=, l += r) 139 | PYBIND11_INPLACE_OPERATOR(isub, operator-=, l -= r) 140 | PYBIND11_INPLACE_OPERATOR(imul, operator*=, l *= r) 141 | PYBIND11_INPLACE_OPERATOR(itruediv, operator/=, l /= r) 142 | PYBIND11_INPLACE_OPERATOR(imod, operator%=, l %= r) 143 | PYBIND11_INPLACE_OPERATOR(ilshift, operator<<=, l <<= r) 144 | PYBIND11_INPLACE_OPERATOR(irshift, operator>>=, l >>= r) 145 | PYBIND11_INPLACE_OPERATOR(iand, operator&=, l &= r) 146 | PYBIND11_INPLACE_OPERATOR(ixor, operator^=, l ^= r) 147 | PYBIND11_INPLACE_OPERATOR(ior, operator|=, l |= r) 148 | PYBIND11_UNARY_OPERATOR(neg, operator-, -l) 149 | PYBIND11_UNARY_OPERATOR(pos, operator+, +l) 150 | PYBIND11_UNARY_OPERATOR(abs, abs, std::abs(l)) 151 | PYBIND11_UNARY_OPERATOR(hash, hash, std::hash()(l)) 152 | PYBIND11_UNARY_OPERATOR(invert, operator~, (~l)) 153 | PYBIND11_UNARY_OPERATOR(bool, operator!, !!l) 154 | PYBIND11_UNARY_OPERATOR(int, int_, (int) l) 155 | PYBIND11_UNARY_OPERATOR(float, float_, (double) l) 156 | 157 | #undef PYBIND11_BINARY_OPERATOR 158 | #undef PYBIND11_INPLACE_OPERATOR 159 | #undef PYBIND11_UNARY_OPERATOR 160 | NAMESPACE_END(detail) 161 | 162 | using detail::self; 163 | 164 | NAMESPACE_END(PYBIND11_NAMESPACE) 165 | 166 | #if defined(_MSC_VER) 167 | # pragma warning(pop) 168 | #endif 169 | -------------------------------------------------------------------------------- /pybind11/options.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/options.h: global settings that are configurable at runtime. 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "detail/common.h" 13 | 14 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 15 | 16 | class options { 17 | public: 18 | 19 | // Default RAII constructor, which leaves settings as they currently are. 20 | options() : previous_state(global_state()) {} 21 | 22 | // Class is non-copyable. 23 | options(const options&) = delete; 24 | options& operator=(const options&) = delete; 25 | 26 | // Destructor, which restores settings that were in effect before. 27 | ~options() { 28 | global_state() = previous_state; 29 | } 30 | 31 | // Setter methods (affect the global state): 32 | 33 | options& disable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = false; return *this; } 34 | 35 | options& enable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = true; return *this; } 36 | 37 | options& disable_function_signatures() & { global_state().show_function_signatures = false; return *this; } 38 | 39 | options& enable_function_signatures() & { global_state().show_function_signatures = true; return *this; } 40 | 41 | // Getter methods (return the global state): 42 | 43 | static bool show_user_defined_docstrings() { return global_state().show_user_defined_docstrings; } 44 | 45 | static bool show_function_signatures() { return global_state().show_function_signatures; } 46 | 47 | // This type is not meant to be allocated on the heap. 48 | void* operator new(size_t) = delete; 49 | 50 | private: 51 | 52 | struct state { 53 | bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings. 54 | bool show_function_signatures = true; //< Include auto-generated function signatures in docstrings. 55 | }; 56 | 57 | static state &global_state() { 58 | static state instance; 59 | return instance; 60 | } 61 | 62 | state previous_state; 63 | }; 64 | 65 | NAMESPACE_END(PYBIND11_NAMESPACE) 66 | -------------------------------------------------------------------------------- /pybind11/stl.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/stl.h: Transparent conversion for STL data types 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #if defined(_MSC_VER) 22 | #pragma warning(push) 23 | #pragma warning(disable: 4127) // warning C4127: Conditional expression is constant 24 | #endif 25 | 26 | #ifdef __has_include 27 | // std::optional (but including it in c++14 mode isn't allowed) 28 | # if defined(PYBIND11_CPP17) && __has_include() 29 | # include 30 | # define PYBIND11_HAS_OPTIONAL 1 31 | # endif 32 | // std::experimental::optional (but not allowed in c++11 mode) 33 | # if defined(PYBIND11_CPP14) && (__has_include() && \ 34 | !__has_include()) 35 | # include 36 | # define PYBIND11_HAS_EXP_OPTIONAL 1 37 | # endif 38 | // std::variant 39 | # if defined(PYBIND11_CPP17) && __has_include() 40 | # include 41 | # define PYBIND11_HAS_VARIANT 1 42 | # endif 43 | #elif defined(_MSC_VER) && defined(PYBIND11_CPP17) 44 | # include 45 | # include 46 | # define PYBIND11_HAS_OPTIONAL 1 47 | # define PYBIND11_HAS_VARIANT 1 48 | #endif 49 | 50 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 51 | NAMESPACE_BEGIN(detail) 52 | 53 | /// Extracts an const lvalue reference or rvalue reference for U based on the type of T (e.g. for 54 | /// forwarding a container element). Typically used indirect via forwarded_type(), below. 55 | template 56 | using forwarded_type = conditional_t< 57 | std::is_lvalue_reference::value, remove_reference_t &, remove_reference_t &&>; 58 | 59 | /// Forwards a value U as rvalue or lvalue according to whether T is rvalue or lvalue; typically 60 | /// used for forwarding a container's elements. 61 | template 62 | forwarded_type forward_like(U &&u) { 63 | return std::forward>(std::forward(u)); 64 | } 65 | 66 | template struct set_caster { 67 | using type = Type; 68 | using key_conv = make_caster; 69 | 70 | bool load(handle src, bool convert) { 71 | if (!isinstance(src)) 72 | return false; 73 | auto s = reinterpret_borrow(src); 74 | value.clear(); 75 | for (auto entry : s) { 76 | key_conv conv; 77 | if (!conv.load(entry, convert)) 78 | return false; 79 | value.insert(cast_op(std::move(conv))); 80 | } 81 | return true; 82 | } 83 | 84 | template 85 | static handle cast(T &&src, return_value_policy policy, handle parent) { 86 | pybind11::set s; 87 | for (auto &&value : src) { 88 | auto value_ = reinterpret_steal(key_conv::cast(forward_like(value), policy, parent)); 89 | if (!value_ || !s.add(value_)) 90 | return handle(); 91 | } 92 | return s.release(); 93 | } 94 | 95 | PYBIND11_TYPE_CASTER(type, _("Set[") + key_conv::name + _("]")); 96 | }; 97 | 98 | template struct map_caster { 99 | using key_conv = make_caster; 100 | using value_conv = make_caster; 101 | 102 | bool load(handle src, bool convert) { 103 | if (!isinstance(src)) 104 | return false; 105 | auto d = reinterpret_borrow(src); 106 | value.clear(); 107 | for (auto it : d) { 108 | key_conv kconv; 109 | value_conv vconv; 110 | if (!kconv.load(it.first.ptr(), convert) || 111 | !vconv.load(it.second.ptr(), convert)) 112 | return false; 113 | value.emplace(cast_op(std::move(kconv)), cast_op(std::move(vconv))); 114 | } 115 | return true; 116 | } 117 | 118 | template 119 | static handle cast(T &&src, return_value_policy policy, handle parent) { 120 | dict d; 121 | for (auto &&kv : src) { 122 | auto key = reinterpret_steal(key_conv::cast(forward_like(kv.first), policy, parent)); 123 | auto value = reinterpret_steal(value_conv::cast(forward_like(kv.second), policy, parent)); 124 | if (!key || !value) 125 | return handle(); 126 | d[key] = value; 127 | } 128 | return d.release(); 129 | } 130 | 131 | PYBIND11_TYPE_CASTER(Type, _("Dict[") + key_conv::name + _(", ") + value_conv::name + _("]")); 132 | }; 133 | 134 | template struct list_caster { 135 | using value_conv = make_caster; 136 | 137 | bool load(handle src, bool convert) { 138 | if (!isinstance(src)) 139 | return false; 140 | auto s = reinterpret_borrow(src); 141 | value.clear(); 142 | reserve_maybe(s, &value); 143 | for (auto it : s) { 144 | value_conv conv; 145 | if (!conv.load(it, convert)) 146 | return false; 147 | value.push_back(cast_op(std::move(conv))); 148 | } 149 | return true; 150 | } 151 | 152 | private: 153 | template ().reserve(0)), void>::value, int> = 0> 155 | void reserve_maybe(sequence s, Type *) { value.reserve(s.size()); } 156 | void reserve_maybe(sequence, void *) { } 157 | 158 | public: 159 | template 160 | static handle cast(T &&src, return_value_policy policy, handle parent) { 161 | list l(src.size()); 162 | size_t index = 0; 163 | for (auto &&value : src) { 164 | auto value_ = reinterpret_steal(value_conv::cast(forward_like(value), policy, parent)); 165 | if (!value_) 166 | return handle(); 167 | PyList_SET_ITEM(l.ptr(), (ssize_t) index++, value_.release().ptr()); // steals a reference 168 | } 169 | return l.release(); 170 | } 171 | 172 | PYBIND11_TYPE_CASTER(Type, _("List[") + value_conv::name + _("]")); 173 | }; 174 | 175 | template struct type_caster> 176 | : list_caster, Type> { }; 177 | 178 | template struct type_caster> 179 | : list_caster, Type> { }; 180 | 181 | template struct array_caster { 182 | using value_conv = make_caster; 183 | 184 | private: 185 | template 186 | bool require_size(enable_if_t size) { 187 | if (value.size() != size) 188 | value.resize(size); 189 | return true; 190 | } 191 | template 192 | bool require_size(enable_if_t size) { 193 | return size == Size; 194 | } 195 | 196 | public: 197 | bool load(handle src, bool convert) { 198 | if (!isinstance(src)) 199 | return false; 200 | auto l = reinterpret_borrow(src); 201 | if (!require_size(l.size())) 202 | return false; 203 | size_t ctr = 0; 204 | for (auto it : l) { 205 | value_conv conv; 206 | if (!conv.load(it, convert)) 207 | return false; 208 | value[ctr++] = cast_op(std::move(conv)); 209 | } 210 | return true; 211 | } 212 | 213 | template 214 | static handle cast(T &&src, return_value_policy policy, handle parent) { 215 | list l(src.size()); 216 | size_t index = 0; 217 | for (auto &&value : src) { 218 | auto value_ = reinterpret_steal(value_conv::cast(forward_like(value), policy, parent)); 219 | if (!value_) 220 | return handle(); 221 | PyList_SET_ITEM(l.ptr(), (ssize_t) index++, value_.release().ptr()); // steals a reference 222 | } 223 | return l.release(); 224 | } 225 | 226 | PYBIND11_TYPE_CASTER(ArrayType, _("List[") + value_conv::name + _(_(""), _("[") + _() + _("]")) + _("]")); 227 | }; 228 | 229 | template struct type_caster> 230 | : array_caster, Type, false, Size> { }; 231 | 232 | template struct type_caster> 233 | : array_caster, Type, true> { }; 234 | 235 | template struct type_caster> 236 | : set_caster, Key> { }; 237 | 238 | template struct type_caster> 239 | : set_caster, Key> { }; 240 | 241 | template struct type_caster> 242 | : map_caster, Key, Value> { }; 243 | 244 | template struct type_caster> 245 | : map_caster, Key, Value> { }; 246 | 247 | // This type caster is intended to be used for std::optional and std::experimental::optional 248 | template struct optional_caster { 249 | using value_conv = make_caster; 250 | 251 | template 252 | static handle cast(T_ &&src, return_value_policy policy, handle parent) { 253 | if (!src) 254 | return none().inc_ref(); 255 | return value_conv::cast(*std::forward(src), policy, parent); 256 | } 257 | 258 | bool load(handle src, bool convert) { 259 | if (!src) { 260 | return false; 261 | } else if (src.is_none()) { 262 | return true; // default-constructed value is already empty 263 | } 264 | value_conv inner_caster; 265 | if (!inner_caster.load(src, convert)) 266 | return false; 267 | 268 | value.emplace(cast_op(std::move(inner_caster))); 269 | return true; 270 | } 271 | 272 | PYBIND11_TYPE_CASTER(T, _("Optional[") + value_conv::name + _("]")); 273 | }; 274 | 275 | #if PYBIND11_HAS_OPTIONAL 276 | template struct type_caster> 277 | : public optional_caster> {}; 278 | 279 | template<> struct type_caster 280 | : public void_caster {}; 281 | #endif 282 | 283 | #if PYBIND11_HAS_EXP_OPTIONAL 284 | template struct type_caster> 285 | : public optional_caster> {}; 286 | 287 | template<> struct type_caster 288 | : public void_caster {}; 289 | #endif 290 | 291 | /// Visit a variant and cast any found type to Python 292 | struct variant_caster_visitor { 293 | return_value_policy policy; 294 | handle parent; 295 | 296 | using result_type = handle; // required by boost::variant in C++11 297 | 298 | template 299 | result_type operator()(T &&src) const { 300 | return make_caster::cast(std::forward(src), policy, parent); 301 | } 302 | }; 303 | 304 | /// Helper class which abstracts away variant's `visit` function. `std::variant` and similar 305 | /// `namespace::variant` types which provide a `namespace::visit()` function are handled here 306 | /// automatically using argument-dependent lookup. Users can provide specializations for other 307 | /// variant-like classes, e.g. `boost::variant` and `boost::apply_visitor`. 308 | template class Variant> 309 | struct visit_helper { 310 | template 311 | static auto call(Args &&...args) -> decltype(visit(std::forward(args)...)) { 312 | return visit(std::forward(args)...); 313 | } 314 | }; 315 | 316 | /// Generic variant caster 317 | template struct variant_caster; 318 | 319 | template class V, typename... Ts> 320 | struct variant_caster> { 321 | static_assert(sizeof...(Ts) > 0, "Variant must consist of at least one alternative."); 322 | 323 | template 324 | bool load_alternative(handle src, bool convert, type_list) { 325 | auto caster = make_caster(); 326 | if (caster.load(src, convert)) { 327 | value = cast_op(caster); 328 | return true; 329 | } 330 | return load_alternative(src, convert, type_list{}); 331 | } 332 | 333 | bool load_alternative(handle, bool, type_list<>) { return false; } 334 | 335 | bool load(handle src, bool convert) { 336 | // Do a first pass without conversions to improve constructor resolution. 337 | // E.g. `py::int_(1).cast>()` needs to fill the `int` 338 | // slot of the variant. Without two-pass loading `double` would be filled 339 | // because it appears first and a conversion is possible. 340 | if (convert && load_alternative(src, false, type_list{})) 341 | return true; 342 | return load_alternative(src, convert, type_list{}); 343 | } 344 | 345 | template 346 | static handle cast(Variant &&src, return_value_policy policy, handle parent) { 347 | return visit_helper::call(variant_caster_visitor{policy, parent}, 348 | std::forward(src)); 349 | } 350 | 351 | using Type = V; 352 | PYBIND11_TYPE_CASTER(Type, _("Union[") + detail::concat(make_caster::name...) + _("]")); 353 | }; 354 | 355 | #if PYBIND11_HAS_VARIANT 356 | template 357 | struct type_caster> : variant_caster> { }; 358 | #endif 359 | NAMESPACE_END(detail) 360 | 361 | inline std::ostream &operator<<(std::ostream &os, const handle &obj) { 362 | os << (std::string) str(obj); 363 | return os; 364 | } 365 | 366 | NAMESPACE_END(PYBIND11_NAMESPACE) 367 | 368 | #if defined(_MSC_VER) 369 | #pragma warning(pop) 370 | #endif 371 | -------------------------------------------------------------------------------- /pybind11/stl_bind.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/std_bind.h: Binding generators for STL data types 3 | 4 | Copyright (c) 2016 Sergey Lyskov and Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "detail/common.h" 13 | #include "operators.h" 14 | 15 | #include 16 | #include 17 | 18 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 19 | NAMESPACE_BEGIN(detail) 20 | 21 | /* SFINAE helper class used by 'is_comparable */ 22 | template struct container_traits { 23 | template static std::true_type test_comparable(decltype(std::declval() == std::declval())*); 24 | template static std::false_type test_comparable(...); 25 | template static std::true_type test_value(typename T2::value_type *); 26 | template static std::false_type test_value(...); 27 | template static std::true_type test_pair(typename T2::first_type *, typename T2::second_type *); 28 | template static std::false_type test_pair(...); 29 | 30 | static constexpr const bool is_comparable = std::is_same(nullptr))>::value; 31 | static constexpr const bool is_pair = std::is_same(nullptr, nullptr))>::value; 32 | static constexpr const bool is_vector = std::is_same(nullptr))>::value; 33 | static constexpr const bool is_element = !is_pair && !is_vector; 34 | }; 35 | 36 | /* Default: is_comparable -> std::false_type */ 37 | template 38 | struct is_comparable : std::false_type { }; 39 | 40 | /* For non-map data structures, check whether operator== can be instantiated */ 41 | template 42 | struct is_comparable< 43 | T, enable_if_t::is_element && 44 | container_traits::is_comparable>> 45 | : std::true_type { }; 46 | 47 | /* For a vector/map data structure, recursively check the value type (which is std::pair for maps) */ 48 | template 49 | struct is_comparable::is_vector>> { 50 | static constexpr const bool value = 51 | is_comparable::value; 52 | }; 53 | 54 | /* For pairs, recursively check the two data types */ 55 | template 56 | struct is_comparable::is_pair>> { 57 | static constexpr const bool value = 58 | is_comparable::value && 59 | is_comparable::value; 60 | }; 61 | 62 | /* Fallback functions */ 63 | template void vector_if_copy_constructible(const Args &...) { } 64 | template void vector_if_equal_operator(const Args &...) { } 65 | template void vector_if_insertion_operator(const Args &...) { } 66 | template void vector_modifiers(const Args &...) { } 67 | 68 | template 69 | void vector_if_copy_constructible(enable_if_t::value, Class_> &cl) { 70 | cl.def(init(), "Copy constructor"); 71 | } 72 | 73 | template 74 | void vector_if_equal_operator(enable_if_t::value, Class_> &cl) { 75 | using T = typename Vector::value_type; 76 | 77 | cl.def(self == self); 78 | cl.def(self != self); 79 | 80 | cl.def("count", 81 | [](const Vector &v, const T &x) { 82 | return std::count(v.begin(), v.end(), x); 83 | }, 84 | arg("x"), 85 | "Return the number of times ``x`` appears in the list" 86 | ); 87 | 88 | cl.def("remove", [](Vector &v, const T &x) { 89 | auto p = std::find(v.begin(), v.end(), x); 90 | if (p != v.end()) 91 | v.erase(p); 92 | else 93 | throw value_error(); 94 | }, 95 | arg("x"), 96 | "Remove the first item from the list whose value is x. " 97 | "It is an error if there is no such item." 98 | ); 99 | 100 | cl.def("__contains__", 101 | [](const Vector &v, const T &x) { 102 | return std::find(v.begin(), v.end(), x) != v.end(); 103 | }, 104 | arg("x"), 105 | "Return true the container contains ``x``" 106 | ); 107 | } 108 | 109 | // Vector modifiers -- requires a copyable vector_type: 110 | // (Technically, some of these (pop and __delitem__) don't actually require copyability, but it seems 111 | // silly to allow deletion but not insertion, so include them here too.) 112 | template 113 | void vector_modifiers(enable_if_t::value, Class_> &cl) { 114 | using T = typename Vector::value_type; 115 | using SizeType = typename Vector::size_type; 116 | using DiffType = typename Vector::difference_type; 117 | 118 | cl.def("append", 119 | [](Vector &v, const T &value) { v.push_back(value); }, 120 | arg("x"), 121 | "Add an item to the end of the list"); 122 | 123 | cl.def(init([](iterable it) { 124 | auto v = std::unique_ptr(new Vector()); 125 | v->reserve(len(it)); 126 | for (handle h : it) 127 | v->push_back(h.cast()); 128 | return v.release(); 129 | })); 130 | 131 | cl.def("extend", 132 | [](Vector &v, const Vector &src) { 133 | v.insert(v.end(), src.begin(), src.end()); 134 | }, 135 | arg("L"), 136 | "Extend the list by appending all the items in the given list" 137 | ); 138 | 139 | cl.def("insert", 140 | [](Vector &v, SizeType i, const T &x) { 141 | if (i > v.size()) 142 | throw index_error(); 143 | v.insert(v.begin() + (DiffType) i, x); 144 | }, 145 | arg("i") , arg("x"), 146 | "Insert an item at a given position." 147 | ); 148 | 149 | cl.def("pop", 150 | [](Vector &v) { 151 | if (v.empty()) 152 | throw index_error(); 153 | T t = v.back(); 154 | v.pop_back(); 155 | return t; 156 | }, 157 | "Remove and return the last item" 158 | ); 159 | 160 | cl.def("pop", 161 | [](Vector &v, SizeType i) { 162 | if (i >= v.size()) 163 | throw index_error(); 164 | T t = v[i]; 165 | v.erase(v.begin() + (DiffType) i); 166 | return t; 167 | }, 168 | arg("i"), 169 | "Remove and return the item at index ``i``" 170 | ); 171 | 172 | cl.def("__setitem__", 173 | [](Vector &v, SizeType i, const T &t) { 174 | if (i >= v.size()) 175 | throw index_error(); 176 | v[i] = t; 177 | } 178 | ); 179 | 180 | /// Slicing protocol 181 | cl.def("__getitem__", 182 | [](const Vector &v, slice slice) -> Vector * { 183 | size_t start, stop, step, slicelength; 184 | 185 | if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) 186 | throw error_already_set(); 187 | 188 | Vector *seq = new Vector(); 189 | seq->reserve((size_t) slicelength); 190 | 191 | for (size_t i=0; ipush_back(v[start]); 193 | start += step; 194 | } 195 | return seq; 196 | }, 197 | arg("s"), 198 | "Retrieve list elements using a slice object" 199 | ); 200 | 201 | cl.def("__setitem__", 202 | [](Vector &v, slice slice, const Vector &value) { 203 | size_t start, stop, step, slicelength; 204 | if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) 205 | throw error_already_set(); 206 | 207 | if (slicelength != value.size()) 208 | throw std::runtime_error("Left and right hand size of slice assignment have different sizes!"); 209 | 210 | for (size_t i=0; i= v.size()) 221 | throw index_error(); 222 | v.erase(v.begin() + DiffType(i)); 223 | }, 224 | "Delete the list elements at index ``i``" 225 | ); 226 | 227 | cl.def("__delitem__", 228 | [](Vector &v, slice slice) { 229 | size_t start, stop, step, slicelength; 230 | 231 | if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) 232 | throw error_already_set(); 233 | 234 | if (step == 1 && false) { 235 | v.erase(v.begin() + (DiffType) start, v.begin() + DiffType(start + slicelength)); 236 | } else { 237 | for (size_t i = 0; i < slicelength; ++i) { 238 | v.erase(v.begin() + DiffType(start)); 239 | start += step - 1; 240 | } 241 | } 242 | }, 243 | "Delete list elements using a slice object" 244 | ); 245 | 246 | } 247 | 248 | // If the type has an operator[] that doesn't return a reference (most notably std::vector), 249 | // we have to access by copying; otherwise we return by reference. 250 | template using vector_needs_copy = negation< 251 | std::is_same()[typename Vector::size_type()]), typename Vector::value_type &>>; 252 | 253 | // The usual case: access and iterate by reference 254 | template 255 | void vector_accessor(enable_if_t::value, Class_> &cl) { 256 | using T = typename Vector::value_type; 257 | using SizeType = typename Vector::size_type; 258 | using ItType = typename Vector::iterator; 259 | 260 | cl.def("__getitem__", 261 | [](Vector &v, SizeType i) -> T & { 262 | if (i >= v.size()) 263 | throw index_error(); 264 | return v[i]; 265 | }, 266 | return_value_policy::reference_internal // ref + keepalive 267 | ); 268 | 269 | cl.def("__iter__", 270 | [](Vector &v) { 271 | return make_iterator< 272 | return_value_policy::reference_internal, ItType, ItType, T&>( 273 | v.begin(), v.end()); 274 | }, 275 | keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ 276 | ); 277 | } 278 | 279 | // The case for special objects, like std::vector, that have to be returned-by-copy: 280 | template 281 | void vector_accessor(enable_if_t::value, Class_> &cl) { 282 | using T = typename Vector::value_type; 283 | using SizeType = typename Vector::size_type; 284 | using ItType = typename Vector::iterator; 285 | cl.def("__getitem__", 286 | [](const Vector &v, SizeType i) -> T { 287 | if (i >= v.size()) 288 | throw index_error(); 289 | return v[i]; 290 | } 291 | ); 292 | 293 | cl.def("__iter__", 294 | [](Vector &v) { 295 | return make_iterator< 296 | return_value_policy::copy, ItType, ItType, T>( 297 | v.begin(), v.end()); 298 | }, 299 | keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ 300 | ); 301 | } 302 | 303 | template auto vector_if_insertion_operator(Class_ &cl, std::string const &name) 304 | -> decltype(std::declval() << std::declval(), void()) { 305 | using size_type = typename Vector::size_type; 306 | 307 | cl.def("__repr__", 308 | [name](Vector &v) { 309 | std::ostringstream s; 310 | s << name << '['; 311 | for (size_type i=0; i < v.size(); ++i) { 312 | s << v[i]; 313 | if (i != v.size() - 1) 314 | s << ", "; 315 | } 316 | s << ']'; 317 | return s.str(); 318 | }, 319 | "Return the canonical string representation of this list." 320 | ); 321 | } 322 | 323 | // Provide the buffer interface for vectors if we have data() and we have a format for it 324 | // GCC seems to have "void std::vector::data()" - doing SFINAE on the existence of data() is insufficient, we need to check it returns an appropriate pointer 325 | template 326 | struct vector_has_data_and_format : std::false_type {}; 327 | template 328 | struct vector_has_data_and_format::format(), std::declval().data()), typename Vector::value_type*>::value>> : std::true_type {}; 329 | 330 | // Add the buffer interface to a vector 331 | template 332 | enable_if_t...>::value> 333 | vector_buffer(Class_& cl) { 334 | using T = typename Vector::value_type; 335 | 336 | static_assert(vector_has_data_and_format::value, "There is not an appropriate format descriptor for this vector"); 337 | 338 | // numpy.h declares this for arbitrary types, but it may raise an exception and crash hard at runtime if PYBIND11_NUMPY_DTYPE hasn't been called, so check here 339 | format_descriptor::format(); 340 | 341 | cl.def_buffer([](Vector& v) -> buffer_info { 342 | return buffer_info(v.data(), static_cast(sizeof(T)), format_descriptor::format(), 1, {v.size()}, {sizeof(T)}); 343 | }); 344 | 345 | cl.def(init([](buffer buf) { 346 | auto info = buf.request(); 347 | if (info.ndim != 1 || info.strides[0] % static_cast(sizeof(T))) 348 | throw type_error("Only valid 1D buffers can be copied to a vector"); 349 | if (!detail::compare_buffer_info::compare(info) || (ssize_t) sizeof(T) != info.itemsize) 350 | throw type_error("Format mismatch (Python: " + info.format + " C++: " + format_descriptor::format() + ")"); 351 | 352 | auto vec = std::unique_ptr(new Vector()); 353 | vec->reserve((size_t) info.shape[0]); 354 | T *p = static_cast(info.ptr); 355 | ssize_t step = info.strides[0] / static_cast(sizeof(T)); 356 | T *end = p + info.shape[0] * step; 357 | for (; p != end; p += step) 358 | vec->push_back(*p); 359 | return vec.release(); 360 | })); 361 | 362 | return; 363 | } 364 | 365 | template 366 | enable_if_t...>::value> vector_buffer(Class_&) {} 367 | 368 | NAMESPACE_END(detail) 369 | 370 | // 371 | // std::vector 372 | // 373 | template , typename... Args> 374 | class_ bind_vector(handle scope, std::string const &name, Args&&... args) { 375 | using Class_ = class_; 376 | 377 | // If the value_type is unregistered (e.g. a converting type) or is itself registered 378 | // module-local then make the vector binding module-local as well: 379 | using vtype = typename Vector::value_type; 380 | auto vtype_info = detail::get_type_info(typeid(vtype)); 381 | bool local = !vtype_info || vtype_info->module_local; 382 | 383 | Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward(args)...); 384 | 385 | // Declare the buffer interface if a buffer_protocol() is passed in 386 | detail::vector_buffer(cl); 387 | 388 | cl.def(init<>()); 389 | 390 | // Register copy constructor (if possible) 391 | detail::vector_if_copy_constructible(cl); 392 | 393 | // Register comparison-related operators and functions (if possible) 394 | detail::vector_if_equal_operator(cl); 395 | 396 | // Register stream insertion operator (if possible) 397 | detail::vector_if_insertion_operator(cl, name); 398 | 399 | // Modifiers require copyable vector value type 400 | detail::vector_modifiers(cl); 401 | 402 | // Accessor and iterator; return by value if copyable, otherwise we return by ref + keep-alive 403 | detail::vector_accessor(cl); 404 | 405 | cl.def("__bool__", 406 | [](const Vector &v) -> bool { 407 | return !v.empty(); 408 | }, 409 | "Check whether the list is nonempty" 410 | ); 411 | 412 | cl.def("__len__", &Vector::size); 413 | 414 | 415 | 416 | 417 | #if 0 418 | // C++ style functions deprecated, leaving it here as an example 419 | cl.def(init()); 420 | 421 | cl.def("resize", 422 | (void (Vector::*) (size_type count)) & Vector::resize, 423 | "changes the number of elements stored"); 424 | 425 | cl.def("erase", 426 | [](Vector &v, SizeType i) { 427 | if (i >= v.size()) 428 | throw index_error(); 429 | v.erase(v.begin() + i); 430 | }, "erases element at index ``i``"); 431 | 432 | cl.def("empty", &Vector::empty, "checks whether the container is empty"); 433 | cl.def("size", &Vector::size, "returns the number of elements"); 434 | cl.def("push_back", (void (Vector::*)(const T&)) &Vector::push_back, "adds an element to the end"); 435 | cl.def("pop_back", &Vector::pop_back, "removes the last element"); 436 | 437 | cl.def("max_size", &Vector::max_size, "returns the maximum possible number of elements"); 438 | cl.def("reserve", &Vector::reserve, "reserves storage"); 439 | cl.def("capacity", &Vector::capacity, "returns the number of elements that can be held in currently allocated storage"); 440 | cl.def("shrink_to_fit", &Vector::shrink_to_fit, "reduces memory usage by freeing unused memory"); 441 | 442 | cl.def("clear", &Vector::clear, "clears the contents"); 443 | cl.def("swap", &Vector::swap, "swaps the contents"); 444 | 445 | cl.def("front", [](Vector &v) { 446 | if (v.size()) return v.front(); 447 | else throw index_error(); 448 | }, "access the first element"); 449 | 450 | cl.def("back", [](Vector &v) { 451 | if (v.size()) return v.back(); 452 | else throw index_error(); 453 | }, "access the last element "); 454 | 455 | #endif 456 | 457 | return cl; 458 | } 459 | 460 | 461 | 462 | // 463 | // std::map, std::unordered_map 464 | // 465 | 466 | NAMESPACE_BEGIN(detail) 467 | 468 | /* Fallback functions */ 469 | template void map_if_insertion_operator(const Args &...) { } 470 | template void map_assignment(const Args &...) { } 471 | 472 | // Map assignment when copy-assignable: just copy the value 473 | template 474 | void map_assignment(enable_if_t::value, Class_> &cl) { 475 | using KeyType = typename Map::key_type; 476 | using MappedType = typename Map::mapped_type; 477 | 478 | cl.def("__setitem__", 479 | [](Map &m, const KeyType &k, const MappedType &v) { 480 | auto it = m.find(k); 481 | if (it != m.end()) it->second = v; 482 | else m.emplace(k, v); 483 | } 484 | ); 485 | } 486 | 487 | // Not copy-assignable, but still copy-constructible: we can update the value by erasing and reinserting 488 | template 489 | void map_assignment(enable_if_t< 490 | !std::is_copy_assignable::value && 491 | is_copy_constructible::value, 492 | Class_> &cl) { 493 | using KeyType = typename Map::key_type; 494 | using MappedType = typename Map::mapped_type; 495 | 496 | cl.def("__setitem__", 497 | [](Map &m, const KeyType &k, const MappedType &v) { 498 | // We can't use m[k] = v; because value type might not be default constructable 499 | auto r = m.emplace(k, v); 500 | if (!r.second) { 501 | // value type is not copy assignable so the only way to insert it is to erase it first... 502 | m.erase(r.first); 503 | m.emplace(k, v); 504 | } 505 | } 506 | ); 507 | } 508 | 509 | 510 | template auto map_if_insertion_operator(Class_ &cl, std::string const &name) 511 | -> decltype(std::declval() << std::declval() << std::declval(), void()) { 512 | 513 | cl.def("__repr__", 514 | [name](Map &m) { 515 | std::ostringstream s; 516 | s << name << '{'; 517 | bool f = false; 518 | for (auto const &kv : m) { 519 | if (f) 520 | s << ", "; 521 | s << kv.first << ": " << kv.second; 522 | f = true; 523 | } 524 | s << '}'; 525 | return s.str(); 526 | }, 527 | "Return the canonical string representation of this map." 528 | ); 529 | } 530 | 531 | 532 | NAMESPACE_END(detail) 533 | 534 | template , typename... Args> 535 | class_ bind_map(handle scope, const std::string &name, Args&&... args) { 536 | using KeyType = typename Map::key_type; 537 | using MappedType = typename Map::mapped_type; 538 | using Class_ = class_; 539 | 540 | // If either type is a non-module-local bound type then make the map binding non-local as well; 541 | // otherwise (e.g. both types are either module-local or converting) the map will be 542 | // module-local. 543 | auto tinfo = detail::get_type_info(typeid(MappedType)); 544 | bool local = !tinfo || tinfo->module_local; 545 | if (local) { 546 | tinfo = detail::get_type_info(typeid(KeyType)); 547 | local = !tinfo || tinfo->module_local; 548 | } 549 | 550 | Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward(args)...); 551 | 552 | cl.def(init<>()); 553 | 554 | // Register stream insertion operator (if possible) 555 | detail::map_if_insertion_operator(cl, name); 556 | 557 | cl.def("__bool__", 558 | [](const Map &m) -> bool { return !m.empty(); }, 559 | "Check whether the map is nonempty" 560 | ); 561 | 562 | cl.def("__iter__", 563 | [](Map &m) { return make_key_iterator(m.begin(), m.end()); }, 564 | keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ 565 | ); 566 | 567 | cl.def("items", 568 | [](Map &m) { return make_iterator(m.begin(), m.end()); }, 569 | keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ 570 | ); 571 | 572 | cl.def("__getitem__", 573 | [](Map &m, const KeyType &k) -> MappedType & { 574 | auto it = m.find(k); 575 | if (it == m.end()) 576 | throw key_error(); 577 | return it->second; 578 | }, 579 | return_value_policy::reference_internal // ref + keepalive 580 | ); 581 | 582 | // Assignment provided only if the type is copyable 583 | detail::map_assignment(cl); 584 | 585 | cl.def("__delitem__", 586 | [](Map &m, const KeyType &k) { 587 | auto it = m.find(k); 588 | if (it == m.end()) 589 | throw key_error(); 590 | m.erase(it); 591 | } 592 | ); 593 | 594 | cl.def("__len__", &Map::size); 595 | 596 | return cl; 597 | } 598 | 599 | NAMESPACE_END(PYBIND11_NAMESPACE) 600 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = setup.rst 3 | license_file = LICENSE 4 | 5 | [flake8] 6 | max-line-length = 80 7 | show_source = True 8 | exclude = .git, __pycache__, build, dist, docs, tools, venv, docs/conf.py 9 | ignore = E111 E114 F821 10 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import absolute_import 16 | from __future__ import division 17 | from __future__ import print_function 18 | 19 | import distutils 20 | import os 21 | import sys 22 | 23 | import setuptools 24 | from setuptools.command import build_ext 25 | 26 | DEFAULT_CODE = 'int add(int x, int y) { return x + y; }' 27 | 28 | 29 | def get_readme(): 30 | with open('setup.rst') as f: 31 | return f.read() 32 | 33 | 34 | def get_system_flags(name): 35 | # TODO(jart): Take quoting into consideration. 36 | value = distutils.sysconfig.get_config_var(name) 37 | return frozenset(value.split()) if value else frozenset() 38 | 39 | 40 | def apply_flags(result, system, flags): 41 | copy = result[:] 42 | del result[:] 43 | known = set() 44 | known.update(result) 45 | known.update(system) 46 | for flag in flags: 47 | if flag not in known: 48 | result.append(flag) 49 | known.add(flag) 50 | result.extend(copy) # so Extension() can say -Os if we say -O3 51 | 52 | 53 | class CcFlags(object): 54 | def __init__(self, compiler, language, system_copts, system_ldflags, tmp): 55 | self.compiler = compiler 56 | self.language = language 57 | self.system_copts = system_copts 58 | self.system_ldflags = system_ldflags 59 | self.tmp = tmp 60 | self.copts = [] 61 | self.ldflags = [] 62 | 63 | def add_if_supported(self, description='', copts=(), ldflags=(), 64 | code=DEFAULT_CODE): 65 | if not (set(copts) - self.system_copts or 66 | set(ldflags) - self.system_ldflags): 67 | return True # no need to check; already in system defaults 68 | if not description: 69 | description = ' '.join(sorted(set(tuple(copts) + tuple(ldflags)))) 70 | distutils.log.info('checking %s flags %s', self.language, description) 71 | if not self._check_flags(copts, ldflags, code): 72 | distutils.log.info('no') 73 | distutils.log.info('') 74 | return False 75 | self.copts.extend(copts) 76 | self.ldflags.extend(ldflags) 77 | distutils.log.info('yes') 78 | distutils.log.info('') 79 | return True 80 | 81 | def apply(self, ext): 82 | if (ext.language == self.language or 83 | (ext.language == 'c++' and self.language == 'c')): 84 | apply_flags(ext.extra_compile_args, self.system_copts, self.copts) 85 | apply_flags(ext.extra_link_args, self.system_ldflags, self.ldflags) 86 | 87 | def _check_flags(self, copts, ldflags, code): 88 | try: 89 | suffix = '.cc' if self.language == 'c++' else '.c' 90 | with open(os.path.join(self.tmp, 'add' + suffix), 'w') as f: 91 | f.write(code) 92 | f.flush() 93 | objs = self.compiler.compile(sources=[f.name], 94 | extra_postargs=list(copts)) 95 | if ldflags: 96 | self.compiler.link_shared_lib(objects=objs, 97 | output_dir=self.tmp, 98 | output_libname='bin', 99 | extra_postargs=list(ldflags)) 100 | return True 101 | except (setuptools.distutils.errors.CompileError, 102 | setuptools.distutils.errors.LinkError): 103 | return False 104 | 105 | 106 | class BuildExt(build_ext.build_ext): 107 | def build_extensions(self): 108 | distutils.log.info('--------------------') 109 | distutils.log.info('autoconf tensorstore') 110 | distutils.log.info('--------------------') 111 | 112 | tmp = os.path.join('build', 'tmp') 113 | os.makedirs(tmp) 114 | 115 | system_cflags = get_system_flags('CFLAGS') 116 | system_cxxflags = get_system_flags('CXXFLAGS') 117 | system_cppflags = get_system_flags('CPPFLAGS') 118 | system_ldflags = get_system_flags('LDFLAGS') 119 | cflags = CcFlags(self.compiler, 'c', 120 | system_cflags | system_cppflags, 121 | system_ldflags, 122 | tmp) 123 | cxxflags = CcFlags(self.compiler, 'c++', 124 | system_cflags | system_cxxflags | system_cppflags, 125 | system_ldflags, 126 | tmp) 127 | 128 | if self.compiler.compiler_type == 'msvc': 129 | cxxflags.copts += [ 130 | '/DVERSION_INFO=\\"%s\\"' % self.distribution.get_version(), 131 | '/EHsc', # allow c++ to have exceptions but not c 132 | ] 133 | 134 | else: # unix, gnu, mingw32, etc. 135 | cflags.copts += ['-DVERSION_INFO="%s"' % self.distribution.get_version()] 136 | if sys.platform == 'darwin': 137 | cflags.add_if_supported(copts=['-mmacosx-version-min=10.7']) 138 | cxxflags.add_if_supported(copts=['-stdlib=libc++']) 139 | 140 | # pybind11 needs c++11 but has smaller footprint with c++14 141 | if not cxxflags.add_if_supported( 142 | copts=['-std=c++14'], 143 | code=''' 144 | // Old Ubuntu14 + Clang5 results in enable_if_t error. 145 | // Possibly due to old version of libstdc++ but new clang. 146 | #include 147 | template 148 | T dubs(std::enable_if_t::value, T> t) { 149 | return t * 2; 150 | } 151 | int double_add_and(int x, int y) { 152 | return dubs(x) + dubs(y); 153 | } 154 | '''): 155 | if not cxxflags.add_if_supported(copts=['-std=c++11']): 156 | raise RuntimeError('Need compiler with C++11 support') 157 | 158 | # symbols hidden by default matters with pybind11 159 | if cflags.add_if_supported(copts=['-fvisibility=hidden']): 160 | cxxflags.add_if_supported(copts=['-fvisibility-inlines-hidden']) 161 | 162 | # there shall be no lulz with tensorstore 163 | cflags.add_if_supported(copts=['-D_FORTIFY_SOURCE=2']) 164 | cflags.add_if_supported(ldflags=['-Wl,-z,relro,-z,now']) 165 | if not cflags.add_if_supported(copts=['-fstack-protector-strong']): 166 | cflags.add_if_supported(copts=['-fstack-protector']) 167 | 168 | # avoid dll hell on gnu/windows 169 | if self.compiler.compiler_type in ('mingw32', 'cygwin'): 170 | cflags.add_if_supported(ldflags=['-static-libgcc']) 171 | cxxflags.add_if_supported(ldflags=['-static-libstdc++']) 172 | 173 | distutils.log.info('-------------------') 174 | distutils.log.info('compile tensorstore') 175 | distutils.log.info('-------------------') 176 | 177 | for ext in self.extensions: 178 | cflags.apply(ext) 179 | cxxflags.apply(ext) 180 | build_ext.build_ext.build_extensions(self) 181 | 182 | 183 | setuptools.setup( 184 | name='tensorstore', 185 | version='0.0.1a1', 186 | description='TensorStore stores tensors', 187 | long_description=get_readme(), 188 | url='https://github.com/tensorflow/tensorstore', 189 | author='Justine Tunney', 190 | author_email='jart@google.com', 191 | license='Apache 2.0, BSD-3', 192 | keywords='tensor sql', 193 | platforms='any', 194 | ext_modules=[ 195 | 196 | setuptools.Extension( 197 | name='tensorstore', 198 | language='c++', 199 | sources=['tensorstore.cc'], 200 | include_dirs=['.'], 201 | ), 202 | 203 | ], 204 | classifiers=[ 205 | 'Development Status :: 1 - Planning', 206 | 'Intended Audience :: Developers', 207 | 'Intended Audience :: Science/Research', 208 | 'License :: OSI Approved :: Apache Software License', # TensorStore 209 | 'License :: OSI Approved :: BSD License' # PyBind11 210 | 'License :: OSI Approved', 211 | 'Operating System :: Android', 212 | 'Operating System :: MacOS', 213 | 'Operating System :: Microsoft :: Windows', 214 | 'Operating System :: POSIX', 215 | 'Operating System :: iOS', 216 | 'Programming Language :: C', 217 | 'Programming Language :: C++', 218 | 'Programming Language :: Python :: 2.7', 219 | 'Programming Language :: Python :: 3.4', 220 | 'Programming Language :: Python :: 3.5', 221 | 'Programming Language :: Python :: 3.6', 222 | 'Programming Language :: SQL', 223 | 'Topic :: Database :: Database Engines/Servers', 224 | 'Topic :: Database', 225 | 'Topic :: Scientific/Engineering :: Mathematics', 226 | 'Topic :: Software Development :: Libraries :: Application Frameworks', 227 | 'Topic :: Software Development :: Libraries', 228 | ], 229 | cmdclass={'build_ext': BuildExt}, 230 | zip_safe=False, 231 | ) 232 | -------------------------------------------------------------------------------- /setup.rst: -------------------------------------------------------------------------------- 1 | TensorStore is a placeholder for TensorBoard storage code. 2 | 3 | This is not an official Google product. 4 | -------------------------------------------------------------------------------- /tensorstore.cc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int add(int i, int j) { 4 | return i + j; 5 | } 6 | 7 | namespace py = pybind11; 8 | 9 | PYBIND11_MODULE(tensorstore, m) { 10 | m.doc() = R"pbdoc( 11 | tensorstore 12 | ----------- 13 | 14 | .. currentmodule:: tensorstore 15 | 16 | .. autosummary:: 17 | :toctree: _generate 18 | 19 | add 20 | subtract 21 | )pbdoc"; 22 | 23 | m.attr("__version__") = VERSION_INFO; 24 | 25 | m.def("add", &add, R"pbdoc( 26 | Add two numbers 27 | 28 | Some other explanation about the add function. 29 | )pbdoc"); 30 | 31 | m.def("subtract", [](int i, int j) { return i - j; }, R"pbdoc( 32 | Subtract two numbers 33 | 34 | Some other explanation about the subtract function. 35 | )pbdoc"); 36 | } 37 | --------------------------------------------------------------------------------