For lines that are too long (e.g. > 79 characters), you can use parentheses to group your conditions:
if (first_index < 0
or second_index > self._number_of_plates - 1
or condition2
and candition3):
raise ValueError
Note that any boolean conditions (or, and) should go at the start of the line before the condition.
In your case, there is a special rule because of the if (...) construct:
When the conditional part of an if-statement is long enough to require
that it be written across multiple lines, it’s worth noting that the
combination of a two character keyword (i.e. if), plus a single space,
plus an opening parenthesis creates a natural 4-space indent for the
subsequent lines of the multiline conditional. This can produce a
visual conflict with the indented suite of code nested inside the
if-statement, which would also naturally be indented to 4 spaces. This
PEP takes no explicit position on how (or whether) to further visually
distinguish such conditional lines from the nested suite inside the
if-statement. Acceptable options in this situation include, but are
not limited to:
# No extra indentation.
if (this_is_one_thing and
that_is_another_thing):
do_something()
# Add a comment, which will provide some distinction in editors
# supporting syntax highlighting.
if (this_is_one_thing and
that_is_another_thing):
# Since both conditions are true, we can frobnicate.
do_something()
# Add some extra indentation on the conditional continuation line.
if (this_is_one_thing
and that_is_another_thing):
do_something()
(Also see the discussion of whether to break before or after binary
operators below.)
Source: PEP 8 Style Guide
This happened to me when using pycodestyle 2.5.0.
Instruction to reproduce:
- Create a script test.py with the following contents:
def a(b):
return b # indented with tab
- Run
pycodestyle --show-source --show-pep8 test.py - Output obtained:
test.py:2:1: W191 indentation contains tabs
return b
^
On new projects, spaces-only are strongly recommended over tabs.
Okay: if True:n return
W191: if True:ntreturn
test.py:2:2: E117 over-indented
return b
^
Use 4 spaces per indentation level.
For really old code that you don't want to mess up, you can continue
to use 8-space tabs.
Okay: a = 1
Okay: if a == 0:n a = 1
E111: a = 1
E114: # a = 1
Okay: for item in items:n pass
E112: for item in items:npass
E115: for item in items:n# Hin pass
Okay: a = 1nb = 2
E113: a = 1n b = 2
E116: a = 1n # b = 2
I’m currently ignoring E117 as a workaround, which can mask actual E117 errors.
That’s mostly a matter of tab historycally being used to indent by 8. The only way to make this work «properly» would be to add an option for what a tab should be expanded into, imo.
My comment from #837:
PEP8 says:
Use 4 spaces per indentation level.
If a tab is used as indentation (my preference), it should be assumed to have a tabwidth of 4 by default.
If other codebases are using other tabwidths (8 and 2 are probably the most common alternatives), then it might make more sense to add a config option to allow customizing tabwidth rather than having the default divert that far from PEP8.
(Note also the existence of
flake8-tabs.)
this is fixed on master:
$ python -m pycodestyle t.py --ignore=W191
$
@GPHemsley the standard width of a tab is 8 btw
@asottile There is no «standard» width of a tab. The default width of a tab differs depending on what domain it appears in. In the domain of programming, most IDEs allow tab size to be configured by the user (or the file).
But we’re not talking about broader culture here; we’re talking about Python code styling. (We could argue about which size is better in other domains, but that would be off-topic.)
As I said above, in the domain of Python code styling, I think having the default size match the Python indentation size (4) would be best, with a configuration option allowing that to be overridden.
I also think it’s important to distinguish between indentation using a combination of tabs and spaces (always bad) and indentation using only tabs (likely programmer preference).
python treats a tab as 8 spaces (try in python2), so yes there is a standard width in python
I also think it’s important to distinguish between indentation using a combination of tabs and spaces (always bad) and indentation using only tabs (likely programmer preference).
Believe it or not, there’s a better reason than «programmer preference» to prefer always using tabs; Accessibility and screen readers. Tabs are better for programmers who either have to verbally dictate code or rely on a screen reader to read it back to them.
I also think it’s important to distinguish between indentation using a combination of tabs and spaces (always bad) and indentation using only tabs (likely programmer preference).
Believe it or not, there’s a better reason than «programmer preference» to prefer always using tabs; Accessibility and screen readers. Tabs are better for programmers who either have to verbally dictate code or rely on a screen reader to read it back to them.
Indeed. I should have said that indentation using only tabs would be «likely an active decision on the part of the programmer».
closing given the fix on master
closing given the fix on master
Can you please point to the fix on (which) master so we know when it is fixed? Many thanks!
here’s how I found the answer to that, I’m not sure why this wasn’t linked as a duplicate of #836
here’s the commands I ran to figure this out. First I wanted to figure out what commit fixed this issue.
git bisect start # these are backwards because we "fixed" it instead of introducing a regression # which is the "normal" use for `git bisect` git bisect good 2.5.0 git bisect bad HEAD git bisect run bash -c '! python3 -m pycodestyle t.py --ignore=W191'
and that ends up with this:
$ git bisect run bash -c '! python -m pycodestyle t.py --ignore=W191' running bash -c ! python -m pycodestyle t.py --ignore=W191 Bisecting: 13 revisions left to test after this (roughly 4 steps) [e5cdc22a29bf0c4abe30c152f81124e4b7a5dad7] Add lines breaks running bash -c ! python -m pycodestyle t.py --ignore=W191 Bisecting: 6 revisions left to test after this (roughly 3 steps) [a5488e2817637eca9def0be4b329566a1ed0f231] Merge pull request #848 from adamchainz/tox_url running bash -c ! python -m pycodestyle t.py --ignore=W191 Bisecting: 2 revisions left to test after this (roughly 2 steps) [dd1d313152a136f80c9ac3d508d2d99d6b3dc0a8] Expect lines to be indented 8 places when tabs are used running bash -c ! python -m pycodestyle t.py --ignore=W191 Bisecting: 0 revisions left to test after this (roughly 1 step) [ac1c5e579c840e20544e9d65dbcebc1ecd9bf796] Merge pull request #832 from asottile/patch-1 running bash -c ! python -m pycodestyle t.py --ignore=W191 t.py:2:2: E117 over-indented dd1d313152a136f80c9ac3d508d2d99d6b3dc0a8 is the first bad commit commit dd1d313152a136f80c9ac3d508d2d99d6b3dc0a8 Author: Jon Dufresne <jon.dufresne@gmail.com> Date: Thu Jan 31 16:38:31 2019 -0800 Expect lines to be indented 8 places when tabs are used Fixes #836 pycodestyle.py | 8 +++++--- testsuite/E10.py | 4 ++-- testsuite/E11.py | 3 +++ testsuite/E90.py | 2 +- testsuite/W19.py | 38 +++++++++++++++++++------------------- testsuite/test_api.py | 4 ++-- testsuite/test_shell.py | 2 +- 7 files changed, 33 insertions(+), 28 deletions(-) bisect run success
so then we want to see when that commit got released, we use the following command:
$ git describe --contains dd1d313152a136f80c9ac3d508d2d99d6b3dc0a8 2.6.0a1~18^2
so that says that this was integrated 18 commits before 2.6.0a1 was released, meaning any version after that will contain it
4 changed files with 17 additions and 17 deletions
@ -88,14 +88,14 @@ class GerritApprovalFilter(object):
|
||||
for k, v in rapproval.items():
|
||||
if k == 'username':
|
||||
if (not v.search(by.get('username', ''))):
|
||||
return False
|
||||
return False
|
||||
elif k == 'email':
|
||||
if (not v.search(by.get('email', ''))):
|
||||
return False
|
||||
return False
|
||||
elif k == 'newer-than':
|
||||
t = now - v
|
||||
if (approval['grantedOn'] < t):
|
||||
return False
|
||||
return False
|
||||
elif k == 'older-than':
|
||||
t = now - v
|
||||
if (approval['grantedOn'] >= t):
|
||||
|
@ -108,14 +108,14 @@ class GithubCommonFilter(object):
|
||||
for k, v in rreview.items():
|
||||
if k == 'username':
|
||||
if (not v.search(by.get('username', ''))):
|
||||
return False
|
||||
return False
|
||||
elif k == 'email':
|
||||
if (not v.search(by.get('email', ''))):
|
||||
return False
|
||||
return False
|
||||
elif k == 'newer-than':
|
||||
t = now - v
|
||||
if (review['grantedOn'] < t):
|
||||
return False
|
||||
return False
|
||||
elif k == 'older-than':
|
||||
t = now - v
|
||||
if (review['grantedOn'] >= t):
|
||||
|
@ -157,12 +157,12 @@ class GithubReporter(BaseReporter):
|
||||
self.log.debug('Reporting change %s, params %s, labels:n%s' %
|
||||
(item.change, self.config, self._labels))
|
||||
for label in self._labels:
|
||||
self.connection.labelPull(project, pr_number, label)
|
||||
self.connection.labelPull(project, pr_number, label)
|
||||
if self._unlabels:
|
||||
self.log.debug('Reporting change %s, params %s, unlabels:n%s' %
|
||||
(item.change, self.config, self._unlabels))
|
||||
for label in self._unlabels:
|
||||
self.connection.unlabelPull(project, pr_number, label)
|
||||
self.connection.unlabelPull(project, pr_number, label)
|
||||
|
||||
def _formatMergeMessage(self, change):
|
||||
message = ''
|
||||
|
@ -548,15 +548,15 @@ class DeduplicateQueue(object):
|
||||
|
||||
|
||||
def _copy_ansible_files(python_module, target_dir):
|
||||
library_path = os.path.dirname(os.path.abspath(python_module.__file__))
|
||||
for fn in os.listdir(library_path):
|
||||
if fn == "__pycache__":
|
||||
continue
|
||||
full_path = os.path.join(library_path, fn)
|
||||
if os.path.isdir(full_path):
|
||||
shutil.copytree(full_path, os.path.join(target_dir, fn))
|
||||
else:
|
||||
shutil.copy(os.path.join(library_path, fn), target_dir)
|
||||
library_path = os.path.dirname(os.path.abspath(python_module.__file__))
|
||||
for fn in os.listdir(library_path):
|
||||
if fn == "__pycache__":
|
||||
continue
|
||||
full_path = os.path.join(library_path, fn)
|
||||
if os.path.isdir(full_path):
|
||||
shutil.copytree(full_path, os.path.join(target_dir, fn))
|
||||
else:
|
||||
shutil.copy(os.path.join(library_path, fn), target_dir)
|
||||
|
||||
|
||||
def check_varnames(var):
|
||||
|