File: util.py

package info (click to toggle)
python-pyinstrument 5.1.1%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,624 kB
  • sloc: python: 6,713; ansic: 897; makefile: 46; sh: 26; javascript: 18
file content (110 lines) | stat: -rw-r--r-- 2,964 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import codecs
import importlib
import math
import os
import re
import sys
import warnings
from typing import IO, Any, AnyStr, Callable

from pyinstrument.vendor.decorator import decorator


def object_with_import_path(import_path: str) -> Any:
    if "." not in import_path:
        raise ValueError("Can't import '%s', it is not a valid import path" % import_path)
    module_path, object_name = import_path.rsplit(".", 1)

    module = importlib.import_module(module_path)
    return getattr(module, object_name)


def truncate(string: str, max_length: int) -> str:
    if len(string) > max_length:
        return string[0 : max_length - 3] + "..."
    return string


@decorator
def deprecated(func: Callable[..., Any], *args: Any, **kwargs: Any) -> Any:
    """Marks a function as deprecated."""
    warnings.warn(
        f"{func} is deprecated and should no longer be used.",
        DeprecationWarning,
        stacklevel=3,
    )
    return func(*args, **kwargs)


def deprecated_option(option_name: str, message: str = "") -> Any:
    """Marks an option as deprecated."""

    def caller(func, *args, **kwargs):
        if option_name in kwargs:
            warnings.warn(
                f"{option_name} is deprecated. {message}",
                DeprecationWarning,
                stacklevel=3,
            )

        return func(*args, **kwargs)

    return decorator(caller)


def file_supports_color(file_obj: IO[AnyStr]) -> bool:
    """
    Returns True if the running system's terminal supports color.

    Borrowed from Django
    https://github.com/django/django/blob/master/django/core/management/color.py
    """
    plat = sys.platform
    supported_platform = plat != "Pocket PC" and (plat != "win32" or "ANSICON" in os.environ)

    is_a_tty = file_is_a_tty(file_obj)

    return supported_platform and is_a_tty


def file_supports_unicode(file_obj: IO[AnyStr]) -> bool:
    encoding = getattr(file_obj, "encoding", None)
    if not encoding:
        return False

    codec_info = codecs.lookup(encoding)

    return "utf" in codec_info.name


def file_is_a_tty(file_obj: IO[AnyStr]) -> bool:
    return hasattr(file_obj, "isatty") and file_obj.isatty()


def unwrap(string: str) -> str:
    string = string.replace("\n", " ")
    string = re.sub(r"\s+", " ", string)
    return string.strip()


def format_float_with_sig_figs(value: float, sig_figs: int = 3, trim_zeroes=False) -> str:
    """
    Format a float to a string with a specific number of significant figures.
    Doesn't use scientific notation.
    """
    if value == 0:
        return "0"

    precision = math.ceil(-math.log10(abs(value))) + sig_figs - 1
    if precision < 0:
        precision = 0
    result = "{:.{precision}f}".format(value, precision=precision)

    if trim_zeroes and "." in result:
        result = result.rstrip("0").rstrip(".")

    return result


def strtobool(val: str) -> bool:
    return val.lower() in {"y", "yes", "t", "true", "on", "1"}