Commit b5e861eb authored by Stefan Behnel's avatar Stefan Behnel

Optimise enum value formatting in f-strings in the same way as integer formatting.

parent d85584fe
......@@ -1730,15 +1730,13 @@ class ForbidUseClass:
ForbidUse = ForbidUseClass()
class CIntType(CNumericType):
is_int = 1
typedef_flag = 0
class CIntLike(object):
"""Mixin for shared behaviour of C integers and enums.
"""
to_py_function = None
from_py_function = None
to_pyunicode_utility = None
default_format_spec = 'd'
exception_value = -1
def can_coerce_to_pyobject(self, env):
return True
......@@ -1746,6 +1744,24 @@ class CIntType(CNumericType):
def can_coerce_from_pyobject(self, env):
return True
def create_to_py_utility_code(self, env):
if type(self).to_py_function is None:
self.to_py_function = "__Pyx_PyInt_From_" + self.specialization_name()
env.use_utility_code(TempitaUtilityCode.load_cached(
"CIntToPy", "TypeConversion.c",
context={"TYPE": self.empty_declaration_code(),
"TO_PY_FUNCTION": self.to_py_function}))
return True
def create_from_py_utility_code(self, env):
if type(self).from_py_function is None:
self.from_py_function = "__Pyx_PyInt_As_" + self.specialization_name()
env.use_utility_code(TempitaUtilityCode.load_cached(
"CIntFromPy", "TypeConversion.c",
context={"TYPE": self.empty_declaration_code(),
"FROM_PY_FUNCTION": self.from_py_function}))
return True
@staticmethod
def _parse_format(format_spec):
padding = ' '
......@@ -1788,23 +1804,12 @@ class CIntType(CNumericType):
format_type, width, padding_char = self._parse_format(format_spec)
return "%s(%s, %d, '%s', '%s')" % (utility_code_name, cvalue, width, padding_char, format_type)
def create_to_py_utility_code(self, env):
if type(self).to_py_function is None:
self.to_py_function = "__Pyx_PyInt_From_" + self.specialization_name()
env.use_utility_code(TempitaUtilityCode.load_cached(
"CIntToPy", "TypeConversion.c",
context={"TYPE": self.empty_declaration_code(),
"TO_PY_FUNCTION": self.to_py_function}))
return True
def create_from_py_utility_code(self, env):
if type(self).from_py_function is None:
self.from_py_function = "__Pyx_PyInt_As_" + self.specialization_name()
env.use_utility_code(TempitaUtilityCode.load_cached(
"CIntFromPy", "TypeConversion.c",
context={"TYPE": self.empty_declaration_code(),
"FROM_PY_FUNCTION": self.from_py_function}))
return True
class CIntType(CIntLike, CNumericType):
is_int = 1
typedef_flag = 0
exception_value = -1
def get_to_py_type_conversion(self):
if self.rank < list(rank_to_type_name).index('int'):
......@@ -3804,7 +3809,7 @@ def is_optional_template_param(type):
return isinstance(type, TemplatePlaceholderType) and type.optional
class CEnumType(CType):
class CEnumType(CIntLike, CType):
# name string
# cname string or None
# typedef_flag boolean
......@@ -3852,28 +3857,6 @@ class CEnumType(CType):
self.name, self.cname, self.typedef_flag, namespace)
return self
def can_coerce_to_pyobject(self, env):
return True
def can_coerce_from_pyobject(self, env):
return True
def create_to_py_utility_code(self, env):
self.to_py_function = "__Pyx_PyInt_From_" + self.specialization_name()
env.use_utility_code(TempitaUtilityCode.load_cached(
"CIntToPy", "TypeConversion.c",
context={"TYPE": self.empty_declaration_code(),
"TO_PY_FUNCTION": self.to_py_function}))
return True
def create_from_py_utility_code(self, env):
self.from_py_function = "__Pyx_PyInt_As_" + self.specialization_name()
env.use_utility_code(TempitaUtilityCode.load_cached(
"CIntFromPy", "TypeConversion.c",
context={"TYPE": self.empty_declaration_code(),
"FROM_PY_FUNCTION": self.from_py_function}))
return True
def from_py_call_code(self, source_code, result_code, error_pos, code,
from_py_function=None, error_condition=None):
rhs = "%s(%s)" % (
......
......@@ -79,6 +79,23 @@ def format2(ab, cd):
return a, b, c
ctypedef enum TestValues:
enum_ABC = 1
enum_XYZ = 2
@cython.test_fail_if_path_exists(
"//CoerceToPyTypeNode",
)
def format_c_enum():
"""
>>> s = format_c_enum()
>>> s == '1-2' or s
True
"""
return f"{enum_ABC}-{enum_XYZ}"
def format_c_numbers(signed char c, short s, int n, long l, float f, double d):
"""
>>> s1, s2, s3, s4 = format_c_numbers(123, 135, 12, 12312312, 2.3456, 3.1415926)
......@@ -123,6 +140,9 @@ def format_c_numbers(signed char c, short s, int n, long l, float f, double d):
return s1, s2, s3, s4
@cython.test_fail_if_path_exists(
"//CoerceToPyTypeNode",
)
def format_c_numbers_max(int n, long l):
"""
>>> n, l = max_int, max_long
......@@ -155,6 +175,9 @@ def format_c_number_const():
return f"{LONG_MAX}"
@cython.test_fail_if_path_exists(
"//CoerceToPyTypeNode",
)
def format_c_number_range(int n):
"""
>>> for i in range(-1000, 1001):
......@@ -163,6 +186,9 @@ def format_c_number_range(int n):
return f'{n}'
@cython.test_fail_if_path_exists(
"//CoerceToPyTypeNode",
)
def format_c_number_range_width(int n):
"""
>>> for i in range(-1000, 1001):
......@@ -183,6 +209,9 @@ def format_c_number_range_width0(int n):
return f'{n:00}'
@cython.test_fail_if_path_exists(
"//CoerceToPyTypeNode",
)
def format_c_number_range_width1(int n):
"""
>>> for i in range(-100, 101):
......@@ -193,6 +222,9 @@ def format_c_number_range_width1(int n):
return f'{n:01}'
@cython.test_fail_if_path_exists(
"//CoerceToPyTypeNode",
)
def format_c_number_range_width_m4(int n):
"""
>>> for i in range(-100, 101):
......@@ -215,6 +247,9 @@ def format_c_number_range_dyn_width(int n, int width):
return f'{n:0{width}}'
@cython.test_fail_if_path_exists(
"//CoerceToPyTypeNode",
)
def format_bool(bint x):
"""
>>> a, b, c, d = format_bool(1)
......
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