Show More
@@ -5,6 +5,7 b' from __future__ import absolute_import, ' | |||
|
5 | 5 | import ast |
|
6 | 6 | import collections |
|
7 | 7 | import os |
|
8 | import re | |
|
8 | 9 | import sys |
|
9 | 10 | |
|
10 | 11 | # Import a minimal set of stdlib modules needed for list_stdlib_modules() |
@@ -568,10 +569,97 b' def find_cycles(imports):' | |||
|
568 | 569 | def _cycle_sortkey(c): |
|
569 | 570 | return len(c), c |
|
570 | 571 | |
|
572 | def embedded(f, modname, src): | |
|
573 | """Extract embedded python code | |
|
574 | ||
|
575 | >>> def test(fn, lines): | |
|
576 | ... for s, m, f, l in embedded(fn, "example", lines): | |
|
577 | ... print("%s %s %s" % (m, f, l)) | |
|
578 | ... print(repr(s)) | |
|
579 | >>> lines = [ | |
|
580 | ... 'comment', | |
|
581 | ... ' >>> from __future__ import print_function', | |
|
582 | ... " >>> ' multiline", | |
|
583 | ... " ... string'", | |
|
584 | ... ' ', | |
|
585 | ... 'comment', | |
|
586 | ... ' $ cat > foo.py <<EOF', | |
|
587 | ... ' > from __future__ import print_function', | |
|
588 | ... ' > EOF', | |
|
589 | ... ] | |
|
590 | >>> test("example.t", lines) | |
|
591 | example[2] doctest.py 2 | |
|
592 | "from __future__ import print_function\\n' multiline\\nstring'\\n" | |
|
593 | example[7] foo.py 7 | |
|
594 | 'from __future__ import print_function\\n' | |
|
595 | """ | |
|
596 | inlinepython = 0 | |
|
597 | shpython = 0 | |
|
598 | script = [] | |
|
599 | prefix = 6 | |
|
600 | t = '' | |
|
601 | n = 0 | |
|
602 | for l in src: | |
|
603 | n += 1 | |
|
604 | if not l.endswith(b'\n'): | |
|
605 | l += b'\n' | |
|
606 | if l.startswith(b' >>> '): # python inlines | |
|
607 | if shpython: | |
|
608 | print("%s:%d: Parse Error" % (f, n)) | |
|
609 | if not inlinepython: | |
|
610 | # We've just entered a Python block. | |
|
611 | inlinepython = n | |
|
612 | t = 'doctest.py' | |
|
613 | script.append(l[prefix:]) | |
|
614 | continue | |
|
615 | if l.startswith(b' ... '): # python inlines | |
|
616 | script.append(l[prefix:]) | |
|
617 | continue | |
|
618 | cat = re.search(r"\$ \s*cat\s*>\s*(\S+\.py)\s*<<\s*EOF", l) | |
|
619 | if cat: | |
|
620 | if inlinepython: | |
|
621 | yield ''.join(script), ("%s[%d]" % | |
|
622 | (modname, inlinepython)), t, inlinepython | |
|
623 | script = [] | |
|
624 | inlinepython = 0 | |
|
625 | shpython = n | |
|
626 | t = cat.group(1) | |
|
627 | continue | |
|
628 | if shpython and l.startswith(b' > '): # sh continuation | |
|
629 | if l == b' > EOF\n': | |
|
630 | yield ''.join(script), ("%s[%d]" % | |
|
631 | (modname, shpython)), t, shpython | |
|
632 | script = [] | |
|
633 | shpython = 0 | |
|
634 | else: | |
|
635 | script.append(l[4:]) | |
|
636 | continue | |
|
637 | if inlinepython and l == b' \n': | |
|
638 | yield ''.join(script), ("%s[%d]" % | |
|
639 | (modname, inlinepython)), t, inlinepython | |
|
640 | script = [] | |
|
641 | inlinepython = 0 | |
|
642 | continue | |
|
643 | ||
|
571 | 644 | def sources(f, modname): |
|
645 | """Yields possibly multiple sources from a filepath | |
|
646 | ||
|
647 | input: filepath, modulename | |
|
648 | yields: script(string), modulename, filepath, linenumber | |
|
649 | ||
|
650 | For embedded scripts, the modulename and filepath will be different | |
|
651 | from the function arguments. linenumber is an offset relative to | |
|
652 | the input file. | |
|
653 | """ | |
|
654 | py = False | |
|
572 | 655 | if f.endswith('.py'): |
|
573 | 656 | with open(f) as src: |
|
574 | yield src.read(), modname | |
|
657 | yield src.read(), modname, f, 0 | |
|
658 | py = True | |
|
659 | if py or f.endswith('.t'): | |
|
660 | with open(f) as src: | |
|
661 | for script, modname, t, line in embedded(f, modname, src): | |
|
662 | yield script, modname, t, line | |
|
575 | 663 | |
|
576 | 664 | def main(argv): |
|
577 | 665 | if len(argv) < 2 or (argv[1] == '-' and len(argv) > 2): |
@@ -587,18 +675,18 b' def main(argv):' | |||
|
587 | 675 | modname = dotted_name_of_path(source_path, trimpure=True) |
|
588 | 676 | localmods[modname] = source_path |
|
589 | 677 | for localmodname, source_path in sorted(localmods.items()): |
|
590 | for src, modname in sources(source_path, localmodname): | |
|
678 | for src, modname, name, line in sources(source_path, localmodname): | |
|
591 | 679 | try: |
|
592 | 680 | used_imports[modname] = sorted( |
|
593 |
imported_modules(src, modname, |
|
|
681 | imported_modules(src, modname, name, localmods, | |
|
594 | 682 | ignore_nested=True)) |
|
595 | 683 | for error, lineno in verify_import_convention(modname, src, |
|
596 | 684 | localmods): |
|
597 | 685 | any_errors = True |
|
598 | print('%s:%d: %s' % (source_path, lineno, error)) | |
|
686 | print('%s:%d: %s' % (source_path, lineno + line, error)) | |
|
599 | 687 | except SyntaxError as e: |
|
600 | 688 | print('%s:%d: SyntaxError: %s' % |
|
601 | (source_path, e.lineno, e)) | |
|
689 | (source_path, e.lineno + line, e)) | |
|
602 | 690 | cycles = find_cycles(used_imports) |
|
603 | 691 | if cycles: |
|
604 | 692 | firstmods = set() |
General Comments 0
You need to be logged in to leave comments.
Login now