diff --git a/docs/Coding-Conventions.md b/docs/Coding-Conventions.md index 26d81a54..01e0c6e7 100644 --- a/docs/Coding-Conventions.md +++ b/docs/Coding-Conventions.md @@ -802,20 +802,21 @@ 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) -â„šī¸ An exception can be made for `__init__.py` files republishing child module declarations +> đŸ’ģ This rule is enforced by error code I252 ```python -# Bad +# Bad - will produce I252 from . import sibling from .sibling import rivalry ``` ```python # Good +import my_app.relationships.parents from my_app.relationships.sibling import rivalry ``` @@ -869,8 +870,9 @@ 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 import sandwich_shop +from monty.mysubmodule import spam, eggs # OK even if neither are used in this module ``` 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" 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/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" 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) 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 8a3f8fda..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_text(encoding="UTF-8") + 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") diff --git a/tests/test_convention_doc/test_rules.py b/tests/test_convention_doc/test_rules.py index 5150e9bc..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 + assert ( + rule.error_codes is None + ), f"Rule ({rule.identifier}) is not marked as automatically enforced, but lists an error code {rule.error_codes}"