2424keywords_set = set (keyword .kwlist )
2525builtins_set = set (__builtins__ .keys ())
2626other_common_names_set = {'datetime' , 'time' , 'date' , 'defaultdict' , 'schema' }
27- blacklist_words = frozenset (keywords_set | builtins_set | other_common_names_set )
28- ones = ['' , 'one' , 'two' , 'three' , 'four' , 'five' , 'six' , 'seven' , 'eight' , 'nine' ]
27+ blacklist_words = frozenset (
28+ keywords_set | builtins_set | other_common_names_set )
29+ ones = ['' , 'one' , 'two' , 'three' , 'four' ,
30+ 'five' , 'six' , 'seven' , 'eight' , 'nine' ]
2931
3032
3133def template (pattern : str , indent : str = INDENT ) -> Template :
@@ -73,7 +75,8 @@ class {{ name }}{% if bases %}({{ bases }}){% endif %}:
7375
7476 STR_CONVERT_DECORATOR = template ("convert_strings({{ str_fields }}{%% if kwargs %%}, %s{%% endif %%})"
7577 % KWAGRS_TEMPLATE )
76- FIELD : Template = template ("{{name}}: {{type}}{% if body %} = {{ body }}{% endif %}" )
78+ FIELD : Template = template (
79+ "{{name}}: {{type}}{% if body %} = {{ body }}{% endif %}" )
7780 DEFAULT_MAX_LITERALS = 10
7881 default_types_style = {
7982 StringLiteral : {
@@ -87,29 +90,36 @@ def __init__(
8790 max_literals = DEFAULT_MAX_LITERALS ,
8891 post_init_converters = False ,
8992 convert_unicode = True ,
90- types_style : Dict [Union ['BaseType' , Type ['BaseType' ]], dict ] = None
93+ types_style : Dict [Union ['BaseType' ,
94+ Type ['BaseType' ]], dict ] = None ,
95+ allow_words : Iterable [str ] = (),
9196 ):
9297 self .model = model
9398 self .post_init_converters = post_init_converters
9499 self .convert_unicode = convert_unicode
100+ self .allow_words = frozenset (allow_words )
95101
96102 resolved_types_style = copy .deepcopy (self .default_types_style )
97103 types_style = types_style or {}
98104 for t , style in types_style .items ():
99105 resolved_types_style .setdefault (t , {})
100106 resolved_types_style [t ].update (style )
101- resolved_types_style [StringLiteral ][StringLiteral .TypeStyle .max_literals ] = int (max_literals )
107+ resolved_types_style [StringLiteral ][StringLiteral .TypeStyle .max_literals ] = int (
108+ max_literals )
102109 self .types_style = resolved_types_style
103110
104- self .model .set_raw_name (self .convert_class_name (self .model .name ), generated = self .model .is_name_generated )
111+ self .model .set_raw_name (self .convert_class_name (
112+ self .model .name ), generated = self .model .is_name_generated )
105113
106114 @cached_method
107115 def convert_class_name (self , name ):
108- return prepare_label (name , convert_unicode = self .convert_unicode , to_snake_case = False )
116+ return prepare_label (name , convert_unicode = self .convert_unicode , to_snake_case = False ,
117+ allow_words = self .allow_words )
109118
110119 @cached_method
111120 def convert_field_name (self , name ):
112- return prepare_label (name , convert_unicode = self .convert_unicode , to_snake_case = True )
121+ return prepare_label (name , convert_unicode = self .convert_unicode , to_snake_case = True ,
122+ allow_words = self .allow_words )
113123
114124 def generate (self , nested_classes : List [str ] = None , bases : str = None , extra : str = "" ) \
115125 -> Tuple [ImportPathList , str ]:
@@ -142,9 +152,11 @@ def decorators(self) -> Tuple[ImportPathList, List[str]]:
142152 if str_fields and decorator_kwargs :
143153 imports .extend ([
144154 * decorator_imports ,
145- ('json_to_models.models.string_converters' , ['convert_strings' ]),
155+ ('json_to_models.models.string_converters' ,
156+ ['convert_strings' ]),
146157 ])
147- decorators .append (self .STR_CONVERT_DECORATOR .render (str_fields = str_fields , kwargs = decorator_kwargs ))
158+ decorators .append (self .STR_CONVERT_DECORATOR .render (
159+ str_fields = str_fields , kwargs = decorator_kwargs ))
148160 return imports , decorators
149161
150162 def field_data (self , name : str , meta : MetaData , optional : bool ) -> Tuple [ImportPathList , dict ]:
@@ -156,7 +168,8 @@ def field_data(self, name: str, meta: MetaData, optional: bool) -> Tuple[ImportP
156168 :param optional: Is field optional
157169 :return: imports, field data
158170 """
159- imports , typing = metadata_to_typing (meta , types_style = self .types_style )
171+ imports , typing = metadata_to_typing (
172+ meta , types_style = self .types_style )
160173
161174 data = {
162175 "name" : self .convert_field_name (name ),
@@ -171,13 +184,15 @@ def fields(self) -> Tuple[ImportPathList, List[str]]:
171184
172185 :return: imports, list of fields as string
173186 """
174- required , optional = sort_fields (self .model , unicode_fix = not self .convert_unicode )
187+ required , optional = sort_fields (
188+ self .model , unicode_fix = not self .convert_unicode )
175189 imports : ImportPathList = []
176190 strings : List [str ] = []
177191 for is_optional , fields in enumerate ((required , optional )):
178192 fields = self ._filter_fields (fields )
179193 for field in fields :
180- field_imports , data = self .field_data (field , self .model .type [field ], bool (is_optional ))
194+ field_imports , data = self .field_data (
195+ field , self .model .type [field ], bool (is_optional ))
181196 imports .extend (field_imports )
182197 strings .append (self .FIELD .render (** data ))
183198 return imports , strings
@@ -256,7 +271,8 @@ def generate_code(structure: ModelsStructureType, class_generator: Type[GenericM
256271 """
257272 root , mapping = structure
258273 with AbsoluteModelRef .inject (mapping ):
259- imports , classes = _generate_code (root , class_generator , class_generator_kwargs or {})
274+ imports , classes = _generate_code (
275+ root , class_generator , class_generator_kwargs or {})
260276 imports_str = ""
261277 if imports :
262278 imports_str = compile_imports (imports ) + objects_delimiter
@@ -284,7 +300,8 @@ def sort_kwargs(kwargs: dict, ordering: Iterable[Iterable[str]]) -> dict:
284300 return sorted_dict
285301
286302
287- def prepare_label (s : str , convert_unicode : bool , to_snake_case : bool ) -> str :
303+ def prepare_label (s : str , convert_unicode : bool , to_snake_case : bool ,
304+ allow_words : frozenset = frozenset ()) -> str :
288305 if convert_unicode :
289306 s = unidecode (s )
290307 s = re .sub (r"\W" , "" , s )
@@ -293,6 +310,6 @@ def prepare_label(s: str, convert_unicode: bool, to_snake_case: bool) -> str:
293310 s = ones [int (s [0 ])] + "_" + s [1 :]
294311 if to_snake_case :
295312 s = inflection .underscore (s )
296- if s in blacklist_words :
313+ if s in ( blacklist_words - allow_words ) :
297314 s += "_"
298315 return s
0 commit comments