Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/tablib/formats/__init__.py: 70%
89 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1""" Tablib - formats
2"""
3from collections import OrderedDict
4from functools import partialmethod
5from importlib import import_module
6from importlib.util import find_spec
8from tablib.exceptions import UnsupportedFormat
9from tablib.utils import normalize_input
11from ._csv import CSVFormat
12from ._json import JSONFormat
13from ._tsv import TSVFormat
15uninstalled_format_messages = {
16 "cli": {"package_name": "tabulate package", "extras_name": "cli"},
17 "df": {"package_name": "pandas package", "extras_name": "pandas"},
18 "html": {"package_name": "MarkupPy package", "extras_name": "html"},
19 "ods": {"package_name": "odfpy package", "extras_name": "ods"},
20 "xls": {"package_name": "xlrd and xlwt packages", "extras_name": "xls"},
21 "xlsx": {"package_name": "openpyxl package", "extras_name": "xlsx"},
22 "yaml": {"package_name": "pyyaml package", "extras_name": "yaml"},
23}
26def load_format_class(dotted_path):
27 try:
28 module_path, class_name = dotted_path.rsplit('.', 1)
29 return getattr(import_module(module_path), class_name)
30 except (ValueError, AttributeError) as err:
31 raise ImportError(f"Unable to load format class '{dotted_path}' ({err})")
34class FormatDescriptorBase:
35 def __init__(self, key, format_or_path):
36 self.key = key
37 self._format_path = None
38 if isinstance(format_or_path, str):
39 self._format = None
40 self._format_path = format_or_path
41 else:
42 self._format = format_or_path
44 def ensure_format_loaded(self):
45 if self._format is None:
46 self._format = load_format_class(self._format_path)
49class ImportExportBookDescriptor(FormatDescriptorBase):
50 def __get__(self, obj, cls, **kwargs):
51 self.ensure_format_loaded()
52 return self._format.export_book(obj, **kwargs)
54 def __set__(self, obj, val):
55 self.ensure_format_loaded()
56 return self._format.import_book(obj, normalize_input(val))
59class ImportExportSetDescriptor(FormatDescriptorBase):
60 def __get__(self, obj, cls, **kwargs):
61 self.ensure_format_loaded()
62 return self._format.export_set(obj, **kwargs)
64 def __set__(self, obj, val):
65 self.ensure_format_loaded()
66 return self._format.import_set(obj, normalize_input(val))
69class Registry:
70 _formats = OrderedDict()
72 def register(self, key, format_or_path):
73 from tablib.core import Databook, Dataset
75 # Create Databook.<format> read or read/write properties
76 setattr(Databook, key, ImportExportBookDescriptor(key, format_or_path))
78 # Create Dataset.<format> read or read/write properties,
79 # and Dataset.get_<format>/set_<format> methods.
80 setattr(Dataset, key, ImportExportSetDescriptor(key, format_or_path))
81 try:
82 setattr(Dataset, 'get_%s' % key, partialmethod(Dataset._get_in_format, key))
83 setattr(Dataset, 'set_%s' % key, partialmethod(Dataset._set_in_format, key))
84 except AttributeError:
85 setattr(Dataset, 'get_%s' % key, partialmethod(Dataset._get_in_format, key))
87 self._formats[key] = format_or_path
89 def register_builtins(self):
90 # Registration ordering matters for autodetection.
91 self.register('json', JSONFormat())
92 # xlsx before as xls (xlrd) can also read xlsx
93 if find_spec('openpyxl'): 93 ↛ 95line 93 didn't jump to line 95, because the condition on line 93 was never false
94 self.register('xlsx', 'tablib.formats._xlsx.XLSXFormat')
95 if find_spec('xlrd') and find_spec('xlwt'): 95 ↛ 97line 95 didn't jump to line 97, because the condition on line 95 was never false
96 self.register('xls', 'tablib.formats._xls.XLSFormat')
97 if find_spec('yaml'): 97 ↛ 99line 97 didn't jump to line 99, because the condition on line 97 was never false
98 self.register('yaml', 'tablib.formats._yaml.YAMLFormat')
99 self.register('csv', CSVFormat())
100 self.register('tsv', TSVFormat())
101 if find_spec('odf'): 101 ↛ 103line 101 didn't jump to line 103, because the condition on line 101 was never false
102 self.register('ods', 'tablib.formats._ods.ODSFormat')
103 self.register('dbf', 'tablib.formats._dbf.DBFFormat')
104 if find_spec('MarkupPy'): 104 ↛ 106line 104 didn't jump to line 106, because the condition on line 104 was never false
105 self.register('html', 'tablib.formats._html.HTMLFormat')
106 self.register('jira', 'tablib.formats._jira.JIRAFormat')
107 self.register('latex', 'tablib.formats._latex.LATEXFormat')
108 if find_spec('pandas'): 108 ↛ 110line 108 didn't jump to line 110, because the condition on line 108 was never false
109 self.register('df', 'tablib.formats._df.DataFrameFormat')
110 self.register('rst', 'tablib.formats._rst.ReSTFormat')
111 if find_spec('tabulate'): 111 ↛ 112line 111 didn't jump to line 112, because the condition on line 111 was never true
112 self.register('cli', 'tablib.formats._cli.CLIFormat')
114 def formats(self):
115 for key, frm in self._formats.items():
116 if isinstance(frm, str):
117 self._formats[key] = load_format_class(frm)
118 yield self._formats[key]
120 def get_format(self, key):
121 if key not in self._formats: 121 ↛ 122line 121 didn't jump to line 122, because the condition on line 121 was never true
122 if key in uninstalled_format_messages:
123 raise UnsupportedFormat(
124 "The '{key}' format is not available. You may want to install the "
125 "{package_name} (or `pip install \"tablib[{extras_name}]\"`).".format(
126 **uninstalled_format_messages[key], key=key
127 )
128 )
129 raise UnsupportedFormat("Tablib has no format '%s' or it is not registered." % key)
130 if isinstance(self._formats[key], str):
131 self._formats[key] = load_format_class(self._formats[key])
132 return self._formats[key]
135registry = Registry()