Skip to content

Commit 4c14e35

Browse files
author
Joel Collins
committed
Added PyLint analysis
1 parent 63b4c1f commit 4c14e35

File tree

25 files changed

+77
-131
lines changed

25 files changed

+77
-131
lines changed

.deepsource.toml

Lines changed: 0 additions & 19 deletions
This file was deleted.

.github/workflows/codeql-analysis.yml

Lines changed: 0 additions & 51 deletions
This file was deleted.

.github/workflows/publish.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ jobs:
3737
- name: Analyse with MyPy
3838
run: poetry run mypy src
3939

40+
- name: Lint with PyLint
41+
run: poetry run pylint .\src\labthings\
42+
4043
- name: Test with pytest
4144
run: poetry run pytest
4245

.github/workflows/test.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ jobs:
3939
- name: Analyse with MyPy
4040
run: poetry run mypy src
4141

42+
- name: Lint with PyLint
43+
run: poetry run pylint .\src\labthings\
44+
4245
- name: Test with pytest
4346
run: poetry run pytest
4447

pyproject.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ sphinx-rtd-theme = "^0.5.0"
3434
mypy = "^0.790"
3535

3636
[tool.black]
37-
exclude = '(\.eggs|\.git|\.venv)'
37+
exclude = '(\.eggs|\.git|\.venv|node_modules/)'
3838

3939
[tool.isort]
4040
multi_line_output = 3
@@ -44,6 +44,13 @@ use_parentheses = true
4444
ensure_newline_before_comments = true
4545
line_length = 88
4646

47+
[tool.pylint.'MESSAGES CONTROL']
48+
disable = "fixme,C,R"
49+
max-line-length = 88
50+
51+
[tool.pylint.'MASTER']
52+
ignore = "marshmallow_jsonschema"
53+
4754
[build-system]
4855
requires = ["poetry>=0.12"]
4956
build-backend = "poetry.masonry.api"

src/labthings/actions/thread.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def __init__(
7070

7171
# copy_current_request_context allows threads to access flask current_app
7272
if has_request_context():
73-
logging.debug(f"Copying request context to {self._target}")
73+
logging.debug("Copying request context to %s", self._target)
7474
self._target = copy_current_request_context(self._target)
7575
try:
7676
self.input = request.json
@@ -298,7 +298,7 @@ def terminate(self, exception=ActionKilledException) -> bool:
298298
:raises which: should cause the thread to exit silently
299299
300300
"""
301-
_LOG.warning(f"Terminating thread {self}")
301+
_LOG.warning("Terminating thread %s", self)
302302
if not (self.is_alive() or self._is_thread_proc_running()):
303303
logging.debug("Cannot kill thread that is no longer running.")
304304
return False
@@ -336,7 +336,7 @@ def stop(self, timeout=None, exception=ActionKilledException) -> bool:
336336
self._status = "cancelled"
337337
return True
338338
# If the timeout tracker stopped before the thread died, kill it
339-
logging.warning(f"Forcefully terminating thread {self}")
339+
logging.warning("Forcefully terminating thread %s", self)
340340
return self.terminate(exception=exception)
341341

342342

@@ -346,7 +346,6 @@ def __init__(
346346
thread: ActionThread,
347347
dest: LockableDeque,
348348
level=logging.INFO,
349-
default_log_len: int = 100,
350349
):
351350
"""Set up a log handler that appends messages to a list.
352351
@@ -371,7 +370,7 @@ def __init__(
371370
self.dest = dest
372371
self.addFilter(self.check_thread)
373372

374-
def check_thread(self, record):
373+
def check_thread(self, *_):
375374
"""Determine if a thread matches the desired record
376375
377376
:param record:

src/labthings/apispec/plugins.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@ def init_attribute_functions(self, *args, **kwargs):
2525
OpenAPIConverter.init_attribute_functions(self, *args, **kwargs)
2626
self.attribute_functions.append(self.jsonschema_type_mapping)
2727

28-
def jsonschema_type_mapping(self, field, **kwargs):
28+
def jsonschema_type_mapping(self, field, **_):
2929
"""
3030
:param field:
3131
:param **kwargs:
3232
"""
3333
ret = {}
3434
if hasattr(field, "_jsonschema_type_mapping"):
35+
# pylint: disable=protected-access
3536
schema = field._jsonschema_type_mapping()
3637
ret.update(schema)
3738
return ret
@@ -246,6 +247,7 @@ def spec_for_event(cls, event):
246247
)
247248
return d
248249

250+
# pylint: disable=signature-differs
249251
def operation_helper(self, path, operations, **kwargs):
250252
"""Path helper that allows passing a Flask view function."""
251253
# rule = self._rule_for_view(interaction.dispatch_request, app=app)

src/labthings/default_views/events.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from .. import fields
21
from ..schema import LogRecordSchema
32
from ..views import EventView
43

src/labthings/extensions.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from flask import url_for
99

10-
from typing import List, Dict, Callable
10+
from typing import List, Dict, Callable, Union
1111

1212
from .utilities import camel_to_snake, get_docstring, snake_to_spine
1313
from .views.builder import static_from
@@ -36,11 +36,11 @@ def __init__(
3636
self._meta: dict = {} # Extra metadata to add to the extension description
3737

3838
self._on_registers: List[
39-
Dict
39+
Union[Dict, Callable]
4040
] = [] # List of dictionaries of functions to run on registration
4141

4242
self._on_components: List[
43-
Dict
43+
Union[Dict, Callable]
4444
] = [] # List of dictionaries of functions to run as components are added
4545

4646
self._cls = str(self) # String description of extension instance
@@ -64,6 +64,14 @@ def views(self):
6464
""" """
6565
return self._views
6666

67+
@property
68+
def on_components(self):
69+
return self._on_components
70+
71+
@property
72+
def on_registers(self):
73+
return self._on_registers
74+
6775
def add_view(self, view_class, *urls, endpoint=None, **kwargs):
6876
"""
6977
@@ -217,7 +225,7 @@ def find_instances_in_module(module, class_to_find):
217225
for attribute in dir(module):
218226
if not attribute.startswith("__"):
219227
if isinstance(getattr(module, attribute), class_to_find):
220-
logging.debug(f"Found extension {getattr(module, attribute).name}")
228+
logging.debug("Found extension %s", getattr(module, attribute).name)
221229
objs.append(getattr(module, attribute))
222230
return objs
223231

@@ -235,17 +243,19 @@ def find_extensions_in_file(extension_path: str, module_name="extensions") -> li
235243
:rtype: list
236244
237245
"""
238-
logging.debug(f"Loading extensions from {extension_path}")
246+
logging.debug("Loading extensions from %s", extension_path)
239247

240248
spec = util.spec_from_file_location(module_name, extension_path)
241249
mod = util.module_from_spec(spec)
242250
sys.modules[spec.name] = mod
243251

244252
try:
245253
spec.loader.exec_module(mod) # type: ignore
246-
except Exception: # skipcq: PYL-W0703
254+
except Exception: # pylint: disable=broad-except
247255
logging.error(
248-
f"Exception in extension path {extension_path}: \n{traceback.format_exc()}"
256+
"Exception in extension path %s: \n%s",
257+
extension_path,
258+
traceback.format_exc(),
249259
)
250260
return []
251261
else:
@@ -270,7 +280,7 @@ def find_extensions(extension_dir: str, module_name="extensions") -> list:
270280
:rtype: list
271281
272282
"""
273-
logging.debug(f"Loading extensions from {extension_dir}")
283+
logging.debug("Loading extensions from %s", extension_dir)
274284

275285
extensions = []
276286
extension_paths = glob.glob(os.path.join(extension_dir, "*.py"))

src/labthings/find.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def current_labthing(app=None):
2727
# reach the Flask app object. Just using current_app returns
2828
# a wrapper, which breaks it's use in Task threads
2929
try:
30-
app = current_app._get_current_object() # skipcq: PYL-W0212
30+
app = current_app._get_current_object() # pylint: disable=protected-access
3131
except RuntimeError:
3232
return None
3333
ext = app.extensions.get(EXTENSION_NAME, None)

src/labthings/json/marshmallow_jsonschema/base.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ def _get_schema_for_field(self, obj, field):
204204
schema = FIELD_VALIDATORS[base_class](schema, field, validator, obj)
205205
return schema
206206

207-
def _from_nested_schema(self, obj, field):
207+
def _from_nested_schema(self, _, field):
208208
"""Support nested field.
209209
210210
:param obj:
@@ -217,17 +217,12 @@ def _from_nested_schema(self, obj, field):
217217
nested = field.nested
218218

219219
if isclass(nested) and issubclass(nested, Schema):
220-
name = nested.__name__
221220
only = field.only
222221
exclude = field.exclude
223-
nested_cls = nested
224222
nested_instance = nested(only=only, exclude=exclude)
225223
else:
226-
nested_cls = nested.__class__
227-
name = nested_cls.__name__
228224
nested_instance = nested
229225

230-
outer_name = obj.__class__.__name__
231226
# If this is not a schema we've seen, and it's not this schema (checking this for recursive schemas),
232227
# put it in our list of schema defs
233228
wrapped_nested = self.__class__(nested=True)
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,2 @@
11
class UnsupportedValueError(Exception):
2-
""" """
3-
4-
pass
2+
""" """

src/labthings/json/schemas.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def argument_to_param(
6868
"""
6969
param: Dict[str, Any] = {"in": "path", "name": argument, "required": True}
7070
type_, format_ = CONVERTER_MAPPING.get(
71-
# skipcq: PYL-W0212
71+
# pylint: disable=protected-access
7272
type(rule._converters[argument]), # type: ignore
7373
DEFAULT_TYPE,
7474
)
@@ -88,6 +88,7 @@ def field_to_property(field: fields.Field):
8888
:param field:
8989
9090
"""
91+
# pylint: disable=protected-access
9192
return JSONSchema()._get_schema_for_field(Schema(), field)
9293

9394

@@ -103,7 +104,7 @@ def schema_to_json(
103104
return None
104105
if isinstance(schema, fields.Field):
105106
return field_to_property(schema)
106-
elif isinstance(schema, Dict):
107+
elif isinstance(schema, dict):
107108
return JSONSchema().dump(Schema.from_dict(schema)())
108109
elif isinstance(schema, Schema):
109110
return JSONSchema().dump(schema)

src/labthings/labthing.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ def dummy(*_):
287287

288288
for extension_object in self.extensions.values():
289289
# For each on_component function
290-
for com_func in extension_object._on_components:
290+
for com_func in extension_object.on_components:
291291
# If the component matches
292292
if com_func.get("component", "") == component_name:
293293
# Call the function
@@ -332,14 +332,14 @@ def dummy(*_):
332332
)
333333

334334
# For each on_register function
335-
for reg_func in extension_object._on_registers:
335+
for reg_func in extension_object.on_registers:
336336
# Call the function
337337
reg_func.get("function", dummy)(
338338
*reg_func.get("args"), **reg_func.get("kwargs")
339339
)
340340

341341
# For each on_component function
342-
for com_func in extension_object._on_components:
342+
for com_func in extension_object.on_components:
343343
key = com_func.get("component", "")
344344
# If the component has already been added
345345
if key in self.components:
@@ -393,7 +393,7 @@ def add_view(
393393
"""
394394
endpoint = endpoint or snake_to_camel(view.__name__)
395395

396-
logging.debug(f"{endpoint}: {type(view)} @ {urls}")
396+
logging.debug("%s: %s @ %s", endpoint, type(view), urls)
397397

398398
if self.app is not None:
399399
self._register_view(self.app, view, *urls, endpoint=endpoint, **kwargs)
@@ -449,8 +449,9 @@ def _register_view(
449449
app.add_url_rule(rule, view_func=resource_func, endpoint=endpoint, **kwargs)
450450

451451
# There might be a better way to do this than _rules_by_endpoint,
452-
# but I can't find one so this will do for now. Skipping PYL-W0212
453-
flask_rules = app.url_map._rules_by_endpoint.get(endpoint) # skipcq: PYL-W0212
452+
# but I can't find one so this will do for now.
453+
# pylint: disable=protected-access
454+
flask_rules = app.url_map._rules_by_endpoint.get(endpoint)
454455
with app.test_request_context():
455456
self.spec.path(view=resource_func, interaction=view)
456457

src/labthings/marshalling/args.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class use_body:
1515
"""Gets the request body as a single value and adds it as a positional argument"""
1616

1717
def __init__(
18-
self, schema: Union[Schema, Field, Dict[str, Union[Field, type]]], **kwargs
18+
self, schema: Union[Schema, Field, Dict[str, Union[Field, type]]], **_
1919
):
2020
self.schema = schema
2121

0 commit comments

Comments
 (0)