github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/pybind11/docs/upgrade.rst (about)

     1  Upgrade guide
     2  #############
     3  
     4  This is a companion guide to the :doc:`changelog`. While the changelog briefly
     5  lists all of the new features, improvements and bug fixes, this upgrade guide
     6  focuses only the subset which directly impacts your experience when upgrading
     7  to a new version. But it goes into more detail. This includes things like
     8  deprecated APIs and their replacements, build system changes, general code
     9  modernization and other useful information.
    10  
    11  .. _upgrade-guide-2.9:
    12  
    13  v2.9
    14  ====
    15  
    16  * Any usage of the recently added ``py::make_simple_namespace`` should be
    17    converted to using ``py::module_::import("types").attr("SimpleNamespace")``
    18    instead.
    19  
    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  
    24  
    25  .. _upgrade-guide-2.7:
    26  
    27  v2.7
    28  ====
    29  
    30  *Before* v2.7, ``py::str`` can hold ``PyUnicodeObject`` or ``PyBytesObject``,
    31  and ``py::isinstance<str>()`` is ``true`` for both ``py::str`` and
    32  ``py::bytes``. Starting with v2.7, ``py::str`` exclusively holds
    33  ``PyUnicodeObject`` (`#2409 <https://github.com/pybind/pybind11/pull/2409>`_),
    34  and ``py::isinstance<str>()`` is ``true`` only for ``py::str``. To help in
    35  the transition of user code, the ``PYBIND11_STR_LEGACY_PERMISSIVE`` macro
    36  is provided as an escape hatch to go back to the legacy behavior. This macro
    37  will be removed in future releases. Two types of required fixes are expected
    38  to be common:
    39  
    40  * Accidental use of ``py::str`` instead of ``py::bytes``, masked by the legacy
    41    behavior. These are probably very easy to fix, by changing from
    42    ``py::str`` to ``py::bytes``.
    43  
    44  * Reliance on py::isinstance<str>(obj) being ``true`` for
    45    ``py::bytes``. This is likely to be easy to fix in most cases by adding
    46    ``|| py::isinstance<bytes>(obj)``, but a fix may be more involved, e.g. if
    47    ``py::isinstance<T>`` appears in a template. Such situations will require
    48    careful review and custom fixes.
    49  
    50  
    51  .. _upgrade-guide-2.6:
    52  
    53  v2.6
    54  ====
    55  
    56  Usage of the ``PYBIND11_OVERLOAD*`` macros and ``get_overload`` function should
    57  be replaced by ``PYBIND11_OVERRIDE*`` and ``get_override``. In the future, the
    58  old macros may be deprecated and removed.
    59  
    60  ``py::module`` has been renamed ``py::module_``, but a backward compatible
    61  typedef has been included. This change was to avoid a language change in C++20
    62  that requires unqualified ``module`` not be placed at the start of a logical
    63  line. Qualified usage is unaffected and the typedef will remain unless the
    64  C++ language rules change again.
    65  
    66  The public constructors of ``py::module_`` have been deprecated. Use
    67  ``PYBIND11_MODULE`` or ``module_::create_extension_module`` instead.
    68  
    69  An error is now thrown when ``__init__`` is forgotten on subclasses. This was
    70  incorrect before, but was not checked. Add a call to ``__init__`` if it is
    71  missing.
    72  
    73  A ``py::type_error`` is now thrown when casting to a subclass (like
    74  ``py::bytes`` from ``py::object``) if the conversion is not valid. Make a valid
    75  conversion instead.
    76  
    77  The undocumented ``h.get_type()`` method has been deprecated and replaced by
    78  ``py::type::of(h)``.
    79  
    80  Enums now have a ``__str__`` method pre-defined; if you want to override it,
    81  the simplest fix is to add the new ``py::prepend()`` tag when defining
    82  ``"__str__"``.
    83  
    84  If ``__eq__`` defined but not ``__hash__``, ``__hash__`` is now set to
    85  ``None``, as in normal CPython. You should add ``__hash__`` if you intended the
    86  class to be hashable, possibly using the new ``py::hash`` shortcut.
    87  
    88  The constructors for ``py::array`` now always take signed integers for size,
    89  for consistency. This may lead to compiler warnings on some systems. Cast to
    90  ``py::ssize_t`` instead of ``std::size_t``.
    91  
    92  The ``tools/clang`` submodule and ``tools/mkdoc.py`` have been moved to a
    93  standalone package, `pybind11-mkdoc`_. If you were using those tools, please
    94  use them via a pip install from the new location.
    95  
    96  The ``pybind11`` package on PyPI no longer fills the wheel "headers" slot - if
    97  you were using the headers from this slot, they are available by requesting the
    98  ``global`` extra, that is, ``pip install "pybind11[global]"``. (Most users will
    99  be unaffected, as the ``pybind11/include`` location is reported by ``python -m
   100  pybind11 --includes`` and ``pybind11.get_include()`` is still correct and has
   101  not changed since 2.5).
   102  
   103  .. _pybind11-mkdoc: https://github.com/pybind/pybind11-mkdoc
   104  
   105  CMake support:
   106  --------------
   107  
   108  The minimum required version of CMake is now 3.4.  Several details of the CMake
   109  support have been deprecated; warnings will be shown if you need to change
   110  something. The changes are:
   111  
   112  * ``PYBIND11_CPP_STANDARD=<platform-flag>`` is deprecated, please use
   113    ``CMAKE_CXX_STANDARD=<number>`` instead, or any other valid CMake CXX or CUDA
   114    standard selection method, like ``target_compile_features``.
   115  
   116  * If you do not request a standard, pybind11 targets will compile with the
   117    compiler default, but not less than C++11, instead of forcing C++14 always.
   118    If you depend on the old behavior, please use ``set(CMAKE_CXX_STANDARD 14 CACHE STRING "")``
   119    instead.
   120  
   121  * Direct ``pybind11::module`` usage should always be accompanied by at least
   122    ``set(CMAKE_CXX_VISIBILITY_PRESET hidden)`` or similar - it used to try to
   123    manually force this compiler flag (but not correctly on all compilers or with
   124    CUDA).
   125  
   126  * ``pybind11_add_module``'s ``SYSTEM`` argument is deprecated and does nothing;
   127    linking now behaves like other imported libraries consistently in both
   128    config and submodule mode, and behaves like a ``SYSTEM`` library by
   129    default.
   130  
   131  * If ``PYTHON_EXECUTABLE`` is not set, virtual environments (``venv``,
   132    ``virtualenv``, and ``conda``) are prioritized over the standard search
   133    (similar to the new FindPython mode).
   134  
   135  In addition, the following changes may be of interest:
   136  
   137  * ``CMAKE_INTERPROCEDURAL_OPTIMIZATION`` will be respected by
   138    ``pybind11_add_module`` if set instead of linking to ``pybind11::lto`` or
   139    ``pybind11::thin_lto``.
   140  
   141  * Using ``find_package(Python COMPONENTS Interpreter Development)`` before
   142    pybind11 will cause pybind11 to use the new Python mechanisms instead of its
   143    own custom search, based on a patched version of classic ``FindPythonInterp``
   144    / ``FindPythonLibs``. In the future, this may become the default. A recent
   145    (3.15+ or 3.18.2+) version of CMake is recommended.
   146  
   147  
   148  
   149  v2.5
   150  ====
   151  
   152  The Python package now includes the headers as data in the package itself, as
   153  well as in the "headers" wheel slot. ``pybind11 --includes`` and
   154  ``pybind11.get_include()`` report the new location, which is always correct
   155  regardless of how pybind11 was installed, making the old ``user=`` argument
   156  meaningless. If you are not using the function to get the location already, you
   157  are encouraged to switch to the package location.
   158  
   159  
   160  v2.2
   161  ====
   162  
   163  Deprecation of the ``PYBIND11_PLUGIN`` macro
   164  --------------------------------------------
   165  
   166  ``PYBIND11_MODULE`` is now the preferred way to create module entry points.
   167  The old macro emits a compile-time deprecation warning.
   168  
   169  .. code-block:: cpp
   170  
   171      // old
   172      PYBIND11_PLUGIN(example) {
   173          py::module m("example", "documentation string");
   174  
   175          m.def("add", [](int a, int b) { return a + b; });
   176  
   177          return m.ptr();
   178      }
   179  
   180      // new
   181      PYBIND11_MODULE(example, m) {
   182          m.doc() = "documentation string"; // optional
   183  
   184          m.def("add", [](int a, int b) { return a + b; });
   185      }
   186  
   187  
   188  New API for defining custom constructors and pickling functions
   189  ---------------------------------------------------------------
   190  
   191  The old placement-new custom constructors have been deprecated. The new approach
   192  uses ``py::init()`` and factory functions to greatly improve type safety.
   193  
   194  Placement-new can be called accidentally with an incompatible type (without any
   195  compiler errors or warnings), or it can initialize the same object multiple times
   196  if not careful with the Python-side ``__init__`` calls. The new-style custom
   197  constructors prevent such mistakes. See :ref:`custom_constructors` for details.
   198  
   199  .. code-block:: cpp
   200  
   201      // old -- deprecated (runtime warning shown only in debug mode)
   202      py::class<Foo>(m, "Foo")
   203          .def("__init__", [](Foo &self, ...) {
   204              new (&self) Foo(...); // uses placement-new
   205          });
   206  
   207      // new
   208      py::class<Foo>(m, "Foo")
   209          .def(py::init([](...) { // Note: no `self` argument
   210              return new Foo(...); // return by raw pointer
   211              // or: return std::make_unique<Foo>(...); // return by holder
   212              // or: return Foo(...); // return by value (move constructor)
   213          }));
   214  
   215  Mirroring the custom constructor changes, ``py::pickle()`` is now the preferred
   216  way to get and set object state. See :ref:`pickling` for details.
   217  
   218  .. code-block:: cpp
   219  
   220      // old -- deprecated (runtime warning shown only in debug mode)
   221      py::class<Foo>(m, "Foo")
   222          ...
   223          .def("__getstate__", [](const Foo &self) {
   224              return py::make_tuple(self.value1(), self.value2(), ...);
   225          })
   226          .def("__setstate__", [](Foo &self, py::tuple t) {
   227              new (&self) Foo(t[0].cast<std::string>(), ...);
   228          });
   229  
   230      // new
   231      py::class<Foo>(m, "Foo")
   232          ...
   233          .def(py::pickle(
   234              [](const Foo &self) { // __getstate__
   235                  return py::make_tuple(self.value1(), self.value2(), ...); // unchanged
   236              },
   237              [](py::tuple t) { // __setstate__, note: no `self` argument
   238                  return new Foo(t[0].cast<std::string>(), ...);
   239                  // or: return std::make_unique<Foo>(...); // return by holder
   240                  // or: return Foo(...); // return by value (move constructor)
   241              }
   242          ));
   243  
   244  For both the constructors and pickling, warnings are shown at module
   245  initialization time (on import, not when the functions are called).
   246  They're only visible when compiled in debug mode. Sample warning:
   247  
   248  .. code-block:: none
   249  
   250      pybind11-bound class 'mymodule.Foo' is using an old-style placement-new '__init__'
   251      which has been deprecated. See the upgrade guide in pybind11's docs.
   252  
   253  
   254  Stricter enforcement of hidden symbol visibility for pybind11 modules
   255  ---------------------------------------------------------------------
   256  
   257  pybind11 now tries to actively enforce hidden symbol visibility for modules.
   258  If you're using either one of pybind11's :doc:`CMake or Python build systems
   259  <compiling>` (the two example repositories) and you haven't been exporting any
   260  symbols, there's nothing to be concerned about. All the changes have been done
   261  transparently in the background. If you were building manually or relied on
   262  specific default visibility, read on.
   263  
   264  Setting default symbol visibility to *hidden* has always been recommended for
   265  pybind11 (see :ref:`faq:symhidden`). On Linux and macOS, hidden symbol
   266  visibility (in conjunction with the ``strip`` utility) yields much smaller
   267  module binaries. `CPython's extension docs`_ also recommend hiding symbols
   268  by default, with the goal of avoiding symbol name clashes between modules.
   269  Starting with v2.2, pybind11 enforces this more strictly: (1) by declaring
   270  all symbols inside the ``pybind11`` namespace as hidden and (2) by including
   271  the ``-fvisibility=hidden`` flag on Linux and macOS (only for extension
   272  modules, not for embedding the interpreter).
   273  
   274  .. _CPython's extension docs: https://docs.python.org/3/extending/extending.html#providing-a-c-api-for-an-extension-module
   275  
   276  The namespace-scope hidden visibility is done automatically in pybind11's
   277  headers and it's generally transparent to users. It ensures that:
   278  
   279  * Modules compiled with different pybind11 versions don't clash with each other.
   280  
   281  * Some new features, like ``py::module_local`` bindings, can work as intended.
   282  
   283  The ``-fvisibility=hidden`` flag applies the same visibility to user bindings
   284  outside of the ``pybind11`` namespace. It's now set automatic by pybind11's
   285  CMake and Python build systems, but this needs to be done manually by users
   286  of other build systems. Adding this flag:
   287  
   288  * Minimizes the chances of symbol conflicts between modules. E.g. if two
   289    unrelated modules were statically linked to different (ABI-incompatible)
   290    versions of the same third-party library, a symbol clash would be likely
   291    (and would end with unpredictable results).
   292  
   293  * Produces smaller binaries on Linux and macOS, as pointed out previously.
   294  
   295  Within pybind11's CMake build system, ``pybind11_add_module`` has always been
   296  setting the ``-fvisibility=hidden`` flag in release mode. From now on, it's
   297  being applied unconditionally, even in debug mode and it can no longer be opted
   298  out of with the ``NO_EXTRAS`` option. The ``pybind11::module`` target now also
   299  adds this flag to its interface. The ``pybind11::embed`` target is unchanged.
   300  
   301  The most significant change here is for the ``pybind11::module`` target. If you
   302  were previously relying on default visibility, i.e. if your Python module was
   303  doubling as a shared library with dependents, you'll need to either export
   304  symbols manually (recommended for cross-platform libraries) or factor out the
   305  shared library (and have the Python module link to it like the other
   306  dependents). As a temporary workaround, you can also restore default visibility
   307  using the CMake code below, but this is not recommended in the long run:
   308  
   309  .. code-block:: cmake
   310  
   311      target_link_libraries(mymodule PRIVATE pybind11::module)
   312  
   313      add_library(restore_default_visibility INTERFACE)
   314      target_compile_options(restore_default_visibility INTERFACE -fvisibility=default)
   315      target_link_libraries(mymodule PRIVATE restore_default_visibility)
   316  
   317  
   318  Local STL container bindings
   319  ----------------------------
   320  
   321  Previous pybind11 versions could only bind types globally -- all pybind11
   322  modules, even unrelated ones, would have access to the same exported types.
   323  However, this would also result in a conflict if two modules exported the
   324  same C++ type, which is especially problematic for very common types, e.g.
   325  ``std::vector<int>``. :ref:`module_local` were added to resolve this (see
   326  that section for a complete usage guide).
   327  
   328  ``py::class_`` still defaults to global bindings (because these types are
   329  usually unique across modules), however in order to avoid clashes of opaque
   330  types, ``py::bind_vector`` and ``py::bind_map`` will now bind STL containers
   331  as ``py::module_local`` if their elements are: builtins (``int``, ``float``,
   332  etc.), not bound using ``py::class_``, or bound as ``py::module_local``. For
   333  example, this change allows multiple modules to bind ``std::vector<int>``
   334  without causing conflicts. See :ref:`stl_bind` for more details.
   335  
   336  When upgrading to this version, if you have multiple modules which depend on
   337  a single global binding of an STL container, note that all modules can still
   338  accept foreign  ``py::module_local`` types in the direction of Python-to-C++.
   339  The locality only affects the C++-to-Python direction. If this is needed in
   340  multiple modules, you'll need to either:
   341  
   342  * Add a copy of the same STL binding to all of the modules which need it.
   343  
   344  * Restore the global status of that single binding by marking it
   345    ``py::module_local(false)``.
   346  
   347  The latter is an easy workaround, but in the long run it would be best to
   348  localize all common type bindings in order to avoid conflicts with
   349  third-party modules.
   350  
   351  
   352  Negative strides for Python buffer objects and numpy arrays
   353  -----------------------------------------------------------
   354  
   355  Support for negative strides required changing the integer type from unsigned
   356  to signed in the interfaces of ``py::buffer_info`` and ``py::array``. If you
   357  have compiler warnings enabled, you may notice some new conversion warnings
   358  after upgrading. These can be resolved using ``static_cast``.
   359  
   360  
   361  Deprecation of some ``py::object`` APIs
   362  ---------------------------------------
   363  
   364  To compare ``py::object`` instances by pointer, you should now use
   365  ``obj1.is(obj2)`` which is equivalent to ``obj1 is obj2`` in Python.
   366  Previously, pybind11 used ``operator==`` for this (``obj1 == obj2``), but
   367  that could be confusing and is now deprecated (so that it can eventually
   368  be replaced with proper rich object comparison in a future release).
   369  
   370  For classes which inherit from ``py::object``, ``borrowed`` and ``stolen``
   371  were previously available as protected constructor tags. Now the types
   372  should be used directly instead: ``borrowed_t{}`` and ``stolen_t{}``
   373  (`#771 <https://github.com/pybind/pybind11/pull/771>`_).
   374  
   375  
   376  Stricter compile-time error checking
   377  ------------------------------------
   378  
   379  Some error checks have been moved from run time to compile time. Notably,
   380  automatic conversion of ``std::shared_ptr<T>`` is not possible when ``T`` is
   381  not directly registered with ``py::class_<T>`` (e.g. ``std::shared_ptr<int>``
   382  or ``std::shared_ptr<std::vector<T>>`` are not automatically convertible).
   383  Attempting to bind a function with such arguments now results in a compile-time
   384  error instead of waiting to fail at run time.
   385  
   386  ``py::init<...>()`` constructor definitions are also stricter and now prevent
   387  bindings which could cause unexpected behavior:
   388  
   389  .. code-block:: cpp
   390  
   391      struct Example {
   392          Example(int &);
   393      };
   394  
   395      py::class_<Example>(m, "Example")
   396          .def(py::init<int &>()); // OK, exact match
   397          // .def(py::init<int>()); // compile-time error, mismatch
   398  
   399  A non-``const`` lvalue reference is not allowed to bind to an rvalue. However,
   400  note that a constructor taking ``const T &`` can still be registered using
   401  ``py::init<T>()`` because a ``const`` lvalue reference can bind to an rvalue.
   402  
   403  v2.1
   404  ====
   405  
   406  Minimum compiler versions are enforced at compile time
   407  ------------------------------------------------------
   408  
   409  The minimums also apply to v2.0 but the check is now explicit and a compile-time
   410  error is raised if the compiler does not meet the requirements:
   411  
   412  * GCC >= 4.8
   413  * clang >= 3.3 (appleclang >= 5.0)
   414  * MSVC >= 2015u3
   415  * Intel C++ >= 15.0
   416  
   417  
   418  The ``py::metaclass`` attribute is not required for static properties
   419  ---------------------------------------------------------------------
   420  
   421  Binding classes with static properties is now possible by default. The
   422  zero-parameter version of ``py::metaclass()`` is deprecated. However, a new
   423  one-parameter ``py::metaclass(python_type)`` version was added for rare
   424  cases when a custom metaclass is needed to override pybind11's default.
   425  
   426  .. code-block:: cpp
   427  
   428      // old -- emits a deprecation warning
   429      py::class_<Foo>(m, "Foo", py::metaclass())
   430          .def_property_readonly_static("foo", ...);
   431  
   432      // new -- static properties work without the attribute
   433      py::class_<Foo>(m, "Foo")
   434          .def_property_readonly_static("foo", ...);
   435  
   436      // new -- advanced feature, override pybind11's default metaclass
   437      py::class_<Bar>(m, "Bar", py::metaclass(custom_python_type))
   438          ...
   439  
   440  
   441  v2.0
   442  ====
   443  
   444  Breaking changes in ``py::class_``
   445  ----------------------------------
   446  
   447  These changes were necessary to make type definitions in pybind11
   448  future-proof, to support PyPy via its ``cpyext`` mechanism (`#527
   449  <https://github.com/pybind/pybind11/pull/527>`_), and to improve efficiency
   450  (`rev. 86d825 <https://github.com/pybind/pybind11/commit/86d825>`_).
   451  
   452  1. Declarations of types that provide access via the buffer protocol must
   453     now include the ``py::buffer_protocol()`` annotation as an argument to
   454     the ``py::class_`` constructor.
   455  
   456     .. code-block:: cpp
   457  
   458         py::class_<Matrix>("Matrix", py::buffer_protocol())
   459             .def(py::init<...>())
   460             .def_buffer(...);
   461  
   462  2. Classes which include static properties (e.g. ``def_readwrite_static()``)
   463     must now include the ``py::metaclass()`` attribute. Note: this requirement
   464     has since been removed in v2.1. If you're upgrading from 1.x, it's
   465     recommended to skip directly to v2.1 or newer.
   466  
   467  3. This version of pybind11 uses a redesigned mechanism for instantiating
   468     trampoline classes that are used to override virtual methods from within
   469     Python. This led to the following user-visible syntax change:
   470  
   471     .. code-block:: cpp
   472  
   473         // old v1.x syntax
   474         py::class_<TrampolineClass>("MyClass")
   475             .alias<MyClass>()
   476             ...
   477  
   478         // new v2.x syntax
   479         py::class_<MyClass, TrampolineClass>("MyClass")
   480             ...
   481  
   482     Importantly, both the original and the trampoline class are now specified
   483     as arguments to the ``py::class_`` template, and the ``alias<..>()`` call
   484     is gone. The new scheme has zero overhead in cases when Python doesn't
   485     override any functions of the underlying C++ class.
   486     `rev. 86d825 <https://github.com/pybind/pybind11/commit/86d825>`_.
   487  
   488     The class type must be the first template argument given to ``py::class_``
   489     while the trampoline can be mixed in arbitrary order with other arguments
   490     (see the following section).
   491  
   492  
   493  Deprecation of the ``py::base<T>()`` attribute
   494  ----------------------------------------------
   495  
   496  ``py::base<T>()`` was deprecated in favor of specifying ``T`` as a template
   497  argument to ``py::class_``. This new syntax also supports multiple inheritance.
   498  Note that, while the type being exported must be the first argument in the
   499  ``py::class_<Class, ...>`` template, the order of the following types (bases,
   500  holder and/or trampoline) is not important.
   501  
   502  .. code-block:: cpp
   503  
   504      // old v1.x
   505      py::class_<Derived>("Derived", py::base<Base>());
   506  
   507      // new v2.x
   508      py::class_<Derived, Base>("Derived");
   509  
   510      // new -- multiple inheritance
   511      py::class_<Derived, Base1, Base2>("Derived");
   512  
   513      // new -- apart from `Derived` the argument order can be arbitrary
   514      py::class_<Derived, Base1, Holder, Base2, Trampoline>("Derived");
   515  
   516  
   517  Out-of-the-box support for ``std::shared_ptr``
   518  ----------------------------------------------
   519  
   520  The relevant type caster is now built in, so it's no longer necessary to
   521  include a declaration of the form:
   522  
   523  .. code-block:: cpp
   524  
   525      PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr<T>)
   526  
   527  Continuing to do so won't cause an error or even a deprecation warning,
   528  but it's completely redundant.
   529  
   530  
   531  Deprecation of a few ``py::object`` APIs
   532  ----------------------------------------
   533  
   534  All of the old-style calls emit deprecation warnings.
   535  
   536  +---------------------------------------+---------------------------------------------+
   537  |  Old syntax                           |  New syntax                                 |
   538  +=======================================+=============================================+
   539  | ``obj.call(args...)``                 | ``obj(args...)``                            |
   540  +---------------------------------------+---------------------------------------------+
   541  | ``obj.str()``                         | ``py::str(obj)``                            |
   542  +---------------------------------------+---------------------------------------------+
   543  | ``auto l = py::list(obj); l.check()`` | ``py::isinstance<py::list>(obj)``           |
   544  +---------------------------------------+---------------------------------------------+
   545  | ``py::object(ptr, true)``             | ``py::reinterpret_borrow<py::object>(ptr)`` |
   546  +---------------------------------------+---------------------------------------------+
   547  | ``py::object(ptr, false)``            | ``py::reinterpret_steal<py::object>(ptr)``  |
   548  +---------------------------------------+---------------------------------------------+
   549  | ``if (obj.attr("foo"))``              | ``if (py::hasattr(obj, "foo"))``            |
   550  +---------------------------------------+---------------------------------------------+
   551  | ``if (obj["bar"])``                   | ``if (obj.contains("bar"))``                |
   552  +---------------------------------------+---------------------------------------------+