Passed
Pull Request — master (#1063)
by Konstantin
03:13
created

ocrd_utils.introspect.resource_string()   A

Complexity

Conditions 2

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 2
nop 2
1
"""
2
Utility functions to simplify access to data structures.
3
"""
4
import json
5
from functools import wraps
6
from pathlib import Path
7
from frozendict import frozendict
8
import atexit
9
from contextlib import ExitStack
10
11
# cannot use importlib.resources until we move to 3.9+ forimportlib.resources.files
12
import sys
13
if sys.version_info < (3, 9):
14
    import importlib_resources
15
else:
16
    import importlib.resources as importlib_resources
17
18
if sys.version_info < (3, 8):
19
    import importlib_metadata
20
else:
21
    import importlib.metadata as importlib_metadata
22
23
file_manager = ExitStack()
24
atexit.register(file_manager.close)
25
26
# Taken from https://github.com/OCR-D/core/pull/884
27
def freeze_args(func):
28
    """
29
    Transform mutable dictionary into immutable. Useful to be compatible with cache.
30
    Code taken from `this post <https://stackoverflow.com/a/53394430/1814420>`_
31
    """
32
    @wraps(func)
33
    def wrapped(*args, **kwargs):
34
        args = tuple([frozendict(arg) if isinstance(arg, dict) else arg for arg in args])
35
        kwargs = {k: frozendict(v) if isinstance(v, dict) else v for k, v in kwargs.items()}
36
        return func(*args, **kwargs)
37
    return wrapped
38
39
40
def membername(class_, val):
41
    """Convert a member variable/constant into a member name string."""
42
    return next((k for k, v in class_.__dict__.items() if v == val), str(val))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable k does not seem to be defined.
Loading history...
43
44
def set_json_key_value_overrides(obj, *kvpairs):
45
    for kv in kvpairs:
46
        k, v = kv
47
        try:
48
            obj[k] = json.loads(v)
49
        except json.decoder.JSONDecodeError:
50
            obj[k] = v
51
    return obj
52
53
def resource_filename(pkg : str, fname : str) -> Path:
54
    ref = importlib_resources.files(pkg) / fname
55
    return file_manager.enter_context(importlib_resources.as_file(ref))
56
57
def resource_string(pkg : str, fname : str) -> str:
58
    with open(resource_filename(pkg, fname), 'r', encoding='utf-8') as f:
59
        return f.read()
60
61
def dist_version(module : str) -> str:
62
    return importlib_metadata.version(module)
63