ictr 1.0a0__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.
ictr/__/__init__.py ADDED
@@ -0,0 +1,27 @@
1
+ # vim: set filetype=python fileencoding=utf-8:
2
+ # -*- coding: utf-8 -*-
3
+
4
+ #============================================================================#
5
+ # #
6
+ # Licensed under the Apache License, Version 2.0 (the "License"); #
7
+ # you may not use this file except in compliance with the License. #
8
+ # You may obtain a copy of the License at #
9
+ # #
10
+ # http://www.apache.org/licenses/LICENSE-2.0 #
11
+ # #
12
+ # Unless required by applicable law or agreed to in writing, software #
13
+ # distributed under the License is distributed on an "AS IS" BASIS, #
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15
+ # See the License for the specific language governing permissions and #
16
+ # limitations under the License. #
17
+ # #
18
+ #============================================================================#
19
+
20
+
21
+ ''' Common constants, imports, and utilities. '''
22
+
23
+
24
+ from .imports import *
25
+ from .miscellany import *
26
+ from .nomina import *
27
+ from .validators import *
ictr/__/imports.py ADDED
@@ -0,0 +1,61 @@
1
+ # vim: set filetype=python fileencoding=utf-8:
2
+ # -*- coding: utf-8 -*-
3
+
4
+ #============================================================================#
5
+ # #
6
+ # Licensed under the Apache License, Version 2.0 (the "License"); #
7
+ # you may not use this file except in compliance with the License. #
8
+ # You may obtain a copy of the License at #
9
+ # #
10
+ # http://www.apache.org/licenses/LICENSE-2.0 #
11
+ # #
12
+ # Unless required by applicable law or agreed to in writing, software #
13
+ # distributed under the License is distributed on an "AS IS" BASIS, #
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15
+ # See the License for the specific language governing permissions and #
16
+ # limitations under the License. #
17
+ # #
18
+ #============================================================================#
19
+
20
+
21
+ ''' Common imports used throughout the package. '''
22
+
23
+ # ruff: noqa: F401
24
+
25
+
26
+ import abc
27
+ import collections.abc as cabc
28
+ import codecs
29
+ import dataclasses as dcls
30
+ import enum
31
+ import functools as funct
32
+ import inspect
33
+ import io
34
+ import itertools as itert
35
+ import locale
36
+ import os
37
+ import pprint
38
+ import re
39
+ import shutil
40
+ import sys
41
+ import traceback as tb
42
+ import textwrap
43
+ import threading as threads
44
+ import time
45
+ import types
46
+ import warnings
47
+
48
+ from datetime import datetime as Datetime, timezone as Timezone
49
+
50
+ import accretive as accret
51
+ import exceptiongroup as excg
52
+ import typing_extensions as typx
53
+ import wcwidth
54
+ # --- BEGIN: Injected by Copier ---
55
+ import dynadoc as ddoc
56
+ import frigid as immut
57
+ # --- END: Injected by Copier ---
58
+
59
+ # --- BEGIN: Injected by Copier ---
60
+ from absence import Absential, absent, is_absent
61
+ # --- END: Injected by Copier ---
ictr/__/miscellany.py ADDED
@@ -0,0 +1,34 @@
1
+ # vim: set filetype=python fileencoding=utf-8:
2
+ # -*- coding: utf-8 -*-
3
+
4
+ #============================================================================#
5
+ # #
6
+ # Licensed under the Apache License, Version 2.0 (the "License"); #
7
+ # you may not use this file except in compliance with the License. #
8
+ # You may obtain a copy of the License at #
9
+ # #
10
+ # http://www.apache.org/licenses/LICENSE-2.0 #
11
+ # #
12
+ # Unless required by applicable law or agreed to in writing, software #
13
+ # distributed under the License is distributed on an "AS IS" BASIS, #
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15
+ # See the License for the specific language governing permissions and #
16
+ # limitations under the License. #
17
+ # #
18
+ #============================================================================#
19
+
20
+
21
+ ''' Miscellaneous package internals. '''
22
+
23
+
24
+
25
+ from . import imports as __
26
+
27
+
28
+ def install_builtin_safely(
29
+ alias: str, installee: __.typx.Any, errorclass: type[ Exception ]
30
+ ) -> None:
31
+ ''' Adds attribute to interpreter builtins, if absent. '''
32
+ import builtins
33
+ if hasattr( builtins, alias ): raise errorclass( builtins, alias )
34
+ setattr( builtins, alias, installee )
ictr/__/nomina.py ADDED
@@ -0,0 +1,54 @@
1
+ # vim: set filetype=python fileencoding=utf-8:
2
+ # -*- coding: utf-8 -*-
3
+
4
+ #============================================================================#
5
+ # #
6
+ # Licensed under the Apache License, Version 2.0 (the "License"); #
7
+ # you may not use this file except in compliance with the License. #
8
+ # You may obtain a copy of the License at #
9
+ # #
10
+ # http://www.apache.org/licenses/LICENSE-2.0 #
11
+ # #
12
+ # Unless required by applicable law or agreed to in writing, software #
13
+ # distributed under the License is distributed on an "AS IS" BASIS, #
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15
+ # See the License for the specific language governing permissions and #
16
+ # limitations under the License. #
17
+ # #
18
+ #============================================================================#
19
+
20
+
21
+ ''' Common names and type aliases. '''
22
+
23
+
24
+ from . import imports as __
25
+
26
+
27
+ H = __.typx.TypeVar( 'H', bound = __.cabc.Hashable ) # Hash Key
28
+ V = __.typx.TypeVar( 'V' ) # Value
29
+
30
+
31
+ ComparisonResult: __.typx.TypeAlias = bool | __.types.NotImplementedType
32
+ NominativeArguments: __.typx.TypeAlias = __.cabc.Mapping[ str, __.typx.Any ]
33
+ PositionalArguments: __.typx.TypeAlias = __.cabc.Sequence[ __.typx.Any ]
34
+
35
+ DictionaryNominativeArgument: __.typx.TypeAlias = __.typx.Annotated[
36
+ V,
37
+ __.ddoc.Doc(
38
+ 'Zero or more keyword arguments from which to initialize '
39
+ 'dictionary data.' ),
40
+ ]
41
+ DictionaryPositionalArgument: __.typx.TypeAlias = __.typx.Annotated[
42
+ __.cabc.Mapping[ H, V ] | __.cabc.Iterable[ tuple[ H, V ] ],
43
+ __.ddoc.Doc(
44
+ 'Zero or more iterables from which to initialize dictionary data. '
45
+ 'Each iterable must be dictionary or sequence of key-value pairs. '
46
+ 'Duplicate keys will result in an error.' ),
47
+ ]
48
+ ExceptionInfo: __.typx.TypeAlias = tuple[
49
+ type[ BaseException ] | None,
50
+ BaseException | None,
51
+ __.types.TracebackType | None ]
52
+
53
+
54
+ package_name = __name__.split( '.', maxsplit = 1 )[ 0 ]
ictr/__/validators.py ADDED
@@ -0,0 +1,77 @@
1
+ # vim: set filetype=python fileencoding=utf-8:
2
+ # -*- coding: utf-8 -*-
3
+
4
+ #============================================================================#
5
+ # #
6
+ # Licensed under the Apache License, Version 2.0 (the "License"); #
7
+ # you may not use this file except in compliance with the License. #
8
+ # You may obtain a copy of the License at #
9
+ # #
10
+ # http://www.apache.org/licenses/LICENSE-2.0 #
11
+ # #
12
+ # Unless required by applicable law or agreed to in writing, software #
13
+ # distributed under the License is distributed on an "AS IS" BASIS, #
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15
+ # See the License for the specific language governing permissions and #
16
+ # limitations under the License. #
17
+ # #
18
+ #============================================================================#
19
+
20
+
21
+ ''' Validators for internal use. '''
22
+
23
+
24
+
25
+ from . import imports as __
26
+
27
+
28
+ def validate_arguments(
29
+ globalvars: dict[ str, __.typx.Any ],
30
+ errorclass: type[ Exception ],
31
+ ):
32
+ ''' Decorator factory which produces argument validators. '''
33
+
34
+ def decorate( function: __.cabc.Callable[ ..., __.typx.Any ] ):
35
+ ''' Decorates function to be validated. '''
36
+
37
+ @__.funct.wraps( function )
38
+ def validate( *posargs: __.typx.Any, **nomargs: __.typx.Any ):
39
+ ''' Validates arguments before invocation. '''
40
+ signature = __.inspect.signature( function )
41
+ inspectee = signature.bind( *posargs, **nomargs )
42
+ inspectee.apply_defaults( )
43
+ for name, value in inspectee.arguments.items( ):
44
+ param = signature.parameters[ name ]
45
+ annotation = param.annotation
46
+ if __.is_absent( value ): continue
47
+ if annotation is param.empty: continue
48
+ classes = _reduce_annotation(
49
+ annotation, globalvars = globalvars )
50
+ if not isinstance( value, classes ):
51
+ raise errorclass( name, classes )
52
+ return function( *posargs, **nomargs )
53
+
54
+ return validate
55
+
56
+ return decorate
57
+
58
+
59
+ def _reduce_annotation(
60
+ annotation: __.typx.Any, globalvars: dict[ str, __.typx.Any ]
61
+ ) -> tuple[ type, ... ]:
62
+ if isinstance( annotation, str ):
63
+ return _reduce_annotation(
64
+ eval( annotation, globalvars ), # noqa: S307
65
+ globalvars = globalvars )
66
+ origin = __.typx.get_origin( annotation )
67
+ if isinstance( annotation, __.types.UnionType ) or origin is __.typx.Union:
68
+ return tuple( __.itert.chain.from_iterable(
69
+ map(
70
+ lambda a: _reduce_annotation( a, globalvars = globalvars ),
71
+ __.typx.get_args( annotation ) ) ) )
72
+ if origin is None: return ( annotation, )
73
+ if origin is __.typx.Annotated:
74
+ return _reduce_annotation(
75
+ annotation.__origin__, globalvars = globalvars )
76
+ # TODO? Other special forms.
77
+ return ( origin, )
ictr/__init__.py ADDED
@@ -0,0 +1,39 @@
1
+ # vim: set filetype=python fileencoding=utf-8:
2
+ # -*- coding: utf-8 -*-
3
+
4
+ #============================================================================#
5
+ # #
6
+ # Licensed under the Apache License, Version 2.0 (the "License"); #
7
+ # you may not use this file except in compliance with the License. #
8
+ # You may obtain a copy of the License at #
9
+ # #
10
+ # http://www.apache.org/licenses/LICENSE-2.0 #
11
+ # #
12
+ # Unless required by applicable law or agreed to in writing, software #
13
+ # distributed under the License is distributed on an "AS IS" BASIS, #
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15
+ # See the License for the specific language governing permissions and #
16
+ # limitations under the License. #
17
+ # #
18
+ #============================================================================#
19
+
20
+
21
+ ''' Non-intrusive system for logging and debug printing. '''
22
+
23
+
24
+ from . import __
25
+ from . import standard
26
+ # --- BEGIN: Injected by Copier ---
27
+ from . import exceptions
28
+ # --- END: Injected by Copier ---
29
+
30
+
31
+ from .dispatchers import *
32
+ from .printers import *
33
+ from .textualizers import *
34
+
35
+
36
+ __version__ = '1.0a0'
37
+
38
+
39
+ __.immut.finalize_module( __name__, recursive = True )
@@ -0,0 +1,9 @@
1
+ # Copied from dedicated project to avoid additional dependency:
2
+ # https://github.com/trim21/wcwidth-stubs/blob/master/src/wcwidth-stubs/__init__.pyi
3
+ def list_versions() -> tuple[str, ...]: ...
4
+ def wcwidth(wc: str, unicode_version: str = ...) -> int: ...
5
+ def wcswidth(
6
+ pwcs: str, n: int | None = None, unicode_version: str = ...
7
+ ) -> int: ...
8
+
9
+ __all__ = ("list_versions", "wcswidth", "wcwidth")
ictr/configuration.py ADDED
@@ -0,0 +1,107 @@
1
+ # vim: set filetype=python fileencoding=utf-8:
2
+ # -*- coding: utf-8 -*-
3
+
4
+ #============================================================================#
5
+ # #
6
+ # Licensed under the Apache License, Version 2.0 (the "License"); #
7
+ # you may not use this file except in compliance with the License. #
8
+ # You may obtain a copy of the License at #
9
+ # #
10
+ # http://www.apache.org/licenses/LICENSE-2.0 #
11
+ # #
12
+ # Unless required by applicable law or agreed to in writing, software #
13
+ # distributed under the License is distributed on an "AS IS" BASIS, #
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15
+ # See the License for the specific language governing permissions and #
16
+ # limitations under the License. #
17
+ # #
18
+ #============================================================================#
19
+
20
+
21
+ ''' Portions of configuration hierarchy. '''
22
+
23
+
24
+ from . import __
25
+ from . import flavors as _flavors
26
+ from . import textualizers as _texts
27
+
28
+
29
+ class FlavorConfiguration( __.immut.DataclassObject ):
30
+ ''' Per-flavor configuration. '''
31
+
32
+ compositor_factory: __.typx.Annotated[
33
+ __.typx.Optional[ _texts.CompositorFactory ],
34
+ __.typx.Doc(
35
+ ''' Factory which produces compositor callable.
36
+
37
+ Takes address and flavor as arguments. Returns compositor.
38
+
39
+ Default ``None`` inherits from cumulative configuration.
40
+ ''' ),
41
+ ] = None
42
+
43
+
44
+ FlavorsRegistry: __.typx.TypeAlias = (
45
+ __.immut.Dictionary[ _flavors.Flavor, FlavorConfiguration ] )
46
+ FlavorsRegistryLiberal: __.typx.TypeAlias = (
47
+ __.cabc.Mapping[ _flavors.Flavor, FlavorConfiguration ] )
48
+
49
+
50
+ def produce_flavors_default( ) -> FlavorsRegistry:
51
+ ''' Produces registry of all standard flavors without customization. '''
52
+ flavors: FlavorsRegistryLiberal = { }
53
+ for name, spec in _flavors.flavor_specifications_standard.items( ):
54
+ tfactory = _texts.produce_compositor_factory_default(
55
+ introducer = f"{spec.label}| ", trace_exceptions = spec.stack )
56
+ flavors[ name ] = FlavorConfiguration(
57
+ compositor_factory = tfactory )
58
+ for alias, name in _flavors.flavor_aliases_standard.items( ):
59
+ flavors[ alias ] = flavors[ name ]
60
+ for level in range( 10 ):
61
+ indent_i = ' ' * level
62
+ indent_s = ' ' * ( level + 1 )
63
+ tfactory = _texts.produce_compositor_factory_default(
64
+ introducer = f"TRACE{level}| ",
65
+ line_prefix_initial = indent_i,
66
+ line_prefix_subsequent = indent_s )
67
+ flavors[ level ] = FlavorConfiguration(
68
+ compositor_factory = tfactory )
69
+ return __.immut.Dictionary( flavors )
70
+
71
+
72
+ class AddressConfiguration( __.immut.DataclassObject ):
73
+ ''' Per-address configuration. '''
74
+
75
+ compositor_factory: __.typx.Annotated[
76
+ __.typx.Optional[ _texts.CompositorFactory ],
77
+ __.typx.Doc(
78
+ ''' Factory which produces compositor callable.
79
+
80
+ Takes address and flavor as arguments. Returns compositor.
81
+
82
+ Default ``None`` inherits from cumulative configuration.
83
+ ''' ),
84
+ ] = None
85
+ flavors: __.typx.Annotated[
86
+ FlavorsRegistry,
87
+ __.typx.Doc(
88
+ ''' Registry of flavor identifiers to configurations. ''' ),
89
+ ] = __.dcls.field( default_factory = FlavorsRegistry )
90
+
91
+
92
+ class DispatcherConfiguration( __.immut.DataclassObject ):
93
+ ''' Per-dispatcher configuration. '''
94
+
95
+ compositor_factory: __.typx.Annotated[
96
+ _texts.CompositorFactory,
97
+ __.typx.Doc(
98
+ ''' Factory which produces compositor callable.
99
+
100
+ Takes address and flavor as arguments. Returns compositor.
101
+ ''' ),
102
+ ] = _texts.produce_compositor_factory_default( )
103
+ flavors: __.typx.Annotated[
104
+ FlavorsRegistry,
105
+ __.typx.Doc(
106
+ ''' Registry of flavor identifiers to configurations. ''' ),
107
+ ] = __.dcls.field( default_factory = produce_flavors_default )