summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2020-04-19 21:45:58 +0200
committerGitHub <noreply@github.com>2020-04-19 21:45:58 +0200
commitb692adc13c560551e3ea87e0c0d01bc983248893 (patch)
treebfb663a5a42123ecf319436634872ac81843c0eb
parentf4d8332f657df46e015e44e04ad3e09e71213e28 (diff)
downloadcython-b692adc13c560551e3ea87e0c0d01bc983248893.tar.gz
Turn plain classes without bases into new-style classes with language_level=3 (GH-3530)
-rw-r--r--Cython/Compiler/ExprNodes.py4
-rw-r--r--Cython/Compiler/Nodes.py4
-rw-r--r--docs/src/userguide/migrating_to_cy30.rst3
-rw-r--r--tests/run/cdef_multiple_inheritance_errors.srctree1
-rw-r--r--tests/run/cython3.pyx12
5 files changed, 23 insertions, 1 deletions
diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py
index 8ff912ca3..182d03784 100644
--- a/Cython/Compiler/ExprNodes.py
+++ b/Cython/Compiler/ExprNodes.py
@@ -9005,9 +9005,11 @@ class Py3ClassNode(ExprNode):
# class_def_node PyClassDefNode PyClassDefNode defining this class
# calculate_metaclass bool should call CalculateMetaclass()
# allow_py2_metaclass bool should look for Py2 metaclass
+ # force_type bool always create a "new style" class, even with no bases
subexprs = []
type = py_object_type
+ force_type = False
is_temp = True
def infer_type(self, env):
@@ -9029,6 +9031,8 @@ class Py3ClassNode(ExprNode):
mkw = class_def_node.mkw.py_result() if class_def_node.mkw else 'NULL'
if class_def_node.metaclass:
metaclass = class_def_node.metaclass.py_result()
+ elif self.force_type:
+ metaclass = "((PyObject*)&PyType_Type)"
else:
metaclass = "((PyObject*)&__Pyx_DefaultClassType)"
code.putln(
diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py
index ca417f172..4912ce035 100644
--- a/Cython/Compiler/Nodes.py
+++ b/Cython/Compiler/Nodes.py
@@ -4690,7 +4690,9 @@ class PyClassDefNode(ClassDefNode):
self.classobj = ExprNodes.Py3ClassNode(
pos, name=name, class_def_node=self, doc=doc_node,
calculate_metaclass=needs_metaclass_calculation,
- allow_py2_metaclass=allow_py2_metaclass)
+ allow_py2_metaclass=allow_py2_metaclass,
+ force_type=force_py3_semantics,
+ )
else:
# no bases, no metaclass => old style class creation
self.dict = ExprNodes.DictNode(pos, key_value_pairs=[])
diff --git a/docs/src/userguide/migrating_to_cy30.rst b/docs/src/userguide/migrating_to_cy30.rst
index fe54dfe86..892d91a08 100644
--- a/docs/src/userguide/migrating_to_cy30.rst
+++ b/docs/src/userguide/migrating_to_cy30.rst
@@ -29,6 +29,9 @@ Further semantic changes due to the language level include:
* ``/``-division uses the true (float) division operator, unless ``cdivision`` is enabled.
* ``print`` is a function, not a statement.
+* Python classes that are defined without bases (``class C: ...``) are "new-style"
+ classes also in Py2.x (if you never heard about "old-style classes", you're probably
+ happy without them).
* Annotations (type hints) are now stored as strings.
(`PEP 563 <https://github.com/cython/cython/issues/2863>`_)
* ``StopIteration`` handling in generators has been changed according to
diff --git a/tests/run/cdef_multiple_inheritance_errors.srctree b/tests/run/cdef_multiple_inheritance_errors.srctree
index e6b3426ba..dd4aaa200 100644
--- a/tests/run/cdef_multiple_inheritance_errors.srctree
+++ b/tests/run/cdef_multiple_inheritance_errors.srctree
@@ -48,6 +48,7 @@ cdef class X(Base, Py):
pass
######## oldstyle.pyx ########
+# cython: language_level=2
cdef class Base:
cdef dict __dict__
diff --git a/tests/run/cython3.pyx b/tests/run/cython3.pyx
index 82bc40905..76a9a564a 100644
--- a/tests/run/cython3.pyx
+++ b/tests/run/cython3.pyx
@@ -30,6 +30,18 @@ def locals_function(a, b=2):
return locals()
+### "new style" classes
+
+class T:
+ """
+ >>> t = T()
+ >>> isinstance(t, T)
+ True
+ >>> isinstance(T, type) # not a Py2 old style class!
+ True
+ """
+
+
### true division
def truediv(x):