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