Changeset 178

Show
Ignore:
Timestamp:
12/29/06 01:36:00 (2 years ago)
Author:
akhavr
Message:

ticket:370:

  • added Dict support
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • pybeast/trunk/Makefile

    • Property svn:keywords changed from Id to Revision
    r176 r178  
    1 # $Id
     1# $Id: Makefile 176 2006-12-28 11:38:15Z akhavr
    22# Copyright (C) 2001-2006 KDS Software Group http://www.kds.com.ua/ 
    33 
  • pybeast/trunk/ctest/Makefile

    • Property svn:keywords changed from Id to Revision
    r173 r178  
    1 # $Id
     1# $Id: Makefile 173 2006-12-27 18:54:01Z akhavr
    22# Copyright (C) 2001-2006 KDS Software Group 
    33 
  • pybeast/trunk/ctest/__init__.py

    • Property svn:keywords changed from Id to Revision
    r175 r178  
    1 # $Id
     1# $Id: __init__.py 175 2006-12-28 06:37:23Z akhavr
    22# Copyright (C) 2006 KDS Software Group http://www.kds.com.ua 
    33 
  • pybeast/trunk/dtest/Makefile

    • Property svn:keywords changed from Id to Revision
    r175 r178  
    1 # $Id
     1# $Id: Makefile 175 2006-12-28 06:37:23Z akhavr
    22# Copyright (C) 2001-2006 KDS Software Group 
    33 
  • pybeast/trunk/dtest/__init__.py

    • Property svn:keywords changed from Id to Revision
    r175 r178  
    1 # $Id
     1# $Id: __init__.py 175 2006-12-28 06:37:23Z akhavr
    22# Copyright (C) 2006 KDS Software Group http://www.kds.com.ua 
    33 
  • pybeast/trunk/dtest/cov

    • Property svn:keywords changed from Id to Revision
    r175 r178  
    11#!/usr/bin/python 
    2 # $Id
     2# $Id: cov 175 2006-12-28 06:37:23Z akhavr
    33# Copyright (C) 2006 KDS Software Group http://www.kds.com.ua 
    44 
  • pybeast/trunk/dtest/py2py.py

    • Property svn:keywords changed from Id to Revision
    r177 r178  
    1 # $Id
     1# $Id: py2py.py 177 2006-12-28 12:41:17Z akhavr
    22# Copyright (C) 2006 KDS Software Group http://www.kds.com.ua 
    33 
    4 '''Test src.py2py''' 
    5  
    6 from src.py2py import Pep8Formatter, walk 
     4'''Test src.py2py 
     5 
     6$Id: py2py.py 177 2006-12-28 12:41:17Z akhavr $ 
     7Copyright (C) 2006 KDS Software Group http://www.kds.com.ua 
     8''' 
     9 
     10__version__ = '$Revision$' 
     11 
     12from src.py2py import Pep8Formatter, Styler, walk 
    713 
    814import compiler 
     
    5763    def test_add_and_mult_with_subexpr(self): 
    5864        'Test combined add and mult expr' 
    59         self.reformat_and_test('( a + b ) * c') 
     65        self.reformat_and_test('(a + b) * c') 
    6066 
    6167    def test_mult_and_add_with_subexpr(self): 
     
    133139    def test_with_varargs(self): 
    134140        'Test lambda with varargs' 
    135         self.reformat_and_test('a = lambda x, y=1, *args: x + y + len( args )') 
     141        self.reformat_and_test('a = lambda x, y=1, *args: x + y + len(args)') 
    136142 
    137143    def test_with_varargs_and_kw(self): 
    138144        'Test lambda with varargs and kw' 
    139145        self.reformat_and_test( 
    140             'lambda x, y=1, *args, **kw: x + y + len( args ) + len( dir( kw ) )' 
     146            'lambda x, y=1, *args, **kw: x + y + len(args) + len(dir(kw))' 
    141147            ) 
    142148 
    143149    def test_with_just_kw(self): 
    144150        'Test lambda with kw only' 
    145         self.reformat_and_test('lambda x, y=1, **kw: x + y + len( dir( kw ) )') 
    146  
     151        self.reformat_and_test('lambda x, y=1, **kw: x + y + len(dir(kw))') 
     152 
     153 
     154# New in python 2.5, not implemented now 
     155# class IfExp(Expr): 
     156#     'Test IfExp reformatting' 
     157 
     158#     def test_simple(self): 
     159#         'Test simple IfExp' 
     160#         self.reformat_and_test('x = 1 if y >= 0') 
     161 
     162class Dict(Expr): 
     163    'Test Dict reformatting' 
     164 
     165    def test_simple(self): 
     166        'Test simple Dict expr' 
     167        self.reformat_and_test('a = { k : v }') 
     168 
     169    def test_twoitem(self): 
     170        'Test two keys Dict expr' 
     171        self.reformat_and_test('a = { k1 : v1, k2 : v2 }') 
     172 
     173    def test_multiline_dist(self): 
     174        'Test multiline multikey Dict expr' 
     175        self.reformat_and_test('''\ 
     176m = { k1 : v1, 
     177      k2 : v2, 
     178      k3 : v3, 
     179    }''') 
     180 
     181 
     182class NeedSpace(unittest.TestCase): 
     183    'Test need_space before current op function' 
     184     
     185    def test_unary(self): 
     186        'Test unary op' 
     187        self.failUnless(not Styler().need_space(['Invert', 'Const']), 
     188                        'Trying to put a space after an Invert op') 
     189 
     190    def test_parens(self): 
     191        'Test space after parens' 
     192        stack = ['Mul', 'Add', 'Name'] 
     193        self.failUnless(not Styler().need_space(stack), 
     194                        'Trying to put a space after a parens around Add op') 
    147195         
     196 
     197class NeedParens(unittest.TestCase): 
     198    'Test need_parens around current op' 
     199 
     200    def test_mul_the_add(self): 
     201        'Test parens around multiplication to an addition' 
     202        self.failUnless(Styler().need_parens(['Mul', 'Add']), 
     203                        'Failed to put parens around (a + b) * c') 
     204 
     205 
     206class NeedNewline(unittest.TestCase): 
     207    'Test need_newline' 
     208 
     209    def test_dict(self): 
     210        'Test need_newline if so much in the dict' 
     211        self.failUnless(Styler().need_newline(['Dict'], [1, 2, 3]), 
     212                        'Failed to put newlines in the dict when there are ' 
     213                        + 'three items') 
     214 
     215 
     216class AddSpaces(unittest.TestCase): 
     217    'Test add_spaces' 
     218 
     219    def test_simple(self): 
     220        'Should return enough spaces to pad until last carriage return' 
     221        spaces = Styler().add_spaces('\nm = {') 
     222        self.failUnless(spaces==' '*5, 
     223                        'Returned wrong number of spaces: %d' % len(spaces)) 
     224 
     225    def test_firstline(self): 
     226        'This is first line, but we have stil pad correctly' 
     227        spaces = Styler().add_spaces('m = {') 
     228        self.failUnless(spaces==' '*5, 
     229                        'Returned wrong number of spaces: %d' % len(spaces)) 
     230     
     231     
    148232if __name__ == '__main__': 
    149233    unittest.main() 
  • pybeast/trunk/src/Makefile

    • Property svn:keywords changed from Id to Revision
    r173 r178  
    1 # $Id
     1# $Id: Makefile 173 2006-12-27 18:54:01Z akhavr
    22# Copyright (C) 2001-2006 KDS Software Group 
    33 
  • pybeast/trunk/src/__init__.py

    • Property svn:keywords changed from Id to Revision
    r175 r178  
    1 # $Id
     1# $Id: __init__.py 175 2006-12-28 06:37:23Z akhavr
    22# Copyright (C) 2006 KDS Software Group http://www.kds.com.ua 
    33 
  • pybeast/trunk/src/py2py.py

    • Property svn:keywords changed from Id to Revision
    r177 r178  
    1 # $Id
     1# $Id: py2py.py 177 2006-12-28 12:41:17Z akhavr
    22# Copyright (C) 2006 KDS Software Group http://www.kds.com.ua 
    33 
    44'''Dump python AST into a source code 
    55 
    6 $Id
     6$Id: py2py.py 177 2006-12-28 12:41:17Z akhavr
    77Copyright (C) 2006 KDS Software Group http://www.kds.com.ua 
    88''' 
    99 
     10__version__ = '$Revision$' 
     11 
    1012import compiler 
    1113import compiler.consts 
    1214 
    13 def need_parens(inside_op, outside_op): 
    14     'Determines if we need to put parens around inside_op' 
    15     if inside_op in ('Add', 'Sub') and outside_op in ('Mul', 'Div'): 
    16         return 1 
    17     return 0 
     15 
     16class Styler: 
     17    'Sets the parens and space style' 
     18 
     19    def __init__(self): 
     20        self.space_after_parens = 1 
     21        self.space_around_callfunc = 0 
     22     
     23    def need_parens(self, op_stack): 
     24        'Determines if we need to put parens around inside_op' 
     25        if len(op_stack)<2: 
     26            return False 
     27 
     28        outside_op = op_stack[-2] 
     29        inside_op = op_stack[-1] 
     30        if inside_op in ('Add', 'Sub') and outside_op in ('Mul', 'Div'): 
     31            return True 
     32        return False 
     33 
     34    def need_space(self, op_stack): 
     35        'Determines if we need to put a space before a current op' 
     36        if len(op_stack)<2: 
     37            return True 
     38         
     39        if op_stack[-2] in ('Invert', 'Lambda', 'UnaryAdd', 'UnarySub'): 
     40            return False 
     41         
     42        if op_stack[-2] == 'CallFunc': 
     43            return False 
     44         
     45        if self.need_parens(op_stack[:-1]): 
     46            if self.space_after_parens: 
     47                self.space_after_parens = False 
     48            else: 
     49                self.space_after_parens = True 
     50            return self.space_after_parens 
     51        return True 
     52 
     53    def need_newline(self, op_stack, items): 
     54        'Determines if we need to put newline here' 
     55        if len(op_stack)<1: 
     56            return False 
     57         
     58        if op_stack[-1] == 'Dict' and len(items)>2: 
     59            return True 
     60        return False 
     61 
     62    def add_spaces(self, code): 
     63        'Returns string of spaces necessary to pad next string' 
     64        num_spaces = len(code) - 1 - code.rfind('\n') 
     65        return ' '*num_spaces 
     66 
    1867 
    1968class Pep8Formatter: 
     
    2372        self.code = '' 
    2473        self.expr_ops_stack = [] 
     74        self.style = Styler() 
    2575 
    2676    def visit_binop(self, node, walker, code): 
    2777        'visit BinOp node' 
    2878 
    29         need_parens_now = False 
    30  
    31         if len(self.expr_ops_stack)>0: 
    32             upper_node = self.expr_ops_stack[-1] 
    33             need_parens_now = need_parens(node.__class__.__name__, 
    34                                           upper_node) 
     79        need_parens_now = self.style.need_parens(self.expr_ops_stack) 
    3580        if need_parens_now: 
    3681            self.code += ' (' 
    3782             
    38         self.expr_ops_stack.append(node.__class__.__name__) 
    3983        walker.dispatch(node.left) 
    4084        self.code += ' %s' % code 
    4185        walker.dispatch(node.right) 
    42         self.expr_ops_stack.pop() 
    4386         
    4487        if need_parens_now: 
    45             self.code += ' )' 
     88            self.code += ')' 
    4689 
    4790    def visit_list(self, node, walker, code): 
    4891        'visit list join node' 
    49         self.expr_ops_stack.append(node.__class__.__name__) 
    5092        for subnode in node.getChildNodes(): 
    5193            walker.dispatch(subnode) 
     
    5395            continue 
    5496        self.code = self.code[:-len(' %s' %code)] 
    55         self.expr_ops_stack.pop() 
    5697 
    5798    def visit_unary(self, node, walker, code): 
    5899        'visit unary op node' 
    59         self.expr_ops_stack.append(node.__class__.__name__) 
    60100        self.code += ' %s' % code 
    61101        walker.dispatch(node.expr) 
    62         self.expr_ops_stack.pop()         
    63  
     102         
    64103    def visit_assname(self, node, *args): 
    65104        'visit AssName node' 
     
    71110    def visit_callfunc(self, node, walker): 
    72111        'visit CallFunc node' 
    73         self.expr_ops_stack.append(node.__class__.__name__) 
     112        if self.style.need_space(self.expr_ops_stack): 
     113            self.code += ' ' 
    74114        walker.dispatch(node.node) 
    75115        self.code += '(' 
     
    80120        self.code = self.code[:-2] 
    81121 
    82         self.code += ' )' 
    83         self.expr_ops_stack.pop() 
     122        self.code += ')' 
    84123 
    85124    def visit_const(self, node, *args): 
    86125        'visit Const node' 
    87         if self.expr_ops_stack[-1] not in ('Invert', 'Lambda', 'UnaryAdd', 
    88                                            'UnarySub'): 
     126        if self.style.need_space(self.expr_ops_stack): 
    89127            self.code += ' ' 
    90128        self.code += str(node.value) 
     129 
     130    def visit_dict(self, node, walker): 
     131        'visit Dict node' 
     132        self.code += ' {' 
     133 
     134        separator = ',' 
     135        if self.style.need_newline(self.expr_ops_stack, node.items): 
     136            separator += '\n' + self.style.add_spaces(self.code) 
     137        for item in node.items: 
     138            walker.dispatch( item[0] ) 
     139            self.code += ' :' 
     140            walker.dispatch( item[1] ) 
     141            self.code += separator 
     142        self.code = self.code[:-1] 
     143        if not self.style.need_newline(self.expr_ops_stack, node.items): 
     144            self.code += ' ' 
     145        self.code += '}' 
    91146 
    92147    def visit_lambda(self, node, walker): 
    93148        'visit Lambda node' 
    94         self.expr_ops_stack.append(node.__class__.__name__) 
    95  
    96149        len_defaults = len(node.argnames) 
    97150        have_varargs = node.flags & compiler.consts.CO_VARARGS 
     
    130183        walker.dispatch(node.code) 
    131184 
    132         self.expr_ops_stack.pop() 
    133  
    134185    def visit_name(self, node, *args): 
    135186        'visit Name node' 
    136         if self.expr_ops_stack[-1] not in ('Invert', 'Lambda', 'UnaryAdd', 
    137                                            'UnarySub'): 
     187        if self.style.need_space(self.expr_ops_stack): 
    138188            self.code += ' ' 
    139189        self.code += str(node.name) 
     
    183233            meth = self.visitor.map_operation(klass.__name__, self.default) 
    184234            self._cache[klass] = meth 
    185         return meth(node, self) 
     235        self.visitor.expr_ops_stack.append(node.__class__.__name__) 
     236        res = meth(node, self) 
     237        self.visitor.expr_ops_stack.pop() 
     238        return res 
    186239 
    187240def walk(ast, formatter):