mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-24 22:25:10 +00:00
Adding dedicated test_const_name. (#3578)
* Adding dedicated test_const_name. Also exercises pybind11::detail::_ backward compatibility. See also: PR #3423 * Backing out tests involving int_to_str (requires C++17 or higher). * Suppressing clang-tidy errors. * Disabling test_const_name for MSVC 2015 due to bizarre failures. * Stacking @pytest.mark.parametrize (thanks to @skylion007 for pointing out).
This commit is contained in:
parent
9b4f71d12d
commit
1bbaeb3462
@ -59,6 +59,7 @@ constexpr descr<0> const_name(char const(&)[1]) { return {}; }
|
|||||||
|
|
||||||
template <size_t Rem, size_t... Digits> struct int_to_str : int_to_str<Rem/10, Rem%10, Digits...> { };
|
template <size_t Rem, size_t... Digits> struct int_to_str : int_to_str<Rem/10, Rem%10, Digits...> { };
|
||||||
template <size_t...Digits> struct int_to_str<0, Digits...> {
|
template <size_t...Digits> struct int_to_str<0, Digits...> {
|
||||||
|
// WARNING: This only works with C++17 or higher.
|
||||||
static constexpr auto digits = descr<sizeof...(Digits)>(('0' + Digits)...);
|
static constexpr auto digits = descr<sizeof...(Digits)>(('0' + Digits)...);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -84,9 +85,12 @@ auto constexpr const_name() -> remove_cv_t<decltype(int_to_str<Size / 10, Size %
|
|||||||
|
|
||||||
template <typename Type> constexpr descr<1, Type> const_name() { return {'%'}; }
|
template <typename Type> constexpr descr<1, Type> const_name() { return {'%'}; }
|
||||||
|
|
||||||
// The "_" might be defined as a macro - don't define it if so.
|
// If "_" is defined as a macro, py::detail::_ cannot be provided.
|
||||||
// Repeating the const_name code to avoid introducing a #define.
|
// It is therefore best to use py::detail::const_name universally.
|
||||||
|
// This block is for backward compatibility only.
|
||||||
|
// (The const_name code is repeated to avoid introducing a "_" #define ourselves.)
|
||||||
#ifndef _
|
#ifndef _
|
||||||
|
#define PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
constexpr descr<N-1> _(char const(&text)[N]) { return const_name<N>(text); }
|
constexpr descr<N-1> _(char const(&text)[N]) { return const_name<N>(text); }
|
||||||
template <bool B, size_t N1, size_t N2>
|
template <bool B, size_t N1, size_t N2>
|
||||||
@ -107,7 +111,7 @@ auto constexpr _() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::dig
|
|||||||
return const_name<Size>();
|
return const_name<Size>();
|
||||||
}
|
}
|
||||||
template <typename Type> constexpr descr<1, Type> _() { return const_name<Type>(); }
|
template <typename Type> constexpr descr<1, Type> _() { return const_name<Type>(); }
|
||||||
#endif
|
#endif // #ifndef _
|
||||||
|
|
||||||
constexpr descr<0> concat() { return {}; }
|
constexpr descr<0> concat() { return {}; }
|
||||||
|
|
||||||
|
@ -101,6 +101,7 @@ set(PYBIND11_TEST_FILES
|
|||||||
test_callbacks.cpp
|
test_callbacks.cpp
|
||||||
test_chrono.cpp
|
test_chrono.cpp
|
||||||
test_class.cpp
|
test_class.cpp
|
||||||
|
test_const_name.cpp
|
||||||
test_constants_and_functions.cpp
|
test_constants_and_functions.cpp
|
||||||
test_copy_move.cpp
|
test_copy_move.cpp
|
||||||
test_custom_type_casters.cpp
|
test_custom_type_casters.cpp
|
||||||
|
70
tests/test_const_name.cpp
Normal file
70
tests/test_const_name.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// Copyright (c) 2021 The Pybind Development Team.
|
||||||
|
// All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "pybind11_tests.h"
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER < 1910
|
||||||
|
|
||||||
|
// MSVC 2015 fails in bizarre ways.
|
||||||
|
# define PYBIND11_SKIP_TEST_CONST_NAME
|
||||||
|
|
||||||
|
#else // Only test with MSVC 2017 or newer.
|
||||||
|
|
||||||
|
// IUT = Implementation Under Test
|
||||||
|
# define CONST_NAME_TESTS(TEST_FUNC, IUT) \
|
||||||
|
std::string TEST_FUNC(int selector) { \
|
||||||
|
switch (selector) { \
|
||||||
|
case 0: \
|
||||||
|
return IUT("").text; \
|
||||||
|
case 1: \
|
||||||
|
return IUT("A").text; \
|
||||||
|
case 2: \
|
||||||
|
return IUT("Bd").text; \
|
||||||
|
case 3: \
|
||||||
|
return IUT("Cef").text; \
|
||||||
|
case 4: \
|
||||||
|
return IUT<int>().text; /*NOLINT(bugprone-macro-parentheses)*/ \
|
||||||
|
case 5: \
|
||||||
|
return IUT<std::string>().text; /*NOLINT(bugprone-macro-parentheses)*/ \
|
||||||
|
case 6: \
|
||||||
|
return IUT<true>("T1", "T2").text; /*NOLINT(bugprone-macro-parentheses)*/ \
|
||||||
|
case 7: \
|
||||||
|
return IUT<false>("U1", "U2").text; /*NOLINT(bugprone-macro-parentheses)*/ \
|
||||||
|
case 8: \
|
||||||
|
/*NOLINTNEXTLINE(bugprone-macro-parentheses)*/ \
|
||||||
|
return IUT<true>(IUT("D1"), IUT("D2")).text; \
|
||||||
|
case 9: \
|
||||||
|
/*NOLINTNEXTLINE(bugprone-macro-parentheses)*/ \
|
||||||
|
return IUT<false>(IUT("E1"), IUT("E2")).text; \
|
||||||
|
case 10: \
|
||||||
|
return IUT("KeepAtEnd").text; \
|
||||||
|
default: \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
throw std::runtime_error("Invalid selector value."); \
|
||||||
|
}
|
||||||
|
|
||||||
|
CONST_NAME_TESTS(const_name_tests, py::detail::const_name)
|
||||||
|
|
||||||
|
# ifdef PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY
|
||||||
|
CONST_NAME_TESTS(underscore_tests, py::detail::_)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif // MSVC >= 2017
|
||||||
|
|
||||||
|
TEST_SUBMODULE(const_name, m) {
|
||||||
|
#ifdef PYBIND11_SKIP_TEST_CONST_NAME
|
||||||
|
m.attr("const_name_tests") = "PYBIND11_SKIP_TEST_CONST_NAME";
|
||||||
|
#else
|
||||||
|
m.def("const_name_tests", const_name_tests);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PYBIND11_SKIP_TEST_CONST_NAME
|
||||||
|
m.attr("underscore_tests") = "PYBIND11_SKIP_TEST_CONST_NAME";
|
||||||
|
#elif defined(PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY)
|
||||||
|
m.def("underscore_tests", underscore_tests);
|
||||||
|
#else
|
||||||
|
m.attr("underscore_tests") = "PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY not defined.";
|
||||||
|
#endif
|
||||||
|
}
|
31
tests/test_const_name.py
Normal file
31
tests/test_const_name.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
import env
|
||||||
|
from pybind11_tests import const_name as m
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("func", (m.const_name_tests, m.underscore_tests))
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"selector, expected",
|
||||||
|
enumerate(
|
||||||
|
(
|
||||||
|
"",
|
||||||
|
"A",
|
||||||
|
"Bd",
|
||||||
|
"Cef",
|
||||||
|
"%",
|
||||||
|
"%",
|
||||||
|
"T1",
|
||||||
|
"U2",
|
||||||
|
"D1",
|
||||||
|
"E2",
|
||||||
|
"KeepAtEnd",
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
def test_const_name(func, selector, expected):
|
||||||
|
if isinstance(func, type(u"") if env.PY2 else str):
|
||||||
|
pytest.skip(func)
|
||||||
|
text = func(selector)
|
||||||
|
assert text == expected
|
@ -19,7 +19,7 @@ namespace pybind11 { namespace detail {
|
|||||||
template <> struct type_caster<ArgInspector1> {
|
template <> struct type_caster<ArgInspector1> {
|
||||||
public:
|
public:
|
||||||
// Classic
|
// Classic
|
||||||
#ifndef _
|
#ifdef PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY
|
||||||
PYBIND11_TYPE_CASTER(ArgInspector1, _("ArgInspector1"));
|
PYBIND11_TYPE_CASTER(ArgInspector1, _("ArgInspector1"));
|
||||||
#else
|
#else
|
||||||
PYBIND11_TYPE_CASTER(ArgInspector1, const_name("ArgInspector1"));
|
PYBIND11_TYPE_CASTER(ArgInspector1, const_name("ArgInspector1"));
|
||||||
|
Loading…
Reference in New Issue
Block a user