]> granicus.if.org Git - python/commitdiff
Checking in new module code.py -- utilities dealing with code objects.
authorGuido van Rossum <guido@python.org>
Fri, 18 Jul 1997 16:57:52 +0000 (16:57 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 18 Jul 1997 16:57:52 +0000 (16:57 +0000)
Currently, contains one function: compile_command(), which helps
determining whether a source string is complete, incomplete or in
error.  This is useful when writing your own version of the Python
read-eval-print loop.

Lib/code.py [new file with mode: 0644]

diff --git a/Lib/code.py b/Lib/code.py
new file mode 100644 (file)
index 0000000..49fe541
--- /dev/null
@@ -0,0 +1,52 @@
+"""Utilities dealing with code objects."""
+
+def compile_command(source, filename="<input>", symbol="single"):
+    r"""Compile a command and determine whether it is incomplete.
+
+    Arguments:
+
+    source -- the source string; may contain \n characters
+    filename -- optional filename from which source was read; default "<input>"
+    symbol -- optional grammar start symbol; "single" (default) or "eval"
+
+    Return value / exception raised:
+
+    - Return a code object if the command is complete and valid
+    - Return None if the command is incomplete
+    - Raise SyntaxError if the command is a syntax error
+
+    Approach:
+    
+    Compile three times: as is, with \n, and with \n\n appended.  If
+    it compiles as is, it's complete.  If it compiles with one \n
+    appended, we expect more.  If it doesn't compile either way, we
+    compare the error we get when compiling with \n or \n\n appended.
+    If the errors are the same, the code is broken.  But if the errors
+    are different, we expect more.  Not intuitive; not even guaranteed
+    to hold in future releases; but this matches the compiler's
+    behavior in Python 1.4 and 1.5.
+
+    """
+
+    err = err1 = err2 = None
+    code = code1 = code2 = None
+
+    try:
+       code = compile(source, filename, symbol)
+    except SyntaxError, err:
+       pass
+
+    try:
+       code1 = compile(source + "\n", filename, symbol)
+    except SyntaxError, err1:
+       pass
+
+    try:
+       code2 = compile(source + "\n\n", filename, symbol)
+    except SyntaxError, err2:
+       pass
+
+    if code:
+       return code
+    if not code1 and err1 == err2:
+       raise SyntaxError, err1