| r"""Utilities to compile possibly incomplete Python source code. | 
 |  | 
 | This module provides two interfaces, broadly similar to the builtin | 
 | function compile(), which take program text, a filename and a 'mode' | 
 | and: | 
 |  | 
 | - Return code object if the command is complete and valid | 
 | - Return None if the command is incomplete | 
 | - Raise SyntaxError, ValueError or OverflowError if the command is a | 
 |   syntax error (OverflowError and ValueError can be produced by | 
 |   malformed literals). | 
 |  | 
 | Approach: | 
 |  | 
 | First, check if the source consists entirely of blank lines and | 
 | comments; if so, replace it with 'pass', because the built-in | 
 | parser doesn't always do the right thing for these. | 
 |  | 
 | 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 from Python 1.4 | 
 | through 2.2, at least. | 
 |  | 
 | Caveat: | 
 |  | 
 | It is possible (but not likely) that the parser stops parsing with a | 
 | successful outcome before reaching the end of the source; in this | 
 | case, trailing symbols may be ignored instead of causing an error. | 
 | For example, a backslash followed by two newlines may be followed by | 
 | arbitrary garbage.  This will be fixed once the API for the parser is | 
 | better. | 
 |  | 
 | The two interfaces are: | 
 |  | 
 | compile_command(source, filename, symbol): | 
 |  | 
 |     Compiles a single command in the manner described above. | 
 |  | 
 | CommandCompiler(): | 
 |  | 
 |     Instances of this class have __call__ methods identical in | 
 |     signature to compile_command; the difference is that if the | 
 |     instance compiles program text containing a __future__ statement, | 
 |     the instance 'remembers' and compiles all subsequent program texts | 
 |     with the statement in force. | 
 |  | 
 | The module also provides another class: | 
 |  | 
 | Compile(): | 
 |  | 
 |     Instances of this class act like the built-in function compile, | 
 |     but with 'memory' in the sense described above. | 
 | """ | 
 |  | 
 | import __future__ | 
 |  | 
 | _features = [getattr(__future__, fname) | 
 |              for fname in __future__.all_feature_names] | 
 |  | 
 | __all__ = ["compile_command", "Compile", "CommandCompiler"] | 
 |  | 
 | PyCF_DONT_IMPLY_DEDENT = 0x200          # Matches pythonrun.h | 
 |  | 
 | def _maybe_compile(compiler, source, filename, symbol): | 
 |     # Check for source consisting of only blank lines and comments | 
 |     for line in source.split("\n"): | 
 |         line = line.strip() | 
 |         if line and line[0] != '#': | 
 |             break               # Leave it alone | 
 |     else: | 
 |         if symbol != "eval": | 
 |             source = "pass"     # Replace it with a 'pass' statement | 
 |  | 
 |     err = err1 = err2 = None | 
 |     code = code1 = code2 = None | 
 |  | 
 |     try: | 
 |         code = compiler(source, filename, symbol) | 
 |     except SyntaxError as err: | 
 |         pass | 
 |  | 
 |     try: | 
 |         code1 = compiler(source + "\n", filename, symbol) | 
 |     except SyntaxError as e: | 
 |         err1 = e | 
 |  | 
 |     try: | 
 |         code2 = compiler(source + "\n\n", filename, symbol) | 
 |     except SyntaxError as e: | 
 |         err2 = e | 
 |  | 
 |     if code: | 
 |         return code | 
 |     if not code1 and repr(err1) == repr(err2): | 
 |         raise SyntaxError(err1) | 
 |  | 
 | def _compile(source, filename, symbol): | 
 |     return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT) | 
 |  | 
 | 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 / exceptions raised: | 
 |  | 
 |     - Return a code object if the command is complete and valid | 
 |     - Return None if the command is incomplete | 
 |     - Raise SyntaxError, ValueError or OverflowError if the command is a | 
 |       syntax error (OverflowError and ValueError can be produced by | 
 |       malformed literals). | 
 |     """ | 
 |     return _maybe_compile(_compile, source, filename, symbol) | 
 |  | 
 | class Compile: | 
 |     """Instances of this class behave much like the built-in compile | 
 |     function, but if one is used to compile text containing a future | 
 |     statement, it "remembers" and compiles all subsequent program texts | 
 |     with the statement in force.""" | 
 |     def __init__(self): | 
 |         self.flags = PyCF_DONT_IMPLY_DEDENT | 
 |  | 
 |     def __call__(self, source, filename, symbol): | 
 |         codeob = compile(source, filename, symbol, self.flags, 1) | 
 |         for feature in _features: | 
 |             if codeob.co_flags & feature.compiler_flag: | 
 |                 self.flags |= feature.compiler_flag | 
 |         return codeob | 
 |  | 
 | class CommandCompiler: | 
 |     """Instances of this class have __call__ methods identical in | 
 |     signature to compile_command; the difference is that if the | 
 |     instance compiles program text containing a __future__ statement, | 
 |     the instance 'remembers' and compiles all subsequent program texts | 
 |     with the statement in force.""" | 
 |  | 
 |     def __init__(self,): | 
 |         self.compiler = Compile() | 
 |  | 
 |     def __call__(self, 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 / exceptions raised: | 
 |  | 
 |         - Return a code object if the command is complete and valid | 
 |         - Return None if the command is incomplete | 
 |         - Raise SyntaxError, ValueError or OverflowError if the command is a | 
 |           syntax error (OverflowError and ValueError can be produced by | 
 |           malformed literals). | 
 |         """ | 
 |         return _maybe_compile(self.compiler, source, filename, symbol) |