ast: threats and opportunities

Post on 16-Apr-2017

80 Views

Category:

Software

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

ASTOpportunities and Threats

ITGM, Dec 2016

RDD

TDD

Slap this sh*t & release

ITGM, Dec 2016

Code Test

Test

Test

ITGM, Dec 2016

Code Test

Test

Test

def f(a,b): return a+b

5 == f(2,3)

0 == f(2,-2)

1 == f(1,0)

ITGM, Dec 2016

Code Test

Test

Test

def f(a,b): return a+b

5 == f(2,3)

0 == f(2,-2)

1 == f(1,0)

Test 1e15 == f(1,1e15-1)

ITGM, Dec 2016

DIS

ITGM, Dec 2016

>>> def foo(): ... a = 2 ... b = 3 ... return a + b ...

ITGM, Dec 2016

>>> import dis >>> dis.dis(foo) 2 0 LOAD_CONST 1 (2) 3 STORE_FAST 0 (a)

3 6 LOAD_CONST 2 (3) 9 STORE_FAST 1 (b)

4 12 LOAD_FAST 0 (a) 15 LOAD_FAST 1 (b) 18 BINARY_ADD 19 RETURN_VALUE

ITGM, Dec 2016

ITGM, Dec 2016

ITGM, Dec 2016

Zephyr ASDLParser/Python.asdl

ITGM, Dec 2016

Python/Python-ast.cimport _ast

ITGM, Dec 2016

Lib/ast.pyimport ast

ITGM, Dec 2016

• AST

• Add, And, Assert …

• NodeVisitor

• NodeTransformer

ITGM, Dec 2016

class DepthVisitor(ast.NodeVisitor): depth = 0

def generic_visit(self, node): parent = node.parent if parent: while parent: self.depth += 1 parent = parent.parent ast.NodeVisitor.generic_visit(self, node)

ITGM, Dec 2016

• parse

• copy_location

• fix_missing_locations

• dump

• increment_lineno

ITGM, Dec 2016

Модификация AST

ITGM, Dec 2016

class HackedImporter: def load_module(self, name): # do magic stuff return module

sys.path_hook.insert(0, HackedImporter)

ITGM, Dec 2016

https://github.com/alifanov/ast-spbpython-example

ITGM, Dec 2016

class ReturnIncrement(ast.NodeTransformer): def visit_Return(self, node): node.value = (ast.BinOp( left=node.value, op=ast.Add(), right=ast.Num(n=1) ) return node

ITGM, Dec 2016

def transform_with(transformer): def transform_decorator(func): node = func_to_node(func) node = transformer().visit(node) node = ast.fix_missing_locations(node) func = node_to_func(node, func) return func return transform_decorator

ITGM, Dec 2016

@transform_with(ReturnIncrementer) def f(a,b): return a+b

f(2,2) # 5

ITGM, Dec 2016

Threats

• Debug glitch

• Errors with multiple applies

• Strange errors

• Compiler version dependence

ITGM, Dec 2016

>>> parseprint("func(a, b=c, *d, **e)") # Python 3.4 Module(body=[ Expr(value=Call(func=Name(id='func', ctx=Load()), args=[Name(id='a', ctx=Load())], keywords=[keyword(arg='b', value=Name(id='c', ctx=Load()))], starargs=Name(id='d', ctx=Load()), # gone in 3.5 kwargs=Name(id='e', ctx=Load()))), # gone in 3.5 ])

>>> parseprint("func(a, b=c, *d, **e)") # Python 3.5 Module(body=[ Expr(value=Call(func=Name(id='func', ctx=Load()), args=[ Name(id='a', ctx=Load()), Starred(value=Name(id='d', ctx=Load()), ctx=Load()) # new in 3.5 ], keywords=[ keyword(arg='b', value=Name(id='c', ctx=Load())), keyword(arg=None, value=Name(id='e', ctx=Load())) # new in 3.5 ])) ])

ITGM, Dec 2016

Opportunities• Constant propagation

• Autologger

• Autoprofiler

• Macros (karnickel)

• Extend language

• MacroPy

• PonyORM

• Linters (auto codereview)ITGM, Dec 2016

>>> from macropy.tracing import macros, trace >>> trace[[x*2 for x in range(3)]] range(3) -> [0, 1, 2] x*2 -> 0 x*2 -> 2 x*2 -> 4 x*2 for x in range(3) -> [0, 2, 4] [0, 2, 4]

Macros

ITGM, Dec 2016

welcome = gettext("Welcome, {}!").format(user_name)

welcome = gettext("Welcome, {}!".format(user_name))

Linters

ITGM, Dec 2016

https://github.com/edx/edx-lint/blob/master/edx_lint/pylint/i18n_check.py

Linters

ITGM, Dec 2016

TRANSLATION_FUNCTIONS = set([ '_', 'gettext', 'ngettext', 'ngettext_lazy', 'npgettext', 'npgettext_lazy', 'pgettext', 'pgettext_lazy', 'ugettext', 'ugettext_lazy', 'ugettext_noop', 'ungettext', 'ungettext_lazy', ])

def visit_callfunc(self, node): if not isinstance(node.func, astroid.Name): # It isn't a simple name, can't deduce what function it is. return

if node.func.name not in self.TRANSLATION_FUNCTIONS: # Not a function we care about. return

if not self.linter.is_message_enabled(self.MESSAGE_ID): return

first = node.args[0] if isinstance(first, astroid.Const): if isinstance(first.value, basestring): # The first argument is a constant string! All is well! return

# Bad! self.add_message(self.MESSAGE_ID, args=node.func.name, node=node)

ITGM, Dec 2016

Tools• astdump

• astviewer

• ast_tool_box

• astroid

• baron

• redbaron

• astor

• meta

• astmonkey

ITGM, Dec 2016

Recommendation unit tests system

ITGM, Dec 2016

Pythoscope

ITGM, Dec 2016

Smother

ITGM, Dec 2016

app.views:add,app/tests.py::FunctionTest::test_add app.views:fact,app/tests.py::FunctionTest::test_fact app.views:hello,app/tests.py::FunctionTest::test_hello

ITGM, Dec 2016

Code1 Test1

Code1 Test2

Code1 Test3

Code2 Test1

Code2 Test2

ITGM, Dec 2016

def test_default_ordering(self): class OrderingListView(generics.ListAPIView): queryset = OrderingFilterModel.objects.all() serializer_class = OrderingFilterSerializer filter_backends = (filters.OrderingFilter,) ordering = ('title',) ordering_fields = ('text',)

view = OrderingListView.as_view() request = factory.get('') response = view(request) self.assertEqual( response.data, [ {'id': 3, 'title': 'xwv', 'text': 'cde'}, {'id': 2, 'title': 'yxw', 'text': 'bcd'}, {'id': 1, 'title': 'zyx', 'text': 'abc'}, ] ) # not in context

ITGM, Dec 2016

def fact(a): if a == 0: return 1 return a * fact(a - 1)

def test_fact(self): self.assertTrue(fact(0) == 1) self.assertTrue(fact(1) == 1) self.assertTrue(fact(2) == 2) self.assertTrue(fact(3) == 6) self.assertTrue(fact(4) == 24)

ITGM, Dec 2016

github.com

ITGM, Dec 2016

https://www.cosc.canterbury.ac.nz/research/reports/HonsReps/2015/hons_1508.pdf

ITGM, Dec 2016

ITGM, Dec 2016

ITGM, Dec 2016

ITGM, Dec 2016

ITGM, Dec 2016

ITGM, Dec 2016

ITGM, Dec 2016

Edges

ITGM, Dec 2016

BinOpLeftNum

ITGM, Dec 2016

Child Edge Parent Freq

Num left BinOp 12

Num value Assign 20

ITGM, Dec 2016

Depth

ITGM, Dec 2016

Builtin function

ITGM, Dec 2016

https://github.com/alifanov/testedio

ITGM, Dec 2016

Roadmap

ITGM, Dec 2016

Improve searchmodules names as features

ITGM, Dec 2016

Import github projectsunit-test monitoring

ITGM, Dec 2016

Fuzzy recommendations

hypothesis*pylint plugin

ITGM, Dec 2016

Performance optimizationmap -> list comprehension

*pylint plugin

ITGM, Dec 2016

Other languagesJavaScript

ITGM, Dec 2016

Real TDDtests -> code generation

ITGM, Dec 2016

Linkshttps://github.com/mkwiatkowski/pythoscope http://smother.readthedocs.io/en/latest/index.html http://testmon.org/ https://www.cosc.canterbury.ac.nz/research/reports/HonsReps/2015/hons_1508.pdf http://is.ifmo.ru/diploma-theses/2013/bachelor/rost/rost.pdf https://habrahabr.ru/post/65944/ http://pyke.sourceforge.net/

ITGM, Dec 2016

Contacts

Telegram: @jetbootsmaker

Alexander Lifanov

ITGM, Dec 2016

top related