Skip to content

Commit 64541ce

Browse files
committed
accumulated already-submitted changes
1 parent d7a2a75 commit 64541ce

File tree

8 files changed

+89
-16
lines changed

8 files changed

+89
-16
lines changed

clif/backend/matcher.cc

+6-6
Original file line numberDiff line numberDiff line change
@@ -2989,20 +2989,20 @@ const clang::FunctionDecl* ClifMatcher::SpecializeFunctionTemplate(
29892989
}
29902990

29912991
std::string ClifMatcher::TemplateDeductionResult(
2992-
Sema::TemplateDeductionResult specialized_result) const {
2992+
clang::TemplateDeductionResult specialized_result) const {
29932993
switch (specialized_result) {
2994-
case Sema::TDK_Invalid:
2994+
case clang::TemplateDeductionResult::Invalid:
29952995
return "The template function declaration was invalid.";
2996-
case Sema::TDK_InstantiationDepth:
2996+
case clang::TemplateDeductionResult::InstantiationDepth:
29972997
return "Template argument deduction exceeded the maximum template "
29982998
"instantiation depth.";
2999-
case Sema::TDK_Incomplete:
2999+
case clang::TemplateDeductionResult::Incomplete:
30003000
return "Template argument deduction did not deduce a value for every "
30013001
"template parameter.";
3002-
case Sema::TDK_Inconsistent:
3002+
case clang::TemplateDeductionResult::Inconsistent:
30033003
return "Template argument deduction produced inconsistent deduced "
30043004
"values.";
3005-
case Sema::TDK_Underqualified:
3005+
case clang::TemplateDeductionResult::Underqualified:
30063006
return "Template argument deduction failed due to inconsistent "
30073007
"cv-qualifiers.";
30083008
default:

clif/backend/matcher.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ class ClifMatcher {
402402

403403
// Transform template type deduction error codes into error messages.
404404
std::string TemplateDeductionResult(
405-
clang::Sema::TemplateDeductionResult specialized_result) const;
405+
clang::TemplateDeductionResult specialized_result) const;
406406

407407
// Add the class type as the first parameter to a function.
408408
void AdjustForNonClassMethods(protos::FuncDecl* clif_func_decl) const;

clif/pybind11/classes.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
I = utils.I
2828

29+
_USE_PYTYPE_TYPE_AS_METACLASS = True
30+
2931
_KNOWN_TYPES_WITH_MULTIPLE_INHERITANCE = {
3032
'::borg::Config': ['::borg::ConfigArgs']
3133
}
@@ -100,6 +102,8 @@ def generate_from(
100102
base.cpp_canonical_type in codegen_info.dynamic_attr_types):
101103
enable_instance_dict = True
102104
break
105+
if _USE_PYTYPE_TYPE_AS_METACLASS:
106+
definition += ', py::metaclass((PyObject*) &PyType_Type)'
103107
definition += ', py::release_gil_before_calling_cpp_dtor()'
104108
if mi_bases:
105109
definition += ', py::multiple_inheritance()'
@@ -117,7 +121,7 @@ def generate_from(
117121
for member in class_decl.members:
118122
if member.decltype == ast_pb2.Decl.Type.CONST:
119123
for s in consts.generate_from(class_name, member.const):
120-
yield I + I + s
124+
yield I + s
121125
elif member.decltype == ast_pb2.Decl.Type.FUNC:
122126
if member.func.name.native in ('__reduce__', '__reduce_ex__'):
123127
reduce_or_reduce_ex_defined = True

clif/python/BUILD

+23
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# CLIF python frontend
22

33
load("@clif_python_deps//:requirements.bzl", "requirement")
4+
load("//devtools/clif/python:clif_build_rule.bzl", "py_clif_cc")
45
load("//third_party/bazel_rules/rules_python/python:py_test.bzl", "py_test")
56

67
package(
@@ -412,3 +413,25 @@ py_library(
412413
srcs_version = "PY2AND3",
413414
visibility = ["//visibility:public"],
414415
)
416+
417+
cc_library(
418+
name = "meta_ext_lib",
419+
hdrs = ["meta_ext.h"],
420+
)
421+
422+
py_clif_cc(
423+
name = "_meta_ext",
424+
srcs = ["meta_ext.clif"],
425+
deps = [
426+
":meta_ext_lib",
427+
],
428+
)
429+
430+
py_library(
431+
name = "abc_utils",
432+
srcs = ["abc_utils.py"],
433+
visibility = ["//visibility:public"],
434+
deps = [
435+
":_meta_ext",
436+
],
437+
)

clif/python/primer.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -713,8 +713,8 @@ of the return values as positional arguments. Whatever it returns becomes the
713713
actual return value.
714714

715715
Some commonly needed post-processors have been provided in the above imported
716-
library with CLIF. You can also
717-
provide your own Python post-processor library.
716+
library with CLIF.
717+
You can also provide your own Python post-processor library.
718718

719719
## Naming Rules in CLIF Files {#naming_rules}
720720

clif/python/types.cc

-2
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ bool Clif_PyObjAs(PyObject* py, long* c) { //NOLINT: runtime/int
209209
}
210210

211211
// int64
212-
#ifdef HAVE_LONG_LONG
213212
bool Clif_PyObjAs(PyObject* py, long long* c) { //NOLINT: runtime/int
214213
CHECK(c != nullptr);
215214
if (!PyLong_Check(py)) {
@@ -270,7 +269,6 @@ bool Clif_PyObjAs(PyObject* py, absl::uint128* c) { // NOLINT: runtime/int
270269
}
271270
return !PyErr_Occurred();
272271
}
273-
#endif // HAVE_LONG_LONG
274272

275273
#ifdef ABSL_HAVE_INTRINSIC_INT128
276274
bool Clif_PyObjAs(PyObject* py, __int128* c) {

clif/python/types.h

-4
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ inline PyObject* Clif_PyObjFrom(unsigned long c, // NOLINT runtime/int
102102
return pc.Apply(PyLong_FromSize_t(c));
103103
}
104104
// CLIF use `int64` as int64
105-
#ifdef HAVE_LONG_LONG
106105
inline PyObject* Clif_PyObjFrom(long long c, // NOLINT runtime/int
107106
const py::PostConv& pc) {
108107
return pc.Apply(PyLong_FromLongLong(c));
@@ -128,7 +127,6 @@ inline PyObject* Clif_PyObjFrom(absl::uint128 c, const py::PostConv& pc) {
128127
auto lo = PyLong_FromUnsignedLongLong(absl::Uint128Low64(c));
129128
return pc.Apply(PyNumber_Add(hi, lo));
130129
}
131-
#endif
132130

133131
#ifdef ABSL_HAVE_INTRINSIC_INT128
134132
// CLIF use2 `__int128` as int
@@ -195,12 +193,10 @@ bool Clif_PyObjAs(PyObject*, unsigned char*);
195193
bool Clif_PyObjAs(PyObject*, unsigned short*); // NOLINT runtime/int
196194
bool Clif_PyObjAs(PyObject*, unsigned int*);
197195
bool Clif_PyObjAs(PyObject*, unsigned long*); // NOLINT runtime/int
198-
#ifdef HAVE_LONG_LONG
199196
bool Clif_PyObjAs(PyObject*, unsigned long long*); // NOLINT runtime/int
200197
bool Clif_PyObjAs(PyObject*, long long*); // NOLINT runtime/int
201198
bool Clif_PyObjAs(PyObject*, absl::int128*); // NOLINT runtime/int
202199
bool Clif_PyObjAs(PyObject*, absl::uint128*); // NOLINT runtime/int
203-
#endif
204200
#ifdef ABSL_HAVE_INTRINSIC_INT128
205201
bool Clif_PyObjAs(PyObject*, __int128*);
206202
bool Clif_PyObjAs(PyObject*, unsigned __int128*);

clif/testing/python/classes_test.py

+52
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414

1515
"""Tests for clif.testing.python.classes."""
1616

17+
import abc
1718
from unittest import mock
1819

1920
from absl.testing import absltest
2021
from absl.testing import parameterized
2122

23+
from clif.python import abc_utils
2224
from clif.testing.python import classes
2325

2426

@@ -35,6 +37,20 @@ def testKlass(self):
3537
# AttributeError on CPython; TypeError on PyPy.
3638
with self.assertRaises((AttributeError, TypeError)):
3739
k.i2 = 0
40+
self.assertEqual(classes.Klass.C, 1)
41+
self.assertEqual(k.C, 1)
42+
with self.assertRaisesRegex(AttributeError, 'read-only'):
43+
k.C = 0
44+
45+
# UNDESIRABLE but long established behavior.
46+
classes.Klass.C = 0 # C++ const but not read-only in Python.
47+
self.assertEqual(classes.Klass.C, 0)
48+
self.assertEqual(k.C, 0)
49+
# Restore original value, to minimize the potential for surprises,
50+
# just in case.
51+
classes.Klass.C = 1
52+
self.assertEqual(classes.Klass.C, 1)
53+
self.assertEqual(k.C, 1)
3854

3955
def testMockIsRejected(self):
4056
k_inst = classes.Klass(3)
@@ -212,6 +228,42 @@ def testNestedUnproperty(self, attr, expected, new_value, new_expected):
212228
ret = getattr(obj, getter)()
213229
self.assertEqual(ret, new_expected)
214230

231+
def testABCMeta(self):
232+
# Purely to help the linter.
233+
ABCMeta = abc.ABCMeta # pylint: disable=unused-variable
234+
235+
if abc_utils.PyCLIFMeta is type:
236+
237+
class KlassABCMeta(classes.Klass, metaclass=ABCMeta):
238+
pass
239+
240+
self.assertEqual(type(classes.Klass).__name__, 'type')
241+
km = KlassABCMeta(5)
242+
self.assertEqual(km.i, 5)
243+
244+
else:
245+
self.assertEqual(classes.__pyclif_codegen_mode__, 'pybind11')
246+
with self.assertRaisesRegex(TypeError, 'metaclass conflict'):
247+
248+
class KlassABCMeta(classes.Klass, metaclass=ABCMeta):
249+
pass
250+
251+
def testPyCLIFABCMeta(self):
252+
# Purely to help the linter.
253+
PyCLIFABCMeta = abc_utils.PyCLIFABCMeta # pylint: disable=unused-variable,invalid-name
254+
255+
class KlassPyCLIFABCMeta(classes.Klass, metaclass=PyCLIFABCMeta):
256+
pass
257+
258+
if abc_utils.PyCLIFMeta is type:
259+
expected_type_name = 'type'
260+
else:
261+
self.assertEqual(classes.__pyclif_codegen_mode__, 'pybind11')
262+
expected_type_name = 'pybind11_type'
263+
self.assertEqual(type(classes.Klass).__name__, expected_type_name)
264+
km = KlassPyCLIFABCMeta(5)
265+
self.assertEqual(km.i, 5)
266+
215267

216268
if __name__ == '__main__':
217269
absltest.main()

0 commit comments

Comments
 (0)