Skip to content

Commit

Permalink
Change GH action to not run Pylint using EOL Python 3.6
Browse files Browse the repository at this point in the history
(and fix formatting issues in keylime.models.base.pylint)

Signed-off-by: Jean Snyman <git@jsnyman.com>
  • Loading branch information
stringlytyped committed May 28, 2024
1 parent 33b7184 commit 7d8a4ee
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 16 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
- name: Install Python dependencies
run: sudo dnf -y install python3.6 tox python3-pip python3-gpg
- name: Run lints
run: tox -vv -e 'pylint,pylint36'
run: tox -vv -e 'pylint'
- name: Run mypy
run: tox -vv -e 'mypy'
- name: Run pyright
Expand Down
35 changes: 20 additions & 15 deletions keylime/models/base/pylint.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,19 @@ def register(_linter):
def transform_model_class(cls: astroid.ClassDef):
"""Given the Astroid abstract syntax tree (AST) of a model class, modifies it to include those members which are not
present in the source code but created dynamically at runtime. This is achieved by inspecting the schema definition
of the model and identifying calls which trigger creation of new fields or associations. Fake attributes are added
of the model and identifying calls which trigger creation of new fields or associations. Fake attributes are added
to the AST for each field and association identified.
This has the effect of suppressing "access-member-before-definition" (E0203) and
"attribute-defined-outside-init" (W0201) when accessing a field or association using dot notation.
"""
if (isinstance(cls.parent, astroid.Module) and cls.name and cls.parent.name
and cls.parent.name.startswith("keylime.models")
and not cls.parent.name.startswith("keylime.models.base")):

if (
isinstance(cls.parent, astroid.Module)
and cls.name
and cls.parent.name
and cls.parent.name.startswith("keylime.models")
and not cls.parent.name.startswith("keylime.models.base")
):
# Iterate over declarations in the body of the model's _schema method
for exp in cls.locals["_schema"][0].body:
# Only declarations which create a new field or association are relevant
Expand All @@ -66,15 +69,16 @@ def transform_model_class(cls: astroid.ClassDef):
)
]


def transform_model_module(mod: astroid.Module):
"""Given the Astroid abstract syntax tree (AST) of a module containing a model, modifies it to replace any wildcard
import of the ``keylime.models.base`` package with an explicit import that mentions all the items exported by the
package by name. This is useful as defining a model consistently requires a good many constructs from
import of the ``keylime.models.base`` package with an explicit import that mentions all the items exported by the
package by name. This is useful as defining a model consistently requires a good many constructs from
``keylime.models.base`` and so the model API has been designed to allow wildcard imports instead of tediously
importing each construct manually.
Additionally, a dummy function is added to the end of the module AST which references all the items imported from
``keylime.models.base``. This is so that if an available construct is not used in the model, this does not cause a
``keylime.models.base``. This is so that if an available construct is not used in the model, this does not cause a
further warning to be generated by Pylint.
This has the effect of suppressing "wildcard-import" (W0401) and "unused-import" (W0611) when importing the model
Expand All @@ -84,8 +88,12 @@ def transform_model_module(mod: astroid.Module):
return mod

# Return modules which are not expected to contain a model definition unchanged
if (not mod.name or not mod.name.startswith("keylime.models")
or mod.name.startswith("keylime.models.base") or "__init__" in mod.name):
if (
not mod.name
or not mod.name.startswith("keylime.models")
or mod.name.startswith("keylime.models.base")
or "__init__" in mod.name
):
return mod

body = mod.body.copy()
Expand All @@ -97,15 +105,12 @@ def transform_model_module(mod: astroid.Module):
if isinstance(item, astroid.ImportFrom) and item.modname == base_pkg and item.names == [("*", None)]:
# From the list of base imports produced by the ``register(...)`` function, generate a list of import names
# without any aliases (specifying None)
import_names = [ (name, None) for name in base_exports ] # type: list[tuple[str, str | None]]
import_names = [(name, None) for name in base_exports] # type: list[tuple[str, str | None]]
# Replace the wildcard import statement with a new import statement with all imports explicitly named
body[i] = astroid.ImportFrom(base_pkg, import_names, item.level, item.lineno, item.col_offset, item.parent)

# Create new dummy function to reference the imports and avoid "unused-import" warnings
fake_f_code = (
f"def fake_import_use():\n"
f" return [{', '.join(base_exports)}]"
)
fake_f_code = f"def fake_import_use():\n" f" return [{', '.join(base_exports)}]"

# Get AST from dummy function and append it to the end of the statement tree
fake_f = astroid.extract_node(fake_f_code, mod.name)
Expand Down

0 comments on commit 7d8a4ee

Please sign in to comment.