@@ -88,13 +88,19 @@ def __init__(self, operand):
8888 )
8989 self .operand = operand
9090
91- def __repr__ (self ):
92- stream = io .BytesIO ()
93- writer = KhiopsOutputWriter (stream )
91+ def write (self , writer ):
92+ assert isinstance (writer , KhiopsOutputWriter ), type_error_message (
93+ "writer" , writer , KhiopsOutputWriter
94+ )
9495 if isinstance (self .operand , Variable ):
9596 writer .write (_format_name (self .operand .name ))
9697 else :
9798 self .operand .write (writer )
99+
100+ def __repr__ (self ):
101+ stream = io .BytesIO ()
102+ writer = KhiopsOutputWriter (stream )
103+ self .write (writer )
98104 return "." + str (stream .getvalue (), encoding = "utf8" , errors = "replace" )
99105
100106
@@ -1556,7 +1562,7 @@ class Rule:
15561562
15571563 Parameters
15581564 ----------
1559- name : str
1565+ name : str or bytes
15601566 Name or verbatim of the rule. It is intepreted as the verbatim
15611567 representation of an entire rule if and only if:
15621568
@@ -1573,6 +1579,7 @@ class Rule:
15731579 Each operand can have one of the following types:
15741580
15751581 - str
1582+ - bytes
15761583 - int
15771584 - float
15781585 - ``Variable``
@@ -1586,12 +1593,13 @@ class Rule:
15861593
15871594 Attributes
15881595 ----------
1589- name : str
1596+ name : str or bytes
15901597 Name of the rule.
15911598 operands : tuple of operands
15921599 Each operand has one of the following types:
15931600
15941601 - str
1602+ - bytes
15951603 - int
15961604 - float
15971605 - ``Variable``
@@ -1601,17 +1609,17 @@ class Rule:
16011609 def __init__ (self , name , * operands ):
16021610 """See class docstring"""
16031611 # Check input parameters
1604- if not isinstance (name , str ):
1605- raise TypeError (type_error_message ("name" , name , str ))
1612+ if not is_string_like (name ):
1613+ raise TypeError (type_error_message ("name" , name , "string-like" ))
16061614 for operand in operands :
1607- if not isinstance (
1608- operand , (str , int , float , Variable , Rule , _ScopedOperand )
1615+ if not is_string_like ( operand ) and not isinstance (
1616+ operand , (int , float , Variable , Rule , _ScopedOperand )
16091617 ):
16101618 raise TypeError (
16111619 type_error_message (
16121620 f"Operand '{ operand } '" ,
16131621 operand ,
1614- str ,
1622+ "string-like" ,
16151623 int ,
16161624 float ,
16171625 Variable ,
@@ -1660,9 +1668,15 @@ def write(self, writer):
16601668 raise TypeError (type_error_message ("writer" , writer , KhiopsOutputWriter ))
16611669
16621670 # Write standard rule
1663- rule_regex = re .compile (r"^[A-Z]([a-zA-Z]*)\(.*\)" )
1671+ rule_pattern = r"^[A-Z]([a-zA-Z]*)\(.*\)"
1672+ rule_regex = re .compile (rule_pattern )
1673+ bytes_rule_regex = re .compile (bytes (rule_pattern , encoding = "ascii" ))
16641674 if self .operands :
1665- writer .write (f"{ _format_name (self .name )} (" )
1675+ if isinstance (self .name , str ):
1676+ writer .write (f"{ _format_name (self .name )} (" )
1677+ else :
1678+ assert isinstance (self .name , bytes )
1679+ writer .write (f"{ _format_name (self .name ).decode ('ascii' )} (" )
16661680
16671681 # Write operand, according to its type
16681682 # Variable operands have their name written only
@@ -1673,6 +1687,8 @@ def write(self, writer):
16731687 writer .write (_format_name (operand .name ))
16741688 elif isinstance (operand , str ):
16751689 writer .write (f'"{ operand } "' )
1690+ elif isinstance (operand , bytes ):
1691+ writer .write (f'"{ operand .decode ("ascii" )} "' )
16761692 elif isinstance (operand , float ) and not math .isfinite (operand ):
16771693 writer .write ("#Missing" )
16781694 # int, finite float or _ScopedOperand cases
@@ -1682,11 +1698,17 @@ def write(self, writer):
16821698 writer .write (", " )
16831699 writer .write (")" )
16841700 # Write verbatim-given rule
1685- elif rule_regex .match (self .name ):
1701+ elif isinstance ( self . name , str ) and rule_regex .match (self .name ):
16861702 writer .write (self .name )
1703+ elif isinstance (self .name , bytes ) and bytes_rule_regex .match (self .name ):
1704+ writer .write (self .name .decode (encoding = "ascii" ))
16871705 # Write rule as a reference rule
16881706 else :
1689- writer .write (f"[{ self .name } ]" )
1707+ if isinstance (self .name , str ):
1708+ writer .write (f"[{ self .name } ]" )
1709+ else :
1710+ assert isinstance (self .name , bytes )
1711+ writer .write (f"[{ self .name .decode ('ascii' )} ]" )
16901712
16911713
16921714class MetaData :
0 commit comments