Skip to content

Commit

Permalink
CodeHealth: Enabling clang-tidy google-explicit-constructor (#3250)
Browse files Browse the repository at this point in the history
* Adding google-explicit-constructor to .clang-tidy

* clang-tidy explicit attr.h (all automatic)

* clang-tidy explicit cast.h (all automatic)

* clang-tidy detail/init.h (1 NOLINT)

* clang-tidy detail/type_caster_base.h (2 NOLINT)

* clang-tidy pybind11.h (7 NOLINT)

* clang-tidy detail/common.h (3 NOLINT)

* clang-tidy detail/descr.h (2 NOLINT)

* clang-tidy pytypes.h (23 NOLINT, only 1 explicit)

* clang-tidy eigen.h (7 NOLINT, 0 explicit)

* Adding 2 explicit in functional.h

* Adding 4 explicit in iostream.h

* clang-tidy numpy.h (1 NOLINT, 1 explicit)

* clang-tidy embed.h (0 NOLINT, 1 explicit)

* clang-tidy tests/local_bindings.h (0 NOLINT, 4 explicit)

* clang-tidy tests/pybind11_cross_module_tests.cpp (0 NOLINT, 1 explicit)

* clang-tidy tests/pybind11_tests.h (0 NOLINT, 2 explicit)

* clang-tidy tests/test_buffers.cpp (0 NOLINT, 2 explicit)

* clang-tidy tests/test_builtin_casters.cpp (0 NOLINT, 4 explicit)

* clang-tidy tests/test_class.cpp (0 NOLINT, 6 explicit)

* clang-tidy tests/test_copy_move.cpp (0 NOLINT, 7 explicit)

* clang-tidy tests/test_embed/external_module.cpp (0 NOLINT, 1 explicit)

* clang-tidy tests/test_embed/test_interpreter.cpp (0 NOLINT, 1 explicit)

* clang-tidy tests/object.h (0 NOLINT, 2 explicit)

* clang-tidy batch of fully automatic fixes.

* Workaround for MSVC 19.16.27045.0 C++17 Python 2 C++ syntax error.
  • Loading branch information
Ralf W. Grosse-Kunstleve authored Sep 9, 2021
1 parent 39a0aac commit 6abf2ba
Show file tree
Hide file tree
Showing 38 changed files with 231 additions and 132 deletions.
1 change: 1 addition & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Checks: '
cppcoreguidelines-init-variables,
cppcoreguidelines-slicing,
clang-analyzer-optin.cplusplus.VirtualCall,
google-explicit-constructor,
llvm-namespace-comment,
misc-misplaced-const,
misc-non-copyable-objects,
Expand Down
24 changes: 18 additions & 6 deletions include/pybind11/attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
/// @{

/// Annotation for methods
struct is_method { handle class_; is_method(const handle &c) : class_(c) { } };
struct is_method { handle class_;
explicit is_method(const handle &c) : class_(c) {}
};

/// Annotation for operators
struct is_operator { };
Expand All @@ -27,16 +29,24 @@ struct is_operator { };
struct is_final { };

/// Annotation for parent scope
struct scope { handle value; scope(const handle &s) : value(s) { } };
struct scope { handle value;
explicit scope(const handle &s) : value(s) {}
};

/// Annotation for documentation
struct doc { const char *value; doc(const char *value) : value(value) { } };
struct doc { const char *value;
explicit doc(const char *value) : value(value) {}
};

/// Annotation for function names
struct name { const char *value; name(const char *value) : value(value) { } };
struct name { const char *value;
explicit name(const char *value) : value(value) {}
};

/// Annotation indicating that a function is an overload associated with a given "sibling"
struct sibling { handle value; sibling(const handle &value) : value(value.ptr()) { } };
struct sibling { handle value;
explicit sibling(const handle &value) : value(value.ptr()) {}
};

/// Annotation indicating that a class derives from another given type
template <typename T> struct base {
Expand Down Expand Up @@ -70,7 +80,9 @@ struct metaclass {
};

/// Annotation that marks a class as local to the module:
struct module_local { const bool value; constexpr module_local(bool v = true) : value(v) { } };
struct module_local { const bool value;
constexpr explicit module_local(bool v = true) : value(v) {}
};

/// Annotation to mark enums as an arithmetic type
struct arithmetic { };
Expand Down
14 changes: 8 additions & 6 deletions include/pybind11/cast.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ template <typename type> class type_caster<std::reference_wrapper<type>> {
return caster_t::cast(&src.get(), policy, parent);
}
template <typename T> using cast_op_type = std::reference_wrapper<type>;
operator std::reference_wrapper<type>() { return cast_op<type &>(subcaster); }
explicit operator std::reference_wrapper<type>() { return cast_op<type &>(subcaster); }
};

#define PYBIND11_TYPE_CASTER(type, py_name) \
Expand Down Expand Up @@ -279,7 +279,7 @@ template <> class type_caster<void> : public type_caster<void_type> {
}

template <typename T> using cast_op_type = void*&;
operator void *&() { return value; }
explicit operator void *&() { return value; }
static constexpr auto name = _("capsule");
private:
void *value = nullptr;
Expand Down Expand Up @@ -487,8 +487,10 @@ template <typename CharT> struct type_caster<CharT, enable_if_t<is_std_char_type
return StringCaster::cast(StringType(1, src), policy, parent);
}

operator CharT*() { return none ? nullptr : const_cast<CharT *>(static_cast<StringType &>(str_caster).c_str()); }
operator CharT&() {
explicit operator CharT *() {
return none ? nullptr : const_cast<CharT *>(static_cast<StringType &>(str_caster).c_str());
}
explicit operator CharT &() {
if (none)
throw value_error("Cannot convert None to a character");

Expand Down Expand Up @@ -581,8 +583,8 @@ template <template<typename...> class Tuple, typename... Ts> class tuple_caster

template <typename T> using cast_op_type = type;

operator type() & { return implicit_cast(indices{}); }
operator type() && { return std::move(*this).implicit_cast(indices{}); }
explicit operator type() & { return implicit_cast(indices{}); }
explicit operator type() && { return std::move(*this).implicit_cast(indices{}); }

protected:
template <size_t... Is>
Expand Down
3 changes: 3 additions & 0 deletions include/pybind11/detail/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,7 @@ class any_container {

// Implicit conversion constructor from any arbitrary container type with values convertible to T
template <typename Container, typename = enable_if_t<std::is_convertible<decltype(*std::begin(std::declval<const Container &>())), T>::value>>
// NOLINTNEXTLINE(google-explicit-constructor)
any_container(const Container &c) : any_container(std::begin(c), std::end(c)) { }

// initializer_list's aren't deducible, so don't get matched by the above template; we need this
Expand All @@ -926,9 +927,11 @@ class any_container {
any_container(const std::initializer_list<TIn> &c) : any_container(c.begin(), c.end()) { }

// Avoid copying if given an rvalue vector of the correct type.
// NOLINTNEXTLINE(google-explicit-constructor)
any_container(std::vector<T> &&v) : v(std::move(v)) { }

// Moves the vector out of an rvalue any_container
// NOLINTNEXTLINE(google-explicit-constructor)
operator std::vector<T> &&() && { return std::move(v); }

// Dereferencing obtains a reference to the underlying vector
Expand Down
2 changes: 2 additions & 0 deletions include/pybind11/detail/descr.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ struct descr {
char text[N + 1]{'\0'};

constexpr descr() = default;
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr descr(char const (&s)[N+1]) : descr(s, make_index_sequence<N>()) { }

template <size_t... Is>
constexpr descr(char const (&s)[N+1], index_sequence<Is...>) : text{s[Is]..., '\0'} { }

template <typename... Chars>
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr descr(char c, Chars... cs) : text{c, static_cast<char>(cs)..., '\0'} { }

static constexpr std::array<const std::type_info *, sizeof...(Ts) + 1> types() {
Expand Down
5 changes: 3 additions & 2 deletions include/pybind11/detail/init.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class type_caster<value_and_holder> {
}

template <typename> using cast_op_type = value_and_holder &;
operator value_and_holder &() { return *value; }
explicit operator value_and_holder &() { return *value; }
static constexpr auto name = _<value_and_holder>();

private:
Expand Down Expand Up @@ -222,7 +222,8 @@ template <typename Func, typename Return, typename... Args>
struct factory<Func, void_type (*)(), Return(Args...)> {
remove_reference_t<Func> class_factory;

factory(Func &&f) : class_factory(std::forward<Func>(f)) { }
// NOLINTNEXTLINE(google-explicit-constructor)
factory(Func &&f) : class_factory(std::forward<Func>(f)) {}

// The given class either has no alias or has no separate alias factory;
// this always constructs the class itself. If the class is registered with an alias
Expand Down
18 changes: 11 additions & 7 deletions include/pybind11/detail/type_caster_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ struct value_and_holder {
value_and_holder() = default;

// Used for past-the-end iterator
value_and_holder(size_t index) : index{index} {}
explicit value_and_holder(size_t index) : index{index} {}

template <typename V = void> V *&value_ptr() const {
return reinterpret_cast<V *&>(vh[0]);
Expand Down Expand Up @@ -274,7 +274,8 @@ struct values_and_holders {
const type_vec &tinfo;

public:
values_and_holders(instance *inst) : inst{inst}, tinfo(all_type_info(Py_TYPE(inst))) {}
explicit values_and_holders(instance *inst)
: inst{inst}, tinfo(all_type_info(Py_TYPE(inst))) {}

struct iterator {
private:
Expand All @@ -290,7 +291,8 @@ struct values_and_holders {
0 /* index */)
{}
// Past-the-end iterator:
iterator(size_t end) : curr(end) {}
explicit iterator(size_t end) : curr(end) {}

public:
bool operator==(const iterator &other) const { return curr.index == other.curr.index; }
bool operator!=(const iterator &other) const { return curr.index != other.curr.index; }
Expand Down Expand Up @@ -491,11 +493,11 @@ inline PyObject *make_new_instance(PyTypeObject *type);

class type_caster_generic {
public:
PYBIND11_NOINLINE type_caster_generic(const std::type_info &type_info)
: typeinfo(get_type_info(type_info)), cpptype(&type_info) { }
PYBIND11_NOINLINE explicit type_caster_generic(const std::type_info &type_info)
: typeinfo(get_type_info(type_info)), cpptype(&type_info) {}

type_caster_generic(const type_info *typeinfo)
: typeinfo(typeinfo), cpptype(typeinfo ? typeinfo->cpptype : nullptr) { }
explicit type_caster_generic(const type_info *typeinfo)
: typeinfo(typeinfo), cpptype(typeinfo ? typeinfo->cpptype : nullptr) {}

bool load(handle src, bool convert) {
return load_impl<type_caster_generic>(src, convert);
Expand Down Expand Up @@ -923,7 +925,9 @@ template <typename type> class type_caster_base : public type_caster_generic {

template <typename T> using cast_op_type = detail::cast_op_type<T>;

// NOLINTNEXTLINE(google-explicit-constructor)
operator itype*() { return (type *) value; }
// NOLINTNEXTLINE(google-explicit-constructor)
operator itype&() { if (!value) throw reference_cast_error(); return *((itype *) value); }

protected:
Expand Down
7 changes: 7 additions & 0 deletions include/pybind11/eigen.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ template <bool EigenRowMajor> struct EigenConformable {
EigenDStride stride{0, 0}; // Only valid if negativestrides is false!
bool negativestrides = false; // If true, do not use stride!

// NOLINTNEXTLINE(google-explicit-constructor)
EigenConformable(bool fits = false) : conformable{fits} {}
// Matrix type:
EigenConformable(EigenIndex r, EigenIndex c,
Expand Down Expand Up @@ -88,6 +89,7 @@ template <bool EigenRowMajor> struct EigenConformable {
(props::outer_stride == Eigen::Dynamic || props::outer_stride == stride.outer() ||
(EigenRowMajor ? rows : cols) == 1);
}
// NOLINTNEXTLINE(google-explicit-constructor)
operator bool() const { return conformable; }
};

Expand Down Expand Up @@ -326,8 +328,11 @@ struct type_caster<Type, enable_if_t<is_eigen_dense_plain<Type>::value>> {

static constexpr auto name = props::descriptor;

// NOLINTNEXTLINE(google-explicit-constructor)
operator Type*() { return &value; }
// NOLINTNEXTLINE(google-explicit-constructor)
operator Type&() { return value; }
// NOLINTNEXTLINE(google-explicit-constructor)
operator Type&&() && { return std::move(value); }
template <typename T> using cast_op_type = movable_cast_op_type<T>;

Expand Down Expand Up @@ -451,7 +456,9 @@ struct type_caster<
return true;
}

// NOLINTNEXTLINE(google-explicit-constructor)
operator Type*() { return ref.get(); }
// NOLINTNEXTLINE(google-explicit-constructor)
operator Type&() { return *ref; }
template <typename _T> using cast_op_type = pybind11::detail::cast_op_type<_T>;

Expand Down
8 changes: 4 additions & 4 deletions include/pybind11/embed.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,10 @@ inline void finalize_interpreter() {
\endrst */
class scoped_interpreter {
public:
scoped_interpreter(bool init_signal_handlers = true,
int argc = 0,
const char *const *argv = nullptr,
bool add_program_dir_to_path = true) {
explicit scoped_interpreter(bool init_signal_handlers = true,
int argc = 0,
const char *const *argv = nullptr,
bool add_program_dir_to_path = true) {
initialize_interpreter(init_signal_handlers, argc, argv, add_program_dir_to_path);
}

Expand Down
6 changes: 5 additions & 1 deletion include/pybind11/functional.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ struct type_caster<std::function<Return(Args...)>> {
// ensure GIL is held during functor destruction
struct func_handle {
function f;
#if !(defined(_MSC_VER) && _MSC_VER == 1916 && defined(PYBIND11_CPP17) && PY_MAJOR_VERSION < 3)
// This triggers a syntax error under very special conditions (very weird indeed).
explicit
#endif
func_handle(function &&f_) noexcept : f(std::move(f_)) {}
func_handle(const func_handle &f_) { operator=(f_); }
func_handle &operator=(const func_handle &f_) {
Expand All @@ -85,7 +89,7 @@ struct type_caster<std::function<Return(Args...)>> {
// to emulate 'move initialization capture' in C++11
struct func_wrapper {
func_handle hfunc;
func_wrapper(func_handle &&hf) noexcept : hfunc(std::move(hf)) {}
explicit func_wrapper(func_handle &&hf) noexcept : hfunc(std::move(hf)) {}
Return operator()(Args... args) const {
gil_scoped_acquire acq;
object retval(hfunc.f(std::forward<Args>(args)...));
Expand Down
14 changes: 8 additions & 6 deletions include/pybind11/iostream.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class pythonbuf : public std::streambuf {
}

public:
pythonbuf(const object &pyostream, size_t buffer_size = 1024)
explicit pythonbuf(const object &pyostream, size_t buffer_size = 1024)
: buf_size(buffer_size), d_buffer(new char[buf_size]), pywrite(pyostream.attr("write")),
pyflush(pyostream.attr("flush")) {
setp(d_buffer.get(), d_buffer.get() + buf_size - 1);
Expand Down Expand Up @@ -171,8 +171,9 @@ class scoped_ostream_redirect {
detail::pythonbuf buffer;

public:
scoped_ostream_redirect(std::ostream &costream = std::cout,
const object &pyostream = module_::import("sys").attr("stdout"))
explicit scoped_ostream_redirect(std::ostream &costream = std::cout,
const object &pyostream
= module_::import("sys").attr("stdout"))
: costream(costream), buffer(pyostream) {
old = costream.rdbuf(&buffer);
}
Expand Down Expand Up @@ -201,8 +202,9 @@ class scoped_ostream_redirect {
\endrst */
class scoped_estream_redirect : public scoped_ostream_redirect {
public:
scoped_estream_redirect(std::ostream &costream = std::cerr,
const object &pyostream = module_::import("sys").attr("stderr"))
explicit scoped_estream_redirect(std::ostream &costream = std::cerr,
const object &pyostream
= module_::import("sys").attr("stderr"))
: scoped_ostream_redirect(costream, pyostream) {}
};

Expand All @@ -217,7 +219,7 @@ class OstreamRedirect {
std::unique_ptr<scoped_estream_redirect> redirect_stderr;

public:
OstreamRedirect(bool do_stdout = true, bool do_stderr = true)
explicit OstreamRedirect(bool do_stdout = true, bool do_stderr = true)
: do_stdout_(do_stdout), do_stderr_(do_stderr) {}

void enter() {
Expand Down
3 changes: 2 additions & 1 deletion include/pybind11/numpy.h
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ class dtype : public object {
m_ptr = from_args(pybind11::str(format)).release().ptr();
}

dtype(const char *format) : dtype(std::string(format)) { }
explicit dtype(const char *format) : dtype(std::string(format)) {}

dtype(list names, list formats, list offsets, ssize_t itemsize) {
dict args;
Expand Down Expand Up @@ -894,6 +894,7 @@ template <typename T, int ExtraFlags = array::forcecast> class array_t : public
if (!is_borrowed) Py_XDECREF(h.ptr());
}

// NOLINTNEXTLINE(google-explicit-constructor)
array_t(const object &o) : array(raw_array_t(o.ptr()), stolen_t{}) {
if (!m_ptr) throw error_already_set();
}
Expand Down
Loading

0 comments on commit 6abf2ba

Please sign in to comment.