tableio 0.1__tar.gz → 0.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.
- {tableio-0.1/tableio.egg-info → tableio-0.3}/PKG-INFO +62 -20
- {tableio-0.1 → tableio-0.3}/README.md +14 -19
- tableio-0.3/README_pypi.md +123 -0
- {tableio-0.1 → tableio-0.3}/pyproject.toml +2 -3
- {tableio-0.1 → tableio-0.3}/setup.py +6 -3
- tableio-0.3/src/tableio/__init__.py +47 -0
- {tableio-0.1 → tableio-0.3}/src/tableio/capability.py +94 -1
- {tableio-0.1 → tableio-0.3}/src/tableio/factory.py +46 -3
- {tableio-0.1 → tableio-0.3}/src/tableio/reg_pkg_formats.py +7 -1
- {tableio-0.1 → tableio-0.3}/src/tableio/tableio.py +354 -168
- {tableio-0.1 → tableio-0.3}/src/tableio/tableio_csv.py +26 -37
- tableio-0.3/src/tableio/tableio_excel_openpyxl.py +286 -0
- tableio-0.3/src/tableio/tableio_excel_pylightxl.py +709 -0
- tableio-0.3/src/tableio/tableio_excel_xlsxwriter.py +407 -0
- {tableio-0.1 → tableio-0.3}/src/tableio/tableio_excelbased.py +49 -2
- {tableio-0.1 → tableio-0.3}/src/tableio/tableio_mformat.py +1 -1
- {tableio-0.1 → tableio-0.3}/src/tableio/tableio_mformatbased.py +32 -37
- tableio-0.3/src/tableio/tableio_ods_odfdo.py +482 -0
- tableio-0.3/src/tableio/tableio_spreadsheetbased.py +783 -0
- tableio-0.3/src/tableio/tableio_types.py +61 -0
- {tableio-0.1 → tableio-0.3}/src/tableio/value_type.py +2 -0
- tableio-0.3/src/tableio/valueconversion.py +397 -0
- {tableio-0.1 → tableio-0.3/tableio.egg-info}/PKG-INFO +62 -20
- {tableio-0.1 → tableio-0.3}/tableio.egg-info/SOURCES.txt +5 -0
- {tableio-0.1 → tableio-0.3}/tableio.egg-info/requires.txt +4 -1
- tableio-0.1/README_pypi.md +0 -83
- tableio-0.1/src/tableio/__init__.py +0 -6
- tableio-0.1/src/tableio/tableio_excel_openpyxl.py +0 -630
- tableio-0.1/src/tableio/tableio_spreadsheetbased.py +0 -46
- {tableio-0.1 → tableio-0.3}/LICENSE.txt +0 -0
- {tableio-0.1 → tableio-0.3}/setup.cfg +0 -0
- {tableio-0.1 → tableio-0.3}/src/tableio/color.py +0 -0
- {tableio-0.1 → tableio-0.3}/src/tableio/optional_args.py +0 -0
- {tableio-0.1 → tableio-0.3}/src/tableio/py.typed +0 -0
- {tableio-0.1 → tableio-0.3}/src/tableio/tableio_textbased.py +0 -0
- {tableio-0.1 → tableio-0.3}/tableio.egg-info/dependency_links.txt +0 -0
- {tableio-0.1 → tableio-0.3}/tableio.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tableio
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3
|
|
4
4
|
Summary: Uniform way to write table data to and read from different file formats
|
|
5
5
|
Author: Tom Björkholm
|
|
6
6
|
Author-email: Tom Björkholm <klausuler_linnet0q@icloud.com>
|
|
@@ -8,17 +8,19 @@ License-Expression: MIT
|
|
|
8
8
|
Project-URL: Source code, https://bitbucket.org/tom-bjorkholm/table-io
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
|
-
Classifier: Development Status :: 2 - Pre-Alpha
|
|
12
11
|
Requires-Python: >=3.12
|
|
13
12
|
Description-Content-Type: text/markdown
|
|
14
13
|
License-File: LICENSE.txt
|
|
15
14
|
Requires-Dist: pip>=26.0.1
|
|
16
15
|
Requires-Dist: setuptools>=82.0.1
|
|
17
|
-
Requires-Dist: build>=1.4.
|
|
16
|
+
Requires-Dist: build>=1.4.2
|
|
18
17
|
Requires-Dist: wheel>=0.46.3
|
|
19
18
|
Requires-Dist: mformat-ext>=0.6
|
|
20
19
|
Requires-Dist: openpyxl>=3.1.5
|
|
21
20
|
Requires-Dist: types-openpyxl>=3.1.5.20260322
|
|
21
|
+
Requires-Dist: odfdo>=3.22.3
|
|
22
|
+
Requires-Dist: xlsxwriter>=3.2.9
|
|
23
|
+
Requires-Dist: pylightxl>=1.61
|
|
22
24
|
Dynamic: author
|
|
23
25
|
Dynamic: license-file
|
|
24
26
|
Dynamic: requires-dist
|
|
@@ -30,9 +32,15 @@ The tableio package contains a number of classes providing a uniform way for
|
|
|
30
32
|
a python program to write table data (rows of columns) to and read table data
|
|
31
33
|
from a number of different common file formats.
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
An increasing number of users want output from programs to be in a format
|
|
36
|
+
like a spreadsheet, and not the old fashoned raw text files. Similarly,
|
|
37
|
+
many users want the data they feed into programs to be in a particular format
|
|
38
|
+
(like a spreadsheet). The tableio package tries to make it easier for the
|
|
39
|
+
programmer to fullfil requests like that.
|
|
40
|
+
|
|
41
|
+
The primary intended use is for data table output from a python program
|
|
42
|
+
and data table input to a python program, where the programmer would like
|
|
43
|
+
the user to be able to select the input and output file formats.
|
|
36
44
|
|
|
37
45
|
The support for spreadsheets is for reading and writing data. There is no
|
|
38
46
|
intention to support reading or writing formulas. There is no support for
|
|
@@ -40,10 +48,6 @@ running calculations in the spreadsheets (although nothing will stop a
|
|
|
40
48
|
receiver of a spreadsheet created by tableio package to manually add
|
|
41
49
|
formulas in the received spreadsheet).
|
|
42
50
|
|
|
43
|
-
## Early design phase
|
|
44
|
-
|
|
45
|
-
This project is in an early design phase. This means that major changes to the APIs are still expected.
|
|
46
|
-
|
|
47
51
|
## Installing tableio
|
|
48
52
|
|
|
49
53
|
### Installing tableio on mac and Linux
|
|
@@ -66,24 +70,60 @@ The currently supported formats are:
|
|
|
66
70
|
|-------------|----------------|-----------|----------|
|
|
67
71
|
| CSV | csv | yes | yes |
|
|
68
72
|
| Excel | OpenPyXL | yes | yes |
|
|
73
|
+
| Excel | XlsxWriter | yes | - |
|
|
74
|
+
| Excel | pylightxl | yes | yes |
|
|
75
|
+
| ODS | odfdo | yes | yes |
|
|
69
76
|
| HTML | mformat | yes | - |
|
|
70
77
|
| LaTeX | mformat | yes | - |
|
|
71
78
|
| docx | mformat | yes | - |
|
|
72
79
|
| md | mformat | yes | - |
|
|
73
80
|
| odt | mformat | yes | - |
|
|
74
81
|
| pdf | mformat | yes | - |
|
|
75
|
-
|
|
|
82
|
+
| reST | mformat | yes | - |
|
|
76
83
|
| rtf | mformat | yes | - |
|
|
77
84
|
| txt | mformat | yes | - |
|
|
78
85
|
|
|
86
|
+
## Features
|
|
87
|
+
|
|
88
|
+
All features are not available for all file formats. Often the file
|
|
89
|
+
format restricts what features are reasonable in that format. Using
|
|
90
|
+
a selection mechanism called Capabilities it is possible to select
|
|
91
|
+
file format at runtime based on what features are essential. It is
|
|
92
|
+
also possible to ignore some features when using a file format that
|
|
93
|
+
cannot support that feature (like ignoring bold fomatting in CSV).
|
|
94
|
+
|
|
95
|
+
The main features are:
|
|
96
|
+
|
|
97
|
+
- File open modes: Create, Read or Update
|
|
98
|
+
- Writing tables from list of lists or list of dicts
|
|
99
|
+
- Writing headings before and between tables
|
|
100
|
+
- Reading tables to list of lists or list of dicts, including the headings
|
|
101
|
+
before the table.
|
|
102
|
+
- formatting per cell or per row:
|
|
103
|
+
- bold format
|
|
104
|
+
- italics format
|
|
105
|
+
- highlight colour
|
|
106
|
+
- reading and writing cells with data types:
|
|
107
|
+
- str
|
|
108
|
+
- bool
|
|
109
|
+
- int
|
|
110
|
+
- float
|
|
111
|
+
- datetime
|
|
112
|
+
- writing a table as a filtered data range
|
|
113
|
+
- writing a table to a specific location in a spreadsheet (specified by a box)
|
|
114
|
+
- reading table data from a specific location in a spreadsheet (specified by a box)
|
|
115
|
+
- using multiple sheets in spreadsheets
|
|
116
|
+
- finding location where some data is present in spreadsheet and doing modifications
|
|
117
|
+
at that position or at positions relative to that position.
|
|
118
|
+
|
|
79
119
|
## Example programs
|
|
80
120
|
|
|
81
|
-
|
|
121
|
+
The best way to learn to use this package is to use the provided
|
|
122
|
+
example programs:
|
|
123
|
+
[https://bitbucket.org/tom-bjorkholm/table-io/src/master/example/src/example/README.md](https://bitbucket.org/tom-bjorkholm/table-io/src/master/example/src/example/README.md).
|
|
82
124
|
|
|
83
125
|
## API documentation
|
|
84
126
|
|
|
85
|
-
Be aware that this is still in early development. The APIs may change between versions.
|
|
86
|
-
|
|
87
127
|
You can find the public API documentation at [https://bitbucket.org/tom-bjorkholm/table-io/src/master/doc/api.md](https://bitbucket.org/tom-bjorkholm/table-io/src/master/doc/api.md)
|
|
88
128
|
|
|
89
129
|
You can find the protected API documentation at [https://bitbucket.org/tom-bjorkholm/table-io/src/master/doc/protected_api.md](https://bitbucket.org/tom-bjorkholm/table-io/src/master/doc/protected_api.md)
|
|
@@ -96,14 +136,16 @@ a better start by reading the examples.
|
|
|
96
136
|
|
|
97
137
|
## Version history
|
|
98
138
|
|
|
99
|
-
| Version | Date | Python version | Comment
|
|
100
|
-
|
|
101
|
-
| 0.
|
|
139
|
+
| Version | Date | Python version | Comment |
|
|
140
|
+
|---------|-------------|----------------|-----------------------------|
|
|
141
|
+
| 0.3 | 2023 Apr 01 | 3.12 or newer | Improved API, more backends |
|
|
142
|
+
| 0.2 | 2026 Mar 28 | 3.12 or newer | More features, API changes |
|
|
143
|
+
| 0.1 | 2026 Mar 23 | 3.12 or newer | First released version |
|
|
102
144
|
|
|
103
145
|
## Test summary
|
|
104
146
|
|
|
105
|
-
- Test result:
|
|
106
|
-
- No
|
|
147
|
+
- Test result: 1010 passed in 14s
|
|
148
|
+
- No flake8 warnings.
|
|
107
149
|
- No mypy errors found.
|
|
108
|
-
- Built version(s): 0.
|
|
150
|
+
- Built version(s): 0.3
|
|
109
151
|
- Build and test using Python 3.14.3
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
# tableio
|
|
2
2
|
|
|
3
|
-
## Early protoype
|
|
4
|
-
|
|
5
|
-
This package is still an early prototype. This means that major changes to the APIs are expected.
|
|
6
|
-
|
|
7
|
-
## Use
|
|
8
|
-
|
|
9
3
|
> **👤 Looking to use this in your program**
|
|
10
|
-
> This repository is for developers of the package. If you want to install
|
|
4
|
+
> This repository is for developers of the package. If you want to install
|
|
5
|
+
> and use `tableio` including writing programs that use them, please visit
|
|
6
|
+
> the **PyPI project page [https://pypi.org/project/tableio](https://pypi.org/project/tableio)
|
|
7
|
+
> for installation instructions and user documentation.
|
|
11
8
|
|
|
12
9
|
## What is it
|
|
13
10
|
|
|
@@ -52,22 +49,20 @@ git submodule update --remote --merge
|
|
|
52
49
|
|
|
53
50
|
#### OS
|
|
54
51
|
|
|
55
|
-
For running the script and running the test suite you need a mac or a Linux computer.
|
|
52
|
+
For running the script and running the test suite you need a mac or a Linux computer.
|
|
53
|
+
Even if the resulting package can be installed and used on Windows, the scripts for
|
|
54
|
+
building and testing are only implemented for mac and Linux.
|
|
56
55
|
|
|
57
56
|
#### Python version
|
|
58
57
|
|
|
59
|
-
Please see README_pypi.md for information on needed python version.
|
|
60
|
-
|
|
61
|
-
#### Zsh
|
|
62
|
-
|
|
63
|
-
Most scripts are Python.
|
|
64
|
-
Some scripts are zsh. zsh is available by default on modern macs. zsh can easily be installed on Linux (on Ubuntu: `sudo apt install zsh`).
|
|
58
|
+
Please see README_pypi.md for information on needed python version.
|
|
59
|
+
Main development is on newest Python version.
|
|
65
60
|
|
|
66
61
|
### Quick start
|
|
67
62
|
|
|
68
63
|
1. Clone this repository
|
|
69
|
-
2. Run `./
|
|
70
|
-
3. Run `./
|
|
64
|
+
2. Run `./run_setup_build_environment.py` to set up the build environment
|
|
65
|
+
3. Run `./run_build.py` to build and test the package
|
|
71
66
|
|
|
72
67
|
### Building application
|
|
73
68
|
|
|
@@ -98,8 +93,8 @@ information about the build system. This README can also be viewed at
|
|
|
98
93
|
|
|
99
94
|
## Test summary
|
|
100
95
|
|
|
101
|
-
- Test result:
|
|
102
|
-
- No
|
|
96
|
+
- Test result: 1010 passed in 14s
|
|
97
|
+
- No flake8 warnings.
|
|
103
98
|
- No mypy errors found.
|
|
104
|
-
- Built version(s): 0.
|
|
99
|
+
- Built version(s): 0.3
|
|
105
100
|
- Build and test using Python 3.14.3
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# tableio
|
|
2
|
+
|
|
3
|
+
The tableio package contains a number of classes providing a uniform way for
|
|
4
|
+
a python program to write table data (rows of columns) to and read table data
|
|
5
|
+
from a number of different common file formats.
|
|
6
|
+
|
|
7
|
+
An increasing number of users want output from programs to be in a format
|
|
8
|
+
like a spreadsheet, and not the old fashoned raw text files. Similarly,
|
|
9
|
+
many users want the data they feed into programs to be in a particular format
|
|
10
|
+
(like a spreadsheet). The tableio package tries to make it easier for the
|
|
11
|
+
programmer to fullfil requests like that.
|
|
12
|
+
|
|
13
|
+
The primary intended use is for data table output from a python program
|
|
14
|
+
and data table input to a python program, where the programmer would like
|
|
15
|
+
the user to be able to select the input and output file formats.
|
|
16
|
+
|
|
17
|
+
The support for spreadsheets is for reading and writing data. There is no
|
|
18
|
+
intention to support reading or writing formulas. There is no support for
|
|
19
|
+
running calculations in the spreadsheets (although nothing will stop a
|
|
20
|
+
receiver of a spreadsheet created by tableio package to manually add
|
|
21
|
+
formulas in the received spreadsheet).
|
|
22
|
+
|
|
23
|
+
## Installing tableio
|
|
24
|
+
|
|
25
|
+
### Installing tableio on mac and Linux
|
|
26
|
+
|
|
27
|
+
````sh
|
|
28
|
+
pip3 install --upgrade tableio
|
|
29
|
+
````
|
|
30
|
+
|
|
31
|
+
### Installing tableio on Microsoft Windows
|
|
32
|
+
|
|
33
|
+
````sh
|
|
34
|
+
pip install --upgrade tableio
|
|
35
|
+
````
|
|
36
|
+
|
|
37
|
+
## Supported formats
|
|
38
|
+
|
|
39
|
+
The currently supported formats are:
|
|
40
|
+
|
|
41
|
+
| File format | Implementation | Can write | Can read |
|
|
42
|
+
|-------------|----------------|-----------|----------|
|
|
43
|
+
| CSV | csv | yes | yes |
|
|
44
|
+
| Excel | OpenPyXL | yes | yes |
|
|
45
|
+
| Excel | XlsxWriter | yes | - |
|
|
46
|
+
| Excel | pylightxl | yes | yes |
|
|
47
|
+
| ODS | odfdo | yes | yes |
|
|
48
|
+
| HTML | mformat | yes | - |
|
|
49
|
+
| LaTeX | mformat | yes | - |
|
|
50
|
+
| docx | mformat | yes | - |
|
|
51
|
+
| md | mformat | yes | - |
|
|
52
|
+
| odt | mformat | yes | - |
|
|
53
|
+
| pdf | mformat | yes | - |
|
|
54
|
+
| reST | mformat | yes | - |
|
|
55
|
+
| rtf | mformat | yes | - |
|
|
56
|
+
| txt | mformat | yes | - |
|
|
57
|
+
|
|
58
|
+
## Features
|
|
59
|
+
|
|
60
|
+
All features are not available for all file formats. Often the file
|
|
61
|
+
format restricts what features are reasonable in that format. Using
|
|
62
|
+
a selection mechanism called Capabilities it is possible to select
|
|
63
|
+
file format at runtime based on what features are essential. It is
|
|
64
|
+
also possible to ignore some features when using a file format that
|
|
65
|
+
cannot support that feature (like ignoring bold fomatting in CSV).
|
|
66
|
+
|
|
67
|
+
The main features are:
|
|
68
|
+
|
|
69
|
+
- File open modes: Create, Read or Update
|
|
70
|
+
- Writing tables from list of lists or list of dicts
|
|
71
|
+
- Writing headings before and between tables
|
|
72
|
+
- Reading tables to list of lists or list of dicts, including the headings
|
|
73
|
+
before the table.
|
|
74
|
+
- formatting per cell or per row:
|
|
75
|
+
- bold format
|
|
76
|
+
- italics format
|
|
77
|
+
- highlight colour
|
|
78
|
+
- reading and writing cells with data types:
|
|
79
|
+
- str
|
|
80
|
+
- bool
|
|
81
|
+
- int
|
|
82
|
+
- float
|
|
83
|
+
- datetime
|
|
84
|
+
- writing a table as a filtered data range
|
|
85
|
+
- writing a table to a specific location in a spreadsheet (specified by a box)
|
|
86
|
+
- reading table data from a specific location in a spreadsheet (specified by a box)
|
|
87
|
+
- using multiple sheets in spreadsheets
|
|
88
|
+
- finding location where some data is present in spreadsheet and doing modifications
|
|
89
|
+
at that position or at positions relative to that position.
|
|
90
|
+
|
|
91
|
+
## Example programs
|
|
92
|
+
|
|
93
|
+
The best way to learn to use this package is to use the provided
|
|
94
|
+
example programs:
|
|
95
|
+
[https://bitbucket.org/tom-bjorkholm/table-io/src/master/example/src/example/README.md](https://bitbucket.org/tom-bjorkholm/table-io/src/master/example/src/example/README.md).
|
|
96
|
+
|
|
97
|
+
## API documentation
|
|
98
|
+
|
|
99
|
+
You can find the public API documentation at [https://bitbucket.org/tom-bjorkholm/table-io/src/master/doc/api.md](https://bitbucket.org/tom-bjorkholm/table-io/src/master/doc/api.md)
|
|
100
|
+
|
|
101
|
+
You can find the protected API documentation at [https://bitbucket.org/tom-bjorkholm/table-io/src/master/doc/protected_api.md](https://bitbucket.org/tom-bjorkholm/table-io/src/master/doc/protected_api.md)
|
|
102
|
+
The protected API documentation is only for developers that want to
|
|
103
|
+
extend the framework with by adding their own classes as registered
|
|
104
|
+
readers/writers to the factory.
|
|
105
|
+
|
|
106
|
+
Even though the API documentation exists, most users and programmers probably get
|
|
107
|
+
a better start by reading the examples.
|
|
108
|
+
|
|
109
|
+
## Version history
|
|
110
|
+
|
|
111
|
+
| Version | Date | Python version | Comment |
|
|
112
|
+
|---------|-------------|----------------|-----------------------------|
|
|
113
|
+
| 0.3 | 2023 Apr 01 | 3.12 or newer | Improved API, more backends |
|
|
114
|
+
| 0.2 | 2026 Mar 28 | 3.12 or newer | More features, API changes |
|
|
115
|
+
| 0.1 | 2026 Mar 23 | 3.12 or newer | First released version |
|
|
116
|
+
|
|
117
|
+
## Test summary
|
|
118
|
+
|
|
119
|
+
- Test result: 1010 passed in 14s
|
|
120
|
+
- No flake8 warnings.
|
|
121
|
+
- No mypy errors found.
|
|
122
|
+
- Built version(s): 0.3
|
|
123
|
+
- Build and test using Python 3.14.3
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tableio"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Tom Björkholm", email="klausuler_linnet0q@icloud.com" },
|
|
10
10
|
]
|
|
@@ -15,8 +15,7 @@ license = "MIT"
|
|
|
15
15
|
license-files = ["LICENSE.txt"]
|
|
16
16
|
classifiers = [
|
|
17
17
|
"Programming Language :: Python :: 3",
|
|
18
|
-
"Operating System :: OS Independent"
|
|
19
|
-
"Development Status :: 2 - Pre-Alpha"
|
|
18
|
+
"Operating System :: OS Independent"
|
|
20
19
|
]
|
|
21
20
|
dynamic = ["dependencies"]
|
|
22
21
|
|
|
@@ -5,7 +5,7 @@ from setuptools import setup
|
|
|
5
5
|
|
|
6
6
|
setup(
|
|
7
7
|
name='tableio',
|
|
8
|
-
version='0.
|
|
8
|
+
version='0.3',
|
|
9
9
|
description='Uniform way to write table data to and read from different ' \
|
|
10
10
|
'file formats',
|
|
11
11
|
author='Tom Björkholm',
|
|
@@ -17,10 +17,13 @@ setup(
|
|
|
17
17
|
install_requires=[ # pylint: disable=duplicate-code
|
|
18
18
|
'pip >= 26.0.1',
|
|
19
19
|
'setuptools >= 82.0.1',
|
|
20
|
-
'build >= 1.4.
|
|
20
|
+
'build >= 1.4.2',
|
|
21
21
|
'wheel >= 0.46.3',
|
|
22
22
|
'mformat-ext >= 0.6',
|
|
23
23
|
'openpyxl >= 3.1.5',
|
|
24
|
-
'types-openpyxl >= 3.1.5.20260322'
|
|
24
|
+
'types-openpyxl >= 3.1.5.20260322',
|
|
25
|
+
'odfdo >= 3.22.3',
|
|
26
|
+
'xlsxwriter >= 3.2.9',
|
|
27
|
+
'pylightxl >= 1.61'
|
|
25
28
|
]
|
|
26
29
|
)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#! /usr/local/bin/python3
|
|
2
|
+
"""Curated top-level public API for the tableio package."""
|
|
3
|
+
|
|
4
|
+
# Copyright (c) 2026 Tom Björkholm
|
|
5
|
+
# MIT License
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
from tableio.capability import CAP_IGNORABLE, CAP_NEEDED, CAP_NOT_USED, \
|
|
9
|
+
Capabilities
|
|
10
|
+
from tableio.color import Color
|
|
11
|
+
from tableio.factory import create_tableio, filter_args_tableio, \
|
|
12
|
+
list_implementations_tableio, list_registered_tableio
|
|
13
|
+
from tableio.optional_args import CsvDialect, OptionalArgs, OptionalArgsDict
|
|
14
|
+
from tableio.tableio import Box, FileAccess, Position, TableIO
|
|
15
|
+
from tableio.value_type import CellT, DictData, DictDataMap, Fmt, \
|
|
16
|
+
FmtDictData, FmtDictRow, FmtListData, FmtListRow, ListData, \
|
|
17
|
+
ListDataSeq, ReadResult, Value, ValueFmt
|
|
18
|
+
|
|
19
|
+
__all__ = ['create_tableio',
|
|
20
|
+
'TableIO',
|
|
21
|
+
'FileAccess',
|
|
22
|
+
'Box',
|
|
23
|
+
'Position',
|
|
24
|
+
'OptionalArgs',
|
|
25
|
+
'OptionalArgsDict',
|
|
26
|
+
'Value',
|
|
27
|
+
'ListData',
|
|
28
|
+
'ListDataSeq',
|
|
29
|
+
'DictData',
|
|
30
|
+
'DictDataMap',
|
|
31
|
+
'ReadResult',
|
|
32
|
+
'Fmt',
|
|
33
|
+
'ValueFmt',
|
|
34
|
+
'FmtListRow',
|
|
35
|
+
'FmtDictRow',
|
|
36
|
+
'FmtListData',
|
|
37
|
+
'FmtDictData',
|
|
38
|
+
'CellT',
|
|
39
|
+
'Color',
|
|
40
|
+
'Capabilities',
|
|
41
|
+
'CAP_NEEDED',
|
|
42
|
+
'CAP_NOT_USED',
|
|
43
|
+
'CAP_IGNORABLE',
|
|
44
|
+
'filter_args_tableio',
|
|
45
|
+
'list_registered_tableio',
|
|
46
|
+
'list_implementations_tableio',
|
|
47
|
+
'CsvDialect']
|
|
@@ -84,6 +84,12 @@ class Capabilities(NamedTuple):
|
|
|
84
84
|
can_write_highlight: SingleCapability = SingleCapability()
|
|
85
85
|
"""The writer class can write highlight according to format."""
|
|
86
86
|
|
|
87
|
+
multi_sheet: SingleCapability = SingleCapability()
|
|
88
|
+
"""The reader/writer class can read from or write to multiple sheets."""
|
|
89
|
+
|
|
90
|
+
can_find_value_position: SingleCapability = SingleCapability()
|
|
91
|
+
"""The reader/writer class can find the position of a value."""
|
|
92
|
+
|
|
87
93
|
|
|
88
94
|
def single_capability_match(offered: SingleCapability,
|
|
89
95
|
will_use: SingleCapability,
|
|
@@ -98,7 +104,7 @@ def single_capability_match(offered: SingleCapability,
|
|
|
98
104
|
ignore_allowed: If False: when the offered single capability would
|
|
99
105
|
ignore the will use single capability it is
|
|
100
106
|
considered a mismatch, and will return False.
|
|
101
|
-
If
|
|
107
|
+
If True: when the offered single capability would
|
|
102
108
|
ignore the will use single capability it is
|
|
103
109
|
considered a match, and will return True.
|
|
104
110
|
Returns:
|
|
@@ -154,3 +160,90 @@ class CapabilityNotSupported(ValueError):
|
|
|
154
160
|
"""
|
|
155
161
|
self.action = action
|
|
156
162
|
super().__init__(f'The class does not support {action}.')
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def capability_to_str(capability: SingleCapability) -> str:
|
|
166
|
+
"""Convert a single capability to a string.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
capability: The single capability to convert.
|
|
170
|
+
Returns:
|
|
171
|
+
A string representation of the single capability.
|
|
172
|
+
"""
|
|
173
|
+
result = ''
|
|
174
|
+
if capability.supported:
|
|
175
|
+
result += 'supported'
|
|
176
|
+
else:
|
|
177
|
+
result += 'not supported'
|
|
178
|
+
if capability.strictness == Strictness.STRICT:
|
|
179
|
+
result += ' (strict)'
|
|
180
|
+
else:
|
|
181
|
+
result += ' (ignore)'
|
|
182
|
+
return result
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
# ----------------------------------------------------------------------------
|
|
186
|
+
# Capability constants from the point of view of the requester
|
|
187
|
+
# ----------------------------------------------------------------------------
|
|
188
|
+
|
|
189
|
+
CAP_NOT_USED = SingleCapability(supported=False, strictness=Strictness.IGNORE)
|
|
190
|
+
"""A capability that is not used.
|
|
191
|
+
|
|
192
|
+
The requester promises to not use this capability, so it does not
|
|
193
|
+
matter if the implementation supports it or not.
|
|
194
|
+
"""
|
|
195
|
+
|
|
196
|
+
CAP_NEEDED = SingleCapability(supported=True, strictness=Strictness.STRICT)
|
|
197
|
+
"""A capability that is used and must be supported.
|
|
198
|
+
|
|
199
|
+
In the selection of reader/writer class it is a must that the selected
|
|
200
|
+
class supports this capability. If no matching reader/writer class is
|
|
201
|
+
found to fulfill the request, an exception is raised.
|
|
202
|
+
"""
|
|
203
|
+
|
|
204
|
+
CAP_IGNORABLE = SingleCapability(supported=True, strictness=Strictness.IGNORE)
|
|
205
|
+
"""A capability that can be ignored if not supported.
|
|
206
|
+
|
|
207
|
+
An example might be that prefer to be able to write a value in bold,
|
|
208
|
+
but the request can accept that the implementation ignores the bold
|
|
209
|
+
formatting.
|
|
210
|
+
"""
|
|
211
|
+
|
|
212
|
+
# ----------------------------------------------------------------------------
|
|
213
|
+
# Capability constants from the point of view of the reader/writer class
|
|
214
|
+
# ----------------------------------------------------------------------------
|
|
215
|
+
|
|
216
|
+
CAP_IMPLEMENTED = SingleCapability(supported=True,
|
|
217
|
+
strictness=Strictness.STRICT)
|
|
218
|
+
"""A capability that is fully implemented and supported."""
|
|
219
|
+
|
|
220
|
+
CAP_IGNORED = SingleCapability(supported=False, strictness=Strictness.IGNORE)
|
|
221
|
+
"""A capability that is not supported and will be ignored if requested.
|
|
222
|
+
|
|
223
|
+
The implementation cannot fulfill the request, but it makes sense to
|
|
224
|
+
ignore this feature and continue anyway. A typical example would be
|
|
225
|
+
a request to format a written value in bold. Here ignoring the bold
|
|
226
|
+
formatting makes sense as there is still a value written to the file.
|
|
227
|
+
"""
|
|
228
|
+
|
|
229
|
+
CAP_UNSUPPORTED = SingleCapability(supported=False,
|
|
230
|
+
strictness=Strictness.STRICT)
|
|
231
|
+
"""A capability that is not supported and will raise an exception if requested.
|
|
232
|
+
|
|
233
|
+
This is a for a feature that cannot be supported but it would not make
|
|
234
|
+
sense to ignore. A typical example would be a request to write
|
|
235
|
+
a value in a specific location in the file. Writing the value to a
|
|
236
|
+
different location would not make sense. Thus the only sensible thing
|
|
237
|
+
to do is to raise an exception.
|
|
238
|
+
"""
|
|
239
|
+
|
|
240
|
+
CAP_ALL_IMPLEMENTED = Capabilities(can_read=CAP_IMPLEMENTED,
|
|
241
|
+
can_write=CAP_IMPLEMENTED,
|
|
242
|
+
can_fmt_row=CAP_IMPLEMENTED,
|
|
243
|
+
can_fmt_value=CAP_IMPLEMENTED,
|
|
244
|
+
filtered_data_range=CAP_IMPLEMENTED,
|
|
245
|
+
can_write_box=CAP_IMPLEMENTED,
|
|
246
|
+
can_read_box=CAP_IMPLEMENTED,
|
|
247
|
+
can_write_highlight=CAP_IMPLEMENTED,
|
|
248
|
+
multi_sheet=CAP_IMPLEMENTED,
|
|
249
|
+
can_find_value_position=CAP_IMPLEMENTED)
|
|
@@ -51,6 +51,37 @@ class TableIOFactoryNoCapabilityMatch(ValueError):
|
|
|
51
51
|
"""
|
|
52
52
|
|
|
53
53
|
|
|
54
|
+
class InsufficientCapabilities(ValueError):
|
|
55
|
+
"""Raised when requested capabilities contradict requested file access.
|
|
56
|
+
|
|
57
|
+
Error raised when the caller supplies both file access and an explicit
|
|
58
|
+
Capabilities object, but the requested capabilities do not include the
|
|
59
|
+
capability implied by that access mode. For example, READ requires
|
|
60
|
+
can_read, CREATE requires can_write, and UPDATE requires both.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _check_capabilities_for_file_access(
|
|
65
|
+
file_access: FileAccess,
|
|
66
|
+
capabilities: Optional[Capabilities]) -> None:
|
|
67
|
+
"""Raise if explicit capabilities not enough for requested access mode."""
|
|
68
|
+
if capabilities is None:
|
|
69
|
+
return
|
|
70
|
+
if file_access == FileAccess.READ and not capabilities.can_read.supported:
|
|
71
|
+
msg = 'FileAccess.READ requires can_read capability.'
|
|
72
|
+
raise InsufficientCapabilities(msg)
|
|
73
|
+
if file_access == FileAccess.CREATE and \
|
|
74
|
+
not capabilities.can_write.supported:
|
|
75
|
+
msg = 'FileAccess.CREATE requires can_write capability.'
|
|
76
|
+
raise InsufficientCapabilities(msg)
|
|
77
|
+
if file_access == FileAccess.UPDATE and (
|
|
78
|
+
not capabilities.can_write.supported or
|
|
79
|
+
not capabilities.can_read.supported):
|
|
80
|
+
msg = 'FileAccess.UPDATE requires both can_read and '
|
|
81
|
+
msg += 'can_write capabilities.'
|
|
82
|
+
raise InsufficientCapabilities(msg)
|
|
83
|
+
|
|
84
|
+
|
|
54
85
|
@total_ordering
|
|
55
86
|
class ImplPrio(NamedTuple):
|
|
56
87
|
"""Priority of an implementation."""
|
|
@@ -339,6 +370,7 @@ class TableIOFactory:
|
|
|
339
370
|
An instance of the requested TableIO subclass.
|
|
340
371
|
Intended to be used as context manager, using a with statement.
|
|
341
372
|
Raises:
|
|
373
|
+
InsufficientCapabilities: If capabilities contradict file_access.
|
|
342
374
|
TableIOFactoryNoSuchError: If the format_name is not registered
|
|
343
375
|
or the implementation name is not
|
|
344
376
|
registered.
|
|
@@ -357,7 +389,17 @@ class TableIOFactory:
|
|
|
357
389
|
file_access: FileAccess, args: OptionalArgs = None,
|
|
358
390
|
implementation: Optional[str] = None,
|
|
359
391
|
capabilities: Optional[Capabilities] = None) -> TableIO:
|
|
360
|
-
"""Internally create an instance of a registered subclass.
|
|
392
|
+
"""Internally create an instance of a registered subclass.
|
|
393
|
+
|
|
394
|
+
Raises:
|
|
395
|
+
InsufficientCapabilities: If capabilities contradict file_access.
|
|
396
|
+
TableIOFactoryNoSuchError: If the format_name is not registered
|
|
397
|
+
or the implementation name is not
|
|
398
|
+
registered.
|
|
399
|
+
TableIOFactoryNoCapabilityMatch: If the capabilities cannot be
|
|
400
|
+
matched to any implementation.
|
|
401
|
+
"""
|
|
402
|
+
_check_capabilities_for_file_access(file_access, capabilities)
|
|
361
403
|
correct_name: Optional[str] = None
|
|
362
404
|
if format_name in self._formats:
|
|
363
405
|
correct_name = format_name
|
|
@@ -371,8 +413,8 @@ class TableIOFactory:
|
|
|
371
413
|
)
|
|
372
414
|
assert correct_name is not None
|
|
373
415
|
format_info: FactoryFormatInfo = self._formats[correct_name]
|
|
374
|
-
best_matches = format_info.best_match_names(
|
|
375
|
-
|
|
416
|
+
best_matches = format_info.best_match_names(
|
|
417
|
+
capabilities=capabilities, empty_is_ok=False)
|
|
376
418
|
if implementation is not None:
|
|
377
419
|
fikeys = list(format_info._registry.keys()) # pylint: disable=protected-access # noqa: E501
|
|
378
420
|
if implementation not in fikeys:
|
|
@@ -666,6 +708,7 @@ def create_tableio(format_name: str, # pylint: disable=too-many-arguments, too-
|
|
|
666
708
|
Returns:
|
|
667
709
|
An instance of the requested TableIO subclass.
|
|
668
710
|
Raises:
|
|
711
|
+
InsufficientCapabilities: If capabilities contradict file_access.
|
|
669
712
|
TableIOFactoryNoSuchError: If the format_name or implementation
|
|
670
713
|
name is not registered.
|
|
671
714
|
TableIOFactoryNoCapabilityMatch: If the capabilities cannot be
|
|
@@ -16,6 +16,9 @@ from tableio.tableio_mformat import TableIOMformatHtml, TableIOMformatMd, \
|
|
|
16
16
|
TableIOMformatRtf
|
|
17
17
|
from tableio.tableio_csv import TableIOCsv
|
|
18
18
|
from tableio.tableio_excel_openpyxl import TableIOExcelOpenPyXL
|
|
19
|
+
from tableio.tableio_excel_pylightxl import TableIOExcelPylightxl
|
|
20
|
+
from tableio.tableio_excel_xlsxwriter import TableIOExcelXlsxWriter
|
|
21
|
+
from tableio.tableio_ods_odfdo import TableIOOdsOdfdo
|
|
19
22
|
from tableio.tableio import TableIO
|
|
20
23
|
|
|
21
24
|
|
|
@@ -26,5 +29,8 @@ def register_formats_in_pkg() -> list[type[TableIO]]:
|
|
|
26
29
|
TableIOMformatLatex, TableIOMformatDocx,
|
|
27
30
|
TableIOMformatOdt, TableIOMformatPdf,
|
|
28
31
|
TableIOMformatRtf, TableIOCsv,
|
|
29
|
-
TableIOExcelOpenPyXL
|
|
32
|
+
TableIOExcelOpenPyXL,
|
|
33
|
+
TableIOExcelPylightxl,
|
|
34
|
+
TableIOExcelXlsxWriter,
|
|
35
|
+
TableIOOdsOdfdo]
|
|
30
36
|
return ret
|