winrt-runtime 4.0.1__tar.gz → 4.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. {winrt_runtime-4.0.1/python/winrt_runtime.egg-info → winrt_runtime-4.0.2}/PKG-INFO +1 -1
  2. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2/python/winrt_runtime.egg-info}/PKG-INFO +1 -1
  3. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/_winrt.cpp +40 -0
  4. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/compose.cpp +23 -26
  5. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/compose.h +2 -2
  6. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/members.cpp +22 -18
  7. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/objects.cpp +193 -14
  8. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/objects.h +21 -0
  9. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/protocols.cpp +21 -6
  10. winrt_runtime-4.0.2/version.txt +1 -0
  11. winrt_runtime-4.0.1/version.txt +0 -1
  12. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/LICENSE +0 -0
  13. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/MANIFEST.in +0 -0
  14. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/README.md +0 -0
  15. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/pyproject.toml +0 -0
  16. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/python/winrt/__pyinstaller/__init__.py +0 -0
  17. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/python/winrt/__pyinstaller/hook-winrt.py +0 -0
  18. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/python/winrt/_winrt.pyi +0 -0
  19. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/python/winrt/py.typed +0 -0
  20. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/python/winrt/runtime/__init__.py +0 -0
  21. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/python/winrt/runtime/_internals.py +0 -0
  22. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/python/winrt/runtime/interop.py +0 -0
  23. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/python/winrt/runtime/py.typed +0 -0
  24. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/python/winrt/system/__init__.py +0 -0
  25. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/python/winrt/system/hresult.py +0 -0
  26. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/python/winrt/system/py.typed +0 -0
  27. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/python/winrt_runtime.egg-info/SOURCES.txt +0 -0
  28. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/python/winrt_runtime.egg-info/dependency_links.txt +0 -0
  29. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/python/winrt_runtime.egg-info/entry_points.txt +0 -0
  30. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/python/winrt_runtime.egg-info/requires.txt +0 -0
  31. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/python/winrt_runtime.egg-info/top_level.txt +0 -0
  32. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/requirements.txt +0 -0
  33. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/setup.cfg +0 -0
  34. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/setup.py +0 -0
  35. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/_winrt_array.cpp +0 -0
  36. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/_winrt_array.h +0 -0
  37. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/_winrt_box.cpp +0 -0
  38. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/_winrt_buffer.cpp +0 -0
  39. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/_winrt_buffer.h +0 -0
  40. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/arrays.cpp +0 -0
  41. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/arrays.h +0 -0
  42. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/async.cpp +0 -0
  43. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/async.h +0 -0
  44. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/callbacks.cpp +0 -0
  45. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/callbacks.h +0 -0
  46. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/collections.cpp +0 -0
  47. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/collections.h +0 -0
  48. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/delegates.cpp +0 -0
  49. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/delegates.h +0 -0
  50. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/enums.cpp +0 -0
  51. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/enums.h +0 -0
  52. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/errors.cpp +0 -0
  53. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/generics.cpp +0 -0
  54. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/generics.h +0 -0
  55. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/implements.cpp +0 -0
  56. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/implements.h +0 -0
  57. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/Windows.Foundation.Collections.h +0 -0
  58. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/Windows.Foundation.Metadata.h +0 -0
  59. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/Windows.Foundation.h +0 -0
  60. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/Windows.Storage.Streams.h +0 -0
  61. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/Windows.Storage.h +0 -0
  62. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/base.h +0 -0
  63. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/base_macros.h +0 -0
  64. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Devices.Geolocation.0.h +0 -0
  65. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Devices.Geolocation.1.h +0 -0
  66. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Foundation.0.h +0 -0
  67. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Foundation.1.h +0 -0
  68. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Foundation.2.h +0 -0
  69. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Foundation.Collections.0.h +0 -0
  70. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Foundation.Collections.1.h +0 -0
  71. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Foundation.Collections.2.h +0 -0
  72. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Foundation.Metadata.0.h +0 -0
  73. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Foundation.Metadata.1.h +0 -0
  74. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Foundation.Metadata.2.h +0 -0
  75. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Storage.0.h +0 -0
  76. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Storage.1.h +0 -0
  77. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Storage.2.h +0 -0
  78. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Storage.FileProperties.0.h +0 -0
  79. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Storage.FileProperties.1.h +0 -0
  80. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Storage.FileProperties.2.h +0 -0
  81. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Storage.Provider.0.h +0 -0
  82. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Storage.Provider.1.h +0 -0
  83. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Storage.Provider.2.h +0 -0
  84. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Storage.Search.0.h +0 -0
  85. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Storage.Search.1.h +0 -0
  86. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Storage.Search.2.h +0 -0
  87. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Storage.Streams.0.h +0 -0
  88. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Storage.Streams.1.h +0 -0
  89. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.Storage.Streams.2.h +0 -0
  90. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.System.0.h +0 -0
  91. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.System.1.h +0 -0
  92. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.System.2.h +0 -0
  93. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.System.RemoteSystems.0.h +0 -0
  94. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/cppwinrt/winrt/impl/Windows.System.RemoteSystems.1.h +0 -0
  95. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/pythoncapi_compat.h +0 -0
  96. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/pywinrt/abi.h +0 -0
  97. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/pywinrt/array.h +0 -0
  98. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/pywinrt/async.h +0 -0
  99. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/pywinrt/base.h +0 -0
  100. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/pywinrt/buffer.h +0 -0
  101. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/pywinrt/convert.h +0 -0
  102. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/pywinrt/errors.h +0 -0
  103. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/pywinrt/handles.h +0 -0
  104. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/pywinrt/prelude.h +0 -0
  105. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/pywinrt/throw_helpers.h +0 -0
  106. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/pywinrt/traits.h +0 -0
  107. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/include/pywinrt/wrappers.h +0 -0
  108. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/interp.cpp +0 -0
  109. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/interp.h +0 -0
  110. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/members.h +0 -0
  111. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/metaclass.h +0 -0
  112. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/module_state.h +0 -0
  113. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/numerics-buffer.cpp +0 -0
  114. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/numerics-buffer.h +0 -0
  115. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/numerics-statics.cpp +0 -0
  116. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/numerics-statics.h +0 -0
  117. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/numerics-traits.h +0 -0
  118. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/numerics-values.h +0 -0
  119. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/numerics.cpp +0 -0
  120. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/numerics.h +0 -0
  121. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/protocols.h +0 -0
  122. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/pycollections.cpp +0 -0
  123. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/pycollections.h +0 -0
  124. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/pymapping.cpp +0 -0
  125. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/pymapping.h +0 -0
  126. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/pysequence.cpp +0 -0
  127. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/pysequence.h +0 -0
  128. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/runtime.cpp +0 -0
  129. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/runtime.h +0 -0
  130. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/shapes-generated.h +0 -0
  131. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/shapes.cpp +0 -0
  132. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/shapes.h +0 -0
  133. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/structs.cpp +0 -0
  134. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/structs.h +0 -0
  135. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/table.cpp +0 -0
  136. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/table.h +0 -0
  137. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/types.cpp +0 -0
  138. {winrt_runtime-4.0.1 → winrt_runtime-4.0.2}/src/types.h +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: winrt-runtime
3
- Version: 4.0.1
3
+ Version: 4.0.2
4
4
  Summary: The runtime that every PyWinRT projection package runs on
5
5
  License-Expression: MIT
6
6
  Project-URL: Documentation, https://pywinrt.readthedocs.io
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: winrt-runtime
3
- Version: 4.0.1
3
+ Version: 4.0.2
4
4
  Summary: The runtime that every PyWinRT projection package runs on
5
5
  License-Expression: MIT
6
6
  Project-URL: Documentation, https://pywinrt.readthedocs.io
@@ -322,9 +322,32 @@ namespace py::cpp::_winrt
322
322
  nullptr},
323
323
  {}};
324
324
 
325
+ /**
326
+ * __call__ of every projected class: what type's does, and then, for a
327
+ * Python class derived from a composable one whose __init__() returned
328
+ * without composing the instance, composing it with the call's arguments.
329
+ */
330
+ static PyObject* Object_Static_call(
331
+ PyObject* type, PyObject* args, PyObject* kwds) noexcept
332
+ {
333
+ py::pyobj_handle self{PyType_Type.tp_call(type, args, kwds)};
334
+ if (!self)
335
+ {
336
+ return nullptr;
337
+ }
338
+
339
+ if (!py::interp::compose_after_init(self.get(), args, kwds))
340
+ {
341
+ return nullptr;
342
+ }
343
+
344
+ return self.detach();
345
+ }
346
+
325
347
  static PyType_Slot Object_Static_type_slots[]
326
348
  = {{Py_tp_base, reinterpret_cast<void*>(&PyType_Type)},
327
349
  {Py_tp_methods, reinterpret_cast<void*>(Object_Static_methods)},
350
+ {Py_tp_call, reinterpret_cast<void*>(Object_Static_call)},
328
351
  {}};
329
352
 
330
353
  static PyType_Spec Object_Static_type_spec
@@ -377,6 +400,11 @@ namespace py::cpp::_winrt
377
400
  py::winrt_wrapper<winrt::Windows::Foundation::IInspectable>* self,
378
401
  void* /*unused*/) noexcept
379
402
  {
403
+ if (!py::interp::instance_abi(reinterpret_cast<PyObject*>(self)))
404
+ {
405
+ return nullptr;
406
+ }
407
+
380
408
  return py::interp::iids_of(self->obj);
381
409
  }
382
410
 
@@ -388,6 +416,11 @@ namespace py::cpp::_winrt
388
416
  py::winrt_wrapper<winrt::Windows::Foundation::IInspectable>* self,
389
417
  void* /*unused*/) noexcept
390
418
  {
419
+ if (!py::interp::instance_abi(reinterpret_cast<PyObject*>(self)))
420
+ {
421
+ return nullptr;
422
+ }
423
+
391
424
  return py::interp::runtime_class_name_of(self->obj);
392
425
  }
393
426
 
@@ -470,6 +503,13 @@ namespace py::cpp::_winrt
470
503
  Py_RETURN_NOTIMPLEMENTED;
471
504
  }
472
505
 
506
+ // A Python object derived from a composable class holds nothing until
507
+ // its __init__() has composed it, and is no other object until then.
508
+ if (!self->obj)
509
+ {
510
+ Py_RETURN_NOTIMPLEMENTED;
511
+ }
512
+
473
513
  auto const equal
474
514
  = self->obj
475
515
  == reinterpret_cast<
@@ -923,21 +923,24 @@ namespace py::interp
923
923
  }
924
924
 
925
925
  /**
926
- * Makes an instance of @p type, which is a Python class derived from the
927
- * composable class @p entry: the Python object, and the WinRT object it is
928
- * composed into, each holding the other.
926
+ * Composes @p self, an instance of a Python class derived from the
927
+ * composable class @p entry that holds nothing yet, into a WinRT object:
928
+ * the Python object, and the WinRT object it is composed into, each
929
+ * holding the other.
929
930
  *
930
- * @returns A new reference to the Python object, or @c nullptr with a
931
- * Python error set.
931
+ * @returns @c true, or @c false with a Python error set and @p self left
932
+ * holding nothing.
932
933
  */
933
- PyObject* make_composed_object(
934
- PyTypeObject* type,
934
+ bool compose_into(
935
+ PyObject* self,
935
936
  type_entry& entry,
936
937
  member_desc const& constructor,
937
938
  overload_desc& overload,
938
939
  PyObject* const* args,
939
940
  Py_ssize_t nargs) noexcept
940
941
  {
942
+ auto* const type = Py_TYPE(self);
943
+
941
944
  if (!composes(overload))
942
945
  {
943
946
  PyErr_Format(
@@ -946,14 +949,14 @@ namespace py::interp
946
949
  "instance rather than composing one",
947
950
  entry.winrt_name,
948
951
  overload.winrt_name);
949
- return nullptr;
952
+ return false;
950
953
  }
951
954
 
952
955
  // init_subclass() refuses such a class already, unless a base before
953
956
  // it in the MRO does not call the next __init_subclass__().
954
957
  if (!check_composed_bases(type))
955
958
  {
956
- return nullptr;
959
+ return false;
957
960
  }
958
961
 
959
962
  // What the outer object answers itself: every interface the Python
@@ -963,14 +966,14 @@ namespace py::interp
963
966
 
964
967
  if (!collect_interfaces(type, interfaces))
965
968
  {
966
- return nullptr;
969
+ return false;
967
970
  }
968
971
 
969
972
  for (auto* const iface : interfaces)
970
973
  {
971
974
  if (!ensure_interface_vtable(*iface))
972
975
  {
973
- return nullptr;
976
+ return false;
974
977
  }
975
978
  }
976
979
 
@@ -1003,14 +1006,14 @@ namespace py::interp
1003
1006
  auto* const iface = ensure_named_entry(*base->owner, overridables[i]);
1004
1007
  if (!iface)
1005
1008
  {
1006
- return nullptr;
1009
+ return false;
1007
1010
  }
1008
1011
 
1009
1012
  // An overridable interface is exclusive to the class, so the
1010
1013
  // class's own record is where its members are written down.
1011
1014
  if (!ensure_interface_vtable(*iface, *base))
1012
1015
  {
1013
- return nullptr;
1016
+ return false;
1014
1017
  }
1015
1018
 
1016
1019
  if (!named)
@@ -1026,16 +1029,10 @@ namespace py::interp
1026
1029
  }
1027
1030
  }
1028
1031
 
1029
- pyobj_handle self{type->tp_alloc(type, 0)};
1030
- if (!self)
1031
- {
1032
- return nullptr;
1033
- }
1034
-
1035
1032
  // A weak reference to the pair takes the Python object from whatever
1036
1033
  // thread resolves it, which a free-threaded build only allows for an
1037
1034
  // object that has been told to expect it.
1038
- PyUnstable_EnableTryIncRef(self.get());
1035
+ PyUnstable_EnableTryIncRef(self);
1039
1036
 
1040
1037
  auto outer = std::make_unique<compose_object>();
1041
1038
 
@@ -1047,7 +1044,7 @@ namespace py::interp
1047
1044
  outer->source_head.target = outer.get();
1048
1045
  outer->weak_head.vtable = weak_reference_vtable;
1049
1046
  outer->weak_head.target = outer.get();
1050
- outer->calls.obj = self.get();
1047
+ outer->calls.obj = self;
1051
1048
 
1052
1049
  try
1053
1050
  {
@@ -1056,7 +1053,7 @@ namespace py::interp
1056
1053
  catch (...)
1057
1054
  {
1058
1055
  to_PyErr();
1059
- return nullptr;
1056
+ return false;
1060
1057
  }
1061
1058
 
1062
1059
  make_tearoffs(interfaces, outer->head, outer->calls, outer->tearoffs);
@@ -1074,7 +1071,7 @@ namespace py::interp
1074
1071
  if (!instance)
1075
1072
  {
1076
1073
  object_release(&outer.release()->head);
1077
- return nullptr;
1074
+ return false;
1078
1075
  }
1079
1076
 
1080
1077
  // The wrapper holds the outer object seen as the class's own default
@@ -1098,12 +1095,12 @@ namespace py::interp
1098
1095
  catch (...)
1099
1096
  {
1100
1097
  to_PyErr();
1101
- return nullptr;
1098
+ return false;
1102
1099
  }
1103
1100
  }
1104
1101
 
1105
- abi_of(self.get()) = abi;
1102
+ abi_of(self) = abi;
1106
1103
 
1107
- return self.detach();
1104
+ return true;
1108
1105
  }
1109
1106
  } // namespace py::interp
@@ -21,8 +21,8 @@
21
21
 
22
22
  namespace py::interp
23
23
  {
24
- PyObject* make_composed_object(
25
- PyTypeObject* type,
24
+ bool compose_into(
25
+ PyObject* self,
26
26
  type_entry& entry,
27
27
  member_desc const& constructor,
28
28
  overload_desc& overload,
@@ -82,18 +82,19 @@ namespace py::interp
82
82
  return nullptr;
83
83
  }
84
84
 
85
+ void* abi{};
86
+ if (!self->member->is_static && !(abi = instance_abi(instance)))
87
+ {
88
+ return nullptr;
89
+ }
90
+
85
91
  auto const overload = select_overload(*self->member, nargs - 1);
86
92
  if (!overload)
87
93
  {
88
94
  return nullptr;
89
95
  }
90
96
 
91
- return call_member(
92
- *self->member,
93
- *overload,
94
- self->member->is_static ? nullptr : abi_of(instance),
95
- args + 1,
96
- nargs - 1);
97
+ return call_member(*self->member, *overload, abi, args + 1, nargs - 1);
97
98
  }
98
99
 
99
100
  PyObject* method_descr_get(
@@ -211,18 +212,20 @@ namespace py::interp
211
212
  PyObject* property_get(PyObject* self, void* closure) noexcept
212
213
  {
213
214
  auto const member = static_cast<member_desc*>(closure);
215
+
216
+ void* abi{};
217
+ if (!member->is_static && !(abi = instance_abi(self)))
218
+ {
219
+ return nullptr;
220
+ }
221
+
214
222
  auto const overload = select_overload(*member, 0);
215
223
  if (!overload)
216
224
  {
217
225
  return nullptr;
218
226
  }
219
227
 
220
- return call_member(
221
- *member,
222
- *overload,
223
- member->is_static ? nullptr : abi_of(self),
224
- nullptr,
225
- 0);
228
+ return call_member(*member, *overload, abi, nullptr, 0);
226
229
  }
227
230
 
228
231
  int property_set(PyObject* self, PyObject* value, void* closure) noexcept
@@ -236,18 +239,19 @@ namespace py::interp
236
239
  return -1;
237
240
  }
238
241
 
242
+ void* abi{};
243
+ if (!member->is_static && !(abi = instance_abi(self)))
244
+ {
245
+ return -1;
246
+ }
247
+
239
248
  auto const overload = select_overload(*member, 1);
240
249
  if (!overload)
241
250
  {
242
251
  return -1;
243
252
  }
244
253
 
245
- pyobj_handle result{call_member(
246
- *member,
247
- *overload,
248
- member->is_static ? nullptr : abi_of(self),
249
- &value,
250
- 1)};
254
+ pyobj_handle result{call_member(*member, *overload, abi, &value, 1)};
251
255
 
252
256
  return result ? 0 : -1;
253
257
  }
@@ -179,10 +179,9 @@ namespace py::interp
179
179
  throw python_exception();
180
180
  }
181
181
 
182
- auto const abi = abi_of(obj);
182
+ auto const abi = instance_abi(obj);
183
183
  if (!abi)
184
184
  {
185
- PyErr_SetString(PyExc_RuntimeError, "the object holds nothing");
186
185
  throw python_exception();
187
186
  }
188
187
 
@@ -215,6 +214,20 @@ namespace py::interp
215
214
  return result;
216
215
  }
217
216
 
217
+ /**
218
+ * Says that @p self holds no WinRT object, as an instance of a Python
219
+ * class derived from a composable one does until its __init__() has
220
+ * composed it.
221
+ */
222
+ void set_not_composed_error(PyObject* self) noexcept
223
+ {
224
+ PyErr_Format(
225
+ PyExc_RuntimeError,
226
+ "'%s' object holds no WinRT object until its __init__() calls "
227
+ "super().__init__()",
228
+ Py_TYPE(self)->tp_name);
229
+ }
230
+
218
231
  namespace
219
232
  {
220
233
  void release_interface_capsule(PyObject* capsule) noexcept
@@ -298,21 +311,75 @@ namespace py::interp
298
311
  return nullptr;
299
312
  }
300
313
 
314
+ int class_init(PyObject* self, PyObject* args, PyObject* kwds) noexcept;
315
+
316
+ /**
317
+ * Composes @p self, an instance of a Python class derived from the
318
+ * composable class @p info that holds nothing yet, with the
319
+ * constructor overload that takes @p args.
320
+ */
321
+ bool compose_with(PyObject* self, type_entry& info, PyObject* args) noexcept
322
+ {
323
+ auto const overload
324
+ = select_overload(*info.constructor, PyTuple_GET_SIZE(args));
325
+
326
+ if (!overload)
327
+ {
328
+ return false;
329
+ }
330
+
331
+ return compose_into(
332
+ self,
333
+ info,
334
+ *info.constructor,
335
+ *overload,
336
+ tuple_items(args),
337
+ PyTuple_GET_SIZE(args));
338
+ }
339
+
301
340
  PyObject* class_new(PyTypeObject* type, PyObject* args, PyObject* kwds) noexcept
302
341
  {
342
+ auto const info = class_entry_of(type);
343
+
344
+ // A Python class with an __init__ of its own takes the arguments
345
+ // that __init__ declares, as any Python class does, so it is
346
+ // class_init(), which its __init__ reaches through super(), that
347
+ // composes it, with the arguments given there, or else
348
+ // compose_after_init(), with the arguments of the call, once
349
+ // __init__ has returned without doing so.
350
+ if (info && type != info->py_type && type->tp_init != class_init)
351
+ {
352
+ return type->tp_alloc(type, 0);
353
+ }
354
+
303
355
  if (kwds && PyDict_GET_SIZE(kwds) != 0)
304
356
  {
305
357
  set_invalid_kwd_args_error();
306
358
  return nullptr;
307
359
  }
308
360
 
309
- auto const info = class_entry_of(type);
310
361
  if (!info || !info->constructor)
311
362
  {
312
363
  set_invalid_activation_error(info ? info->winrt_name : type->tp_name);
313
364
  return nullptr;
314
365
  }
315
366
 
367
+ if (type != info->py_type)
368
+ {
369
+ pyobj_handle self{type->tp_alloc(type, 0)};
370
+ if (!self)
371
+ {
372
+ return nullptr;
373
+ }
374
+
375
+ if (!compose_with(self.get(), *info, args))
376
+ {
377
+ return nullptr;
378
+ }
379
+
380
+ return self.detach();
381
+ }
382
+
316
383
  auto const overload
317
384
  = select_overload(*info->constructor, PyTuple_GET_SIZE(args));
318
385
 
@@ -321,17 +388,6 @@ namespace py::interp
321
388
  return nullptr;
322
389
  }
323
390
 
324
- if (type != info->py_type)
325
- {
326
- return make_composed_object(
327
- type,
328
- *info,
329
- *info->constructor,
330
- *overload,
331
- tuple_items(args),
332
- PyTuple_GET_SIZE(args));
333
- }
334
-
335
391
  if (overload->is_protected)
336
392
  {
337
393
  PyErr_Format(
@@ -350,6 +406,48 @@ namespace py::interp
350
406
  PyTuple_GET_SIZE(args));
351
407
  }
352
408
 
409
+ /**
410
+ * __init__() of a composable class. The arguments of a call to the
411
+ * class went to the constructor already, in class_new(), unless the
412
+ * class called is a Python one with an __init__ of its own, which
413
+ * calls this one through super() with the arguments for the
414
+ * constructor instead.
415
+ */
416
+ int class_init(PyObject* self, PyObject* args, PyObject* kwds) noexcept
417
+ {
418
+ auto* const type = Py_TYPE(self);
419
+
420
+ if (type->tp_init == class_init)
421
+ {
422
+ return 0;
423
+ }
424
+
425
+ if (abi_of(self))
426
+ {
427
+ PyErr_Format(
428
+ PyExc_TypeError,
429
+ "'%s' object is already composed into a WinRT object, so "
430
+ "it cannot be initialized again",
431
+ type->tp_name);
432
+ return -1;
433
+ }
434
+
435
+ if (kwds && PyDict_GET_SIZE(kwds) != 0)
436
+ {
437
+ set_invalid_kwd_args_error();
438
+ return -1;
439
+ }
440
+
441
+ auto const info = class_entry_of(type);
442
+ if (!info || !info->constructor)
443
+ {
444
+ set_invalid_activation_error(info ? info->winrt_name : type->tp_name);
445
+ return -1;
446
+ }
447
+
448
+ return compose_with(self, *info, args) ? 0 : -1;
449
+ }
450
+
353
451
  /**
354
452
  * Refuses @p cls as a type a WinRT object can be seen as.
355
453
  * @returns nullptr, for the caller to return.
@@ -548,6 +646,82 @@ namespace py::interp
548
646
  {}};
549
647
  } // namespace
550
648
 
649
+ /**
650
+ * Composes @p self, an instance of a Python class derived from a
651
+ * composable one whose __init__() has returned without composing it, with
652
+ * the arguments of the call, @p args and @p kwds, as class_new() composes
653
+ * an instance of a class without an __init__ of its own. An object that
654
+ * is composed already, or that is no such instance, is left as it is.
655
+ *
656
+ * @returns @c true, or @c false with a Python error set.
657
+ */
658
+ bool compose_after_init(PyObject* self, PyObject* args, PyObject* kwds) noexcept
659
+ {
660
+ auto* const type = Py_TYPE(self);
661
+
662
+ auto const info = class_entry_of(type);
663
+ if (!info)
664
+ {
665
+ return true;
666
+ }
667
+
668
+ if (info->category != table::category::class_)
669
+ {
670
+ return true;
671
+ }
672
+
673
+ if (type == info->py_type)
674
+ {
675
+ return true;
676
+ }
677
+
678
+ if (abi_of(self))
679
+ {
680
+ return true;
681
+ }
682
+
683
+ if (kwds && PyDict_GET_SIZE(kwds) != 0)
684
+ {
685
+ PyErr_Format(
686
+ PyExc_TypeError,
687
+ "%s.__init__() did not call super().__init__(), and a call with "
688
+ "keyword arguments fits no constructor of '%s'",
689
+ type->tp_name,
690
+ info->winrt_name);
691
+ return false;
692
+ }
693
+
694
+ if (!info->constructor)
695
+ {
696
+ set_invalid_activation_error(info->winrt_name);
697
+ return false;
698
+ }
699
+
700
+ auto const overload
701
+ = select_overload(*info->constructor, PyTuple_GET_SIZE(args));
702
+
703
+ if (!overload)
704
+ {
705
+ PyErr_Clear();
706
+ PyErr_Format(
707
+ PyExc_TypeError,
708
+ "%s.__init__() did not call super().__init__(), and a call with "
709
+ "%zd arguments fits no constructor of '%s'",
710
+ type->tp_name,
711
+ PyTuple_GET_SIZE(args),
712
+ info->winrt_name);
713
+ return false;
714
+ }
715
+
716
+ return compose_into(
717
+ self,
718
+ *info,
719
+ *info->constructor,
720
+ *overload,
721
+ tuple_items(args),
722
+ PyTuple_GET_SIZE(args));
723
+ }
724
+
551
725
  /**
552
726
  * Creates the Python type of an interface, and the abstract type its public
553
727
  * name is bound to.
@@ -793,6 +967,11 @@ namespace py::interp
793
967
  }
794
968
 
795
969
  slots.push_back({Py_tp_new, reinterpret_cast<void*>(class_new)});
970
+
971
+ if (composable)
972
+ {
973
+ slots.push_back({Py_tp_init, reinterpret_cast<void*>(class_init)});
974
+ }
796
975
  slots.push_back(
797
976
  {Py_tp_getset,
798
977
  reinterpret_cast<void*>(keep_getsets(proj, collected.instance_getsets))});
@@ -29,6 +29,27 @@ namespace py::interp
29
29
  return *reinterpret_cast<void**>(reinterpret_cast<uint8_t*>(self) + abi_offset);
30
30
  }
31
31
 
32
+ void set_not_composed_error(PyObject* self) noexcept;
33
+
34
+ /**
35
+ * The ABI pointer @p self holds, to call an instance member on, or
36
+ * @c nullptr with a Python error set when it holds none, which an instance
37
+ * of a Python class derived from a composable one does until its
38
+ * __init__() has called the WinRT class's.
39
+ */
40
+ inline void* instance_abi(PyObject* self) noexcept
41
+ {
42
+ auto const abi = abi_of(self);
43
+ if (!abi)
44
+ {
45
+ set_not_composed_error(self);
46
+ }
47
+
48
+ return abi;
49
+ }
50
+
51
+ bool compose_after_init(PyObject* self, PyObject* args, PyObject* kwds) noexcept;
52
+
32
53
  /**
33
54
  * The name every interface pointer capsule carries. A capsule of this
34
55
  * name holds one reference to a COM interface, which its destructor
@@ -68,13 +68,19 @@ namespace py::interp
68
68
  return nullptr;
69
69
  }
70
70
 
71
+ auto const abi = instance_abi(self);
72
+ if (!abi)
73
+ {
74
+ return nullptr;
75
+ }
76
+
71
77
  auto const overload = select_overload(*member, nargs);
72
78
  if (!overload)
73
79
  {
74
80
  return nullptr;
75
81
  }
76
82
 
77
- return call_member(*member, *overload, abi_of(self), args, nargs);
83
+ return call_member(*member, *overload, abi, args, nargs);
78
84
  }
79
85
 
80
86
  /**
@@ -168,6 +174,12 @@ namespace py::interp
168
174
  return nullptr;
169
175
  }
170
176
 
177
+ auto const abi = instance_abi(self);
178
+ if (!abi)
179
+ {
180
+ return nullptr;
181
+ }
182
+
171
183
  // A WinRT vector counts its elements in a uint32_t, so there is
172
184
  // nothing to ask it for outside that range. CPython has already
173
185
  // added the length to a negative index given to this slot, and
@@ -190,10 +202,7 @@ namespace py::interp
190
202
  bool direct{};
191
203
 
192
204
  auto* const direct_item = call_indexed(
193
- info->protocol.get_at,
194
- abi_of(self),
195
- static_cast<uint32_t>(index),
196
- direct);
205
+ info->protocol.get_at, abi, static_cast<uint32_t>(index), direct);
197
206
 
198
207
  if (direct)
199
208
  {
@@ -1171,8 +1180,14 @@ namespace py::interp
1171
1180
  */
1172
1181
  winrt::Windows::Foundation::IInspectable object_of(PyObject* self)
1173
1182
  {
1183
+ auto const abi = instance_abi(self);
1184
+ if (!abi)
1185
+ {
1186
+ throw python_exception();
1187
+ }
1188
+
1174
1189
  winrt::Windows::Foundation::IInspectable object;
1175
- winrt::copy_from_abi(object, abi_of(self));
1190
+ winrt::copy_from_abi(object, abi);
1176
1191
  return object;
1177
1192
  }
1178
1193
 
@@ -0,0 +1 @@
1
+ 4.0.2
@@ -1 +0,0 @@
1
- 4.0.1
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes