meerschaum 2.2.5.dev2__py3-none-any.whl → 2.2.6__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.
- meerschaum/__init__.py +4 -1
- meerschaum/_internal/arguments/_parser.py +13 -3
- meerschaum/_internal/docs/index.py +513 -110
- meerschaum/_internal/term/__init__.py +2 -2
- meerschaum/actions/bootstrap.py +13 -14
- meerschaum/actions/python.py +11 -8
- meerschaum/actions/register.py +130 -32
- meerschaum/actions/show.py +92 -75
- meerschaum/actions/stack.py +12 -12
- meerschaum/actions/stop.py +11 -11
- meerschaum/api/__init__.py +0 -1
- meerschaum/api/dash/__init__.py +0 -1
- meerschaum/api/dash/callbacks/custom.py +1 -1
- meerschaum/api/dash/callbacks/login.py +21 -13
- meerschaum/api/dash/pages/login.py +2 -2
- meerschaum/api/dash/plugins.py +5 -6
- meerschaum/api/routes/_login.py +5 -5
- meerschaum/config/__init__.py +8 -1
- meerschaum/config/_paths.py +20 -2
- meerschaum/config/_version.py +1 -1
- meerschaum/config/paths.py +21 -2
- meerschaum/config/static/__init__.py +1 -0
- meerschaum/connectors/Connector.py +7 -2
- meerschaum/connectors/__init__.py +7 -5
- meerschaum/connectors/api/APIConnector.py +7 -2
- meerschaum/connectors/api/_actions.py +23 -31
- meerschaum/connectors/api/_uri.py +5 -5
- meerschaum/core/Pipe/__init__.py +7 -3
- meerschaum/core/Pipe/_data.py +23 -15
- meerschaum/core/Pipe/_deduplicate.py +1 -1
- meerschaum/core/Pipe/_dtypes.py +5 -0
- meerschaum/core/Pipe/_fetch.py +18 -16
- meerschaum/core/Pipe/_sync.py +20 -15
- meerschaum/plugins/_Plugin.py +6 -6
- meerschaum/plugins/__init__.py +1 -1
- meerschaum/utils/daemon/RotatingFile.py +15 -16
- meerschaum/utils/dataframe.py +12 -4
- meerschaum/utils/debug.py +9 -15
- meerschaum/utils/formatting/__init__.py +13 -12
- meerschaum/utils/misc.py +117 -11
- meerschaum/utils/packages/__init__.py +7 -1
- meerschaum/utils/typing.py +1 -0
- meerschaum/utils/venv/__init__.py +5 -1
- meerschaum/utils/warnings.py +9 -1
- meerschaum/utils/yaml.py +2 -2
- {meerschaum-2.2.5.dev2.dist-info → meerschaum-2.2.6.dist-info}/METADATA +1 -1
- {meerschaum-2.2.5.dev2.dist-info → meerschaum-2.2.6.dist-info}/RECORD +53 -54
- {meerschaum-2.2.5.dev2.dist-info → meerschaum-2.2.6.dist-info}/WHEEL +1 -1
- meerschaum/actions/backup.py +0 -43
- {meerschaum-2.2.5.dev2.dist-info → meerschaum-2.2.6.dist-info}/LICENSE +0 -0
- {meerschaum-2.2.5.dev2.dist-info → meerschaum-2.2.6.dist-info}/NOTICE +0 -0
- {meerschaum-2.2.5.dev2.dist-info → meerschaum-2.2.6.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.2.5.dev2.dist-info → meerschaum-2.2.6.dist-info}/top_level.txt +0 -0
- {meerschaum-2.2.5.dev2.dist-info → meerschaum-2.2.6.dist-info}/zip-safe +0 -0
meerschaum/core/Pipe/_sync.py
CHANGED
@@ -14,7 +14,9 @@ import threading
|
|
14
14
|
import multiprocessing
|
15
15
|
import functools
|
16
16
|
from datetime import datetime, timedelta
|
17
|
+
from typing import TYPE_CHECKING
|
17
18
|
|
19
|
+
import meerschaum as mrsm
|
18
20
|
from meerschaum.utils.typing import (
|
19
21
|
Union,
|
20
22
|
Optional,
|
@@ -26,13 +28,16 @@ from meerschaum.utils.typing import (
|
|
26
28
|
List,
|
27
29
|
Iterable,
|
28
30
|
Generator,
|
29
|
-
Iterator,
|
30
31
|
)
|
31
32
|
from meerschaum.utils.warnings import warn, error
|
32
33
|
|
34
|
+
if TYPE_CHECKING:
|
35
|
+
pd = mrsm.attempt_import('pandas')
|
36
|
+
|
33
37
|
class InferFetch:
|
34
38
|
MRSM_INFER_FETCH: bool = True
|
35
39
|
|
40
|
+
|
36
41
|
def sync(
|
37
42
|
self,
|
38
43
|
df: Union[
|
@@ -125,7 +130,7 @@ def sync(
|
|
125
130
|
from meerschaum.utils.formatting import get_console
|
126
131
|
from meerschaum.utils.venv import Venv
|
127
132
|
from meerschaum.connectors import get_connector_plugin
|
128
|
-
from meerschaum.utils.misc import df_is_chunk_generator, filter_keywords
|
133
|
+
from meerschaum.utils.misc import df_is_chunk_generator, filter_keywords, filter_arguments
|
129
134
|
from meerschaum.utils.pool import get_pool
|
130
135
|
from meerschaum.config import get_config
|
131
136
|
|
@@ -210,28 +215,28 @@ def sync(
|
|
210
215
|
):
|
211
216
|
with Venv(get_connector_plugin(self.instance_connector)):
|
212
217
|
p._exists = None
|
213
|
-
|
218
|
+
_args, _kwargs = filter_arguments(
|
219
|
+
p.instance_connector.sync_pipe_inplace,
|
214
220
|
p,
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
221
|
+
debug=debug,
|
222
|
+
**kw
|
223
|
+
)
|
224
|
+
return self.instance_connector.sync_pipe_inplace(
|
225
|
+
*_args,
|
226
|
+
**_kwargs
|
220
227
|
)
|
221
|
-
|
222
228
|
|
223
229
|
### Activate and invoke `sync(pipe)` for plugin connectors with `sync` methods.
|
224
230
|
try:
|
225
231
|
if getattr(p.connector, 'sync', None) is not None:
|
226
232
|
with Venv(get_connector_plugin(p.connector), debug=debug):
|
227
|
-
|
233
|
+
_args, _kwargs = filter_arguments(
|
234
|
+
p.connector.sync,
|
228
235
|
p,
|
229
|
-
|
230
|
-
|
231
|
-
debug=debug,
|
232
|
-
**kw
|
233
|
-
)
|
236
|
+
debug=debug,
|
237
|
+
**kw
|
234
238
|
)
|
239
|
+
return_tuple = p.connector.sync(*_args, **_kwargs)
|
235
240
|
p._exists = None
|
236
241
|
if not isinstance(return_tuple, tuple):
|
237
242
|
return_tuple = (
|
meerschaum/plugins/_Plugin.py
CHANGED
@@ -654,17 +654,18 @@ class Plugin:
|
|
654
654
|
import ast, re
|
655
655
|
### NOTE: This technically would break
|
656
656
|
### if `required` was the very first line of the file.
|
657
|
-
req_start_match = re.search(r'
|
657
|
+
req_start_match = re.search(r'required(:\s*)?.*=', text)
|
658
658
|
if not req_start_match:
|
659
659
|
return []
|
660
660
|
req_start = req_start_match.start()
|
661
|
+
equals_sign = req_start + text[req_start:].find('=')
|
661
662
|
|
662
663
|
### Dependencies may have brackets within the strings, so push back the index.
|
663
|
-
first_opening_brace =
|
664
|
+
first_opening_brace = equals_sign + 1 + text[equals_sign:].find('[')
|
664
665
|
if first_opening_brace == -1:
|
665
666
|
return []
|
666
667
|
|
667
|
-
next_closing_brace =
|
668
|
+
next_closing_brace = equals_sign + 1 + text[equals_sign:].find(']')
|
668
669
|
if next_closing_brace == -1:
|
669
670
|
return []
|
670
671
|
|
@@ -681,12 +682,11 @@ class Plugin:
|
|
681
682
|
|
682
683
|
req_end = end_ix + 1
|
683
684
|
req_text = (
|
684
|
-
text[
|
685
|
-
.lstrip()
|
686
|
-
.replace('required', '', 1)
|
685
|
+
text[(first_opening_brace-1):req_end]
|
687
686
|
.lstrip()
|
688
687
|
.replace('=', '', 1)
|
689
688
|
.lstrip()
|
689
|
+
.rstrip()
|
690
690
|
)
|
691
691
|
try:
|
692
692
|
required = ast.literal_eval(req_text)
|
meerschaum/plugins/__init__.py
CHANGED
@@ -27,7 +27,7 @@ _locks = {
|
|
27
27
|
'PLUGINS_INTERNAL_LOCK_PATH': RLock(),
|
28
28
|
}
|
29
29
|
__all__ = (
|
30
|
-
"Plugin", "make_action", "api_plugin", "import_plugins",
|
30
|
+
"Plugin", "make_action", "api_plugin", "dash_plugin", "import_plugins",
|
31
31
|
"reload_plugins", "get_plugins", "get_data_plugins", "add_plugin_argument",
|
32
32
|
"pre_sync_hook", "post_sync_hook",
|
33
33
|
)
|
@@ -32,14 +32,14 @@ class RotatingFile(io.IOBase):
|
|
32
32
|
SEEK_BACK_ATTEMPTS: int = 5
|
33
33
|
|
34
34
|
def __init__(
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
35
|
+
self,
|
36
|
+
file_path: pathlib.Path,
|
37
|
+
num_files_to_keep: Optional[int] = None,
|
38
|
+
max_file_size: Optional[int] = None,
|
39
|
+
redirect_streams: bool = False,
|
40
|
+
write_timestamps: bool = False,
|
41
|
+
timestamp_format: str = '%Y-%m-%d %H:%M',
|
42
|
+
):
|
43
43
|
"""
|
44
44
|
Create a file-like object which manages other files.
|
45
45
|
|
@@ -79,11 +79,7 @@ class RotatingFile(io.IOBase):
|
|
79
79
|
self.redirect_streams = redirect_streams
|
80
80
|
self.write_timestamps = write_timestamps
|
81
81
|
self.timestamp_format = timestamp_format
|
82
|
-
self.subfile_regex_pattern = re.compile(
|
83
|
-
r'^'
|
84
|
-
+ self.file_path.name
|
85
|
-
+ r'(?:\.\d+)?$'
|
86
|
-
)
|
82
|
+
self.subfile_regex_pattern = re.compile(r'(.*)\.log(?:\.\d+)?$')
|
87
83
|
|
88
84
|
### When subfiles are opened, map from their index to the file objects.
|
89
85
|
self.subfile_objects = {}
|
@@ -173,7 +169,7 @@ class RotatingFile(io.IOBase):
|
|
173
169
|
latest_index = (
|
174
170
|
self.get_index_from_subfile_name(existing_subfile_paths[-1].name)
|
175
171
|
if existing_subfile_paths
|
176
|
-
else
|
172
|
+
else 0
|
177
173
|
)
|
178
174
|
return latest_index
|
179
175
|
|
@@ -222,9 +218,12 @@ class RotatingFile(io.IOBase):
|
|
222
218
|
[
|
223
219
|
(file_name, self.get_index_from_subfile_name(file_name))
|
224
220
|
for file_name in os.listdir(self.file_path.parent)
|
225
|
-
if
|
221
|
+
if (
|
222
|
+
file_name.startswith(self.file_path.name)
|
223
|
+
and re.match(self.subfile_regex_pattern, file_name)
|
224
|
+
)
|
226
225
|
],
|
227
|
-
key
|
226
|
+
key=lambda x: x[1],
|
228
227
|
)
|
229
228
|
return [
|
230
229
|
(self.file_path.parent / file_name)
|
meerschaum/utils/dataframe.py
CHANGED
@@ -8,13 +8,21 @@ Utility functions for working with DataFrames.
|
|
8
8
|
|
9
9
|
from __future__ import annotations
|
10
10
|
from datetime import datetime
|
11
|
+
|
12
|
+
import meerschaum as mrsm
|
11
13
|
from meerschaum.utils.typing import (
|
12
14
|
Optional, Dict, Any, List, Hashable, Generator,
|
13
|
-
Iterator, Iterable, Union,
|
15
|
+
Iterator, Iterable, Union, TYPE_CHECKING,
|
14
16
|
)
|
15
17
|
|
18
|
+
if TYPE_CHECKING:
|
19
|
+
pd, dask = mrsm.attempt_import('pandas', 'dask')
|
20
|
+
|
16
21
|
|
17
|
-
def add_missing_cols_to_df(
|
22
|
+
def add_missing_cols_to_df(
|
23
|
+
df: 'pd.DataFrame',
|
24
|
+
dtypes: Dict[str, Any],
|
25
|
+
) -> 'pd.DataFrame':
|
18
26
|
"""
|
19
27
|
Add columns from the dtypes dictionary as null columns to a new DataFrame.
|
20
28
|
|
@@ -723,7 +731,7 @@ def get_datetime_bound_from_df(
|
|
723
731
|
df: Union['pd.DataFrame', dict, list],
|
724
732
|
datetime_column: str,
|
725
733
|
minimum: bool = True,
|
726
|
-
) -> Union[int,
|
734
|
+
) -> Union[int, datetime, None]:
|
727
735
|
"""
|
728
736
|
Return the minimum or maximum datetime (or integer) from a DataFrame.
|
729
737
|
|
@@ -818,7 +826,7 @@ def chunksize_to_npartitions(chunksize: Optional[int]) -> int:
|
|
818
826
|
|
819
827
|
|
820
828
|
def df_from_literal(
|
821
|
-
pipe: Optional[
|
829
|
+
pipe: Optional[mrsm.Pipe] = None,
|
822
830
|
literal: str = None,
|
823
831
|
debug: bool = False
|
824
832
|
) -> 'pd.DataFrame':
|
meerschaum/utils/debug.py
CHANGED
@@ -93,22 +93,16 @@ def _checkpoint(
|
|
93
93
|
) -> None:
|
94
94
|
"""If the `_progress` and `_task` objects are provided, increment the task by one step.
|
95
95
|
If `_total` is provided, update the total instead.
|
96
|
-
|
97
|
-
Parameters
|
98
|
-
----------
|
99
|
-
_progress: Optional['rich.progress.Progress'] :
|
100
|
-
(Default value = None)
|
101
|
-
_task: Optional[int] :
|
102
|
-
(Default value = None)
|
103
|
-
_total: Optional[int] :
|
104
|
-
(Default value = None)
|
105
|
-
**kw :
|
106
|
-
|
107
|
-
|
108
|
-
Returns
|
109
|
-
-------
|
110
|
-
|
111
96
|
"""
|
112
97
|
if _progress is not None and _task is not None:
|
113
98
|
_kw = {'total': _total} if _total is not None else {'advance': 1}
|
114
99
|
_progress.update(_task, **_kw)
|
100
|
+
|
101
|
+
|
102
|
+
def trace(browser: bool = True):
|
103
|
+
"""
|
104
|
+
Open a web-based debugger to trace the execution of the program.
|
105
|
+
"""
|
106
|
+
from meerschaum.utils.packages import attempt_import
|
107
|
+
heartrate = attempt_import('heartrate')
|
108
|
+
heartrate.trace(files=heartrate.files.all, browser=browser)
|
@@ -291,16 +291,16 @@ def print_tuple(
|
|
291
291
|
|
292
292
|
|
293
293
|
def print_options(
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
294
|
+
options: Optional[Dict[str, Any]] = None,
|
295
|
+
nopretty: bool = False,
|
296
|
+
no_rich: bool = False,
|
297
|
+
name: str = 'options',
|
298
|
+
header: Optional[str] = None,
|
299
|
+
num_cols: Optional[int] = None,
|
300
|
+
adjust_cols: bool = True,
|
301
|
+
sort_options: bool = False,
|
302
|
+
**kw
|
303
|
+
) -> None:
|
304
304
|
"""
|
305
305
|
Print items in an iterable as a fancy table.
|
306
306
|
|
@@ -342,7 +342,7 @@ def print_options(
|
|
342
342
|
_options.append(str(o))
|
343
343
|
if sort_options:
|
344
344
|
_options = sorted(_options)
|
345
|
-
_header = f"
|
345
|
+
_header = f"\nAvailable {name}" if header is None else header
|
346
346
|
|
347
347
|
if num_cols is None:
|
348
348
|
num_cols = 8
|
@@ -388,7 +388,7 @@ def print_options(
|
|
388
388
|
|
389
389
|
if _header is not None:
|
390
390
|
table = Table(
|
391
|
-
title =
|
391
|
+
title = _header,
|
392
392
|
box = box.SIMPLE,
|
393
393
|
show_header = False,
|
394
394
|
show_footer = False,
|
@@ -467,6 +467,7 @@ def fill_ansi(string: str, style: str = '') -> str:
|
|
467
467
|
|
468
468
|
return rich_text_to_str(msg)
|
469
469
|
|
470
|
+
|
470
471
|
def __getattr__(name: str) -> str:
|
471
472
|
"""
|
472
473
|
Lazily load module-level variables.
|
meerschaum/utils/misc.py
CHANGED
@@ -6,6 +6,7 @@ Miscellaneous functions go here
|
|
6
6
|
"""
|
7
7
|
|
8
8
|
from __future__ import annotations
|
9
|
+
import sys
|
9
10
|
from datetime import timedelta, datetime, timezone
|
10
11
|
from meerschaum.utils.typing import (
|
11
12
|
Union,
|
@@ -22,8 +23,11 @@ from meerschaum.utils.typing import (
|
|
22
23
|
Hashable,
|
23
24
|
Generator,
|
24
25
|
Iterator,
|
26
|
+
TYPE_CHECKING,
|
25
27
|
)
|
26
28
|
import meerschaum as mrsm
|
29
|
+
if TYPE_CHECKING:
|
30
|
+
import collections
|
27
31
|
|
28
32
|
__pdoc__: Dict[str, bool] = {
|
29
33
|
'to_pandas_dtype': False,
|
@@ -208,6 +212,7 @@ def parse_config_substitution(
|
|
208
212
|
|
209
213
|
return leading_key[len(leading_key):][len():-1].split(delimeter)
|
210
214
|
|
215
|
+
|
211
216
|
def edit_file(
|
212
217
|
path: Union[pathlib.Path, str],
|
213
218
|
default_editor: str = 'pyvim',
|
@@ -233,7 +238,6 @@ def edit_file(
|
|
233
238
|
Returns
|
234
239
|
-------
|
235
240
|
A bool indicating the file was successfully edited.
|
236
|
-
|
237
241
|
"""
|
238
242
|
import os
|
239
243
|
from subprocess import call
|
@@ -254,7 +258,7 @@ def edit_file(
|
|
254
258
|
|
255
259
|
|
256
260
|
def is_pipe_registered(
|
257
|
-
pipe:
|
261
|
+
pipe: mrsm.Pipe,
|
258
262
|
pipes: PipesDict,
|
259
263
|
debug: bool = False
|
260
264
|
) -> bool:
|
@@ -726,25 +730,53 @@ def replace_password(d: Dict[str, Any], replace_with: str = '*') -> Dict[str, An
|
|
726
730
|
return _d
|
727
731
|
|
728
732
|
|
733
|
+
def filter_arguments(
|
734
|
+
func: Callable[[Any], Any],
|
735
|
+
*args: Any,
|
736
|
+
**kwargs: Any
|
737
|
+
) -> Tuple[Tuple[Any], Dict[str, Any]]:
|
738
|
+
"""
|
739
|
+
Filter out unsupported positional and keyword arguments.
|
740
|
+
|
741
|
+
Parameters
|
742
|
+
----------
|
743
|
+
func: Callable[[Any], Any]
|
744
|
+
The function to inspect.
|
745
|
+
|
746
|
+
*args: Any
|
747
|
+
Positional arguments to filter and pass to `func`.
|
748
|
+
|
749
|
+
**kwargs
|
750
|
+
Keyword arguments to filter and pass to `func`.
|
751
|
+
|
752
|
+
Returns
|
753
|
+
-------
|
754
|
+
The `args` and `kwargs` accepted by `func`.
|
755
|
+
"""
|
756
|
+
args = filter_positionals(func, *args)
|
757
|
+
kwargs = filter_keywords(func, **kwargs)
|
758
|
+
return args, kwargs
|
759
|
+
|
760
|
+
|
729
761
|
def filter_keywords(
|
730
|
-
|
731
|
-
|
732
|
-
|
762
|
+
func: Callable[[Any], Any],
|
763
|
+
**kw: Any
|
764
|
+
) -> Dict[str, Any]:
|
733
765
|
"""
|
734
|
-
Filter out unsupported
|
766
|
+
Filter out unsupported keyword arguments.
|
735
767
|
|
736
768
|
Parameters
|
737
769
|
----------
|
738
770
|
func: Callable[[Any], Any]
|
739
771
|
The function to inspect.
|
740
|
-
|
772
|
+
|
741
773
|
**kw: Any
|
742
774
|
The arguments to be filtered and passed into `func`.
|
743
775
|
|
744
776
|
Returns
|
745
777
|
-------
|
746
778
|
A dictionary of keyword arguments accepted by `func`.
|
747
|
-
|
779
|
+
|
748
780
|
Examples
|
749
781
|
--------
|
750
782
|
```python
|
@@ -766,6 +798,69 @@ def filter_keywords(
|
|
766
798
|
return {k: v for k, v in kw.items() if k in func_params}
|
767
799
|
|
768
800
|
|
801
|
+
def filter_positionals(
|
802
|
+
func: Callable[[Any], Any],
|
803
|
+
*args: Any
|
804
|
+
) -> Tuple[Any]:
|
805
|
+
"""
|
806
|
+
Filter out unsupported positional arguments.
|
807
|
+
|
808
|
+
Parameters
|
809
|
+
----------
|
810
|
+
func: Callable[[Any], Any]
|
811
|
+
The function to inspect.
|
812
|
+
|
813
|
+
*args: Any
|
814
|
+
The arguments to be filtered and passed into `func`.
|
815
|
+
NOTE: If the function signature expects more arguments than provided,
|
816
|
+
the missing slots will be filled with `None`.
|
817
|
+
|
818
|
+
Returns
|
819
|
+
-------
|
820
|
+
A tuple of positional arguments accepted by `func`.
|
821
|
+
|
822
|
+
Examples
|
823
|
+
--------
|
824
|
+
```python
|
825
|
+
>>> def foo(a, b):
|
826
|
+
... return a * b
|
827
|
+
>>> filter_positionals(foo, 2, 4, 6)
|
828
|
+
(2, 4)
|
829
|
+
>>> foo(*filter_positionals(foo, 2, 4, 6))
|
830
|
+
8
|
831
|
+
```
|
832
|
+
|
833
|
+
"""
|
834
|
+
import inspect
|
835
|
+
from meerschaum.utils.warnings import warn
|
836
|
+
func_params = inspect.signature(func).parameters
|
837
|
+
acceptable_args: List[Any] = []
|
838
|
+
|
839
|
+
def _warn_invalids(_num_invalid):
|
840
|
+
if _num_invalid > 0:
|
841
|
+
warn(
|
842
|
+
"Too few arguments were provided. "
|
843
|
+
+ f"{_num_invalid} argument"
|
844
|
+
+ ('s have ' if _num_invalid != 1 else " has ")
|
845
|
+
+ " been filled with `None`.",
|
846
|
+
)
|
847
|
+
|
848
|
+
num_invalid: int = 0
|
849
|
+
for i, (param, val) in enumerate(func_params.items()):
|
850
|
+
if '=' in str(val) or '*' in str(val):
|
851
|
+
_warn_invalids(num_invalid)
|
852
|
+
return tuple(acceptable_args)
|
853
|
+
|
854
|
+
try:
|
855
|
+
acceptable_args.append(args[i])
|
856
|
+
except IndexError:
|
857
|
+
acceptable_args.append(None)
|
858
|
+
num_invalid += 1
|
859
|
+
|
860
|
+
_warn_invalids(num_invalid)
|
861
|
+
return tuple(acceptable_args)
|
862
|
+
|
863
|
+
|
769
864
|
def dict_from_od(od: collections.OrderedDict) -> Dict[Any, Any]:
|
770
865
|
"""
|
771
866
|
Convert an ordered dict to a dict.
|
@@ -974,10 +1069,11 @@ def async_wrap(func):
|
|
974
1069
|
def debug_trace(browser: bool = True):
|
975
1070
|
"""
|
976
1071
|
Open a web-based debugger to trace the execution of the program.
|
1072
|
+
|
1073
|
+
This is an alias import for `meerschaum.utils.debug.debug_trace`.
|
977
1074
|
"""
|
978
|
-
from meerschaum.utils.
|
979
|
-
|
980
|
-
heartrate.trace(files=heartrate.files.all, browser=browser)
|
1075
|
+
from meerschaum.utils.debug import trace
|
1076
|
+
trace(browser=browser)
|
981
1077
|
|
982
1078
|
|
983
1079
|
def items_str(
|
@@ -1554,3 +1650,13 @@ def _get_subaction_names(*args, **kwargs) -> Any:
|
|
1554
1650
|
"""
|
1555
1651
|
from meerschaum.actions import _get_subaction_names as real_function
|
1556
1652
|
return real_function(*args, **kwargs)
|
1653
|
+
|
1654
|
+
|
1655
|
+
_current_module = sys.modules[__name__]
|
1656
|
+
__all__ = tuple(
|
1657
|
+
name
|
1658
|
+
for name, obj in globals().items()
|
1659
|
+
if callable(obj)
|
1660
|
+
and name not in __pdoc__
|
1661
|
+
and getattr(obj, '__module__', None) == _current_module.__name__
|
1662
|
+
)
|
@@ -1849,10 +1849,16 @@ def _get_pip_os_env(color: bool = True):
|
|
1849
1849
|
Return the environment variables context in which `pip` should be run.
|
1850
1850
|
See PEP 668 for why we are overriding the environment.
|
1851
1851
|
"""
|
1852
|
-
import os
|
1852
|
+
import os, sys, platform
|
1853
|
+
python_bin_path = pathlib.Path(sys.executable)
|
1853
1854
|
pip_os_env = os.environ.copy()
|
1855
|
+
path_str = pip_os_env.get('PATH', '') or ''
|
1856
|
+
path_sep = ':' if platform.system() != 'Windows' else ';'
|
1854
1857
|
pip_os_env.update({
|
1855
1858
|
'PIP_BREAK_SYSTEM_PACKAGES': 'true',
|
1856
1859
|
('FORCE_COLOR' if color else 'NO_COLOR'): '1',
|
1857
1860
|
})
|
1861
|
+
if str(python_bin_path) not in path_str:
|
1862
|
+
pip_os_env['PATH'] = str(python_bin_path.parent) + path_sep + path_str
|
1863
|
+
|
1858
1864
|
return pip_os_env
|
meerschaum/utils/typing.py
CHANGED
@@ -616,7 +616,11 @@ def venv_target_path(
|
|
616
616
|
return site_packages_path
|
617
617
|
|
618
618
|
if not inside_venv():
|
619
|
-
|
619
|
+
user_site_packages = site.getusersitepackages()
|
620
|
+
if user_site_packages is None:
|
621
|
+
raise EnvironmentError("Could not determine user site packages.")
|
622
|
+
|
623
|
+
site_path = pathlib.Path(user_site_packages)
|
620
624
|
if not site_path.exists():
|
621
625
|
|
622
626
|
### Windows does not have `os.geteuid()`.
|
meerschaum/utils/warnings.py
CHANGED
@@ -3,15 +3,23 @@
|
|
3
3
|
# vim:fenc=utf-8
|
4
4
|
|
5
5
|
"""
|
6
|
-
Handle all things warnings and errors
|
6
|
+
Handle all things warnings and errors.
|
7
7
|
"""
|
8
8
|
|
9
9
|
from __future__ import annotations
|
10
10
|
from meerschaum.utils.typing import Any, Union
|
11
|
+
from meerschaum.utils.debug import dprint
|
11
12
|
|
12
13
|
import sys
|
13
14
|
import warnings
|
14
15
|
|
16
|
+
__all__ = (
|
17
|
+
'warn',
|
18
|
+
'info',
|
19
|
+
'error',
|
20
|
+
'dprint',
|
21
|
+
)
|
22
|
+
|
15
23
|
warnings.filterwarnings(
|
16
24
|
"always",
|
17
25
|
category = UserWarning
|
meerschaum/utils/yaml.py
CHANGED
@@ -10,7 +10,7 @@ This is so switching between PyYAML and ruamel.yaml is smoother.
|
|
10
10
|
|
11
11
|
from meerschaum.utils.misc import filter_keywords
|
12
12
|
from meerschaum.utils.packages import attempt_import, all_packages, _import_module
|
13
|
-
from meerschaum.utils.warnings import error
|
13
|
+
from meerschaum.utils.warnings import error
|
14
14
|
from meerschaum.utils.threading import Lock
|
15
15
|
|
16
16
|
_lib = None
|
@@ -49,7 +49,7 @@ class yaml:
|
|
49
49
|
"""
|
50
50
|
global _yaml, _lib, _dumper
|
51
51
|
if _import_name is None:
|
52
|
-
error(
|
52
|
+
error("No YAML library declared.")
|
53
53
|
with _locks['_lib']:
|
54
54
|
try:
|
55
55
|
_lib = _import_module(_import_name)
|