mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-23 05:35:13 +00:00
Merge branch 'pybind:master' into master
This commit is contained in:
commit
aa4a9ff4d2
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
docs/*.svg binary
|
32
.github/matchers/pylint.json
vendored
Normal file
32
.github/matchers/pylint.json
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"problemMatcher": [
|
||||
{
|
||||
"severity": "warning",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^([^:]+):(\\d+):(\\d+): ([A-DF-Z]\\d+): \\033\\[[\\d;]+m([^\\033]+).*$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"code": 4,
|
||||
"message": 5
|
||||
}
|
||||
],
|
||||
"owner": "pylint-warning"
|
||||
},
|
||||
{
|
||||
"severity": "error",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^([^:]+):(\\d+):(\\d+): (E\\d+): \\033\\[[\\d;]+m([^\\033]+).*$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"code": 4,
|
||||
"message": 5
|
||||
}
|
||||
],
|
||||
"owner": "pylint-error"
|
||||
}
|
||||
]
|
||||
}
|
5
.github/workflows/format.yml
vendored
5
.github/workflows/format.yml
vendored
@ -12,6 +12,9 @@ on:
|
||||
- stable
|
||||
- "v*"
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 3
|
||||
|
||||
jobs:
|
||||
pre-commit:
|
||||
name: Format
|
||||
@ -19,6 +22,8 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- name: Add matchers
|
||||
run: echo "::add-matcher::$GITHUB_WORKSPACE/.github/matchers/pylint.json"
|
||||
- uses: pre-commit/action@v2.0.3
|
||||
with:
|
||||
# Slow hooks are marked with manual - slow is okay here, run them too
|
||||
|
@ -59,7 +59,7 @@ repos:
|
||||
|
||||
# Changes tabs to spaces
|
||||
- repo: https://github.com/Lucas-C/pre-commit-hooks
|
||||
rev: "v1.1.11"
|
||||
rev: "v1.1.12"
|
||||
hooks:
|
||||
- id: remove-tabs
|
||||
|
||||
@ -87,23 +87,30 @@ repos:
|
||||
- id: rst-directive-colons
|
||||
- id: rst-inline-touching-normal
|
||||
|
||||
# Flake8 also supports pre-commit natively (same author)
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: "4.0.1"
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies: &flake8_dependencies
|
||||
- flake8-bugbear
|
||||
- pep8-naming
|
||||
exclude: ^(docs/.*|tools/.*)$
|
||||
|
||||
# Automatically remove noqa that are not used
|
||||
- repo: https://github.com/asottile/yesqa
|
||||
rev: "v1.3.0"
|
||||
hooks:
|
||||
- id: yesqa
|
||||
additional_dependencies: &flake8_dependencies
|
||||
- flake8-bugbear
|
||||
- pep8-naming
|
||||
|
||||
# Flake8 also supports pre-commit natively (same author)
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: "4.0.1"
|
||||
hooks:
|
||||
- id: flake8
|
||||
exclude: ^(docs/.*|tools/.*)$
|
||||
additional_dependencies: *flake8_dependencies
|
||||
|
||||
# PyLint has native support - not always usable, but works for us
|
||||
- repo: https://github.com/PyCQA/pylint
|
||||
rev: "v2.12.2"
|
||||
hooks:
|
||||
- id: pylint
|
||||
files: ^pybind11
|
||||
|
||||
# CMake formatting
|
||||
- repo: https://github.com/cheshirekow/cmake-format-precommit
|
||||
rev: "v0.6.13"
|
||||
|
@ -1,8 +1,13 @@
|
||||
import os
|
||||
|
||||
import nox
|
||||
|
||||
nox.options.sessions = ["lint", "tests", "tests_packaging"]
|
||||
|
||||
PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"]
|
||||
PYTHON_VERISONS = ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "pypy3.7", "pypy3.8"]
|
||||
|
||||
if os.environ.get("CI", None):
|
||||
nox.options.error_on_missing_interpreters = True
|
||||
|
||||
|
||||
@nox.session(reuse_venv=True)
|
||||
@ -14,7 +19,7 @@ def lint(session: nox.Session) -> None:
|
||||
session.run("pre-commit", "run", "-a")
|
||||
|
||||
|
||||
@nox.session(python=PYTHON_VERSIONS)
|
||||
@nox.session(python=PYTHON_VERISONS)
|
||||
def tests(session: nox.Session) -> None:
|
||||
"""
|
||||
Run the tests (requires a compiler).
|
||||
|
@ -1,3 +1,5 @@
|
||||
# pylint: disable=missing-function-docstring
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import sysconfig
|
||||
|
@ -3,16 +3,23 @@ import os
|
||||
DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
def get_include(user: bool = False) -> str:
|
||||
def get_include(user: bool = False) -> str: # pylint: disable=unused-argument
|
||||
"""
|
||||
Return the path to the pybind11 include directory. The historical "user"
|
||||
argument is unused, and may be removed.
|
||||
"""
|
||||
installed_path = os.path.join(DIR, "include")
|
||||
source_path = os.path.join(os.path.dirname(DIR), "include")
|
||||
return installed_path if os.path.exists(installed_path) else source_path
|
||||
|
||||
|
||||
def get_cmake_dir() -> str:
|
||||
"""
|
||||
Return the path to the pybind11 CMake module directory.
|
||||
"""
|
||||
cmake_installed_path = os.path.join(DIR, "share", "cmake", "pybind11")
|
||||
if os.path.exists(cmake_installed_path):
|
||||
return cmake_installed_path
|
||||
else:
|
||||
msg = "pybind11 not installed, installation required to access the CMake files"
|
||||
raise ImportError(msg)
|
||||
|
||||
msg = "pybind11 not installed, installation required to access the CMake files"
|
||||
raise ImportError(msg)
|
||||
|
@ -239,7 +239,7 @@ def has_flag(compiler: Any, flag: str) -> bool:
|
||||
with tmp_chdir():
|
||||
fname = Path("flagcheck.cpp")
|
||||
# Don't trigger -Wunused-parameter.
|
||||
fname.write_text("int main (int, char **) { return 0; }")
|
||||
fname.write_text("int main (int, char **) { return 0; }", encoding="utf-8")
|
||||
|
||||
try:
|
||||
compiler.compile([str(fname)], extra_postargs=[flag])
|
||||
@ -303,29 +303,31 @@ def intree_extensions(
|
||||
"""
|
||||
exts = []
|
||||
|
||||
for path in paths:
|
||||
if package_dir is None:
|
||||
if package_dir is None:
|
||||
for path in paths:
|
||||
parent, _ = os.path.split(path)
|
||||
while os.path.exists(os.path.join(parent, "__init__.py")):
|
||||
parent, _ = os.path.split(parent)
|
||||
relname, _ = os.path.splitext(os.path.relpath(path, parent))
|
||||
qualified_name = relname.replace(os.path.sep, ".")
|
||||
exts.append(Pybind11Extension(qualified_name, [path]))
|
||||
else:
|
||||
for prefix, parent in package_dir.items():
|
||||
if path.startswith(parent):
|
||||
relname, _ = os.path.splitext(os.path.relpath(path, parent))
|
||||
qualified_name = relname.replace(os.path.sep, ".")
|
||||
if prefix:
|
||||
qualified_name = prefix + "." + qualified_name
|
||||
exts.append(Pybind11Extension(qualified_name, [path]))
|
||||
return exts
|
||||
|
||||
if not exts:
|
||||
msg = (
|
||||
f"path {path} is not a child of any of the directories listed "
|
||||
f"in 'package_dir' ({package_dir})"
|
||||
)
|
||||
raise ValueError(msg)
|
||||
for path in paths:
|
||||
for prefix, parent in package_dir.items():
|
||||
if path.startswith(parent):
|
||||
relname, _ = os.path.splitext(os.path.relpath(path, parent))
|
||||
qualified_name = relname.replace(os.path.sep, ".")
|
||||
if prefix:
|
||||
qualified_name = prefix + "." + qualified_name
|
||||
exts.append(Pybind11Extension(qualified_name, [path]))
|
||||
break
|
||||
else:
|
||||
msg = (
|
||||
f"path {path} is not a child of any of the directories listed "
|
||||
f"in 'package_dir' ({package_dir})"
|
||||
)
|
||||
raise ValueError(msg)
|
||||
|
||||
return exts
|
||||
|
||||
@ -339,7 +341,7 @@ def naive_recompile(obj: str, src: str) -> bool:
|
||||
return os.stat(obj).st_mtime < os.stat(src).st_mtime
|
||||
|
||||
|
||||
def no_recompile(obg: str, src: str) -> bool:
|
||||
def no_recompile(obg: str, src: str) -> bool: # pylint: disable=unused-argument
|
||||
"""
|
||||
This is the safest but slowest choice (and is the default) - will always
|
||||
recompile sources.
|
||||
@ -412,7 +414,7 @@ class ParallelCompile:
|
||||
self,
|
||||
envvar: Optional[str] = None,
|
||||
default: int = 0,
|
||||
max: int = 0,
|
||||
max: int = 0, # pylint: disable=redefined-builtin
|
||||
needs_recompile: Callable[[str, str], bool] = no_recompile,
|
||||
) -> None:
|
||||
self.envvar = envvar
|
||||
@ -488,6 +490,9 @@ class ParallelCompile:
|
||||
return compile_function
|
||||
|
||||
def install(self: S) -> S:
|
||||
"""
|
||||
Installs the compile function into distutils.ccompiler.CCompiler.compile.
|
||||
"""
|
||||
distutils.ccompiler.CCompiler.compile = self.function() # type: ignore[assignment]
|
||||
return self
|
||||
|
||||
|
@ -30,3 +30,30 @@ strict = true
|
||||
[[tool.mypy.overrides]]
|
||||
module = ["ghapi.*", "setuptools.*"]
|
||||
ignore_missing_imports = true
|
||||
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
minversion = "6.0"
|
||||
addopts = ["-ra", "--showlocals", "--strict-markers", "--strict-config"]
|
||||
xfail_strict = true
|
||||
filterwarnings = ["error"]
|
||||
log_cli_level = "info"
|
||||
testpaths = [
|
||||
"tests",
|
||||
]
|
||||
timeout=300
|
||||
|
||||
|
||||
[tool.pylint]
|
||||
master.py-version = "3.6"
|
||||
reports.output-format = "colorized"
|
||||
messages_control.disable = [
|
||||
"design",
|
||||
"fixme",
|
||||
"imports",
|
||||
"line-too-long",
|
||||
"imports",
|
||||
"invalid-name",
|
||||
"protected-access",
|
||||
"missing-module-docstring",
|
||||
]
|
||||
|
@ -1,4 +1,3 @@
|
||||
// clang-format off
|
||||
/*
|
||||
tests/test_pickling.cpp -- pickle support
|
||||
|
||||
@ -11,8 +10,6 @@
|
||||
|
||||
#include "pybind11_tests.h"
|
||||
|
||||
// clang-format on
|
||||
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
@ -63,19 +60,18 @@ void wrap(py::module m) {
|
||||
|
||||
} // namespace exercise_trampoline
|
||||
|
||||
// clang-format off
|
||||
|
||||
TEST_SUBMODULE(pickling, m) {
|
||||
// test_roundtrip
|
||||
class Pickleable {
|
||||
public:
|
||||
explicit Pickleable(const std::string &value) : m_value(value) { }
|
||||
explicit Pickleable(const std::string &value) : m_value(value) {}
|
||||
const std::string &value() const { return m_value; }
|
||||
|
||||
void setExtra1(int extra1) { m_extra1 = extra1; }
|
||||
void setExtra2(int extra2) { m_extra2 = extra2; }
|
||||
int extra1() const { return m_extra1; }
|
||||
int extra2() const { return m_extra2; }
|
||||
|
||||
private:
|
||||
std::string m_value;
|
||||
int m_extra1 = 0;
|
||||
@ -88,8 +84,7 @@ TEST_SUBMODULE(pickling, m) {
|
||||
};
|
||||
|
||||
py::class_<Pickleable> pyPickleable(m, "Pickleable");
|
||||
pyPickleable
|
||||
.def(py::init<std::string>())
|
||||
pyPickleable.def(py::init<std::string>())
|
||||
.def("value", &Pickleable::value)
|
||||
.def("extra1", &Pickleable::extra1)
|
||||
.def("extra2", &Pickleable::extra2)
|
||||
@ -105,7 +100,7 @@ TEST_SUBMODULE(pickling, m) {
|
||||
pyPickleable.def("__setstate__", [](Pickleable &p, const py::tuple &t) {
|
||||
if (t.size() != 3) {
|
||||
throw std::runtime_error("Invalid state!");
|
||||
}
|
||||
}
|
||||
/* Invoke the constructor (need to use in-place version) */
|
||||
new (&p) Pickleable(t[0].cast<std::string>());
|
||||
|
||||
@ -124,7 +119,7 @@ TEST_SUBMODULE(pickling, m) {
|
||||
[](const py::tuple &t) {
|
||||
if (t.size() != 3) {
|
||||
throw std::runtime_error("Invalid state!");
|
||||
}
|
||||
}
|
||||
auto p = PickleableNew(t[0].cast<std::string>());
|
||||
|
||||
p.setExtra1(t[1].cast<int>());
|
||||
@ -136,7 +131,7 @@ TEST_SUBMODULE(pickling, m) {
|
||||
// test_roundtrip_with_dict
|
||||
class PickleableWithDict {
|
||||
public:
|
||||
explicit PickleableWithDict(const std::string &value) : value(value) { }
|
||||
explicit PickleableWithDict(const std::string &value) : value(value) {}
|
||||
|
||||
std::string value;
|
||||
int extra;
|
||||
@ -147,7 +142,8 @@ TEST_SUBMODULE(pickling, m) {
|
||||
using PickleableWithDict::PickleableWithDict;
|
||||
};
|
||||
|
||||
py::class_<PickleableWithDict> pyPickleableWithDict(m, "PickleableWithDict", py::dynamic_attr());
|
||||
py::class_<PickleableWithDict> pyPickleableWithDict(
|
||||
m, "PickleableWithDict", py::dynamic_attr());
|
||||
pyPickleableWithDict.def(py::init<std::string>())
|
||||
.def_readwrite("value", &PickleableWithDict::value)
|
||||
.def_readwrite("extra", &PickleableWithDict::extra)
|
||||
@ -159,7 +155,7 @@ TEST_SUBMODULE(pickling, m) {
|
||||
pyPickleableWithDict.def("__setstate__", [](const py::object &self, const py::tuple &t) {
|
||||
if (t.size() != 3) {
|
||||
throw std::runtime_error("Invalid state!");
|
||||
}
|
||||
}
|
||||
/* Cast and construct */
|
||||
auto &p = self.cast<PickleableWithDict &>();
|
||||
new (&p) PickleableWithDict(t[0].cast<std::string>());
|
||||
@ -176,12 +172,13 @@ TEST_SUBMODULE(pickling, m) {
|
||||
.def(py::init<std::string>())
|
||||
.def(py::pickle(
|
||||
[](const py::object &self) {
|
||||
return py::make_tuple(self.attr("value"), self.attr("extra"), self.attr("__dict__"));
|
||||
return py::make_tuple(
|
||||
self.attr("value"), self.attr("extra"), self.attr("__dict__"));
|
||||
},
|
||||
[](const py::tuple &t) {
|
||||
if (t.size() != 3) {
|
||||
throw std::runtime_error("Invalid state!");
|
||||
}
|
||||
}
|
||||
|
||||
auto cpp_state = PickleableWithDictNew(t[0].cast<std::string>());
|
||||
cpp_state.extra = t[1].cast<int>();
|
||||
|
Loading…
Reference in New Issue
Block a user