En beaucoup trop détaillé : http://worlddomination.be/about/about.html
Pas lossless !
ast_to_code(code_to_ast(code_source)) != source_code
(Commentaires, formatting)
(Et ast_to_code n'existe même pas de manière standard).
API Sax like
1 class KeyAttributesFinder(ast.NodeVisitor):
2 def visit_Assign(self, assign_node):
3 # ...
4
5 def visit_FunctionDef(self, function_node):
6 # ...
7
8 # visit_...
Super chiant, impossible à utiliser dans IPython efficacement.
Auto formater du code python
Django (memopol et co) :
donnees.json -> models.py + import.py
Autre projet :
Générer du boiler plate en lisant des models de db
1 from baron.helpers import show
2
3 print show("1 + 2")
4
5 [
6 {
7 "first_formatting": [
8 {
9 "type": "space",
10 "value": " "
11 }
12 ],
13 "value": "+",
14 "second_formatting": [
15 {
16 "type": "space",
17 "value": " "
18 }
19 ],
20 "second": {
21 "section": "number",
22 "type": "int",
23 "value": "2"
24 },
25 "type": "binary_operator",
26 "first": {
27 "section": "number",
28 "type": "int",
29 "value": "1"
30 }
31 }
32 ]
1 an de boulot (j'ai dû apprendre)
API super simple :
1 from redbaron import RedBaron
2
3 red = RedBaron("string représentant du code source")
4 # ...
5 red.dumps() # code source
Surcharge de __repr__ :
BeautifulSoup :
Surcharge de __repr__ :
BeautifulSoup :
RedBaron :
RedBaron :
RedBaron :
".help()"
Comme BeautifulSoup :
1 red = RedBaron("a = 42\ndef test_chocolat(): pass")
2 red.find("name")
3 red.find("int", value=42)
4 red.find("def", name="g:test_*")
5 red.find("def", name="re:test_*")
6 red.find("assignment", lambda x: x.target.dumps() == "INSTALLED_APPS")
7
8 red.find_all("name")
9 red.find_all(("name", "int"))
10 red.find_all("def", arguments=lambda x: len(x) == 3)
11 red.find_all("def", recursive=False)
Comme BeautifulSoup :
1 red = RedBaron("a = 42\ndef test_chocolat(): pass")
2 red.find("name")
3 red.find("int", value=42)
4 red.find("def", name="g:test_*")
5 red.find("def", name="re:test_*")
6 red.find("assignment", lambda x: x.target.dumps() == "INSTALLED_APPS")
7
8 red.find_all("name")
9 red.find_all(("name", "int"))
10 red.find_all("def", arguments=lambda x: len(x) == 3)
11 red.find_all("def", recursive=False)
Raccourcis (comme BeautifulSoup) :
1 red = RedBaron("a = 42\ndef test_chocolat(): pass")
2 red.name
3 red.int
4 red.else_
5
6 red("name")
7 red(("name", "int"))
8 red("def", arguments=lambda x: len(x) == 3)
Comment modifier une node ?
1 from redbaron import RedBaron, BinaryOperatorNode
2
3 red = RedBaron("a = 'plop'")
4 red[O].value # 'plop'
5 red[0].value = BinaryOperatorNode({'first_formatting':[{'type': 'space',
6 'value': ' '}], 'value': '+', 'second_formatting': [{'type': 'space',
7 'value': ' '}], 'second': {'section': 'number', 'type': 'int', 'value':
8 '1'}, 'type': 'binary_operator', 'first': {'section': 'number', 'type':
9 'int', 'value': '1'}})
Pas hyper pratique ...
1 from redbaron import RedBaron, BinaryOperatorNode
2
3 red = RedBaron("a = 'plop'")
4 red[0].value = "1 + 1"
5
6 # marche aussi avec : nodes redbaron et ast
Marche pour toutes les nodes.
Autre problème : quel est le corps/body de la fonction "bar" ?
1 class Foo():
2 def bar(self):
3 pass
4
5 def baz(self):
6 pass
Autre problème : quel est le corps/body de la fonction "bar" ?
1 class Foo():
2 def bar(self):
3 pass
4
5 def baz(self):
6 pass
Expected :
Autre problème : quel est le corps/body de la fonction "bar" ?
1 class Foo():
2 def bar(self):
3 pass
4
5 def baz(self):
6 pass
Expected :
Reality :