Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dropping MSVC 2015 #3722

Merged
merged 17 commits into from
Feb 14, 2022
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
4 changes: 2 additions & 2 deletions .appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
version: 1.0.{build}
image:
- Visual Studio 2015
- Visual Studio 2017
test: off
skip_branch_with_pr: true
build:
Expand All @@ -13,7 +13,7 @@ environment:
CONFIG: Debug
install:
- ps: |
$env:CMAKE_GENERATOR = "Visual Studio 14 2015"
$env:CMAKE_GENERATOR = "Visual Studio 15 2017"
if ($env:PLATFORM -eq "x64") { $env:PYTHON = "$env:PYTHON-x64" }
$env:PATH = "C:\Python$env:PYTHON\;C:\Python$env:PYTHON\Scripts\;$env:PATH"
python -W ignore -m pip install --upgrade pip wheel
Expand Down
47 changes: 0 additions & 47 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -755,53 +755,6 @@ jobs:
- name: Python tests
run: cmake --build build -t pytest

win32-msvc2015:
name: "🐍 ${{ matrix.python }} • MSVC 2015 • x64"
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
python:
- 3.6
- 3.7
# todo: check/cpptest does not support 3.8+ yet

steps:
- uses: actions/checkout@v2

- name: Setup 🐍 ${{ matrix.python }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python }}

- name: Update CMake
uses: jwlawson/[email protected]

- name: Prepare MSVC
uses: ilammy/[email protected]
with:
toolset: 14.0

- name: Prepare env
run: |
python -m pip install -r tests/requirements.txt

# First build - C++11 mode and inplace
- name: Configure
run: >
cmake -S . -B build
-G "Visual Studio 14 2015" -A x64
-DPYBIND11_WERROR=ON
-DDOWNLOAD_CATCH=ON
-DDOWNLOAD_EIGEN=ON

- name: Build C++14
run: cmake --build build -j 2

- name: Run all checks
run: cmake --build build -t check


win32-msvc2017:
name: "🐍 ${{ matrix.python }} • MSVC 2017 • x64"
runs-on: windows-2016
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ Supported compilers
1. Clang/LLVM 3.3 or newer (for Apple Xcode's clang, this is 5.0.0 or
newer)
2. GCC 4.8 or newer
3. Microsoft Visual Studio 2015 Update 3 or newer
3. Microsoft Visual Studio 2017 or newer
4. Intel classic C++ compiler 18 or newer (ICC 20.2 tested in CI)
5. Cygwin/GCC (previously tested on 2.5.1)
6. NVCC (CUDA 11.0 tested in CI)
Expand Down
2 changes: 0 additions & 2 deletions docs/advanced/cast/stl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ included to tell pybind11 how to visit the variant.

pybind11 only supports the modern implementation of ``boost::variant``
which makes use of variadic templates. This requires Boost 1.56 or newer.
Additionally, on Windows, MSVC 2017 is required because ``boost::variant``
falls back to the old non-variadic implementation on MSVC 2015.

.. _opaque:

Expand Down
7 changes: 0 additions & 7 deletions docs/advanced/classes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1118,13 +1118,6 @@ described trampoline:
py::class_<A, Trampoline>(m, "A") // <-- `Trampoline` here
.def("foo", &Publicist::foo); // <-- `Publicist` here, not `Trampoline`!

.. note::

MSVC 2015 has a compiler bug (fixed in version 2017) which
requires a more explicit function binding in the form of
``.def("foo", static_cast<int (A::*)() const>(&Publicist::foo));``
where ``int (A::*)() const`` is the type of ``A::foo``.

Binding final classes
=====================

Expand Down
3 changes: 1 addition & 2 deletions docs/basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ The last line will both compile and run the tests.
Windows
-------

On Windows, only **Visual Studio 2015** and newer are supported since pybind11 relies
on various C++11 language features that break older versions of Visual Studio.
On Windows, only **Visual Studio 2017** and newer are supported.

.. Note::

Expand Down
3 changes: 1 addition & 2 deletions docs/classes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -434,8 +434,7 @@ you can use ``py::detail::overload_cast_impl`` with an additional set of parenth
.def("set", overload_cast_<int>()(&Pet::set), "Set the pet's age")
.def("set", overload_cast_<const std::string &>()(&Pet::set), "Set the pet's name");

.. [#cpp14] A compiler which supports the ``-std=c++14`` flag
or Visual Studio 2015 Update 2 and newer.
.. [#cpp14] A compiler which supports the ``-std=c++14`` flag.

.. note::

Expand Down
14 changes: 0 additions & 14 deletions docs/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -220,20 +220,6 @@ In addition to decreasing binary size, ``-fvisibility=hidden`` also avoids
potential serious issues when loading multiple modules and is required for
proper pybind operation. See the previous FAQ entry for more details.

Working with ancient Visual Studio 2008 builds on Windows
=========================================================

The official Windows distributions of Python are compiled using truly
ancient versions of Visual Studio that lack good C++11 support. Some users
implicitly assume that it would be impossible to load a plugin built with
Visual Studio 2015 into a Python distribution that was compiled using Visual
Studio 2008. However, no such issue exists: it's perfectly legitimate to
interface DLLs that are built with different compilers and/or C libraries.
Common gotchas to watch out for involve not ``free()``-ing memory region
that that were ``malloc()``-ed in another shared library, using data
structures with incompatible ABIs, and so on. pybind11 is very careful not
to make these types of mistakes.

How can I properly handle Ctrl-C in long-running functions?
===========================================================

Expand Down
5 changes: 2 additions & 3 deletions include/pybind11/attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ struct base {

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

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

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

/// Override pybind11's default metaclass
explicit metaclass(handle value) : value(value) {}
Expand Down
27 changes: 13 additions & 14 deletions include/pybind11/detail/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
// or newer.
# if _MSVC_LANG >= 201402L
# define PYBIND11_CPP14
# if _MSVC_LANG > 201402L && _MSC_VER >= 1910
# if _MSVC_LANG > 201402L
# define PYBIND11_CPP17
# if _MSVC_LANG >= 202002L
# define PYBIND11_CPP20
Expand Down Expand Up @@ -81,10 +81,8 @@
# error pybind11 requires gcc 4.8 or newer
# endif
#elif defined(_MSC_VER)
// Pybind hits various compiler bugs in 2015u2 and earlier, and also makes use of some stl features
// (e.g. std::negation) added in 2015u3:
# if _MSC_FULL_VER < 190024210
# error pybind11 requires MSVC 2015 update 3 or newer
# if _MSC_VER < 1910
# error pybind11 2.10+ requires MSVC 2017 or newer
# endif
#endif

Expand Down Expand Up @@ -149,7 +147,7 @@

/* Don't let Python.h #define (v)snprintf as macro because they are implemented
properly in Visual Studio since 2015. */
#if defined(_MSC_VER) && _MSC_VER >= 1900
#if defined(_MSC_VER)
# define HAVE_SNPRINTF 1
#endif

Expand Down Expand Up @@ -561,7 +559,7 @@ static_assert(std::is_standard_layout<instance>::value,
"Internal error: `pybind11::detail::instance` is not standard layout!");

/// from __cpp_future__ import (convenient aliases from C++14/17)
#if defined(PYBIND11_CPP14) && (!defined(_MSC_VER) || _MSC_VER >= 1910)
#if defined(PYBIND11_CPP14)
using std::conditional_t;
using std::enable_if_t;
using std::remove_cv_t;
Expand Down Expand Up @@ -824,10 +822,10 @@ struct is_template_base_of_impl {
/// Check if a template is the base of a type. For example:
/// `is_template_base_of<Base, T>` is true if `struct T : Base<U> {}` where U can be anything
template <template <typename...> class Base, typename T>
#if !defined(_MSC_VER)
#if defined(PYBIND11_CPP20) || !defined(_MSC_VER) // Sadly, all MSVC versions incl. 2022 need this.
using is_template_base_of
= decltype(is_template_base_of_impl<Base>::check((intrinsic_t<T> *) nullptr));
#else // MSVC2015 has trouble with decltype in template aliases
#else
struct is_template_base_of
: decltype(is_template_base_of_impl<Base>::check((intrinsic_t<T> *) nullptr)) {
};
Expand Down Expand Up @@ -1002,9 +1000,6 @@ struct nodelete {
PYBIND11_NAMESPACE_BEGIN(detail)
template <typename... Args>
struct overload_cast_impl {
// NOLINTNEXTLINE(modernize-use-equals-default): MSVC 2015 needs this
constexpr overload_cast_impl() {}

template <typename Return>
constexpr auto operator()(Return (*pf)(Args...)) const noexcept -> decltype(pf) {
return pf;
Expand All @@ -1031,8 +1026,12 @@ PYBIND11_NAMESPACE_END(detail)
/// - regular: static_cast<Return (Class::*)(Arg0, Arg1, Arg2)>(&Class::func)
/// - sweet: overload_cast<Arg0, Arg1, Arg2>(&Class::func)
template <typename... Args>
# if (defined(_MSC_VER) && _MSC_VER < 1920) /* MSVC 2017 */ \
|| (defined(__clang__) && __clang_major__ == 5)
static constexpr detail::overload_cast_impl<Args...> overload_cast = {};
// MSVC 2015 only accepts this particular initialization syntax for this variable template.
# else
static constexpr detail::overload_cast_impl<Args...> overload_cast;
# endif
henryiii marked this conversation as resolved.
Show resolved Hide resolved
#endif

/// Const member function selector for overload_cast
Expand Down Expand Up @@ -1118,7 +1117,7 @@ try_get_shared_from_this(std::enable_shared_from_this<T> *holder_value_ptr) {

// For silencing "unused" compiler warnings in special situations.
template <typename... Args>
#if defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER < 1920 // MSVC 2017
#if defined(_MSC_VER) && _MSC_VER < 1920 // MSVC 2017
constexpr
#endif
inline void
Expand Down
3 changes: 1 addition & 2 deletions include/pybind11/functional.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@ struct type_caster<std::function<Return(Args...)>> {
Return operator()(Args... args) const {
gil_scoped_acquire acq;
object retval(hfunc.f(std::forward<Args>(args)...));
/* Visual studio 2015 parser issue: need parentheses around this expression */
return (retval.template cast<Return>());
return retval.template cast<Return>();
}
};

Expand Down
6 changes: 0 additions & 6 deletions tests/pybind11_tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,6 @@
#include <pybind11/eval.h>
#include <pybind11/pybind11.h>

#if defined(_MSC_VER) && _MSC_VER < 1910
// We get some really long type names here which causes MSVC 2015 to emit warnings
# pragma warning( \
disable : 4503) // NOLINT: warning C4503: decorated name length exceeded, name was truncated
#endif

namespace py = pybind11;
using namespace pybind11::literals;

Expand Down
12 changes: 1 addition & 11 deletions tests/test_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,13 +354,7 @@ TEST_SUBMODULE(class_, m) {
using ProtectedA::foo;
};

py::class_<ProtectedA>(m, "ProtectedA")
.def(py::init<>())
#if !defined(_MSC_VER) || _MSC_VER >= 1910
.def("foo", &PublicistA::foo);
#else
.def("foo", static_cast<int (ProtectedA::*)() const>(&PublicistA::foo));
#endif
py::class_<ProtectedA>(m, "ProtectedA").def(py::init<>()).def("foo", &PublicistA::foo);

class ProtectedB {
public:
Expand Down Expand Up @@ -391,11 +385,7 @@ TEST_SUBMODULE(class_, m) {

py::class_<ProtectedB, TrampolineB>(m, "ProtectedB")
.def(py::init<>())
#if !defined(_MSC_VER) || _MSC_VER >= 1910
.def("foo", &PublicistB::foo);
#else
.def("foo", static_cast<int (ProtectedB::*)() const>(&PublicistB::foo));
#endif

// test_brace_initialization
struct BraceInitialization {
Expand Down
85 changes: 35 additions & 50 deletions tests/test_const_name.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,65 +4,50 @@

#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."); \
}
#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
#ifdef PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY
CONST_NAME_TESTS(underscore_tests, py::detail::_)
# endif

#endif // MSVC >= 2017
#endif

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)
#if defined(PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY)
m.def("underscore_tests", underscore_tests);
#else
m.attr("underscore_tests") = "PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY not defined.";
Expand Down
Loading