Passed
Push — main ( b312d0...29adcf )
by Douglas
01:37
created

pocketutils.core._internal   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 132
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 87
dl 0
loc 132
rs 10
c 0
b 0
f 0
wmc 21

3 Functions

Rating   Name   Duplication   Size   Complexity  
A nicesize() 0 22 4
C look() 0 20 10
A null_context() 0 2 1

3 Methods

Rating   Name   Duplication   Size   Complexity  
A PathLikeUtils.isinstance() 0 4 1
A Pretty.expanded() 0 25 3
A Pretty.condensed() 0 17 2
1
from __future__ import annotations
0 ignored issues
show
introduced by
Missing module docstring
Loading history...
2
3
import logging
4
import operator
5
import os
6
import sys
7
from pathlib import PurePath
8
from typing import Any, Callable, Iterable, Optional, TypeVar, Union
9
10
T = TypeVar("T", covariant=True)
0 ignored issues
show
Coding Style Naming introduced by
Class name "T" doesn't conform to PascalCase naming style ('[^\\W\\da-z][^\\W_]+$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
11
Y = TypeVar("Y")
0 ignored issues
show
Coding Style Naming introduced by
Class name "Y" doesn't conform to PascalCase naming style ('[^\\W\\da-z][^\\W_]+$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
12
Z = TypeVar("Z")
0 ignored issues
show
Coding Style Naming introduced by
Class name "Z" doesn't conform to PascalCase naming style ('[^\\W\\da-z][^\\W_]+$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
13
logger = logging.getLogger("pocketutils")
14
15
PathLike = Union[str, PurePath, os.PathLike]
16
17
18
class PathLikeUtils:
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
19
    @classmethod
20
    def isinstance(cls, value: Any):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
21
        return (
22
            isinstance(value, str) or isinstance(value, os.PathLike) or isinstance(value, PurePath)
0 ignored issues
show
Unused Code introduced by
Consider merging these isinstance calls to isinstance(value, (PurePath, os.PathLike, str))
Loading history...
23
        )
24
25
26
if sys.version_info < (3, 9):
27
    # TODO remove both of these on 0.5 release, breaking backwards-compat
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
28
    # This breaks on Python 3.9
29
    # https://github.com/dmyersturnbull/pocketutils/issues/2
30
    PathLike.isinstance = PathLikeUtils.isinstance
31
    # and this just provides backwards-compat until 0.5 release
32
    pathlike_isinstance = PathLikeUtils.isinstance
33
34
35
class Pretty:
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
36
    @classmethod
37
    def condensed(cls, item, depth=1):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
38
        if isinstance(item, dict):
0 ignored issues
show
unused-code introduced by
Unnecessary "else" after "return"
Loading history...
39
            return (
40
                "{\n"
41
                + "\n".join(
42
                    [
43
                        "\t" * (depth + 1) + k + " = " + cls.condensed(v, depth + 1)
44
                        for k, v in item.items()
45
                    ]
46
                )
47
                + "\n"
48
                + "\t" * depth
49
                + "}"
50
            )
51
        else:
52
            return str(item)
53
54
    @classmethod
55
    def expanded(cls, item, depth=1):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
56
        if isinstance(item, dict):
0 ignored issues
show
unused-code introduced by
Unnecessary "elif" after "return"
Loading history...
57
            return (
58
                "{\n"
59
                + "\n".join(
60
                    [
61
                        "\t" * (depth + 1) + k + " = " + cls.expanded(v, depth + 1)
62
                        for k, v in item.items()
63
                    ]
64
                )
65
                + "\n"
66
                + "\t" * depth
67
                + "}"
68
            )
69
        elif isinstance(item, (list, set)):
70
            return (
71
                "[\n"
72
                + "\n".join(["\t" * (depth + 1) + cls.expanded(v, depth + 1) for v in item])
73
                + "\n"
74
                + "\t" * depth
75
                + "]"
76
            )
77
        else:
78
            return str(item)
79
80
81
def nicesize(nbytes: int, space: str = "") -> str:
82
    """
83
    Uses IEC 1998 units, such as KiB (1024).
84
        nbytes: Number of bytes
85
        space: Separator between digits and units
86
87
        Returns:
88
            Formatted string
89
    """
90
    data = {
91
        "PiB": 1024 ** 5,
92
        "TiB": 1024 ** 4,
93
        "GiB": 1024 ** 3,
94
        "MiB": 1024 ** 2,
95
        "KiB": 1024 ** 1,
96
    }
97
    for suffix, scale in data.items():
98
        if nbytes >= scale:
99
            break
100
    else:
101
        scale, suffix = 1, "B"
102
    return str(nbytes // scale) + space + suffix
103
104
105
def look(obj: Y, attrs: Union[str, Iterable[str], Callable[[Y], Z]]) -> Optional[Z]:
106
    """
107
    See VeryCommonTools.look.
108
    """
109
    if attrs is None:
110
        return obj
111
    if not isinstance(attrs, str) and hasattr(attrs, "__len__") and len(attrs) == 0:
112
        return obj
113
    if isinstance(attrs, str):
114
        attrs = operator.attrgetter(attrs)
115
    elif isinstance(attrs, Iterable) and all((isinstance(a, str) for a in attrs)):
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable a does not seem to be defined.
Loading history...
introduced by
Second argument of isinstance is not a type
Loading history...
116
        attrs = operator.attrgetter(".".join(attrs))
117
    elif not callable(attrs):
118
        raise TypeError(
119
            f"Type {type(attrs)} unrecognized for key/attrib. Must be a function, string, or sequence of strings"
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (113/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
120
        )
121
    try:
122
        return attrs(obj)
123
    except AttributeError:
124
        return None
125
126
127
def null_context():
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
128
    yield
129
130
131
__all__ = ["nicesize", "look", "logger", "Pretty", "PathLike", "PathLikeUtils"]
132