Mercurial > cpython-lru_cache-weakref
annotate Lib/codeop.py @ 16413:8819867f14ef legacy-trunk
Patch derived from Trent's 101162: a Python/C API testing framework.
STILL NEEDS UNIX BUILD CHANGES.
| author | Tim Peters <tim.peters@gmail.com> |
|---|---|
| date | Fri, 02 Feb 2001 05:57:15 +0000 |
| parents | b5345e99596b |
| children | 69f162dcd8b4 |
| rev | line source |
|---|---|
|
9440
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
1 """Utility to compile possibly incomplete Python source code.""" |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
2 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
3 import sys |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
4 import string |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
5 import traceback |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
6 |
|
16070
b5345e99596b
added __all__ lists to a number of Python modules
Skip Montanaro <skip@pobox.com>
parents:
9440
diff
changeset
|
7 __all__ = ["compile_command"] |
|
b5345e99596b
added __all__ lists to a number of Python modules
Skip Montanaro <skip@pobox.com>
parents:
9440
diff
changeset
|
8 |
|
9440
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
9 def compile_command(source, filename="<input>", symbol="single"): |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
10 r"""Compile a command and determine whether it is incomplete. |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
11 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
12 Arguments: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
13 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
14 source -- the source string; may contain \n characters |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
15 filename -- optional filename from which source was read; default "<input>" |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
16 symbol -- optional grammar start symbol; "single" (default) or "eval" |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
17 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
18 Return value / exceptions raised: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
19 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
20 - Return a code object if the command is complete and valid |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
21 - Return None if the command is incomplete |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
22 - Raise SyntaxError or OverflowError if the command is a syntax error |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
23 (OverflowError if the error is in a numeric constant) |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
24 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
25 Approach: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
26 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
27 First, check if the source consists entirely of blank lines and |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
28 comments; if so, replace it with 'pass', because the built-in |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
29 parser doesn't always do the right thing for these. |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
30 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
31 Compile three times: as is, with \n, and with \n\n appended. If |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
32 it compiles as is, it's complete. If it compiles with one \n |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
33 appended, we expect more. If it doesn't compile either way, we |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
34 compare the error we get when compiling with \n or \n\n appended. |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
35 If the errors are the same, the code is broken. But if the errors |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
36 are different, we expect more. Not intuitive; not even guaranteed |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
37 to hold in future releases; but this matches the compiler's |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
38 behavior from Python 1.4 through 1.5.2, at least. |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
39 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
40 Caveat: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
41 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
42 It is possible (but not likely) that the parser stops parsing |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
43 with a successful outcome before reaching the end of the source; |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
44 in this case, trailing symbols may be ignored instead of causing an |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
45 error. For example, a backslash followed by two newlines may be |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
46 followed by arbitrary garbage. This will be fixed once the API |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
47 for the parser is better. |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
48 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
49 """ |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
50 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
51 # Check for source consisting of only blank lines and comments |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
52 for line in string.split(source, "\n"): |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
53 line = string.strip(line) |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
54 if line and line[0] != '#': |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
55 break # Leave it alone |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
56 else: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
57 source = "pass" # Replace it with a 'pass' statement |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
58 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
59 err = err1 = err2 = None |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
60 code = code1 = code2 = None |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
61 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
62 try: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
63 code = compile(source, filename, symbol) |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
64 except SyntaxError, err: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
65 pass |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
66 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
67 try: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
68 code1 = compile(source + "\n", filename, symbol) |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
69 except SyntaxError, err1: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
70 pass |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
71 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
72 try: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
73 code2 = compile(source + "\n\n", filename, symbol) |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
74 except SyntaxError, err2: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
75 pass |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
76 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
77 if code: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
78 return code |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
79 try: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
80 e1 = err1.__dict__ |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
81 except AttributeError: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
82 e1 = err1 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
83 try: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
84 e2 = err2.__dict__ |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
85 except AttributeError: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
86 e2 = err2 |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
87 if not code1 and e1 == e2: |
|
f8ddd2340398
Moved compile_command() here from code.py, so JPython can provide its
Guido van Rossum <guido@python.org>
parents:
diff
changeset
|
88 raise SyntaxError, err1 |
