1+ import keyword
2+ import re
13from typing import Iterable , List , Tuple , Type
24
35import inflection
46from jinja2 import Template
7+ from unidecode import unidecode
58
69from . import INDENT , ModelsStructureType , OBJECTS_DELIMITER , indent , sort_fields
710from ..dynamic_typing import AbsoluteModelRef , ImportPathList , MetaData , ModelMeta , compile_imports , metadata_to_typing
1215 "{% if not loop.last %}, {% endif %}" \
1316 "{% endfor %}"
1417
18+ keywords_set = set (keyword .kwlist )
19+ ones = ['' , 'one' , 'two' , 'three' , 'four' , 'five' , 'six' , 'seven' , 'eight' , 'nine' ]
1520
1621def template (pattern : str , indent : str = INDENT ) -> Template :
1722 """
@@ -80,6 +85,17 @@ def decorators(self) -> List[str]:
8085 """
8186 return []
8287
88+ @classmethod
89+ def convert_field_name (cls , name ):
90+ if name in keywords_set :
91+ name += "_"
92+ name = unidecode (name )
93+ name = re .sub (r"\W" , "" , name )
94+ if not ('a' <= name [0 ].lower () <= 'z' ):
95+ if '0' <= name [0 ] <= '9' :
96+ name = ones [int (name [0 ])] + "_" + name [1 :]
97+ return inflection .underscore (name )
98+
8399 def field_data (self , name : str , meta : MetaData , optional : bool ) -> Tuple [ImportPathList , dict ]:
84100 """
85101 Form field data for template
@@ -90,8 +106,9 @@ def field_data(self, name: str, meta: MetaData, optional: bool) -> Tuple[ImportP
90106 :return: imports, field data
91107 """
92108 imports , typing = metadata_to_typing (meta )
109+
93110 data = {
94- "name" : inflection . underscore (name ),
111+ "name" : self . convert_field_name (name ),
95112 "type" : typing
96113 }
97114 return imports , data
0 commit comments