Back to index

python3.2  3.2.2
codeop.py
Go to the documentation of this file.
00001 r"""Utilities to compile possibly incomplete Python source code.
00002 
00003 This module provides two interfaces, broadly similar to the builtin
00004 function compile(), which take program text, a filename and a 'mode'
00005 and:
00006 
00007 - Return code object if the command is complete and valid
00008 - Return None if the command is incomplete
00009 - Raise SyntaxError, ValueError or OverflowError if the command is a
00010   syntax error (OverflowError and ValueError can be produced by
00011   malformed literals).
00012 
00013 Approach:
00014 
00015 First, check if the source consists entirely of blank lines and
00016 comments; if so, replace it with 'pass', because the built-in
00017 parser doesn't always do the right thing for these.
00018 
00019 Compile three times: as is, with \n, and with \n\n appended.  If it
00020 compiles as is, it's complete.  If it compiles with one \n appended,
00021 we expect more.  If it doesn't compile either way, we compare the
00022 error we get when compiling with \n or \n\n appended.  If the errors
00023 are the same, the code is broken.  But if the errors are different, we
00024 expect more.  Not intuitive; not even guaranteed to hold in future
00025 releases; but this matches the compiler's behavior from Python 1.4
00026 through 2.2, at least.
00027 
00028 Caveat:
00029 
00030 It is possible (but not likely) that the parser stops parsing with a
00031 successful outcome before reaching the end of the source; in this
00032 case, trailing symbols may be ignored instead of causing an error.
00033 For example, a backslash followed by two newlines may be followed by
00034 arbitrary garbage.  This will be fixed once the API for the parser is
00035 better.
00036 
00037 The two interfaces are:
00038 
00039 compile_command(source, filename, symbol):
00040 
00041     Compiles a single command in the manner described above.
00042 
00043 CommandCompiler():
00044 
00045     Instances of this class have __call__ methods identical in
00046     signature to compile_command; the difference is that if the
00047     instance compiles program text containing a __future__ statement,
00048     the instance 'remembers' and compiles all subsequent program texts
00049     with the statement in force.
00050 
00051 The module also provides another class:
00052 
00053 Compile():
00054 
00055     Instances of this class act like the built-in function compile,
00056     but with 'memory' in the sense described above.
00057 """
00058 
00059 import __future__
00060 
00061 _features = [getattr(__future__, fname)
00062              for fname in __future__.all_feature_names]
00063 
00064 __all__ = ["compile_command", "Compile", "CommandCompiler"]
00065 
00066 PyCF_DONT_IMPLY_DEDENT = 0x200          # Matches pythonrun.h
00067 
00068 def _maybe_compile(compiler, source, filename, symbol):
00069     # Check for source consisting of only blank lines and comments
00070     for line in source.split("\n"):
00071         line = line.strip()
00072         if line and line[0] != '#':
00073             break               # Leave it alone
00074     else:
00075         if symbol != "eval":
00076             source = "pass"     # Replace it with a 'pass' statement
00077 
00078     err = err1 = err2 = None
00079     code = code1 = code2 = None
00080 
00081     try:
00082         code = compiler(source, filename, symbol)
00083     except SyntaxError as err:
00084         pass
00085 
00086     try:
00087         code1 = compiler(source + "\n", filename, symbol)
00088     except SyntaxError as e:
00089         err1 = e
00090 
00091     try:
00092         code2 = compiler(source + "\n\n", filename, symbol)
00093     except SyntaxError as e:
00094         err2 = e
00095 
00096     if code:
00097         return code
00098     if not code1 and repr(err1) == repr(err2):
00099         raise err1
00100 
00101 def _compile(source, filename, symbol):
00102     return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT)
00103 
00104 def compile_command(source, filename="<input>", symbol="single"):
00105     r"""Compile a command and determine whether it is incomplete.
00106 
00107     Arguments:
00108 
00109     source -- the source string; may contain \n characters
00110     filename -- optional filename from which source was read; default
00111                 "<input>"
00112     symbol -- optional grammar start symbol; "single" (default) or "eval"
00113 
00114     Return value / exceptions raised:
00115 
00116     - Return a code object if the command is complete and valid
00117     - Return None if the command is incomplete
00118     - Raise SyntaxError, ValueError or OverflowError if the command is a
00119       syntax error (OverflowError and ValueError can be produced by
00120       malformed literals).
00121     """
00122     return _maybe_compile(_compile, source, filename, symbol)
00123 
00124 class Compile:
00125     """Instances of this class behave much like the built-in compile
00126     function, but if one is used to compile text containing a future
00127     statement, it "remembers" and compiles all subsequent program texts
00128     with the statement in force."""
00129     def __init__(self):
00130         self.flags = PyCF_DONT_IMPLY_DEDENT
00131 
00132     def __call__(self, source, filename, symbol):
00133         codeob = compile(source, filename, symbol, self.flags, 1)
00134         for feature in _features:
00135             if codeob.co_flags & feature.compiler_flag:
00136                 self.flags |= feature.compiler_flag
00137         return codeob
00138 
00139 class CommandCompiler:
00140     """Instances of this class have __call__ methods identical in
00141     signature to compile_command; the difference is that if the
00142     instance compiles program text containing a __future__ statement,
00143     the instance 'remembers' and compiles all subsequent program texts
00144     with the statement in force."""
00145 
00146     def __init__(self,):
00147         self.compiler = Compile()
00148 
00149     def __call__(self, source, filename="<input>", symbol="single"):
00150         r"""Compile a command and determine whether it is incomplete.
00151 
00152         Arguments:
00153 
00154         source -- the source string; may contain \n characters
00155         filename -- optional filename from which source was read;
00156                     default "<input>"
00157         symbol -- optional grammar start symbol; "single" (default) or
00158                   "eval"
00159 
00160         Return value / exceptions raised:
00161 
00162         - Return a code object if the command is complete and valid
00163         - Return None if the command is incomplete
00164         - Raise SyntaxError, ValueError or OverflowError if the command is a
00165           syntax error (OverflowError and ValueError can be produced by
00166           malformed literals).
00167         """
00168         return _maybe_compile(self.compiler, source, filename, symbol)