Browse Source

Continue RATP notifier

* Introduce meta agents.
* Add pylint and hooks to lint code.
* Beginning of jsonpath agent.
Phyks (Lucas Verney) 4 years ago
parent
commit
0936a35cb4
No known key found for this signature in database

+ 1
- 0
.gitignore View File

@@ -1,3 +1,4 @@
1 1
 *.pyc
2 2
 __pycache__
3 3
 *.json
4
+config/

+ 4
- 0
hooks/pre-commit View File

@@ -0,0 +1,4 @@
1
+#!/bin/sh
2
+
3
+flake8
4
+pylint -E infotuyo

+ 1
- 1
infotuyo/agents/echoagent.py View File

@@ -10,7 +10,7 @@ from __future__ import absolute_import, unicode_literals
10 10
 import logging
11 11
 
12 12
 # Local imports
13
-from infotuyo.agents.base import Agent, InvalidAgentConfiguration
13
+from infotuyo.agents.base import Agent
14 14
 
15 15
 # Logger
16 16
 logger = logging.getLogger('EchoAgent')

+ 5
- 4
infotuyo/agents/httpagent.py View File

@@ -14,7 +14,7 @@ import infotuyo.helpers.python as helpers
14 14
 from infotuyo.agents.base import Agent, InvalidAgentConfiguration
15 15
 
16 16
 # Logger
17
-logger = logging.getLogger('EchoAgent')
17
+logger = logging.getLogger('HTTPAgent')
18 18
 logger.setLevel(logging.WARN)
19 19
 
20 20
 try:
@@ -81,13 +81,14 @@ class HTTPAgent(Agent):
81 81
             dict: Some payload to pass to the next agent in the pipeline. Can
82 82
             be `None`.
83 83
         """
84
-        r = (
84
+        if payload_input is None:
85
+            payload_input = {}
86
+        response = (
85 87
             getattr(requests, self.method)(
86 88
                 self.url,
87 89
                 data=payload_input.get("data", {})
88 90
             )
89 91
         )
90 92
         return {
91
-            "code": r.status_code
93
+            "code": response.status_code
92 94
         }
93
-

+ 68
- 0
infotuyo/agents/jsonpathagent.py View File

@@ -0,0 +1,68 @@
1
+"""
2
+JSONPath agent
3
+
4
+TODO
5
+"""
6
+# coding: utf-8
7
+from __future__ import absolute_import, unicode_literals
8
+
9
+# System imports
10
+import logging
11
+
12
+# Local imports
13
+import infotuyo.helpers.python as helpers
14
+from infotuyo.agents.base import Agent
15
+
16
+# Logger
17
+logger = logging.getLogger('JSONPathAgent')
18
+logger.setLevel(logging.WARN)
19
+
20
+try:
21
+    import jsonpath_rw
22
+except ImportError:
23
+    helpers.import_failure(logger, "jsonpath_rw")
24
+    raise
25
+
26
+
27
+class JSONPathAgent(Agent):
28
+    """
29
+    TODO
30
+    An agent which makes requests to an HTTP website.
31
+
32
+    Settings:
33
+        None
34
+    Input payload:
35
+        {
36
+            "data": {
37
+                "A dictionary of payload to pass (as GET or POST parameters).
38
+            } (defaults to {})
39
+        }
40
+    Output payload:
41
+        {
42
+            "code": int: "
43
+                Returned HTTP code.
44
+            "
45
+        }
46
+
47
+    Requires `jsonpath-rw` Python module.
48
+    """
49
+    def __init__(self, *args, **kwargs):
50
+        super(JSONPathAgent, self).__init__(*args, **kwargs)
51
+        # TODO
52
+
53
+    def run(self, payload_input=None):
54
+        """
55
+        Run your agent.
56
+
57
+        Params:
58
+            payload_input (dict): The input payload, which is also the output
59
+            of the previous agent in the pipeline. Defaults to `None` if there
60
+            is no previous agent in the pipeline.
61
+
62
+        Returns:
63
+            dict: Some payload to pass to the next agent in the pipeline. Can
64
+            be `None`.
65
+        """
66
+        payload_output = {}
67
+        # TODO
68
+        return payload_output

+ 10
- 5
infotuyo/agents/weboobimporter.py View File

@@ -34,7 +34,7 @@ class ExtendedWeboobEncoder(WeboobEncoder):
34 34
     Extend the WeboobEncoder to encode Weboob objects to JSON to serialize
35 35
     generator objects.
36 36
     """
37
-    def default(self, o):
37
+    def default(self, o):  # pylint: disable=E0202
38 38
         if isinstance(o, types.GeneratorType):
39 39
             return [self.default(item) for item in o]
40 40
         return super(ExtendedWeboobEncoder, self).default(o)
@@ -98,10 +98,15 @@ class WeboobImporter(Agent):
98 98
             be `None`.
99 99
         """
100 100
         # Get items for Weboob
101
-        items = getattr(self.backend, payload_input["method"])(
102
-            *payload_input.get("args", []),
103
-            **payload_input.get("kwargs", {})
104
-        )
101
+        try:
102
+            items = getattr(self.backend, payload_input["method"])(
103
+                *payload_input.get("args", []),
104
+                **payload_input.get("kwargs", {})
105
+            )
106
+        except (KeyError, TypeError):
107
+            logger.warn("Invalid input payload received.")
108
+            return None
109
+
105 110
         return {
106 111
             # FIXME: Ugly hack to serialize Weboob objects to plain Python
107 112
             # objects, using the JSON encoder.

+ 5
- 2
infotuyo/helpers/__init__.py View File

@@ -1,4 +1,7 @@
1
-import json_helpers
2
-import python
1
+"""
2
+Collection of helpers functions.
3
+"""
4
+from . import json_helpers
5
+from . import python
3 6
 
4 7
 __all__ = ["json_helpers", "python"]

+ 14
- 10
infotuyo/helpers/json_helpers.py View File

@@ -18,15 +18,19 @@ class DateAwareJSONDecoder(json.JSONDecoder):
18 18
     to datetime objects.
19 19
     """
20 20
     def __init__(self, *args, **kwargs):
21
-        super(DateAwareJSONDecoder, self).__init__(object_hook=self.date_hook,
21
+        super(DateAwareJSONDecoder, self).__init__(object_hook=date_hook,
22 22
                                                    *args, **kwargs)
23 23
 
24
-    def date_hook(self, json_dict):
25
-        for key, value in json_dict.items():
26
-            if not isinstance(value, str):
27
-                continue
28
-            try:
29
-                json_dict[key] = arrow.parser.DateTimeParser().parse_iso(value)
30
-            except arrow.parser.ParserError:
31
-                pass
32
-        return json_dict
24
+
25
+def date_hook(json_dict):
26
+    """
27
+    JSONDecoder hook to parse ISO dates to datetime.
28
+    """
29
+    for key, value in json_dict.items():
30
+        if not isinstance(value, str):
31
+            continue
32
+        try:
33
+            json_dict[key] = arrow.parser.DateTimeParser().parse_iso(value)
34
+        except arrow.parser.ParserError:
35
+            pass
36
+    return json_dict

+ 18
- 2
infotuyo/meta/freemobilenotifymetaagent.py View File

@@ -7,6 +7,7 @@ An agent which sends notifications through FreeMobile SMS API.
7 7
 from __future__ import absolute_import, unicode_literals
8 8
 
9 9
 # Local imports
10
+from infotuyo.agents.base import InvalidAgentConfiguration
10 11
 from infotuyo.agents.httpagent import HTTPAgent
11 12
 
12 13
 
@@ -17,7 +18,8 @@ class FreeMobileNotifyMetaAgent(HTTPAgent):
17 18
     Settings:
18 19
         None
19 20
     Input payload:
20
-        None
21
+        {
22
+
21 23
     Output payload:
22 24
         {
23 25
             "code": int: "
@@ -26,7 +28,12 @@ class FreeMobileNotifyMetaAgent(HTTPAgent):
26 28
         }
27 29
     """
28 30
     def __init__(self, settings, *args, **kwargs):
29
-        # TODO: Handle phone number and API key
31
+        try:
32
+            self.phone_number = settings["phone_number"]
33
+            self.api_key = settings["api_key"]
34
+        except KeyError:
35
+            raise InvalidAgentConfiguration
36
+
30 37
         super(FreeMobileNotifyMetaAgent, self).__init__(
31 38
             {
32 39
                 "url": "https://smsapi.free-mobile.fr/sendmsg",
@@ -49,4 +56,13 @@ class FreeMobileNotifyMetaAgent(HTTPAgent):
49 56
             dict: Some payload to pass to the next agent in the pipeline. Can
50 57
             be `None`.
51 58
         """
59
+        if payload_input is None:
60
+            payload_input = {}
61
+
62
+        # Extend data
63
+        data = payload_input.get("data", {})
64
+        data["user"] = self.phone_number
65
+        data["pass"] = self.api_key
66
+        payload_input["data"] = data
67
+
52 68
         return super(FreeMobileNotifyMetaAgent, self).run(payload_input)

+ 4
- 2
infotuyo/meta/ratpmetaagent.py View File

@@ -23,12 +23,14 @@ class RATPMetaAgent(WeboobImporter):
23 23
         None
24 24
     Output payload:
25 25
         {
26
-            "status": TODO
26
+            "status": float:
27
+                A float representing the current status of the line. 0.0 is
28
+                everything alright. The more negative the status, the higher
29
+                the perturbations.
27 30
         }
28 31
     """
29 32
     def __init__(self, settings, *args, **kwargs):
30 33
         try:
31
-            # TODO: Not using standard settings
32 34
             self.sensor = settings["line"] + "_sensor"
33 35
         except KeyError:
34 36
             raise InvalidAgentConfiguration

+ 3
- 0
infotuyo/scenarios/base.py View File

@@ -17,6 +17,9 @@ import sys
17 17
 
18 18
 
19 19
 class Scenario(object):
20
+    """
21
+    Base scenario object, from which a scenario should be derived.
22
+    """
20 23
     def __init__(self, settings=None):
21 24
         """
22 25
         Build a Scenario object.

+ 3
- 4
infotuyo/scenarios/ics_to_caldav.py View File

@@ -28,13 +28,12 @@ class IcsToCalDAV(Scenario):
28 28
                 "calendar": "str:
29 29
                     CalDAV calendar display name of the calendar to use.
30 30
                 ",
31
-                "purge_events": bool(false): "
31
+                "purge_events": bool(false):
32 32
                     Whether to purge events from the
33 33
                     calendar prior to import or not.
34
-                ",
35
-                "ssl_verify_cert": bool(true): "
34
+                ,
35
+                "ssl_verify_cert": bool(true)
36 36
                     Whether to verify SSL certificate or not.
37
-                "
38 37
             }
39 38
         }
40 39
     """

+ 410
- 0
pylintrc View File

@@ -0,0 +1,410 @@
1
+[MASTER]
2
+
3
+# A comma-separated list of package or module names from where C extensions may
4
+# be loaded. Extensions are loading into the active Python interpreter and may
5
+# run arbitrary code
6
+extension-pkg-whitelist=
7
+
8
+# Add files or directories to the blacklist. They should be base names, not
9
+# paths.
10
+ignore=CVS
11
+
12
+# Add files or directories matching the regex patterns to the blacklist. The
13
+# regex matches against base names, not paths.
14
+ignore-patterns=
15
+
16
+# Python code to execute, usually for sys.path manipulation such as
17
+# pygtk.require().
18
+#init-hook=
19
+
20
+# Use multiple processes to speed up Pylint.
21
+jobs=1
22
+
23
+# List of plugins (as comma separated values of python modules names) to load,
24
+# usually to register additional checkers.
25
+load-plugins=
26
+
27
+# Pickle collected data for later comparisons.
28
+persistent=yes
29
+
30
+# Specify a configuration file.
31
+#rcfile=
32
+
33
+# Allow loading of arbitrary C extensions. Extensions are imported into the
34
+# active Python interpreter and may run arbitrary code.
35
+unsafe-load-any-extension=no
36
+
37
+
38
+[MESSAGES CONTROL]
39
+
40
+# Only show warnings with the listed confidence levels. Leave empty to show
41
+# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
42
+confidence=
43
+
44
+# Disable the message, report, category or checker with the given id(s). You
45
+# can either give multiple identifiers separated by comma (,) or put this
46
+# option multiple times (only on the command line, not in the configuration
47
+# file where it should appear only once).You can also use "--disable=all" to
48
+# disable everything first and then reenable specific checks. For example, if
49
+# you want to run only the similarities checker, you can use "--disable=all
50
+# --enable=similarities". If you want to run only the classes checker, but have
51
+# no Warning level messages displayed, use"--disable=all --enable=classes
52
+# --disable=W"
53
+disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call
54
+
55
+# Enable the message, report, category or checker with the given id(s). You can
56
+# either give multiple identifier separated by comma (,) or put this option
57
+# multiple time (only on the command line, not in the configuration file where
58
+# it should appear only once). See also the "--disable" option for examples.
59
+enable=
60
+
61
+
62
+[REPORTS]
63
+
64
+# Python expression which should return a note less than 10 (10 is the highest
65
+# note). You have access to the variables errors warning, statement which
66
+# respectively contain the number of errors / warnings messages and the total
67
+# number of statements analyzed. This is used by the global evaluation report
68
+# (RP0004).
69
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
70
+
71
+# Template used to display messages. This is a python new-style format string
72
+# used to format the message information. See doc for all details
73
+#msg-template=
74
+
75
+# Set the output format. Available formats are text, parseable, colorized, json
76
+# and msvs (visual studio).You can also give a reporter class, eg
77
+# mypackage.mymodule.MyReporterClass.
78
+output-format=text
79
+
80
+# Tells whether to display a full report or only the messages
81
+reports=no
82
+
83
+# Activate the evaluation score.
84
+score=yes
85
+
86
+
87
+[REFACTORING]
88
+
89
+# Maximum number of nested blocks for function / method body
90
+max-nested-blocks=5
91
+
92
+
93
+[MISCELLANEOUS]
94
+
95
+# List of note tags to take in consideration, separated by a comma.
96
+notes=FIXME,XXX,TODO
97
+
98
+
99
+[BASIC]
100
+
101
+# Naming hint for argument names
102
+argument-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
103
+
104
+# Regular expression matching correct argument names
105
+argument-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
106
+
107
+# Naming hint for attribute names
108
+attr-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
109
+
110
+# Regular expression matching correct attribute names
111
+attr-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
112
+
113
+# Bad variable names which should always be refused, separated by a comma
114
+bad-names=foo,bar,baz,toto,tutu,tata
115
+
116
+# Naming hint for class attribute names
117
+class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
118
+
119
+# Regular expression matching correct class attribute names
120
+class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
121
+
122
+# Naming hint for class names
123
+class-name-hint=[A-Z_][a-zA-Z0-9]+$
124
+
125
+# Regular expression matching correct class names
126
+class-rgx=[A-Z_][a-zA-Z0-9]+$
127
+
128
+# Naming hint for constant names
129
+const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
130
+
131
+# Regular expression matching correct constant names
132
+const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
133
+
134
+# Minimum line length for functions/classes that require docstrings, shorter
135
+# ones are exempt.
136
+docstring-min-length=-1
137
+
138
+# Naming hint for function names
139
+function-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
140
+
141
+# Regular expression matching correct function names
142
+function-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
143
+
144
+# Good variable names which should always be accepted, separated by a comma
145
+good-names=i,j,k,ex,Run,_,fh,logger
146
+
147
+# Include a hint for the correct naming format with invalid-name
148
+include-naming-hint=no
149
+
150
+# Naming hint for inline iteration names
151
+inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
152
+
153
+# Regular expression matching correct inline iteration names
154
+inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
155
+
156
+# Naming hint for method names
157
+method-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
158
+
159
+# Regular expression matching correct method names
160
+method-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
161
+
162
+# Naming hint for module names
163
+module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
164
+
165
+# Regular expression matching correct module names
166
+module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
167
+
168
+# Colon-delimited sets of names that determine each other's naming style when
169
+# the name regexes allow several styles.
170
+name-group=
171
+
172
+# Regular expression which should only match function or class names that do
173
+# not require a docstring.
174
+no-docstring-rgx=^_
175
+
176
+# List of decorators that produce properties, such as abc.abstractproperty. Add
177
+# to this list to register other decorators that produce valid properties.
178
+property-classes=abc.abstractproperty
179
+
180
+# Naming hint for variable names
181
+variable-name-hint=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
182
+
183
+# Regular expression matching correct variable names
184
+variable-rgx=(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$
185
+
186
+
187
+[LOGGING]
188
+
189
+# Logging modules to check that the string format arguments are in logging
190
+# function parameter format
191
+logging-modules=logging
192
+
193
+
194
+[SPELLING]
195
+
196
+# Spelling dictionary name. Available dictionaries: none. To make it working
197
+# install python-enchant package.
198
+spelling-dict=
199
+
200
+# List of comma separated words that should not be checked.
201
+spelling-ignore-words=
202
+
203
+# A path to a file that contains private dictionary; one word per line.
204
+spelling-private-dict-file=
205
+
206
+# Tells whether to store unknown words to indicated private dictionary in
207
+# --spelling-private-dict-file option instead of raising a message.
208
+spelling-store-unknown-words=no
209
+
210
+
211
+[TYPECHECK]
212
+
213
+# List of decorators that produce context managers, such as
214
+# contextlib.contextmanager. Add to this list to register other decorators that
215
+# produce valid context managers.
216
+contextmanager-decorators=contextlib.contextmanager
217
+
218
+# List of members which are set dynamically and missed by pylint inference
219
+# system, and so shouldn't trigger E1101 when accessed. Python regular
220
+# expressions are accepted.
221
+generated-members=
222
+
223
+# Tells whether missing members accessed in mixin class should be ignored. A
224
+# mixin class is detected if its name ends with "mixin" (case insensitive).
225
+ignore-mixin-members=yes
226
+
227
+# List of class names for which member attributes should not be checked (useful
228
+# for classes with dynamically set attributes). This supports the use of
229
+# qualified names.
230
+ignored-classes=optparse.Values,thread._local,_thread._local
231
+
232
+# List of module names for which member attributes should not be checked
233
+# (useful for modules/projects where namespaces are manipulated during runtime
234
+# and thus existing member attributes cannot be deduced by static analysis. It
235
+# supports qualified module names, as well as Unix pattern matching.
236
+ignored-modules=
237
+
238
+# Show a hint with possible names when a member name was not found. The aspect
239
+# of finding the hint is based on edit distance.
240
+missing-member-hint=yes
241
+
242
+# The minimum edit distance a name should have in order to be considered a
243
+# similar match for a missing member name.
244
+missing-member-hint-distance=1
245
+
246
+# The total number of similar names that should be taken in consideration when
247
+# showing a hint for a missing member.
248
+missing-member-max-choices=1
249
+
250
+
251
+[SIMILARITIES]
252
+
253
+# Ignore comments when computing similarities.
254
+ignore-comments=yes
255
+
256
+# Ignore docstrings when computing similarities.
257
+ignore-docstrings=yes
258
+
259
+# Ignore imports when computing similarities.
260
+ignore-imports=no
261
+
262
+# Minimum lines number of a similarity.
263
+min-similarity-lines=4
264
+
265
+
266
+[VARIABLES]
267
+
268
+# List of additional names supposed to be defined in builtins. Remember that
269
+# you should avoid to define new builtins when possible.
270
+additional-builtins=
271
+
272
+# Tells whether unused global variables should be treated as a violation.
273
+allow-global-unused-variables=yes
274
+
275
+# List of strings which can identify a callback function by name. A callback
276
+# name must start or end with one of those strings.
277
+callbacks=cb_,_cb
278
+
279
+# A regular expression matching the name of dummy variables (i.e. expectedly
280
+# not used).
281
+dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy
282
+
283
+# Argument names that match this expression will be ignored. Default to name
284
+# with leading underscore
285
+ignored-argument-names=_.*
286
+
287
+# Tells whether we should check for unused import in __init__ files.
288
+init-import=no
289
+
290
+# List of qualified module names which can have objects that can redefine
291
+# builtins.
292
+redefining-builtins-modules=six.moves,future.builtins,builtins,io
293
+
294
+
295
+[FORMAT]
296
+
297
+# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
298
+expected-line-ending-format=
299
+
300
+# Regexp for a line that is allowed to be longer than the limit.
301
+ignore-long-lines=^\s*(# )?<?https?://\S+>?$
302
+
303
+# Number of spaces of indent required inside a hanging  or continued line.
304
+indent-after-paren=4
305
+
306
+# String used as indentation unit. This is usually "    " (4 spaces) or "\t" (1
307
+# tab).
308
+indent-string='    '
309
+
310
+# Maximum number of characters on a single line.
311
+max-line-length=100
312
+
313
+# Maximum number of lines in a module
314
+max-module-lines=1000
315
+
316
+# List of optional constructs for which whitespace checking is disabled. `dict-
317
+# separator` is used to allow tabulation in dicts, etc.: {1  : 1,\n222: 2}.
318
+# `trailing-comma` allows a space between comma and closing bracket: (a, ).
319
+# `empty-line` allows space-only lines.
320
+no-space-check=trailing-comma,dict-separator
321
+
322
+# Allow the body of an if to be on the same line as the test if there is no
323
+# else.
324
+single-line-if-stmt=no
325
+
326
+
327
+[DESIGN]
328
+
329
+# Maximum number of arguments for function / method
330
+max-args=5
331
+
332
+# Maximum number of attributes for a class (see R0902).
333
+max-attributes=7
334
+
335
+# Maximum number of boolean expressions in a if statement
336
+max-bool-expr=5
337
+
338
+# Maximum number of branch for function / method body
339
+max-branches=12
340
+
341
+# Maximum number of locals for function / method body
342
+max-locals=15
343
+
344
+# Maximum number of parents for a class (see R0901).
345
+max-parents=7
346
+
347
+# Maximum number of public methods for a class (see R0904).
348
+max-public-methods=20
349
+
350
+# Maximum number of return / yield for function / method body
351
+max-returns=6
352
+
353
+# Maximum number of statements in function / method body
354
+max-statements=50
355
+
356
+# Minimum number of public methods for a class (see R0903).
357
+min-public-methods=1
358
+
359
+
360
+[IMPORTS]
361
+
362
+# Analyse import fallback blocks. This can be used to support both Python 2 and
363
+# 3 compatible code, which means that the block might have code that exists
364
+# only in one or another interpreter, leading to false positives when analysed.
365
+analyse-fallback-blocks=no
366
+
367
+# Deprecated modules which should not be used, separated by a comma
368
+deprecated-modules=optparse,tkinter.tix
369
+
370
+# Create a graph of external dependencies in the given file (report RP0402 must
371
+# not be disabled)
372
+ext-import-graph=
373
+
374
+# Create a graph of every (i.e. internal and external) dependencies in the
375
+# given file (report RP0402 must not be disabled)
376
+import-graph=
377
+
378
+# Create a graph of internal dependencies in the given file (report RP0402 must
379
+# not be disabled)
380
+int-import-graph=
381
+
382
+# Force import order to recognize a module as part of the standard
383
+# compatibility libraries.
384
+known-standard-library=
385
+
386
+# Force import order to recognize a module as part of a third party library.
387
+known-third-party=enchant
388
+
389
+
390
+[CLASSES]
391
+
392
+# List of method names used to declare (i.e. assign) instance attributes.
393
+defining-attr-methods=__init__,__new__,setUp
394
+
395
+# List of member names, which should be excluded from the protected access
396
+# warning.
397
+exclude-protected=_asdict,_fields,_replace,_source,_make
398
+
399
+# List of valid names for the first argument in a class method.
400
+valid-classmethod-first-arg=cls
401
+
402
+# List of valid names for the first argument in a metaclass class method.
403
+valid-metaclass-classmethod-first-arg=mcs
404
+
405
+
406
+[EXCEPTIONS]
407
+
408
+# Exceptions that will emit a warning when being caught. Defaults to
409
+# "Exception"
410
+overgeneral-exceptions=Exception