encommon 1.1.0__py3-none-any.whl → 2.0.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.
- encommon/config/__init__.py +2 -2
- encommon/config/common.py +12 -2
- encommon/config/config.py +68 -9
- encommon/config/files.py +2 -2
- encommon/config/logger.py +3 -9
- encommon/config/params.py +46 -0
- encommon/config/paths.py +2 -2
- encommon/config/test/__init__.py +2 -2
- encommon/config/test/test_common.py +2 -2
- encommon/config/test/test_config.py +35 -10
- encommon/config/test/test_files.py +2 -2
- encommon/config/test/test_logger.py +2 -2
- encommon/config/test/test_paths.py +2 -2
- encommon/conftest.py +2 -2
- encommon/{crypt → crypts}/__init__.py +2 -2
- encommon/{crypt/crypt.py → crypts/crypts.py} +14 -14
- encommon/crypts/params.py +19 -0
- encommon/{crypt/test/test_crypt.py → crypts/test/test_crypts.py} +21 -21
- encommon/{crypt → crypts}/test/test_hashes.py +2 -2
- encommon/times/parse.py +1 -1
- encommon/version.txt +1 -1
- {encommon-1.1.0.dist-info → encommon-2.0.0.dist-info}/METADATA +4 -3
- {encommon-1.1.0.dist-info → encommon-2.0.0.dist-info}/RECORD +28 -26
- /encommon/{crypt → crypts}/hashes.py +0 -0
- /encommon/{crypt → crypts}/test/__init__.py +0 -0
- {encommon-1.1.0.dist-info → encommon-2.0.0.dist-info}/LICENSE +0 -0
- {encommon-1.1.0.dist-info → encommon-2.0.0.dist-info}/WHEEL +0 -0
- {encommon-1.1.0.dist-info → encommon-2.0.0.dist-info}/top_level.txt +0 -0
    
        encommon/config/__init__.py
    CHANGED
    
    | @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            """
         | 
| 2 2 | 
             
            Functions and routines associated with Enasis Network Common Library.
         | 
| 3 3 |  | 
| 4 | 
            -
            This file is part of Enasis Network software eco-system. Distribution | 
| 5 | 
            -
            permitted, for more information consult the project license file.
         | 
| 4 | 
            +
            This file is part of Enasis Network software eco-system. Distribution
         | 
| 5 | 
            +
            is permitted, for more information consult the project license file.
         | 
| 6 6 | 
             
            """
         | 
| 7 7 |  | 
| 8 8 |  | 
    
        encommon/config/common.py
    CHANGED
    
    | @@ -1,14 +1,15 @@ | |
| 1 1 | 
             
            """
         | 
| 2 2 | 
             
            Functions and routines associated with Enasis Network Common Library.
         | 
| 3 3 |  | 
| 4 | 
            -
            This file is part of Enasis Network software eco-system. Distribution | 
| 5 | 
            -
            permitted, for more information consult the project license file.
         | 
| 4 | 
            +
            This file is part of Enasis Network software eco-system. Distribution
         | 
| 5 | 
            +
            is permitted, for more information consult the project license file.
         | 
| 6 6 | 
             
            """
         | 
| 7 7 |  | 
| 8 8 |  | 
| 9 9 |  | 
| 10 10 | 
             
            from pathlib import Path
         | 
| 11 11 | 
             
            from typing import Any
         | 
| 12 | 
            +
            from typing import Literal
         | 
| 12 13 | 
             
            from typing import Optional
         | 
| 13 14 |  | 
| 14 15 | 
             
            from yaml import SafeLoader
         | 
| @@ -22,6 +23,15 @@ from ..utils.paths import resolve_paths | |
| 22 23 |  | 
| 23 24 |  | 
| 24 25 |  | 
| 26 | 
            +
            LOGLEVELS = Literal[
         | 
| 27 | 
            +
                'critical',
         | 
| 28 | 
            +
                'debug',
         | 
| 29 | 
            +
                'error',
         | 
| 30 | 
            +
                'info',
         | 
| 31 | 
            +
                'warning']
         | 
| 32 | 
            +
             | 
| 33 | 
            +
             | 
| 34 | 
            +
             | 
| 25 35 | 
             
            def config_load(
         | 
| 26 36 | 
             
                path: str | Path,
         | 
| 27 37 | 
             
            ) -> dict[str, Any]:
         | 
    
        encommon/config/config.py
    CHANGED
    
    | @@ -1,19 +1,23 @@ | |
| 1 1 | 
             
            """
         | 
| 2 2 | 
             
            Functions and routines associated with Enasis Network Common Library.
         | 
| 3 3 |  | 
| 4 | 
            -
            This file is part of Enasis Network software eco-system. Distribution | 
| 5 | 
            -
            permitted, for more information consult the project license file.
         | 
| 4 | 
            +
            This file is part of Enasis Network software eco-system. Distribution
         | 
| 5 | 
            +
            is permitted, for more information consult the project license file.
         | 
| 6 6 | 
             
            """
         | 
| 7 7 |  | 
| 8 8 |  | 
| 9 9 |  | 
| 10 10 | 
             
            from copy import deepcopy
         | 
| 11 11 | 
             
            from typing import Any
         | 
| 12 | 
            +
            from typing import Callable
         | 
| 12 13 | 
             
            from typing import Optional
         | 
| 13 14 |  | 
| 15 | 
            +
            from .common import config_paths
         | 
| 14 16 | 
             
            from .files import ConfigFiles
         | 
| 15 17 | 
             
            from .logger import Logger
         | 
| 18 | 
            +
            from .params import ConfigFileParams
         | 
| 16 19 | 
             
            from .paths import ConfigPaths
         | 
| 20 | 
            +
            from ..crypts.crypts import Crypts
         | 
| 17 21 | 
             
            from ..types.dicts import merge_dicts
         | 
| 18 22 | 
             
            from ..utils.common import PATHABLE
         | 
| 19 23 |  | 
| @@ -23,19 +27,27 @@ class Config: | |
| 23 27 | 
             
                """
         | 
| 24 28 | 
             
                Contain the configurations from the arguments and files.
         | 
| 25 29 |  | 
| 30 | 
            +
                .. note::
         | 
| 31 | 
            +
                   Configuration loaded from files is validated with the
         | 
| 32 | 
            +
                   Pydantic model :class:`.ConfigFileParams`.
         | 
| 33 | 
            +
             | 
| 26 34 | 
             
                :param files: Complete or relative path to config files.
         | 
| 27 35 | 
             
                :param paths: Complete or relative path to config paths.
         | 
| 28 36 | 
             
                :param cargs: Configuration arguments in dictionary form,
         | 
| 29 37 | 
             
                    which will override contents from the config files.
         | 
| 38 | 
            +
                :param model: Override default config validation model.
         | 
| 30 39 | 
             
                """
         | 
| 31 40 |  | 
| 32 41 | 
             
                __files: ConfigFiles
         | 
| 33 42 | 
             
                __paths: ConfigPaths
         | 
| 34 43 | 
             
                __cargs: dict[str, Any]
         | 
| 35 44 |  | 
| 45 | 
            +
                __model: Callable  # type: ignore
         | 
| 46 | 
            +
             | 
| 36 47 | 
             
                __config: Optional[dict[str, Any]]
         | 
| 37 48 | 
             
                __merged: Optional[dict[str, Any]]
         | 
| 38 49 | 
             
                __logger: Optional[Logger]
         | 
| 50 | 
            +
                __crypts: Optional[Crypts]
         | 
| 39 51 |  | 
| 40 52 |  | 
| 41 53 | 
             
                def __init__(
         | 
| @@ -44,6 +56,7 @@ class Config: | |
| 44 56 | 
             
                    files: Optional[PATHABLE] = None,
         | 
| 45 57 | 
             
                    paths: Optional[PATHABLE] = None,
         | 
| 46 58 | 
             
                    cargs: Optional[dict[str, Any]] = None,
         | 
| 59 | 
            +
                    model: Optional[Callable] = None,  # type: ignore
         | 
| 47 60 | 
             
                ) -> None:
         | 
| 48 61 | 
             
                    """
         | 
| 49 62 | 
             
                    Initialize instance for class using provided parameters.
         | 
| @@ -53,13 +66,26 @@ class Config: | |
| 53 66 | 
             
                    paths = paths or []
         | 
| 54 67 | 
             
                    cargs = cargs or {}
         | 
| 55 68 |  | 
| 69 | 
            +
                    paths = list(config_paths(paths))
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                    self.__model = (
         | 
| 72 | 
            +
                        model or ConfigFileParams)
         | 
| 73 | 
            +
             | 
| 56 74 | 
             
                    self.__files = ConfigFiles(files)
         | 
| 57 75 | 
             
                    self.__cargs = deepcopy(cargs)
         | 
| 58 | 
            -
                    self.__paths = ConfigPaths(paths)
         | 
| 59 76 |  | 
| 60 77 | 
             
                    self.__config = None
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                    enconfig = self.config['enconfig']
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                    if enconfig['paths']:
         | 
| 82 | 
            +
                        paths.extend(enconfig['paths'])
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                    self.__paths = ConfigPaths(paths)
         | 
| 85 | 
            +
             | 
| 61 86 | 
             
                    self.__merged = None
         | 
| 62 87 | 
             
                    self.__logger = None
         | 
| 88 | 
            +
                    self.__crypts = None
         | 
| 63 89 |  | 
| 64 90 |  | 
| 65 91 | 
             
                @property
         | 
| @@ -101,6 +127,19 @@ class Config: | |
| 101 127 | 
             
                    return self.__cargs
         | 
| 102 128 |  | 
| 103 129 |  | 
| 130 | 
            +
                @property
         | 
| 131 | 
            +
                def model(
         | 
| 132 | 
            +
                    self,
         | 
| 133 | 
            +
                ) -> Callable:  # type: ignore
         | 
| 134 | 
            +
                    """
         | 
| 135 | 
            +
                    Return the property for attribute from the class instance.
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                    :returns: Property for attribute from the class instance.
         | 
| 138 | 
            +
                    """
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                    return self.__model
         | 
| 141 | 
            +
             | 
| 142 | 
            +
             | 
| 104 143 | 
             
                @property
         | 
| 105 144 | 
             
                def config(
         | 
| 106 145 | 
             
                    self,
         | 
| @@ -138,7 +177,10 @@ class Config: | |
| 138 177 | 
             
                        force=True)
         | 
| 139 178 |  | 
| 140 179 |  | 
| 141 | 
            -
                     | 
| 180 | 
            +
                    config = self.__model(**merged)
         | 
| 181 | 
            +
             | 
| 182 | 
            +
             | 
| 183 | 
            +
                    self.__config = config.model_dump()
         | 
| 142 184 |  | 
| 143 185 | 
             
                    return deepcopy(self.__config)
         | 
| 144 186 |  | 
| @@ -187,11 +229,28 @@ class Config: | |
| 187 229 | 
             
                    if self.__logger is not None:
         | 
| 188 230 | 
             
                        return self.__logger
         | 
| 189 231 |  | 
| 190 | 
            -
                    enlogger =  | 
| 232 | 
            +
                    enlogger = (
         | 
| 233 | 
            +
                        self.config['enlogger'] or {})
         | 
| 191 234 |  | 
| 192 | 
            -
                    self.__logger = Logger(
         | 
| 193 | 
            -
                        stdo_level=enlogger.get('stdo_level'),
         | 
| 194 | 
            -
                        file_level=enlogger.get('file_level'),
         | 
| 195 | 
            -
                        file_path=enlogger.get('file_path'))
         | 
| 235 | 
            +
                    self.__logger = Logger(**enlogger)
         | 
| 196 236 |  | 
| 197 237 | 
             
                    return self.__logger
         | 
| 238 | 
            +
             | 
| 239 | 
            +
             | 
| 240 | 
            +
                @property
         | 
| 241 | 
            +
                def crypts(
         | 
| 242 | 
            +
                    self,
         | 
| 243 | 
            +
                ) -> Crypts:
         | 
| 244 | 
            +
                    """
         | 
| 245 | 
            +
                    Initialize the encryption instance using the parameters.
         | 
| 246 | 
            +
                    """
         | 
| 247 | 
            +
             | 
| 248 | 
            +
                    if self.__crypts is not None:
         | 
| 249 | 
            +
                        return self.__crypts
         | 
| 250 | 
            +
             | 
| 251 | 
            +
                    encrypts = (
         | 
| 252 | 
            +
                        self.config['encrypts'] or {})
         | 
| 253 | 
            +
             | 
| 254 | 
            +
                    self.__crypts = Crypts(**encrypts)
         | 
| 255 | 
            +
             | 
| 256 | 
            +
                    return self.__crypts
         | 
    
        encommon/config/files.py
    CHANGED
    
    | @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            """
         | 
| 2 2 | 
             
            Functions and routines associated with Enasis Network Common Library.
         | 
| 3 3 |  | 
| 4 | 
            -
            This file is part of Enasis Network software eco-system. Distribution | 
| 5 | 
            -
            permitted, for more information consult the project license file.
         | 
| 4 | 
            +
            This file is part of Enasis Network software eco-system. Distribution
         | 
| 5 | 
            +
            is permitted, for more information consult the project license file.
         | 
| 6 6 | 
             
            """
         | 
| 7 7 |  | 
| 8 8 |  | 
    
        encommon/config/logger.py
    CHANGED
    
    | @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            """
         | 
| 2 2 | 
             
            Functions and routines associated with Enasis Network Common Library.
         | 
| 3 3 |  | 
| 4 | 
            -
            This file is part of Enasis Network software eco-system. Distribution | 
| 5 | 
            -
            permitted, for more information consult the project license file.
         | 
| 4 | 
            +
            This file is part of Enasis Network software eco-system. Distribution
         | 
| 5 | 
            +
            is permitted, for more information consult the project license file.
         | 
| 6 6 | 
             
            """
         | 
| 7 7 |  | 
| 8 8 |  | 
| @@ -25,6 +25,7 @@ from typing import Any | |
| 25 25 | 
             
            from typing import Literal
         | 
| 26 26 | 
             
            from typing import Optional
         | 
| 27 27 |  | 
| 28 | 
            +
            from .common import LOGLEVELS
         | 
| 28 29 | 
             
            from .common import config_path
         | 
| 29 30 | 
             
            from ..times.common import PARSABLE
         | 
| 30 31 | 
             
            from ..times.times import Times
         | 
| @@ -36,13 +37,6 @@ from ..utils.stdout import kvpair_ansi | |
| 36 37 | 
             
            LOGGER_FILE = 'encommon.logger.file'
         | 
| 37 38 | 
             
            LOGGER_STDO = 'encommon.logger.stdo'
         | 
| 38 39 |  | 
| 39 | 
            -
            LOGLEVELS = Literal[
         | 
| 40 | 
            -
                'critical',
         | 
| 41 | 
            -
                'debug',
         | 
| 42 | 
            -
                'error',
         | 
| 43 | 
            -
                'info',
         | 
| 44 | 
            -
                'warning']
         | 
| 45 | 
            -
             | 
| 46 40 | 
             
            LOGSEVERS = {
         | 
| 47 41 | 
             
                'critical': int(CRITICAL),
         | 
| 48 42 | 
             
                'debug': int(DEBUG),
         | 
| @@ -0,0 +1,46 @@ | |
| 1 | 
            +
            """
         | 
| 2 | 
            +
            Functions and routines associated with Enasis Network Common Library.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            This file is part of Enasis Network software eco-system. Distribution
         | 
| 5 | 
            +
            is permitted, for more information consult the project license file.
         | 
| 6 | 
            +
            """
         | 
| 7 | 
            +
             | 
| 8 | 
            +
             | 
| 9 | 
            +
             | 
| 10 | 
            +
            from typing import Optional
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            from pydantic import BaseModel
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            from .common import LOGLEVELS
         | 
| 15 | 
            +
            from ..crypts.params import CryptsParams
         | 
| 16 | 
            +
             | 
| 17 | 
            +
             | 
| 18 | 
            +
             | 
| 19 | 
            +
            class ConfigParams(BaseModel):
         | 
| 20 | 
            +
                """
         | 
| 21 | 
            +
                Process and validate the common configuration parameters.
         | 
| 22 | 
            +
                """
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                paths: Optional[list[str]] = None
         | 
| 25 | 
            +
             | 
| 26 | 
            +
             | 
| 27 | 
            +
             | 
| 28 | 
            +
            class LoggerParams(BaseModel):
         | 
| 29 | 
            +
                """
         | 
| 30 | 
            +
                Process and validate the common configuration parameters.
         | 
| 31 | 
            +
                """
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                stdo_level: Optional[LOGLEVELS] = None
         | 
| 34 | 
            +
                file_level: Optional[LOGLEVELS] = None
         | 
| 35 | 
            +
                file_path: Optional[str] = None
         | 
| 36 | 
            +
             | 
| 37 | 
            +
             | 
| 38 | 
            +
             | 
| 39 | 
            +
            class ConfigFileParams(BaseModel):
         | 
| 40 | 
            +
                """
         | 
| 41 | 
            +
                Process and validate the common configuration parameters.
         | 
| 42 | 
            +
                """
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                enconfig: Optional[ConfigParams] = None
         | 
| 45 | 
            +
                enlogger: Optional[LoggerParams] = None
         | 
| 46 | 
            +
                encrypts: Optional[CryptsParams] = None
         | 
    
        encommon/config/paths.py
    CHANGED
    
    | @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            """
         | 
| 2 2 | 
             
            Functions and routines associated with Enasis Network Common Library.
         | 
| 3 3 |  | 
| 4 | 
            -
            This file is part of Enasis Network software eco-system. Distribution | 
| 5 | 
            -
            permitted, for more information consult the project license file.
         | 
| 4 | 
            +
            This file is part of Enasis Network software eco-system. Distribution
         | 
| 5 | 
            +
            is permitted, for more information consult the project license file.
         | 
| 6 6 | 
             
            """
         | 
| 7 7 |  | 
| 8 8 |  | 
    
        encommon/config/test/__init__.py
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            """
         | 
| 2 2 | 
             
            Functions and routines associated with Enasis Network Common Library.
         | 
| 3 3 |  | 
| 4 | 
            -
            This file is part of Enasis Network software eco-system. Distribution | 
| 5 | 
            -
            permitted, for more information consult the project license file.
         | 
| 4 | 
            +
            This file is part of Enasis Network software eco-system. Distribution
         | 
| 5 | 
            +
            is permitted, for more information consult the project license file.
         | 
| 6 6 | 
             
            """
         | 
| @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            """
         | 
| 2 2 | 
             
            Functions and routines associated with Enasis Network Common Library.
         | 
| 3 3 |  | 
| 4 | 
            -
            This file is part of Enasis Network software eco-system. Distribution | 
| 5 | 
            -
            permitted, for more information consult the project license file.
         | 
| 4 | 
            +
            This file is part of Enasis Network software eco-system. Distribution
         | 
| 5 | 
            +
            is permitted, for more information consult the project license file.
         | 
| 6 6 | 
             
            """
         | 
| 7 7 |  | 
| 8 8 |  | 
| @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            """
         | 
| 2 2 | 
             
            Functions and routines associated with Enasis Network Common Library.
         | 
| 3 3 |  | 
| 4 | 
            -
            This file is part of Enasis Network software eco-system. Distribution | 
| 5 | 
            -
            permitted, for more information consult the project license file.
         | 
| 4 | 
            +
            This file is part of Enasis Network software eco-system. Distribution
         | 
| 5 | 
            +
            is permitted, for more information consult the project license file.
         | 
| 6 6 | 
             
            """
         | 
| 7 7 |  | 
| 8 8 |  | 
| @@ -12,6 +12,7 @@ from pathlib import Path | |
| 12 12 | 
             
            from ..config import Config
         | 
| 13 13 | 
             
            from ..logger import Logger
         | 
| 14 14 | 
             
            from ... import ENPYRWS
         | 
| 15 | 
            +
            from ...crypts.crypts import Crypts
         | 
| 15 16 | 
             
            from ...utils.sample import load_sample
         | 
| 16 17 | 
             
            from ...utils.sample import prep_sample
         | 
| 17 18 |  | 
| @@ -37,29 +38,40 @@ def test_Config(  # noqa: CFQ001 | |
| 37 38 | 
             
                (config_path
         | 
| 38 39 | 
             
                    .joinpath('one.yml')
         | 
| 39 40 | 
             
                    .write_text(
         | 
| 40 | 
            -
                        ' | 
| 41 | 
            +
                        'enconfig:\n'
         | 
| 42 | 
            +
                        f'  paths: ["{config_path}"]\n'
         | 
| 43 | 
            +
                        'enlogger:\n'
         | 
| 44 | 
            +
                        '  stdo_level: info\n'))
         | 
| 41 45 |  | 
| 42 46 | 
             
                (config_path
         | 
| 43 47 | 
             
                    .joinpath('two.yml')
         | 
| 44 48 | 
             
                    .write_text(
         | 
| 45 | 
            -
                        ' | 
| 46 | 
            -
                        ' | 
| 49 | 
            +
                        'encrypts:\n'
         | 
| 50 | 
            +
                        '  phrases:\n'
         | 
| 51 | 
            +
                        '    default: fernetpassphrase\n'
         | 
| 52 | 
            +
                        'enlogger:\n'
         | 
| 53 | 
            +
                        '  stdo_level: debug\n'
         | 
| 54 | 
            +
                        '  file_level: info\n'))
         | 
| 47 55 |  | 
| 48 56 |  | 
| 49 57 | 
             
                config = Config(
         | 
| 50 58 | 
             
                    files=[
         | 
| 51 59 | 
             
                        f'{config_path}/one.yml',
         | 
| 52 60 | 
             
                        f'{config_path}/two.yml'],
         | 
| 53 | 
            -
                     | 
| 54 | 
            -
             | 
| 61 | 
            +
                    cargs={
         | 
| 62 | 
            +
                        'enlogger': {
         | 
| 63 | 
            +
                            'file_level': 'warning'}})
         | 
| 55 64 |  | 
| 56 | 
            -
                assert len(config.__dict__) ==  | 
| 65 | 
            +
                assert len(config.__dict__) == 8
         | 
| 57 66 |  | 
| 58 67 | 
             
                assert hasattr(config, '_Config__files')
         | 
| 59 68 | 
             
                assert hasattr(config, '_Config__paths')
         | 
| 60 69 | 
             
                assert hasattr(config, '_Config__cargs')
         | 
| 70 | 
            +
                assert hasattr(config, '_Config__model')
         | 
| 61 71 | 
             
                assert hasattr(config, '_Config__config')
         | 
| 62 72 | 
             
                assert hasattr(config, '_Config__merged')
         | 
| 73 | 
            +
                assert hasattr(config, '_Config__logger')
         | 
| 74 | 
            +
                assert hasattr(config, '_Config__crypts')
         | 
| 63 75 |  | 
| 64 76 |  | 
| 65 77 | 
             
                assert list(config.files.paths) == [
         | 
| @@ -70,10 +82,13 @@ def test_Config(  # noqa: CFQ001 | |
| 70 82 | 
             
                    Path(f'{config_path}')]
         | 
| 71 83 |  | 
| 72 84 | 
             
                assert config.cargs == {
         | 
| 73 | 
            -
                    ' | 
| 85 | 
            +
                    'enlogger': {
         | 
| 86 | 
            +
                        'file_level': 'warning'}}
         | 
| 74 87 |  | 
| 88 | 
            +
                assert hasattr(config.model, 'model_dump')
         | 
| 75 89 |  | 
| 76 | 
            -
             | 
| 90 | 
            +
             | 
| 91 | 
            +
                assert len(config.config) == 3
         | 
| 77 92 |  | 
| 78 93 | 
             
                _config1 = config.config
         | 
| 79 94 | 
             
                _config2 = config.config
         | 
| @@ -135,3 +150,13 @@ def test_Config(  # noqa: CFQ001 | |
| 135 150 | 
             
                _logger2 = config.logger
         | 
| 136 151 |  | 
| 137 152 | 
             
                assert _logger1 is _logger2
         | 
| 153 | 
            +
             | 
| 154 | 
            +
             | 
| 155 | 
            +
                crypts = config.crypts
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                assert isinstance(crypts, Crypts)
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                _crypts1 = config.crypts
         | 
| 160 | 
            +
                _crypts2 = config.crypts
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                assert _crypts1 is _crypts2
         | 
| @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            """
         | 
| 2 2 | 
             
            Functions and routines associated with Enasis Network Common Library.
         | 
| 3 3 |  | 
| 4 | 
            -
            This file is part of Enasis Network software eco-system. Distribution | 
| 5 | 
            -
            permitted, for more information consult the project license file.
         | 
| 4 | 
            +
            This file is part of Enasis Network software eco-system. Distribution
         | 
| 5 | 
            +
            is permitted, for more information consult the project license file.
         | 
| 6 6 | 
             
            """
         | 
| 7 7 |  | 
| 8 8 |  | 
| @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            """
         | 
| 2 2 | 
             
            Functions and routines associated with Enasis Network Common Library.
         | 
| 3 3 |  | 
| 4 | 
            -
            This file is part of Enasis Network software eco-system. Distribution | 
| 5 | 
            -
            permitted, for more information consult the project license file.
         | 
| 4 | 
            +
            This file is part of Enasis Network software eco-system. Distribution
         | 
| 5 | 
            +
            is permitted, for more information consult the project license file.
         | 
| 6 6 | 
             
            """
         | 
| 7 7 |  | 
| 8 8 |  | 
| @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            """
         | 
| 2 2 | 
             
            Functions and routines associated with Enasis Network Common Library.
         | 
| 3 3 |  | 
| 4 | 
            -
            This file is part of Enasis Network software eco-system. Distribution | 
| 5 | 
            -
            permitted, for more information consult the project license file.
         | 
| 4 | 
            +
            This file is part of Enasis Network software eco-system. Distribution
         | 
| 5 | 
            +
            is permitted, for more information consult the project license file.
         | 
| 6 6 | 
             
            """
         | 
| 7 7 |  | 
| 8 8 |  | 
    
        encommon/conftest.py
    CHANGED
    
    | @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            """
         | 
| 2 2 | 
             
            Functions and routines associated with Enasis Network Common Library.
         | 
| 3 3 |  | 
| 4 | 
            -
            This file is part of Enasis Network software eco-system. Distribution | 
| 5 | 
            -
            permitted, for more information consult the project license file.
         | 
| 4 | 
            +
            This file is part of Enasis Network software eco-system. Distribution
         | 
| 5 | 
            +
            is permitted, for more information consult the project license file.
         | 
| 6 6 | 
             
            """
         | 
| 7 7 |  | 
| 8 8 |  | 
| @@ -20,40 +20,40 @@ ENCRYPT = compile( | |
| 20 20 |  | 
| 21 21 |  | 
| 22 22 |  | 
| 23 | 
            -
            class  | 
| 23 | 
            +
            class Crypts:
         | 
| 24 24 | 
             
                """
         | 
| 25 25 | 
             
                Encrypt and decrypt values using passphrase dictionary.
         | 
| 26 26 |  | 
| 27 27 | 
             
                Example
         | 
| 28 28 | 
             
                -------
         | 
| 29 | 
            -
                >>> phrase =  | 
| 30 | 
            -
                >>>  | 
| 31 | 
            -
                >>> encrypt =  | 
| 32 | 
            -
                >>>  | 
| 29 | 
            +
                >>> phrase = Crypts.keygen()
         | 
| 30 | 
            +
                >>> crypts = Crypts({'default': phrase})
         | 
| 31 | 
            +
                >>> encrypt = crypts.encrypt('example')
         | 
| 32 | 
            +
                >>> crypts.decrypt(encrypt)
         | 
| 33 33 | 
             
                'example'
         | 
| 34 34 |  | 
| 35 | 
            -
                :param  | 
| 35 | 
            +
                :param phrases: Passphrases that are used in operations.
         | 
| 36 36 | 
             
                """
         | 
| 37 37 |  | 
| 38 | 
            -
                 | 
| 38 | 
            +
                __phrases: dict[str, str]
         | 
| 39 39 |  | 
| 40 40 |  | 
| 41 41 | 
             
                def __init__(
         | 
| 42 42 | 
             
                    self,
         | 
| 43 | 
            -
                     | 
| 43 | 
            +
                    phrases: dict[str, str],
         | 
| 44 44 | 
             
                ) -> None:
         | 
| 45 45 | 
             
                    """
         | 
| 46 46 | 
             
                    Initialize instance for class using provided parameters.
         | 
| 47 47 | 
             
                    """
         | 
| 48 48 |  | 
| 49 | 
            -
                    if 'default' not in  | 
| 49 | 
            +
                    if 'default' not in phrases:
         | 
| 50 50 | 
             
                        raise ValueError('default')
         | 
| 51 51 |  | 
| 52 | 
            -
                    self. | 
| 52 | 
            +
                    self.__phrases = dict(phrases)
         | 
| 53 53 |  | 
| 54 54 |  | 
| 55 55 | 
             
                @property
         | 
| 56 | 
            -
                def  | 
| 56 | 
            +
                def phrases(
         | 
| 57 57 | 
             
                    self,
         | 
| 58 58 | 
             
                ) -> dict[str, str]:
         | 
| 59 59 | 
             
                    """
         | 
| @@ -62,7 +62,7 @@ class Crypt: | |
| 62 62 | 
             
                    :returns: Property for attribute from the class instance.
         | 
| 63 63 | 
             
                    """
         | 
| 64 64 |  | 
| 65 | 
            -
                    return dict(self. | 
| 65 | 
            +
                    return dict(self.__phrases)
         | 
| 66 66 |  | 
| 67 67 |  | 
| 68 68 | 
             
                def encrypt(
         | 
| @@ -78,7 +78,7 @@ class Crypt: | |
| 78 78 | 
             
                    :returns: Encrypted value using the relevant passphrase.
         | 
| 79 79 | 
             
                    """
         | 
| 80 80 |  | 
| 81 | 
            -
                    phrase = self. | 
| 81 | 
            +
                    phrase = self.__phrases[unique]
         | 
| 82 82 |  | 
| 83 83 | 
             
                    encrypt = (
         | 
| 84 84 | 
             
                        Fernet(phrase)
         | 
| @@ -112,7 +112,7 @@ class Crypt: | |
| 112 112 | 
             
                    if version != '1.0':
         | 
| 113 113 | 
             
                        raise ValueError('version')
         | 
| 114 114 |  | 
| 115 | 
            -
                    phrase = self. | 
| 115 | 
            +
                    phrase = self.__phrases[unique]
         | 
| 116 116 |  | 
| 117 117 | 
             
                    return (
         | 
| 118 118 | 
             
                        Fernet(phrase)
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            """
         | 
| 2 | 
            +
            Functions and routines associated with Enasis Network Common Library.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            This file is part of Enasis Network software eco-system. Distribution
         | 
| 5 | 
            +
            is permitted, for more information consult the project license file.
         | 
| 6 | 
            +
            """
         | 
| 7 | 
            +
             | 
| 8 | 
            +
             | 
| 9 | 
            +
             | 
| 10 | 
            +
            from pydantic import BaseModel
         | 
| 11 | 
            +
             | 
| 12 | 
            +
             | 
| 13 | 
            +
             | 
| 14 | 
            +
            class CryptsParams(BaseModel):
         | 
| 15 | 
            +
                """
         | 
| 16 | 
            +
                Process and validate the common configuration parameters.
         | 
| 17 | 
            +
                """
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                phrases: dict[str, str]
         | 
| @@ -10,37 +10,37 @@ is permitted, for more information consult the project license file. | |
| 10 10 | 
             
            from pytest import mark
         | 
| 11 11 | 
             
            from pytest import raises
         | 
| 12 12 |  | 
| 13 | 
            -
            from .. | 
| 13 | 
            +
            from ..crypts import Crypts
         | 
| 14 14 |  | 
| 15 15 |  | 
| 16 16 |  | 
| 17 17 | 
             
            _PHRASES = {
         | 
| 18 | 
            -
                'default':  | 
| 19 | 
            -
                'secrets':  | 
| 18 | 
            +
                'default': Crypts.keygen(),
         | 
| 19 | 
            +
                'secrets': Crypts.keygen()}
         | 
| 20 20 |  | 
| 21 21 |  | 
| 22 22 |  | 
| 23 | 
            -
            def  | 
| 23 | 
            +
            def test_Crypts() -> None:
         | 
| 24 24 | 
             
                """
         | 
| 25 25 | 
             
                Perform various tests associated with relevant routines.
         | 
| 26 26 | 
             
                """
         | 
| 27 27 |  | 
| 28 28 |  | 
| 29 | 
            -
                 | 
| 29 | 
            +
                crypts = Crypts(_PHRASES)
         | 
| 30 30 |  | 
| 31 | 
            -
                assert len( | 
| 31 | 
            +
                assert len(crypts.__dict__) == 1
         | 
| 32 32 |  | 
| 33 | 
            -
                assert hasattr( | 
| 33 | 
            +
                assert hasattr(crypts, '_Crypts__phrases')
         | 
| 34 34 |  | 
| 35 35 |  | 
| 36 | 
            -
                assert repr( | 
| 37 | 
            -
                    '<encommon. | 
| 36 | 
            +
                assert repr(crypts).startswith(
         | 
| 37 | 
            +
                    '<encommon.crypts.crypts.Crypts')
         | 
| 38 38 |  | 
| 39 | 
            -
                assert str( | 
| 40 | 
            -
                    '<encommon. | 
| 39 | 
            +
                assert str(crypts).startswith(
         | 
| 40 | 
            +
                    '<encommon.crypts.crypts.Crypts')
         | 
| 41 41 |  | 
| 42 42 |  | 
| 43 | 
            -
                assert  | 
| 43 | 
            +
                assert crypts.phrases == _PHRASES
         | 
| 44 44 |  | 
| 45 45 |  | 
| 46 46 |  | 
| @@ -48,7 +48,7 @@ def test_Crypt() -> None: | |
| 48 48 | 
             
                'value,unique',
         | 
| 49 49 | 
             
                [('foo', 'default'),
         | 
| 50 50 | 
             
                 ('foo', 'secrets')])
         | 
| 51 | 
            -
            def  | 
| 51 | 
            +
            def test_Crypts_iterate(
         | 
| 52 52 | 
             
                value: str,
         | 
| 53 53 | 
             
                unique: str,
         | 
| 54 54 | 
             
            ) -> None:
         | 
| @@ -59,43 +59,43 @@ def test_Crypt_iterate( | |
| 59 59 | 
             
                :param unique: Unique identifier of mapping passphrase.
         | 
| 60 60 | 
             
                """
         | 
| 61 61 |  | 
| 62 | 
            -
                 | 
| 62 | 
            +
                crypts = Crypts(_PHRASES)
         | 
| 63 63 |  | 
| 64 | 
            -
                encrypt =  | 
| 64 | 
            +
                encrypt = crypts.encrypt(value, unique)
         | 
| 65 65 |  | 
| 66 66 | 
             
                split = encrypt.split(';')
         | 
| 67 67 |  | 
| 68 68 | 
             
                assert split[1] == '1.0'
         | 
| 69 69 | 
             
                assert split[2] == unique
         | 
| 70 70 |  | 
| 71 | 
            -
                decrypt =  | 
| 71 | 
            +
                decrypt = crypts.decrypt(encrypt)
         | 
| 72 72 |  | 
| 73 73 | 
             
                assert decrypt == value
         | 
| 74 74 |  | 
| 75 75 |  | 
| 76 76 |  | 
| 77 | 
            -
            def  | 
| 77 | 
            +
            def test_Crypts_raises() -> None:
         | 
| 78 78 | 
             
                """
         | 
| 79 79 | 
             
                Perform various tests associated with relevant routines.
         | 
| 80 80 | 
             
                """
         | 
| 81 81 |  | 
| 82 82 |  | 
| 83 83 | 
             
                with raises(ValueError) as reason:
         | 
| 84 | 
            -
                     | 
| 84 | 
            +
                    Crypts({'foo': 'bar'})
         | 
| 85 85 |  | 
| 86 86 | 
             
                assert str(reason.value) == 'default'
         | 
| 87 87 |  | 
| 88 88 |  | 
| 89 | 
            -
                 | 
| 89 | 
            +
                crypts = Crypts(_PHRASES)
         | 
| 90 90 |  | 
| 91 91 |  | 
| 92 92 | 
             
                with raises(ValueError) as reason:
         | 
| 93 | 
            -
                     | 
| 93 | 
            +
                    crypts.decrypt('foo')
         | 
| 94 94 |  | 
| 95 95 | 
             
                assert str(reason.value) == 'string'
         | 
| 96 96 |  | 
| 97 97 |  | 
| 98 98 | 
             
                with raises(ValueError) as reason:
         | 
| 99 | 
            -
                     | 
| 99 | 
            +
                    crypts.decrypt('$ENCRYPT;1.1;f;oo')
         | 
| 100 100 |  | 
| 101 101 | 
             
                assert str(reason.value) == 'version'
         | 
| @@ -25,10 +25,10 @@ def test_Hashes() -> None: | |
| 25 25 |  | 
| 26 26 |  | 
| 27 27 | 
             
                assert repr(hashes).startswith(
         | 
| 28 | 
            -
                    '<encommon. | 
| 28 | 
            +
                    '<encommon.crypts.hashes.Hashes')
         | 
| 29 29 |  | 
| 30 30 | 
             
                assert str(hashes).startswith(
         | 
| 31 | 
            -
                    '<encommon. | 
| 31 | 
            +
                    '<encommon.crypts.hashes.Hashes')
         | 
| 32 32 |  | 
| 33 33 |  | 
| 34 34 | 
             
                assert hashes.string == 'string'
         | 
    
        encommon/times/parse.py
    CHANGED
    
    | @@ -257,7 +257,7 @@ def duration( | |
| 257 257 | 
             
                '1 year, 11 months'
         | 
| 258 258 |  | 
| 259 259 | 
             
                :param seconds: Period in seconds that will be iterated.
         | 
| 260 | 
            -
                :param compact: Determines if output will be  | 
| 260 | 
            +
                :param compact: Determines if output will be condensed.
         | 
| 261 261 | 
             
                :param maximum: Determines how many time units are shown.
         | 
| 262 262 | 
             
                    Default value happens to be same number of time units
         | 
| 263 263 | 
             
                    supported; year, month, week, day, hour, and minute.
         | 
    
        encommon/version.txt
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
             | 
| 1 | 
            +
            2.0.0
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            Metadata-Version: 2.1
         | 
| 2 2 | 
             
            Name: encommon
         | 
| 3 | 
            -
            Version:  | 
| 3 | 
            +
            Version: 2.0.0
         | 
| 4 4 | 
             
            Summary: Enasis Network Common Library
         | 
| 5 5 | 
             
            License: MIT
         | 
| 6 6 | 
             
            Classifier: Programming Language :: Python :: 3
         | 
| @@ -11,6 +11,7 @@ Description-Content-Type: text/markdown | |
| 11 11 | 
             
            License-File: LICENSE
         | 
| 12 12 | 
             
            Requires-Dist: croniter
         | 
| 13 13 | 
             
            Requires-Dist: cryptography
         | 
| 14 | 
            +
            Requires-Dist: pydantic
         | 
| 14 15 | 
             
            Requires-Dist: python-dateutil
         | 
| 15 16 | 
             
            Requires-Dist: pyyaml
         | 
| 16 17 | 
             
            Requires-Dist: snaptime
         | 
| @@ -30,8 +31,8 @@ pip install encommon | |
| 30 31 |  | 
| 31 32 | 
             
            ## Documentation
         | 
| 32 33 | 
             
            Documentation can be found on [Read the Docs](https://encommon.readthedocs.io).
         | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 34 | 
            +
            If you venture into the sections below you will be able to use the `sphinx`
         | 
| 35 | 
            +
            recipe to build the documention in `docs/html` for local consumption.
         | 
| 35 36 |  | 
| 36 37 | 
             
            ## Quick start for local development
         | 
| 37 38 | 
             
            Start by cloning the repository to your local machine.
         | 
| @@ -1,28 +1,30 @@ | |
| 1 1 | 
             
            encommon/__init__.py,sha256=VoXUcphq-gcXCraaU47EtXBftF6UVuQPMGr0fuCTt9A,525
         | 
| 2 | 
            -
            encommon/conftest.py,sha256= | 
| 2 | 
            +
            encommon/conftest.py,sha256=D_8TAxCdBXYyUacz6V5Iovgka7mn7pXH_rBcx8xbLEg,772
         | 
| 3 3 | 
             
            encommon/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 4 | 
            -
            encommon/version.txt,sha256= | 
| 5 | 
            -
            encommon/config/__init__.py,sha256= | 
| 6 | 
            -
            encommon/config/common.py,sha256= | 
| 7 | 
            -
            encommon/config/config.py,sha256= | 
| 8 | 
            -
            encommon/config/files.py,sha256= | 
| 9 | 
            -
            encommon/config/logger.py,sha256= | 
| 10 | 
            -
            encommon/config/ | 
| 11 | 
            -
            encommon/config/ | 
| 12 | 
            -
            encommon/config/test/ | 
| 13 | 
            -
            encommon/config/test/ | 
| 14 | 
            -
            encommon/config/test/ | 
| 15 | 
            -
            encommon/config/test/ | 
| 16 | 
            -
            encommon/config/test/ | 
| 17 | 
            -
            encommon/ | 
| 18 | 
            -
            encommon/ | 
| 19 | 
            -
            encommon/ | 
| 20 | 
            -
            encommon/ | 
| 21 | 
            -
            encommon/ | 
| 22 | 
            -
            encommon/ | 
| 4 | 
            +
            encommon/version.txt,sha256=wo_MpTY3vIjhJK8XJd8Ty5jGne3v1i-zzb4c22t2BiQ,6
         | 
| 5 | 
            +
            encommon/config/__init__.py,sha256=tCvJrBTdtNSyg3sZkwUFQBwtK8QHgxLQl833OxblKAo,469
         | 
| 6 | 
            +
            encommon/config/common.py,sha256=OTmxJhbNA2B9f_fZGQEQPma_zPHeiSDvkd_gEVsLrkE,2081
         | 
| 7 | 
            +
            encommon/config/config.py,sha256=b1TGPxIUdmYmSI4EP425zXzcuBkShBvsqdMiRh9v1PU,5545
         | 
| 8 | 
            +
            encommon/config/files.py,sha256=RlAk9iCH7JNYubDQe7IeenKuPY1l8h-DCPcmw2Qv9fI,1535
         | 
| 9 | 
            +
            encommon/config/logger.py,sha256=2y-VFzgM2pZzEYq48XfvrDPrtUcxyP9QjbH5OG7fv5o,13449
         | 
| 10 | 
            +
            encommon/config/params.py,sha256=iLCigmZKJfXvIclbCBJ2MBsALCeUeUqJwq92hpv4tk0,988
         | 
| 11 | 
            +
            encommon/config/paths.py,sha256=NIt4jQy2SalEXuOyZqSdin_3LzLADsqp44bH8tm8RQU,1729
         | 
| 12 | 
            +
            encommon/config/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv5g,218
         | 
| 13 | 
            +
            encommon/config/test/test_common.py,sha256=U6XWfCLxtLmArn8P6h4cmCALzdXxV7IMUxKNU-UhwPw,731
         | 
| 14 | 
            +
            encommon/config/test/test_config.py,sha256=Zl-bQKS2lGZEWlXna-OdLmxaFHITBfCil5PZl05A21s,3836
         | 
| 15 | 
            +
            encommon/config/test/test_files.py,sha256=KUdPUvDzBPL9jTRTjJ5nRUOti5i8Z_MF1aBTSHUpmLM,1300
         | 
| 16 | 
            +
            encommon/config/test/test_logger.py,sha256=Ya0lVnOB97M6FTRwxbmcKcULUGW_nPt4bLCdSRHbTQI,4366
         | 
| 17 | 
            +
            encommon/config/test/test_paths.py,sha256=SlDJnUeW9JK9Hu3B-QCdHadwPDeqdfzqa-73YYbeefQ,1167
         | 
| 18 | 
            +
            encommon/crypts/__init__.py,sha256=7tNT1KqdYaVTLMKJazQGBULe8RpxD4MJoJi8nGMZixw,318
         | 
| 19 | 
            +
            encommon/crypts/crypts.py,sha256=Av6kb9xSvj8mVMxZW8J_PuzBWV24Rw-fOFR9OKW-oH4,3158
         | 
| 20 | 
            +
            encommon/crypts/hashes.py,sha256=PNw-leN3Mx2U1-aVrjK2ueK3b2qXwwXj4rLEMC85DpY,2797
         | 
| 21 | 
            +
            encommon/crypts/params.py,sha256=EZM_96lZEwQW5Ay5fKkc6FKxVh-sNENaQ_lbDWBXsR0,393
         | 
| 22 | 
            +
            encommon/crypts/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv5g,218
         | 
| 23 | 
            +
            encommon/crypts/test/test_crypts.py,sha256=HE83AgvhgRs0jn75wVvizLYf6VTtyJLjUsYbRePQ37A,1902
         | 
| 24 | 
            +
            encommon/crypts/test/test_hashes.py,sha256=slqATRMWOM91o1I1zXQUGDMqBFuIU2aLPIDe-nKKKAg,1088
         | 
| 23 25 | 
             
            encommon/times/__init__.py,sha256=Yr6rd_bflwOR4XcYkJ3bKKO4HoWI4d8G8PH7eAEfKkc,591
         | 
| 24 26 | 
             
            encommon/times/common.py,sha256=zDI5ztMkfLmV090jlLLK3hFzGGveasy8I_wNfOQDScg,2500
         | 
| 25 | 
            -
            encommon/times/parse.py,sha256= | 
| 27 | 
            +
            encommon/times/parse.py,sha256=ffk-Az5nF24EFE1xbkh9Jp-JjTlTp1hRf8AKTXeZ8pQ,7917
         | 
| 26 28 | 
             
            encommon/times/timer.py,sha256=dsxGgxQ-I75nnwcY9qdxuYD6TdCbhof2KvJuPcatimw,3200
         | 
| 27 29 | 
             
            encommon/times/times.py,sha256=xpaZ1F25VHj6s862doLQWqmPf9yrj1lkN-BILRH3sPw,8947
         | 
| 28 30 | 
             
            encommon/times/window.py,sha256=Fx_OJfU9B0IctCyaJ5XH_HxzhGlzeRATwuhI-HlsTPA,8023
         | 
| @@ -49,8 +51,8 @@ encommon/utils/test/test_paths.py,sha256=ZPU84G_vI13G6t-PtDhM9UG4SHOoF4TiEdqApxt | |
| 49 51 | 
             
            encommon/utils/test/test_regexp.py,sha256=oJglz-8TJiSUtE7NuseFy0dVjau2jR1foEj-ZsBlcek,697
         | 
| 50 52 | 
             
            encommon/utils/test/test_sample.py,sha256=EZnRI27qf7x3s7Xbtkd9t0o_y1xDQB0o2sPxbO0_dDQ,1465
         | 
| 51 53 | 
             
            encommon/utils/test/test_stdout.py,sha256=a060uA8oEHFGoVqdwB5iYxdl4R2TRSgr6Z7pMEbxibs,1675
         | 
| 52 | 
            -
            encommon- | 
| 53 | 
            -
            encommon- | 
| 54 | 
            -
            encommon- | 
| 55 | 
            -
            encommon- | 
| 56 | 
            -
            encommon- | 
| 54 | 
            +
            encommon-2.0.0.dist-info/LICENSE,sha256=04XJC5i4LRUf1A_U1EGCMJLpGodnmOFlh30yu7FAVfs,1071
         | 
| 55 | 
            +
            encommon-2.0.0.dist-info/METADATA,sha256=vHmdrKOuzKSplACFjW9tNIKZcbOWFcKQ638Racl3k0s,2315
         | 
| 56 | 
            +
            encommon-2.0.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
         | 
| 57 | 
            +
            encommon-2.0.0.dist-info/top_level.txt,sha256=bP8q7-5tLDNm-3XPlqn_bDENfYNug5801H_xfz3BEAM,9
         | 
| 58 | 
            +
            encommon-2.0.0.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         |