-
-
Notifications
You must be signed in to change notification settings - Fork 40
Update Python integration #15
Changes from all commits
2bfe9d7
8224c07
b7b8cf1
33c98cb
2e096ff
ee7d610
7291885
9691a9c
ddb74b8
7a1fdd4
b1f31a0
3c47843
a580f63
4a0c38d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,22 +4,19 @@ node_js: | |
- 6 | ||
- 8 | ||
- 9 | ||
env: | ||
- PYTHON_VERSION=2.7.14 | ||
- PYTHON_VERSION=3.6.3 | ||
cache: | ||
yarn: true | ||
directories: | ||
- node_modules | ||
- /home/travis/.pyenv_cache | ||
before_install: | ||
- pyenv install -s $PYTHON_VERSION | ||
- pyenv global $PYTHON_VERSION | ||
- python --version | ||
install: | ||
- yarn install | ||
before_install: | ||
- export PYTHON_BUILD_CACHE_PATH="/home/travis/.pyenv_cache" | ||
- curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Turns out pyenv is already available on Travis (even when the language is |
||
- export PATH="/home/travis/.pyenv/bin:$PATH" | ||
- eval "$(pyenv init -)" | ||
- eval "$(pyenv virtualenv-init -)" | ||
- pyenv install -s 2.7.11 | ||
- pyenv install -s 3.6.3 | ||
- pyenv global 2.7.11 3.6.3 | ||
script: | ||
- yarn lint | ||
- yarn test -- --runInBand | ||
- yarn test --runInBand |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,8 @@ | ||
import ast | ||
import fileinput | ||
import json | ||
import tokenize | ||
|
||
import asttokens | ||
|
||
|
||
def export_json(atok, pretty_print=False): | ||
dict = export_dict(atok) | ||
dict['comments'] = [{ | ||
'ast_type': 'comment', | ||
'value': token.string, | ||
'start': token.startpos, | ||
'end': token.endpos, | ||
} for token in atok.tokens if token.type == 57] | ||
return json.dumps( | ||
dict, | ||
indent=4 if pretty_print else None, | ||
sort_keys=True, | ||
separators=(",", ": ") if pretty_print else (",", ":") | ||
) | ||
|
||
|
||
def export_dict(atok): | ||
return DictExportVisitor(atok).visit(atok.tree) | ||
|
||
|
||
class DictExportVisitor: | ||
class DictExportVisitor(object): | ||
ast_type_field = "ast_type" | ||
|
||
def __init__(self, atok): | ||
|
@@ -102,21 +79,17 @@ def visit_field_Num_n(self, val): | |
} | ||
|
||
|
||
def parse(source): | ||
assert (isinstance(source, str)) | ||
|
||
atok = asttokens.ASTTokens(source, parse=True) | ||
|
||
return atok | ||
|
||
|
||
def main(): | ||
source = "".join(fileinput.input()) | ||
|
||
tree = parse(source) | ||
json = export_json(tree, True) | ||
print(json) | ||
def export(atok): | ||
exported_ast = DictExportVisitor(atok).visit(atok.tree) | ||
|
||
exported_ast['comments'] = [ | ||
{ | ||
'ast_type': 'comment', | ||
'value': token.string, | ||
'start': token.startpos, | ||
'end': token.endpos, | ||
} | ||
for token in atok.tokens if token.type == tokenize.COMMENT | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. resolves https://github.com/prettier/prettier-python/pull/9/files#r158746577 and correspondingly fixes comment handling in python 2 |
||
] | ||
|
||
if __name__ == '__main__': | ||
main() | ||
return exported_ast |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import os | ||
import sys | ||
|
||
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | ||
|
||
sys.path.insert(0, os.path.join(base_dir, 'vendor')) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've seen this pattern used elsewhere for CLI-y things where messing with the global Python path isn't a problem. I like that this hides the vendoring details from the caller. It's also good to split out vendored things from things that are patched from upstream. |
||
sys.path.insert(0, os.path.join(base_dir, 'patched')) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import json | ||
import sys | ||
|
||
import astexport | ||
import asttokens | ||
|
||
|
||
def main(): | ||
source = sys.stdin.read() | ||
atok = asttokens.ASTTokens(source, parse=True) | ||
|
||
exported_ast = astexport.export(atok) | ||
json.dump(exported_ast, sys.stdout, separators=(',', ':')) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,31 +3,24 @@ | |
const spawnSync = require("child_process").spawnSync; | ||
const path = require("path"); | ||
|
||
function parseText(text, pythonExecutable) { | ||
const executionResult = spawnSync( | ||
pythonExecutable, | ||
[path.join(__dirname, "../vendor/python/astexport.py")], | ||
{ | ||
input: text | ||
} | ||
); | ||
|
||
const error = executionResult.stderr.toString(); | ||
|
||
if (error) { | ||
throw new Error(error); | ||
function parse(text) { | ||
const executionResult = spawnSync("python", ["-m", "prettier.parser"], { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you get a bit more flexibility when you run something as a module... you can do things like relative imports, which are sorta handy |
||
env: { | ||
PATH: process.env.PATH, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is so the virtualenv python gets picked up. i don't think we need anything else from env here |
||
PYTHONPATH: [ | ||
path.join(__dirname, "../python"), | ||
process.env.PYTHONPATH | ||
].join(path.delimiter) | ||
}, | ||
input: text | ||
}); | ||
|
||
if (executionResult.status) { | ||
throw new Error(executionResult.stderr.toString()); | ||
} | ||
|
||
return executionResult; | ||
} | ||
|
||
function parse(text, parsers, opts) { | ||
const pythonExectuable = `python${opts.pythonVersion == "2" ? "" : "3"}`; | ||
const executionResult = parseText(text, pythonExectuable); | ||
|
||
const res = executionResult.stdout.toString(); | ||
const ast = JSON.parse(res); | ||
return ast; | ||
return JSON.parse(res); | ||
} | ||
|
||
module.exports = parse; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1 @@ | ||
run_spec(__dirname, ["python"], { | ||
pythonVersion: "3" | ||
}); | ||
run_spec(__dirname, ["python"], ">=3"); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
run_spec(__dirname, ["python"], { pythonVersion: "3" }); | ||
run_spec(__dirname, ["python"], ">=3"); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
run_spec(__dirname, ["python"], { pythonVersion: "3" }); | ||
run_spec(__dirname, ["python"], ">=3.5"); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
run_spec(__dirname, ["python"], { pythonVersion: "3" }); | ||
run_spec(__dirname, ["python"], ">=3.5"); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
run_spec(__dirname, ["python"], { pythonVersion: "3" }); | ||
run_spec(__dirname, ["python"], ">=3.6"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. might as well... python 3.5 still sees some use, since it's what some of the active ubuntu LTS versions still ship There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Elasticbeanstalk (AWS) is stuck to python 3.4, I'd keep support for 3.4+ if possible |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
run_spec(__dirname, ["python"], { pythonVersion: "3" }); | ||
run_spec(__dirname, ["python"], ">=3"); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1 @@ | ||
run_spec(__dirname, ["python"], { pythonVersion: "2" }); | ||
run_spec(__dirname, ["python"], { pythonVersion: "3" }); | ||
run_spec(__dirname, ["python"], "*"); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1 @@ | ||
run_spec(__dirname, ["python"], { pythonVersion: "2" }); | ||
run_spec(__dirname, ["python"], { pythonVersion: "3" }); | ||
run_spec(__dirname, ["python"], "*"); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1 @@ | ||
run_spec(__dirname, ["python"], { pythonVersion: "2" }); | ||
run_spec(__dirname, ["python"], { pythonVersion: "3" }); | ||
run_spec(__dirname, ["python"], "*"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2.7.14 is the current release here; 2.7.11 is two years old and hasn't been current for a year and a half