Skip to content

Commit 39fbc79

Browse files
authored
fix: avoiding usage of _ if already defined (#3423)
* fix: avoid usage of _ * ci: test _ defined * docs: include change in docs * fix: add a test and comment * refactor: const_str -> const_name
1 parent b3d9c35 commit 39fbc79

20 files changed

+94
-75
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ jobs:
4444
python: '3.6'
4545
args: >
4646
-DPYBIND11_FINDPYTHON=ON
47+
-DCMAKE_CXX_FLAGS="-D_=1"
4748
- runs-on: windows-latest
4849
python: '3.6'
4950
args: >
@@ -68,7 +69,8 @@ jobs:
6869
python-version: ${{ matrix.python }}
6970

7071
- name: Setup Boost (Linux)
71-
if: runner.os == 'Linux'
72+
# Can't use boost + define _
73+
if: runner.os == 'Linux' && matrix.python != '3.6'
7274
run: sudo apt-get install libboost-dev
7375

7476
- name: Setup Boost (macOS)

docs/advanced/cast/custom.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ type is explicitly allowed.
4646
* function signatures and declares a local variable
4747
* 'value' of type inty
4848
*/
49-
PYBIND11_TYPE_CASTER(inty, _("inty"));
49+
PYBIND11_TYPE_CASTER(inty, const_name("inty"));
5050
5151
/**
5252
* Conversion part 1 (Python->C++): convert a PyObject into a inty

docs/upgrade.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ v2.9
1717
converted to using ``py::module_::import("types").attr("SimpleNamespace")``
1818
instead.
1919

20+
* The use of ``_`` in custom type casters can now be replaced with the more
21+
readable ``const_name`` instead. The old ``_`` shortcut has been retained
22+
unless it is being used as a macro (like for gettext).
23+
2024

2125
.. _upgrade-guide-2.7:
2226

include/pybind11/cast.h

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ struct type_caster<T, enable_if_t<std::is_arithmetic<T>::value && !is_std_char_t
208208
return PyLong_FromUnsignedLongLong((unsigned long long) src);
209209
}
210210

211-
PYBIND11_TYPE_CASTER(T, _<std::is_integral<T>::value>("int", "float"));
211+
PYBIND11_TYPE_CASTER(T, const_name<std::is_integral<T>::value>("int", "float"));
212212
};
213213

214214
template<typename T> struct void_caster {
@@ -221,7 +221,7 @@ template<typename T> struct void_caster {
221221
static handle cast(T, return_value_policy /* policy */, handle /* parent */) {
222222
return none().inc_ref();
223223
}
224-
PYBIND11_TYPE_CASTER(T, _("None"));
224+
PYBIND11_TYPE_CASTER(T, const_name("None"));
225225
};
226226

227227
template <> class type_caster<void_type> : public void_caster<void_type> {};
@@ -264,7 +264,7 @@ template <> class type_caster<void> : public type_caster<void_type> {
264264

265265
template <typename T> using cast_op_type = void*&;
266266
explicit operator void *&() { return value; }
267-
static constexpr auto name = _("capsule");
267+
static constexpr auto name = const_name("capsule");
268268
private:
269269
void *value = nullptr;
270270
};
@@ -315,7 +315,7 @@ template <> class type_caster<bool> {
315315
static handle cast(bool src, return_value_policy /* policy */, handle /* parent */) {
316316
return handle(src ? Py_True : Py_False).inc_ref();
317317
}
318-
PYBIND11_TYPE_CASTER(bool, _("bool"));
318+
PYBIND11_TYPE_CASTER(bool, const_name("bool"));
319319
};
320320

321321
// Helper class for UTF-{8,16,32} C++ stl strings:
@@ -405,7 +405,7 @@ template <typename StringType, bool IsView = false> struct string_caster {
405405
return s;
406406
}
407407

408-
PYBIND11_TYPE_CASTER(StringType, _(PYBIND11_STRING_NAME));
408+
PYBIND11_TYPE_CASTER(StringType, const_name(PYBIND11_STRING_NAME));
409409

410410
private:
411411
static handle decode_utfN(const char *buffer, ssize_t nbytes) {
@@ -542,7 +542,7 @@ template <typename CharT> struct type_caster<CharT, enable_if_t<is_std_char_type
542542
return one_char;
543543
}
544544

545-
static constexpr auto name = _(PYBIND11_STRING_NAME);
545+
static constexpr auto name = const_name(PYBIND11_STRING_NAME);
546546
template <typename _T> using cast_op_type = pybind11::detail::cast_op_type<_T>;
547547
};
548548

@@ -579,7 +579,7 @@ template <template<typename...> class Tuple, typename... Ts> class tuple_caster
579579
return cast(*src, policy, parent);
580580
}
581581

582-
static constexpr auto name = _("Tuple[") + concat(make_caster<Ts>::name...) + _("]");
582+
static constexpr auto name = const_name("Tuple[") + concat(make_caster<Ts>::name...) + const_name("]");
583583

584584
template <typename T> using cast_op_type = type;
585585

@@ -764,14 +764,14 @@ template <typename base, typename holder> struct is_holder_type :
764764
template <typename base, typename deleter> struct is_holder_type<base, std::unique_ptr<base, deleter>> :
765765
std::true_type {};
766766

767-
template <typename T> struct handle_type_name { static constexpr auto name = _<T>(); };
768-
template <> struct handle_type_name<bytes> { static constexpr auto name = _(PYBIND11_BYTES_NAME); };
769-
template <> struct handle_type_name<int_> { static constexpr auto name = _("int"); };
770-
template <> struct handle_type_name<iterable> { static constexpr auto name = _("Iterable"); };
771-
template <> struct handle_type_name<iterator> { static constexpr auto name = _("Iterator"); };
772-
template <> struct handle_type_name<none> { static constexpr auto name = _("None"); };
773-
template <> struct handle_type_name<args> { static constexpr auto name = _("*args"); };
774-
template <> struct handle_type_name<kwargs> { static constexpr auto name = _("**kwargs"); };
767+
template <typename T> struct handle_type_name { static constexpr auto name = const_name<T>(); };
768+
template <> struct handle_type_name<bytes> { static constexpr auto name = const_name(PYBIND11_BYTES_NAME); };
769+
template <> struct handle_type_name<int_> { static constexpr auto name = const_name("int"); };
770+
template <> struct handle_type_name<iterable> { static constexpr auto name = const_name("Iterable"); };
771+
template <> struct handle_type_name<iterator> { static constexpr auto name = const_name("Iterator"); };
772+
template <> struct handle_type_name<none> { static constexpr auto name = const_name("None"); };
773+
template <> struct handle_type_name<args> { static constexpr auto name = const_name("*args"); };
774+
template <> struct handle_type_name<kwargs> { static constexpr auto name = const_name("**kwargs"); };
775775

776776
template <typename type>
777777
struct pyobject_caster {

include/pybind11/chrono.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ template <typename type> class duration_caster {
9797
return PyDelta_FromDSU(dd.count(), ss.count(), us.count());
9898
}
9999

100-
PYBIND11_TYPE_CASTER(type, _("datetime.timedelta"));
100+
PYBIND11_TYPE_CASTER(type, const_name("datetime.timedelta"));
101101
};
102102

103103
inline std::tm *localtime_thread_safe(const std::time_t *time, std::tm *buf) {
@@ -195,7 +195,7 @@ template <typename Duration> class type_caster<std::chrono::time_point<std::chro
195195
localtime.tm_sec,
196196
us.count());
197197
}
198-
PYBIND11_TYPE_CASTER(type, _("datetime.datetime"));
198+
PYBIND11_TYPE_CASTER(type, const_name("datetime.datetime"));
199199
};
200200

201201
// Other clocks that are not the system clock are not measured as datetime.datetime objects

include/pybind11/complex.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ template <typename T> class type_caster<std::complex<T>> {
5959
return PyComplex_FromDoubles((double) src.real(), (double) src.imag());
6060
}
6161

62-
PYBIND11_TYPE_CASTER(std::complex<T>, _("complex"));
62+
PYBIND11_TYPE_CASTER(std::complex<T>, const_name("complex"));
6363
};
6464
PYBIND11_NAMESPACE_END(detail)
6565
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

include/pybind11/detail/descr.h

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,17 @@ constexpr descr<N1 + N2, Ts1..., Ts2...> operator+(const descr<N1, Ts1...> &a, c
5353
return plus_impl(a, b, make_index_sequence<N1>(), make_index_sequence<N2>());
5454
}
5555

56+
template <size_t N>
57+
constexpr descr<N - 1> const_name(char const(&text)[N]) { return descr<N - 1>(text); }
58+
constexpr descr<0> const_name(char const(&)[1]) { return {}; }
59+
60+
// The "_" might be defined as a macro - don't define it if so.
61+
// Repeating the const_name code to avoid introducing a #define.
62+
#ifndef _
5663
template <size_t N>
5764
constexpr descr<N - 1> _(char const(&text)[N]) { return descr<N - 1>(text); }
5865
constexpr descr<0> _(char const(&)[1]) { return {}; }
66+
#endif
5967

6068
template <size_t Rem, size_t... Digits> struct int_to_str : int_to_str<Rem/10, Rem%10, Digits...> { };
6169
template <size_t...Digits> struct int_to_str<0, Digits...> {
@@ -64,25 +72,25 @@ template <size_t...Digits> struct int_to_str<0, Digits...> {
6472

6573
// Ternary description (like std::conditional)
6674
template <bool B, size_t N1, size_t N2>
67-
constexpr enable_if_t<B, descr<N1 - 1>> _(char const(&text1)[N1], char const(&)[N2]) {
68-
return _(text1);
75+
constexpr enable_if_t<B, descr<N1 - 1>> const_name(char const(&text1)[N1], char const(&)[N2]) {
76+
return const_name(text1);
6977
}
7078
template <bool B, size_t N1, size_t N2>
71-
constexpr enable_if_t<!B, descr<N2 - 1>> _(char const(&)[N1], char const(&text2)[N2]) {
72-
return _(text2);
79+
constexpr enable_if_t<!B, descr<N2 - 1>> const_name(char const(&)[N1], char const(&text2)[N2]) {
80+
return const_name(text2);
7381
}
7482

7583
template <bool B, typename T1, typename T2>
76-
constexpr enable_if_t<B, T1> _(const T1 &d, const T2 &) { return d; }
84+
constexpr enable_if_t<B, T1> const_name(const T1 &d, const T2 &) { return d; }
7785
template <bool B, typename T1, typename T2>
78-
constexpr enable_if_t<!B, T2> _(const T1 &, const T2 &d) { return d; }
86+
constexpr enable_if_t<!B, T2> const_name(const T1 &, const T2 &d) { return d; }
7987

8088
template <size_t Size>
81-
auto constexpr _() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
89+
auto constexpr const_name() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
8290
return int_to_str<Size / 10, Size % 10>::digits;
8391
}
8492

85-
template <typename Type> constexpr descr<1, Type> _() { return {'%'}; }
93+
template <typename Type> constexpr descr<1, Type> const_name() { return {'%'}; }
8694

8795
constexpr descr<0> concat() { return {}; }
8896

@@ -92,12 +100,12 @@ constexpr descr<N, Ts...> concat(const descr<N, Ts...> &descr) { return descr; }
92100
template <size_t N, typename... Ts, typename... Args>
93101
constexpr auto concat(const descr<N, Ts...> &d, const Args &...args)
94102
-> decltype(std::declval<descr<N + 2, Ts...>>() + concat(args...)) {
95-
return d + _(", ") + concat(args...);
103+
return d + const_name(", ") + concat(args...);
96104
}
97105

98106
template <size_t N, typename... Ts>
99107
constexpr descr<N + 2, Ts...> type_descr(const descr<N, Ts...> &descr) {
100-
return _("{") + descr + _("}");
108+
return const_name("{") + descr + const_name("}");
101109
}
102110

103111
PYBIND11_NAMESPACE_END(detail)

include/pybind11/detail/init.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class type_caster<value_and_holder> {
2424

2525
template <typename> using cast_op_type = value_and_holder &;
2626
explicit operator value_and_holder &() { return *value; }
27-
static constexpr auto name = _<value_and_holder>();
27+
static constexpr auto name = const_name<value_and_holder>();
2828

2929
private:
3030
value_and_holder *value = nullptr;

include/pybind11/detail/type_caster_base.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,7 @@ template <typename type> class type_caster_base : public type_caster_generic {
897897
using itype = intrinsic_t<type>;
898898

899899
public:
900-
static constexpr auto name = _<type>();
900+
static constexpr auto name = const_name<type>();
901901

902902
type_caster_base() : type_caster_base(typeid(type)) { }
903903
explicit type_caster_base(const std::type_info &info) : type_caster_generic(info) { }

include/pybind11/eigen.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -192,20 +192,20 @@ template <typename Type_> struct EigenProps {
192192
static constexpr bool show_f_contiguous = !show_c_contiguous && show_order && requires_col_major;
193193

194194
static constexpr auto descriptor =
195-
_("numpy.ndarray[") + npy_format_descriptor<Scalar>::name +
196-
_("[") + _<fixed_rows>(_<(size_t) rows>(), _("m")) +
197-
_(", ") + _<fixed_cols>(_<(size_t) cols>(), _("n")) +
198-
_("]") +
195+
const_name("numpy.ndarray[") + npy_format_descriptor<Scalar>::name +
196+
const_name("[") + const_name<fixed_rows>(const_name<(size_t) rows>(), const_name("m")) +
197+
const_name(", ") + const_name<fixed_cols>(const_name<(size_t) cols>(), const_name("n")) +
198+
const_name("]") +
199199
// For a reference type (e.g. Ref<MatrixXd>) we have other constraints that might need to be
200200
// satisfied: writeable=True (for a mutable reference), and, depending on the map's stride
201201
// options, possibly f_contiguous or c_contiguous. We include them in the descriptor output
202202
// to provide some hint as to why a TypeError is occurring (otherwise it can be confusing to
203203
// see that a function accepts a 'numpy.ndarray[float64[3,2]]' and an error message that you
204204
// *gave* a numpy.ndarray of the right type and dimensions.
205-
_<show_writeable>(", flags.writeable", "") +
206-
_<show_c_contiguous>(", flags.c_contiguous", "") +
207-
_<show_f_contiguous>(", flags.f_contiguous", "") +
208-
_("]");
205+
const_name<show_writeable>(", flags.writeable", "") +
206+
const_name<show_c_contiguous>(", flags.c_contiguous", "") +
207+
const_name<show_f_contiguous>(", flags.f_contiguous", "") +
208+
const_name("]");
209209
};
210210

211211
// Casts an Eigen type to numpy array. If given a base, the numpy array references the src data,
@@ -600,8 +600,8 @@ struct type_caster<Type, enable_if_t<is_eigen_sparse<Type>::value>> {
600600
).release();
601601
}
602602

603-
PYBIND11_TYPE_CASTER(Type, _<(Type::IsRowMajor) != 0>("scipy.sparse.csr_matrix[", "scipy.sparse.csc_matrix[")
604-
+ npy_format_descriptor<Scalar>::name + _("]"));
603+
PYBIND11_TYPE_CASTER(Type, const_name<(Type::IsRowMajor) != 0>("scipy.sparse.csr_matrix[", "scipy.sparse.csc_matrix[")
604+
+ npy_format_descriptor<Scalar>::name + const_name("]"));
605605
};
606606

607607
PYBIND11_NAMESPACE_END(detail)

include/pybind11/functional.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ struct type_caster<std::function<Return(Args...)>> {
113113
return cpp_function(std::forward<Func>(f_), policy).release();
114114
}
115115

116-
PYBIND11_TYPE_CASTER(type, _("Callable[[") + concat(make_caster<Args>::name...) + _("], ")
117-
+ make_caster<retval_type>::name + _("]"));
116+
PYBIND11_TYPE_CASTER(type, const_name("Callable[[") + concat(make_caster<Args>::name...) + const_name("], ")
117+
+ make_caster<retval_type>::name + const_name("]"));
118118
};
119119

120120
PYBIND11_NAMESPACE_END(detail)

include/pybind11/numpy.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class array; // Forward declaration
3939

4040
PYBIND11_NAMESPACE_BEGIN(detail)
4141

42-
template <> struct handle_type_name<array> { static constexpr auto name = _("numpy.ndarray"); };
42+
template <> struct handle_type_name<array> { static constexpr auto name = const_name("numpy.ndarray"); };
4343

4444
template <typename type, typename SFINAE = void> struct npy_format_descriptor;
4545

@@ -290,7 +290,7 @@ template <typename T> struct array_info_scalar {
290290
using type = T;
291291
static constexpr bool is_array = false;
292292
static constexpr bool is_empty = false;
293-
static constexpr auto extents = _("");
293+
static constexpr auto extents = const_name("");
294294
static void append_extents(list& /* shape */) { }
295295
};
296296
// Computes underlying type and a comma-separated list of extents for array
@@ -309,8 +309,8 @@ template <typename T, size_t N> struct array_info<std::array<T, N>> {
309309
array_info<T>::append_extents(shape);
310310
}
311311

312-
static constexpr auto extents = _<array_info<T>::is_array>(
313-
concat(_<N>(), array_info<T>::extents), _<N>()
312+
static constexpr auto extents = const_name<array_info<T>::is_array>(
313+
concat(const_name<N>(), array_info<T>::extents), const_name<N>()
314314
);
315315
};
316316
// For numpy we have special handling for arrays of characters, so we don't include
@@ -1021,7 +1021,7 @@ template <typename T>
10211021
struct format_descriptor<T, detail::enable_if_t<detail::array_info<T>::is_array>> {
10221022
static std::string format() {
10231023
using namespace detail;
1024-
static constexpr auto extents = _("(") + array_info<T>::extents + _(")");
1024+
static constexpr auto extents = const_name("(") + array_info<T>::extents + const_name(")");
10251025
return extents.text + format_descriptor<remove_all_extents_t<T>>::format();
10261026
}
10271027
};
@@ -1056,28 +1056,28 @@ struct npy_format_descriptor_name;
10561056

10571057
template <typename T>
10581058
struct npy_format_descriptor_name<T, enable_if_t<std::is_integral<T>::value>> {
1059-
static constexpr auto name = _<std::is_same<T, bool>::value>(
1060-
_("bool"), _<std::is_signed<T>::value>("numpy.int", "numpy.uint") + _<sizeof(T)*8>()
1059+
static constexpr auto name = const_name<std::is_same<T, bool>::value>(
1060+
const_name("bool"), const_name<std::is_signed<T>::value>("numpy.int", "numpy.uint") + const_name<sizeof(T)*8>()
10611061
);
10621062
};
10631063

10641064
template <typename T>
10651065
struct npy_format_descriptor_name<T, enable_if_t<std::is_floating_point<T>::value>> {
1066-
static constexpr auto name = _<std::is_same<T, float>::value
1066+
static constexpr auto name = const_name<std::is_same<T, float>::value
10671067
|| std::is_same<T, const float>::value
10681068
|| std::is_same<T, double>::value
10691069
|| std::is_same<T, const double>::value>(
1070-
_("numpy.float") + _<sizeof(T)*8>(), _("numpy.longdouble")
1070+
const_name("numpy.float") + const_name<sizeof(T)*8>(), const_name("numpy.longdouble")
10711071
);
10721072
};
10731073

10741074
template <typename T>
10751075
struct npy_format_descriptor_name<T, enable_if_t<is_complex<T>::value>> {
1076-
static constexpr auto name = _<std::is_same<typename T::value_type, float>::value
1076+
static constexpr auto name = const_name<std::is_same<typename T::value_type, float>::value
10771077
|| std::is_same<typename T::value_type, const float>::value
10781078
|| std::is_same<typename T::value_type, double>::value
10791079
|| std::is_same<typename T::value_type, const double>::value>(
1080-
_("numpy.complex") + _<sizeof(typename T::value_type)*16>(), _("numpy.longcomplex")
1080+
const_name("numpy.complex") + const_name<sizeof(typename T::value_type)*16>(), const_name("numpy.longcomplex")
10811081
);
10821082
};
10831083

@@ -1105,7 +1105,7 @@ struct npy_format_descriptor<T, enable_if_t<satisfies_any_of<T, std::is_arithmet
11051105
};
11061106

11071107
#define PYBIND11_DECL_CHAR_FMT \
1108-
static constexpr auto name = _("S") + _<N>(); \
1108+
static constexpr auto name = const_name("S") + const_name<N>(); \
11091109
static pybind11::dtype dtype() { return pybind11::dtype(std::string("S") + std::to_string(N)); }
11101110
template <size_t N> struct npy_format_descriptor<char[N]> { PYBIND11_DECL_CHAR_FMT };
11111111
template <size_t N> struct npy_format_descriptor<std::array<char, N>> { PYBIND11_DECL_CHAR_FMT };
@@ -1117,7 +1117,7 @@ template<typename T> struct npy_format_descriptor<T, enable_if_t<array_info<T>::
11171117
public:
11181118
static_assert(!array_info<T>::is_empty, "Zero-sized arrays are not supported");
11191119

1120-
static constexpr auto name = _("(") + array_info<T>::extents + _(")") + base_descr::name;
1120+
static constexpr auto name = const_name("(") + array_info<T>::extents + const_name(")") + base_descr::name;
11211121
static pybind11::dtype dtype() {
11221122
list shape;
11231123
array_info<T>::append_extents(shape);
@@ -1705,7 +1705,7 @@ vectorize_extractor(const Func &f, Return (*) (Args ...)) {
17051705
}
17061706

17071707
template <typename T, int Flags> struct handle_type_name<array_t<T, Flags>> {
1708-
static constexpr auto name = _("numpy.ndarray[") + npy_format_descriptor<T>::name + _("]");
1708+
static constexpr auto name = const_name("numpy.ndarray[") + npy_format_descriptor<T>::name + const_name("]");
17091709
};
17101710

17111711
PYBIND11_NAMESPACE_END(detail)

include/pybind11/pybind11.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ class cpp_function : public function {
262262
}
263263

264264
/* Generate a readable signature describing the function's arguments and return value types */
265-
static constexpr auto signature = _("(") + cast_in::arg_names + _(") -> ") + cast_out::name;
265+
static constexpr auto signature = const_name("(") + cast_in::arg_names + const_name(") -> ") + cast_out::name;
266266
PYBIND11_DESCR_CONSTEXPR auto types = decltype(signature)::types();
267267

268268
/* Register the function with Python from generic (non-templated) code */

0 commit comments

Comments
 (0)