reykit 1.0.0__py3-none-any.whl → 1.1.0__py3-none-any.whl

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.
reykit/__init__.py CHANGED
@@ -38,4 +38,4 @@ rzip : File compress methods.
38
38
  from typing import Final
39
39
 
40
40
 
41
- __version__: Final[str] = '1.0.0'
41
+ __version__: Final[str] = '1.1.0'
reykit/rrandom.py CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
 
12
12
  from __future__ import annotations
13
- from typing import Dict, Union, Optional, Literal, Self, overload
13
+ from typing import Union, Optional, Literal, Self, overload
14
14
  from types import TracebackType
15
15
  from collections.abc import Sequence
16
16
  from string import digits as string_digits, ascii_letters as string_ascii_letters, punctuation as string_punctuation
@@ -42,30 +42,62 @@ class RConfigRandom(object, metaclass=RConfigMeta):
42
42
  """
43
43
 
44
44
  # RRandom.
45
- _rrandom_dict: Dict[int, RRandomSeed] = {}
45
+ _rrandom_dict: dict[int, RRandomSeed] = {}
46
46
 
47
47
 
48
48
  class RRandomSeed(object):
49
49
  """
50
- Rey's `random seed` type.
51
- To be used in syntax `with`, set random seed.
50
+ Rey's `random seed` type, set random seed.
52
51
  If set, based on `random` package.
53
52
  If not set, based on `secrets` package.
53
+
54
+ Examples
55
+ --------
56
+ Use active switch.
57
+ >>> RRandomSeed(seed)
58
+ >>> randn()
59
+ >>> RRandomSeed()
60
+
61
+ Use `with` syntax.
62
+ >>> with RRandomSeed(seed):
63
+ >>> randn()
54
64
  """
55
65
 
56
66
 
57
- def __init__(self, seed: Union[int, float, str, bytes, bytearray]) -> None:
67
+ def __init__(self, seed: Optional[Union[int, float, str, bytes, bytearray]] = None) -> None:
58
68
  """
59
69
  Build `random` attributes.
70
+
71
+ Parameters
72
+ ----------
73
+ seed : Random seed.
74
+ - `None`: Clear seed.
75
+ - `Union[int, float, str, bytes, bytearray]` : Set seed.
60
76
  """
61
77
 
78
+ # Delete.
79
+ if seed is None:
80
+ self.__del__()
81
+
62
82
  # Build.
63
- self.seed = seed
64
- self.random = Random(seed)
83
+ else:
84
+ self.seed = seed
85
+ self.random = Random(seed)
65
86
 
66
- # Record.
87
+ ## Record.
88
+ thread_id = threading_get_ident()
89
+ RConfigRandom._rrandom_dict[thread_id] = self
90
+
91
+
92
+ def __del__(self) -> None:
93
+ """
94
+ Delete instance.
95
+ """
96
+
97
+ # Delete.
67
98
  thread_id = threading_get_ident()
68
- RConfigRandom._rrandom_dict[thread_id] = self
99
+ if thread_id in RConfigRandom._rrandom_dict:
100
+ del RConfigRandom._rrandom_dict[thread_id]
69
101
 
70
102
 
71
103
  def __enter__(self) -> Self:
@@ -97,8 +129,7 @@ class RRandomSeed(object):
97
129
  """
98
130
 
99
131
  # Delete.
100
- thread_id = threading_get_ident()
101
- del RConfigRandom._rrandom_dict[thread_id]
132
+ self.__del__()
102
133
 
103
134
 
104
135
  @overload
reykit/rsystem.py CHANGED
@@ -39,6 +39,21 @@ from time import sleep as time_sleep
39
39
  from datetime import datetime
40
40
  from varname import VarnameRetrievingError, argname
41
41
  from webbrowser import open as webbrowser_open
42
+ from tkinter.messagebox import (
43
+ showinfo as tkinter_showinfo,
44
+ showwarning as tkinter_showwarning,
45
+ showerror as tkinter_showerror,
46
+ askyesno as tkinter_askyesno,
47
+ askyesnocancel as tkinter_askyesnocancel,
48
+ askokcancel as tkinter_askokcancel,
49
+ askretrycancel as tkinter_askretrycancel
50
+ )
51
+ from tkinter.filedialog import (
52
+ askopenfilename as tkinter_askopenfilename,
53
+ askopenfilenames as tkinter_askopenfilenames,
54
+ asksaveasfilename as tkinter_asksaveasfilename,
55
+ askdirectory as tkinter_askdirectory
56
+ )
42
57
 
43
58
  from .rexception import throw
44
59
  from .rtype import RConfigMeta
@@ -68,7 +83,10 @@ __all__ = (
68
83
  'stop_process',
69
84
  'start_process',
70
85
  'get_idle_port',
71
- 'open_browser'
86
+ 'open_browser',
87
+ 'popup_message',
88
+ 'popup_ask',
89
+ 'popup_select'
72
90
  )
73
91
 
74
92
 
@@ -1178,3 +1196,179 @@ def open_browser(url: str) -> bool:
1178
1196
  succeeded = webbrowser_open(url)
1179
1197
 
1180
1198
  return succeeded
1199
+
1200
+
1201
+ def popup_message(
1202
+ style: Literal['info', 'warn', 'error'] = 'info',
1203
+ message: Optional[str] = None,
1204
+ title: Optional[str] = None
1205
+ ) -> None:
1206
+ """
1207
+ Pop up system message box.
1208
+
1209
+ Parameters
1210
+ ----------
1211
+ style : Message box style.
1212
+ - `Literal['info']`: Information box.
1213
+ - `Literal['warn']`: Warning box.
1214
+ - `Literal['error']`: Error box.
1215
+ message : Message box content.
1216
+ title : Message box title.
1217
+ """
1218
+
1219
+ # Pop up.
1220
+ match style:
1221
+
1222
+ ## Information.
1223
+ case 'info':
1224
+ method = tkinter_showinfo
1225
+
1226
+ ## Warning.
1227
+ case 'warn':
1228
+ method = tkinter_showwarning
1229
+
1230
+ ## Error.
1231
+ case 'error':
1232
+ method = tkinter_showerror
1233
+
1234
+ method(title, message)
1235
+
1236
+
1237
+ @overload
1238
+ def popup_ask(
1239
+ style: Literal['yes_no_cancel'] = 'yes_no',
1240
+ message: Optional[str] = None,
1241
+ title: Optional[str] = None
1242
+ ) -> Optional[bool]: ...
1243
+
1244
+ @overload
1245
+ def popup_ask(
1246
+ style: Literal['yes_no', 'ok_cancel', 'retry_cancel'] = 'yes_no',
1247
+ message: Optional[str] = None,
1248
+ title: Optional[str] = None
1249
+ ) -> bool: ...
1250
+
1251
+ def popup_ask(
1252
+ style: Literal['yes_no', 'ok_cancel', 'retry_cancel', 'yes_no_cancel'] = 'yes_no',
1253
+ message: Optional[str] = None,
1254
+ title: Optional[str] = None
1255
+ ) -> Optional[bool]:
1256
+ """
1257
+ Pop up system ask box.
1258
+
1259
+ Parameters
1260
+ ----------
1261
+ style : Ask box style.
1262
+ - `Literal['yes_no']`: Buttons are `yes` and `no`.
1263
+ - `Literal['ok_cancel']`: Buttons are `ok` and `cancel`.
1264
+ - `Literal['retry_cancel']`: Buttons are `retry` and `cancel`.
1265
+ - `Literal['yes_no_cancel']`: Buttons are `yes` and `no` and `cancel`.
1266
+ message : Ask box content.
1267
+ title : Ask box title.
1268
+ """
1269
+
1270
+ # Pop up.
1271
+ match style:
1272
+
1273
+ ## Yes and no.
1274
+ case 'yes_no':
1275
+ method = tkinter_askyesno
1276
+
1277
+ ## Ok and cancel.
1278
+ case 'ok_cancel':
1279
+ method = tkinter_askokcancel
1280
+
1281
+ ## Retry and cancel.
1282
+ case 'retry_cancel':
1283
+ method = tkinter_askretrycancel
1284
+
1285
+ ## Yes and no and cancel.
1286
+ case 'yes_no_cancel':
1287
+ method = tkinter_askyesnocancel
1288
+
1289
+ method(title, message)
1290
+
1291
+
1292
+ @overload
1293
+ def popup_select(
1294
+ style: Literal['file', 'save'] = 'file',
1295
+ title : Optional[str] = None,
1296
+ init_folder : Optional[str] = None,
1297
+ init_file : Optional[str] = None,
1298
+ filter_file : Optional[list[tuple[str, str | list[str]]]] = None
1299
+ ) -> str: ...
1300
+
1301
+ @overload
1302
+ def popup_select(
1303
+ style: Literal['files'] = 'file',
1304
+ title : Optional[str] = None,
1305
+ init_folder : Optional[str] = None,
1306
+ init_file : Optional[str] = None,
1307
+ filter_file : Optional[list[tuple[str, str | list[str]]]] = None
1308
+ ) -> tuple[str, ...]: ...
1309
+
1310
+ @overload
1311
+ def popup_select(
1312
+ style: Literal['folder'] = 'file',
1313
+ title : Optional[str] = None,
1314
+ init_folder : Optional[str] = None
1315
+ ) -> str: ...
1316
+
1317
+ def popup_select(
1318
+ style: Literal['file', 'files', 'folder', 'save'] = 'file',
1319
+ title : Optional[str] = None,
1320
+ init_folder : Optional[str] = None,
1321
+ init_file : Optional[str] = None,
1322
+ filter_file : Optional[list[tuple[str, str | list[str]]]] = None
1323
+ ) -> Union[str, tuple[str, ...]]:
1324
+ """
1325
+ Pop up system select box.
1326
+
1327
+ Parameters
1328
+ ----------
1329
+ style : Select box style.
1330
+ - `Literal['file']`: Select file box.
1331
+ - `Literal['files']`: Select multiple files box.
1332
+ - `Literal['folder']`: Select folder box.
1333
+ - `Literal['save']`: Select save file box.
1334
+ title : Select box title.
1335
+ init_folder : Initial folder path.
1336
+ init_file : Initial file name.
1337
+ filter_file : Filter file.
1338
+ - `tuple[str, str]`: Filter name and filter pattern.
1339
+ - `tuple[str, list[str]]`: Filter name and multiple filter patterns (or).
1340
+ """
1341
+
1342
+ # Pop up.
1343
+ kwargs = {
1344
+ 'filetypes': filter_file,
1345
+ 'initialdir': init_folder,
1346
+ 'initialfile': init_file,
1347
+ 'title': title
1348
+ }
1349
+ kwargs = {
1350
+ key: value
1351
+ for key, value in kwargs.items()
1352
+ if value is not None
1353
+ }
1354
+ match style:
1355
+
1356
+ ## File.
1357
+ case 'file':
1358
+ method = tkinter_askopenfilename
1359
+
1360
+ ## Files.
1361
+ case 'files':
1362
+ method = tkinter_askopenfilenames
1363
+
1364
+ ## Folder.
1365
+ case 'folder':
1366
+ method = tkinter_askdirectory
1367
+
1368
+ ## Save.
1369
+ case 'save':
1370
+ method = tkinter_asksaveasfilename
1371
+
1372
+ path = method(**kwargs)
1373
+
1374
+ return path
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: reykit
3
- Version: 1.0.0
3
+ Version: 1.1.0
4
4
  Summary: Rey's kit method set.
5
5
  Home-page: https://github.com/reyxbo/reykit/
6
6
  Author: Rey
@@ -1,4 +1,4 @@
1
- reykit/__init__.py,sha256=6_scPOFt0urqRmhU5MJwghJHNudgWPhgV6J6fuYibKg,917
1
+ reykit/__init__.py,sha256=cvteTneRjZ-mxhKx57bNG5pdQc4nEtNkGG8pNXmApQs,917
2
2
  reykit/rall.py,sha256=mOFwHXZ4-BOkJ5Ptbm6lQc2zwNf_VqcqM6AYYnYPfoo,672
3
3
  reykit/rcomm.py,sha256=_i0hrCB3moZhA3sm2ebg54i9dQ8QjI57ZV2cKm0vxA4,11523
4
4
  reykit/rdata.py,sha256=qmx9yKrfP2frOQjj-34ze8sa1l4sOQXtemkKyrVtKXs,8495
@@ -10,11 +10,11 @@ reykit/rmonkey.py,sha256=s8TdR-_tRRMiR11eCLHCkFAJuAZe7PVIhkR-74Xt8vw,7644
10
10
  reykit/rmultitask.py,sha256=L4_dlIKGV3DrWlID2MDc1Fl-o0kt23l7oYGp4-WJRYU,22057
11
11
  reykit/rnumber.py,sha256=MajaVOVa3_H1lm91cu9HLaLXd9ZsvZYFxXvcklC0LWs,3209
12
12
  reykit/ros.py,sha256=wv1DM2N8MXBwGqBhNUSiDLrvHRK7syibhFwEPGkpxYM,39336
13
- reykit/rrandom.py,sha256=uroEvO8oy5zyp8pk2NWcq49ofJxo1_F3H5_W1U_oj5w,8499
13
+ reykit/rrandom.py,sha256=88SN3BxbVqF0UQJxk6z_76butNnzePHsKD7izEYyNvs,9155
14
14
  reykit/rregex.py,sha256=E9BConP7ADYyGVZ5jpxwUmtc_WXFb-I1Zjt6IZSHkIQ,6218
15
15
  reykit/rschedule.py,sha256=TiIFQ0siL20nlhikWfvRGhOdeRbyHQtN6uxFivA2WoI,5852
16
16
  reykit/rstdout.py,sha256=yjCTegPqm2FNIpNGVrmz16Jn2bNncYO1axuANVdTmVQ,9710
17
- reykit/rsystem.py,sha256=EbPOKtwtVyXqX4AqKMKPW1cEAixqHAOemaxrlEpT0ZY,29388
17
+ reykit/rsystem.py,sha256=jFaIk80gH2Ky-WKmu40jYN38wxmbI7SHcxMbbpABzdc,34623
18
18
  reykit/rtable.py,sha256=ghsppMMOGkz3boV_CSxpkel5Lfj-ViBziZrpcCoY5YA,12229
19
19
  reykit/rtext.py,sha256=xilQxaMMdaVCBk6rxQb1aI8-j52QVUH5EtTZVMQsa8Q,11108
20
20
  reykit/rtime.py,sha256=2xOGGETwl1Sc3W80a2KiPbI4GsSfIyksTeXgqNOTYVw,17178
@@ -24,7 +24,7 @@ reykit/rzip.py,sha256=HTrxyb4e6f38eOPFIXsdbcEwr7FQSqnU2MVmVRBYTbg,3563
24
24
  reykit/rdll/__init__.py,sha256=vM9V7wSNno-WH9RrxgHTIgCkQm8LmBFoLFO8z7qovNo,306
25
25
  reykit/rdll/rdll_inject.py,sha256=bETl8tywtN1OiQudbA21u6GwBM_bqVX7jbiisNj_JBg,645
26
26
  reykit/rdll/rdll_inject_core.py,sha256=Trgh_pdJs_Lw-Y-0Kkn8kHr4BnilM9dBKnHnX25T_pM,5092
27
- reykit-1.0.0.dist-info/METADATA,sha256=vUTX5EFI5_u-5aksMa9dRmhar7ESZqvIbljey8pbav0,700
28
- reykit-1.0.0.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
29
- reykit-1.0.0.dist-info/top_level.txt,sha256=2hvySInjpVEcpYg-XFCYVU5xB2TWW8RovoDtBDzAqyE,7
30
- reykit-1.0.0.dist-info/RECORD,,
27
+ reykit-1.1.0.dist-info/METADATA,sha256=bbyeoS_7XYrdRSiOH0BD6CSIMRbeewvCIxtX01Z9acc,700
28
+ reykit-1.1.0.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
29
+ reykit-1.1.0.dist-info/top_level.txt,sha256=2hvySInjpVEcpYg-XFCYVU5xB2TWW8RovoDtBDzAqyE,7
30
+ reykit-1.1.0.dist-info/RECORD,,
File without changes