diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 207c0cb..bb5ba2a 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -34,6 +34,27 @@ jobs: - name: Check with pre-commit run: pre-commit run --all-files --show-diff-on-failure + pylint: + + runs-on: ubuntu-24.04 + + steps: + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Pylint + run: python -m pip install 'pylint[spelling]' + + - name: Run Pylint + run: pylint --output-format=github '**/*.py' + + build-job: runs-on: ubuntu-24.04 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1db9002..30ce60a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,6 +8,27 @@ pre-commit: script: - pre-commit run --all-files --show-diff-on-failure +pylint: + image: python:3.10 + before_script: + - apt-get --assume-yes --quiet update + - > + apt-get --assume-yes --quiet install --no-install-recommends + libenchant-2-2 + - python -m pip install 'pylint[spelling]' pylint-gitlab + script: + - > + pylint + --output-format=pylint_gitlab.GitlabCodeClimateReporter + '**/*.py' + > pylint.json + artifacts: + paths: + - pylint.json + reports: + codequality: pylint.json + when: always + .build: image: python:3.10 before_script: diff --git a/conf.py b/conf.py index 09ac8e7..e02c6e5 100644 --- a/conf.py +++ b/conf.py @@ -1,20 +1,18 @@ -""" Sphinx documentation generator configuration -""" +"""Sphinx documentation generator configuration.""" AUTHOR = 'sinoroc' MASTER_DOCUMENT = 'contents' SUBTITLE = 'Bits of knowledge' TITLE = 'Sinoroc KB' -# # General -# +# ======= extensions = [ 'sphinx.ext.graphviz', ] -master_doc = MASTER_DOCUMENT +master_doc = MASTER_DOCUMENT # pylint: disable=invalid-name suppress_warnings = [ 'download.not_readable', @@ -24,23 +22,20 @@ 'src/_templates', ] -# # Project -# +# ======= -project = TITLE +project = TITLE # pylint: disable=invalid-name -# # HTML -# +# ==== -html_show_copyright = False -html_show_sphinx = False +html_show_copyright = False # pylint: disable=invalid-name +html_show_sphinx = False # pylint: disable=invalid-name html_sidebars = { - # 'about.html' provided by 'alabaster' theme '**': [ - 'about.html', + 'about.html', # Provided by 'alabaster' theme 'globaltoc.html', 'searchbox.html', ], @@ -50,19 +45,18 @@ 'description': SUBTITLE, } -html_title = TITLE +html_title = TITLE # pylint: disable=invalid-name -html_use_modindex = False -html_use_index = False +html_use_modindex = False # pylint: disable=invalid-name +html_use_index = False # pylint: disable=invalid-name -# # Latex -# +# ===== latex_documents = [ ( MASTER_DOCUMENT, - '{}.tex'.format(TITLE.lower().replace(' ', '')), + f'{TITLE.lower().replace(" ", "")}.tex', TITLE, AUTHOR, 'manual', @@ -73,9 +67,7 @@ 'papersize': 'a4paper', } -latex_show_pagerefs = True -latex_show_urls = 'footnote' +latex_show_pagerefs = True # pylint: disable=invalid-name +latex_show_urls = 'footnote' # pylint: disable=invalid-name -latex_toplevel_sectioning = 'part' - -# EOF +latex_toplevel_sectioning = 'part' # pylint: disable=invalid-name diff --git a/pylintrc b/pylintrc new file mode 100644 index 0000000..216b04b --- /dev/null +++ b/pylintrc @@ -0,0 +1,46 @@ +[MASTER] + +jobs = 0 + +load-plugins = + pylint.extensions.bad_builtin, + pylint.extensions.broad_try_clause, + pylint.extensions.check_elif, + pylint.extensions.code_style, + pylint.extensions.comparison_placement, + pylint.extensions.confusing_elif, + pylint.extensions.consider_refactoring_into_while_condition, + pylint.extensions.consider_ternary_expression, + pylint.extensions.dict_init_mutate, + pylint.extensions.docparams, + pylint.extensions.docstyle, + pylint.extensions.dunder, + pylint.extensions.empty_comment, + pylint.extensions.eq_without_hash, + pylint.extensions.for_any_all, + pylint.extensions.magic_value, + pylint.extensions.mccabe, + pylint.extensions.no_self_use, + pylint.extensions.overlapping_exceptions, + pylint.extensions.private_import, + pylint.extensions.redefined_variable_type, + pylint.extensions.redefined_loop_name, + pylint.extensions.set_membership, + pylint.extensions.typing, + pylint.extensions.while_used, + + +[MESSAGES CONTROL] + +disable = + +enable = + use-symbolic-message-instead, + useless-suppression, + + +[SPELLING] + +spelling-dict = en_US + +spelling-private-dict-file = spelling-dict.txt diff --git a/spelling-dict.txt b/spelling-dict.txt new file mode 100644 index 0000000..0e6b2dd --- /dev/null +++ b/spelling-dict.txt @@ -0,0 +1 @@ +initializer diff --git a/src/python/fizz_buzz.py b/src/python/fizz_buzz.py index 4f24f00..9f27b9e 100755 --- a/src/python/fizz_buzz.py +++ b/src/python/fizz_buzz.py @@ -1,47 +1,50 @@ #!/usr/bin/env python3 +"""Fizz buzz.""" -class Injector: +import sys - def __init__(self, multiple, word): + +class Injector: # pylint: disable=too-few-public-methods + """Callable to inject a word if value is a multiple.""" + + def __init__(self, multiple: int, word: str) -> None: + """Initializer.""" self._multiple = multiple - self._output = '{}!'.format(word) + self._output = f'{word}!' - def __call__(self, value): + def __call__(self, value: int): + """Callable.""" result = None if value % self._multiple == 0: result = self._output return result -def fizz_buzz(start, end): +def fizz_buzz(start: int, end: int) -> None: + """Fizz buzz.""" injectors = [ Injector(3, 'Fizz'), Injector(5, 'Buzz'), ] - # + for i in range(start, end + 1): items = [] output = None - # + for injector in injectors: - item = injector(i) - if item: + if (item := injector(i)): items.append(item) - # - if items: - output = ' '.join(items) - else: - output = str(i) - # + + output = ' '.join(items) if items else str(i) + print(output) -def main(): +def _main() -> int: fizz_buzz(1, 50) + return 0 if __name__ == '__main__': - main() - -# EOF + sys.exit(_main())