Show More
@@ -5,6 +5,7 b' from __future__ import absolute_import, ' | |||||
5 | import ast |
|
5 | import ast | |
6 | import collections |
|
6 | import collections | |
7 | import os |
|
7 | import os | |
|
8 | import re | |||
8 | import sys |
|
9 | import sys | |
9 |
|
10 | |||
10 | # Import a minimal set of stdlib modules needed for list_stdlib_modules() |
|
11 | # Import a minimal set of stdlib modules needed for list_stdlib_modules() | |
@@ -568,10 +569,97 b' def find_cycles(imports):' | |||||
568 | def _cycle_sortkey(c): |
|
569 | def _cycle_sortkey(c): | |
569 | return len(c), c |
|
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 | def sources(f, modname): |
|
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 | if f.endswith('.py'): |
|
655 | if f.endswith('.py'): | |
573 | with open(f) as src: |
|
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 | def main(argv): |
|
664 | def main(argv): | |
577 | if len(argv) < 2 or (argv[1] == '-' and len(argv) > 2): |
|
665 | if len(argv) < 2 or (argv[1] == '-' and len(argv) > 2): | |
@@ -587,18 +675,18 b' def main(argv):' | |||||
587 | modname = dotted_name_of_path(source_path, trimpure=True) |
|
675 | modname = dotted_name_of_path(source_path, trimpure=True) | |
588 | localmods[modname] = source_path |
|
676 | localmods[modname] = source_path | |
589 | for localmodname, source_path in sorted(localmods.items()): |
|
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 | try: |
|
679 | try: | |
592 | used_imports[modname] = sorted( |
|
680 | used_imports[modname] = sorted( | |
593 |
imported_modules(src, modname, |
|
681 | imported_modules(src, modname, name, localmods, | |
594 | ignore_nested=True)) |
|
682 | ignore_nested=True)) | |
595 | for error, lineno in verify_import_convention(modname, src, |
|
683 | for error, lineno in verify_import_convention(modname, src, | |
596 | localmods): |
|
684 | localmods): | |
597 | any_errors = True |
|
685 | any_errors = True | |
598 | print('%s:%d: %s' % (source_path, lineno, error)) |
|
686 | print('%s:%d: %s' % (source_path, lineno + line, error)) | |
599 | except SyntaxError as e: |
|
687 | except SyntaxError as e: | |
600 | print('%s:%d: SyntaxError: %s' % |
|
688 | print('%s:%d: SyntaxError: %s' % | |
601 | (source_path, e.lineno, e)) |
|
689 | (source_path, e.lineno + line, e)) | |
602 | cycles = find_cycles(used_imports) |
|
690 | cycles = find_cycles(used_imports) | |
603 | if cycles: |
|
691 | if cycles: | |
604 | firstmods = set() |
|
692 | firstmods = set() |
General Comments 0
You need to be logged in to leave comments.
Login now