Changeset 189

Show
Ignore:
Timestamp:
12/31/06 15:46:50 (2 years ago)
Author:
akhavr
Message:

ticket:371:

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • pybeast/trunk/dtest/py2py.py

    r188 r189  
    4545        self.failUnless(Styler().need_space(stack, 'a = 1 and'), 
    4646                        'Failed to put a space after boolean op sign') 
     47 
     48    def test_function_def_param(self): 
     49        'Test for no space after = in function defaults' 
     50        stack = ['Stmt', 'Function', 'Const'] 
     51        self.failUnless(not Styler().need_space(stack, 'def x(a, b='), 
     52                        'Trying to put a space after = in function default') 
    4753         
    4854 
     
    5460        self.failUnless(Styler().need_parens(['Mul', 'Add']), 
    5561                        'Failed to put parens around (a + b) * c') 
     62 
     63    def test_no_parens_in_if(self): 
     64        'Test no parens in if len(list) < 2:' 
     65        self.failUnless(not Styler().need_parens(['Module', 'Stmt', 'If', 
     66                                                  'Compare', 'CallFunc']), 
     67                        'Tried to put parens as in if(len(op_stack)) < 2:') 
    5668 
    5769 
     
    417429        'from xyz import abc as a' 
    418430        self.reformat_and_test('from unittest import TestCase as tc') 
     431 
     432 
     433class FunctionDef(Expr): 
     434    'Test how we reformat function definitions' 
     435 
     436    def test_simple(self): 
     437        'simple function' 
     438        self.reformat_and_test('def x(a):\n    return 0\n    \n') 
     439 
     440    def test_with_defaults(self): 
     441        'function with defaults' 
     442        self.reformat_and_test('def x(a, b=1):\n    return a + b\n    \n') 
     443 
     444 
     445    def test_with_docstring(self): 
     446        'function with docstring' 
     447        self.reformat_and_test('def x(a):\n    \'This is docstring\'\n' 
     448                               +'    return a * a\n    \n') 
     449 
     450    def test_with_decorators(self): 
     451        'function with decorators' 
     452        self.reformat_and_test('''\ 
     453@dec2 
     454@dec1(param) 
     455def fun(a): 
     456    \'DocString\' 
     457    return a * a 
     458     
     459''' 
     460                               ) 
     461 
     462 
     463class ClassDef(Expr): 
     464    'Test how we handle class definitions' 
     465 
     466    def test_simple(self): 
     467        'test simple class' 
     468        self.reformat_and_test('\nclass X:\n    \n    pass\n    \n') 
     469 
     470    def test_derived_with_docstring(self): 
     471        'test derived class with docstring' 
     472        self.reformat_and_test('\nclass Y(X, Z):\n    \'docstring\'\n    \n' 
     473                               + '    pass\n    \n') 
     474 
     475 
     476class ClassAndConstructor(Expr): 
     477    'Test constructor assignments' 
     478 
     479    def test_styler(self): 
     480        'test src.py2py.Styler constructor' 
     481        self.reformat_and_test(''' 
     482class Styler: 
     483    \'Sets the parens and space style\' 
     484     
     485    def __init__(self): 
     486        self.space_after_parens = 1 
     487        self.offset = 0 
    419488         
     489     
     490''') 
     491 
     492class If(Expr): 
     493    'Test If statement handling' 
     494 
     495    def test_simple(self): 
     496        'test simple if' 
     497        self.reformat_and_test('if len(op_stack) < 2:\n    return False\n' 
     498                               +'    \n') 
     499 
    420500     
    421501if __name__ == '__main__': 
  • pybeast/trunk/src/py2py.py

    r188 r189  
    1919    def __init__(self): 
    2020        self.space_after_parens = 1 
    21         self.space_around_callfunc = 0 
     21        self.offset = 0 
    2222     
    2323    def need_parens(self, op_stack): 
     
    3030        if inside_op in ('Add', 'Sub') and outside_op in ('Mul', 'Div'): 
    3131            return True 
    32         if outside_op == 'Compare' and inside_op not in ('Name', 'Const'): 
     32        if outside_op == 'Compare' and inside_op not in ('Name', 'Const', 
     33                                                         'CallFunc',): 
    3334            return True 
    3435        return False 
     
    4344         
    4445        if op_stack[-2] in ('Invert', 'Lambda', 'UnaryAdd', 'UnarySub', 
    45                             'CallFunc',): 
     46                            'CallFunc', 'Function'): 
    4647            return False 
    4748 
     
    7879        num_spaces = len(code) - code.rfind('\n') 
    7980        return ' '*num_spaces 
     81 
     82    def get_newline(self): 
     83        'Returns newline and offset to the next non-space symbol' 
     84        return '\n' + ' '*self.offset 
     85 
     86    def add_offset(self): 
     87        'Creates block' 
     88        self.offset += 4 
     89 
     90    def sub_offset(self): 
     91        'Closes block' 
     92        self.offset -= 4 
    8093 
    8194 
     
    115128        self.code = self.code[:-len(' %s' %code)] 
    116129 
     130    def visit_function_paramlist(self, node, walker): 
     131        'visit function parameter list' 
     132        len_defaults = len(node.argnames) 
     133        have_varargs = node.flags & compiler.consts.CO_VARARGS 
     134        have_varkeywords = node.flags & compiler.consts.CO_VARKEYWORDS 
     135 
     136        if have_varargs: 
     137            len_defaults -= 1 
     138        if have_varkeywords: 
     139            len_defaults -= 1 
     140        defaults = [None] * len_defaults 
     141        defaults[:len(node.defaults)] = node.defaults 
     142        defaults.reverse() 
     143 
     144        prefix = '' 
     145        for i in range( len(node.argnames) ): 
     146            arg = node.argnames[i] 
     147            try: 
     148                default = defaults[i] 
     149            except IndexError: 
     150                default = None 
     151                if prefix == '' and have_varargs: 
     152                    prefix = '*' 
     153                else: 
     154                    prefix = '**' 
     155            if self.style.need_space(self.expr_ops_stack, self.code): 
     156                self.code += ' ' 
     157            self.code += '%s%s' % (prefix, arg) 
     158            if default is None: 
     159                self.code += ',' 
     160            else: 
     161                self.code += '=' 
     162                walker.dispatch(default) 
     163                self.code += ',' 
     164         
    117165    def visit_sequence(self, node, walker, braket): 
    118166        'visit List node' 
     
    132180        self.code += code 
    133181        walker.dispatch(node.expr) 
     182 
     183    # only specific nodes below 
     184 
     185    def visit_assattr(self, node, walker): 
     186        'visit AssAttr node' 
     187        if self.style.need_space(self.expr_ops_stack, self.code): 
     188            self.code += ' ' 
     189        walker.dispatch(node.expr) 
     190        self.code += '.'+node.attrname 
     191        if node.flags == 'OP_ASSIGN': 
     192            self.code += ' =' 
     193         
    134194         
    135195    def visit_assname(self, node, *args): 
     
    180240 
    181241        self.code += ')' 
     242 
     243    def visit_class(self, node, walker): 
     244        'visit Class node' 
     245        self.code += self.style.get_newline() 
     246        self.code += 'class ' 
     247        self.code += node.name 
     248        if node.bases: 
     249            self.code += '(' 
     250            for base in node.bases: 
     251                walker.dispatch(base) 
     252                self.code += ',' 
     253            self.code = self.code[:-1] + ')' 
     254                     
     255        self.code += ':' 
     256        self.style.add_offset() 
     257        self.code += self.style.get_newline() 
     258 
     259        if node.doc: 
     260            self.code += repr(node.doc) 
     261            self.code += self.style.get_newline() 
     262        self.code += self.style.get_newline() 
     263        walker.dispatch(node.code) 
     264        self.style.sub_offset() 
    182265 
    183266    def visit_compare(self, node, walker): 
     
    219302        self.code += '}' 
    220303 
     304    def visit_from(self, node, walker): 
     305        'visit From node (from xyz import abc)' 
     306        self.code += 'from %s import' % node.modname 
     307        for name in node.names: 
     308            self.code += ' %s' % name[0] 
     309            if name[1]: 
     310                self.code += ' as %s' % name[1] 
     311            self.code += ',' 
     312        self.code = self.code[:-1] 
     313 
     314    def visit_function(self, node, walker): 
     315        'visit Function node' 
     316        if node.decorators: 
     317            for decorator in node.decorators: 
     318                self.code += '@' 
     319                walker.dispatch(decorator) 
     320                self.code += self.style.get_newline() 
     321         
     322        self.code += 'def %s(' % node.name 
     323 
     324        self.visit_function_paramlist(node, walker)                 
     325        self.code = self.code[:-1] + '):' 
     326         
     327        self.style.add_offset() 
     328        self.code += self.style.get_newline() 
     329 
     330        if node.doc: 
     331            self.code += "'%s'" % node.doc 
     332            self.code += self.style.get_newline() 
     333 
     334        walker.dispatch(node.code) 
     335        self.style.sub_offset() 
     336 
    221337    def visit_getattr(self, node, walker): 
    222338        'visit Getattr node' 
     
    237353                walker.dispatch(ifs) 
    238354 
    239     def visit_from(self, node, walker): 
    240         'visit From node (from xyz import abc)' 
    241         self.code += 'from %s import' % node.modname 
    242         for name in node.names: 
    243             self.code += ' %s' % name[0] 
    244             if name[1]: 
    245                 self.code += ' as %s' % name[1] 
    246             self.code += ',' 
    247         self.code = self.code[:-1] 
     355    def visit_if(self, node, walker): 
     356        'visit If node' 
     357        self.code += 'if' 
     358        for test in node.tests: 
     359            walker.dispatch(test[0]) 
     360            self.code += ':' 
     361            self.style.add_offset() 
     362            self.code += self.style.get_newline() 
     363            walker.dispatch(test[1]) 
     364            self.style.sub_offset() 
    248365 
    249366    def visit_import(self, node, walker): 
     
    264381    def visit_lambda(self, node, walker): 
    265382        'visit Lambda node' 
    266         len_defaults = len(node.argnames) 
    267         have_varargs = node.flags & compiler.consts.CO_VARARGS 
    268         have_varkeywords = node.flags & compiler.consts.CO_VARKEYWORDS 
    269  
    270         if have_varargs: 
    271             len_defaults -= 1 
    272         if have_varkeywords: 
    273             len_defaults -= 1 
    274         defaults = [None] * len_defaults 
    275         defaults[:len(node.defaults)] = node.defaults 
    276         defaults.reverse() 
    277  
    278383        if self.style.need_space(self.expr_ops_stack, self.code): 
    279384            self.code += ' ' 
    280385        self.code += 'lambda' 
    281  
    282         prefix = '' 
    283         for i in range( len(node.argnames) ): 
    284             arg = node.argnames[i] 
    285             try: 
    286                 default = defaults[i] 
    287             except IndexError: 
    288                 default = None 
    289                 if prefix == '' and have_varargs: 
    290                     prefix = '*' 
    291                 else: 
    292                     prefix = '**' 
    293             self.code += ' %s%s' % (prefix, arg) 
    294             if default is None: 
    295                 self.code += ',' 
    296             else: 
    297                 self.code += '=' 
    298                 walker.dispatch(default) 
    299                 self.code += ',' 
    300                  
     386        self.visit_function_paramlist(node, walker)                 
    301387        self.code = self.code[:-1] + ':' 
    302388        walker.dispatch(node.code) 
     
    328414        self.code += str(node.name) 
    329415 
     416    def visit_pass(self, node, walker): 
     417        'visit Pass node' 
     418        self.code += 'pass' 
     419 
     420    def visit_return(self, node, walker): 
     421        'visit Return node' 
     422        self.code += 'return' 
     423        walker.dispatch(node.value) 
     424 
    330425    def visit_stmt(self, node, walker): 
    331426        'visit Stmt node' 
    332427        for stmt_node in node.nodes: 
    333428            walker.dispatch(stmt_node) 
    334             self.code += '\n' 
     429            self.code += self.style.get_newline() 
    335430 
    336431    def visit_subscript(self, node, walker):