[py-svn] r9642 - in py/dist/py: . code code/testing

hpk at codespeak.net hpk at codespeak.net
Fri Mar 4 18:21:51 CET 2005


Author: hpk
Date: Fri Mar  4 18:21:50 2005
New Revision: 9642

Added:
   py/dist/py/code/code.py
      - copied, changed from r9470, py/dist/py/code/frame.py
   py/dist/py/code/testing/test_code.py   (contents, props changed)
Modified:
   py/dist/py/__init__.py
   py/dist/py/code/frame.py
   py/dist/py/code/source.py
   py/dist/py/code/testing/test_source.py
   py/dist/py/code/traceback.py   (props changed)
Log:
refactored py.code.Code() to directly offer
a convienent new() method that returns a raw code object
with modified attributes.   Now you can say: 

    py.code.Code(rawpycode).new(co_filename="newfilename")

and this returns a cpython code object with a modified 
co_filename.  if you specify rec=True like so: 

    py.code.Code(rawpycode).new(rec=True, co_filename="newfilename")

then you will get a raw python code object where all the
inner code object have their co_filename changed as well. 

We might later want to allow passing a function instead of just 
true as a value for "rec" to change code objects more 
dynamically ... 

added a couple of tests. 



Modified: py/dist/py/__init__.py
==============================================================================
--- py/dist/py/__init__.py	(original)
+++ py/dist/py/__init__.py	Fri Mar  4 18:21:50 2005
@@ -42,7 +42,7 @@
 
     'code.compile'           : ('./code/source.py', 'compile_'),
     'code.Source'            : ('./code/source.py', 'Source'),
-    'code.Code'              : ('./code/frame.py', 'Code'),
+    'code.Code'              : ('./code/code.py', 'Code'),
     'code.Frame'             : ('./code/frame.py', 'Frame'),
     'code.ExceptionInfo'     : ('./code/excinfo.py', 'ExceptionInfo'),
     'code.Traceback'         : ('./code/traceback.py', 'Traceback'),

Copied: py/dist/py/code/code.py (from r9470, py/dist/py/code/frame.py)
==============================================================================
--- py/dist/py/code/frame.py	(original)
+++ py/dist/py/code/code.py	Fri Mar  4 18:21:50 2005
@@ -1,10 +1,51 @@
 import py
 
 class Code(object):
-    def __init__(self, f_code):
-        self.raw = f_code
-        self.firstlineno = f_code.co_firstlineno - 1
-        self.name = f_code.co_name
+    def __init__(self, rawcode):
+        self.raw = rawcode 
+        self.firstlineno = rawcode.co_firstlineno - 1
+        self.name = rawcode.co_name
+        
+    def __eq__(self, other): 
+        return self.raw == other.raw 
+
+    def new(self, rec=False, **kwargs): 
+        """ return new code object with modified attributes. 
+            if rec-cursive is true then dive into code 
+            objects contained in co_consts. 
+        """ 
+        names = [x for x in dir(self.raw) if x[:3] == 'co_']
+        for name in kwargs: 
+            if name not in names: 
+                raise TypeError("unknown code attribute: %r" %(name, ))
+        if rec: 
+            newconstlist = []
+            co = self.raw
+            cotype = type(co)
+            for c in co.co_consts:
+                if isinstance(c, cotype):
+                    c = self.__class__(c).new(rec=True, **kwargs) 
+                newconstlist.append(c)
+            return self.new(rec=False, co_consts=tuple(newconstlist), **kwargs) 
+        for name in names:
+            if name not in kwargs:
+                kwargs[name] = getattr(self.raw, name)
+        return py.std.new.code(
+                 kwargs['co_argcount'],
+                 kwargs['co_nlocals'],
+                 kwargs['co_stacksize'],
+                 kwargs['co_flags'],
+                 kwargs['co_code'],
+                 kwargs['co_consts'],
+                 kwargs['co_names'],
+                 kwargs['co_varnames'],
+                 kwargs['co_filename'],
+                 kwargs['co_name'],
+                 kwargs['co_firstlineno'],
+                 kwargs['co_lnotab'],
+                 kwargs['co_freevars'],
+                 kwargs['co_cellvars'],
+        )
 
     def path(self):
         try:
@@ -22,34 +63,3 @@
     fullsource = property(fullsource, None, None,
                           "full source containing this code object")
 
-
-class Frame(object):
-    """Wrapper around a Python frame holding f_locals and f_globals
-    in which expressions can be evaluated."""
-
-    def __init__(self, frame):
-        self.code = Code(frame.f_code)
-        self.lineno = frame.f_lineno - 1
-        self.f_globals = frame.f_globals
-        self.f_locals = frame.f_locals
-
-    def statement(self):
-        return self.code.fullsource.getstatement(self.lineno)
-    statement = property(statement, None, None,
-                         "statement this frame is at")
-
-    def eval(self, code, **vars):
-        self.f_locals.update(vars)
-        return eval(code, self.f_globals, self.f_locals)
-
-    def exec_(self, code, **vars):
-        self.f_locals.update(vars)
-        exec code in self.f_globals, self.f_locals
-
-    def repr(self, object):
-        return repr(object)
-
-    def is_true(self, object):
-        return object
-
-

Modified: py/dist/py/code/frame.py
==============================================================================
--- py/dist/py/code/frame.py	(original)
+++ py/dist/py/code/frame.py	Fri Mar  4 18:21:50 2005
@@ -1,34 +1,11 @@
 import py
 
-class Code(object):
-    def __init__(self, f_code):
-        self.raw = f_code
-        self.firstlineno = f_code.co_firstlineno - 1
-        self.name = f_code.co_name
-
-    def path(self):
-        try:
-            return self.raw.co_filename.__path__
-        except AttributeError:
-            return py.path.local(self.raw.co_filename)
-    path = property(path, None, None, "path of this code object")
-
-    def fullsource(self):
-        fn = self.raw.co_filename
-        try:
-            return fn.__source__
-        except AttributeError:
-            return py.code.Source(self.path.read(mode="rU"))
-    fullsource = property(fullsource, None, None,
-                          "full source containing this code object")
-
-
 class Frame(object):
     """Wrapper around a Python frame holding f_locals and f_globals
     in which expressions can be evaluated."""
 
     def __init__(self, frame):
-        self.code = Code(frame.f_code)
+        self.code = py.code.Code(frame.f_code)
         self.lineno = frame.f_lineno - 1
         self.f_globals = frame.f_globals
         self.f_locals = frame.f_locals

Modified: py/dist/py/code/source.py
==============================================================================
--- py/dist/py/code/source.py	(original)
+++ py/dist/py/code/source.py	Fri Mar  4 18:21:50 2005
@@ -193,7 +193,8 @@
         else:
             co_filename = MyStr(filename)
             co_filename.__source__ = self
-            return newcode_withfilename(co, co_filename)
+            return py.code.Code(co).new(rec=1, co_filename=co_filename) 
+            #return newcode_withfilename(co, co_filename)
 
 #
 # public API shortcut functions
@@ -255,36 +256,3 @@
         newlines.append(line)
     return newlines
 
-def newcode(fromcode, **kwargs):
-    names = [x for x in dir(fromcode) if x[:3] == 'co_']
-    for name in names:
-        if name not in kwargs:
-            kwargs[name] = getattr(fromcode, name)
-    import new
-    return new.code(
-             kwargs['co_argcount'],
-             kwargs['co_nlocals'],
-             kwargs['co_stacksize'],
-             kwargs['co_flags'],
-             kwargs['co_code'],
-             kwargs['co_consts'],
-             kwargs['co_names'],
-             kwargs['co_varnames'],
-             kwargs['co_filename'],
-             kwargs['co_name'],
-             kwargs['co_firstlineno'],
-             kwargs['co_lnotab'],
-             kwargs['co_freevars'],
-             kwargs['co_cellvars'],
-    )
-
-def newcode_withfilename(co, co_filename):
-    newconstlist = []
-    cotype = type(co)
-    for c in co.co_consts:
-        if isinstance(c, cotype):
-            c = newcode_withfilename(c, co_filename)
-        newconstlist.append(c)
-    return newcode(co, co_consts = tuple(newconstlist),
-                       co_filename = co_filename)
-

Added: py/dist/py/code/testing/test_code.py
==============================================================================
--- (empty file)
+++ py/dist/py/code/testing/test_code.py	Fri Mar  4 18:21:50 2005
@@ -0,0 +1,50 @@
+import py
+
+def test_newcode(): 
+    source = "i = 3"
+    co = compile(source, '', 'exec') 
+    code = py.code.Code(co) 
+    newco = code.new() 
+    assert co == newco 
+
+def test_newcode_unknown_args(): 
+    code = py.code.Code(compile("", '', 'exec'))
+    py.test.raises(TypeError, 'code.new(filename="hello")')
+
+def test_newcode_withfilename():
+    source = py.code.Source("""
+        def f():
+            def g():
+                pass
+    """)
+    co = compile(str(source)+'\n', 'nada', 'exec')
+    obj = 'hello'
+    newco = py.code.Code(co).new(rec=True, co_filename=obj)
+    def walkcode(co):
+        for x in co.co_consts:
+            if isinstance(x, type(co)):
+                for y in walkcode(x):
+                    yield y
+        yield co
+
+    names = []
+    for code in walkcode(newco):
+        assert newco.co_filename == obj
+        assert newco.co_filename is obj
+        names.append(code.co_name)
+    assert 'f' in names
+    assert 'g' in names
+
+def test_newcode_with_filename(): 
+    source = "i = 3"
+    co = compile(source, '', 'exec') 
+    code = py.code.Code(co) 
+    class MyStr(str): 
+        pass 
+    filename = MyStr("hello") 
+    filename.__source__ = py.code.Source(source) 
+    newco = code.new(rec=True, co_filename=filename) 
+    assert newco.co_filename is filename 
+    s = py.code.Source(newco) 
+    assert str(s) == source 
+

Modified: py/dist/py/code/testing/test_source.py
==============================================================================
--- py/dist/py/code/testing/test_source.py	(original)
+++ py/dist/py/code/testing/test_source.py	Fri Mar  4 18:21:50 2005
@@ -109,41 +109,6 @@
         l = [x for x in self.source] 
         assert len(l) == 4 
             
-
-class TestCodeHacks:
-    def test_newcode(self):
-        from py.__impl__.code.source import newcode
-        def f():
-            pass
-        co_filename = 'hello'
-        c = newcode(f.func_code, co_filename=co_filename)
-        assert c.co_filename is co_filename
-
-    def test_newcode_withfilename(self):
-        from py.__impl__.code.source import newcode_withfilename
-        source = py.code.Source("""
-            def f():
-                def g():
-                    pass
-        """)
-        co = compile(str(source)+'\n', 'nada', 'exec')
-        obj = 'hello'
-        newco = newcode_withfilename(co, obj)
-        def walkcode(co):
-            for x in co.co_consts:
-                if isinstance(x, type(co)):
-                    for y in walkcode(x):
-                        yield y
-            yield co
-
-        names = []
-        for code in walkcode(newco):
-            assert newco.co_filename == obj
-            assert newco.co_filename is obj
-            names.append(code.co_name)
-        assert 'f' in names
-        assert 'g' in names
-
 class TestSourceParsingAndCompiling:
     source = Source("""\
         def f(x):



More information about the pytest-commit mailing list