mirror of
https://github.com/facebook/sapling.git
synced 2024-10-16 19:57:18 +03:00
584656dff3
Summary: Turned on the auto formatter. Ran `arc lint --apply-patches --take BLACK **/*.py`. Then run `arc lint` again so some other autofixers like spellchecker etc. looked at the code base. Manually accept the changes whenever they make sense, or use a workaround (ex. changing "dict()" to "dict constructor") where autofix is false positive. Disabled linters on files that are hard (i18n/polib.py) to fix, or less interesting to fix (hgsubversion tests), or cannot be fixed without breaking OSS build (FBPYTHON4). Conflicted linters (test-check-module-imports.t, part of test-check-code.t, test-check-pyflakes.t) are removed or disabled. Duplicated linters (test-check-pyflakes.t, test-check-pylint.t) are removed. An issue of the auto-formatter is lines are no longer guarnateed to be <= 80 chars. But that seems less important comparing with the benefit auto-formatter provides. As we're here, also remove test-check-py3-compat.t, as it is currently broken if `PYTHON3=/bin/python3` is set. Reviewed By: wez, phillco, simpkins, pkaush, singhsrb Differential Revision: D8173629 fbshipit-source-id: 90e248ae0c5e6eaadbe25520a6ee42d32005621b
105 lines
3.2 KiB
Python
Executable File
105 lines
3.2 KiB
Python
Executable File
#!/usr/bin/env python
|
|
#
|
|
# check-py3-compat - check Python 3 compatibility of Mercurial files
|
|
#
|
|
# Copyright 2015 Gregory Szorc <gregory.szorc@gmail.com>
|
|
#
|
|
# This software may be used and distributed according to the terms of the
|
|
# GNU General Public License version 2 or any later version.
|
|
|
|
from __future__ import absolute_import, print_function
|
|
|
|
import ast
|
|
import importlib
|
|
import os
|
|
import sys
|
|
import traceback
|
|
|
|
|
|
def check_compat_py2(f):
|
|
"""Check Python 3 compatibility for a file with Python 2"""
|
|
with open(f, "rb") as fh:
|
|
content = fh.read()
|
|
root = ast.parse(content)
|
|
|
|
# Ignore empty files.
|
|
if not root.body:
|
|
return
|
|
|
|
futures = set()
|
|
haveprint = False
|
|
for node in ast.walk(root):
|
|
if isinstance(node, ast.ImportFrom):
|
|
if node.module == "__future__":
|
|
futures |= set(n.name for n in node.names)
|
|
elif isinstance(node, ast.Print):
|
|
haveprint = True
|
|
|
|
if "absolute_import" not in futures:
|
|
print("%s not using absolute_import" % f)
|
|
if haveprint and "print_function" not in futures:
|
|
print("%s requires print_function" % f)
|
|
|
|
|
|
def check_compat_py3(f):
|
|
"""Check Python 3 compatibility of a file with Python 3."""
|
|
with open(f, "rb") as fh:
|
|
content = fh.read()
|
|
|
|
try:
|
|
ast.parse(content)
|
|
except SyntaxError as e:
|
|
print("%s: invalid syntax: %s" % (f, e))
|
|
return
|
|
|
|
# Try to import the module.
|
|
# For now we only support modules in packages because figuring out module
|
|
# paths for things not in a package can be confusing.
|
|
if f.startswith(("hgdemandimport/", "hgext/", "mercurial/")) and not f.endswith(
|
|
"__init__.py"
|
|
):
|
|
assert f.endswith(".py")
|
|
name = f.replace("/", ".")[:-3]
|
|
try:
|
|
importlib.import_module(name)
|
|
except Exception as e:
|
|
exc_type, exc_value, tb = sys.exc_info()
|
|
# We walk the stack and ignore frames from our custom importer,
|
|
# import mechanisms, and stdlib modules. This kinda/sorta
|
|
# emulates CPython behavior in import.c while also attempting
|
|
# to pin blame on a Mercurial file.
|
|
for frame in reversed(traceback.extract_tb(tb)):
|
|
if frame.name == "_call_with_frames_removed":
|
|
continue
|
|
if "importlib" in frame.filename:
|
|
continue
|
|
if "mercurial/__init__.py" in frame.filename:
|
|
continue
|
|
if frame.filename.startswith(sys.prefix):
|
|
continue
|
|
break
|
|
|
|
if frame.filename:
|
|
filename = os.path.basename(frame.filename)
|
|
print(
|
|
"%s: error importing: <%s> %s (error at %s:%d)"
|
|
% (f, type(e).__name__, e, filename, frame.lineno)
|
|
)
|
|
else:
|
|
print(
|
|
"%s: error importing module: <%s> %s (line %d)"
|
|
% (f, type(e).__name__, e, frame.lineno)
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if sys.version_info[0] == 2:
|
|
fn = check_compat_py2
|
|
else:
|
|
fn = check_compat_py3
|
|
|
|
for f in sys.argv[1:]:
|
|
fn(f)
|
|
|
|
sys.exit(0)
|