diff --git a/contrib/import-checker.py b/contrib/import-checker.py index e3900c4dc0..de1d0ae2ee 100755 --- a/contrib/import-checker.py +++ b/contrib/import-checker.py @@ -411,7 +411,8 @@ def verify_modern_convention(module, root, localmods, root_col_offset=0): assign the symbol to a module-level variable. In addition, these imports must be performed before other local imports. This rule only applies to import statements outside of any blocks. - * Relative imports from the standard library are not allowed. + * Relative imports from the standard library are not allowed, unless that + library is also a local module. * Certain modules must be aliased to alternate names to avoid aliasing and readability problems. See `requirealias`. """ @@ -493,7 +494,10 @@ def verify_modern_convention(module, root, localmods, root_col_offset=0): # __future__ is special since it needs to come first and use # symbol import. if fullname != '__future__': - if not fullname or fullname in stdlib_modules: + if not fullname or ( + fullname in stdlib_modules + and fullname not in localmods + and fullname + '.__init__' not in localmods): yield msg('relative import of stdlib module') else: seenlocal = fullname diff --git a/tests/test-imports-checker.t b/tests/test-imports-checker.t index 1df7a47bfb..60303a4cef 100644 --- a/tests/test-imports-checker.t +++ b/tests/test-imports-checker.t @@ -125,7 +125,19 @@ Run additional tests for the import checker > from mercurial.node import hex > EOF - $ $PYTHON "$import_checker" testpackage*/*.py testpackage/subpackage/*.py +# Shadowing a stdlib module to test "relative import of stdlib module" is +# allowed if the module is also being checked + + $ mkdir email + $ touch email/__init__.py + $ touch email/errors.py + $ cat > email/utils.py << EOF + > from __future__ import absolute_import + > from . import errors + > EOF + + $ $PYTHON "$import_checker" testpackage*/*.py testpackage/subpackage/*.py \ + > email/*.py testpackage/importalias.py:2: ui module must be "as" aliased to uimod testpackage/importfromalias.py:2: ui from testpackage must be "as" aliased to uimod testpackage/importfromrelative.py:2: import should be relative: testpackage.unsorted