From 8448d779cf880feb0eadcddf7962cbdb86925e37 Mon Sep 17 00:00:00 2001 From: mshafer-NI <23644905+mshafer-NI@users.noreply.github.com> Date: Wed, 21 May 2025 16:03:27 -0500 Subject: [PATCH 01/13] make it show which rule is failing more clearly --- tests/test_convention_doc/test_rules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_convention_doc/test_rules.py b/tests/test_convention_doc/test_rules.py index 5150e9bc..e91b83c5 100644 --- a/tests/test_convention_doc/test_rules.py +++ b/tests/test_convention_doc/test_rules.py @@ -53,4 +53,4 @@ def test_rule_documents_enforcement_codes(rule): if rule.is_automatically_enforced: assert rule.error_codes is not None else: - assert rule.error_codes is None + assert rule.error_codes is None, f"Rule ({rule.identifier}) is not marked as automatically enforced, but lists an error code {rule.error_codes}" From 46e7bfe198d4361a540665c7ecbafe1c1be11405 Mon Sep 17 00:00:00 2001 From: mshafer-NI <23644905+mshafer-NI@users.noreply.github.com> Date: Wed, 21 May 2025 16:03:27 -0500 Subject: [PATCH 02/13] add tool and update config and convention docs --- docs/Coding-Conventions.md | 10 ++++++---- ni_python_styleguide/config.ini | 2 ++ pyproject.toml | 4 ++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/Coding-Conventions.md b/docs/Coding-Conventions.md index 26d81a54..d6046e9d 100644 --- a/docs/Coding-Conventions.md +++ b/docs/Coding-Conventions.md @@ -802,14 +802,16 @@ from collections import defaultdict from contextlib import contextmanager ``` -### [O.1.5] âœ”ī¸ **DO** Use absolute imports +### [O.1.5] âœ”ī¸ **DO** Use absolute imports đŸ’ģ > 🐍 This rule stems from [PEP 8](https://www.python.org/dev/peps/pep-0008) +> đŸ’ģ This rule is enforced by error code I252 + â„šī¸ An exception can be made for `__init__.py` files republishing child module declarations ```python -# Bad +# Bad - will produce I252 from . import sibling from .sibling import rivalry ``` @@ -869,8 +871,8 @@ import os # Assuming os is never used ``` ```python -# Good - assuming we are in a __init__.py file -from .mysubmodule import spam, eggs # OK even if neither are used in this module +# Good - assuming we are in a monty/__init__.py file +from monty.mysubmodule import spam, eggs # OK even if neither are used in this module ``` diff --git a/ni_python_styleguide/config.ini b/ni_python_styleguide/config.ini index e3ced7b8..6fa818a4 100644 --- a/ni_python_styleguide/config.ini +++ b/ni_python_styleguide/config.ini @@ -129,3 +129,5 @@ docstring-convention=all # flake8-import-order import-order-style=smarkets + +ban-relative-imports = True diff --git a/pyproject.toml b/pyproject.toml index f86a4c70..072668b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,6 +38,10 @@ isort = ">=5.10" flake8-black = ">=0.2.1" flake8-docstrings = ">=1.5.0" flake8-import-order = ">=0.18.1" +flake8-tidy-imports = [ + {version = ">=4.4.1", python = ">=3.7,<3.9"}, + {version=">=4.11.0", python="^3.9"}, +] pep8-naming = ">=0.11.1" # Rejected flake8 plugins should be listed here (in alphabetical order) From 798891b2dd43f9d4ecec9fa9ff03875070f31185 Mon Sep 17 00:00:00 2001 From: mshafer-NI <23644905+mshafer-NI@users.noreply.github.com> Date: Wed, 21 May 2025 16:03:27 -0500 Subject: [PATCH 03/13] add tool to lock file --- poetry.lock | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index 308d3f11..68c9f4f8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -177,6 +177,34 @@ files = [ pycodestyle = "*" setuptools = "*" +[[package]] +name = "flake8-tidy-imports" +version = "4.10.0" +description = "A flake8 plugin that helps you write tidier imports." +optional = false +python-versions = ">=3.8" +files = [ + {file = "flake8_tidy_imports-4.10.0-py3-none-any.whl", hash = "sha256:b0387fb2ea200441bd142309e716fb7b8f4b0937bdf5f8b7c0c118a5f5e2b8ed"}, + {file = "flake8_tidy_imports-4.10.0.tar.gz", hash = "sha256:bd6cf86465402d2b86903009b748d85a628e599e17b76e810c9857e3a2815173"}, +] + +[package.dependencies] +flake8 = ">=3.8.0" + +[[package]] +name = "flake8-tidy-imports" +version = "4.11.0" +description = "A flake8 plugin that helps you write tidier imports." +optional = false +python-versions = ">=3.9" +files = [ + {file = "flake8_tidy_imports-4.11.0-py3-none-any.whl", hash = "sha256:607a76a7c2a9dec682e214f0692d4e7876862a618b766cef8f16979efac1ce22"}, + {file = "flake8_tidy_imports-4.11.0.tar.gz", hash = "sha256:fcd57e275a9f4f8163db2ecb17c9c942d311750e2315cf9ae931f22f7043d496"}, +] + +[package.dependencies] +flake8 = ">=3.8" + [[package]] name = "iniconfig" version = "2.0.0" @@ -467,4 +495,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "213ef0945cdb89318447e8214d555e59e833b200d319cab47ef905b095b4359e" +content-hash = "0674dc02f387b83c7995f1e0e060a7406c4cb7660b8c1b80939869da9ad90fff" From e0c6f3df14a7013a9ac5f60eb3b5a3453dfcee8d Mon Sep 17 00:00:00 2001 From: mshafer-NI <23644905+mshafer-NI@users.noreply.github.com> Date: Wed, 21 May 2025 16:03:27 -0500 Subject: [PATCH 04/13] add example import that doesn't use from --- docs/Coding-Conventions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Coding-Conventions.md b/docs/Coding-Conventions.md index d6046e9d..cf066c5b 100644 --- a/docs/Coding-Conventions.md +++ b/docs/Coding-Conventions.md @@ -818,6 +818,7 @@ from .sibling import rivalry ```python # Good +import my_app.relationships.parents from my_app.relationships.sibling import rivalry ``` From eaf84a57c757fc8f7a2e7f7ebb41e70dfec40628 Mon Sep 17 00:00:00 2001 From: mshafer-NI <23644905+mshafer-NI@users.noreply.github.com> Date: Wed, 21 May 2025 16:03:27 -0500 Subject: [PATCH 05/13] update own code to match --- ni_python_styleguide/_utils/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ni_python_styleguide/_utils/__init__.py b/ni_python_styleguide/_utils/__init__.py index d2a859ed..8976e3f0 100644 --- a/ni_python_styleguide/_utils/__init__.py +++ b/ni_python_styleguide/_utils/__init__.py @@ -1,6 +1,6 @@ -from . import code_analysis # noqa: F401 -from . import lint # noqa: F401 -from . import string_helpers # noqa: F401 -from . import temp_file # noqa: F401 +from ni_python_styleguide._utils import code_analysis # noqa: F401 +from ni_python_styleguide._utils import lint # noqa: F401 +from ni_python_styleguide._utils import string_helpers # noqa: F401 +from ni_python_styleguide._utils import temp_file # noqa: F401 DEFAULT_ENCODING = "UTF-8" From 92ed5a86b49b92151477c95206738b616d4ac316 Mon Sep 17 00:00:00 2001 From: mshafer-NI <23644905+mshafer-NI@users.noreply.github.com> Date: Wed, 21 May 2025 16:03:27 -0500 Subject: [PATCH 06/13] format --- tests/test_convention_doc/test_rules.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_convention_doc/test_rules.py b/tests/test_convention_doc/test_rules.py index e91b83c5..d2d1395e 100644 --- a/tests/test_convention_doc/test_rules.py +++ b/tests/test_convention_doc/test_rules.py @@ -53,4 +53,6 @@ def test_rule_documents_enforcement_codes(rule): if rule.is_automatically_enforced: assert rule.error_codes is not None else: - assert rule.error_codes is None, f"Rule ({rule.identifier}) is not marked as automatically enforced, but lists an error code {rule.error_codes}" + assert ( + rule.error_codes is None + ), f"Rule ({rule.identifier}) is not marked as automatically enforced, but lists an error code {rule.error_codes}" From d7489eef5e64e85348677bd14622dadf3797bfc7 Mon Sep 17 00:00:00 2001 From: mshafer-NI <23644905+mshafer-NI@users.noreply.github.com> Date: Wed, 21 May 2025 16:03:28 -0500 Subject: [PATCH 07/13] unformat --- tests/test_convention_doc/test_codeblocks.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_convention_doc/test_codeblocks.py b/tests/test_convention_doc/test_codeblocks.py index a7e97961..99af6899 100644 --- a/tests/test_convention_doc/test_codeblocks.py +++ b/tests/test_convention_doc/test_codeblocks.py @@ -74,6 +74,8 @@ def test_bad_codeblocks_document_lint_errors(lint_codeblock, bad_codeblock): assert result, result.output + + def test_good_codeblocks_have_no_lint_errors(lint_codeblock, good_codeblock): """Tests that "good" codeblocks do not fail to lint.""" result = lint_codeblock(good_codeblock) From 2de360a4381307be78af060199ac58f27f27de34 Mon Sep 17 00:00:00 2001 From: mshafer-NI <23644905+mshafer-NI@users.noreply.github.com> Date: Wed, 21 May 2025 16:03:28 -0500 Subject: [PATCH 08/13] format --- tests/test_convention_doc/test_codeblocks.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_convention_doc/test_codeblocks.py b/tests/test_convention_doc/test_codeblocks.py index 99af6899..a7e97961 100644 --- a/tests/test_convention_doc/test_codeblocks.py +++ b/tests/test_convention_doc/test_codeblocks.py @@ -74,8 +74,6 @@ def test_bad_codeblocks_document_lint_errors(lint_codeblock, bad_codeblock): assert result, result.output - - def test_good_codeblocks_have_no_lint_errors(lint_codeblock, good_codeblock): """Tests that "good" codeblocks do not fail to lint.""" result = lint_codeblock(good_codeblock) From 7beaa44d8a61325a57f5bc015c01353dd4c51112 Mon Sep 17 00:00:00 2001 From: mshafer-NI <23644905+mshafer-NI@users.noreply.github.com> Date: Wed, 21 May 2025 16:03:28 -0500 Subject: [PATCH 09/13] remove the exception note --- docs/Coding-Conventions.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/Coding-Conventions.md b/docs/Coding-Conventions.md index cf066c5b..1b219cc0 100644 --- a/docs/Coding-Conventions.md +++ b/docs/Coding-Conventions.md @@ -808,8 +808,6 @@ from contextlib import contextmanager > đŸ’ģ This rule is enforced by error code I252 -â„šī¸ An exception can be made for `__init__.py` files republishing child module declarations - ```python # Bad - will produce I252 from . import sibling From b51b2374d321ea4ad1df22a196654e7f464ec088 Mon Sep 17 00:00:00 2001 From: mshafer-NI <23644905+mshafer-NI@users.noreply.github.com> Date: Wed, 21 May 2025 16:03:28 -0500 Subject: [PATCH 10/13] add another ok example --- docs/Coding-Conventions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Coding-Conventions.md b/docs/Coding-Conventions.md index 1b219cc0..01e0c6e7 100644 --- a/docs/Coding-Conventions.md +++ b/docs/Coding-Conventions.md @@ -871,6 +871,7 @@ import os # Assuming os is never used ```python # Good - assuming we are in a monty/__init__.py file +from monty import sandwich_shop from monty.mysubmodule import spam, eggs # OK even if neither are used in this module ``` From a7f2f30cdf9b15f1a99192483ffddc36002d0cda Mon Sep 17 00:00:00 2001 From: mshafer-NI <23644905+mshafer-NI@users.noreply.github.com> Date: Wed, 21 May 2025 16:03:28 -0500 Subject: [PATCH 11/13] try disabling mac testing for now --- .github/workflows/PR.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/PR.yml b/.github/workflows/PR.yml index 88f57fd8..e662a07c 100644 --- a/.github/workflows/PR.yml +++ b/.github/workflows/PR.yml @@ -45,7 +45,10 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [macos-latest, windows-latest, ubuntu-latest] + os: [ + # macos-latest, + windows-latest, ubuntu-latest + ] python-version: [3.8, 3.9, '3.10', 3.11, 3.12, 3.13] steps: - uses: actions/checkout@v2 From 4b88bcd7796084256685f13c7581c71708f7fc09 Mon Sep 17 00:00:00 2001 From: mshafer-NI <23644905+mshafer-NI@users.noreply.github.com> Date: Wed, 21 May 2025 16:06:51 -0500 Subject: [PATCH 12/13] try byte comparison --- .github/workflows/PR.yml | 5 +---- tests/test_cli/test_format.py | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/PR.yml b/.github/workflows/PR.yml index e662a07c..88f57fd8 100644 --- a/.github/workflows/PR.yml +++ b/.github/workflows/PR.yml @@ -45,10 +45,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ - # macos-latest, - windows-latest, ubuntu-latest - ] + os: [macos-latest, windows-latest, ubuntu-latest] python-version: [3.8, 3.9, '3.10', 3.11, 3.12, 3.13] steps: - uses: actions/checkout@v2 diff --git a/tests/test_cli/test_format.py b/tests/test_cli/test_format.py index 8a3f8fda..093e5726 100644 --- a/tests/test_cli/test_format.py +++ b/tests/test_cli/test_format.py @@ -24,7 +24,7 @@ def test_given_input_file__produces_expected_output_simple( output = styleguide_command(command="format") assert output.exit_code in (True, 0), f"Error in running:\n{output}" - result = test_file.read_text(encoding="UTF-8") + result = test_file.read_bytes() snapshot.snapshot_dir = test_dir snapshot.assert_match(result, "output.py") From 88d8f99d10771a98543f47ad6438c7b92b06cc99 Mon Sep 17 00:00:00 2001 From: mshafer-NI <23644905+mshafer-NI@users.noreply.github.com> Date: Wed, 21 May 2025 16:11:10 -0500 Subject: [PATCH 13/13] ok, let's use an rstrip --- .../format_test_cases__snapshots/blank_file/output.diff | 1 - .../file_with_hanging_whitespace/output.diff | 3 +-- .../file_with_malsorted_imports/output.diff | 3 +-- tests/test_cli/test_format.py | 4 +++- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/test_cli/format_test_cases__snapshots/blank_file/output.diff b/tests/test_cli/format_test_cases__snapshots/blank_file/output.diff index 8b137891..e69de29b 100644 --- a/tests/test_cli/format_test_cases__snapshots/blank_file/output.diff +++ b/tests/test_cli/format_test_cases__snapshots/blank_file/output.diff @@ -1 +0,0 @@ - diff --git a/tests/test_cli/format_test_cases__snapshots/file_with_hanging_whitespace/output.diff b/tests/test_cli/format_test_cases__snapshots/file_with_hanging_whitespace/output.diff index 0a633293..076106dc 100644 --- a/tests/test_cli/format_test_cases__snapshots/file_with_hanging_whitespace/output.diff +++ b/tests/test_cli/format_test_cases__snapshots/file_with_hanging_whitespace/output.diff @@ -13,5 +13,4 @@ -x = 5 ? ^ -+x = 5 - ++x = 5 \ No newline at end of file diff --git a/tests/test_cli/format_test_cases__snapshots/file_with_malsorted_imports/output.diff b/tests/test_cli/format_test_cases__snapshots/file_with_malsorted_imports/output.diff index 8e913217..375ae3c1 100644 --- a/tests/test_cli/format_test_cases__snapshots/file_with_malsorted_imports/output.diff +++ b/tests/test_cli/format_test_cases__snapshots/file_with_malsorted_imports/output.diff @@ -16,5 +16,4 @@ + @click.command() - def _main(): - + def _main(): \ No newline at end of file diff --git a/tests/test_cli/test_format.py b/tests/test_cli/test_format.py index 093e5726..dad47b67 100644 --- a/tests/test_cli/test_format.py +++ b/tests/test_cli/test_format.py @@ -24,7 +24,7 @@ def test_given_input_file__produces_expected_output_simple( output = styleguide_command(command="format") assert output.exit_code in (True, 0), f"Error in running:\n{output}" - result = test_file.read_bytes() + result = test_file.read_text() snapshot.snapshot_dir = test_dir snapshot.assert_match(result, "output.py") @@ -44,6 +44,8 @@ def test_given_input_file__produces_expected_output_diff( assert output.exception is None result = output.stdout.replace(str(test_file), in_file.relative_to(TEST_CASE_DIR).as_posix()) + # to make line endings on different platforms consistent + result = result.rstrip() snapshot.snapshot_dir = test_dir snapshot.assert_match(result, "output.diff")