2010-10-09 01:08:46 +04:00
|
|
|
$ cat > correct.py <<EOF
|
|
|
|
> def toto(arg1, arg2):
|
|
|
|
> del arg2
|
|
|
|
> return (5 + 6, 9)
|
|
|
|
> EOF
|
|
|
|
$ cat > wrong.py <<EOF
|
|
|
|
> def toto( arg1, arg2):
|
|
|
|
> del(arg2)
|
|
|
|
> return ( 5+6, 9)
|
|
|
|
> EOF
|
|
|
|
$ cat > quote.py <<EOF
|
|
|
|
> # let's use quote in comments
|
|
|
|
> (''' ( 4x5 )
|
|
|
|
> but """\\''' and finally''',
|
|
|
|
> """let's fool checkpatch""", '1+2',
|
|
|
|
> '"""', 42+1, """and
|
|
|
|
> ( 4-1 ) """, "( 1+1 )\" and ")
|
|
|
|
> a, '\\\\\\\\', "\\\\\\" x-2", "c-1"
|
|
|
|
> EOF
|
2011-06-29 15:45:51 +04:00
|
|
|
$ cat > classstyle.py <<EOF
|
|
|
|
> class newstyle_class(object):
|
|
|
|
> pass
|
|
|
|
>
|
|
|
|
> class oldstyle_class:
|
|
|
|
> pass
|
|
|
|
>
|
|
|
|
> class empty():
|
|
|
|
> pass
|
|
|
|
>
|
|
|
|
> no_class = 1:
|
|
|
|
> pass
|
|
|
|
> EOF
|
2010-10-09 01:08:46 +04:00
|
|
|
$ check_code="$TESTDIR"/../contrib/check-code.py
|
2015-05-19 00:30:24 +03:00
|
|
|
$ "$check_code" ./wrong.py ./correct.py ./quote.py ./classstyle.py
|
2010-10-09 01:08:46 +04:00
|
|
|
./wrong.py:1:
|
|
|
|
> def toto( arg1, arg2):
|
|
|
|
gratuitous whitespace in () or []
|
|
|
|
./wrong.py:2:
|
|
|
|
> del(arg2)
|
2010-12-03 14:22:56 +03:00
|
|
|
Python keyword is not a function
|
2010-10-09 01:08:46 +04:00
|
|
|
./wrong.py:3:
|
|
|
|
> return ( 5+6, 9)
|
|
|
|
gratuitous whitespace in () or []
|
2011-10-17 05:26:20 +04:00
|
|
|
missing whitespace in expression
|
2010-10-09 01:08:46 +04:00
|
|
|
./quote.py:5:
|
|
|
|
> '"""', 42+1, """and
|
|
|
|
missing whitespace in expression
|
2011-06-29 15:45:51 +04:00
|
|
|
./classstyle.py:4:
|
|
|
|
> class oldstyle_class:
|
|
|
|
old-style class, use class foo(object)
|
|
|
|
./classstyle.py:7:
|
|
|
|
> class empty():
|
2015-05-18 03:40:26 +03:00
|
|
|
class foo() creates old style object, use class foo(object)
|
2010-10-09 01:08:46 +04:00
|
|
|
[1]
|
2013-01-01 23:05:22 +04:00
|
|
|
$ cat > python3-compat.py << EOF
|
|
|
|
> foo <> bar
|
|
|
|
> reduce(lambda a, b: a + b, [1, 2, 3, 4])
|
2014-03-12 21:31:27 +04:00
|
|
|
> dict(key=value)
|
2013-01-01 23:05:22 +04:00
|
|
|
> EOF
|
|
|
|
$ "$check_code" python3-compat.py
|
|
|
|
python3-compat.py:1:
|
|
|
|
> foo <> bar
|
|
|
|
<> operator is not available in Python 3+, use !=
|
|
|
|
python3-compat.py:2:
|
|
|
|
> reduce(lambda a, b: a + b, [1, 2, 3, 4])
|
|
|
|
reduce is not available in Python 3+
|
2014-03-12 21:31:27 +04:00
|
|
|
python3-compat.py:3:
|
|
|
|
> dict(key=value)
|
|
|
|
dict() is different in Py2 and 3 and is slower than {}
|
2013-01-01 23:05:22 +04:00
|
|
|
[1]
|
2010-11-21 13:52:27 +03:00
|
|
|
|
2016-03-20 03:18:38 +03:00
|
|
|
$ cat > foo.c <<EOF
|
|
|
|
> void narf() {
|
|
|
|
> strcpy(foo, bar);
|
|
|
|
> // strcpy_s is okay, but this comment is not
|
|
|
|
> strcpy_s(foo, bar);
|
|
|
|
> }
|
|
|
|
> EOF
|
|
|
|
$ "$check_code" ./foo.c
|
|
|
|
./foo.c:2:
|
|
|
|
> strcpy(foo, bar);
|
|
|
|
don't use strcpy, use strlcpy or memcpy
|
|
|
|
./foo.c:3:
|
|
|
|
> // strcpy_s is okay, but this comment is not
|
|
|
|
don't use //-style comments
|
|
|
|
[1]
|
|
|
|
|
2010-11-21 13:52:27 +03:00
|
|
|
$ cat > is-op.py <<EOF
|
|
|
|
> # is-operator comparing number or string literal
|
|
|
|
> x = None
|
|
|
|
> y = x is 'foo'
|
|
|
|
> y = x is "foo"
|
|
|
|
> y = x is 5346
|
|
|
|
> y = x is -6
|
|
|
|
> y = x is not 'foo'
|
|
|
|
> y = x is not "foo"
|
|
|
|
> y = x is not 5346
|
|
|
|
> y = x is not -6
|
|
|
|
> EOF
|
|
|
|
|
|
|
|
$ "$check_code" ./is-op.py
|
|
|
|
./is-op.py:3:
|
|
|
|
> y = x is 'foo'
|
|
|
|
object comparison with literal
|
|
|
|
./is-op.py:4:
|
|
|
|
> y = x is "foo"
|
|
|
|
object comparison with literal
|
|
|
|
./is-op.py:5:
|
|
|
|
> y = x is 5346
|
|
|
|
object comparison with literal
|
|
|
|
./is-op.py:6:
|
|
|
|
> y = x is -6
|
|
|
|
object comparison with literal
|
|
|
|
./is-op.py:7:
|
|
|
|
> y = x is not 'foo'
|
|
|
|
object comparison with literal
|
|
|
|
./is-op.py:8:
|
|
|
|
> y = x is not "foo"
|
|
|
|
object comparison with literal
|
|
|
|
./is-op.py:9:
|
|
|
|
> y = x is not 5346
|
|
|
|
object comparison with literal
|
|
|
|
./is-op.py:10:
|
|
|
|
> y = x is not -6
|
|
|
|
object comparison with literal
|
|
|
|
[1]
|
|
|
|
|
2013-03-10 01:14:46 +04:00
|
|
|
$ cat > for-nolineno.py <<EOF
|
2011-11-11 04:25:47 +04:00
|
|
|
> except:
|
|
|
|
> EOF
|
2013-03-10 01:14:46 +04:00
|
|
|
$ "$check_code" for-nolineno.py --nolineno
|
|
|
|
for-nolineno.py:0:
|
2011-11-11 04:25:47 +04:00
|
|
|
> except:
|
2013-03-10 01:14:46 +04:00
|
|
|
naked except clause
|
2011-11-11 04:25:47 +04:00
|
|
|
[1]
|
2013-01-01 22:58:21 +04:00
|
|
|
|
2013-07-16 03:29:14 +04:00
|
|
|
$ cat > warning.t <<EOF
|
|
|
|
> $ function warnonly {
|
|
|
|
> > }
|
2013-11-09 13:21:20 +04:00
|
|
|
> $ diff -N aaa
|
|
|
|
> $ function onwarn {}
|
2013-07-16 03:29:14 +04:00
|
|
|
> EOF
|
|
|
|
$ "$check_code" warning.t
|
|
|
|
$ "$check_code" --warn warning.t
|
|
|
|
warning.t:1:
|
|
|
|
> $ function warnonly {
|
|
|
|
warning: don't use 'function', use old style
|
2013-11-09 13:21:20 +04:00
|
|
|
warning.t:3:
|
|
|
|
> $ diff -N aaa
|
|
|
|
warning: don't use 'diff -N'
|
|
|
|
warning.t:4:
|
|
|
|
> $ function onwarn {}
|
|
|
|
warning: don't use 'function', use old style
|
2013-07-16 03:29:14 +04:00
|
|
|
[1]
|
2017-05-15 21:08:02 +03:00
|
|
|
$ cat > error.t <<EOF
|
|
|
|
> $ [ foo == bar ]
|
|
|
|
> EOF
|
|
|
|
$ "$check_code" error.t
|
|
|
|
error.t:1:
|
|
|
|
> $ [ foo == bar ]
|
|
|
|
[ foo == bar ] is a bashism, use [ foo = bar ] instead
|
|
|
|
[1]
|
|
|
|
$ rm error.t
|
2013-01-01 22:58:21 +04:00
|
|
|
$ cat > raise-format.py <<EOF
|
|
|
|
> raise SomeException, message
|
|
|
|
> # this next line is okay
|
|
|
|
> raise SomeException(arg1, arg2)
|
|
|
|
> EOF
|
2013-07-22 12:04:45 +04:00
|
|
|
$ "$check_code" not-existing.py raise-format.py
|
|
|
|
Skipping*not-existing.py* (glob)
|
2013-01-01 22:58:21 +04:00
|
|
|
raise-format.py:1:
|
|
|
|
> raise SomeException, message
|
|
|
|
don't use old-style two-argument raise, use Exception(message)
|
|
|
|
[1]
|
2013-07-22 12:04:45 +04:00
|
|
|
|
2013-11-05 12:00:31 +04:00
|
|
|
$ cat > rst.py <<EOF
|
|
|
|
> """problematic rst text
|
|
|
|
>
|
|
|
|
> .. note::
|
|
|
|
> wrong
|
|
|
|
> """
|
|
|
|
>
|
|
|
|
> '''
|
|
|
|
>
|
|
|
|
> .. note::
|
|
|
|
>
|
|
|
|
> valid
|
|
|
|
>
|
|
|
|
> new text
|
|
|
|
>
|
|
|
|
> .. note::
|
|
|
|
>
|
|
|
|
> also valid
|
|
|
|
> '''
|
|
|
|
>
|
|
|
|
> """mixed
|
|
|
|
>
|
|
|
|
> .. note::
|
|
|
|
>
|
|
|
|
> good
|
|
|
|
>
|
|
|
|
> .. note::
|
|
|
|
> plus bad
|
|
|
|
> """
|
|
|
|
> EOF
|
|
|
|
$ $check_code -w rst.py
|
|
|
|
rst.py:3:
|
|
|
|
> .. note::
|
|
|
|
warning: add two newlines after '.. note::'
|
|
|
|
rst.py:26:
|
|
|
|
> .. note::
|
|
|
|
warning: add two newlines after '.. note::'
|
|
|
|
[1]
|
|
|
|
|
2014-04-15 22:05:00 +04:00
|
|
|
$ cat > ./map-inside-gettext.py <<EOF
|
|
|
|
> print _("map inside gettext %s" % v)
|
|
|
|
>
|
|
|
|
> print _("concatenating " " by " " space %s" % v)
|
|
|
|
> print _("concatenating " + " by " + " '+' %s" % v)
|
|
|
|
>
|
2014-04-18 00:47:38 +04:00
|
|
|
> print _("mapping operation in different line %s"
|
2014-04-15 22:05:00 +04:00
|
|
|
> % v)
|
|
|
|
>
|
|
|
|
> print _(
|
|
|
|
> "leading spaces inside of '(' %s" % v)
|
|
|
|
> EOF
|
|
|
|
$ "$check_code" ./map-inside-gettext.py
|
|
|
|
./map-inside-gettext.py:1:
|
|
|
|
> print _("map inside gettext %s" % v)
|
|
|
|
don't use % inside _()
|
|
|
|
./map-inside-gettext.py:3:
|
|
|
|
> print _("concatenating " " by " " space %s" % v)
|
|
|
|
don't use % inside _()
|
|
|
|
./map-inside-gettext.py:4:
|
|
|
|
> print _("concatenating " + " by " + " '+' %s" % v)
|
|
|
|
don't use % inside _()
|
|
|
|
./map-inside-gettext.py:6:
|
2014-04-18 00:47:38 +04:00
|
|
|
> print _("mapping operation in different line %s"
|
2014-04-15 22:05:00 +04:00
|
|
|
don't use % inside _()
|
|
|
|
./map-inside-gettext.py:9:
|
|
|
|
> print _(
|
|
|
|
don't use % inside _()
|
|
|
|
[1]
|
2014-05-17 13:11:06 +04:00
|
|
|
|
|
|
|
web templates
|
|
|
|
|
|
|
|
$ mkdir -p mercurial/templates
|
|
|
|
$ cat > mercurial/templates/example.tmpl <<EOF
|
|
|
|
> {desc}
|
|
|
|
> {desc|escape}
|
|
|
|
> {desc|firstline}
|
|
|
|
> {desc|websub}
|
|
|
|
> EOF
|
|
|
|
|
|
|
|
$ "$check_code" --warnings mercurial/templates/example.tmpl
|
|
|
|
mercurial/templates/example.tmpl:2:
|
|
|
|
> {desc|escape}
|
|
|
|
warning: follow desc keyword with either firstline or websub
|
|
|
|
[1]
|
2016-05-31 14:58:10 +03:00
|
|
|
|
|
|
|
'string join across lines with no space' detection
|
|
|
|
|
|
|
|
$ cat > stringjoin.py <<EOF
|
|
|
|
> foo = (' foo'
|
|
|
|
> 'bar foo.'
|
|
|
|
> 'bar foo:'
|
|
|
|
> 'bar foo@'
|
2016-05-31 15:02:30 +03:00
|
|
|
> 'bar foo%'
|
|
|
|
> 'bar foo*'
|
|
|
|
> 'bar foo+'
|
|
|
|
> 'bar foo-'
|
2016-05-31 14:58:10 +03:00
|
|
|
> 'bar')
|
|
|
|
> EOF
|
check-code: detect "missing _() in ui message" more exactly
Before this patch, "missing _() in ui message" rule overlooks
translatable message, which starts with other than alphabet.
To detect "missing _() in ui message" more exactly, this patch
improves the regexp with assumptions below.
- sequence consisting of below might precede "translatable message"
in same string token
- formatting string, which starts with '%'
- escaped character, which starts with 'b' (as replacement of '\\'), or
- characters other than '%', 'b' and 'x' (as replacement of alphabet)
- any string tokens might precede a string token, which contains
"translatable message"
This patch builds an input file, which is used to examine "missing _()
in ui message" detection, before '"$check_code" stringjoin.py' in
test-contrib-check-code.t, because this reduces amount of change churn
in subsequent patch.
This patch also applies "()" instead of "_()" on messages below to
hide false-positives:
- messages for ui.debug() or debug commands/tools
- contrib/debugshell.py
- hgext/win32mbcs.py (ui.write() is used, though)
- mercurial/commands.py
- _debugchangegroup
- debugindex
- debuglocks
- debugrevlog
- debugrevspec
- debugtemplate
- untranslatable messages
- doc/gendoc.py (ReST specific text)
- hgext/hgk.py (permission string)
- hgext/keyword.py (text written into configuration file)
- mercurial/cmdutil.py (formatting strings for JSON)
2016-06-20 18:50:39 +03:00
|
|
|
|
|
|
|
'missing _() in ui message' detection
|
|
|
|
|
|
|
|
$ cat > uigettext.py <<EOF
|
|
|
|
> ui.status("% 10s %05d % -3.2f %*s %%"
|
|
|
|
> # this use '\\\\' instead of '\\', because the latter in
|
|
|
|
> # heredoc on shell becomes just '\'
|
|
|
|
> '\\\\ \n \t \0'
|
|
|
|
> """12345
|
|
|
|
> """
|
|
|
|
> '''.:*+-=
|
|
|
|
> ''' "%-6d \n 123456 .:*+-= foobar")
|
|
|
|
> EOF
|
|
|
|
|
2016-06-20 18:50:39 +03:00
|
|
|
(Checking multiple invalid files at once examines whether caching
|
|
|
|
translation table for repquote() works as expected or not. All files
|
|
|
|
should break rules depending on result of repquote(), in this case)
|
|
|
|
|
|
|
|
$ "$check_code" stringjoin.py uigettext.py
|
2016-05-31 14:58:10 +03:00
|
|
|
stringjoin.py:1:
|
|
|
|
> foo = (' foo'
|
|
|
|
string join across lines with no space
|
|
|
|
stringjoin.py:2:
|
|
|
|
> 'bar foo.'
|
|
|
|
string join across lines with no space
|
|
|
|
stringjoin.py:3:
|
|
|
|
> 'bar foo:'
|
|
|
|
string join across lines with no space
|
|
|
|
stringjoin.py:4:
|
|
|
|
> 'bar foo@'
|
|
|
|
string join across lines with no space
|
2016-05-31 15:02:30 +03:00
|
|
|
stringjoin.py:5:
|
|
|
|
> 'bar foo%'
|
|
|
|
string join across lines with no space
|
|
|
|
stringjoin.py:6:
|
|
|
|
> 'bar foo*'
|
|
|
|
string join across lines with no space
|
|
|
|
stringjoin.py:7:
|
|
|
|
> 'bar foo+'
|
|
|
|
string join across lines with no space
|
|
|
|
stringjoin.py:8:
|
|
|
|
> 'bar foo-'
|
|
|
|
string join across lines with no space
|
check-code: detect "missing _() in ui message" more exactly
Before this patch, "missing _() in ui message" rule overlooks
translatable message, which starts with other than alphabet.
To detect "missing _() in ui message" more exactly, this patch
improves the regexp with assumptions below.
- sequence consisting of below might precede "translatable message"
in same string token
- formatting string, which starts with '%'
- escaped character, which starts with 'b' (as replacement of '\\'), or
- characters other than '%', 'b' and 'x' (as replacement of alphabet)
- any string tokens might precede a string token, which contains
"translatable message"
This patch builds an input file, which is used to examine "missing _()
in ui message" detection, before '"$check_code" stringjoin.py' in
test-contrib-check-code.t, because this reduces amount of change churn
in subsequent patch.
This patch also applies "()" instead of "_()" on messages below to
hide false-positives:
- messages for ui.debug() or debug commands/tools
- contrib/debugshell.py
- hgext/win32mbcs.py (ui.write() is used, though)
- mercurial/commands.py
- _debugchangegroup
- debugindex
- debuglocks
- debugrevlog
- debugrevspec
- debugtemplate
- untranslatable messages
- doc/gendoc.py (ReST specific text)
- hgext/hgk.py (permission string)
- hgext/keyword.py (text written into configuration file)
- mercurial/cmdutil.py (formatting strings for JSON)
2016-06-20 18:50:39 +03:00
|
|
|
uigettext.py:1:
|
|
|
|
> ui.status("% 10s %05d % -3.2f %*s %%"
|
|
|
|
missing _() in ui message (use () to hide false-positives)
|
|
|
|
[1]
|