├── requirements.txt
├── tests
├── __init__.py
├── modules
│ ├── __init__.py
│ ├── without_all.py
│ └── with_all.py
├── simple_print.py
├── simple_lambda.py
├── chain.py
├── compare.py
├── future_braces.py
├── lambda.py
├── dictionary.py
├── if.py
├── simple_slice.py
├── simple_state.py
├── division.py
├── function.py
├── function_name.py
├── future_division.py
├── importdot.py
├── set.py
├── tuple.py
├── class_free.py
├── genexp.py
├── nullary.py
├── scope.py
├── imports.py
├── ifelse.py
├── while.py
├── for_return.py
├── future_unicode_literals.py
├── global.py
├── importfrom.py
├── override_builtin.py
├── 1line.py
├── boring_try.py
├── future_division_inplace.py
├── future_print_function.py
├── num_repr.py
├── return_exec_defined_variable.py
├── unimplemented
│ ├── class_doc_scope.py
│ ├── argument_named_print.py
│ ├── softspace.py
│ ├── exec_local_return_behavior.py
│ ├── print_eval_order.py
│ ├── 9lines.py
│ ├── 20lines.py
│ └── reraise_bug.py
├── binding_indeterminate.py
├── future_absolute_import.py
├── aug.py
├── ifelifelse.py
├── name_main.py
├── return_none.py
├── slice.py
├── aug_coerce.py
├── closing_over.py
├── reassignment.py
├── 2lines.py
├── reraise.py
├── exec.py
├── call.py
├── closing_over_2.py
├── fibonacci.py
├── if_comprehensive.py
├── future_braces_as_division.py
├── future_division_as_braces.py
├── html_module.py
├── ifelse_comprehensive.py
├── 5lines.py
├── count_vowels.py
├── list_comprehension.py
├── try_finally_except.py
├── decorated_function_name.py
├── finally_return_swallows_exception.py
├── try_try_again.py
├── 3lines.py
├── 4lines.py
├── old_style_class.py
├── decorator_order.py
├── import_specific.py
├── closure.py
├── decorator.py
├── aug_getattr.py
├── 8lines.py
├── class_function_scope.py
├── 6lines.py
├── future_division_eval.py
├── relative_import.py
├── metaclass.py
├── 7lines.py
├── print.py
├── ifelifelse_comprehensive.py
├── del.py
├── for.py
├── 11lines.py
├── while_break_continue_else.py
├── aug_getattribute.py
├── for_break_continue_else.py
├── 14lines.py
├── 12lines.py
├── closure_mutate.py
├── 13lines.py
├── 15lines.py
├── exec_scope.py
├── 10lines.py
├── guess_my_number.py
├── slice_getattribute.py
├── mangle.py
├── exec_del.py
├── 18lines.py
├── 16lines.py
├── try_finally.py
├── 33lines.py
├── prime_tester.py
├── 28lines.py
├── 21lines.py
├── scope_comprehension.py
├── try_except.py
├── slice_torture.py
├── doc.py
├── eval_order.py
└── symtable_torture.py
├── onelinerizer
├── __init__.py
├── runtests.py
├── __main__.py
├── template.py
└── onelinerizer.py
├── .gitignore
├── .travis.yml
├── talks
├── presentation-pycon-2016.pdf
├── presentation-wecode-2017.pdf
└── oneliner-bostonpython-presentation.pdf
├── setup.py
├── .setup.py
├── LICENSE.md
├── README.md
└── main_ol.py
/requirements.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/modules/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/simple_print.py:
--------------------------------------------------------------------------------
1 | print 42
2 |
--------------------------------------------------------------------------------
/tests/simple_lambda.py:
--------------------------------------------------------------------------------
1 | print (lambda x: 8*x)(4)
2 |
--------------------------------------------------------------------------------
/tests/chain.py:
--------------------------------------------------------------------------------
1 | d = {}
2 | i = d[i] = 1
3 | print d
4 |
--------------------------------------------------------------------------------
/tests/compare.py:
--------------------------------------------------------------------------------
1 | x = 3
2 | y = 4
3 | print (x < y < 5)
4 |
--------------------------------------------------------------------------------
/tests/future_braces.py:
--------------------------------------------------------------------------------
1 | from __future__ import braces
2 |
--------------------------------------------------------------------------------
/tests/lambda.py:
--------------------------------------------------------------------------------
1 | f = lambda x: x * 4
2 | print f(f(8))
3 |
--------------------------------------------------------------------------------
/tests/dictionary.py:
--------------------------------------------------------------------------------
1 | print {'1':'2', 3:4, "stringy":2+2*8}
2 |
--------------------------------------------------------------------------------
/tests/if.py:
--------------------------------------------------------------------------------
1 | x = 7
2 | if True:
3 | x = 5
4 | print x
5 |
--------------------------------------------------------------------------------
/tests/simple_slice.py:
--------------------------------------------------------------------------------
1 | print 'meow'[:2]
2 | print 'meow'[2:]
3 |
--------------------------------------------------------------------------------
/onelinerizer/__init__.py:
--------------------------------------------------------------------------------
1 | from .onelinerizer import onelinerize
2 |
--------------------------------------------------------------------------------
/tests/simple_state.py:
--------------------------------------------------------------------------------
1 | x = 5
2 | y = x + x
3 | print y, x+(x+x)
4 |
--------------------------------------------------------------------------------
/tests/division.py:
--------------------------------------------------------------------------------
1 | print 10/3
2 | print 10./3
3 | print int(10./3)
4 |
--------------------------------------------------------------------------------
/tests/function.py:
--------------------------------------------------------------------------------
1 | def f(x):
2 | return x+5
3 |
4 | print f(13)
5 |
--------------------------------------------------------------------------------
/tests/function_name.py:
--------------------------------------------------------------------------------
1 | def foo():
2 | pass
3 | print foo.__name__
4 |
--------------------------------------------------------------------------------
/tests/future_division.py:
--------------------------------------------------------------------------------
1 | from __future__ import division
2 | print 1/2
3 |
--------------------------------------------------------------------------------
/tests/importdot.py:
--------------------------------------------------------------------------------
1 | import os.path
2 | print os.path.join('hello', 'world')
3 |
--------------------------------------------------------------------------------
/tests/set.py:
--------------------------------------------------------------------------------
1 | print {} # (not a set)
2 | print {0}
3 | print {0, 1, 2}
4 |
--------------------------------------------------------------------------------
/tests/tuple.py:
--------------------------------------------------------------------------------
1 | x = (2,3,4,5)
2 | (y,z) = (6,7)
3 | print x, y, x, (), (4,)
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | stocks.csv
3 | *.egg-info
4 | build/
5 | dist/
6 | .ve
7 |
--------------------------------------------------------------------------------
/tests/class_free.py:
--------------------------------------------------------------------------------
1 | def f(x):
2 | class c:
3 | print x
4 | f(3)
5 |
--------------------------------------------------------------------------------
/tests/genexp.py:
--------------------------------------------------------------------------------
1 | def p(x):
2 | print x
3 | map(p, (10*x for x in [1,2,3]))
4 |
--------------------------------------------------------------------------------
/tests/modules/without_all.py:
--------------------------------------------------------------------------------
1 | a = 2
2 | b = 2
3 | c = 2
4 | _d = 2
5 | __e = 2
6 |
--------------------------------------------------------------------------------
/tests/nullary.py:
--------------------------------------------------------------------------------
1 | def f():
2 | print 'hi'
3 | f()
4 |
5 | (lambda: None)()
6 |
--------------------------------------------------------------------------------
/tests/scope.py:
--------------------------------------------------------------------------------
1 | x = 2
2 | def foo():
3 | x = 1
4 |
5 | foo()
6 | print x
7 |
--------------------------------------------------------------------------------
/tests/imports.py:
--------------------------------------------------------------------------------
1 | import re, string as s
2 | print re.sub('abc','zxy',s.lowercase)
3 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: python
2 | python:
3 | - "2.7"
4 | script: python setup.py test
5 |
--------------------------------------------------------------------------------
/tests/ifelse.py:
--------------------------------------------------------------------------------
1 | x = 7
2 | if x > 8:
3 | x = 5
4 | else:
5 | x = 10
6 | print x
7 |
--------------------------------------------------------------------------------
/tests/while.py:
--------------------------------------------------------------------------------
1 | x = 5
2 | while x > 0:
3 | x = x - 1
4 | print x
5 | print "Done!"
6 |
--------------------------------------------------------------------------------
/tests/for_return.py:
--------------------------------------------------------------------------------
1 | def f(x):
2 | for i in [1, 2, 3]:
3 | return i
4 | print f(0)
5 |
--------------------------------------------------------------------------------
/tests/future_unicode_literals.py:
--------------------------------------------------------------------------------
1 | from __future__ import unicode_literals
2 | print(type(''))
3 |
--------------------------------------------------------------------------------
/tests/global.py:
--------------------------------------------------------------------------------
1 | x = 2
2 | def foo():
3 | global x
4 | x = 1
5 |
6 | foo()
7 | print x
8 |
--------------------------------------------------------------------------------
/tests/importfrom.py:
--------------------------------------------------------------------------------
1 | from os.path import join, split as s
2 | print join(*s('hello/world'))
3 |
--------------------------------------------------------------------------------
/tests/override_builtin.py:
--------------------------------------------------------------------------------
1 | False = True
2 | while False:
3 | print False
4 | del False
5 |
--------------------------------------------------------------------------------
/tests/1line.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | print "Hello, world!"
3 |
--------------------------------------------------------------------------------
/tests/boring_try.py:
--------------------------------------------------------------------------------
1 | try:
2 | print "Hello!"
3 | except:
4 | print "Something went wrong."
5 |
--------------------------------------------------------------------------------
/tests/future_division_inplace.py:
--------------------------------------------------------------------------------
1 | from __future__ import division
2 | x = 1
3 | x /= 2
4 | print x
5 |
--------------------------------------------------------------------------------
/tests/future_print_function.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | print('hello', 'world')
3 |
--------------------------------------------------------------------------------
/tests/num_repr.py:
--------------------------------------------------------------------------------
1 | print repr(123)
2 | print repr(123.0)
3 | print repr(123L)
4 | print repr(123j)
5 |
--------------------------------------------------------------------------------
/tests/return_exec_defined_variable.py:
--------------------------------------------------------------------------------
1 | def f():
2 | exec('a = 5')
3 | return a
4 | print f()
5 |
--------------------------------------------------------------------------------
/tests/modules/with_all.py:
--------------------------------------------------------------------------------
1 | a = 1
2 | b = 1
3 | c = 1
4 | _d = 1
5 | __e = 1
6 |
7 | __all__ = ['a', 'b']
8 |
--------------------------------------------------------------------------------
/tests/unimplemented/class_doc_scope.py:
--------------------------------------------------------------------------------
1 | '''foo'''
2 | class C:
3 | '''bar'''
4 | print __doc__
5 |
--------------------------------------------------------------------------------
/tests/binding_indeterminate.py:
--------------------------------------------------------------------------------
1 | def f(y):
2 | if y > 0.5: x = 'x'
3 | return x
4 |
5 | print f(0)
6 |
--------------------------------------------------------------------------------
/tests/future_absolute_import.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import
2 | __package__ = 'os'
3 | import path
4 |
--------------------------------------------------------------------------------
/talks/presentation-pycon-2016.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/csvoss/onelinerizer/HEAD/talks/presentation-pycon-2016.pdf
--------------------------------------------------------------------------------
/talks/presentation-wecode-2017.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/csvoss/onelinerizer/HEAD/talks/presentation-wecode-2017.pdf
--------------------------------------------------------------------------------
/tests/aug.py:
--------------------------------------------------------------------------------
1 | x = [1]
2 | y = x
3 | y += [2]
4 | print x, y
5 |
6 | x = 1
7 | y = x
8 | y += 2
9 | print x, y
10 |
--------------------------------------------------------------------------------
/tests/ifelifelse.py:
--------------------------------------------------------------------------------
1 | x = 1
2 | if False:
3 | x = 2
4 | elif True:
5 | x = 6
6 | else:
7 | x = 7
8 | print x
9 |
--------------------------------------------------------------------------------
/tests/name_main.py:
--------------------------------------------------------------------------------
1 | ## Does __name__ == '__main__' check pass?
2 |
3 | if __name__ == '__main__':
4 | print "Pass!"
5 |
--------------------------------------------------------------------------------
/tests/return_none.py:
--------------------------------------------------------------------------------
1 | def f():
2 | print 1
3 | return
4 | print 2
5 |
6 | print 3
7 | print f()
8 | print 4
9 |
--------------------------------------------------------------------------------
/tests/slice.py:
--------------------------------------------------------------------------------
1 | print "meow"[:], "meow"[:2], "meow"[2:]
2 | print "meow"[::], "meow"[::-1], "meow"[:2:], "meow"[2::]
3 |
--------------------------------------------------------------------------------
/tests/aug_coerce.py:
--------------------------------------------------------------------------------
1 | class C:
2 | def __coerce__(self, other):
3 | return 2, 2
4 | o = C()
5 | o += C()
6 | print o
7 |
--------------------------------------------------------------------------------
/tests/closing_over.py:
--------------------------------------------------------------------------------
1 | def f():
2 | x = 'closed-over'
3 | def g():
4 | return x
5 | return g
6 | print f()()
7 |
--------------------------------------------------------------------------------
/tests/reassignment.py:
--------------------------------------------------------------------------------
1 | def f():
2 | x = 'local'
3 | x = 'reassigned'
4 | x = 'reassigned again'
5 |
6 | print f()
7 |
--------------------------------------------------------------------------------
/talks/oneliner-bostonpython-presentation.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/csvoss/onelinerizer/HEAD/talks/oneliner-bostonpython-presentation.pdf
--------------------------------------------------------------------------------
/tests/2lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | name = raw_input("Enter your name: ")
3 | print "Hi, %s." % name
4 |
--------------------------------------------------------------------------------
/tests/reraise.py:
--------------------------------------------------------------------------------
1 | try:
2 | try:
3 | 0/0
4 | except Exception:
5 | raise
6 | except Exception as e:
7 | print repr(e)
8 |
--------------------------------------------------------------------------------
/tests/exec.py:
--------------------------------------------------------------------------------
1 | exec "print s" in {}, {'s': 'Hello, world!'}
2 | exec "print s" in {'s': 'Hello, world!'}
3 | s = 'Hello, world!'
4 | exec "print s"
5 |
--------------------------------------------------------------------------------
/tests/unimplemented/argument_named_print.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | def f(print):
3 | return print
4 | print(f(**{'print': 1}))
5 |
--------------------------------------------------------------------------------
/tests/call.py:
--------------------------------------------------------------------------------
1 | def function_call(x, y, *args, **kwargs):
2 | print x,y,args,kwargs
3 |
4 | function_call(42, "stringy\n\"", 5, 6, 7, foo=43+4, bar=22)
5 |
--------------------------------------------------------------------------------
/tests/closing_over_2.py:
--------------------------------------------------------------------------------
1 | def g():
2 | x = 'outer'
3 | def h():
4 | x = 'inner'
5 | return x
6 | return (h(), x)
7 | print g()
8 |
--------------------------------------------------------------------------------
/tests/fibonacci.py:
--------------------------------------------------------------------------------
1 | x = 0
2 | y = 1
3 |
4 | counter = 0
5 |
6 | while counter < 15:
7 | counter += 1
8 | x, y = y, x + y
9 | print x
10 |
--------------------------------------------------------------------------------
/tests/if_comprehensive.py:
--------------------------------------------------------------------------------
1 | x = 1
2 | if True:
3 | x = 2
4 | else:
5 | x = 3
6 | print x
7 | if False:
8 | x = 4
9 | else:
10 | x = 5
11 | print x
--------------------------------------------------------------------------------
/tests/future_braces_as_division.py:
--------------------------------------------------------------------------------
1 | from __future__ import braces as division
2 |
3 | # These ought not to execute.
4 | print 3/5
5 | print division
6 | print braces
7 |
--------------------------------------------------------------------------------
/tests/future_division_as_braces.py:
--------------------------------------------------------------------------------
1 | from __future__ import division as braces
2 |
3 | print 3/5
4 | print braces
5 |
6 | # This one ought to error.
7 | print division
8 |
--------------------------------------------------------------------------------
/tests/html_module.py:
--------------------------------------------------------------------------------
1 | ## Minimized version of a bug that appeared in 21lines.py
2 | import xml.etree.ElementTree as etree
3 | print etree.fromstring("").tag
4 |
--------------------------------------------------------------------------------
/tests/ifelse_comprehensive.py:
--------------------------------------------------------------------------------
1 | x = 1
2 | if True:
3 | x = 2
4 | else:
5 | x = 3
6 | print x
7 | if False:
8 | x = 4
9 | else:
10 | x = 5
11 | print x
12 |
--------------------------------------------------------------------------------
/tests/5lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | def greet(name):
3 | print 'Hello', name
4 | greet('Jack')
5 | greet('Jill')
6 | greet('Bob')
7 |
--------------------------------------------------------------------------------
/tests/count_vowels.py:
--------------------------------------------------------------------------------
1 | def count_vowels(x):
2 | return sum([1 if i in "aeiou" else 0 for i in x.lower()])
3 |
4 | print count_vowels("Supercalifragilisticexpialidocious!")
5 |
--------------------------------------------------------------------------------
/tests/list_comprehension.py:
--------------------------------------------------------------------------------
1 | print [i for i in range(5) if i%2==0]
2 | print [i for j in range(5) for i in range(j)]
3 | print [i for j in range(5) if j%2==0 for i in range(j) if i%2==0]
4 |
--------------------------------------------------------------------------------
/tests/try_finally_except.py:
--------------------------------------------------------------------------------
1 | try:
2 | try:
3 | print 'try 1'
4 | assert False
5 | finally:
6 | print 'finally 1'
7 | except AssertionError:
8 | print 'except 1'
9 |
--------------------------------------------------------------------------------
/tests/decorated_function_name.py:
--------------------------------------------------------------------------------
1 | def decorator(f):
2 | print f.__name__
3 | def bar():
4 | return f()
5 | return bar
6 |
7 | @decorator
8 | def foo():
9 | pass
10 | print foo.__name__
11 |
--------------------------------------------------------------------------------
/tests/finally_return_swallows_exception.py:
--------------------------------------------------------------------------------
1 | def f():
2 | try:
3 | print 'try f'
4 | assert False
5 | finally:
6 | print 'finally f'
7 | return 'returned'
8 |
9 | print 'f: ' + f()
10 |
--------------------------------------------------------------------------------
/tests/unimplemented/softspace.py:
--------------------------------------------------------------------------------
1 | # The output should have a trailing newline and no spaces.
2 | print '\t', 0
3 | print '\n', 1
4 | print '\x0b', 2
5 | print '\x0c', 3
6 | print '\r', 4
7 | print 5,
8 | print
9 | print 6,
10 |
--------------------------------------------------------------------------------
/tests/try_try_again.py:
--------------------------------------------------------------------------------
1 | def f():
2 | try:
3 | try:
4 | return 'returned'
5 | except AssertionError:
6 | pass
7 | except AssertionError:
8 | pass
9 |
10 | print 'f: ' + f()
11 |
--------------------------------------------------------------------------------
/tests/3lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | friends = ['john', 'pat', 'gary', 'michael']
3 | for i, name in enumerate(friends):
4 | print "iteration {iteration} is {name}".format(iteration=i, name=name)
5 |
--------------------------------------------------------------------------------
/tests/4lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | parents, babies = (1, 1)
3 | while babies < 100:
4 | print 'This generation has {0} babies'.format(babies)
5 | parents, babies = (babies, parents + babies)
6 |
--------------------------------------------------------------------------------
/tests/old_style_class.py:
--------------------------------------------------------------------------------
1 | class C:
2 | def __getattr__(self, name):
3 | if name == '__str__':
4 | return lambda: 'foo'
5 | raise AttributeError
6 | print C()
7 |
8 | class D(C):
9 | pass
10 | print D()
11 |
--------------------------------------------------------------------------------
/tests/unimplemented/exec_local_return_behavior.py:
--------------------------------------------------------------------------------
1 | def f():
2 | exec ""
3 | locals()['a'] = 6
4 | return a
5 |
6 | def g():
7 | locals()['a'] = 6
8 | return a
9 |
10 | a = 5
11 | print f()
12 |
13 | a = 5
14 | print g()
15 |
--------------------------------------------------------------------------------
/tests/decorator_order.py:
--------------------------------------------------------------------------------
1 | def f0(g0):
2 | print 0
3 | return lambda: [0] + g0()
4 |
5 | def f1(g1):
6 | print 1
7 | return lambda: [1] + g1()
8 |
9 | @f0
10 | @f1
11 | def g():
12 | print 2
13 | return [2]
14 |
15 | print g()
16 |
--------------------------------------------------------------------------------
/tests/import_specific.py:
--------------------------------------------------------------------------------
1 | a = 0
2 | b = 0
3 | c = 0
4 | _d = 0
5 | __e = 0
6 | print a, b, c, _d, __e
7 |
8 | from tests.modules.with_all import a
9 | print a, b, c, _d, __e
10 |
11 | from tests.modules.without_all import b
12 | print a, b, c, _d, __e
13 |
--------------------------------------------------------------------------------
/tests/closure.py:
--------------------------------------------------------------------------------
1 | a = 1
2 | print a
3 | def outer(b):
4 | c = 3
5 | print a, b, c
6 | def inner(d):
7 | e = 5
8 | print a, b, c, d, e
9 | return lambda f: (a, b, c, d, e, f)
10 | return inner
11 | print outer(2)(4)(6)
12 |
--------------------------------------------------------------------------------
/tests/decorator.py:
--------------------------------------------------------------------------------
1 | def print_decorator(f):
2 | def g(*args, **kwargs):
3 | print "Calling the function!"
4 | return f(*args, **kwargs)
5 | return g
6 |
7 | @print_decorator
8 | def add_numbers(x,y):
9 | print x+y
10 |
11 | add_numbers(42, 56)
12 |
--------------------------------------------------------------------------------
/tests/aug_getattr.py:
--------------------------------------------------------------------------------
1 | class C:
2 | def __getattr__(self, name):
3 | global o
4 | if name == '__iadd__':
5 | o = None
6 | elif name == '__add__':
7 | return lambda other: None
8 | raise AttributeError
9 |
10 | o = C()
11 | o += 1
12 |
--------------------------------------------------------------------------------
/tests/8lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | # This program adds up integers in the command line
3 | import sys
4 | try:
5 | total = sum(int(arg) for arg in sys.argv[1:])
6 | print 'sum =', total
7 | except ValueError:
8 | print 'Please supply integer arguments'
9 |
--------------------------------------------------------------------------------
/tests/class_function_scope.py:
--------------------------------------------------------------------------------
1 | def f(x, y):
2 | print x
3 | print y
4 | class c:
5 | x = 4
6 | print x
7 | print y
8 | def g(self):
9 | print x
10 | print y
11 | print c
12 | return c
13 | print f("x", "y")().g()
14 |
--------------------------------------------------------------------------------
/tests/6lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | import re
3 | for test_string in ['555-1212', 'ILL-EGAL']:
4 | if re.match(r'^\d{3}-\d{4}$', test_string):
5 | print test_string, 'is a valid US local phone number'
6 | else:
7 | print test_string, 'rejected'
8 |
--------------------------------------------------------------------------------
/tests/future_division_eval.py:
--------------------------------------------------------------------------------
1 | from __future__ import division
2 | print eval('1/2')
3 | exec('print 1/2')
4 | eval(compile('print 1/2', 'wat.py', 'exec'))
5 | print eval(compile('1/2', 'wat.py', 'eval'))
6 | print eval(compile('1/2', 'wat.py', 'eval', 0, 0))
7 | print eval(compile('1/2', 'wat.py', 'eval', 0, ~0))
8 |
--------------------------------------------------------------------------------
/tests/relative_import.py:
--------------------------------------------------------------------------------
1 | __package__ = 'os'
2 | import path
3 | print path.join(*path.split('hello/world'))
4 |
5 | __package__ = 'os.path'
6 | from . import join
7 | from ..path import split
8 | print join(*split('hello/world'))
9 |
10 | from .. import path
11 | print path.join(*path.split('hello/world'))
12 |
--------------------------------------------------------------------------------
/tests/metaclass.py:
--------------------------------------------------------------------------------
1 | class M(type):
2 | def __init__(cls, name, bases, dct):
3 | print 'metaclass'
4 | super(M, cls).__init__(name, bases, dct)
5 |
6 | class C:
7 | __metaclass__ = M
8 |
9 | class C(object):
10 | __metaclass__ = M
11 |
12 | __metaclass__ = M
13 |
14 | class C:
15 | pass
16 |
--------------------------------------------------------------------------------
/tests/7lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | prices = {'apple': 0.40, 'banana': 0.50}
3 | my_purchase = {
4 | 'apple': 1,
5 | 'banana': 6}
6 | grocery_bill = sum(prices[fruit] * my_purchase[fruit]
7 | for fruit in my_purchase)
8 | print 'I owe the grocer $%.2f' % grocery_bill
9 |
--------------------------------------------------------------------------------
/tests/print.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import StringIO
3 |
4 | print
5 | print 1,
6 | print 2
7 |
8 | s = StringIO.StringIO()
9 | print >>s, 3,
10 | print >>s, 4
11 | print repr(s.getvalue())
12 |
13 | def f():
14 | print 'f'
15 | return sys.stdout
16 | def g():
17 | print 'g'
18 | return 'hello'
19 | print >>f(), g()
20 |
--------------------------------------------------------------------------------
/tests/ifelifelse_comprehensive.py:
--------------------------------------------------------------------------------
1 | x = 1
2 | if True:
3 | x = 2
4 | elif False:
5 | x = 3
6 | else:
7 | x = 4
8 | print x
9 | if False:
10 | x = 5
11 | elif True:
12 | x = 6
13 | else:
14 | x = 7
15 | print x
16 | if False:
17 | x = 8
18 | elif False:
19 | x = 9
20 | else:
21 | x = 10
22 | print x
23 |
--------------------------------------------------------------------------------
/tests/del.py:
--------------------------------------------------------------------------------
1 | i = 17
2 | del i
3 |
4 | class dummy(object):
5 | def __init__(self):
6 | self.foo = 1
7 | print getattr(self, 'foo', 'missing')
8 | del self.foo
9 | print getattr(self, 'foo', 'missing')
10 |
11 | dummy()
12 |
13 | a = range(15)
14 | del (a[4:6], [a[::2], a[4]]), a[0]
15 | print a
16 |
17 | del []
18 | del [], []
19 |
--------------------------------------------------------------------------------
/tests/for.py:
--------------------------------------------------------------------------------
1 | x = 5
2 | for i in range(5):
3 | x = x + i
4 | print x
5 |
6 | # inner loop takes in d, returns a modified d?
7 | # list: a list of i
8 | # function: takes in i, d; spits out d
9 | # for loop: takes in d, spits out d
10 | # reduce: function, sequence, initial
11 | # (lambda d.x: (lambda d: print(d.x))(reduce((lambda d, i: (lambda d.x: d)(d.x+i)), range(5), d)))(5)
12 |
--------------------------------------------------------------------------------
/tests/11lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | REFRAIN = '''
3 | %d bottles of beer on the wall,
4 | %d bottles of beer,
5 | take one down, pass it around,
6 | %d bottles of beer on the wall!
7 | '''
8 | bottles_of_beer = 99
9 | while bottles_of_beer > 1:
10 | print REFRAIN % (bottles_of_beer, bottles_of_beer,
11 | bottles_of_beer - 1)
12 | bottles_of_beer -= 1
13 |
--------------------------------------------------------------------------------
/tests/while_break_continue_else.py:
--------------------------------------------------------------------------------
1 | out = ''
2 | f = True
3 | while True:
4 | out += 'a'
5 | g = True
6 | while g:
7 | g = False
8 | out += 'b'
9 | continue
10 | else:
11 | out += 'c'
12 | if f:
13 | f = False
14 | continue
15 | else:
16 | break
17 | out += 'd'
18 | else:
19 | out += 'e'
20 | print out
21 |
--------------------------------------------------------------------------------
/tests/aug_getattribute.py:
--------------------------------------------------------------------------------
1 | class M(type):
2 | __getattribute__ = None
3 |
4 | class G(object):
5 | __metaclass__ = M
6 | __getattribute__ = None
7 | def __get__(self, instance, owner):
8 | return lambda other: 'pass'
9 |
10 | class C(object):
11 | __metaclass__ = M
12 | __getattribute__ = None
13 | __iadd__ = G()
14 |
15 | o = C()
16 | o.__iadd__ = None
17 | o += 1
18 | print o
19 |
--------------------------------------------------------------------------------
/tests/for_break_continue_else.py:
--------------------------------------------------------------------------------
1 | out = ''
2 | for i in [1,2,3,4]:
3 | print i
4 | out += 'a'
5 | for j in [5,6,7,8]:
6 | print j
7 | out += 'b'
8 | continue
9 | else:
10 | print j
11 | out += 'c'
12 | if i == 2:
13 | continue
14 | elif i == 3:
15 | break
16 | out += 'd'
17 | else:
18 | out += 'e'
19 | print i, out
20 |
--------------------------------------------------------------------------------
/tests/unimplemented/print_eval_order.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | def trace(msg, value):
4 | print msg
5 | return value
6 |
7 | print trace('print arg 0', 0), trace('print arg 1', 1),
8 | print trace('print arg 2', 2), trace('print arg 3', 3)
9 | print >>trace('print file 0', sys.stdout), trace('print arg 4', 4), trace('print arg 5', 5),
10 | print >>trace('print file 1', sys.stdout), trace('print arg 6', 6), trace('print arg 7', 7)
11 |
--------------------------------------------------------------------------------
/tests/unimplemented/9lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | # indent your Python code to put into an email
3 | import glob
4 | # glob supports Unix style pathname extensions
5 | python_files = glob.glob('*.py')
6 | for file_name in sorted(python_files):
7 | print ' ------' + file_name
8 |
9 | with open(file_name) as f:
10 | for line in f:
11 | print ' ' + line.rstrip()
12 |
13 | print
14 |
--------------------------------------------------------------------------------
/tests/14lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | def median(pool):
3 | '''Statistical median to demonstrate doctest.
4 | >>> median([2, 9, 9, 7, 9, 2, 4, 5, 8])
5 | 7
6 | '''
7 | copy = sorted(pool)
8 | size = len(copy)
9 | if size % 2 == 1:
10 | return copy[(size - 1) / 2]
11 | else:
12 | return (copy[size/2 - 1] + copy[size/2]) / 2
13 |
14 | print median([2, 9, 9, 7, 9, 2, 4, 5, 8])
15 |
--------------------------------------------------------------------------------
/tests/12lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | class BankAccount(object):
3 | def __init__(self, initial_balance=0):
4 | self.balance = initial_balance
5 | def deposit(self, amount):
6 | self.balance += amount
7 | def withdraw(self, amount):
8 | self.balance -= amount
9 | def overdrawn(self):
10 | return self.balance < 0
11 | my_account = BankAccount(15)
12 | my_account.withdraw(5)
13 | print my_account.balance
14 |
--------------------------------------------------------------------------------
/tests/closure_mutate.py:
--------------------------------------------------------------------------------
1 | def f():
2 | x = 1
3 | a = lambda: x
4 | b = (lambda: lambda: x)()
5 | c = (lambda: lambda: lambda: x)()()
6 | x = 2
7 | print a(), b(), c()
8 | f()
9 |
10 | def g():
11 | print [f() for f in [lambda: x for x in range(5)]]
12 | print [f() for f in [(lambda: lambda: x)() for x in range(5)]]
13 | print [f() for f in [(lambda x: lambda: x)(x) for x in range(5)]]
14 | print [f() for f in map(lambda x: lambda: x, range(5))]
15 | g()
16 |
--------------------------------------------------------------------------------
/tests/13lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | import unittest
3 | def median(pool):
4 | copy = sorted(pool)
5 | size = len(copy)
6 | if size % 2 == 1:
7 | return copy[(size - 1) / 2]
8 | else:
9 | return (copy[size/2 - 1] + copy[size/2]) / 2
10 | class TestMedian(unittest.TestCase):
11 | def testMedian(self):
12 | self.failUnlessEqual(median([2, 9, 9, 7, 9, 2, 4, 5, 8]), 7)
13 | if __name__ == '__main__':
14 | unittest.main()
15 |
--------------------------------------------------------------------------------
/tests/15lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | from itertools import groupby
3 | lines = '''
4 | This is the
5 | first paragraph.
6 |
7 | This is the second.
8 | '''.splitlines()
9 | # Use itertools.groupby and bool to return groups of
10 | # consecutive lines that either have content or don't.
11 | for has_chars, frags in groupby(lines, bool):
12 | if has_chars:
13 | print ' '.join(frags)
14 | # PRINTS:
15 | # This is the first paragraph.
16 | # This is the second.
17 |
--------------------------------------------------------------------------------
/tests/exec_scope.py:
--------------------------------------------------------------------------------
1 | g = 0
2 | def f():
3 | global g
4 | l = 0
5 | exec 'global g; g = 1; l = 1'
6 | print g, l
7 | exec 'global g; g = 2; l = 2' in None
8 | print g, l
9 | exec 'global g; g = 3; l = 3' in {}
10 | print g, l
11 | exec 'global g; g = 4; l = 4' in None, None
12 | print g, l
13 | exec 'global g; g = 5; l = 5' in None, {}
14 | print g, l
15 | exec 'global g; g = 6; l = 6' in {}, None
16 | print g, l
17 | exec 'global g; g = 7; l = 7' in {}, {}
18 | print g, l
19 | f()
20 |
--------------------------------------------------------------------------------
/tests/10lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | from time import localtime
3 |
4 | activities = {8: 'Sleeping',
5 | 9: 'Commuting',
6 | 17: 'Working',
7 | 18: 'Commuting',
8 | 20: 'Eating',
9 | 22: 'Resting' }
10 |
11 | time_now = localtime()
12 | hour = time_now.tm_hour
13 |
14 | for activity_time in sorted(activities.keys()):
15 | if hour < activity_time:
16 | print activities[activity_time]
17 | break
18 | else:
19 | print 'Unknown, AFK or sleeping!'
20 |
--------------------------------------------------------------------------------
/tests/guess_my_number.py:
--------------------------------------------------------------------------------
1 | def guess_my_number(n):
2 | while True:
3 | user_input = raw_input("Enter a positive integer to guess: ")
4 | if len(user_input)==0 or not user_input.isdigit():
5 | print "Not a positive integer!"
6 | else:
7 | user_input = int(user_input)
8 | if user_input > n:
9 | print "Too big! Try again!"
10 | elif user_input < n:
11 | print "Too small! Try again!"
12 | else:
13 | print "You win!"
14 | return True
15 | guess_my_number(42)
16 |
--------------------------------------------------------------------------------
/tests/slice_getattribute.py:
--------------------------------------------------------------------------------
1 | class M(type):
2 | __getattribute__ = None
3 |
4 | class G(object):
5 | __metaclass__ = M
6 | __getattribute__ = None
7 | def __get__(self, instance, owner):
8 | def f(*args):
9 | print args
10 | return f
11 |
12 | class C(object):
13 | __metaclass__ = M
14 | __getattribute__ = None
15 | __getitem__ = G()
16 | __setitem__ = G()
17 | __delitem__ = G()
18 |
19 | o = C()
20 | o.__getitem__ = None
21 | o.__setitem__ = None
22 | o.__delitem__ = None
23 | o[:]
24 | o[::]
25 | o[:] = []
26 | o[::] = []
27 | del o[:]
28 | del o[::]
29 |
--------------------------------------------------------------------------------
/tests/mangle.py:
--------------------------------------------------------------------------------
1 | __a, _A__a, _B__a, __b, _A__b, _B__b, __c, _A__c, _B__c = 0, 1, 2, 3, 4, 5, 6, 7, 8
2 | print __a, _A__a, _B__a, __b, _A__b, _B__b, __c, _A__c, _B__c
3 | class A(object):
4 | __a = 9
5 | print __a, _A__a, _B__a, __b, _A__b, _B__b, __c, _A__c, _B__c
6 | def f(self):
7 | print __a, _A__a, _B__a, __b, _A__b, _B__b, __c, _A__c, _B__c
8 | class B(object):
9 | __b = 10
10 | print __a, _A__a, _B__a, __b, _A__b, _B__b, __c, _A__c, _B__c
11 | def f(self):
12 | print __a, _A__a, _B__a, __b, _A__b, _B__b, __c, _A__c, _B__c
13 |
14 | A().f()
15 | A().B().f()
16 |
--------------------------------------------------------------------------------
/tests/exec_del.py:
--------------------------------------------------------------------------------
1 | a = 0
2 |
3 | def f():
4 | a = 1
5 | exec 'g = lambda: a; print a, g()'
6 | print a, g()
7 | exec 'a = 2; print a, g()'
8 | exec 'print a, g()'
9 | print a, g()
10 | exec 'del a; print a, g()'
11 | exec 'print a, g()'
12 | print a, g()
13 | a = 3
14 | exec 'print a, g()'
15 | print a, g()
16 |
17 | f()
18 |
19 | a = 4
20 | exec 'g = lambda: a; print a, g()'
21 | print a, g()
22 | exec 'a = 5; print a, g()'
23 | exec 'print a, g()'
24 | print a, g()
25 | exec 'del a; print a, g()'
26 | exec 'print a, g()'
27 | print a, g()
28 | a = 6
29 | exec 'print a, g()'
30 | print a, g()
31 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | (lambda __g: (lambda __mod: [(setup(name='onelinerizer', version='1.0.4', author='Chelsea Voss', author_email='csvoss@mit.edu', maintainer='Chelsea Voss and Anders Kaseorg', maintainer_email='onelinerizer@mit.edu', url='https://github.com/csvoss/onelinerizer', description='Convert any Python file into a single line of code.', long_description=open('README.md', 'r').read(), long_description_content_type='text/markdown', packages=['onelinerizer'], entry_points={'console_scripts': ['onelinerizer=onelinerizer.__main__:main']}, test_suite='onelinerizer.runtests'), None)[1] for __g['setup'] in [(__mod.setup)]][0])(__import__('setuptools', __g, __g, ('setup',), 0)))(globals())
2 |
--------------------------------------------------------------------------------
/tests/18lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | BOARD_SIZE = 8
3 |
4 | def under_attack(col, queens):
5 | left = right = col
6 |
7 | for r, c in reversed(queens):
8 | left, right = left - 1, right + 1
9 |
10 | if c in (left, col, right):
11 | return True
12 | return False
13 |
14 | def solve(n):
15 | if n == 0:
16 | return [[]]
17 |
18 | smaller_solutions = solve(n - 1)
19 |
20 | return [solution+[(n,i+1)]
21 | for i in xrange(BOARD_SIZE)
22 | for solution in smaller_solutions
23 | if not under_attack(i+1, solution)]
24 | for answer in solve(BOARD_SIZE):
25 | print answer
26 |
--------------------------------------------------------------------------------
/tests/unimplemented/20lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | import itertools
3 |
4 | def iter_primes():
5 | # an iterator of all numbers between 2 and +infinity
6 | numbers = itertools.count(2)
7 |
8 | # generate primes forever
9 | while True:
10 | # get the first number from the iterator (always a prime)
11 | prime = numbers.next()
12 | yield prime
13 |
14 | # this code iteratively builds up a chain of
15 | # filters...slightly tricky, but ponder it a bit
16 | numbers = itertools.ifilter(prime.__rmod__, numbers)
17 |
18 | for p in iter_primes():
19 | if p > 1000:
20 | break
21 | print p
22 |
--------------------------------------------------------------------------------
/.setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup
2 |
3 | setup(
4 | name="onelinerizer",
5 | version="1.0.4",
6 | author="Chelsea Voss",
7 | author_email="csvoss@mit.edu",
8 | maintainer="Chelsea Voss and Anders Kaseorg",
9 | maintainer_email="onelinerizer@mit.edu",
10 | url='https://github.com/csvoss/onelinerizer',
11 | description='Convert any Python file into a single line of code.',
12 | long_description=open('README.md', 'r').read(),
13 | long_description_content_type='text/markdown',
14 | packages=['onelinerizer'],
15 | entry_points={
16 | 'console_scripts': ['onelinerizer=onelinerizer.__main__:main'],
17 | },
18 | test_suite='onelinerizer.runtests',
19 | )
20 |
--------------------------------------------------------------------------------
/tests/16lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | import csv
3 |
4 | # write stocks data as comma-separated values
5 | writer = csv.writer(open('stocks.csv', 'wb', buffering=0))
6 | writer.writerows([
7 | ('GOOG', 'Google, Inc.', 505.24, 0.47, 0.09),
8 | ('YHOO', 'Yahoo! Inc.', 27.38, 0.33, 1.22),
9 | ('CNET', 'CNET Networks, Inc.', 8.62, -0.13, -1.49)
10 | ])
11 |
12 | # read stocks data, print status messages
13 | stocks = csv.reader(open('stocks.csv', 'rb'))
14 | status_labels = {-1: 'down', 0: 'unchanged', 1: 'up'}
15 | for ticker, name, price, change, pct in stocks:
16 | status = status_labels[cmp(float(change), 0.0)]
17 | print '%s is %s (%s%%)' % (name, status, pct)
18 |
--------------------------------------------------------------------------------
/tests/try_finally.py:
--------------------------------------------------------------------------------
1 | try:
2 | print 'try 0'
3 | finally:
4 | print 'finally 0'
5 |
6 | def f():
7 | try:
8 | print 'try f'
9 | finally:
10 | print 'finally f'
11 | return 'returned'
12 |
13 | print 'f: ' + f()
14 |
15 | def g():
16 | try:
17 | print 'try g'
18 | return 'returned'
19 | finally:
20 | print 'finally g'
21 |
22 | print 'g: ' + g()
23 |
24 | def h():
25 | try:
26 | print 'try h'
27 | finally:
28 | print 'finally h'
29 | return 'returned'
30 |
31 | print 'h: ' + h()
32 |
33 | def i():
34 | try:
35 | print 'try i'
36 | return 'returned'
37 | finally:
38 | print 'finally i'
39 | return 'returned harder'
40 |
41 | print 'i: ' + i()
42 |
--------------------------------------------------------------------------------
/tests/33lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | import random
3 |
4 | guesses_made = 0
5 |
6 | name = raw_input('Hello! What is your name?\n')
7 |
8 | number = random.randint(1, 20)
9 | print 'Well, {0}, I am thinking of a number between 1 and 20.'.format(name)
10 |
11 | while guesses_made < 6:
12 |
13 | guess = int(raw_input('Take a guess: '))
14 |
15 | guesses_made += 1
16 |
17 | if guess < number:
18 | print 'Your guess is too low.'
19 |
20 | if guess > number:
21 | print 'Your guess is too high.'
22 |
23 | if guess == number:
24 | break
25 |
26 | if guess == number:
27 | print 'Good job, {0}! You guessed my number in {1} guesses!'.format(name, guesses_made)
28 | else:
29 | print 'Nope. The number I was thinking of was {0}'.format(number)
30 |
--------------------------------------------------------------------------------
/tests/prime_tester.py:
--------------------------------------------------------------------------------
1 | import math
2 |
3 | def is_prime(n):
4 | if n < 2:
5 | return False
6 | if n == 2:
7 | return True
8 | n = int(n)
9 | factors = range(2, int(math.ceil(math.sqrt(n))+1))
10 | i = 0
11 | while i < len(factors):
12 | factor = factors[i]
13 | if n % factor == 0:
14 | return False
15 | i = i + 1
16 | return True
17 |
18 | def smallest_prime_larger_than(x):
19 | while True:
20 | x = x + 1
21 | if is_prime(x):
22 | return x
23 |
24 | print is_prime(1)
25 | print is_prime(2)
26 | print is_prime(3)
27 | print is_prime(4)
28 | print is_prime(5)
29 | print is_prime(45)
30 | print is_prime(91)
31 | print is_prime(89)
32 |
33 | print smallest_prime_larger_than(1)
34 | print smallest_prime_larger_than(91)
35 | print smallest_prime_larger_than(1000)
36 |
--------------------------------------------------------------------------------
/tests/28lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | BOARD_SIZE = 8
3 |
4 | class BailOut(Exception):
5 | pass
6 |
7 | def validate(queens):
8 | left = right = col = queens[-1]
9 | for r in reversed(queens[:-1]):
10 | left, right = left-1, right+1
11 | if r in (left, col, right):
12 | raise BailOut
13 |
14 | def add_queen(queens):
15 | for i in range(BOARD_SIZE):
16 | test_queens = queens + [i]
17 | try:
18 | validate(test_queens)
19 | if len(test_queens) == BOARD_SIZE:
20 | return test_queens
21 | else:
22 | return add_queen(test_queens)
23 | except BailOut:
24 | pass
25 | raise BailOut
26 |
27 | queens = add_queen([])
28 | print queens
29 | print "\n".join(". "*q + "Q " + ". "*(BOARD_SIZE-q-1) for q in queens)
30 |
--------------------------------------------------------------------------------
/tests/21lines.py:
--------------------------------------------------------------------------------
1 | ## inspired by https://wiki.python.org/moin/SimplePrograms
2 | dinner_recipe = '''
3 | | amt | unit | item |
4 | | 24 | slices | baguette |
5 | | 2+ | tbsp | olive oil |
6 | | 1 | cup | tomatoes |
7 | | 1 | jar | pesto |
8 |
'''
9 |
10 | # In Python 2.5 or from http://effbot.org/zone/element-index.htm
11 | import xml.etree.ElementTree as etree
12 | tree = etree.fromstring(dinner_recipe)
13 |
14 | # For invalid HTML use http://effbot.org/zone/element-soup.htm
15 | # import ElementSoup, StringIO
16 | # tree = ElementSoup.parse(StringIO.StringIO(dinner_recipe))
17 |
18 | pantry = set(['olive oil', 'pesto'])
19 | for ingredient in tree.getiterator('tr'):
20 | amt, unit, item = ingredient
21 | if item.tag == "td" and item.text not in pantry:
22 | print "%s: %s %s" % (item.text, amt.text, unit.text)
23 |
--------------------------------------------------------------------------------
/tests/unimplemented/reraise_bug.py:
--------------------------------------------------------------------------------
1 | # https://bugs.python.org/issue23556
2 |
3 | try:
4 | try:
5 | raise Exception('foo')
6 | except Exception:
7 | try:
8 | raise Exception('bar')
9 | except Exception:
10 | pass
11 |
12 | # In Python 3, this reraises the caught Exception('foo'), like
13 | # you'd expect. In Python 2, this reraises the ignored
14 | # Exception('bar').
15 | raise
16 |
17 | except Exception as e:
18 | print(repr(e))
19 |
20 | try:
21 | try:
22 | raise Exception('foo')
23 | except Exception:
24 | def f():
25 | try:
26 | raise Exception('bar')
27 | except Exception:
28 | pass
29 | f()
30 |
31 | # If we move the inner exception handler into a function, we
32 | # get the expected Exception('foo') in all versions.
33 | raise
34 |
35 | except Exception as e:
36 | print(repr(e))
37 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright © 2015 Chelsea Voss and Anders Kaseorg
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | “Software”), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/tests/scope_comprehension.py:
--------------------------------------------------------------------------------
1 | x = 4
2 |
3 | a = lambda: x
4 |
5 | # Perhaps it once made sense to someone why c and d see the inner x
6 | # but a and b do not.
7 |
8 | print(''.join(
9 | # generator expression
10 | '{}{}{} {}{}{}{}\n'.format(i, j, k, a(), b(), c(), d())
11 | for i, b in enumerate([a, lambda: x, a])
12 | for j, c in enumerate([b, lambda: x, b])
13 | for k, d in enumerate([c, lambda: x, c])
14 | for x in [5]))
15 |
16 | print(''.join(sorted({
17 | # set comprehension
18 | '{}{}{} {}{}{}{}\n'.format(i, j, k, a(), b(), c(), d())
19 | for i, b in enumerate([a, lambda: x, a])
20 | for j, c in enumerate([b, lambda: x, b])
21 | for k, d in enumerate([c, lambda: x, c])
22 | for x in [6]})))
23 |
24 | print(''.join(sorted({
25 | # dict comprehension
26 | '{}{}{} {}{}{}{}\n'.format(i, j, k, a(), b(), c(), d()): 1
27 | for i, b in enumerate([a, lambda: x, a])
28 | for j, c in enumerate([b, lambda: x, b])
29 | for k, d in enumerate([c, lambda: x, c])
30 | for x in [7]}.keys())))
31 |
32 | # Except in list comprehensions.
33 |
34 | print(''.join([
35 | # list comprehension
36 | '{}{}{} {}{}{}{}\n'.format(i, j, k, a(), b(), c(), d())
37 | for i, b in enumerate([a, lambda: x, a])
38 | for j, c in enumerate([b, lambda: x, b])
39 | for k, d in enumerate([c, lambda: x, c])
40 | for x in [8]]))
41 |
--------------------------------------------------------------------------------
/tests/try_except.py:
--------------------------------------------------------------------------------
1 | try:
2 | print 'try 0'
3 | except AssertionError:
4 | print 'except 0'
5 | else:
6 | print 'else 0'
7 |
8 | try:
9 | print 'try 1'
10 | assert False
11 | except AssertionError:
12 | print 'except 1'
13 | else:
14 | print 'else 1'
15 |
16 | try:
17 | try:
18 | print 'try 2'
19 | assert False
20 | except ZeroDivisionError:
21 | print 'wrong except 2'
22 | else:
23 | print 'else 2'
24 | except AssertionError:
25 | print 'right except 2'
26 | else:
27 | print 'else 2'
28 |
29 | try:
30 | print 'try 3'
31 | assert False
32 | except ZeroDivisionError:
33 | print 'wrong except 3'
34 | except AssertionError:
35 | print 'right except 3'
36 | else:
37 | print 'else 3'
38 |
39 | try:
40 | print 'try 4'
41 | assert False
42 | except:
43 | print 'except 4'
44 | else:
45 | print 'else 4'
46 |
47 | def f():
48 | try:
49 | print 'try f'
50 | return 'returned'
51 | except AssertionError:
52 | print 'except f'
53 | else:
54 | print 'else f'
55 |
56 | print 'f: ' + f()
57 |
58 | def g():
59 | try:
60 | print 'try g'
61 | assert False
62 | except AssertionError:
63 | print 'except g'
64 | return 'returned'
65 | else:
66 | print 'else g'
67 |
68 | print 'g: ' + g()
69 |
70 | def f():
71 | try:
72 | print 'try h'
73 | except:
74 | print 'except h'
75 | else:
76 | print 'else h'
77 | return 'returned'
78 |
79 | print 'h: ' + f()
80 |
--------------------------------------------------------------------------------
/onelinerizer/runtests.py:
--------------------------------------------------------------------------------
1 | import unittest
2 | import os
3 | import random
4 | import sys
5 | from StringIO import StringIO
6 |
7 | from .onelinerizer import onelinerize
8 |
9 | TEST_DIRECTORY = 'tests'
10 |
11 | DEBUG = False
12 |
13 | class TestOneLine(unittest.TestCase):
14 | def runTest(self):
15 | pass
16 |
17 | def make_test(filename):
18 | """Return a function that verifies that the file and its onelinerized
19 | version both output the same."""
20 |
21 | def new_test(self):
22 | with open(filename, 'r') as fi:
23 | self.longMessage = True
24 | original = fi.read().strip()
25 | onelinerized = onelinerize(original)
26 | self.assertEqual(capture_exec(original),
27 | capture_exec(onelinerized),
28 | msg="\n\nOnelined: " + onelinerized)
29 | return new_test
30 |
31 | class FakeStdin(object):
32 | """Sometimes tests use raw_input; this feeds those deterministically."""
33 | def __init__(self):
34 | self.counter = 0
35 | def readline(self):
36 | self.counter += 1
37 | return str(self.counter)
38 |
39 | def capture_exec(code_string):
40 | """Run the code with FakeStdin as stdin, return its stdout."""
41 | random.seed(4) # for RFC 1149.5 compliance
42 | new_stdout = StringIO()
43 | old_stdout = sys.stdout
44 | old_stdin = sys.stdin
45 | sys.stdout = new_stdout
46 | sys.stdin = FakeStdin()
47 | namespace = {}
48 | try:
49 | exec code_string in namespace
50 | except Exception as e:
51 | import traceback
52 | exc = traceback.format_exc()
53 | if DEBUG:
54 | old_stdout.write("\nFYI: test threw error %s\n" % str(type(e)(code_string + ', ' + exc)))
55 | new_stdout.write("Error thrown.")
56 | sys.stdout = old_stdout
57 | sys.stdin = old_stdin
58 | return new_stdout.getvalue()
59 |
60 | # Monkey-patch
61 | for subdir, dirs, files in os.walk(TEST_DIRECTORY):
62 | for filename in files:
63 | root, ext = os.path.splitext(filename)
64 | if ext == '.py' and 'unimplemented' not in subdir:
65 | setattr(TestOneLine,
66 | 'test_%s' % root,
67 | make_test(os.path.join(subdir, filename)))
68 |
69 | if __name__ == '__main__':
70 | unittest.main()
71 |
--------------------------------------------------------------------------------
/onelinerizer/__main__.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import sys
3 | import traceback
4 |
5 | from .onelinerizer import onelinerize
6 |
7 | def main():
8 | usage = ['onelinerizer --help',
9 | 'onelinerizer [--debug] [infile.py [outfile.py]]',
10 | ]
11 | parser = argparse.ArgumentParser(usage='\n '.join(usage),
12 | description=("if infile is given and outfile is not, outfile will be "
13 | "infile_ol.py"))
14 | parser.add_argument('infile', nargs='?')
15 | parser.add_argument('outfile', nargs='?')
16 | parser.add_argument('--debug', action='store_true')
17 | args = parser.parse_args()
18 | original = None
19 | if args.infile is None:
20 | # I have gotten no arguments. Look at sys.stdin
21 | original = sys.stdin.read()
22 | outfilename = None
23 | elif args.outfile is None:
24 | # I have gotten one argument. If there's something to read from
25 | # sys.stdin, read from there.
26 | if args.infile.endswith('.py'):
27 | outfilename = '_ol.py'.join(args.infile.rsplit(".py", 1))
28 | else:
29 | outfilename = args.infile + '_ol.py'
30 | else:
31 | outfilename = args.outfile
32 |
33 | if original is None:
34 | infile = open(args.infile)
35 | original = infile.read().strip()
36 | infile.close()
37 | onelinerized = onelinerize(original)
38 | if outfilename is None:
39 | print onelinerized
40 | else:
41 | outfi = open(outfilename, 'w')
42 | outfi.write(onelinerized + '\n')
43 | outfi.close()
44 |
45 | if args.debug:
46 | if outfilename is None:
47 | # redirect to sys.stderr if I'm writing outfile to sys.stdout
48 | sys.stdout = sys.stderr
49 | print '--- ORIGINAL ---------------------------------'
50 | print original
51 | print '----------------------------------------------'
52 | scope = {}
53 | try:
54 | exec(original, scope)
55 | except Exception as e:
56 | traceback.print_exc(e)
57 | print '--- ONELINERIZED -----------------------------'
58 | print onelinerized
59 | print '----------------------------------------------'
60 | scope = {}
61 | try:
62 | exec(onelinerized, scope)
63 | except Exception as e:
64 | traceback.print_exc(e)
65 |
66 | if __name__ == '__main__':
67 | main()
68 |
--------------------------------------------------------------------------------
/tests/slice_torture.py:
--------------------------------------------------------------------------------
1 | import types
2 |
3 | def trace(name):
4 | def f(self, *args):
5 | print name, repr(args)
6 | return 0
7 | return f
8 |
9 | def get(a, s):
10 | a[1*s]
11 | a[...]
12 | a[:]
13 | a[2*s:]
14 | a[:3*s]
15 | a[4*s:5*s]
16 | a[::]
17 | a[6*s::]
18 | a[:7*s:]
19 | a[::8*s]
20 | a[9*s:10*s:]
21 | a[11*s::12*s]
22 | a[:13*s:14*s]
23 | a[15*s:16*s:17*s]
24 | a[18*s, 19*s:20*s, 21*s:22*s:23*s, :, ::, ...]
25 | a[24*s,]
26 | a[25*s:26*s,]
27 | a[27*s:28*s:29*s,]
28 | a[...,]
29 | a[:,]
30 | a[::,]
31 |
32 | def set(a, s):
33 | a[1*s] = 0
34 | a[...] = 0
35 | a[:] = 0
36 | a[2*s:] = 0
37 | a[:3*s] = 0
38 | a[4*s:5*s] = 0
39 | a[::] = 0
40 | a[6*s::] = 0
41 | a[:7*s:] = 0
42 | a[::8*s] = 0
43 | a[9*s:10*s:] = 0
44 | a[11*s::12*s] = 0
45 | a[:13*s:14*s] = 0
46 | a[15*s:16*s:17*s] = 0
47 | a[18*s, 19*s:20*s, 21*s:22*s:23*s, :, ::, ...] = 0
48 | a[24*s,] = 0
49 | a[25*s:26*s,] = 0
50 | a[27*s:28*s:29*s,] = 0
51 | a[...,] = 0
52 | a[:,] = 0
53 | a[::,] = 0
54 |
55 | def aug(a, s):
56 | a[1*s] += 0
57 | a[...] += 0
58 | a[:] += 0
59 | a[2*s:] += 0
60 | a[:3*s] += 0
61 | a[4*s:5*s] += 0
62 | a[::] += 0
63 | a[6*s::] += 0
64 | a[:7*s:] += 0
65 | a[::8*s] += 0
66 | a[9*s:10*s:] += 0
67 | a[11*s::12*s] += 0
68 | a[:13*s:14*s] += 0
69 | a[15*s:16*s:17*s] += 0
70 | a[18*s, 19*s:20*s, 21*s:22*s:23*s, :, ::, ...] += 0
71 | a[24*s,] += 0
72 | a[25*s:26*s,] += 0
73 | a[27*s:28*s:29*s,] += 0
74 | a[...,] += 0
75 | a[:,] += 0
76 | a[::,] += 0
77 |
78 | def delete(a, s):
79 | del a[1*s]
80 | del a[...]
81 | del a[:]
82 | del a[2*s:]
83 | del a[:3*s]
84 | del a[4*s:5*s]
85 | del a[::]
86 | del a[6*s::]
87 | del a[:7*s:]
88 | del a[::8*s]
89 | del a[9*s:10*s:]
90 | del a[11*s::12*s]
91 | del a[:13*s:14*s]
92 | del a[15*s:16*s:17*s]
93 | del a[18*s, 19*s:20*s, 21*s:22*s:23*s, :, ::, ...]
94 | del a[24*s,]
95 | del a[25*s:26*s,]
96 | del a[27*s:28*s:29*s,]
97 | del a[...,]
98 | del a[:,]
99 | del a[::,]
100 |
101 | def g(e):
102 | def __getattr__(self, name):
103 | print '__getattr__', repr(name)
104 | if name == '__len__':
105 | return lambda: 100
106 | if name in e:
107 | return e[name].__get__(self)
108 | raise AttributeError
109 | return {'__getattr__': __getattr__}
110 |
111 | for ns in [['__%sitem__'], ['__%sitem__', '__%sslice__']]:
112 | e = {n % a: trace(n % a) for a in ['get', 'set', 'del'] for n in ns}
113 | for meta, d in [
114 | (type, e),
115 | (type, dict(e, __len__=lambda self: 100)),
116 | (types.ClassType, dict(e, __len__=lambda self: 100)),
117 | (types.ClassType, g(e))]:
118 | a = meta('dummy', (), d)()
119 | for s in [1, -1]:
120 | get(a, s)
121 | set(a, s)
122 | aug(a, s)
123 | delete(a, s)
124 |
--------------------------------------------------------------------------------
/tests/doc.py:
--------------------------------------------------------------------------------
1 | """Lorem ipsum dolor sit amet, consectetur adipiscing elit.
2 |
3 | Curabitur egestas aliquam eros, et luctus felis accumsan a. Mauris
4 | scelerisque sapien non mi vehicula facilisis. Cum sociis natoque
5 | penatibus et magnis dis parturient montes, nascetur ridiculus mus.
6 | Vivamus eget purus ac arcu aliquam vulputate vitae et diam. Nullam sit
7 | amet diam condimentum, laoreet turpis nec, venenatis sem. Morbi mi
8 | tortor, vestibulum sit amet nisi non, euismod suscipit lectus. Ut
9 | vitae est nisi. Quisque et posuere tortor. Maecenas suscipit ut leo
10 | vitae hendrerit.
11 | """
12 |
13 | def aenean_interdum(f):
14 | """Cras ut convallis sapien.
15 |
16 | Aliquam suscipit, enim lacinia lacinia rhoncus, sapien est feugiat
17 | nulla, ac dictum orci magna tincidunt ipsum. Quisque posuere
18 | sodales turpis sit amet tincidunt. Nam tincidunt dolor volutpat
19 | sapien auctor fringilla. Pellentesque arcu turpis, tincidunt
20 | ultrices dignissim in, vestibulum id urna. Curabitur congue
21 | pulvinar arcu ac iaculis. Pellentesque habitant morbi tristique
22 | senectus et netus et malesuada fames ac turpis egestas. Fusce enim
23 | nisi, porta sed ligula ut, fermentum hendrerit sapien. Sed
24 | imperdiet eu quam faucibus faucibus.
25 | """
26 |
27 | print f.__doc__
28 | f.__doc__ += '\nNullam id feugiat orci, nec bibendum lacus.\n'
29 | return f
30 |
31 | @aenean_interdum
32 | def donec_porttitor(whats_up):
33 | """Nulla nec venenatis turpis, fermentum tristique dolor.
34 |
35 | Morbi sodales risus at purus commodo, et pellentesque orci
36 | blandit. Donec lacinia tortor eu mi maximus, sed suscipit ipsum
37 | lobortis. Sed id sollicitudin enim, id feugiat eros. Aenean
38 | accumsan felis ac neque dapibus fringilla. Nam et posuere erat, in
39 | pulvinar metus. Donec vitae maximus tellus, non feugiat nisl. Ut
40 | efficitur mattis lacus vitae feugiat. In rutrum ligula ut erat
41 | viverra interdum. Pellentesque vulputate commodo ligula, in
42 | euismod velit dapibus at. Pellentesque eget posuere mauris. Donec
43 | dictum maximus lacus, eu rutrum massa.
44 | """
45 |
46 | print whats_up.__doc__
47 | return whats_up
48 |
49 | @donec_porttitor
50 | class vestibulum_ante(object):
51 | """Pellentesque habitant morbi tristique senectus et netus et
52 | malesuada fames ac turpis egestas.
53 |
54 | Nunc id risus tellus. Nulla ullamcorper dui a urna sollicitudin
55 | sodales. Ut diam augue, sollicitudin maximus euismod eu, cursus a
56 | dolor. Integer tempor iaculis dignissim. Etiam pulvinar quis nulla
57 | eu molestie. In maximus, justo in congue lobortis, libero enim
58 | pulvinar dolor, non hendrerit lorem magna sit amet
59 | tellus. Suspendisse in tempus est. Nam congue scelerisque diam,
60 | quis consequat orci aliquam ut. Donec sed mauris in leo ultrices
61 | maximus ullamcorper eget arcu. Donec ac urna in dui efficitur
62 | suscipit ac eu ipsum. Aenean ac facilisis nisi. Etiam elit libero,
63 | vulputate at orci accumsan, dignissim volutpat nibh. Aliquam
64 | bibendum felis a erat iaculis, auctor hendrerit felis luctus. Duis
65 | nec hendrerit nisi.
66 | """
67 |
68 | pass
69 |
70 | print __doc__
71 | print aenean_interdum.__doc__
72 | print donec_porttitor.__doc__
73 | print vestibulum_ante.__doc__
74 |
--------------------------------------------------------------------------------
/tests/eval_order.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | def trace(msg, value):
4 | print msg
5 | return value
6 |
7 | @trace('function decorator 0', lambda f: f)
8 | @trace('function decorator 1', lambda f: f)
9 | def function_def(
10 | arg0=trace('function default 0', None),
11 | arg1=trace('function default 1', None)):
12 | trace('function body', None)
13 |
14 | class base0: pass
15 | class base1: pass
16 |
17 | @trace('class decorator 0', lambda cls: cls)
18 | @trace('class decorator 1', lambda cls: cls)
19 | class class_def(trace('class base 0', base0), trace('class base 1', base1)):
20 | trace('class body', None)
21 |
22 | o = base0()
23 | o.attr0 = o.attr1 = o.attr2 = o.attr3 = o.attr4 = 0
24 | l = [0, 0]
25 | d = {(0, 0): 0, (1, 1): 1}
26 |
27 | del trace('del value 0', o).attr0, \
28 | trace('del value 1', l)[trace('del index', 0)], \
29 | trace('del value 2', l)[trace('del lower', 0):trace('del upper', 0):trace('del step', 1)], \
30 | trace('del value 3', d)[trace('del index 0', 0), trace('del index 1', 0)], \
31 | [trace('del value 4', o).attr1, trace('del value 5', o).attr2], \
32 | (trace('del value 6', o).attr3, trace('del value 7', o).attr4)
33 |
34 | trace('assign target 0', o).attr, trace('assign target 1', o).attr = \
35 | trace('assign target 2', o).attr, trace('assign target 3', o).attr = \
36 | trace('assign value', (0, 0))
37 | trace('aug assign target 0', o).attr += trace('aug assign value 0', 0)
38 | trace('aug assign target 1', l)[trace('aug assign index', 0)] += trace('aug assign value 1', 0)
39 | trace('aug assign target 2', l)[trace('aug assign lower 2', 0):trace('aug assign upper 2', 0)] += trace('aug assign value 2', [])
40 | trace('aug assign target 3', l)[trace('aug assign lower 3', 0):trace('aug assign upper 3', 0):trace('aug assign step 3', 1)] += trace('aug assign value 2', [])
41 |
42 | print >>trace('print file', sys.stdout), trace('print arg', 0)
43 |
44 | for trace('for target', o).attr in trace('for iter', [0]):
45 | trace('for body', None)
46 | else:
47 | trace('for else', None)
48 |
49 | b = True
50 | while trace('while test', b):
51 | trace('while body', None)
52 | b = False
53 | else:
54 | trace('while else', None)
55 |
56 | for b in [True, False]:
57 | if trace('if test', b):
58 | trace('if body', None)
59 | else:
60 | trace('if orelse', None)
61 |
62 | # TODO: with
63 |
64 | # TODO: raise
65 |
66 | # TODO: try
67 |
68 | assert trace('assert test', True), trace('assert message', '')
69 |
70 | exec trace('exec body', '')
71 | exec trace('exec body', '') in trace('exec globals', {})
72 | exec trace('exec body', '') in trace('exec globals', {}), trace('exec locals', {})
73 |
74 | trace('bool op left', True) or trace('bool op right', True)
75 | trace('bin op left', 0) + trace('bin op right', 0)
76 | not trace('unary op operand', True)
77 | lam = lambda lambda_arg0=trace('lambda default 0', None), \
78 | lambda_arg1=trace('lambda default 1', None), \
79 | *lambda_args, **lambda_kwargs: \
80 | trace('lambda body', None)
81 | for b in [True, False]:
82 | trace('if exp body', None) if trace('if exp test', b) else trace('if exp orelse', None)
83 | {trace('dict key 0', 0): trace('dict value 0', 0), trace('dict key 1', 1): trace('dict value 1', 1)}
84 | {trace('set elt 0', 0), trace('set elt 1', 1)}
85 |
86 | [trace('list comp elt', 0)
87 | for trace('list comp target 0', o).attr in trace('list comp iter 0', [0])
88 | if trace('list comp test 0', True) if trace('list comp test 1', True)
89 | for trace('list comp target 1', o).attr in trace('list comp iter 1', [0])
90 | if trace('list comp test 2', True) if trace('list comp test 3', True)]
91 |
92 | {trace('set comp elt', 0)
93 | for trace('set comp target 0', o).attr in trace('set comp iter 0', [0])
94 | if trace('set comp test 0', True) if trace('set comp test 1', True)
95 | for trace('set comp target 1', o).attr in trace('set comp iter 1', [0])
96 | if trace('set comp test 2', True) if trace('set comp test 3', True)}
97 |
98 | {trace('dict comp key', 0): trace('dict comp value', 0)
99 | for trace('dict comp target 0', o).attr in trace('dict comp iter 0', [0])
100 | if trace('dict comp test 0', True) if trace('dict comp test 1', True)
101 | for trace('dict comp target 1', o).attr in trace('dict comp iter 1', [0])
102 | if trace('dict comp test 2', True) if trace('dict comp test 3', True)}
103 |
104 | next(trace('generator exp elt', 0)
105 | for trace('generator exp target 0', o).attr in trace('generator exp iter 0', [0])
106 | if trace('generator exp test 0', True) if trace('generator exp test 1', True)
107 | for trace('generator exp target 1', o).attr in trace('generator exp iter 1', [0])
108 | if trace('generator exp test 2', True) if trace('generator exp test 3', True))
109 |
110 | # TODO: yield
111 |
112 | trace('compare left', 0) < trace('compare middle', 1) < trace('compare right', 2)
113 |
114 | trace('lambda func', lam)(
115 | trace('lambda arg 0', 0),
116 | trace('lambda arg 1', 1),
117 | kwarg=trace('lambda kwarg', 0),
118 | *trace('lambda args', []),
119 | **trace('lambda kwargs', {}))
120 |
121 | `trace('repr value', 0)`
122 |
123 | trace('attribute value', o).attr
124 | trace('slice2 value', l)[trace('slice2 lower', 0):trace('slice2 upper', 0)]
125 | trace('slice3 value', l)[trace('slice3 lower', 0):trace('slice3 upper', 0):trace('slice3 step', 1)]
126 | trace('subscript value', l)[trace('subscript index', 0)]
127 | trace('extslice value', d)[trace('extslice index 0', 1), trace('extslice index 1', 1)]
128 |
129 | [trace('list elt 0', 0), trace('list elt 1', 1)]
130 | (trace('tuple elt 0', 0), trace('tuple elt 1', 1))
131 |
--------------------------------------------------------------------------------
/tests/symtable_torture.py:
--------------------------------------------------------------------------------
1 | # This test is designed to complain about any deviation from the
2 | # traversal order used by symtable.
3 |
4 | def only_for_parsing():
5 |
6 | @decorator0(lambda: decorator_arg0)
7 | @decorator1(lambda: decorator_arg1)
8 | def function_def(
9 | function_arg0=lambda: function_default0,
10 | function_arg1=lambda: function_default1,
11 | *function_args, **function_kwargs):
12 | lambda: function_body
13 | return lambda: return_value
14 |
15 | @class_decorator0(lambda: class_decorator_arg0)
16 | @class_decorator1(lambda: class_decorator_arg1)
17 | class class_def(lambda: class_base0, lambda: class_base1):
18 | lambda: class_body
19 |
20 | del (lambda: del_value0).attr, \
21 | (lambda: del_value1)[lambda: del_index], \
22 | (lambda: del_value2)[lambda: del_lower:lambda: del_upper:lambda: del_step], \
23 | (lambda: del_value3)[lambda: del_index0, lambda: del_index1], \
24 | ((lambda: del_value4).attr, (lambda: del_value5).attr), \
25 | [(lambda: del_value6).attr, (lambda: del_value7).attr]
26 |
27 | (lambda: assign_target0).attr, (lambda: assign_target1).attr \
28 | = (lambda: assign_target2).attr, (lambda: assign_target3).attr \
29 | = lambda: assign_value
30 |
31 | (lambda: aug_assign_target0).attr += lambda: aug_assign_value0
32 | (lambda: aug_assign_target1)[lambda: aug_assign_index] += lambda: aug_assign_value1
33 | (lambda: aug_assign_target2)[lambda: aug_assign_lower2:lambda: slice_upper2] += lambda: aug_assign_value2
34 | (lambda: aug_assign_target3)[lambda: aug_assign_lower3:lambda: slice_upper3:lambda: slice_upper3] += lambda: aug_assign_value3
35 |
36 | print lambda: print_arg0, lambda: print_arg1,
37 | print lambda: print_arg2, lambda: print_arg3
38 | print >>lambda: print_file0, lambda: print_arg4, lambda: print_arg5,
39 | print >>lambda: print_file1, lambda: print_arg6, lambda: print_arg7
40 |
41 | for (lambda: for_target).attr in lambda: for_iter:
42 | lambda: for_body
43 | break
44 | else:
45 | lambda: for_orelse
46 |
47 | while lambda: while_test:
48 | lambda: while_body
49 | continue
50 | else:
51 | lambda: while_orelse
52 |
53 | if lambda: if_test:
54 | lambda: if_body
55 | else:
56 | lambda: if_orelse
57 |
58 | # TODO: with
59 |
60 | raise lambda: raise_type, lambda: raise_inst, lambda: raise_tback
61 |
62 | try:
63 | lambda: body
64 | except lambda: handler_type0 as (lambda: handler_name0).attr:
65 | lambda: handler_body0
66 | except lambda: handler_type1 as (lambda: handler_name1).attr:
67 | lambda: handler_body1
68 | else:
69 | lambda: orelse_body
70 |
71 | try:
72 | lambda: body
73 | finally:
74 | lambda: finalbody
75 |
76 | assert lambda: assert_test, lambda: assert_msg
77 |
78 | import import_name0, import_name1 as import_asname1
79 | from import_from_module import import_from_name0, import_from_name1 as import_from_asname1
80 |
81 | exec (lambda: exec_body) in lambda: exec_globals, lambda: exec_locals
82 |
83 | global global_name
84 |
85 | pass
86 |
87 | (lambda: bool_op_left) or (lambda: bool_op_right)
88 | (lambda: bin_op_left) + (lambda: bin_op_right)
89 | not (lambda: unary_op_operand)
90 | lambda lambda_arg0=lambda: lambda_default0, \
91 | lambda_arg1=lambda: lambda_default1, \
92 | *lambda_args, **lambda_kwargs: \
93 | lambda: lambda_body
94 | (lambda: if_exp_body) if (lambda: if_exp_test) else lambda: if_exp_orelse
95 | {lambda: dict_key0: lambda: dict_value0, lambda: dict_key1: lambda: dict_value1}
96 | {lambda: set_elt0, lambda: set_elt1}
97 |
98 | [lambda: list_comp_elt
99 | for (lambda: list_comp_target0).attr in lambda: list_comp_iter0
100 | if lambda: list_comp_test0 if lambda: list_comp_test1
101 | for (lambda: list_comp_target1).attr in lambda: list_comp_iter1
102 | if lambda: list_comp_test2 if lambda: list_comp_test3]
103 |
104 | {lambda: set_comp_elt
105 | for (lambda: set_comp_target0).attr in (lambda: set_comp_iter0)
106 | if lambda: set_comp_test0 if lambda: set_comp_test1
107 | for (lambda: set_comp_target1).attr in (lambda: set_comp_iter1)
108 | if lambda: set_comp_test2 if lambda: set_comp_test3}
109 |
110 | {lambda: dict_comp_key: lambda: dict_comp_value
111 | for (lambda: dict_comp_target0).attr in (lambda: dict_comp_iter0)
112 | if lambda: dict_comp_test0 if lambda: dict_comp_test1
113 | for (lambda: dict_comp_target1).attr in (lambda: dict_comp_iter1)
114 | if lambda: dict_comp_test2 if lambda: dict_comp_test3}
115 |
116 | (lambda: generator_exp_elt
117 | for (lambda: generator_exp_target0).attr in (lambda: generator_exp_iter0)
118 | if lambda: generator_exp_test0 if lambda: generator_exp_test1
119 | for (lambda: generator_exp_target1).attr in (lambda: generator_exp_iter1)
120 | if lambda: generator_exp_test2 if lambda: generator_exp_test3)
121 |
122 | # TODO: yield
123 |
124 | (lambda: compare_left) < (lambda: compare_middle) < (lambda: compare_right)
125 |
126 | (lambda: lambda_func)(
127 | lambda: lambda_arg0,
128 | lambda: lambda_arg1,
129 | kwarg=lambda: lambda_value,
130 | *lambda: lambda_args,
131 | **lambda: lambda_kwargs)
132 |
133 | `lambda: repr_value`
134 | 17
135 | "string"
136 |
137 | (lambda: attribute_value).attr
138 | (lambda: slice2_value)[lambda: slice2_lower:lambda: slice2_upper]
139 | (lambda: slice3_value)[lambda: slice3_lower:lambda: slice3_upper:lambda: slice3_step]
140 | (lambda: subscript_value)[lambda: subscript_index]
141 | (lambda: extslice_value)[lambda: extslice_index0, lambda: extslice_index1]
142 |
143 | name
144 | [lambda: list_elt0, lambda: list_elt1]
145 | (lambda: tuple_elt0, lambda: tuple_elt1)
146 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Oneliner-izer
2 | =========
3 |
4 | [](https://travis-ci.org/csvoss/onelinerizer)
5 |
6 |
7 | Convert any Python 2 script into a single line of code.
8 |
9 | No newlines allowed. No semicolons, either. No silly file I/O tricks, or eval or exec. Just good, old-fashioned λ.
10 |
11 | Play with a live demo at [onelinerizer.com](http://www.onelinerizer.com/)! Watch the [presentation at PyCon 2016](https://www.youtube.com/watch?v=DsUxuz_Rt8g), or peruse the [slide deck](https://speakerdeck.com/pycon2016/chelsea-voss-oneliner-izer-an-exercise-in-constrained-coding).
12 |
13 |
14 | User Installation and Usage
15 | ---
16 |
17 | Install via `pip` from PyPI:
18 |
19 | ```sh
20 | $ pip install onelinerizer
21 | ```
22 |
23 | Use either the command line function or the Python module:
24 |
25 | ```sh
26 | $ echo "def f(x):\n print x\nf(4)" > sandbox.py
27 | $ onelinerizer sandbox.py --debug
28 | $ onelinerizer sandbox_ol.py
29 | ```
30 |
31 | ```python
32 | from onelinerizer import onelinerize
33 | onelinerize("def f(x):\n print x\nf(4)")
34 | ```
35 |
36 | Examples
37 | --------
38 |
39 | **Before:**
40 |
41 | ```python
42 | x = 3
43 | y = 4
44 | print (x < y < 5)
45 | ```
46 |
47 | **After:**
48 |
49 | ```python
50 | (lambda __builtin__: (lambda __print, __y, d: [[__print(d.x n:
90 | print "Too big! Try again!"
91 | elif user_input < n:
92 | print "Too small! Try again!"
93 | else:
94 | print "You win!"
95 | return True
96 | guess_my_number(42)
97 | ```
98 |
99 | **After:**
100 |
101 | ```python
102 | (lambda __builtin__: (lambda __print, __y, d: [(lambda ___: None)(d.guess_my_number(42)) for d.guess_my_number in [(lambda n:[(__y(lambda __this: (lambda d: (lambda __after: [(lambda __after: (lambda ___: __after(d))(__print('Not a positive integer!')) if (d.len(d.user_input)==0 or (not d.user_input.isdigit())) else [(lambda __after: (lambda ___: __after(d))(__print('Too big! Try again!')) if d.user_input>d.n else (lambda __after: (lambda ___: __after(d))(__print('Too small! Try again!')) if d.user_input=3 else (lambda __after: [__after(__d) for __d.outfilename in [('.ol.py'.join(__d.infilename.rsplit('.py',1)))]][0] if '.py' in __d.infilename else [__after(__d) for __d.outfilename in [((__d.infilename+'.ol.py'))]][0])(lambda __d: (lambda ___: __after(__d))(__print(('Writing to %s'%__d.outfilename)))))(lambda __d: [[[[(lambda ___: (lambda __after: (lambda ___: (lambda ___: (lambda ___: (lambda ___: __after(__d))(__print(__d.onelined)))(__print('--- ONELINED ---------------------------------')))(__print(__d.original)))(__print('--- ORIGINAL ---------------------------------')) if __d.VERBOSE else __after(__d))(lambda __d: __after(__d)))(__d.outfi.write((__d.onelined+'\n'))) for __d.onelined in [(__d.to_one_line(__d.original))]][0] for __d.original in [(__d.infi.read().strip())]][0] for __d.outfi in [(__d.open(__d.outfilename,'w'))]][0] for __d.infi in [(__d.open(__d.infilename,'r'))]][0]) for __d.infilename in [(__d.sys.argv[1])]][0])(lambda __d: __after(__d)) if __d.True else __after(__d))(lambda __d: None) for __d.VERBOSE in [(__d.True)]][0] for __d.to_one_line in [(lambda original:[[(lambda __after: __d.original if __d.len(__d.original.splitlines())==1 else __after(__d))(lambda __d: [__d.code(__d.t) for __d.t in [(__d.ast.parse(__d.original))]][0]) for __d.original in [(__d.original.strip())]][0] for __d.original in [(original)]][0])]][0] for __d.code_with_after in [(lambda tree,after:[(lambda __after: '+' if __d.type(__d.tree) is __d.ast.Add else (lambda __after: ' and ' if __d.type(__d.tree) is __d.ast.And else (lambda __after: __after(__d) if __d.type(__d.tree) is __d.ast.Assert else (lambda __after: [[[('[%s for %s in [(%s)]][0]'%(__d.after,__d.targets,__d.value)) for __d.targets in [(','.join(__d.targets))]][0] for __d.value in [(__d.code(__d.tree.value))]][0] for __d.targets in [([__d.code(__d.target) for __d.target in __d.tree.targets])]][0] if __d.type(__d.tree) is __d.ast.Assign else (lambda __after: ('%s.%s'%(__d.code(__d.tree.value),__d.tree.attr)) if __d.type(__d.tree) is __d.ast.Attribute else (lambda __after: [[[('[%s for %s in [%s%s%s]][0]'%(__d.after,__d.target,__d.target,__d.op,__d.value)) for __d.value in [(__d.code(__d.tree.value))]][0] for __d.op in [(__d.code(__d.tree.op))]][0] for __d.target in [(__d.code(__d.tree.target))]][0] if __d.type(__d.tree) is __d.ast.AugAssign else (lambda __after: ('(%s%s%s)'%(__d.code(__d.tree.left),__d.code(__d.tree.op),__d.code(__d.tree.right))) if __d.type(__d.tree) is __d.ast.BinOp else (lambda __after: '&' if __d.type(__d.tree) is __d.ast.BitAnd else (lambda __after: '|' if __d.type(__d.tree) is __d.ast.BitOr else (lambda __after: '^' if __d.type(__d.tree) is __d.ast.BitXor else (lambda __after: ('(%s)'%__d.code(__d.tree.op).join([__d.code(__d.val) for __d.val in __d.tree.values])) if __d.type(__d.tree) is __d.ast.BoolOp else (lambda __after: __after(__d) if __d.type(__d.tree) is __d.ast.Break else (lambda __after: [[[(lambda __after: [__after(__d) for __d.starargs in [([])]][0] if __d.tree.starargs is __d.None else [__after(__d) for __d.starargs in [([('*'+__d.code(__d.tree.starargs))])]][0])(lambda __d: (lambda __after: [__after(__d) for __d.kwargs in [([])]][0] if __d.tree.kwargs is __d.None else [__after(__d) for __d.kwargs in [([('**'+__d.code(__d.tree.kwargs))])]][0])(lambda __d: [[('%s(%s)'%(__d.func,__d.comma_sep_elems)) for __d.comma_sep_elems in [(','.join(__d.elems))]][0] for __d.elems in [((((__d.args+__d.keywords)+__d.starargs)+__d.kwargs))]][0])) for __d.keywords in [([__d.code(__d.kw) for __d.kw in __d.tree.keywords])]][0] for __d.args in [([__d.code(__d.arg) for __d.arg in __d.tree.args])]][0] for __d.func in [(__d.code(__d.tree.func))]][0] if __d.type(__d.tree) is __d.ast.Call else (lambda __after: __after(__d) if __d.type(__d.tree) is __d.ast.ClassDef else (lambda __after: None if __d.type(__d.tree) is __d.ast.Compare else (lambda __after: (('for %s in %s'%(__d.code(__d.tree.target),__d.code(__d.tree.iter)))+''.join([(' if '+__d.code(__d.i)) for __d.i in __d.tree.ifs])) if __d.type(__d.tree) is __d.ast.comprehension else (lambda __after: __after(__d) if __d.type(__d.tree) is __d.ast.Continue else (lambda __after: __after(__d) if __d.type(__d.tree) is __d.ast.Delete else (lambda __after: ('{%s}'%','.join([('%s:%s'%(__d.code(__d.k),__d.code(__d.v))) for (__d.k,__d.v) in __d.zip(__d.tree.keys,__d.tree.values)])) if __d.type(__d.tree) is __d.ast.Dict else (lambda __after: ('{%s}'%' '.join(([((__d.code(__d.tree.key)+':')+__d.code(__d.tree.value))]+[__d.code(__d.gen) for __d.gen in __d.tree.generators]))) if __d.type(__d.tree) is __d.ast.DictComp else (lambda __after: '/' if __d.type(__d.tree) is __d.ast.Div else (lambda __after: '...' if __d.type(__d.tree) is __d.ast.Ellipsis else (lambda __after: '==' if __d.type(__d.tree) is __d.ast.Eq else (lambda __after: __after(__d) if __d.type(__d.tree) is __d.ast.ExceptHandler else (lambda __after: __after(__d) if __d.type(__d.tree) is __d.ast.Exec else (lambda __after: [('(lambda ___: %s)(%s)'%(__d.after,__d.code_to_exec)) for __d.code_to_exec in [(__d.code(__d.tree.value))]][0] if __d.type(__d.tree) is __d.ast.Expr else (lambda __after: __d.code(__d.tree.body) if __d.type(__d.tree) is __d.ast.Expression else (lambda __after: ', '.join([__d.code(__d.dim) for __d.dim in __d.tree.dims]) if __d.type(__d.tree) is __d.ast.ExtSlice else (lambda __after: '//' if __d.type(__d.tree) is __d.ast.FloorDiv else (lambda __after: [[[(lambda __after: __after(__d) if __d.len(__d.tree.orelse) is not 0 else __after(__d))(lambda __d: ('(lambda __d: %s)(reduce((lambda __d, __i:[%s for %s in [__i]][0]),%s,__d))'%(__d.after,__d.body,__d.item,__d.items))) for __d.items in [(__d.code(__d.tree.iter))]][0] for __d.body in [(__d.many_to_one(__d.tree.body,after='__d'))]][0] for __d.item in [(__d.code(__d.tree.target))]][0] if __d.type(__d.tree) is __d.ast.For else (lambda __after: [[[[(lambda __after: (lambda __d: __after(__d))(reduce((lambda __d, __i:[[__d for __d.function_code in [(('%s(%s)'%(__d.code(__d.decorator),__d.function_code)))]][0] for __d.decorator in [__i]][0]),__d.tree.decorator_list,__d)) if __d.len(__d.tree.decorator_list)>0 else __after(__d))(lambda __d: ('[%s for __d.%s in [(%s)]][0]'%(__d.after,__d.tree.name,__d.function_code))) for __d.function_code in [((__d.args+__d.body))]][0] for __d.body in [(('[%s for %s in [(%s)]][0]'%(__d.body,('__d.'+',__d.'.join(__d.arg_names)),','.join(__d.arg_names))))]][0] for __d.body in [(__d.many_to_one(__d.tree.body))]][0] for (__d.args,__d.arg_names) in [(__d.code(__d.tree.args))]][0] if __d.type(__d.tree) is __d.ast.FunctionDef else (lambda __after: [[[[(lambda __after: [[__after(__d) for __d.arg_names in [__d.arg_names+[__d.tree.vararg]]][0] for __d.args in [__d.args+[('*'+__d.tree.vararg)]]][0] if __d.tree.vararg is not __d.None else __after(__d))(lambda __d: (lambda __after: [[__after(__d) for __d.arg_names in [__d.arg_names+[__d.tree.kwarg]]][0] for __d.args in [__d.args+[('**'+__d.tree.kwarg)]]][0] if __d.tree.kwarg is not __d.None else __after(__d))(lambda __d: [(('lambda %s:'%__d.args),__d.arg_names) for __d.args in [(','.join(__d.args))]][0])) for __d.args in [([(__d.a.id if __d.d is __d.None else ((__d.a.id+'=')+__d.code(__d.d))) for (__d.d,__d.a) in __d.args])]][0] for __d.args in [(__d.zip(__d.padded_defaults,__d.tree.args))]][0] for __d.arg_names in [([__d.arg.id for __d.arg in __d.tree.args])]][0] for __d.padded_defaults in [((([__d.None]*(__d.len(__d.tree.args)-__d.len(__d.tree.defaults)))+__d.tree.defaults))]][0] if __d.type(__d.tree) is __d.ast.arguments else (lambda __after: ('%s'%' '.join(([__d.code(__d.tree.elt)]+[__d.code(__d.gen) for __d.gen in __d.tree.generators]))) if __d.type(__d.tree) is __d.ast.GeneratorExp else (lambda __after: __after(__d) if __d.type(__d.tree) is __d.ast.Global else (lambda __after: '>' if __d.type(__d.tree) is __d.ast.Gt else (lambda __after: '>=' if __d.type(__d.tree) is __d.ast.GtE else (lambda __after: [[[('(lambda __after: %s if %s else %s)(lambda __d: %s)'%(__d.body,__d.test,__d.orelse,__d.after)) for __d.orelse in [(__d.many_to_one(__d.tree.orelse,after='__after(__d)'))]][0] for __d.body in [(__d.many_to_one(__d.tree.body,after='__after(__d)'))]][0] for __d.test in [(__d.code(__d.tree.test))]][0] if __d.type(__d.tree) is __d.ast.If else (lambda __after: ('(%s if %s else %s)'%(__d.code(__d.tree.body),__d.code(__d.tree.test),__d.code(__d.tree.orelse))) if __d.type(__d.tree) is __d.ast.IfExp else (lambda __after: (lambda __d: __d.after)(reduce((lambda __d, __i:[(lambda __after: [__after(__d) for __d.alias.asname in [(__d.alias.name)]][0] if __d.alias.asname is __d.None else __after(__d))(lambda __d: [__d for __d.after in [(("[%s for __d.%s in [__import__('%s')]][0]"%(__d.after,__d.alias.asname,__d.alias.name)))]][0]) for __d.alias in [__i]][0]),__d.tree.names,__d)) if __d.type(__d.tree) is __d.ast.Import else (lambda __after: __after(__d) if __d.type(__d.tree) is __d.ast.ImportFrom else (lambda __after: ' in ' if __d.type(__d.tree) is __d.ast.In else (lambda __after: ('%s'%__d.code(__d.tree.value)) if __d.type(__d.tree) is __d.ast.Index else (lambda __after: (__d.INIT_CODE%__d.many_to_one(__d.child_nodes(__d.tree))) if __d.type(__d.tree) is __d.ast.Interactive else (lambda __after: '~' if __d.type(__d.tree) is __d.ast.Invert else (lambda __after: ' is ' if __d.type(__d.tree) is __d.ast.Is else (lambda __after: ' is not ' if __d.type(__d.tree) is __d.ast.IsNot else (lambda __after: '<<' if __d.type(__d.tree) is __d.ast.LShift else (lambda __after: ('%s=%s'%(__d.tree.arg,__d.code(__d.tree.value))) if __d.type(__d.tree) is __d.ast.keyword else (lambda __after: [[[((('('+__d.args)+__d.body)+')') for __d.body in [(('[%s for %s in [(%s)]][0]'%(__d.body,('__d.'+',__d.'.join(__d.arg_names)),','.join(__d.arg_names))))]][0] for __d.body in [(__d.code(__d.tree.body))]][0] for (__d.args,__d.arg_names) in [(__d.code(__d.tree.args))]][0] if __d.type(__d.tree) is __d.ast.Lambda else (lambda __after: [('[%s]'%','.join(__d.elts)) for __d.elts in [([__d.code(__d.elt) for __d.elt in __d.tree.elts])]][0] if __d.type(__d.tree) is __d.ast.List else (lambda __after: ('[%s]'%' '.join(([__d.code(__d.tree.elt)]+[__d.code(__d.gen) for __d.gen in __d.tree.generators]))) if __d.type(__d.tree) is __d.ast.ListComp else (lambda __after: '<' if __d.type(__d.tree) is __d.ast.Lt else (lambda __after: '<=' if __d.type(__d.tree) is __d.ast.LtE else (lambda __after: '%' if __d.type(__d.tree) is __d.ast.Mod else (lambda __after: (__d.INIT_CODE%__d.many_to_one(__d.child_nodes(__d.tree))) if __d.type(__d.tree) is __d.ast.Module else (lambda __after: '*' if __d.type(__d.tree) is __d.ast.Mult else (lambda __after: ('__d.'+__d.tree.id) if __d.type(__d.tree) is __d.ast.Name else (lambda __after: 'not ' if __d.type(__d.tree) is __d.ast.Not else (lambda __after: '!=' if __d.type(__d.tree) is __d.ast.NotEq else (lambda __after: ' not in ' if __d.type(__d.tree) is __d.ast.NotIn else (lambda __after: __d.str(__d.tree.n) if __d.type(__d.tree) is __d.ast.Num else (lambda __after: ' or ' if __d.type(__d.tree) is __d.ast.Or else (lambda __after: __d.after if __d.type(__d.tree) is __d.ast.Pass else (lambda __after: '**' if __d.type(__d.tree) is __d.ast.Pow else (lambda __after: [(lambda __after: ('(lambda ___: %s)(__print(%s))'%(__d.after,__d.to_print)) if __d.after is not 'None' else ('__print(%s)'%__d.to_print))(lambda __d: __after(__d)) for __d.to_print in [(','.join([__d.code(__d.x) for __d.x in __d.tree.values]))]][0] if __d.type(__d.tree) is __d.ast.Print else (lambda __after: '>>' if __d.type(__d.tree) is __d.ast.RShift else (lambda __after: __after(__d) if __d.type(__d.tree) is __d.ast.Raise else (lambda __after: ('repr(%s)'%__d.code(__d.tree.value)) if __d.type(__d.tree) is __d.ast.Repr else (lambda __after: __d.code(__d.tree.value) if __d.type(__d.tree) is __d.ast.Return else (lambda __after: ('set(%s)'%__d.tree.elts) if __d.type(__d.tree) is __d.ast.Set else (lambda __after: ('{%s}'%' '.join(([__d.code(__d.tree.elt)]+[__d.code(__d.gen) for __d.gen in __d.tree.generators]))) if __d.type(__d.tree) is __d.ast.SetComp else (lambda __after: (lambda __after: ('%s:%s'%(__d.code(__d.tree.lower),__d.code(__d.tree.upper))) if __d.tree.step is __d.None else ('%s:%s:%s'%(__d.code(__d.tree.lower),__d.code(__d.tree.upper),__d.code(__d.tree.step))))(lambda __d: __after(__d)) if __d.type(__d.tree) is __d.ast.Slice else (lambda __after: __d.repr(__d.tree.s) if __d.type(__d.tree) is __d.ast.Str else (lambda __after: '-' if __d.type(__d.tree) is __d.ast.Sub else (lambda __after: ('%s[%s]'%(__d.code(__d.tree.value),__d.code(__d.tree.slice))) if __d.type(__d.tree) is __d.ast.Subscript else (lambda __after: (__d.INIT_CODE%__d.many_to_one(__d.child_nodes(__d.tree))) if __d.type(__d.tree) is __d.ast.Suite else (lambda __after: __after(__d) if __d.type(__d.tree) is __d.ast.TryExcept else (lambda __after: __after(__d) if __d.type(__d.tree) is __d.ast.TryFinally else (lambda __after: [(lambda __after: '()' if __d.len(__d.elts) is 0 else (lambda __after: ('(%s,)'%__d.elts[0]) if __d.len(__d.elts) is 1 else ('(%s)'%','.join(__d.elts)))(lambda __d: __after(__d)))(lambda __d: __after(__d)) for __d.elts in [([__d.code(__d.elt) for __d.elt in __d.tree.elts])]][0] if __d.type(__d.tree) is __d.ast.Tuple else (lambda __after: '+' if __d.type(__d.tree) is __d.ast.UAdd else (lambda __after: '-' if __d.type(__d.tree) is __d.ast.USub else (lambda __after: ('(%s%s)'%(__d.code(__d.tree.op),__d.code(__d.tree.operand))) if __d.type(__d.tree) is __d.ast.UnaryOp else (lambda __after: [[[('(__y(lambda __this: (lambda __d: (lambda __after: %s if %s else %s)(lambda __d: %s))))(__d)'%(__d.body,__d.test,__d.orelse,__d.after)) for __d.orelse in [(__d.many_to_one(__d.tree.orelse,after='__after(__d)'))]][0] for __d.body in [(__d.many_to_one(__d.tree.body,after='__this(__d)'))]][0] for __d.test in [(__d.code(__d.tree.test))]][0] if __d.type(__d.tree) is __d.ast.While else (lambda __after: __after(__d) if __d.type(__d.tree) is __d.ast.With else (lambda __after: __after(__d) if __d.type(__d.tree) is __d.ast.Yield else __after(__d))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: __after(__d)))(lambda __d: None) for __d.tree,__d.after in [(tree,after)]][0])]][0] for __d.code in [(lambda tree:[__d.code_with_after(__d.tree,'None') for __d.tree in [(tree)]][0])]][0] for __d.many_to_one in [(lambda trees,after='None':[None for __d.trees,__d.after in [(trees,after)]][0])]][0] for __d.child_nodes in [(lambda tree:[__d.list(__d.ast.iter_child_nodes(__d.tree)) for __d.tree in [(tree)]][0])]][0] for __d.fields in [(lambda tree:[__d.dict(__d.list(__d.ast.iter_fields(__d.tree))) for __d.tree in [(tree)]][0])]][0] for __d.INIT_CODE in [("(lambda __builtin__: (lambda __print, __y, __d: %s)(__builtin__.__dict__['print'],(lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args)))),type('StateDict',(),__builtin__.__dict__)()))(__import__('__builtin__'))")]][0] for __d.sys in [__import__('sys')]][0] for __d.ast in [__import__('ast')]][0])(__builtin__.__dict__['print'],(lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args)))),type('StateDict',(),__builtin__.__dict__)()))(__import__('__builtin__'))
2 |
--------------------------------------------------------------------------------
/onelinerizer/onelinerizer.py:
--------------------------------------------------------------------------------
1 | """Convert any Python file into a single line of code.
2 |
3 | Usage via the command line:
4 |
5 | $ python main.py --help
6 | print usages
7 | $ python main.py infile.py
8 | one-line infile.py, put the result in infile.ol.py
9 | $ python main.py infile.py outfile.py
10 | one-line infile.py, put the result in outfile.py
11 | """
12 |
13 | import ast
14 | import symtable
15 |
16 | from .template import T
17 |
18 |
19 | def lambda_function(arguments_to_values):
20 | """
21 | Arguments:
22 | arguments_to_values: {string: string | T} - e.g. {'a': '47'}
23 |
24 | Returns:
25 | T - e.g. (lambda a: {})(47)
26 | """
27 | return T('(lambda {}: {})({})').format(
28 | T(', ').join(arguments_to_values.keys()),
29 | T('{}'),
30 | T(', ').join(arguments_to_values.values()))
31 |
32 | def provide(body, **subs):
33 | """
34 | Provide the variables in subs to the code in `body`, by wrapping
35 | `body` in a lambda function if needed.
36 |
37 | Arguments:
38 | body: string | T, e.g. '__print(42)'
39 | subs: {string: string | T}, e.g. {'__print': 'f'}
40 |
41 | Returns:
42 | T - e.g. (lambda __print: __print(42))(f)
43 | """
44 | body = T('{}').format(body)
45 | needed = set(body.free()).intersection(subs)
46 | if needed:
47 | return lambda_function({k: subs[k] for k in needed}).format(
48 | body.format(**{k: k for k in needed}))
49 | else:
50 | return body
51 |
52 |
53 | def get_init_code(tree, table):
54 | """Get one-lined code from `tree` and `table.
55 |
56 | Calculate the helper variables that we will need, and wrap the output
57 | code (computed from `tree`) with definitions of those variables.
58 |
59 | TODO: Short-circuit to something far simpler if the program has only one
60 | print statement.
61 |
62 | Arguments:
63 | tree: Python AST node
64 | table: symtable.symtable
65 |
66 | Returns:
67 | string - valid one-line code
68 | """
69 | output = Namespace(table).many_to_one(tree.body)
70 |
71 | doc = ast.get_docstring(tree, clean=False)
72 | if doc is not None:
73 | output = assignment_component(output, T("{__g}['__doc__']"), repr(doc))
74 |
75 | output = provide(
76 | output.format(__l=T('{__g}')),
77 | __print=T("__import__('__builtin__', level=0).__dict__['print']"),
78 | __y="(lambda f: (lambda x: x(x))(lambda y:"
79 | " f(lambda: y(y)())))",
80 | __g=T("globals()"),
81 | __contextlib="__import__('contextlib', level=0)",
82 | __operator="__import__('operator', level=0)",
83 | __sys="__import__('sys', level=0)",
84 | __types="__import__('types', level=0)")
85 |
86 | return output.close()
87 |
88 |
89 | boolop_code = {
90 | ast.And: ' and ',
91 | ast.Or: ' or ',
92 | }
93 |
94 | operator_code = {
95 | ast.Add: '+',
96 | ast.Sub: '-',
97 | ast.Mult: '*',
98 | ast.Div: '/',
99 | ast.Mod: '%',
100 | ast.Pow: '**',
101 | ast.LShift: '<<',
102 | ast.RShift: '>>',
103 | ast.BitOr: '|',
104 | ast.BitXor: '^',
105 | ast.BitAnd: '&',
106 | ast.FloorDiv: '//',
107 | }
108 |
109 | unaryop_code = {
110 | ast.Invert: '~',
111 | ast.Not: 'not ',
112 | ast.UAdd: '+',
113 | ast.USub: '-',
114 | }
115 |
116 | cmpop_code = {
117 | ast.Eq: ' == ',
118 | ast.NotEq: ' != ',
119 | ast.Lt: ' < ',
120 | ast.LtE: ' <= ',
121 | ast.Gt: ' > ',
122 | ast.GtE: ' >= ',
123 | ast.Is: ' is ',
124 | ast.IsNot: ' is not ',
125 | ast.In: ' in ',
126 | ast.NotIn: ' not in ',
127 | }
128 |
129 |
130 | def assignment_component(after, targets, value):
131 | """
132 | Assign `targets` to `value` in the code `after`.
133 |
134 | Arguments:
135 | after: string, e.g. 'x+42'
136 | targets: string, e.g. 'x,y,z'
137 | value: string, e.g. '(1,2,3)'
138 |
139 | Returns:
140 | T, e.g. T('[x+42 for x,y,z in [((1,2,3))]]')
141 | """
142 | # Old way:
143 | # return T('(lambda {}: {})({})').format(targets, after, value)
144 | return T('[{} for {} in [({})]][0]').format(after, targets, value)
145 |
146 |
147 | class Namespace(ast.NodeVisitor):
148 | """
149 | AST visitor.
150 | """
151 | def __init__(self, table, private=''):
152 | self.table = table
153 | self.subtables = iter(table.get_children())
154 | self.private = '_' + table.get_name() if table.get_type() == 'class' \
155 | else private
156 | self.futures = set()
157 |
158 | def next_child(self):
159 | return Namespace(next(self.subtables), private=self.private)
160 |
161 | def mangle(self, name):
162 | return self.private + name if name.startswith('__') and \
163 | not name.endswith('__') else name
164 |
165 | def var(self, name):
166 | name = self.mangle(name)
167 | sym = self.table.lookup(name)
168 | if self.table.get_type() == 'module' or (sym.is_global() and self.table.is_optimized()) or name == 'None':
169 | return T('{__print}') if name == 'print' else T('{}').format(name)
170 | elif sym.is_global():
171 | return T('({__l}[{!r}] if {!r} in __l else {})').format(
172 | name, name, T('{__print}') if name == 'print' else name)
173 | elif sym.is_local():
174 | return T('{__l}[{!r}]').format(name)
175 | elif sym.is_free():
176 | return T('{___f_' + name + '}()').format(name)
177 | else:
178 | raise SyntaxError('confusing symbol {!r}'.format(name))
179 |
180 | def store_var(self, name):
181 | name = self.mangle(name)
182 | sym = self.table.lookup(name)
183 | if sym.is_global():
184 | return T('{__g}[{!r}]').format(name)
185 | elif sym.is_local():
186 | return T('{__l}[{!r}]').format(name)
187 | elif sym.is_free():
188 | raise SyntaxError('storing free variable {!r}'.format(name))
189 | else:
190 | raise SyntaxError('confusing symbol {!r}'.format(name))
191 |
192 | def delete_var(self, name):
193 | name = self.mangle(name)
194 | sym = self.table.lookup(name)
195 | if sym.is_global():
196 | return T('{__g}.pop({!r})').format(name)
197 | elif sym.is_local():
198 | return T('{__l}.pop({!r})').format(name)
199 | elif sym.is_free():
200 | raise SyntaxError('deleting free variable {!r}'.format(name))
201 | else:
202 | raise SyntaxError('confusing symbol {!r}'.format(name))
203 |
204 | def close(self, ns, local, body, **subs):
205 | if self.table.get_type() == 'function':
206 | subs = dict(subs, **{'___f_' + v: T('lambda: {}').format(self.var(v))
207 | for v in self.table.get_locals()})
208 | return provide(body, __l=local, **subs)
209 |
210 | def many_to_one(self, trees, after='None'):
211 | # trees :: [Tree]
212 | # return :: string
213 | return reduce(
214 | lambda ctx, tree: ctx.format(after=self.visit(tree)),
215 | trees,
216 | T('{after}')).format(after=after)
217 |
218 | def slice_repr(self, slice):
219 | if type(slice) is ast.Ellipsis:
220 | return T('Ellipsis')
221 | elif type(slice) is ast.Slice:
222 | return T('slice({}, {}, {})').format(
223 | 'None' if slice.lower is None else self.visit(slice.lower),
224 | 'None' if slice.upper is None else self.visit(slice.upper),
225 | 'None' if slice.step is None else self.visit(slice.step))
226 | elif type(slice) is ast.ExtSlice:
227 | return T('({})').format(T(', ').join(map(self.slice_repr, slice.dims)) +
228 | ','*(len(slice.dims) == 1))
229 | elif type(slice) is ast.Index:
230 | return self.visit(slice.value)
231 | else:
232 | raise NotImplementedError('Case not caught: %s' % str(type(slice)))
233 |
234 | def delete_code(self, target):
235 | if type(target) is ast.Attribute:
236 | return [T('delattr({}, {!r})').format(self.visit(target.value), target.attr)]
237 | elif type(target) is ast.Subscript:
238 | if type(target.slice) is ast.Slice and target.slice.step is None:
239 | return [T("(lambda o, **t: type('translator', (), {{t[m]: "
240 | "staticmethod(object.__getattribute__(d[m], '__get__'"
241 | ")(o, type(o))) for d in [object.__getattribute__("
242 | "type(o), '__dict__')] for m in t if m in d}})())({},"
243 | " __delitem__='__getitem__', __delslice__="
244 | "'__getslice__', __len__='__len__')[{}]").format(
245 | self.visit(target.value),
246 | self.visit(target.slice))]
247 | else:
248 | return [T("{__operator}.delitem({}, {})").format(
249 | self.visit(target.value),
250 | self.slice_repr(target.slice))]
251 | elif type(target) is ast.Name:
252 | return [self.delete_var(target.id)]
253 | elif type(target) in (ast.List, ast.Tuple):
254 | return [c for elt in target.elts for c in self.delete_code(elt)]
255 | else:
256 | raise NotImplementedError('Case not caught: %s' % str(type(target)))
257 |
258 | def visit_Assert(self, tree):
259 | return T('({after} if {} else ([] for [] in []).throw(AssertionError{}))').format(
260 | self.visit(tree.test),
261 | '' if tree.msg is None else T('({})').format(self.visit(tree.msg)))
262 |
263 | def visit_Assign(self, tree):
264 | targets = [self.visit(target) for target in tree.targets]
265 | value = self.visit(tree.value)
266 | targets = T(', ').join(targets)
267 | return assignment_component(T('{after}'), targets,
268 | value if len(tree.targets) == 1
269 | else T('[{}]*{}').format(value, len(tree.targets)))
270 |
271 | def visit_Attribute(self, tree):
272 | return T('{}.{}').format(self.visit(tree.value), tree.attr)
273 |
274 | def visit_AugAssign(self, tree):
275 | if type(tree.target) is ast.Attribute:
276 | target_params = ['__target']
277 | target_args = [self.visit(tree.target.value)]
278 | target_value = T('__target.{}').format(tree.target.attr)
279 | elif type(tree.target) is ast.Subscript:
280 | if type(tree.target.slice) is ast.Slice and tree.target.slice.step is None:
281 | target_params = ['__target']
282 | target_args = [self.visit(tree.target.value)]
283 | if tree.target.slice.lower is not None:
284 | target_params.append('__lower')
285 | target_args.append(self.visit(tree.target.slice.lower))
286 | if tree.target.slice.upper is not None:
287 | target_params.append('__upper')
288 | target_args.append(self.visit(tree.target.slice.upper))
289 | target_value = T('__target[{}:{}]').format(
290 | '' if tree.target.slice.lower is None else '__lower',
291 | '' if tree.target.slice.upper is None else '__upper')
292 | else:
293 | target_params = ['__target', '__slice']
294 | target_args = [self.visit(tree.target.value), self.slice_repr(tree.target.slice)]
295 | target_value = '__target[__slice]'
296 | elif type(tree.target) is ast.Name:
297 | target_params = []
298 | target_args = []
299 | target_value = self.store_var(tree.target.id)
300 | else:
301 | raise SyntaxError('illegal expression for augmented assignment')
302 |
303 | iop = type(tree.op).__name__.lower()
304 | if iop.startswith('bit'):
305 | iop = iop[len('bit'):]
306 | if 'division' in self.futures and isinstance(tree.op, ast.Div):
307 | iop = 'truediv'
308 | value = self.visit(tree.value)
309 | assign = assignment_component(
310 | T('{after}'), target_value,
311 | T("{__operator}.i{}({}, {})").format(iop, target_value, value))
312 | if target_params:
313 | assign = T('(lambda {}: {})({})').format(
314 | T(', ').join(target_params),
315 | assign,
316 | T(', ').join(target_args))
317 | return assign
318 |
319 | def visit_BinOp(self, tree):
320 | if 'division' in self.futures and isinstance(tree.op, ast.Div):
321 | return T('{__operator}.truediv({}, {})').format(self.visit(tree.left), self.visit(tree.right))
322 | return T('({} {} {})').format(self.visit(tree.left), operator_code[type(tree.op)], self.visit(tree.right))
323 |
324 | def visit_BoolOp(self, tree):
325 | return T('({})').format(T(boolop_code[type(tree.op)]).join(map(self.visit, tree.values)))
326 |
327 | def visit_Break(self, tree):
328 | return T('{__break}()')
329 |
330 | def visit_Call(self, tree):
331 | func = self.visit(tree.func)
332 | args = [self.visit(arg) for arg in tree.args]
333 | keywords = [self.visit(kw) for kw in tree.keywords]
334 | if tree.starargs is None:
335 | starargs = []
336 | else:
337 | starargs = ["*" + self.visit(tree.starargs)]
338 | if tree.kwargs is None:
339 | kwargs = []
340 | else:
341 | kwargs = ["**" + self.visit(tree.kwargs)]
342 | elems = args + keywords + starargs + kwargs
343 | comma_sep_elems = T(', ').join(elems)
344 | return T('{}({})').format(func, comma_sep_elems)
345 |
346 | def visit_ClassDef(self, tree):
347 | bases = (T(', ').join(map(self.visit, tree.bases)) +
348 | ','*(len(tree.bases) == 1))
349 | decoration = T('{}')
350 | for decorator in tree.decorator_list:
351 | decoration = decoration.format(T('{}({})').format(self.visit(decorator), T('{}')))
352 | ns = self.next_child()
353 | body = ns.many_to_one(tree.body, after=T('{__l}'))
354 | doc = ast.get_docstring(tree, clean=False)
355 | body = self.close(ns, "{{'__module__': __name__{}}}".format(
356 | '' if doc is None else ", '__doc__': {!r}".format(doc)), body)
357 | if tree.bases:
358 | class_code = T("(lambda b, d: d.get('__metaclass__', getattr(b[0], "
359 | "'__class__', type(b[0])))({!r}, b, d))(({}), "
360 | "{})").format(tree.name, bases, body)
361 | else:
362 | class_code = T("(lambda d: d.get('__metaclass__', {__g}.get("
363 | "'__metaclass__', {__types}.ClassType))({!r}, (), "
364 | "d))({})").format(tree.name, body)
365 | class_code = decoration.format(class_code)
366 | return assignment_component(T('{after}'), self.store_var(tree.name), class_code)
367 |
368 | def visit_Compare(self, tree):
369 | assert len(tree.ops) == len(tree.comparators)
370 | return T('({})').format(self.visit(tree.left) + T('').join(
371 | [cmpop_code[type(tree.ops[i])] + self.visit(tree.comparators[i])
372 | for i in range(len(tree.ops))]))
373 |
374 | def visit_comprehension(self, tree):
375 | return (T('for {} in {}').format(self.visit(tree.target), self.visit(tree.iter)) +
376 | T('').join(' if ' + self.visit(i) for i in tree.ifs))
377 |
378 | def comprehension_code(self, generators, wrap):
379 | iter0 = self.visit(generators[0].iter)
380 | ns = self.next_child()
381 | return self.close(
382 | ns, '{}',
383 | wrap(ns, T(' ').join(
384 | [T('for {} in {__iter}').format(ns.visit(generators[0].target))] +
385 | ['if ' + ns.visit(i) for i in generators[0].ifs] +
386 | map(ns.visit, generators[1:]))),
387 | __iter=iter0)
388 |
389 | def visit_Continue(self, tree):
390 | return T('{__continue}()')
391 |
392 | def visit_Delete(self, tree):
393 | cs = [c for target in tree.targets for c in self.delete_code(target)]
394 | if cs:
395 | return T('({}, {after})[-1]').format(T(', ').join(cs))
396 | else:
397 | return T('{after}')
398 |
399 | def visit_Dict(self, tree):
400 | return T('{{{}}}').format(T(', ').join(
401 | T('{}: {}').format(k, v)
402 | for k, v in zip(map(self.visit, tree.keys), map(self.visit, tree.values))))
403 |
404 | def visit_DictComp(self, tree):
405 | return self.comprehension_code(
406 | tree.generators,
407 | lambda ns, g: T('{{{}: {} {}}}').format(
408 | T('{}'), ns.visit(tree.value), g).format(ns.visit(tree.key)))
409 |
410 | def visit_Ellipsis(self, tree):
411 | return T('...')
412 |
413 | def visit_ExceptHandler(self, tree):
414 | raise NotImplementedError('Open problem: except')
415 |
416 | def visit_Exec(self, tree):
417 | body = self.visit(tree.body)
418 | if tree.globals is None and self.table.get_type() == 'module':
419 | exec_code = T(
420 | "eval(compile({}, '', 'exec'), "
421 | "None, {__l})").format(body)
422 | elif tree.globals is None:
423 | exec_code = T(
424 | "(lambda b, c: (eval(compile(b, '', 'exec'), "
425 | "None, c), {__l}.update(c)))({}, {__l}.copy())").format(body)
426 | elif tree.locals is None and self.table.get_type() == 'module':
427 | exec_code = T(
428 | "(lambda b, g: eval(compile(b, '', 'exec'), g, "
429 | "{__l} if g is None else g))({}, {})").format(
430 | body, self.visit(tree.globals))
431 | elif tree.locals is None:
432 | exec_code = T(
433 | "(lambda b, g, c: (eval(compile(b, '', 'exec'), g, "
434 | "c if g is None else g), "
435 | "{__l}.update(c)))({}, {}, {__l}.copy())").format(
436 | body, self.visit(tree.globals))
437 | elif self.table.get_type() == 'module':
438 | exec_code = T(
439 | "(lambda b, g, l: eval(compile(b, '', 'exec'), g, "
440 | "({__l} if g is None else g) if l is None "
441 | "else l))({}, {}, {})").format(
442 | body, self.visit(tree.globals), self.visit(tree.locals))
443 | else:
444 | exec_code = T(
445 | "(lambda b, g, l, c: (eval(compile(b, '', 'exec'), g, "
446 | "(c if g is None else g) if l is None else l), "
447 | "{__l}.update(c)))({}, {}, {}, {__l}.copy())").format(
448 | body, self.visit(tree.globals), self.visit(tree.locals))
449 | return T('({}, {after})[1]').format(exec_code)
450 |
451 | def visit_Expr(self, tree):
452 | return T('({}, {after})[1]').format(self.visit(tree.value))
453 |
454 | def visit_Expression(self, tree):
455 | return self.visit(tree.body)
456 |
457 | def visit_ExtSlice(self, tree):
458 | return (T(', ').join(map(self.visit, tree.dims)) +
459 | ','*(len(tree.dims) == 1))
460 |
461 | def visit_For(self, tree):
462 | item = self.visit(tree.target)
463 | items = self.visit(tree.iter)
464 | body = self.many_to_one(tree.body, after='__this()')
465 | orelse = self.many_to_one(tree.orelse, after='__after()')
466 | return lambda_function({'__items': T('iter({})').format(items), '__sentinel':
467 | '[]', '__after': T('lambda: {after}')}).format(
468 | T('{__y}(lambda __this: lambda: {})()').format(
469 | lambda_function({'__i': 'next(__items, __sentinel)'}).format(
470 | T('{} if __i is not __sentinel else {}').format(
471 | provide(
472 | assignment_component(body, item, '__i'),
473 | __break='__after', __continue='__this'),
474 | orelse))))
475 |
476 | def visit_FunctionDef(self, tree):
477 | # self.visit() returns something of the form
478 | # ('lambda x, y, z=5, *args: ', ['x', 'y', 'z', 'args'])
479 | args, arg_names = self.visit(tree.args)
480 | decoration = T('{}')
481 | for decorator in tree.decorator_list:
482 | decoration = decoration.format(T('{}({})').format(self.visit(decorator), T('{}')))
483 | ns = self.next_child()
484 | body = ns.many_to_one(tree.body).format(pre_return='', post_return='')
485 | if arg_names:
486 | body = assignment_component(body,
487 | T(', ').join(ns.var(name) for name in arg_names),
488 | T(', ').join(arg_names))
489 | body = self.close(ns, '{}', body)
490 | function_code = args + body
491 | doc = ast.get_docstring(tree, clean=False)
492 | if tree.decorator_list:
493 | return assignment_component(
494 | T('{after}'),
495 | self.store_var(tree.name),
496 | decoration.format(assignment_component(
497 | '__func',
498 | '__func, __func.__name__' + ('' if doc is None else ', __func.__doc__'),
499 | T('{}, {!r}' + ('' if doc is None else ', {!r}')).format(
500 | function_code, tree.name, doc))))
501 | else:
502 | return assignment_component(
503 | T('{after}'),
504 | T('{}, {}.__name__' + ('' if doc is None else ', {}.__doc__')).format(
505 | self.store_var(tree.name), self.var(tree.name), self.var(tree.name)),
506 | T('{}, {!r}' + ('' if doc is None else ', {!r}')).format(
507 | function_code, tree.name, doc))
508 |
509 | def visit_arguments(self, tree):
510 | # this should return something of the form
511 | # ('lambda x, y, z=5, *args: ', ['x', 'y', 'z', 'args'])
512 | padded_defaults = [None] * (len(tree.args) -
513 | len(tree.defaults)) + tree.defaults
514 | arg_names = [arg.id for arg in tree.args]
515 | args = zip(padded_defaults, tree.args)
516 | args = [a.id if d is None else a.id + "=" + self.visit(d) for (d, a) in args]
517 | if tree.vararg is not None:
518 | args += ["*" + tree.vararg]
519 | arg_names += [tree.vararg]
520 | if tree.kwarg is not None:
521 | args += ["**" + tree.kwarg]
522 | arg_names += [tree.kwarg]
523 | args = T(', ').join(args)
524 | return (T('lambda {}: ').format(args), arg_names)
525 |
526 | def visit_GeneratorExp(self, tree):
527 | return self.comprehension_code(
528 | tree.generators,
529 | lambda ns, g: T('({} {})').format(ns.visit(tree.elt), g))
530 |
531 | def visit_Global(self, tree):
532 | return T('{after}')
533 |
534 | def visit_If(self, tree):
535 | test = self.visit(tree.test)
536 | body = self.many_to_one(tree.body, after='__after()')
537 | orelse = self.many_to_one(tree.orelse, after='__after()')
538 | return T('(lambda __after: {} if {} else {})(lambda: {after})').format(
539 | body, test, orelse)
540 |
541 | def visit_IfExp(self, tree):
542 | test = self.visit(tree.test)
543 | body = self.visit(tree.body)
544 | orelse = self.visit(tree.orelse)
545 | return T('({} if {} else {})').format(body, test, orelse)
546 |
547 | def visit_Import(self, tree):
548 | after = T('{after}')
549 | level_arg = ', level=0' if 'absolute_import' in self.futures else ''
550 | for alias in tree.names:
551 | ids = alias.name.split('.')
552 | if alias.asname is None:
553 | after = assignment_component(after, self.store_var(ids[0]),
554 | T('__import__({!r}, {__g}, {__l}{})').format(
555 | alias.name, level_arg))
556 | else:
557 | after = assignment_component(after, self.store_var(alias.asname),
558 | T('.').join([T('__import__({!r}, {__g}, {__l}{})').format(
559 | alias.name, level_arg)] + ids[1:]))
560 | return after
561 |
562 | def visit_ImportFrom(self, tree):
563 | body = assignment_component(
564 | T('{after}'),
565 | T(', ').join(self.store_var(alias.name if alias.asname is None
566 | else alias.asname) for alias in tree.names),
567 | T(', ').join('__mod.' + alias.name for alias in tree.names))
568 | if tree.module == '__future__':
569 | self.futures |= set(alias.name for alias in tree.names)
570 | body = T(
571 | '(lambda __f: type(__f)(type(__f.func_code)('
572 | '__f.func_code.co_argcount, '
573 | '__f.func_code.co_nlocals, '
574 | '__f.func_code.co_stacksize, '
575 | '__f.func_code.co_flags{}, '
576 | '__f.func_code.co_code, '
577 | '__f.func_code.co_consts, '
578 | '__f.func_code.co_names, '
579 | '__f.func_code.co_varnames, '
580 | '__f.func_code.co_filename, '
581 | '__f.func_code.co_name, '
582 | '__f.func_code.co_firstlineno, '
583 | '__f.func_code.co_lnotab, '
584 | '__f.func_code.co_freevars, '
585 | '__f.func_code.co_cellvars), '
586 | '__f.func_globals, '
587 | '__f.func_name, '
588 | '__f.func_defaults, '
589 | '__f.func_closure)())(lambda: {})'
590 | ).format(
591 | ''.join(' | __mod.' + alias.name + '.compiler_flag'
592 | for alias in tree.names),
593 | body)
594 | return T('(lambda __mod: {})(__import__({!r}, {__g}, {__l},'
595 | ' {!r}, {!r}))').format(
596 | body,
597 | '' if tree.module is None else tree.module,
598 | tuple(alias.name for alias in tree.names),
599 | tree.level)
600 |
601 | def visit_Index(self, tree):
602 | return self.visit(tree.value)
603 |
604 | def visit_keyword(self, tree):
605 | return T('{}={}').format(tree.arg, self.visit(tree.value))
606 |
607 | def visit_Lambda(self, tree):
608 | args, arg_names = self.visit(tree.args)
609 | ns = self.next_child()
610 | body = ns.visit(tree.body)
611 | if arg_names:
612 | body = assignment_component(body, T(', ').join(ns.store_var(name)
613 | for name in arg_names), T(', ').join(arg_names))
614 | body = self.close(ns, '{}', body)
615 | return '(' + args + body + ')'
616 |
617 | def visit_List(self, tree):
618 | elts = [self.visit(elt) for elt in tree.elts]
619 | return T('[{}]').format(T(', ').join(elts))
620 |
621 | def visit_ListComp(self, tree):
622 | return T('[{}]').format(T(' ').join([self.visit(tree.elt)] +
623 | map(self.visit, tree.generators)))
624 |
625 | def visit_Name(self, tree):
626 | if isinstance(tree.ctx, (ast.Store, ast.AugStore)):
627 | return self.store_var(tree.id)
628 | else:
629 | return self.var(tree.id)
630 |
631 | def visit_Num(self, tree):
632 | return T('{!r}').format(tree.n)
633 |
634 | def visit_Pass(self, tree):
635 | return T('{after}')
636 |
637 | def visit_Print(self, tree):
638 | to_print = T('{}')
639 | if tree.dest is not None:
640 | # Abuse varargs to get the right evaluation order
641 | to_print = T('file={}, *[{}]').format(self.visit(tree.dest), to_print)
642 | to_print = to_print.format(T(', ').join(self.visit(x) for x in tree.values))
643 | if not tree.nl:
644 | # TODO: This is apparently good enough for 2to3, but gets
645 | # many cases wrong (tests/unimplemented/softspace.py).
646 | to_print += ", end=' '"
647 | return T('({__print}({}), {after})[1]').format(to_print)
648 |
649 | def visit_Raise(self, tree):
650 | if tree.type is None:
651 | return T('([] for [] in []).throw(*{__sys}.exc_info())')
652 | else:
653 | return T('([] for [] in []).throw({}{}{})').format(
654 | self.visit(tree.type),
655 | '' if tree.inst is None else ', ' + self.visit(tree.inst),
656 | '' if tree.tback is None else ', ' + self.visit(tree.tback))
657 |
658 | def visit_Repr(self, tree):
659 | return T('`{}`').format(self.visit(tree.value))
660 |
661 | def visit_Return(self, tree):
662 | return T('{pre_return}{}{post_return}').format(
663 | 'None' if tree.value is None else self.visit(tree.value))
664 |
665 | def visit_Set(self, tree):
666 | assert tree.elts, '{} is a dict'
667 | return T('{{{}}}').format(T(', ').join(self.visit(elt) for elt in tree.elts))
668 |
669 | def visit_SetComp(self, tree):
670 | return self.comprehension_code(
671 | tree.generators,
672 | lambda ns, g: T('{{{} {}}}').format(ns.visit(tree.elt), g))
673 |
674 | def visit_Slice(self, tree):
675 | return T('{}:{}{}').format(
676 | '' if tree.lower is None else self.visit(tree.lower),
677 | '' if tree.upper is None else self.visit(tree.upper),
678 | '' if tree.step is None else ':' + self.visit(tree.step))
679 |
680 | def visit_Str(self, tree):
681 | return T('{!r}').format(tree.s)
682 |
683 | def visit_Subscript(self, tree):
684 | return T('{}[{}]').format(self.visit(tree.value), self.visit(tree.slice))
685 |
686 | def visit_TryExcept(self, tree):
687 | body = self.many_to_one(
688 | tree.body, after=T('(lambda __after: {orelse})')).format(
689 | orelse=self.many_to_one(tree.orelse, after='__after()'),
690 | pre_return=T('(lambda ret: lambda after: ret)({pre_return}'),
691 | post_return=T('{post_return})'))
692 | handlers = []
693 | for handler in tree.handlers:
694 | if handler.type is None:
695 | code = T('{body}')
696 | else:
697 | code = T('issubclass(__exctype, {type}) and {body}').format(
698 | type=self.visit(handler.type))
699 | if handler.name is not None:
700 | code = code.format(body=assignment_component(
701 | T('{body}'), self.visit(handler.name), '__value'))
702 | handlers.append(code.format(
703 | body=assignment_component(
704 | 'True',
705 | '__out[0]',
706 | self.many_to_one(handler.body, after='lambda after: after()').format(
707 | pre_return=T('(lambda ret: lambda after: ret)({pre_return}'),
708 | post_return=T('{post_return})')))))
709 | return \
710 | lambda_function({'__out': '[None]'}).format(
711 | lambda_function({
712 | '__ctx': T(
713 | "{__contextlib}.nested(type('except', (), {{"
714 | "'__enter__': lambda self: None, "
715 | "'__exit__': lambda __self, __exctype, __value, __traceback: "
716 | "__exctype is not None and ({handlers})}})(), "
717 | "type('try', (), {{"
718 | "'__enter__': lambda self: None, "
719 | "'__exit__': lambda __self, __exctype, __value, __traceback: "
720 | "{body}}})())").format(
721 | body=assignment_component('False', '__out[0]', body),
722 | handlers=T(' or ').join(handlers))
723 | }).format(
724 | T('[__ctx.__enter__(), __ctx.__exit__(None, None, None), __out[0](lambda: {after})][2]')))
725 |
726 | def visit_TryFinally(self, tree):
727 | body = self.many_to_one(
728 | tree.body, after=T('(lambda after: after())')).format(
729 | pre_return=T('(lambda ret: lambda after: ret)({pre_return}'),
730 | post_return=T('{post_return})'))
731 |
732 | finalbody = self.many_to_one(tree.finalbody, after=T('{after}'))
733 | if 'pre_return' in finalbody.free():
734 | finalbody = T('({})(lambda ret: {})').format(
735 | finalbody.format(
736 | after='lambda change_ret: False',
737 | pre_return=T('(lambda ret: lambda change_ret: change_ret(ret))({pre_return}'),
738 | post_return=T('{post_return})')),
739 | assignment_component('True', '__out[0]', 'lambda after: ret'))
740 | else:
741 | finalbody = finalbody.format(after='False')
742 |
743 | return \
744 | lambda_function({'__out': '[None]'}).format(
745 | lambda_function({
746 | '__ctx': T(
747 | "{__contextlib}.nested(type('except', (), {{"
748 | "'__enter__': lambda self: None, "
749 | "'__exit__': lambda __self, __exctype, __value, __traceback: "
750 | "{finalbody}}})(), "
751 | "type('try', (), {{"
752 | "'__enter__': lambda self: None, "
753 | "'__exit__': lambda __self, __exctype, __value, __traceback: "
754 | "{body}}})())").format(
755 | body=assignment_component('False', '__out[0]', body),
756 | finalbody=finalbody)
757 | }).format(
758 | T('[__ctx.__enter__(), __ctx.__exit__(None, None, None), __out[0](lambda: {after})][2]')))
759 |
760 | def visit_Tuple(self, tree):
761 | return T('({})').format(T(', ').join(map(self.visit, tree.elts)) +
762 | ','*(len(tree.elts) == 1))
763 |
764 | def visit_UnaryOp(self, tree):
765 | return T('({}{})').format(unaryop_code[type(tree.op)], self.visit(tree.operand))
766 |
767 | def visit_While(self, tree):
768 | test = self.visit(tree.test)
769 | body = self.many_to_one(tree.body, after='__this()')
770 | orelse = self.many_to_one(tree.orelse, after='__after()')
771 | return lambda_function({'__after': T('lambda: {after}')}).format(
772 | T('{__y}(lambda __this: lambda: {} if {} else {})()').format(
773 | provide(body, __break='__after', __continue='__this'),
774 | test, orelse))
775 |
776 | def visit_With(self, tree):
777 | raise NotImplementedError('Open problem: with')
778 |
779 | def visit_Yield(self, tree):
780 | raise NotImplementedError('Open problem: yield')
781 |
782 | def generic_visit(self, tree):
783 | raise NotImplementedError('Case not caught: %s' % str(type(tree)))
784 |
785 |
786 | # The entry point for everything.
787 | def onelinerize(original):
788 | # original :: string
789 | # :: string
790 | t = ast.parse(original)
791 | table = symtable.symtable(original, '', 'exec')
792 |
793 | original = original.strip()
794 |
795 | # If there's only one line anyways, be lazy
796 | if len(original.splitlines()) == 1 and \
797 | len(t.body) == 1 and \
798 | type(t.body[0]) in (ast.Delete, ast.Assign, ast.AugAssign, ast.Print,
799 | ast.Raise, ast.Assert, ast.Import, ast.ImportFrom,
800 | ast.Exec, ast.Global, ast.Expr, ast.Pass):
801 | return original
802 |
803 | return get_init_code(t, table)
804 |
--------------------------------------------------------------------------------