ae-base 0.3.38__py3-none-any.whl → 0.3.39__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.
- ae/base.py +67 -4
- {ae_base-0.3.38.dist-info → ae_base-0.3.39.dist-info}/METADATA +31 -31
- ae_base-0.3.39.dist-info/RECORD +7 -0
- {ae_base-0.3.38.dist-info → ae_base-0.3.39.dist-info}/WHEEL +1 -1
- ae_base-0.3.38.dist-info/RECORD +0 -7
- {ae_base-0.3.38.dist-info → ae_base-0.3.39.dist-info}/LICENSE.md +0 -0
- {ae_base-0.3.38.dist-info → ae_base-0.3.39.dist-info}/top_level.txt +0 -0
- {ae_base-0.3.38.dist-info → ae_base-0.3.39.dist-info}/zip-safe +0 -0
ae/base.py
CHANGED
|
@@ -42,7 +42,7 @@ absolute, call the function :func:`norm_path`.
|
|
|
42
42
|
|
|
43
43
|
:func:`camel_to_snake` and :func:`snake_to_camel` providing name conversions of class and method names.
|
|
44
44
|
|
|
45
|
-
to encode
|
|
45
|
+
to encode Unicode strings to other codecs the functions :func:`force_encoding` and :func:`to_ascii` can be used.
|
|
46
46
|
|
|
47
47
|
the :func:`round_traditional` function get provided by this module for traditional rounding of float values. the
|
|
48
48
|
function signature is fully compatible to Python's :func:`round` function.
|
|
@@ -137,6 +137,7 @@ import shutil
|
|
|
137
137
|
import socket
|
|
138
138
|
import sys
|
|
139
139
|
import unicodedata
|
|
140
|
+
import urllib.parse
|
|
140
141
|
import warnings
|
|
141
142
|
|
|
142
143
|
from configparser import ConfigParser, ExtendedInterpolation
|
|
@@ -146,7 +147,8 @@ from inspect import getinnerframes, getouterframes, getsourcefile
|
|
|
146
147
|
from types import ModuleType
|
|
147
148
|
from typing import Any, Callable, Dict, Generator, Iterable, List, Optional, Tuple, Union, cast
|
|
148
149
|
|
|
149
|
-
|
|
150
|
+
|
|
151
|
+
__version__ = '0.3.39'
|
|
150
152
|
|
|
151
153
|
|
|
152
154
|
DOCS_FOLDER = 'docs' #: project documentation root folder name
|
|
@@ -921,7 +923,7 @@ def sys_env_text(ind_ch: str = " ", ind_len: int = 12, key_ch: str = "=", key_le
|
|
|
921
923
|
extra_sys_env_dict: Optional[Dict[str, str]] = None) -> str:
|
|
922
924
|
""" compile formatted text block with system environment info.
|
|
923
925
|
|
|
924
|
-
:param ind_ch: indent character (
|
|
926
|
+
:param ind_ch: indent character (defaults to " ").
|
|
925
927
|
:param ind_len: indent depths (default=12 characters).
|
|
926
928
|
:param key_ch: key-value separator character (default="=").
|
|
927
929
|
:param key_len: key-name minimum length (default=15 characters).
|
|
@@ -940,7 +942,7 @@ def sys_env_text(ind_ch: str = " ", ind_len: int = 12, key_ch: str = "=", key_le
|
|
|
940
942
|
|
|
941
943
|
|
|
942
944
|
def to_ascii(unicode_str: str) -> str:
|
|
943
|
-
""" converts
|
|
945
|
+
""" converts Unicode string into ascii representation.
|
|
944
946
|
|
|
945
947
|
useful for fuzzy string compare; inspired by MiniQuark's answer
|
|
946
948
|
in: https://stackoverflow.com/questions/517923/what-is-the-best-way-to-remove-accents-in-a-python-unicode-string
|
|
@@ -952,6 +954,36 @@ def to_ascii(unicode_str: str) -> str:
|
|
|
952
954
|
return "".join([c for c in nfkd_form if not unicodedata.combining(c)]).replace('ß', "ss").replace('€', "Euro")
|
|
953
955
|
|
|
954
956
|
|
|
957
|
+
def uri2filename(uri: str) -> str:
|
|
958
|
+
""" convert a URI to be usable as name of a file or folder
|
|
959
|
+
|
|
960
|
+
:param uri: URI to convert to a corresponding file name, that will be revertible back to this URI.
|
|
961
|
+
:return: name of a file/folder representing the specified URI.
|
|
962
|
+
|
|
963
|
+
in *nix only / and \0 are not allowed characters in file names.
|
|
964
|
+
in MS Windows are not allowed: ASCII 0...31): / \\ : * ? ” < > | (). some blogs recommend to also not allow
|
|
965
|
+
(convert) the characters # and '.
|
|
966
|
+
only old POSIX seems to be even more restricted (only allowing alphanumeric characters plus . - and _).
|
|
967
|
+
|
|
968
|
+
file name length is not restricted/shortened by this function, although the maximum is 255 characters on most OSs.
|
|
969
|
+
|
|
970
|
+
more on allowed characters in file names in the answers of RedGrittyBrick on https://superuser.com/questions/358855
|
|
971
|
+
and of Christopher Oezbek on https://stackoverflow.com/questions/1976007.
|
|
972
|
+
"""
|
|
973
|
+
# using urllib.parse.quote(uri, safe="") instead would convert also any non-ascii (e.g. umlaut) characters into hex
|
|
974
|
+
# added [] to str.join() argument because List comprehensions are faster than generator expressions
|
|
975
|
+
return "".join([f"%{hex(ord(_))[2:].upper()}" if _ in '/|\\:*?"<>%' else _ for _ in uri])
|
|
976
|
+
|
|
977
|
+
|
|
978
|
+
def filename2uri(file_name: str) -> str:
|
|
979
|
+
""" convert a file name converted by :func:`uri2filename` back to its representation as a URI
|
|
980
|
+
|
|
981
|
+
:param file_name: name of the file/folder to convert back to its URI representation.
|
|
982
|
+
:return: URI string.
|
|
983
|
+
"""
|
|
984
|
+
return urllib.parse.unquote(file_name)
|
|
985
|
+
|
|
986
|
+
|
|
955
987
|
def write_file(file_path: str, content: Union[str, bytes], extra_mode: str = "", encoding: Optional[str] = None):
|
|
956
988
|
""" (over)write the file specified by :paramref:`~write_file.file_path` with text or binary/bytes content.
|
|
957
989
|
|
|
@@ -966,11 +998,42 @@ def write_file(file_path: str, content: Union[str, bytes], extra_mode: str = "",
|
|
|
966
998
|
:raises OSError: if :paramref:`~read_file.file_path` is misspelled or contains invalid characters.
|
|
967
999
|
:raises PermissionError: if current OS user account lacks permissions to read the file content.
|
|
968
1000
|
:raises ValueError: on decoding errors.
|
|
1001
|
+
|
|
1002
|
+
to extend this function for Android 14+ see https://github.com/beeware/toga/pull/1158#issuecomment-2254564657
|
|
1003
|
+
and https://gist.github.com/neonankiti/05922cf0a44108a2e2732671ed9ef386
|
|
1004
|
+
Yes, to use ACTION_CREATE_DOCUMENT, you don't supply a URI in the intent. You wait for the intent result, and that
|
|
1005
|
+
will contain a URI which you can write to.
|
|
1006
|
+
See #1158 (comment - https://github.com/beeware/toga/pull/1158#issuecomment-2254564657) for a link to a Java
|
|
1007
|
+
example, and #1158 (comment - https://github.com/beeware/toga/pull/1158#issuecomment-1446196973) for how to wait
|
|
1008
|
+
for an intent result.
|
|
1009
|
+
Related german docs: https://developer.android.com/training/data-storage/shared/media?hl=de
|
|
969
1010
|
"""
|
|
970
1011
|
with open(file_path, ('' if extra_mode.startswith('a') else 'w') + extra_mode, encoding=encoding) as file_handle:
|
|
971
1012
|
file_handle.write(content)
|
|
972
1013
|
|
|
973
1014
|
|
|
1015
|
+
class ErrorMsgMixin:
|
|
1016
|
+
""" mixin class providing error message """
|
|
1017
|
+
_err_msg: str = ""
|
|
1018
|
+
|
|
1019
|
+
@property
|
|
1020
|
+
def error_message(self) -> str:
|
|
1021
|
+
""" error message string if an error occurred or an empty string if not.
|
|
1022
|
+
|
|
1023
|
+
:getter: return the accumulated error message of the recently occurred error(s).
|
|
1024
|
+
:setter: any assigned error message will be accumulated to recent error messages.
|
|
1025
|
+
pass an empty string to reset the error message.
|
|
1026
|
+
"""
|
|
1027
|
+
return self._err_msg
|
|
1028
|
+
|
|
1029
|
+
@error_message.setter
|
|
1030
|
+
def error_message(self, next_err_msg: str):
|
|
1031
|
+
if next_err_msg:
|
|
1032
|
+
self._err_msg += ("\n\n" if self._err_msg else "") + next_err_msg
|
|
1033
|
+
else:
|
|
1034
|
+
self._err_msg = ""
|
|
1035
|
+
|
|
1036
|
+
|
|
974
1037
|
PACKAGE_NAME = stack_var('__name__') or 'unspecified_package'
|
|
975
1038
|
PACKAGE_DOMAIN = 'org.test'
|
|
976
1039
|
PERMISSIONS = "INTERNET, VIBRATE, READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ae_base
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.39
|
|
4
4
|
Summary: ae namespace module portion base: basic constants, helper functions and context manager
|
|
5
5
|
Home-page: https://gitlab.com/ae-group/ae_base
|
|
6
6
|
Author: AndiEcker
|
|
@@ -22,48 +22,48 @@ Requires-Python: >=3.9
|
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE.md
|
|
24
24
|
Provides-Extra: dev
|
|
25
|
-
Requires-Dist: aedev-tpl-project
|
|
26
|
-
Requires-Dist: ae-ae
|
|
27
|
-
Requires-Dist: anybadge
|
|
28
|
-
Requires-Dist: coverage-badge
|
|
29
|
-
Requires-Dist: aedev-git-repo-manager
|
|
30
|
-
Requires-Dist: flake8
|
|
31
|
-
Requires-Dist: mypy
|
|
32
|
-
Requires-Dist: pylint
|
|
33
|
-
Requires-Dist: pytest
|
|
34
|
-
Requires-Dist: pytest-cov
|
|
35
|
-
Requires-Dist: typing
|
|
36
|
-
Requires-Dist: types-setuptools
|
|
37
|
-
Requires-Dist: wheel
|
|
38
|
-
Requires-Dist: twine
|
|
25
|
+
Requires-Dist: aedev-tpl-project; extra == "dev"
|
|
26
|
+
Requires-Dist: ae-ae; extra == "dev"
|
|
27
|
+
Requires-Dist: anybadge; extra == "dev"
|
|
28
|
+
Requires-Dist: coverage-badge; extra == "dev"
|
|
29
|
+
Requires-Dist: aedev-git-repo-manager; extra == "dev"
|
|
30
|
+
Requires-Dist: flake8; extra == "dev"
|
|
31
|
+
Requires-Dist: mypy; extra == "dev"
|
|
32
|
+
Requires-Dist: pylint; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
35
|
+
Requires-Dist: typing; extra == "dev"
|
|
36
|
+
Requires-Dist: types-setuptools; extra == "dev"
|
|
37
|
+
Requires-Dist: wheel; extra == "dev"
|
|
38
|
+
Requires-Dist: twine; extra == "dev"
|
|
39
39
|
Provides-Extra: docs
|
|
40
40
|
Provides-Extra: tests
|
|
41
|
-
Requires-Dist: anybadge
|
|
42
|
-
Requires-Dist: coverage-badge
|
|
43
|
-
Requires-Dist: aedev-git-repo-manager
|
|
44
|
-
Requires-Dist: flake8
|
|
45
|
-
Requires-Dist: mypy
|
|
46
|
-
Requires-Dist: pylint
|
|
47
|
-
Requires-Dist: pytest
|
|
48
|
-
Requires-Dist: pytest-cov
|
|
49
|
-
Requires-Dist: typing
|
|
50
|
-
Requires-Dist: types-setuptools
|
|
51
|
-
Requires-Dist: wheel
|
|
52
|
-
Requires-Dist: twine
|
|
41
|
+
Requires-Dist: anybadge; extra == "tests"
|
|
42
|
+
Requires-Dist: coverage-badge; extra == "tests"
|
|
43
|
+
Requires-Dist: aedev-git-repo-manager; extra == "tests"
|
|
44
|
+
Requires-Dist: flake8; extra == "tests"
|
|
45
|
+
Requires-Dist: mypy; extra == "tests"
|
|
46
|
+
Requires-Dist: pylint; extra == "tests"
|
|
47
|
+
Requires-Dist: pytest; extra == "tests"
|
|
48
|
+
Requires-Dist: pytest-cov; extra == "tests"
|
|
49
|
+
Requires-Dist: typing; extra == "tests"
|
|
50
|
+
Requires-Dist: types-setuptools; extra == "tests"
|
|
51
|
+
Requires-Dist: wheel; extra == "tests"
|
|
52
|
+
Requires-Dist: twine; extra == "tests"
|
|
53
53
|
|
|
54
54
|
<!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project ae.ae V0.3.94 -->
|
|
55
55
|
<!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project aedev.tpl_namespace_root V0.3.14 -->
|
|
56
|
-
# base 0.3.
|
|
56
|
+
# base 0.3.39
|
|
57
57
|
|
|
58
58
|
[](
|
|
59
59
|
https://gitlab.com/ae-group/ae_base)
|
|
60
60
|
[](
|
|
62
|
+
https://gitlab.com/ae-group/ae_base/-/tree/release0.3.38)
|
|
63
63
|
[](
|
|
64
64
|
https://pypi.org/project/ae-base/#history)
|
|
65
65
|
|
|
66
|
-
>ae_base module 0.3.
|
|
66
|
+
>ae_base module 0.3.39.
|
|
67
67
|
|
|
68
68
|
[](
|
|
69
69
|
https://ae-group.gitlab.io/ae_base/coverage/index.html)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
ae/base.py,sha256=aA_qa4s-17EzXKjN9wwfya688eGnFNJP0EglSLeYJjw,55182
|
|
2
|
+
ae_base-0.3.39.dist-info/LICENSE.md,sha256=3X7IwvwQFt4PqRHb7mV8qoJjQ1E-HmcGioyT4Y6-6c8,35002
|
|
3
|
+
ae_base-0.3.39.dist-info/METADATA,sha256=YPZbM4qKqfaO-3WvDLvV77O9WNWOfxg6uxhkO7nu0vA,5219
|
|
4
|
+
ae_base-0.3.39.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
5
|
+
ae_base-0.3.39.dist-info/top_level.txt,sha256=vUdgAslSmhZLXWU48fm8AG2BjVnkOWLco8rzuW-5zY0,3
|
|
6
|
+
ae_base-0.3.39.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
7
|
+
ae_base-0.3.39.dist-info/RECORD,,
|
ae_base-0.3.38.dist-info/RECORD
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
ae/base.py,sha256=HAkWF2Ft6XPRF9DpPVHalbrsD7YwxqBNoihmJHLK-8E,52051
|
|
2
|
-
ae_base-0.3.38.dist-info/LICENSE.md,sha256=3X7IwvwQFt4PqRHb7mV8qoJjQ1E-HmcGioyT4Y6-6c8,35002
|
|
3
|
-
ae_base-0.3.38.dist-info/METADATA,sha256=CpX74Z8BWOU201lQrKvn5JjDX8IN1ihff65-F8nCpDw,5245
|
|
4
|
-
ae_base-0.3.38.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
5
|
-
ae_base-0.3.38.dist-info/top_level.txt,sha256=vUdgAslSmhZLXWU48fm8AG2BjVnkOWLco8rzuW-5zY0,3
|
|
6
|
-
ae_base-0.3.38.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
7
|
-
ae_base-0.3.38.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|