Commit b692adc1 authored by Stefan Behnel's avatar Stefan Behnel Committed by GitHub

Turn plain classes without bases into new-style classes with language_level=3 (GH-3530)

parent f4d8332f
...@@ -9005,9 +9005,11 @@ class Py3ClassNode(ExprNode): ...@@ -9005,9 +9005,11 @@ class Py3ClassNode(ExprNode):
# class_def_node PyClassDefNode PyClassDefNode defining this class # class_def_node PyClassDefNode PyClassDefNode defining this class
# calculate_metaclass bool should call CalculateMetaclass() # calculate_metaclass bool should call CalculateMetaclass()
# allow_py2_metaclass bool should look for Py2 metaclass # allow_py2_metaclass bool should look for Py2 metaclass
# force_type bool always create a "new style" class, even with no bases
subexprs = [] subexprs = []
type = py_object_type type = py_object_type
force_type = False
is_temp = True is_temp = True
def infer_type(self, env): def infer_type(self, env):
...@@ -9029,6 +9031,8 @@ class Py3ClassNode(ExprNode): ...@@ -9029,6 +9031,8 @@ class Py3ClassNode(ExprNode):
mkw = class_def_node.mkw.py_result() if class_def_node.mkw else 'NULL' mkw = class_def_node.mkw.py_result() if class_def_node.mkw else 'NULL'
if class_def_node.metaclass: if class_def_node.metaclass:
metaclass = class_def_node.metaclass.py_result() metaclass = class_def_node.metaclass.py_result()
elif self.force_type:
metaclass = "((PyObject*)&PyType_Type)"
else: else:
metaclass = "((PyObject*)&__Pyx_DefaultClassType)" metaclass = "((PyObject*)&__Pyx_DefaultClassType)"
code.putln( code.putln(
......
...@@ -4690,7 +4690,9 @@ class PyClassDefNode(ClassDefNode): ...@@ -4690,7 +4690,9 @@ class PyClassDefNode(ClassDefNode):
self.classobj = ExprNodes.Py3ClassNode( self.classobj = ExprNodes.Py3ClassNode(
pos, name=name, class_def_node=self, doc=doc_node, pos, name=name, class_def_node=self, doc=doc_node,
calculate_metaclass=needs_metaclass_calculation, calculate_metaclass=needs_metaclass_calculation,
allow_py2_metaclass=allow_py2_metaclass) allow_py2_metaclass=allow_py2_metaclass,
force_type=force_py3_semantics,
)
else: else:
# no bases, no metaclass => old style class creation # no bases, no metaclass => old style class creation
self.dict = ExprNodes.DictNode(pos, key_value_pairs=[]) self.dict = ExprNodes.DictNode(pos, key_value_pairs=[])
......
...@@ -29,6 +29,9 @@ Further semantic changes due to the language level include: ...@@ -29,6 +29,9 @@ Further semantic changes due to the language level include:
* ``/``-division uses the true (float) division operator, unless ``cdivision`` is enabled. * ``/``-division uses the true (float) division operator, unless ``cdivision`` is enabled.
* ``print`` is a function, not a statement. * ``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. * Annotations (type hints) are now stored as strings.
(`PEP 563 <https://github.com/cython/cython/issues/2863>`_) (`PEP 563 <https://github.com/cython/cython/issues/2863>`_)
* ``StopIteration`` handling in generators has been changed according to * ``StopIteration`` handling in generators has been changed according to
......
...@@ -48,6 +48,7 @@ cdef class X(Base, Py): ...@@ -48,6 +48,7 @@ cdef class X(Base, Py):
pass pass
######## oldstyle.pyx ######## ######## oldstyle.pyx ########
# cython: language_level=2
cdef class Base: cdef class Base:
cdef dict __dict__ cdef dict __dict__
......
...@@ -30,6 +30,18 @@ def locals_function(a, b=2): ...@@ -30,6 +30,18 @@ def locals_function(a, b=2):
return locals() 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 ### true division
def truediv(x): def truediv(x):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment