dsff 1.2.2__tar.gz → 1.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dsff-1.2.2/src/dsff.egg-info → dsff-1.2.3}/PKG-INFO +1 -1
- dsff-1.2.3/src/dsff/VERSION.txt +1 -0
- {dsff-1.2.2 → dsff-1.2.3}/src/dsff/formats/__init__.py +1 -1
- {dsff-1.2.2 → dsff-1.2.3}/src/dsff/formats/arff.py +21 -13
- {dsff-1.2.2 → dsff-1.2.3}/src/dsff/formats/csv.py +14 -13
- {dsff-1.2.2 → dsff-1.2.3}/src/dsff/formats/dataset.py +22 -8
- {dsff-1.2.2 → dsff-1.2.3}/src/dsff/formats/db.py +32 -25
- dsff-1.2.3/src/dsff/formats/pa.py +46 -0
- {dsff-1.2.2 → dsff-1.2.3/src/dsff.egg-info}/PKG-INFO +1 -1
- {dsff-1.2.2 → dsff-1.2.3}/tests/test_dsff.py +10 -4
- dsff-1.2.2/src/dsff/VERSION.txt +0 -1
- dsff-1.2.2/src/dsff/formats/pa.py +0 -36
- {dsff-1.2.2 → dsff-1.2.3}/.coveragerc +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/.github/workflows/python-package.yml +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/.gitignore +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/.readthedocs.yml +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/LICENSE +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/README.md +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/docs/coverage.svg +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/docs/mkdocs.yml +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/docs/pages/imgs/dsff-from.png +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/docs/pages/imgs/dsff-to.png +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/docs/pages/imgs/icon.png +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/docs/pages/imgs/logo.png +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/docs/pages/index.md +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/docs/pages/usage.md +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/docs/requirements.txt +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/pyproject.toml +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/pytest.ini +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/requirements.txt +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/setup.cfg +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/src/dsff/__info__.py +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/src/dsff/__init__.py +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/src/dsff/formats/__common__.py +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/src/dsff.egg-info/SOURCES.txt +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/src/dsff.egg-info/dependency_links.txt +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/src/dsff.egg-info/requires.txt +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/src/dsff.egg-info/top_level.txt +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/tests/__init__.py +0 -0
- {dsff-1.2.2 → dsff-1.2.3}/tests/utils.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.2.3
|
|
@@ -23,7 +23,7 @@ if PYARROW: # pragma: no cover
|
|
|
23
23
|
|
|
24
24
|
__all__ = ["DSFF"]
|
|
25
25
|
for k in list(globals().keys()):
|
|
26
|
-
if k.startswith("is_"):
|
|
26
|
+
if k.startswith("is_") or k.startswith("load_"):
|
|
27
27
|
__all__.append(k)
|
|
28
28
|
|
|
29
29
|
_FORMAT_TEXT_ALIAS = {'arff': "ARFF", 'csv': "CSV", 'db': "SQL", 'orc': "ORC"}
|
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
from .__common__ import *
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
__all__ = ["from_arff", "is_arff", "to_arff"]
|
|
5
|
+
__all__ = ["from_arff", "is_arff", "load_arff", "to_arff"]
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
def _parse(text_or_fh, target=TARGET_NAME, missing=MISSING_TOKEN):
|
|
8
|
+
def _parse(text_or_fh, target=TARGET_NAME, missing=MISSING_TOKEN, **kw):
|
|
9
9
|
d, features, metadata, title = [], {}, {}, ""
|
|
10
10
|
relation, attributes, data = False, [False, False], False
|
|
11
11
|
for n, l in enumerate(t.splitlines() if isinstance(t := text_or_fh, str) else t):
|
|
12
12
|
l, pf = l.strip(), f"Line {n}: "
|
|
13
13
|
# the file shall start with "@RELATION"
|
|
14
14
|
if not relation:
|
|
15
|
-
if l.startswith("@RELATION "):
|
|
15
|
+
if l.upper().startswith("@RELATION "):
|
|
16
16
|
relation = True
|
|
17
17
|
try:
|
|
18
|
-
title = re.match(r"@RELATION\s+('[^']*'|\"[^\"]*\")$", l).group(1).strip("'\"")
|
|
18
|
+
title = re.match(r"@RELATION\s+('[^']*'|\"[^\"]*\")$", l, re.I).group(1).strip("'\"")
|
|
19
19
|
continue
|
|
20
20
|
except Exception as e:
|
|
21
21
|
raise BadInputData(f"{pf}failed on @RELATION ({e})")
|
|
@@ -34,9 +34,8 @@ def _parse(text_or_fh, target=TARGET_NAME, missing=MISSING_TOKEN):
|
|
|
34
34
|
if attributes[0] and not attributes[1]:
|
|
35
35
|
# close the atributes block
|
|
36
36
|
attributes[1] = True
|
|
37
|
-
n_cols = len(d[0])
|
|
38
37
|
continue
|
|
39
|
-
if l.startswith("@ATTRIBUTE "):
|
|
38
|
+
if l.upper().startswith("@ATTRIBUTE "):
|
|
40
39
|
if not attributes[0]:
|
|
41
40
|
attributes[0] = True
|
|
42
41
|
if len(d) == 0:
|
|
@@ -45,21 +44,23 @@ def _parse(text_or_fh, target=TARGET_NAME, missing=MISSING_TOKEN):
|
|
|
45
44
|
if attributes[1]:
|
|
46
45
|
raise BadInputData(f"{pf}found @ATTRIBUTE out of the attributes block)")
|
|
47
46
|
try:
|
|
48
|
-
header = re.match(r"@ATTRIBUTE\s+([^\s]+)\s+[
|
|
47
|
+
header = re.match(r"@ATTRIBUTE\s+([^\s]+)\s+(?:[a-zA-Z]+|\{.*?\})$", l, re.I).group(1).strip("'\"")
|
|
49
48
|
if header == "class":
|
|
50
49
|
header = target
|
|
50
|
+
else:
|
|
51
|
+
features.setdefault(header, "")
|
|
51
52
|
d[0].append(header)
|
|
52
53
|
continue
|
|
53
54
|
except AttributeError:
|
|
54
55
|
raise BadInputData(f"{pf}failed on @ATTRIBUTE (bad type)")
|
|
55
56
|
if not data:
|
|
56
|
-
if l == "@DATA":
|
|
57
|
+
if l.upper() == "@DATA":
|
|
57
58
|
data = True
|
|
59
|
+
n_cols = len(d[0])
|
|
58
60
|
continue
|
|
59
61
|
else:
|
|
60
62
|
raise BadInputData(f"{pf}did not find @DATA where expected")
|
|
61
|
-
row
|
|
62
|
-
if len(row) != n_cols:
|
|
63
|
+
if len(row := list(map(lambda x: x.strip("'\""), re.split(r",\s*", l)))) != n_cols:
|
|
63
64
|
raise BadInputData(f"{pf}this row does not match the number of columns")
|
|
64
65
|
d.append(row)
|
|
65
66
|
for i in range(n_cols):
|
|
@@ -78,7 +79,7 @@ def _parse(text_or_fh, target=TARGET_NAME, missing=MISSING_TOKEN):
|
|
|
78
79
|
return d, features, metadata, title
|
|
79
80
|
|
|
80
81
|
|
|
81
|
-
def from_arff(dsff, path=None, target=TARGET_NAME, missing=MISSING_TOKEN):
|
|
82
|
+
def from_arff(dsff, path=None, target=TARGET_NAME, missing=MISSING_TOKEN, **kw):
|
|
82
83
|
""" Populate the DSFF file from an ARFF file. """
|
|
83
84
|
with open(path) as f:
|
|
84
85
|
d, ft, md, t = _parse(f, target, missing)
|
|
@@ -87,7 +88,7 @@ def from_arff(dsff, path=None, target=TARGET_NAME, missing=MISSING_TOKEN):
|
|
|
87
88
|
|
|
88
89
|
|
|
89
90
|
@text_or_path
|
|
90
|
-
def is_arff(text):
|
|
91
|
+
def is_arff(text, target=TARGET_NAME, missing=MISSING_TOKEN, **kw):
|
|
91
92
|
""" Check if the input text or path is a valid ARFF. """
|
|
92
93
|
try:
|
|
93
94
|
_parse(ensure_str(text))
|
|
@@ -96,7 +97,14 @@ def is_arff(text):
|
|
|
96
97
|
return False
|
|
97
98
|
|
|
98
99
|
|
|
99
|
-
def
|
|
100
|
+
def load_arff(path, target=TARGET_NAME, missing=MISSING_TOKEN, **kw):
|
|
101
|
+
""" Load an ARFF file as a dictionary with data, features and metadata. """
|
|
102
|
+
with open(path) as f:
|
|
103
|
+
d, ft, md, _ = _parse(f, target, missing)
|
|
104
|
+
return {'data': d, 'features': ft, 'metadata': md}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def to_arff(dsff, path=None, target=TARGET_NAME, exclude=DEFAULT_EXCL, missing=MISSING_TOKEN, text=False, **kw):
|
|
100
108
|
""" Output the dataset in ARFF format, suitable for use with the Weka framework, saved as a file or output as a
|
|
101
109
|
string. """
|
|
102
110
|
name = splitext(basename(path))[0]
|
|
@@ -2,24 +2,16 @@
|
|
|
2
2
|
from .__common__ import *
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
__all__ = ["from_csv", "is_csv", "to_csv"]
|
|
5
|
+
__all__ = ["from_csv", "is_csv", "load_csv", "to_csv"]
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
def from_csv(dsff, path=None, exclude=DEFAULT_EXCL):
|
|
8
|
+
def from_csv(dsff, path=None, exclude=DEFAULT_EXCL, **kw):
|
|
9
9
|
""" Populate the DSFF file from a CSV file. """
|
|
10
|
-
dsff.write(path)
|
|
11
|
-
features = {}
|
|
12
|
-
for headers in dsff['data'].rows:
|
|
13
|
-
for header in headers:
|
|
14
|
-
if header.value in exclude:
|
|
15
|
-
continue
|
|
16
|
-
features[header.value] = ""
|
|
17
|
-
break
|
|
18
|
-
dsff.write(features=features)
|
|
10
|
+
dsff.write(**load_csv(path))
|
|
19
11
|
|
|
20
12
|
|
|
21
13
|
@text_or_path
|
|
22
|
-
def is_csv(text):
|
|
14
|
+
def is_csv(text, **kw):
|
|
23
15
|
""" Check if the input text or path is a valid CSV. """
|
|
24
16
|
try:
|
|
25
17
|
dialect = csvmod.Sniffer().sniff(text := ensure_str(text))
|
|
@@ -29,7 +21,16 @@ def is_csv(text):
|
|
|
29
21
|
return False
|
|
30
22
|
|
|
31
23
|
|
|
32
|
-
def
|
|
24
|
+
def load_csv(path, exclude=DEFAULT_EXCL, **kw):
|
|
25
|
+
""" Load a CSV file as a dictionary with data, features and metadata. """
|
|
26
|
+
data = {'metadata': {}}
|
|
27
|
+
with open(expanduser(path)) as f:
|
|
28
|
+
data['data'] = [r for r in csvmod.reader(f, delimiter=CSV_DELIMITER)]
|
|
29
|
+
data['features'] = {h: "" for h in data['data'][0] if h not in exclude}
|
|
30
|
+
return data
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def to_csv(dsff, path=None, text=False, **kw):
|
|
33
34
|
""" Create a CSV from the data worksheet, saved as a file or output as a string. """
|
|
34
35
|
with (StringIO() if text else open(path, 'w+')) as f:
|
|
35
36
|
writer = csvmod.writer(f, delimiter=";")
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
# -*- coding: UTF-8 -*-
|
|
2
2
|
from .__common__ import *
|
|
3
|
+
from .csv import load_csv
|
|
3
4
|
|
|
4
5
|
|
|
5
|
-
__all__ = ["from_dataset", "is_dataset", "to_dataset"]
|
|
6
|
+
__all__ = ["from_dataset", "is_dataset", "load_dataset", "to_dataset"]
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
def _parse(path):
|
|
9
|
-
if not isdir(path):
|
|
10
|
+
if not isdir(expanduser(path)):
|
|
10
11
|
raise BadInputData("Not a folder")
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
raise BadInputData(f"Not a valid dataset folder (missing: {', '.join(missing)})")
|
|
12
|
+
if len(missing := [f for f in ["data.csv", "features.json", "metadata.json"] if not isfile(join(path, f))]) > 0:
|
|
13
|
+
raise BadInputData(f"Not a valid dataset folder (missing: {', '.join(missing)})")
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
def from_dataset(dsff, path=None):
|
|
16
|
+
def from_dataset(dsff, path=None, **kw):
|
|
17
17
|
""" Populate the DSFF file from a Dataset structure. """
|
|
18
18
|
_parse(path)
|
|
19
19
|
dsff.write(path)
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def is_dataset(path):
|
|
22
|
+
def is_dataset(path, **kw):
|
|
23
23
|
""" Check if the input path is a valid Dataset. """
|
|
24
24
|
try:
|
|
25
25
|
_parse(path)
|
|
@@ -28,7 +28,21 @@ def is_dataset(path):
|
|
|
28
28
|
return False
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
def
|
|
31
|
+
def load_dataset(path, **kw):
|
|
32
|
+
""" Load a dataset folder as a dictionary with data, features and metadata. """
|
|
33
|
+
if not isdir(d := expanduser(str(path))):
|
|
34
|
+
raise BadInputData("Not a folder")
|
|
35
|
+
dp, fp, mp = join(d, "data.csv"), join(d, "features.json"), join(d, "metadata.json")
|
|
36
|
+
data = {}
|
|
37
|
+
data['data'] = load_csv(dp)['data']
|
|
38
|
+
with open(fp) as f:
|
|
39
|
+
data['features'] = json.load(f)
|
|
40
|
+
with open(mp) as f:
|
|
41
|
+
data['metadata'] = json.load(f)
|
|
42
|
+
return data
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def to_dataset(dsff, path=None, **kw):
|
|
32
46
|
""" Create a dataset folder according to the following structure ;
|
|
33
47
|
name
|
|
34
48
|
+-- data.csv
|
|
@@ -2,36 +2,16 @@
|
|
|
2
2
|
from .__common__ import *
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
__all__ = ["from_db", "is_db", "to_db"]
|
|
5
|
+
__all__ = ["from_db", "is_db", "load_db", "to_db"]
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
def from_db(dsff, path=None,
|
|
8
|
+
def from_db(dsff, path=None, **kw):
|
|
9
9
|
""" Populate the DSFF file from a SQLDB file. """
|
|
10
|
-
|
|
11
|
-
from sqlite3 import connect
|
|
12
|
-
conn = connect(path)
|
|
13
|
-
cursor = conn.cursor()
|
|
14
|
-
# list tables
|
|
15
|
-
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
|
|
16
|
-
tables = [table[0] for table in cursor.fetchall()]
|
|
17
|
-
if not all(t in tables for t in ["data", "features", "metadata"]): # pragma: no cover
|
|
18
|
-
raise BadInputData("The target SQLDB does not have the right format")
|
|
19
|
-
# import data
|
|
20
|
-
cursor.execute("PRAGMA table_info('data')")
|
|
21
|
-
headers = [[col[1] for col in cursor.fetchall()]]
|
|
22
|
-
cursor.execute("SELECT * FROM data;")
|
|
23
|
-
dsff.write(headers + [r for r in cursor.fetchall()])
|
|
24
|
-
# import feature definitions
|
|
25
|
-
cursor.execute("SELECT name,description FROM features;")
|
|
26
|
-
dsff.write(features={r[0]: r[1] for r in cursor.fetchall()})
|
|
27
|
-
# import metadata
|
|
28
|
-
cursor.execute("SELECT key,value FROM metadata;")
|
|
29
|
-
dsff.write(metadata={r[0]: loads(r[1]) if isinstance(r[1], str) else r[1] for r in cursor.fetchall()})
|
|
30
|
-
conn.close()
|
|
10
|
+
dsff.write(**load_db(path))
|
|
31
11
|
|
|
32
12
|
|
|
33
13
|
@text_or_path
|
|
34
|
-
def is_db(data):
|
|
14
|
+
def is_db(data, **kw):
|
|
35
15
|
""" Check if the input data or path is a valid SQL database. """
|
|
36
16
|
from sqlite3 import connect, Error
|
|
37
17
|
from sys import version_info
|
|
@@ -60,7 +40,34 @@ def is_db(data):
|
|
|
60
40
|
return False
|
|
61
41
|
|
|
62
42
|
|
|
63
|
-
def
|
|
43
|
+
def load_db(path, **kw):
|
|
44
|
+
""" Load a SQLDB file as a dictionary with data, features and metadata. """
|
|
45
|
+
from json import loads
|
|
46
|
+
from os.path import basename, splitext
|
|
47
|
+
from sqlite3 import connect
|
|
48
|
+
conn = connect(path)
|
|
49
|
+
cursor, data = conn.cursor(), {}
|
|
50
|
+
# list tables
|
|
51
|
+
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
|
|
52
|
+
tables = [table[0] for table in cursor.fetchall()]
|
|
53
|
+
if not all(t in tables for t in ["data", "features", "metadata"]): # pragma: no cover
|
|
54
|
+
raise BadInputData("The target SQLDB does not have the right format")
|
|
55
|
+
# import data
|
|
56
|
+
cursor.execute("PRAGMA table_info('data')")
|
|
57
|
+
headers = [[col[1] for col in cursor.fetchall()]]
|
|
58
|
+
cursor.execute("SELECT * FROM data;")
|
|
59
|
+
data['data'] = headers + [r for r in cursor.fetchall()]
|
|
60
|
+
# import feature definitions
|
|
61
|
+
cursor.execute("SELECT name,description FROM features;")
|
|
62
|
+
data['features'] = {r[0]: r[1] for r in cursor.fetchall()}
|
|
63
|
+
# import metadata
|
|
64
|
+
cursor.execute("SELECT key,value FROM metadata;")
|
|
65
|
+
data['metadata'] = {r[0]: loads(r[1]) if isinstance(r[1], str) else r[1] for r in cursor.fetchall()}
|
|
66
|
+
conn.close()
|
|
67
|
+
return data
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def to_db(dsff, path=None, text=False, primary_index=0, **kw):
|
|
64
71
|
""" Create a SQLDB from the data worksheet, saved as a file or output as a string. """
|
|
65
72
|
from json import dumps
|
|
66
73
|
from sqlite3 import connect
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
|
2
|
+
from .__common__ import *
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
__all__ = []
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _nowrite(m):
|
|
9
|
+
raise NotImplementedError(f"none of {m}.write_table and {m}.write_{m} is implemented")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _parse(ds):
|
|
13
|
+
return {
|
|
14
|
+
'data': [ds.schema.names] + [list(r.values()) for r in ds.to_pylist()],
|
|
15
|
+
'features': {k.decode(): v.decode() for k, v in ds.schema.metadata.items()},
|
|
16
|
+
'metadata': literal_eval(ds.schema.metadata.pop(b'__metadata__', b"{}").decode()),
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
for module in ["feather", "orc", "parquet"]:
|
|
21
|
+
__all__ += [f"from_{module}", f"is_{module}", f"load_{module}", f"to_{module}"]
|
|
22
|
+
def gen_func(m):
|
|
23
|
+
def from_(dsff, path=None, **kw):
|
|
24
|
+
from os.path import basename, splitext
|
|
25
|
+
dsff.write(**_parse(globals()[m].read_table(path)))
|
|
26
|
+
from_.__name__ = f"from_{m}"
|
|
27
|
+
def is_(data, **kw):
|
|
28
|
+
try:
|
|
29
|
+
globals()[m].read_table(pyarrow.BufferReader(data))
|
|
30
|
+
return True
|
|
31
|
+
except Exception:
|
|
32
|
+
return False
|
|
33
|
+
is_.__name__ = f"is_{m}"
|
|
34
|
+
def load_(path, **kw):
|
|
35
|
+
return _parse(globals()[m].read_table(path))
|
|
36
|
+
load_.__name__ = f"load_{m}"
|
|
37
|
+
def to_(dsff, path=None, text=False, **kw):
|
|
38
|
+
with (BytesIO() if text else open(path, 'wb+')) as f:
|
|
39
|
+
getattr(globals()[m], "write_table", getattr(globals()[m], f"write_{m}", _nowrite))(dsff._to_table(), f)
|
|
40
|
+
if text:
|
|
41
|
+
return f.getvalue()
|
|
42
|
+
to_.__name__ = f"to_{m}"
|
|
43
|
+
return from_, text_or_path(is_), load_, to_
|
|
44
|
+
globals()[f'from_{module}'], globals()[f'is_{module}'], globals()[f'load_{module}'], globals()[f'to_{module}'] = \
|
|
45
|
+
gen_func(module)
|
|
46
|
+
|
|
@@ -89,6 +89,7 @@ class TestDsff(TestCase):
|
|
|
89
89
|
with open(arff := f"{TEST_BASENAME}.arff", 'w') as f:
|
|
90
90
|
f.write(TEST_ARFF)
|
|
91
91
|
self.assertTrue(is_arff(arff))
|
|
92
|
+
self.assertIsInstance(load_arff(arff), dict)
|
|
92
93
|
with DSFF() as f:
|
|
93
94
|
f.from_arff(TEST_BASENAME)
|
|
94
95
|
# test for multiple error scenarios
|
|
@@ -130,7 +131,8 @@ class TestDsff(TestCase):
|
|
|
130
131
|
with DSFF(TEST) as f:
|
|
131
132
|
self.assertIsNotNone(f.to_csv(text=True))
|
|
132
133
|
self.assertIsNone(f.to_csv())
|
|
133
|
-
self.assertTrue(is_csv(f"{
|
|
134
|
+
self.assertTrue(is_csv(csv := f"{TEST_BASENAME}.csv"))
|
|
135
|
+
self.assertIsInstance(load_csv(csv), dict)
|
|
134
136
|
# CSV to DSFF
|
|
135
137
|
with DSFF() as f:
|
|
136
138
|
f.from_csv(TEST_BASENAME)
|
|
@@ -143,7 +145,9 @@ class TestDsff(TestCase):
|
|
|
143
145
|
# FilelessDataset to DSFF
|
|
144
146
|
with DSFF() as f:
|
|
145
147
|
f.from_dataset(TEST_BASENAME)
|
|
146
|
-
self.assertTrue(is_dataset(
|
|
148
|
+
self.assertTrue(is_dataset(TEST_BASENAME))
|
|
149
|
+
self.assertRaises(BadInputData, load_dataset, 0)
|
|
150
|
+
self.assertIsInstance(load_dataset(TEST_BASENAME), dict)
|
|
147
151
|
# FilelessDataset to DSFF (bad input dataset)
|
|
148
152
|
os.remove(os.path.join(TEST_BASENAME, "metadata.json"))
|
|
149
153
|
with DSFF() as f:
|
|
@@ -167,7 +171,8 @@ class TestDsff(TestCase):
|
|
|
167
171
|
with DSFF(TEST) as f:
|
|
168
172
|
self.assertIsNotNone(f.to_db(text=True))
|
|
169
173
|
self.assertIsNone(f.to_db())
|
|
170
|
-
self.assertTrue(is_db(f"{TEST_BASENAME}.db"))
|
|
174
|
+
self.assertTrue(is_db(db := f"{TEST_BASENAME}.db"))
|
|
175
|
+
self.assertIsInstance(load_db(db), dict)
|
|
171
176
|
# SQL database to DSFF
|
|
172
177
|
with DSFF() as f:
|
|
173
178
|
f.from_db(TEST_BASENAME)
|
|
@@ -183,8 +188,9 @@ class TestDsff(TestCase):
|
|
|
183
188
|
self.assertIsNone(getattr(f, f"to_{fmt}")(TEST_BASENAME))
|
|
184
189
|
self.assertIsNotNone(getattr(f, f"to_{fmt}")(text=True))
|
|
185
190
|
is_ = globals()[f'is_{fmt}']
|
|
186
|
-
self.assertTrue(is_(f"{TEST_BASENAME}.{fmt}"))
|
|
191
|
+
self.assertTrue(is_(fn := f"{TEST_BASENAME}.{fmt}"))
|
|
187
192
|
self.assertFalse(is_(b"PK\x03\x04\x14\x00\x00\x00\x08\x00P\xb3T\\F\xc7MH"))
|
|
193
|
+
self.assertIsInstance(globals()[f'load_{fmt}'](fn), dict)
|
|
188
194
|
with DSFF(INMEMORY) as f:
|
|
189
195
|
self.assertIsNone(getattr(f, f"from_{fmt}")(TEST_BASENAME))
|
|
190
196
|
f.to_dataset(path=TEST_BASENAME)
|
dsff-1.2.2/src/dsff/VERSION.txt
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1.2.2
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# -*- coding: UTF-8 -*-
|
|
2
|
-
from .__common__ import *
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
__all__ = []
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def _nowrite(m):
|
|
9
|
-
raise NotImplementedError(f"none of {m}.write_table and {m}.write_{m} is implemented")
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
for module in ["feather", "orc", "parquet"]:
|
|
13
|
-
__all__ += [f"from_{module}", f"is_{module}", f"to_{module}"]
|
|
14
|
-
def gen_func(m):
|
|
15
|
-
def from_(dsff, path=None, exclude=DEFAULT_EXCL):
|
|
16
|
-
dataset = globals()[m].read_table(path)
|
|
17
|
-
dsff.write(data=[dataset.schema.names] + [list(r.values()) for r in dataset.to_pylist()],
|
|
18
|
-
metadata=literal_eval(dataset.schema.metadata.pop(b'__metadata__', b"{}").decode()),
|
|
19
|
-
features={k.decode(): v.decode() for k, v in dataset.schema.metadata.items()})
|
|
20
|
-
from_.__name__ = f"from_{m}"
|
|
21
|
-
def is_(data):
|
|
22
|
-
try:
|
|
23
|
-
globals()[m].read_table(pyarrow.BufferReader(data))
|
|
24
|
-
return True
|
|
25
|
-
except Exception:
|
|
26
|
-
return False
|
|
27
|
-
is_.__name__ = f"is_{m}"
|
|
28
|
-
def to_(dsff, path=None, text=False):
|
|
29
|
-
with (BytesIO() if text else open(path, 'wb+')) as f:
|
|
30
|
-
getattr(globals()[m], "write_table", getattr(globals()[m], f"write_{m}", _nowrite))(dsff._to_table(), f)
|
|
31
|
-
if text:
|
|
32
|
-
return f.getvalue()
|
|
33
|
-
to_.__name__ = f"to_{m}"
|
|
34
|
-
return from_, text_or_path(is_), to_
|
|
35
|
-
globals()[f'from_{module}'], globals()[f'is_{module}'], globals()[f'to_{module}'] = gen_func(module)
|
|
36
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|