Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FormatStyle: file

Checks: '
llvm-namespace-comment,
modernize-use-override,
readability-container-size-empty,
modernize-use-using,
modernize-use-equals-default,
modernize-use-auto,
modernize-use-emplace,
'

HeaderFilterRegex: 'pybind11/.*h'
25 changes: 24 additions & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,30 @@ name, pre-commit):
pre-commit install
```

### Clang-Tidy

To run Clang tidy, the following recipe should work. Files will be modified in
place, so you can use git to monitor the changes.

```bash
docker run --rm -v $PWD:/pybind11 -it silkeh/clang:10
apt-get update && apt-get install python3-dev python3-pytest
cmake -S pybind11/ -B build -DCMAKE_CXX_CLANG_TIDY="$(which clang-tidy);-fix"
cmake --build build
```

### Include what you use

To run include what you use, install (`brew install include-what-you-use` on
macOS), then run:

```bash
cmake -S . -B build-iwyu -DCMAKE_CXX_INCLUDE_WHAT_YOU_USE=$(which include-what-you-use)
cmake --build build
```

The report is sent to stderr; you can pip it into a file if you wish.

### Build recipes

This builds with the Intel compiler (assuming it is in your path, along with a
Expand All @@ -186,7 +210,6 @@ cmake -S pybind11/ -B build
cmake --build build
```


[pre-commit]: https://pre-commit.com
[pybind11.readthedocs.org]: http://pybind11.readthedocs.org/en/latest
[issue tracker]: https://github.com/pybind/pybind11/issues
Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,19 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: pre-commit/[email protected]

clang-tidy:
name: Clang-Tidy
runs-on: ubuntu-latest
container: silkeh/clang:10
steps:
- uses: actions/checkout@v2

- name: Install requirements
run: apt-get update && apt-get install -y python3-dev python3-pytest

- name: Configure
run: cmake -S . -B build -DCMAKE_CXX_CLANG_TIDY="$(which clang-tidy);--warnings-as-errors=*"

- name: Build
run: cmake --build build -j 2
5 changes: 3 additions & 2 deletions include/pybind11/attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ struct sibling { handle value; sibling(const handle &value) : value(value.ptr())

/// Annotation indicating that a class derives from another given type
template <typename T> struct base {

PYBIND11_DEPRECATED("base<T>() was deprecated in favor of specifying 'T' as a template argument to class_")
base() { }
base() { } // NOLINT(modernize-use-equals-default): breaks MSVC 2015 when adding an attribute
};

/// Keep patient alive while nurse lives
Expand All @@ -61,7 +62,7 @@ struct metaclass {
handle value;

PYBIND11_DEPRECATED("py::metaclass() is no longer required. It's turned on by default now.")
metaclass() {}
metaclass() { } // NOLINT(modernize-use-equals-default): breaks MSVC 2015 when adding an attribute

/// Override pybind11's default metaclass
explicit metaclass(handle value) : value(value) { }
Expand Down
2 changes: 1 addition & 1 deletion include/pybind11/buffer_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct buffer_info {
std::vector<ssize_t> strides; // Number of bytes between adjacent entries (for each per dimension)
bool readonly = false; // flag to indicate if the underlying storage may be written to

buffer_info() { }
buffer_info() = default;

buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim,
detail::any_container<ssize_t> shape_in, detail::any_container<ssize_t> strides_in, bool readonly=false)
Expand Down
16 changes: 8 additions & 8 deletions include/pybind11/cast.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class loader_life_support {
Py_CLEAR(ptr);

// A heuristic to reduce the stack's capacity (e.g. after long recursive calls)
if (stack.capacity() > 16 && stack.size() != 0 && stack.capacity() / stack.size() > 2)
if (stack.capacity() > 16 && !stack.empty() && stack.capacity() / stack.size() > 2)
stack.shrink_to_fit();
}

Expand Down Expand Up @@ -163,7 +163,7 @@ inline const std::vector<detail::type_info *> &all_type_info(PyTypeObject *type)
*/
PYBIND11_NOINLINE inline detail::type_info* get_type_info(PyTypeObject *type) {
auto &bases = all_type_info(type);
if (bases.size() == 0)
if (bases.empty())
return nullptr;
if (bases.size() > 1)
pybind11_fail("pybind11::detail::get_type_info: type has multiple pybind11-registered bases");
Expand Down Expand Up @@ -220,7 +220,7 @@ struct value_and_holder {
{}

// Default constructor (used to signal a value-and-holder not found by get_value_and_holder())
value_and_holder() {}
value_and_holder() = default;

// Used for past-the-end iterator
value_and_holder(size_t index) : index{index} {}
Expand Down Expand Up @@ -432,7 +432,7 @@ PYBIND11_NOINLINE inline std::string error_string() {

#if !defined(PYPY_VERSION)
if (scope.trace) {
PyTracebackObject *trace = (PyTracebackObject *) scope.trace;
auto *trace = (PyTracebackObject *) scope.trace;

/* Get the deepest trace possible */
while (trace->tb_next)
Expand Down Expand Up @@ -1244,7 +1244,7 @@ template <typename StringType, bool IsView = false> struct string_caster {
load_src.ptr(), UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr));
if (!utfNbytes) { PyErr_Clear(); return false; }

const CharT *buffer = reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr()));
const auto *buffer = reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr()));
size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT);
if (UTF_N > 8) { buffer++; length--; } // Skip BOM for UTF-16/32
value = StringType(buffer, length);
Expand All @@ -1258,7 +1258,7 @@ template <typename StringType, bool IsView = false> struct string_caster {

static handle cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) {
const char *buffer = reinterpret_cast<const char *>(src.data());
ssize_t nbytes = ssize_t(src.size() * sizeof(CharT));
auto nbytes = ssize_t(src.size() * sizeof(CharT));
handle s = decode_utfN(buffer, nbytes);
if (!s) throw error_already_set();
return s;
Expand Down Expand Up @@ -1364,7 +1364,7 @@ template <typename CharT> struct type_caster<CharT, enable_if_t<is_std_char_type
// errors. We also allow want to allow unicode characters U+0080 through U+00FF, as those
// can fit into a single char value.
if (StringCaster::UTF_N == 8 && str_len > 1 && str_len <= 4) {
unsigned char v0 = static_cast<unsigned char>(value[0]);
auto v0 = static_cast<unsigned char>(value[0]);
size_t char0_bytes = !(v0 & 0x80) ? 1 : // low bits only: 0-127
(v0 & 0xE0) == 0xC0 ? 2 : // 0b110xxxxx - start of 2-byte sequence
(v0 & 0xF0) == 0xE0 ? 3 : // 0b1110xxxx - start of 3-byte sequence
Expand Down Expand Up @@ -1929,7 +1929,7 @@ inline namespace literals {
String literal version of `arg`
\endrst */
constexpr arg operator"" _a(const char *name, size_t) { return arg(name); }
}
} // namespace literals

PYBIND11_NAMESPACE_BEGIN(detail)

Expand Down
6 changes: 3 additions & 3 deletions include/pybind11/chrono.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ PYBIND11_NAMESPACE_BEGIN(detail)
template <typename type> class duration_caster {
public:
typedef typename type::rep rep;
typedef typename type::period period;
using period = typename type::period;

typedef std::chrono::duration<uint_fast32_t, std::ratio<86400>> days;
using days = std::chrono::duration<uint_fast32_t, std::ratio<86400>>;

bool load(handle src, bool) {
using namespace std::chrono;
Expand Down Expand Up @@ -98,7 +98,7 @@ template <typename type> class duration_caster {
// This is for casting times on the system clock into datetime.datetime instances
template <typename Duration> class type_caster<std::chrono::time_point<std::chrono::system_clock, Duration>> {
public:
typedef std::chrono::time_point<std::chrono::system_clock, Duration> type;
using type = std::chrono::time_point<std::chrono::system_clock, Duration>;
bool load(handle src, bool) {
using namespace std::chrono;

Expand Down
4 changes: 2 additions & 2 deletions include/pybind11/detail/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ inline PyObject* make_new_python_type(const type_record &rec) {

auto &internals = get_internals();
auto bases = tuple(rec.bases);
auto base = (bases.size() == 0) ? internals.instance_base
auto base = (bases.empty()) ? internals.instance_base
: bases[0].ptr();

/* Danger zone: from now (and until PyType_Ready), make sure to
Expand All @@ -616,7 +616,7 @@ inline PyObject* make_new_python_type(const type_record &rec) {
type->tp_doc = tp_doc;
type->tp_base = type_incref((PyTypeObject *)base);
type->tp_basicsize = static_cast<ssize_t>(sizeof(instance));
if (bases.size() > 0)
if (!bases.empty())
type->tp_bases = bases.release().ptr();

/* Don't inherit base __init__ */
Expand Down
20 changes: 10 additions & 10 deletions include/pybind11/detail/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -537,17 +537,17 @@ template <class T, template<class> class... Predicates> using satisfies_none_of

/// Strip the class from a method type
template <typename T> struct remove_class { };
template <typename C, typename R, typename... A> struct remove_class<R (C::*)(A...)> { typedef R type(A...); };
template <typename C, typename R, typename... A> struct remove_class<R (C::*)(A...) const> { typedef R type(A...); };
template <typename C, typename R, typename... A> struct remove_class<R (C::*)(A...)> { using type = R (A...); };
template <typename C, typename R, typename... A> struct remove_class<R (C::*)(A...) const> { using type = R (A...); };

/// Helper template to strip away type modifiers
template <typename T> struct intrinsic_type { typedef T type; };
template <typename T> struct intrinsic_type<const T> { typedef typename intrinsic_type<T>::type type; };
template <typename T> struct intrinsic_type<T*> { typedef typename intrinsic_type<T>::type type; };
template <typename T> struct intrinsic_type<T&> { typedef typename intrinsic_type<T>::type type; };
template <typename T> struct intrinsic_type<T&&> { typedef typename intrinsic_type<T>::type type; };
template <typename T, size_t N> struct intrinsic_type<const T[N]> { typedef typename intrinsic_type<T>::type type; };
template <typename T, size_t N> struct intrinsic_type<T[N]> { typedef typename intrinsic_type<T>::type type; };
template <typename T> struct intrinsic_type { using type = T; };
template <typename T> struct intrinsic_type<const T> { using type = typename intrinsic_type<T>::type; };
template <typename T> struct intrinsic_type<T*> { using type = typename intrinsic_type<T>::type; };
template <typename T> struct intrinsic_type<T&> { using type = typename intrinsic_type<T>::type; };
template <typename T> struct intrinsic_type<T&&> { using type = typename intrinsic_type<T>::type; };
template <typename T, size_t N> struct intrinsic_type<const T[N]> { using type = typename intrinsic_type<T>::type; };
template <typename T, size_t N> struct intrinsic_type<T[N]> { using type = typename intrinsic_type<T>::type; };
template <typename T> using intrinsic_t = typename intrinsic_type<T>::type;

/// Helper type to replace 'void' in some expressions
Expand Down Expand Up @@ -761,7 +761,7 @@ struct nodelete { template <typename T> void operator()(T*) { } };
PYBIND11_NAMESPACE_BEGIN(detail)
template <typename... Args>
struct overload_cast_impl {
constexpr overload_cast_impl() {} // MSVC 2015 needs this
constexpr overload_cast_impl() {}; // NOLINT(modernize-use-equals-default): MSVC 2015 needs this

template <typename Return>
constexpr auto operator()(Return (*pf)(Args...)) const noexcept
Expand Down
15 changes: 11 additions & 4 deletions include/pybind11/iostream.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,18 @@ class pythonbuf : public std::streambuf {
object pywrite;
object pyflush;

int overflow(int c) {
int overflow(int c) override {
if (!traits_type::eq_int_type(c, traits_type::eof())) {
*pptr() = traits_type::to_char_type(c);
pbump(1);
}
return sync() == 0 ? traits_type::not_eof(c) : traits_type::eof();
}

int sync() {
// This function must be non-virtual to be called in a destructor. If the
// rare MSVC test failure shows up with this version, then this should be
// simplified to a fully qualified call.
int _sync() {
if (pbase() != pptr()) {
// This subtraction cannot be negative, so dropping the sign
str line(pbase(), static_cast<size_t>(pptr() - pbase()));
Expand All @@ -54,6 +57,10 @@ class pythonbuf : public std::streambuf {
return 0;
}

int sync() override {
return _sync();
}

public:

pythonbuf(object pyostream, size_t buffer_size = 1024)
Expand All @@ -67,8 +74,8 @@ class pythonbuf : public std::streambuf {
pythonbuf(pythonbuf&&) = default;

/// Sync before destroy
~pythonbuf() {
sync();
~pythonbuf() override {
_sync();
}
};

Expand Down
6 changes: 3 additions & 3 deletions include/pybind11/numpy.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ template <typename T> struct is_complex : std::false_type { };
template <typename T> struct is_complex<std::complex<T>> : std::true_type { };

template <typename T> struct array_info_scalar {
typedef T type;
using type = T;
static constexpr bool is_array = false;
static constexpr bool is_empty = false;
static constexpr auto extents = _("");
Expand Down Expand Up @@ -1296,7 +1296,7 @@ class common_iterator {
m_strides.back() = static_cast<value_type>(strides.back());
for (size_type i = m_strides.size() - 1; i != 0; --i) {
size_type j = i - 1;
value_type s = static_cast<value_type>(shape[i]);
auto s = static_cast<value_type>(shape[i]);
m_strides[j] = strides[j] + m_strides[i] - strides[i] * s;
}
}
Expand Down Expand Up @@ -1539,7 +1539,7 @@ struct vectorize_helper {
ssize_t nd = 0;
std::vector<ssize_t> shape(0);
auto trivial = broadcast(buffers, nd, shape);
size_t ndim = (size_t) nd;
auto ndim = (size_t) nd;

size_t size = std::accumulate(shape.begin(), shape.end(), (size_t) 1, std::multiplies<size_t>());

Expand Down
Loading