1414 ...
1515
1616"""
17+
1718import csv
19+ from functools import cached_property
1820from io import StringIO
1921
2022from odin import bases
2123from odin .datastructures import CaseLessStringList
2224from odin .exceptions import CodecDecodeError , ValidationError
2325from odin .fields import NotProvided
2426from odin .resources import create_resource_from_iter
25- from odin .utils import getmeta , lazy_property
27+ from odin .utils import getmeta
2628
2729CONTENT_TYPE = "text/csv"
2830
@@ -167,37 +169,29 @@ def _create_reader(self, f, kwargs):
167169 return self .csv_reader (f , self .csv_dialect , ** kwargs )
168170
169171 def _read_header (self ):
170- """
171- Get the header, this needs to be called **once** only!
172- """
172+ """Get the header, this needs to be called **once** only!"""
173173 header = next (self ._reader )
174174 if self .ignore_header_case :
175175 header = CaseLessStringList (header )
176176 return header
177177
178- @lazy_property
178+ @cached_property
179179 def field_names (self ):
180- """
181- Field names from resource.
182- """
180+ """Field names from resource."""
183181 fields = getmeta (self .resource_type ).fields
184182 if self .ignore_header_case :
185183 return CaseLessStringList (field .name for field in fields )
186184 else :
187185 return tuple (field .name for field in fields )
188186
189- @lazy_property
187+ @cached_property
190188 def extra_field_names (self ):
191- """
192- Extra fields not included in header
193- """
189+ """Extra fields not included in header."""
194190 return tuple (field for field in self .header if field not in self .field_names )
195191
196- @lazy_property
192+ @cached_property
197193 def field_mapping (self ):
198- """
199- Index mapping of CSV fields to resource fields.
200- """
194+ """Index mapping of CSV fields to resource fields."""
201195 mapping = []
202196
203197 # Add expected fields
@@ -215,15 +209,15 @@ def field_mapping(self):
215209 return tuple (mapping )
216210
217211
218- def reader (
212+ def reader ( # noqa: PLR0913
219213 f ,
220214 resource ,
221215 includes_header = False ,
222216 csv_module = csv ,
223217 full_clean = True ,
224218 ignore_header_case = False ,
225219 strict_fields = False ,
226- ** kwargs
220+ ** kwargs ,
227221):
228222 """
229223 CSV reader that returns resource objects
@@ -248,7 +242,7 @@ def reader(
248242 includes_header = includes_header ,
249243 ignore_header_case = ignore_header_case ,
250244 strict_fields = strict_fields ,
251- ** kwargs
245+ ** kwargs ,
252246 )
253247
254248
@@ -266,7 +260,7 @@ def _get_resource_type(resources, resource_type):
266260 return resource_type or resources .resource_type
267261 elif isinstance (resources , bases .ResourceIterable ) and resource_type :
268262 return resource_type
269- elif isinstance (resources , ( list , tuple ) ):
263+ elif isinstance (resources , list | tuple ):
270264 if not len (resources ):
271265 return
272266 # Use first resource to obtain field list
0 commit comments