xlwings-utils 25.0.8__tar.gz → 25.0.10__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.
Potentially problematic release.
This version of xlwings-utils might be problematic. Click here for more details.
- {xlwings_utils-25.0.8 → xlwings_utils-25.0.10}/PKG-INFO +3 -1
- {xlwings_utils-25.0.8 → xlwings_utils-25.0.10}/README.md +2 -0
- {xlwings_utils-25.0.8 → xlwings_utils-25.0.10}/pyproject.toml +1 -1
- {xlwings_utils-25.0.8 → xlwings_utils-25.0.10}/tests/test_xlwings_utils.py +83 -45
- {xlwings_utils-25.0.8 → xlwings_utils-25.0.10}/xlwings_utils/xlwings_utils.py +24 -38
- {xlwings_utils-25.0.8 → xlwings_utils-25.0.10}/xlwings_utils.egg-info/PKG-INFO +3 -1
- {xlwings_utils-25.0.8 → xlwings_utils-25.0.10}/setup.cfg +0 -0
- {xlwings_utils-25.0.8 → xlwings_utils-25.0.10}/xlwings_utils/__init__.py +0 -0
- {xlwings_utils-25.0.8 → xlwings_utils-25.0.10}/xlwings_utils.egg-info/SOURCES.txt +0 -0
- {xlwings_utils-25.0.8 → xlwings_utils-25.0.10}/xlwings_utils.egg-info/dependency_links.txt +0 -0
- {xlwings_utils-25.0.8 → xlwings_utils-25.0.10}/xlwings_utils.egg-info/requires.txt +0 -0
- {xlwings_utils-25.0.8 → xlwings_utils-25.0.10}/xlwings_utils.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xlwings_utils
|
|
3
|
-
Version: 25.0.
|
|
3
|
+
Version: 25.0.10
|
|
4
4
|
Summary: xlwings_utils
|
|
5
5
|
Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/salabim/xlwings_utils
|
|
@@ -61,6 +61,8 @@ In order to make a Dropbox app, and get the required environment variables, just
|
|
|
61
61
|
python -c "exec(__import__('requests').get('https://salabim.org/dropbox setup.py').text)"
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
The file `dropbox setup.py` can also be found in the repo of xlwings_lite .
|
|
65
|
+
|
|
64
66
|
Then, it is possible to list all files in a specified folder using the list_dropbox function.
|
|
65
67
|
It is also possible to get at all folders and to access all underlying folders.
|
|
66
68
|
|
|
@@ -48,6 +48,8 @@ In order to make a Dropbox app, and get the required environment variables, just
|
|
|
48
48
|
python -c "exec(__import__('requests').get('https://salabim.org/dropbox setup.py').text)"
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
The file `dropbox setup.py` can also be found in the repo of xlwings_lite .
|
|
52
|
+
|
|
51
53
|
Then, it is possible to list all files in a specified folder using the list_dropbox function.
|
|
52
54
|
It is also possible to get at all folders and to access all underlying folders.
|
|
53
55
|
|
|
@@ -67,6 +67,39 @@ def test_block2():
|
|
|
67
67
|
assert this_block.value == [[1, 2, 3, None], [4, 5, 6, None], [None, None, None, None]]
|
|
68
68
|
|
|
69
69
|
|
|
70
|
+
def test_highest_used():
|
|
71
|
+
this_block = xwu.block(number_of_rows=4, number_of_columns=4)
|
|
72
|
+
assert this_block._highest_used_row_number is None
|
|
73
|
+
assert this_block.highest_used_row_number == 1
|
|
74
|
+
assert this_block.highest_used_column_number == 1
|
|
75
|
+
this_block[2, 3] = 1
|
|
76
|
+
assert this_block._highest_used_row_number is not None
|
|
77
|
+
assert this_block.highest_used_row_number == 2
|
|
78
|
+
assert this_block.highest_used_column_number == 3
|
|
79
|
+
this_block[1, 2] = 1
|
|
80
|
+
assert this_block._highest_used_row_number is not None
|
|
81
|
+
assert this_block.highest_used_row_number == 2
|
|
82
|
+
assert this_block.highest_used_column_number == 3
|
|
83
|
+
this_block[3, 4] = 1
|
|
84
|
+
assert this_block._highest_used_row_number is not None
|
|
85
|
+
assert this_block.highest_used_row_number == 3
|
|
86
|
+
assert this_block.highest_used_column_number == 4
|
|
87
|
+
this_block[3, 4] = None
|
|
88
|
+
assert this_block._highest_used_row_number is None
|
|
89
|
+
assert this_block.highest_used_row_number == 2
|
|
90
|
+
assert this_block.highest_used_column_number == 3
|
|
91
|
+
this_block[2, 3] = None
|
|
92
|
+
assert this_block._highest_used_row_number is None
|
|
93
|
+
this_block[2, 3] = 1
|
|
94
|
+
assert this_block._highest_used_row_number is None
|
|
95
|
+
this_block[2, 3] = None
|
|
96
|
+
this_block[1, 2] = None
|
|
97
|
+
assert this_block._highest_used_row_number is None
|
|
98
|
+
assert this_block.highest_used_row_number == 1
|
|
99
|
+
assert this_block.highest_used_column_number == 1
|
|
100
|
+
assert this_block._highest_used_row_number is not None
|
|
101
|
+
|
|
102
|
+
|
|
70
103
|
def test_block_one_dimension():
|
|
71
104
|
this_block = xwu.block.from_value([1, 2, 3])
|
|
72
105
|
assert this_block.value == [[1, 2, 3]]
|
|
@@ -79,20 +112,23 @@ def test_block_scalar():
|
|
|
79
112
|
this_block = xwu.block.from_value(1)
|
|
80
113
|
assert this_block.value == [[1]]
|
|
81
114
|
|
|
115
|
+
|
|
82
116
|
def test_transpose():
|
|
83
117
|
this_block = xwu.block.from_value([[1, 2, 3], [4, 5, 6]])
|
|
84
|
-
transposed_block=this_block.transposed()
|
|
85
|
-
assert transposed_block.value==[[1,4],[2,5],[3,6]]
|
|
118
|
+
transposed_block = this_block.transposed()
|
|
119
|
+
assert transposed_block.value == [[1, 4], [2, 5], [3, 6]]
|
|
120
|
+
|
|
86
121
|
|
|
87
122
|
def test_delete_none():
|
|
88
123
|
this_block = xwu.block.from_value([[1, 2, None], [4, 5, None]])
|
|
89
|
-
assert len(this_block.dict)==4
|
|
90
|
-
this_block[1,1]=None
|
|
91
|
-
assert len(this_block.dict)==3
|
|
92
|
-
this_block[1,1]=None
|
|
93
|
-
assert len(this_block.dict)==3
|
|
94
|
-
assert this_block.value==[[None, 2, None], [4, 5, None]]
|
|
95
|
-
|
|
124
|
+
assert len(this_block.dict) == 4
|
|
125
|
+
this_block[1, 1] = None
|
|
126
|
+
assert len(this_block.dict) == 3
|
|
127
|
+
this_block[1, 1] = None
|
|
128
|
+
assert len(this_block.dict) == 3
|
|
129
|
+
assert this_block.value == [[None, 2, None], [4, 5, None]]
|
|
130
|
+
|
|
131
|
+
|
|
96
132
|
def test_raise():
|
|
97
133
|
this_block = xwu.block(number_of_rows=4, number_of_columns=6)
|
|
98
134
|
with pytest.raises(IndexError):
|
|
@@ -115,52 +151,55 @@ def test_raise():
|
|
|
115
151
|
with pytest.raises(IndexError):
|
|
116
152
|
this_block[1, 7] = 1
|
|
117
153
|
|
|
154
|
+
|
|
118
155
|
def test_lookup():
|
|
119
|
-
bl=xwu.block.from_value([[1,"One", "Un"],[2, "Two", "Deux"],[3,"Three","Trois"]])
|
|
120
|
-
assert bl.lookup(1)=="One"
|
|
121
|
-
assert bl.lookup(3, column2=3)=="Trois"
|
|
156
|
+
bl = xwu.block.from_value([[1, "One", "Un"], [2, "Two", "Deux"], [3, "Three", "Trois"]])
|
|
157
|
+
assert bl.lookup(1) == "One"
|
|
158
|
+
assert bl.lookup(3, column2=3) == "Trois"
|
|
122
159
|
with pytest.raises(ValueError):
|
|
123
160
|
bl.lookup(4)
|
|
124
|
-
assert bl.lookup(4,default=
|
|
161
|
+
assert bl.lookup(4, default="x") == "x"
|
|
125
162
|
with pytest.raises(ValueError):
|
|
126
163
|
bl.lookup(1, column1=4)
|
|
127
164
|
with pytest.raises(ValueError):
|
|
128
165
|
bl.lookup(1, column1=3)
|
|
129
|
-
assert bl.lookup_row(1)==1
|
|
130
|
-
assert bl.lookup_row(3)==3
|
|
166
|
+
assert bl.lookup_row(1) == 1
|
|
167
|
+
assert bl.lookup_row(3) == 3
|
|
168
|
+
|
|
131
169
|
|
|
132
170
|
def test_vookup():
|
|
133
|
-
bl=xwu.block.from_value([[1,"One", "Un"],[2, "Two", "Deux"],[3,"Three","Trois"]])
|
|
134
|
-
assert bl.vlookup(1)=="One"
|
|
135
|
-
assert bl.vlookup(3, column2=3)=="Trois"
|
|
171
|
+
bl = xwu.block.from_value([[1, "One", "Un"], [2, "Two", "Deux"], [3, "Three", "Trois"]])
|
|
172
|
+
assert bl.vlookup(1) == "One"
|
|
173
|
+
assert bl.vlookup(3, column2=3) == "Trois"
|
|
136
174
|
with pytest.raises(ValueError):
|
|
137
175
|
bl.vlookup(4)
|
|
138
|
-
assert bl.vlookup(4, default=
|
|
176
|
+
assert bl.vlookup(4, default="x") == "x"
|
|
139
177
|
with pytest.raises(ValueError):
|
|
140
178
|
bl.vlookup(1, column1=4)
|
|
141
179
|
with pytest.raises(ValueError):
|
|
142
180
|
bl.vlookup(1, column1=3)
|
|
143
181
|
|
|
182
|
+
|
|
144
183
|
def test_hlookup():
|
|
145
|
-
bl=xwu.block.from_value([[1,2,3],"One Two Three".split(), "Un Deux Trois".split()])
|
|
146
|
-
|
|
147
|
-
assert bl.hlookup(1)=="One"
|
|
148
|
-
assert bl.hlookup(3, row2=3)=="Trois"
|
|
184
|
+
bl = xwu.block.from_value([[1, 2, 3], "One Two Three".split(), "Un Deux Trois".split()])
|
|
185
|
+
|
|
186
|
+
assert bl.hlookup(1) == "One"
|
|
187
|
+
assert bl.hlookup(3, row2=3) == "Trois"
|
|
149
188
|
with pytest.raises(ValueError):
|
|
150
189
|
bl.hlookup(4)
|
|
151
|
-
assert bl.hlookup(4,default=
|
|
190
|
+
assert bl.hlookup(4, default="x") == "x"
|
|
152
191
|
with pytest.raises(ValueError):
|
|
153
192
|
bl.hlookup(1, row1=4)
|
|
154
193
|
with pytest.raises(ValueError):
|
|
155
194
|
bl.hlookup(1, row1=3)
|
|
156
|
-
assert bl.lookup_column(1)==1
|
|
157
|
-
assert bl.lookup_column(3)==3
|
|
195
|
+
assert bl.lookup_column(1) == 1
|
|
196
|
+
assert bl.lookup_column(3) == 3
|
|
158
197
|
|
|
159
198
|
|
|
160
199
|
def test_capture(capsys):
|
|
161
200
|
print("abc")
|
|
162
201
|
print("def")
|
|
163
|
-
capture=xwu.Capture()
|
|
202
|
+
capture = xwu.Capture()
|
|
164
203
|
out, err = capsys.readouterr()
|
|
165
204
|
assert out == "abc\ndef\n"
|
|
166
205
|
assert capture.str_keep == ""
|
|
@@ -172,10 +211,10 @@ def test_capture(capsys):
|
|
|
172
211
|
out, err = capsys.readouterr()
|
|
173
212
|
assert out == ""
|
|
174
213
|
assert capture.str_keep == "abc\ndef\n"
|
|
175
|
-
assert capture.value_keep == [[
|
|
214
|
+
assert capture.value_keep == [["abc"], ["def"]]
|
|
176
215
|
assert capture.str == "abc\ndef\n"
|
|
177
216
|
assert capture.value == []
|
|
178
|
-
|
|
217
|
+
|
|
179
218
|
with capture:
|
|
180
219
|
print("abc")
|
|
181
220
|
print("def")
|
|
@@ -188,28 +227,27 @@ def test_capture(capsys):
|
|
|
188
227
|
print("def")
|
|
189
228
|
with capture:
|
|
190
229
|
print("ghi")
|
|
191
|
-
print("jkl")
|
|
230
|
+
print("jkl")
|
|
192
231
|
out, err = capsys.readouterr()
|
|
193
232
|
assert out == ""
|
|
194
|
-
assert capture.str_keep == "abc\ndef\nghi\njkl\n"
|
|
195
|
-
assert capture.value_keep == [[
|
|
196
|
-
assert capture.value == [[
|
|
233
|
+
assert capture.str_keep == "abc\ndef\nghi\njkl\n"
|
|
234
|
+
assert capture.value_keep == [["abc"], ["def"], ["ghi"], ["jkl"]]
|
|
235
|
+
assert capture.value == [["abc"], ["def"], ["ghi"], ["jkl"]]
|
|
197
236
|
assert capture.value == []
|
|
198
|
-
|
|
199
|
-
capture.enabled=True
|
|
237
|
+
|
|
238
|
+
capture.enabled = True
|
|
200
239
|
print("abc")
|
|
201
|
-
print("def")
|
|
202
|
-
capture.enabled=False
|
|
240
|
+
print("def")
|
|
241
|
+
capture.enabled = False
|
|
203
242
|
print("xxx")
|
|
204
|
-
print("yyy")
|
|
205
|
-
capture.enabled=True
|
|
243
|
+
print("yyy")
|
|
244
|
+
capture.enabled = True
|
|
206
245
|
print("ghi")
|
|
207
|
-
print("jkl")
|
|
208
|
-
assert capture.str_keep == "abc\ndef\nghi\njkl\n"
|
|
246
|
+
print("jkl")
|
|
247
|
+
assert capture.str_keep == "abc\ndef\nghi\njkl\n"
|
|
248
|
+
|
|
249
|
+
# include_print is not testable with pytest
|
|
250
|
+
|
|
209
251
|
|
|
210
|
-
|
|
211
|
-
# include_print is not testable with pytest
|
|
212
|
-
|
|
213
252
|
if __name__ == "__main__":
|
|
214
253
|
pytest.main(["-vv", "-s", "-x", __file__])
|
|
215
|
-
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# /_/\_\|_| \_/\_/ |_||_| |_| \__, ||___/ _____ \__,_| \__||_||_||___/
|
|
6
6
|
# |___/ |_____|
|
|
7
7
|
|
|
8
|
-
__version__ = "25.0.
|
|
8
|
+
__version__ = "25.0.10"
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
import dropbox
|
|
@@ -28,32 +28,6 @@ except ImportError:
|
|
|
28
28
|
missing = object()
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
def pythonista_environ():
|
|
32
|
-
"""
|
|
33
|
-
tries to update environment variables from the file environ.toml at top level.
|
|
34
|
-
should only be used under Pythonista
|
|
35
|
-
"""
|
|
36
|
-
try:
|
|
37
|
-
import tomlib
|
|
38
|
-
except ModuleNotFoundError:
|
|
39
|
-
import tomli as tomlib
|
|
40
|
-
from pathlib import Path
|
|
41
|
-
import os
|
|
42
|
-
|
|
43
|
-
environ_file = Path("~/Documents").expanduser() / "environ.toml"
|
|
44
|
-
with open(environ_file, "rb") as f:
|
|
45
|
-
d0 = tomlib.load(f)
|
|
46
|
-
d1 = {}
|
|
47
|
-
for k0, v0 in d0.items():
|
|
48
|
-
if isinstance(v0, dict):
|
|
49
|
-
for k1, v1 in v0.items():
|
|
50
|
-
d1[f"{k0}.{k1}".upper()] = v1
|
|
51
|
-
else:
|
|
52
|
-
d1[k0.upper()] = v0
|
|
53
|
-
|
|
54
|
-
os.environ.update(d1)
|
|
55
|
-
|
|
56
|
-
|
|
57
31
|
def dropbox_init(refresh_token=missing, app_key=missing, app_secret=missing, **kwargs):
|
|
58
32
|
"""
|
|
59
33
|
dropbox initialize
|
|
@@ -87,9 +61,6 @@ def dropbox_init(refresh_token=missing, app_key=missing, app_secret=missing, **k
|
|
|
87
61
|
"""
|
|
88
62
|
global dbx
|
|
89
63
|
|
|
90
|
-
if Pythonista:
|
|
91
|
-
pythonista_environ()
|
|
92
|
-
|
|
93
64
|
if refresh_token is missing:
|
|
94
65
|
if "DROPBOX.REFRESH_TOKEN" in os.environ:
|
|
95
66
|
refresh_token = os.environ["DROPBOX.REFRESH_TOKEN"]
|
|
@@ -307,6 +278,8 @@ class block:
|
|
|
307
278
|
self.dict = {}
|
|
308
279
|
self.number_of_rows = number_of_rows
|
|
309
280
|
self.number_of_columns = number_of_columns
|
|
281
|
+
self._highest_used_row_number = None
|
|
282
|
+
self._highest_used_column_number = None
|
|
310
283
|
|
|
311
284
|
def __eq__(self, other):
|
|
312
285
|
if isinstance(other, block):
|
|
@@ -489,8 +462,14 @@ class block:
|
|
|
489
462
|
if value is None:
|
|
490
463
|
if (row, column) in self.dict:
|
|
491
464
|
del self.dict[row, column]
|
|
465
|
+
self._highest_used_row_number = None # invalidate cached value
|
|
466
|
+
self._highest_used_column_number = None # invalidate cached value
|
|
492
467
|
else:
|
|
493
468
|
self.dict[row, column] = value
|
|
469
|
+
if self._highest_used_row_number:
|
|
470
|
+
self._highest_used_row_number = max(self._highest_used_row_number, row)
|
|
471
|
+
if self._highest_used_column_number:
|
|
472
|
+
self._highest_used_column_number = max(self._highest_used_column_number, column)
|
|
494
473
|
|
|
495
474
|
def __getitem__(self, row_column):
|
|
496
475
|
row, column = row_column
|
|
@@ -517,6 +496,7 @@ class block:
|
|
|
517
496
|
def number_of_rows(self, value):
|
|
518
497
|
if value < 1:
|
|
519
498
|
raise ValueError(f"number_of_rows should be >=1, not {value}")
|
|
499
|
+
self._highest_used_row_number = None
|
|
520
500
|
self._number_of_rows = value
|
|
521
501
|
for row, column in list(self.dict):
|
|
522
502
|
if row > self._number_of_rows:
|
|
@@ -530,6 +510,7 @@ class block:
|
|
|
530
510
|
def number_of_columns(self, value):
|
|
531
511
|
if value < 1:
|
|
532
512
|
raise ValueError(f"number_of_columns should be >=1, not {value}")
|
|
513
|
+
self._highest_used_column_number = None
|
|
533
514
|
self._number_of_columns = value
|
|
534
515
|
for row, column in list(self.dict):
|
|
535
516
|
if column > self._number_of_columns:
|
|
@@ -537,17 +518,22 @@ class block:
|
|
|
537
518
|
|
|
538
519
|
@property
|
|
539
520
|
def highest_used_row_number(self):
|
|
540
|
-
if self.
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
521
|
+
if not self._highest_used_row_number:
|
|
522
|
+
if self.dict:
|
|
523
|
+
self._highest_used_row_number = max(row for (row, column) in self.dict)
|
|
524
|
+
else:
|
|
525
|
+
self._highest_used_row_number = 1
|
|
526
|
+
return self._highest_used_row_number
|
|
544
527
|
|
|
545
528
|
@property
|
|
546
529
|
def highest_used_column_number(self):
|
|
547
|
-
if self.
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
530
|
+
if not self._highest_used_column_number:
|
|
531
|
+
if self.dict:
|
|
532
|
+
self._highest_used_column_number = max(column for (row, column) in self.dict)
|
|
533
|
+
else:
|
|
534
|
+
self._highest_used_column_number = 1
|
|
535
|
+
|
|
536
|
+
return self._highest_used_column_number
|
|
551
537
|
|
|
552
538
|
def __repr__(self):
|
|
553
539
|
return f"block({self.value})"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xlwings_utils
|
|
3
|
-
Version: 25.0.
|
|
3
|
+
Version: 25.0.10
|
|
4
4
|
Summary: xlwings_utils
|
|
5
5
|
Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/salabim/xlwings_utils
|
|
@@ -61,6 +61,8 @@ In order to make a Dropbox app, and get the required environment variables, just
|
|
|
61
61
|
python -c "exec(__import__('requests').get('https://salabim.org/dropbox setup.py').text)"
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
The file `dropbox setup.py` can also be found in the repo of xlwings_lite .
|
|
65
|
+
|
|
64
66
|
Then, it is possible to list all files in a specified folder using the list_dropbox function.
|
|
65
67
|
It is also possible to get at all folders and to access all underlying folders.
|
|
66
68
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|