Passed
Push — main ( bfa577...eb6882 )
by Douglas
04:37
created

mandos.model.searches   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 97
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 39
dl 0
loc 97
rs 10
c 0
b 0
f 0
wmc 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A Search.get_h() 0 10 1
B Search.find_all() 0 25 6
A Search.find() 0 14 1
A Search.search_name() 0 3 1
A Search.hit_fields() 0 18 1
1
import abc
0 ignored issues
show
introduced by
Missing module docstring
Loading history...
2
import dataclasses
3
import logging
4
import typing
5
from typing import Generic, Sequence, TypeVar
6
7
from mandos.model.hits import AbstractHit
8
from mandos.model import CompoundNotFoundError
9
10
logger = logging.getLogger("mandos")
11
12
H = TypeVar("H", bound=AbstractHit, covariant=True)
0 ignored issues
show
Coding Style Naming introduced by
Class name "H" 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
14
15
class Search(Generic[H], metaclass=abc.ABCMeta):
16
    """
17
    Something to search and how to do it.
18
    """
19
20
    @property
21
    def search_name(self) -> str:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
22
        return self.__class__.__name__.lower().replace("search", "")
23
24
    def find_all(self, inchikeys: Sequence[str]) -> Sequence[H]:
25
        """
26
        Loops over every compound and calls ``find``.
27
        Just comes with better logging.
28
29
        Args:
30
            inchikeys:
31
32
        Returns:
33
34
        """
35
        lst = []
36
        for i, compound in enumerate(inchikeys):
37
            try:
38
                x = self.find(compound)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "x" 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...
39
            except CompoundNotFoundError:
40
                logger.error(f"Failed to find compound {compound}. Skipping.")
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
41
                continue
42
            lst.extend(x)
43
            logger.debug(f"Found {len(x)} {self.search_name} annotations for {compound}")
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
44
            if i > 0 and i % 20 == 0 or i == len(inchikeys) - 1:
45
                logger.info(
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
46
                    f"Found {len(lst)} {self.search_name} annotations for {i} of {len(inchikeys)} compounds"
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (108/100).

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

Loading history...
47
                )
48
        return lst
49
50
    def find(self, inchikey: str) -> Sequence[H]:
51
        """
52
        To override.
53
54
        Args:
55
            inchikey:
56
57
        Returns:
58
            Something
59
60
        Raises:
61
            CompoundNotFoundError
62
        """
63
        raise NotImplementedError()
64
65
    @classmethod
66
    def hit_fields(cls) -> Sequence[str]:
67
        """
68
        Gets the fields in the Hit type parameter.
69
70
        Returns:
71
72
        """
73
        # Okay, there's a lot of magic going on here
74
        # We need to access the _parameter_ H on cls -- raw `H` doesn't work
75
        # get_args and __orig_bases__ do this for us
76
        # then dataclasses.fields gives us the dataclass fields
77
        # there's also actual_h.__annotations__, but that doesn't include ClassVar and InitVar
78
        # (not that we're using those)
79
        # If this magic is too magical, we can make this an abstract method
80
        # But that would be a lot of excess code and it might be less modular
81
        actual_h = typing.get_args(cls.get_h())[0]
0 ignored issues
show
Bug introduced by
The Module typing does not seem to have a member named get_args.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
82
        return [f.name for f in dataclasses.fields(actual_h)]
83
84
    @classmethod
85
    def get_h(cls):
86
        """
87
        What is my hit type?
88
89
        Returns:
90
91
        """
92
        # noinspection PyUnresolvedReferences
93
        return cls.__orig_bases__[0]
0 ignored issues
show
Bug introduced by
The Class Search does not seem to have a member named __orig_bases__.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
94
95
96
__all__ = ["Search"]
97