Commit Graph

67 Commits

Author SHA1 Message Date
Pierre-Yves David
54022676d2 import-checker: do not enforce lexical sort accross stdlib/local boundary
Before this change, you could get in a start where the checker would either
complain about importing local module before stdlib one or complain about the
local one being wrongly lexically sorted with the stdlib one.

We detect the boundary and avoid complaining about lexical sort across it.
2016-12-15 19:56:48 +01:00
Augie Fackler
cfab112ddc import-checker: ensure cffi is always a system module
I've had reports that this is not always happening, so whitelist it
the way we whitelist other problem cases.
2016-06-23 20:45:37 -04:00
FUJIWARA Katsunori
f32b1f4b1c import-checker: increase portability for python 2.6.x
Before this patch, fromlocalfunc() assumes that "module" attribute of
ast.ImportFrom is None for "from . import a", and Python 2.7.x
satisfies this assumption.

On the other hand, with Python 2.6.x, "module" attribute of
ast.ImportFrom is an empty string for "from . import a", and this
causes failure of test-check-module-imports.t.
2016-06-19 02:15:09 +09:00
Yuya Nishihara
ff61ad577d tests: enable import checker for all python files (including no .py files)
i18n/posplit is excluded as it couldn't be trivially fixed. That's the same
as ade93acee2d6.
2016-05-15 10:48:05 +09:00
Yuya Nishihara
7bd38d257c py3: make contrib/import-checker.py get along with itself
Indent these imports to disable the rule of "not lexically sorted."
2016-05-14 14:33:45 +09:00
Yuya Nishihara
e5d8ee2999 import-checker: extend check of symbol-import order to all local modules
It doesn't make sense that (a) is allowed whereas (b) is disallowed.

 a) from mercurial import hg
    from mercurial.i18n import _

 b) from . import hg
    from .i18n import _
2016-05-14 13:39:33 +09:00
Yuya Nishihara
a97969202f import-checker: always build a list of imported symbols
The next patch will rely on it.
2016-05-14 13:20:13 +09:00
liscju
1283887937 import-checker: recognize relative imports from parents of current package
So far fromlocal recognizes relative imports of the form:
from . import D
from .. import E

It wasn't prepared for recognizing relative imports like:
from ..F import G

The bug was not found so far because all relative imports starting
from the parent was in the list of allowsymbolicimports like:
from ..i18n import
from ..node import
2016-05-07 19:59:30 +02:00
timeless
9af2e630f0 import-checker: parse python code from .t files 2016-04-12 21:43:56 +00:00
timeless
103d337d89 import-checker: track filenames for SyntaxErrors 2016-04-13 16:34:59 +00:00
timeless
37896a9aaf import-checker: track SyntaxErrors
We don't really need to report SyntaxErrors, since in theory
docchecker or a test will catch them, but they happen, and
we can't just have the code crash, so for now, we're reporting
them.
2016-04-13 16:36:19 +00:00
timeless
36d6fb58ef import-checker: refactor source reading
This will allow .t files to generate multiple sources.
It will also allow .py doctests to generate additional sources.
2016-04-11 22:34:04 +00:00
Maciej Fijalkowski
eb8f037251 tests: fix builtin module test on pypy
On pypy datetime and cProfile are modules written in Python, not in C.
For the purpose of this test, just list them explicitely as builtins,
which silences warnings about them being imported before stdlib modules.
2016-03-30 21:54:26 +02:00
timeless
cb70588e15 py3: handle iter/iterkeys+iteritems python3 divergence in import-checker 2016-03-30 08:15:37 +00:00
timeless
14b03acded py3: use print_function in import-checker 2016-03-30 04:55:16 +00:00
timeless
9580d303e6 py3: use absolute_import in import-checker 2016-03-30 04:50:19 +00:00
timeless
250ff767cf py24: remove check-code py24 notation
We require python2.6+
2016-03-30 07:24:51 +00:00
Gregory Szorc
443b14a872 contrib: remove references to 2to3
The custom porting fixers are removed. A comment related to 2to3
has been removed from the import checker.

After this patch, no references to 2to3 remain.
2016-02-27 21:15:16 -08:00
timeless
b31d4af380 import-checker: report local with stdlib late warning
Without this, developers have to figure it out on their own
2016-03-02 15:38:54 +00:00
Yuya Nishihara
79f9ed4511 import-checker: list package directory as stdlib module
Before this patch, a directory containing __init__.py wasn't counted as a
module and __init__.pyc was listed as foo.bar.__init__ module.
2015-12-27 23:37:14 +09:00
Yuya Nishihara
40d0bc65ac import-checker: normalize directory separator to get module name on Windows
It didn't work if a path contains "\\". Therefore, ctypes.util couldn't be
found on Windows.
2015-12-27 23:48:19 +09:00
Gregory Szorc
02bc128123 import-checker: force 'logging' to stdlib module
Not sure why this isn't getting picked up. Perhaps we're not handling
stdlib paths that have sub-modules? Something to investigate for another
day...
2015-12-23 12:27:24 -08:00
Matt Harbison
0cdbeb7bf0 import-checker: force 'ctype.util' to stdlib module
Not having this caused warnings on Windows:

  mercurial/pure/osutil.py:12: stdlib import follows local import: os
  mercurial/pure/osutil.py:13: stdlib import follows local import: socket
  mercurial/pure/osutil.py:14: stdlib import follows local import: stat
  mercurial/pure/osutil.py:15: stdlib import follows local import: sys
2015-12-22 21:47:40 -05:00
Yuya Nishihara
934b9df7b4 import-checker: tell which symbol causes "direct symbol import"
This would be sometimes useful to understand why import-checker.py complains
about it.
2015-12-06 14:28:35 +09:00
Yuya Nishihara
b16ffd4ab4 import-checker: allow absolute imports of sub modules from local packages
Before this patch, import-checker.py didn't know if a name in ImportFrom
statement are module or not. Therefore, it complained the following example
did "direct symbol import from mercurial".

  # hgext/foo.py
  from mercurial import hg

This patch reuses the dict of local modules to filter out sub-module names.
2015-12-06 14:18:19 +09:00
Yuya Nishihara
86b18c8c85 import-checker: allow symbol imports from hgweb.common and .request
This seems the convention of hgweb.
2015-11-01 13:55:21 +09:00
Yuya Nishihara
7ae2e7fc0b import-checker: reset context to verify convention in function scope
I got the following error by rewriting hgweb/webcommands.py to use
absolute_import. It is false-positive because the import line appears in
"help" function:

  hgweb/webcommands.py:1297: higher-level import should come first: mercurial

This patch makes the import checker aware of the function scope and apply
rules recursively.
2015-11-01 17:42:03 +09:00
Yuya Nishihara
e8375646e9 import-checker: allow import of child modules from package root
I got the following error by rewriting hgweb/__init__.py to use
absolute_import, which is obviously wrong:

  Import cycle: mercurial.hgweb.__init__ -> mercurial.hgweb.__init__

"from foo import bar" should not make a cycle if "foo" is a package and
if "bar" is a module or a package. On the other hand, it should be detected
as a cycle if "bar" is a non-module name. Both cases are doc-tested already,
so this patch does not add new doctest.
2015-11-01 00:37:22 +09:00
Yuya Nishihara
b21d72c284 import-checker: include lineno in warning message
This makes it easy to look for imports in function scope.
2015-11-01 15:46:06 +09:00
Yuya Nishihara
1455104bd2 import-checker: extract function to generate a formatted warning
This is the stub to embed lineno. See the next patch for details.
2015-11-01 15:39:25 +09:00
Yuya Nishihara
297152f7e3 import-checker: make it executable for convenience 2015-11-01 13:53:05 +09:00
Mads Kiilerich
09567db49a spelling: trivial spell checking 2015-10-17 00:58:46 +02:00
Augie Fackler
0dd6c0c729 import-checker: use modern .endswith for multiple suffixes
Suggested by Anton Shestakov <engored@ya.ru> on the list. Thanks!
2015-09-10 09:52:17 -04:00
timeless@mozdev.org
0c786bcfc9 import-checker: accept .pyc and .pyo files (issue4812)
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin

$ ls '/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6'/BaseHTTPServer.py*
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/BaseHTTPServer.pyc
/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/BaseHTTPServer.pyo
2015-09-02 16:07:35 -04:00
Augie Fackler
bbff421b33 import-checker: ensure multiprocessing is treated as from stdlib
On my linux machines multiprocessing appears to defeat the logic in
import-checker to detect stdlib modules. Since we now only use
versions of Python which ship with multiprocessing, let's just
whitelist the module.
2015-08-24 10:09:00 -04:00
Yuya Nishihara
879585e8e1 import-checker: exclude mercurial packages installed into the system path
If mercurial was installed into a directory other than the site-packages,
test-module-imports.t failed as 'mercurial.node' was listed in stdlib_modules:

  testpackage/latesymbolimport.py relative import of stdlib module

Instead, we should exclude our packages explicitly.
2015-07-04 10:56:37 +09:00
Yuya Nishihara
cfcee215a8 import-checker: recurse into subtree of sys.path only if __init__.py exists
We can't assume that the site-packages is the only directory that has Python
files but is not handled as a package. For example, we have dist-packages
directory on Debian.
2015-07-04 10:54:03 +09:00
FUJIWARA Katsunori
4bae7bb820 import-checker.py: exit with code 0 if no error is detected
Before this patch, `import-checker.py` exits with non-0 code, if no
error is detected. This is unusual as Unix command.

This change may be a one of preparations for issue4677, because this
can avoid extra explanation about unusual exit code of
`import-checker.py` for third party tool developers.
2015-07-03 06:56:03 +09:00
Gregory Szorc
5fe42b2975 import-checker: establish modern import convention
We introduce a new convention for declaring imports and enforce it via
the import checker script.

The new convention is only active when absolute imports are used, which is
currently nowhere. Keying off "from __future__ import absolute_import" to
engage the new import convention seems like the easiest solution. It is
also beneficial for Mercurial to use this mode because it means less work
and ambiguity for the importer and potentially better performance due to
fewer stat() system calls because the importer won't look for modules in
relative paths unless explicitly asked.

Once all files are converted to use absolute import, we can refactor
this code to again only have a single import convention and we can
require use of absolute import in the style checker.

The rules for the new convention are documented in the docstring of the
added function. Tests have been added to test-module-imports.t. Some
tests are sensitive to newlines and source column position, which makes
docstring testing difficult and/or impossible.
2015-06-28 12:46:34 -07:00
Gregory Szorc
1553443b44 import-checker: establish new function for verifying import conventions
A future patch will formalize the modern import convention. In
preparation for that, introduce a new wrapper function that will invoke
the proper function.
2015-06-28 12:28:48 -07:00
Gregory Szorc
1159e64c84 import-checker: resolve relative imports
"from . import X" will produce an ImportFrom ast node with .module =
None. This resulted in a run-time error from attempting to concatenate
None with a str.

Another problem with relative imports is that the prefix may be dynamic
based on the "level" attribute of the import. e.g. "from ." has level 1
and "from .." has level 2.

We teach the "fromlocal" function how to cope with relative imports.
Where appropriate, the consumer passes in the level so relative module
names may be resolved properly.
2015-06-28 09:36:58 -07:00
Gregory Szorc
5380dea2a7 global: mass rewrite to use modern exception syntax
Python 2.6 introduced the "except type as instance" syntax, replacing
the "except type, instance" syntax that came before. Python 3 dropped
support for the latter syntax. Since we no longer support Python 2.4 or
2.5, we have no need to continue supporting the "except type, instance".

This patch mass rewrites the exception syntax to be Python 2.6+ and
Python 3 compatible.

This patch was produced by running `2to3 -f except -w -n .`.
2015-06-23 22:20:08 -07:00
FUJIWARA Katsunori
d90834b5cb import-checker: don't treat modules as relative one if not found
The previous patch ensures all module names are recorded in `imports`
as absolute names, so we no longer need to treat modules as ones
imported relatively from the target source if they appear to not be
from the stdlib.
2015-05-18 02:52:58 +09:00
FUJIWARA Katsunori
8a7efd627d import-checker: make imported_modules yield absolute dotted_name_of_path
This patch makes `imported_modules()` always yield absolute
`dotted_name_of_path()`-ed name by strict detection with
`fromlocal()`.

This change improves circular detection in some points:

  - locally defined modules, of which name collides against one of
    standard library, can be examined correctly

    For example, circular import related to `commands` is overlooked
    before this patch.

  - names not useful for circular detection are ignored

    Names below are also yielded before this patch:

      - module names of standard library (= not locally defined one)
      - non-module names (e.g. `node.nullid` of `from node import nullid`)

    These redundant names decrease performance of circular detection.

    For example, with files at 13dc86d189c9, average loops per file in
    `checkmod()` is reduced from 165 to 109.

  - `__init__` can be handled correctly in `checkmod()`

    For example, current implementation has problems below:

      - `from xxx import yyy` doesn't recognize `xxx.__init__` as imported

      - `xxx.__init__` imported via `import xxx` is treated as `xxx`,
        and circular detection is aborted, because `key` of such
        module name is not `xxx` but `xxx.__init__`

  - it is easy to enhance for `from . import xxx` style or so (in the
    future)

    Module name detection in `imported_modules()` can use information
    in `ast.ImportFrom` fully.

It is assumed that all locally defined modules are correctly specified
to `import-checker.py` at once.

Strictly speaking, when `from foo.bar.baz import module1` imports
`foo.bar.baz.module1` module, current `imported_modules()` yields only
`foo.bar.baz.__init__`, even though also `foo.__init__` and
`foo.bar.__init__` should be yielded to detect circular import
exactly.

But this limitation is reasonable one for improvement in this patch,
because current `__init__` files in Mercurial seems to be implemented
carefully.
2015-05-18 02:52:55 +09:00
FUJIWARA Katsunori
1576f26d69 import-checker: add utility to examine what module is imported easily
`fromlocalfunc()` uses:

  - `modulename` (of the target source) to compose absolute module
    name imported relatively from it

    It is assumed that `modulename` is an `dotted_name_of_path()`-ed
    source file, which may have `.__init__` at the end of it.

    This assumption makes composing `prefix` of relative name easy.

  - `localmods` to examine whether there is a locally defined (=
    Mercurial specific) module matching against the specified name

    It is assumed that module names not existing in `localmods` are
    ones of Python standard library.
2015-05-18 02:50:22 +09:00
FUJIWARA Katsunori
f1f8b5966c import-checker: loop to get list of locally defined modules at first
This is a preparation for subsequent patches, which expect that all
locally defined (= mercurial specific) modules are already known
before examinations.

Looping twice for specified modules is a little redundant, but
reasonable cost for improvement in subsequent patches.
2015-05-14 01:49:10 +09:00
FUJIWARA Katsunori
0f658fb502 import-checker: add xargs like mode
Before this patch, "import-check.py" is invoked via "xargs" in
"test-module-imports.t", but it doesn't ensure that
"import-checker.py" is certainly invoked with all mercurial specific
files at once.

"xargs" may invoke specified command multiple times with part of
arguments given from stdin: according to "xargs(1)" man page, this
dividing arguments is system-dependent.

This patch adds "xargs" like mode to "import-checker.py".

This can ensure that "import-checker.py" is certainly invoked with all
mercurial specific files at once in "test-module-imports.t". This is
assumed by subsequent patches.
2015-05-14 01:49:10 +09:00
Matt Harbison
6a81772054 import-checker: force 'fcntl', 'grp', 'pwd', and 'termios' to stdlib modules
These are Unix only, and caused these additional warnings on Windows if they
aren't hardcoded as stdlib:

  mercurial/posix.py mixed imports
     stdlib:    errno, getpass, os, socket, stat, sys, tempfile
     relative:  grp, pwd, unicodedata
  mercurial/posix.py mixed imports
     stdlib:    re
     relative:  fcntl
  mercurial/posix.py mixed imports
     stdlib:    array
     relative:  termios

Additionally, this was missing on Windows:

  mercurial/crecord.py mixed imports
     stdlib:    fcntl, termios
     relative:  curses


https://docs.python.org/2/library/fcntl.html
https://docs.python.org/2/library/grp.html
https://docs.python.org/2/library/pwd.html
https://docs.python.org/2/library/termios.html
2015-04-08 22:31:50 -04:00
Matt Harbison
8fffff85bf import-checker: allow *.pyd based stdlib modules
These are Windows dlls, and eliminate the following import check diffs that are
not on Unix:

  mercurial/changegroup.py mixed imports
     stdlib:    os, struct, tempfile, zlib
     relative:  bz2
  mercurial/encoding.py mixed imports
     stdlib:    locale, os
     relative:  unicodedata
2015-04-08 22:23:51 -04:00
Matt Mackall
526b5a1fd1 import-checker: rotatecycle is actually the canonical cycle key
So refactor to drop cyclekey().
2015-03-28 00:08:26 -05:00