Completed
Push — master ( ef7389...74fe88 )
by Satoru
01:52
created

find_processor()   B

Complexity

Conditions 8

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
dl 0
loc 28
rs 7.3333
c 0
b 0
f 0
1
#
2
# Copyright (C) 2018 Satoru SATOH <ssato @ redhat.com>
3
# License: MIT
4
#
5
# pylint: disable=invalid-name
6
r"""Functions for value objects represent inputs and outputs.
7
8
.. versionadded:: 0.9.5
9
10
- Add functions to make and process input and output object holding some
11
  attributes like input and output type (path, stream or pathlib.Path object),
12
  path, opener, etc.
13
"""
14
from __future__ import absolute_import
15
16
import anyconfig.processors
17
import anyconfig.utils
18
19
from anyconfig.globals import (
20
    IOInfo, IOI_NONE, IOI_PATH_STR, IOI_PATH_OBJ, IOI_STREAM,
21
    UnknownFileTypeError
22
)
23
24
25
def guess_io_type(obj):
26
    """Guess input or output type of ``obj``.
27
28
    :param obj: a path string, a pathlib.Path or a file / file-like object
29
    :return: IOInfo type defined in anyconfig.globals.IOI_TYPES
30
31
    >>> apath = "/path/to/a_conf.ext"
32
    >>> assert guess_io_type(apath) == IOI_PATH_STR
33
34
    >>> from anyconfig.compat import pathlib
35
    >>> if pathlib is not None:
36
    ...     assert guess_io_type(pathlib.Path(apath)) == IOI_PATH_OBJ
37
    >>> assert guess_io_type(open(__file__)) == IOI_STREAM
38
    """
39
    if obj is None:
40
        return IOI_NONE
41
    elif anyconfig.utils.is_path(obj):
42
        return IOI_PATH_STR
43
    elif anyconfig.utils.is_path_obj(obj):
44
        return IOI_PATH_OBJ
45
46
    return IOI_STREAM
47
48
49
def inspect_io_obj(obj):
50
    """
51
    :param obj: a path string, a pathlib.Path or a file / file-like object
52
53
    :return: A tuple of (objtype, objpath, objopener)
54
    :raises: UnknownFileTypeError
55
    """
56
    itype = guess_io_type(obj)
57
58
    if itype == IOI_PATH_STR:
59
        ipath = anyconfig.utils.normpath(obj)
60
        opener = open
61
    elif itype == IOI_PATH_OBJ:
62
        ipath = anyconfig.utils.normpath(obj.as_posix())
63
        opener = obj.open
64
    elif itype == IOI_STREAM:
65
        ipath = anyconfig.utils.get_path_from_stream(obj)
66
        opener = anyconfig.utils.noop
67
    elif itype == IOI_NONE:
68
        ipath = None
69
        opener = anyconfig.utils.noop
70
    else:
71
        raise UnknownFileTypeError("%r" % obj)
72
73
    return (itype, ipath, opener)
74
75
76
def make(obj, prs, forced_type=None):
77
    """
78
    :param obj: a path string, a pathlib.Path or a file / file-like object
79
    :param prs: A list of processor classes
80
    :param forced_type: Forced processor type or processor object
81
82
    :return:
83
        Namedtuple object represents a kind of input object such as a file /
84
        file-like object, path string or pathlib.Path object
85
86
    :raises: ValueError, UnknownProcessorTypeError, UnknownFileTypeError
87
    """
88
    if anyconfig.utils.is_ioinfo(obj):
89
        return obj
90
91
    if (obj is None or not obj) and forced_type is None:
92
        raise ValueError("obj or forced_type must be some value")
93
94
    (itype, ipath, opener) = inspect_io_obj(obj)
95
    psr = anyconfig.processors.find(ipath, prs, forced_type)
96
97
    return IOInfo(src=obj, type=itype, path=ipath, processor=psr,
98
                  opener=opener)
99
100
# vim:sw=4:ts=4:et:
101