Passed
Push — main ( 60119b...e5c7f7 )
by Douglas
02:02
created

pocketutils.misc.magic_template   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 108
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 82
dl 0
loc 108
rs 9.84
c 0
b 0
f 0
wmc 32

10 Methods

Rating   Name   Duplication   Size   Complexity  
A MagicTemplate.add() 0 3 1
A MagicTemplate.register_magic() 0 6 2
A MagicTemplate.__init__() 0 4 1
D MagicTemplate.add_datetime() 0 29 13
A MagicTemplate.parse() 0 2 1
A MagicTemplate.add_version() 0 10 3
A MagicTemplate._fill() 0 7 2
A MagicTemplate.__replace() 0 13 5
A MagicTemplate.from_text() 0 3 2
A MagicTemplate.from_path() 0 4 2
1
from __future__ import annotations
0 ignored issues
show
introduced by
Missing module docstring
Loading history...
2
3
import logging
4
from datetime import datetime
5
from pathlib import Path
6
from typing import Any, Callable, Optional, Union
7
8
from pocketutils.core import LazyWrap, PathLike
9
10
logger = logging.getLogger("pocketutils")
11
12
13
class MagicTemplate:
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
14
    @classmethod
15
    def from_path(cls, path: PathLike, *, prefix: str = "${{", suffix: str = "}}") -> __qualname__:
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable '__qualname__'
Loading history...
introduced by
Missing function or method docstring
Loading history...
16
        return MagicTemplate(
17
            reader=lambda: Path(path).read_text(encoding="utf8"), prefix=prefix, suffix=suffix
18
        )
19
20
    @classmethod
21
    def from_text(cls, text: str, *, prefix: str = "${{", suffix: str = "}}") -> __qualname__:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
22
        return MagicTemplate(reader=lambda: text, prefix=prefix, suffix=suffix)
23
24
    def __init__(self, *, reader: Callable[[], str], prefix: str = "${{", suffix: str = "}}"):
25
        self._reader = reader
26
        self._entries = {}
27
        self._prefix, self._suffix = prefix, suffix
28
29
    def add(self, key: str, value: Union[Any, Callable[[str], str]]) -> __qualname__:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
30
        self._entries[key] = value
31
        return self
32
33
    def add_version(self, semantic_version: str) -> __qualname__:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
34
        self._entries.update(
35
            {
36
                "version": semantic_version,
37
                "major": semantic_version.split(".")[0],
38
                "minor": semantic_version.split(".")[1] if semantic_version.count(".") > 0 else "-",
39
                "patch": semantic_version.split(".")[2] if semantic_version.count(".") > 1 else "-",
40
            }
41
        )
42
        return self
43
44
    def add_datetime(self, at: Optional[datetime] = None) -> __qualname__:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
Coding Style Naming introduced by
Argument name "at" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' 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...
45
        if at is None:
46
            now = LazyWrap.new_type("datetime", datetime.now)()
47
        else:
48
            now = LazyWrap.new_type("datetime", lambda: at)()
49
        self._entries.update(
50
            {
51
                "year": lambda _: str(now.get().year),
52
                "month": lambda _: str(now.get().month),
53
                "day": lambda _: str(now.get().day),
54
                "hour": lambda _: str(now.get().hour),
55
                "minute": lambda _: str(now.get().minute),
56
                "second": lambda _: str(now.get().second),
57
                "datestr": lambda _: str(now.get().date()),
58
                "timestr": lambda _: str(now.get().time()),
59
                "datetuple": lambda _: str((now.get().year, now.get().month, now.get().day)),
60
                "datetime": lambda _: str(
61
                    (
62
                        now.get().year,
63
                        now.get().month,
64
                        now.get().day,
65
                        now.get().hour,
66
                        now.get().minute,
67
                        now.get().second,
68
                    )
69
                ),
70
            }
71
        )
72
        return self
73
74
    def register_magic(self, name: str, shell=None) -> None:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
75
        if shell is None:
76
            from IPython import get_ipython
0 ignored issues
show
introduced by
Unable to import 'IPython'
Loading history...
introduced by
Import outside toplevel (IPython.get_ipython)
Loading history...
77
78
            shell = get_ipython()
79
        shell.register_magic_function(self._fill, magic_kind="line_cell", magic_name=name)
80
81
    def parse(self, line: str = "") -> str:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
82
        return self.__replace(self._reader(), line)
83
84
    def _fill(self, line, shell=None):
85
        if shell is None:
86
            from IPython import get_ipython
0 ignored issues
show
introduced by
Unable to import 'IPython'
Loading history...
introduced by
Import outside toplevel (IPython.get_ipython)
Loading history...
87
88
            shell = get_ipython()
89
        text = self.__replace(self._reader(), line)
90
        shell.set_next_input(text, replace=True)
91
92
    def __replace(self, r: str, line: str):
0 ignored issues
show
Coding Style Naming introduced by
Argument name "r" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' 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...
93
        for k, v in self._entries.items():
0 ignored issues
show
Coding Style Naming introduced by
Variable name "v" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' 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...
94
            k = self._prefix + k + self._suffix
95
            if k in r:
96
                try:
97
                    if callable(v):
98
                        r = r.replace(k, v(line))
99
                    else:
100
                        r = r.replace(k, str(v))
101
                except Exception:
102
                    logger.error(f"Failed replacing {k}")
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
103
                    raise
104
        return r
105
106
107
__all__ = ["MagicTemplate"]
108