Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: flake8-abp/flake8_abp.py

Issue 29342824: Issue 4044 - Added handling for __future__ unicode_literals import to check_quotes() (Closed)
Left Patch Set: merged edge case fix Created May 31, 2016, 9:56 p.m.
Right Patch Set: removed redundant comment Created June 2, 2016, 5:45 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « flake8-abp/README.md ('k') | flake8-abp/tests/A109.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # This file is part of Adblock Plus <https://adblockplus.org/>, 1 # This file is part of Adblock Plus <https://adblockplus.org/>,
2 # Copyright (C) 2006-2016 Eyeo GmbH 2 # Copyright (C) 2006-2016 Eyeo GmbH
3 # 3 #
4 # Adblock Plus is free software: you can redistribute it and/or modify 4 # Adblock Plus is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License version 3 as 5 # it under the terms of the GNU General Public License version 3 as
6 # published by the Free Software Foundation. 6 # published by the Free Software Foundation.
7 # 7 #
8 # Adblock Plus is distributed in the hope that it will be useful, 8 # Adblock Plus is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 def check_non_default_encoding(physical_line, line_number): 371 def check_non_default_encoding(physical_line, line_number):
372 if line_number <= 2 and re.search(r'^\s*#.*coding[:=]', physical_line): 372 if line_number <= 2 and re.search(r'^\s*#.*coding[:=]', physical_line):
373 return (0, 'A303 non-default file encoding') 373 return (0, 'A303 non-default file encoding')
374 374
375 check_non_default_encoding.name = 'abp-non-default-encoding' 375 check_non_default_encoding.name = 'abp-non-default-encoding'
376 check_non_default_encoding.version = __version__ 376 check_non_default_encoding.version = __version__
377 377
378 378
379 def check_quotes(logical_line, tokens, previous_logical, checker_state): 379 def check_quotes(logical_line, tokens, previous_logical, checker_state):
380 first_token = True 380 first_token = True
381 if tokens[0][3] == 1: 381
382 checker_state['has_unicode_literals'] = False
Sebastian Noack 2016/06/01 09:37:52 Awesome that we can avoid the global variable. How
383
384 # check if in unicode_literals mode
385 token_strings = [t[1] for t in tokens] 382 token_strings = [t[1] for t in tokens]
386 future_import = token_strings[:3] == ['from', '__future__', 'import'] 383 future_import = token_strings[:3] == ['from', '__future__', 'import']
387 384
388 if future_import and 'unicode_literals' in token_strings: 385 if future_import and 'unicode_literals' in token_strings:
389 checker_state['has_unicode_literals'] = True 386 checker_state['has_unicode_literals'] = True
390
391 has_unicode_literals = checker_state.get('has_unicode_literals')
392 387
393 for kind, token, start, end, _ in tokens: 388 for kind, token, start, end, _ in tokens:
394 if kind == tokenize.INDENT or kind == tokenize.DEDENT: 389 if kind == tokenize.INDENT or kind == tokenize.DEDENT:
395 continue 390 continue
396 391
397 if kind == tokenize.STRING: 392 if kind == tokenize.STRING:
398 match = re.search(r'^([rub]*)([\'"]{1,3})(.*)\2$', 393 match = re.search(r'^([rub]*)([\'"]{1,3})(.*)\2$',
399 token, re.IGNORECASE | re.DOTALL) 394 token, re.IGNORECASE | re.DOTALL)
400 prefixes, quote, text = match.groups() 395 prefixes, quote, text = match.groups()
401 prefixes = prefixes.lower() 396 prefixes = prefixes.lower()
402 397
403 if 'u' in prefixes and not has_unicode_literals: 398 if 'u' in prefixes:
Vasily Kuznetsov 2016/06/01 11:01:32 I wrote it before but maybe it got lost with all t
Jon Sonesen 2016/06/01 17:07:00 Thanks for the reminder I thought I had removed it
404 yield (start, 'A112 use "from __future__ import ' 399 yield (start, 'A112 use "from __future__ import '
405 'unicode_literals" instead of ' 400 'unicode_literals" instead of '
406 'prefixing literals with "u"') 401 'prefixing literals with "u"')
407 402
408 if first_token and re.search(r'^(?:(?:def|class)\s|$)', 403 if first_token and re.search(r'^(?:(?:def|class)\s|$)',
409 previous_logical): 404 previous_logical):
410 if quote != '"""': 405 if quote != '"""':
411 yield (start, 'A109 use triple double ' 406 yield (start, 'A109 use triple double '
412 'quotes for docstrings') 407 'quotes for docstrings')
413 elif start[0] != end[0]: 408 elif start[0] != end[0]:
Vasily Kuznetsov 2016/06/01 11:01:32 I have a mild preference for how this looked befor
Sebastian Noack 2016/06/01 11:05:01 I disagree. That way it's easier to understand tha
Vasily Kuznetsov 2016/06/01 11:34:31 Yeah, you have a point too. Ok, let's leave it as
414 pass 409 pass
415 elif 'r' in prefixes: 410 elif 'r' in prefixes:
416 if quote != "'" and not (quote == '"' and "'" in text): 411 if quote != "'" and not (quote == '"' and "'" in text):
417 yield (start, 'A110 use single quotes for raw string') 412 yield (start, 'A110 use single quotes for raw string')
418 else: 413 else:
419 is_unicode = 'u' in prefixes
420 is_bytes = 'b' in prefixes
421 prefix = '' 414 prefix = ''
422 if sys.version_info[0] >= 3: 415 if sys.version_info[0] >= 3:
423 if 'b' in prefixes: 416 if 'b' in prefixes:
424 prefix = 'b' 417 prefix = 'b'
425 elif is_unicode or has_unicode_literals and not is_bytes: 418 else:
Sebastian Noack 2016/06/01 09:37:52 For better code locality please retrieve checker_s
Jon Sonesen 2016/06/01 17:07:00 I agree with you regarding the use of the fetch ha
Jon Sonesen 2016/06/01 17:14:03 Ah, prior to reducing the indent level with the ch
Jon Sonesen 2016/06/02 01:14:10 Also I just tried to implement the if else logic a
426 prefix = 'u' 419 u_literals = checker_state.get('has_unicode_literals')
420 if 'u' in prefixes or u_literals and 'b' not in prefixes:
421 prefix = 'u'
427 422
428 literal = '{0}{1}{2}{1}'.format(prefix, quote, text) 423 literal = '{0}{1}{2}{1}'.format(prefix, quote, text)
429 if ascii(eval(literal)) != literal: 424 if ascii(eval(literal)) != literal:
430 yield (start, "A110 string literal doesn't match " 425 yield (start, "A110 string literal doesn't match "
431 '{}()'.format(ascii.__name__)) 426 '{}()'.format(ascii.__name__))
432 427
433 first_token = False 428 first_token = False
434 429
435 check_quotes.name = 'abp-quotes' 430 check_quotes.name = 'abp-quotes'
436 check_quotes.version = __version__ 431 check_quotes.version = __version__
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 if tokens[i + 1][:2] != (tokenize.OP, ':'): 476 if tokens[i + 1][:2] != (tokenize.OP, ':'):
482 break 477 break
483 478
484 return [(pos, 'A111 redundant parenthesis for {} ' 479 return [(pos, 'A111 redundant parenthesis for {} '
485 'statement'.format(statement))] 480 'statement'.format(statement))]
486 481
487 return [] 482 return []
488 483
489 check_redundant_parenthesis.name = 'abp-redundant-parenthesis' 484 check_redundant_parenthesis.name = 'abp-redundant-parenthesis'
490 check_redundant_parenthesis.version = __version__ 485 check_redundant_parenthesis.version = __version__
LEFTRIGHT

Powered by Google App Engine
This is Rietveld