Skip to content
This repository was archived by the owner on Mar 27, 2019. It is now read-only.

Commit c6b0cff

Browse files
authored
Add flake8 linter to project and travis ci (#46)
1 parent a5d5807 commit c6b0cff

29 files changed

+597
-407
lines changed

.travis.yml

+1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ before_install:
1313
install: "make"
1414

1515
script:
16+
- make lint
1617
- make test

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ init:
44
pip install pipenv
55
pipenv install --dev
66

7+
lint:
8+
pipenv run flake8
9+
710
test:
811
pipenv run pytest test_langserver.py
912
cd ./test && pipenv run pytest test_*.py

Pipfile

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ lightstep = "*"
1818
py = "==1.4.34"
1919
pytest = "==3.2.3"
2020
"autopep8" = "*"
21+
"flake8" = "*"
22+
autoflake = "*"
23+
docformatter = "*"
2124

2225

2326
[requires]

Pipfile.lock

+40-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

langserver/config.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import os
2-
import os.path
31
import distutils
42

3+
54
class GlobalConfig:
65

76
# TODO: allow different Python stdlib versions per workspace?

langserver/definitions.py

+14-10
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@
88

99

1010
class TargetedSymbolVisitor:
11-
"""
12-
The purpose of this class is to take a SymbolDescriptor (typically the result of a preceding x-definition request)
13-
and perform a more precise symbol search based on the extra metadata available in the descriptor.
14-
"""
11+
"""The purpose of this class is to take a SymbolDescriptor (typically the
12+
result of a preceding x-definition request) and perform a more precise
13+
symbol search based on the extra metadata available in the descriptor."""
14+
1515
def __init__(self, name, kind, path):
1616
self.name = name
1717
self.kind = kind
18-
# the AST nodes for modules don't contain their name, so we have to infer it from the file or folder name
18+
# the AST nodes for modules don't contain their name, so we have to
19+
# infer it from the file or folder name
1920
folder, file = os.path.split(path)
2021
if file == "__init__.py":
2122
self.module = os.path.basename(folder)
@@ -38,7 +39,8 @@ def visit_Module(self, node, container):
3839
yield from self.generic_visit(node)
3940

4041
def visit_ImportFrom(self, node, container):
41-
# this handles the case where imported symbols are re-exported; an xj2d sometimes needs to land here
42+
# this handles the case where imported symbols are re-exported; an xj2d
43+
# sometimes needs to land here
4244
for n in node.names:
4345
if n.name == self.name:
4446
yield Symbol(
@@ -116,8 +118,8 @@ def visit_Assign(self, assign_node, container):
116118
return
117119

118120
def visit_If(self, node, container):
119-
# If is often used provide different implementations for the same var. To avoid duplicate names, we only visit
120-
# the true body.
121+
# If is often used provide different implementations for the same var. To avoid duplicate
122+
# names, we only visit the true body.
121123
for child in node.body:
122124
yield from self.visit(child, container)
123125

@@ -171,9 +173,11 @@ def targeted_symbol(symbol_descriptor, fs, root_path, parent_span):
171173
try:
172174
tree = ast.parse(source, path)
173175
except SyntaxError as e:
174-
log.error("Error parsing Python file %s:%s -- %s: %s", path, e.lineno, e.msg, e.text)
176+
log.error("Error parsing Python file %s:%s -- %s: %s",
177+
path, e.lineno, e.msg, e.text)
175178
continue
176-
visitor = TargetedSymbolVisitor(symbol_descriptor["name"], symbol_descriptor["kind"], path)
179+
visitor = TargetedSymbolVisitor(
180+
symbol_descriptor["name"], symbol_descriptor["kind"], path)
177181
for sym in visitor.visit(tree):
178182
sym.file = path
179183
symbols.append(sym.json_object())

langserver/fetch.py

+26-15
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,50 @@
1111

1212

1313
def fetch_dependency(module_name: str, specifier: str, install_path: str):
14-
"""
15-
Shells out to PIP in order to download and unzip the named package into the specified path. This method only runs
16-
`pip download`, NOT `pip install`, so it's presumably safe.
14+
"""Shells out to PIP in order to download and unzip the named package into
15+
the specified path. This method only runs `pip download`, NOT `pip
16+
install`, so it's presumably safe.
17+
1718
:param module_name: the name of the package to download
1819
:param specifier: the version specifier for the package
1920
:param install_path: the path in which to install the downloaded package
2021
"""
2122
with tempfile.TemporaryDirectory() as download_folder:
22-
log.info("Attempting to download package %s to %s", module_name, download_folder, exc_info=True)
23+
log.info("Attempting to download package %s to %s",
24+
module_name, download_folder, exc_info=True)
2325
# TODO: check the result status
2426

2527
index_url = os.environ.get('INDEX_URL')
2628
if index_url is not None:
27-
result = pip.main(["download", "--no-deps", "-i", index_url, "-d", download_folder, module_name+specifier])
29+
result = pip.main(["download", "--no-deps", "-i", index_url,
30+
"-d", download_folder, module_name + specifier])
2831
else:
29-
result = pip.main(["download", "--no-deps", "-d", download_folder, module_name+specifier])
32+
result = pip.main(["download", "--no-deps", "-d",
33+
download_folder, module_name + specifier])
3034
if result != pip.status_codes.SUCCESS:
3135
log.error("Unable to fetch package %s", module_name)
3236
return
3337
for thing in os.listdir(download_folder):
3438
thing_abs = os.path.join(download_folder, thing)
3539
if os.path.isdir(thing_abs):
36-
log.debug("Moving %s to %s", thing, install_path, exc_info=True)
40+
log.debug("Moving %s to %s", thing,
41+
install_path, exc_info=True)
3742
shutil.move(thing_abs, install_path)
3843
elif thing.endswith(".whl") or thing.endswith(".zip"):
39-
log.debug("Unzipping %s to %s", thing, install_path, exc_info=True)
40-
result = subprocess.run(["unzip", "-o", "-d", install_path, thing_abs])
44+
log.debug("Unzipping %s to %s", thing,
45+
install_path, exc_info=True)
46+
result = subprocess.run(
47+
["unzip", "-o", "-d", install_path, thing_abs])
4148
elif thing.endswith(".tar.gz"):
42-
log.debug("Untarring %s to %s", thing, install_path, exc_info=True)
43-
result = subprocess.run(["tar", "-C", install_path, "-xzf", thing_abs])
49+
log.debug("Untarring %s to %s", thing,
50+
install_path, exc_info=True)
51+
result = subprocess.run(
52+
["tar", "-C", install_path, "-xzf", thing_abs])
4453
elif thing.endswith(".tar.bz2"):
45-
log.debug("Untarring %s to %s", thing, install_path, exc_info=True)
46-
result = subprocess.run(["tar", "-C", install_path, "-xjf", thing_abs])
54+
log.debug("Untarring %s to %s", thing,
55+
install_path, exc_info=True)
56+
result = subprocess.run(
57+
["tar", "-C", install_path, "-xjf", thing_abs])
4758
else:
48-
log.warning("Unrecognized package file: %s", thing, exc_info=True)
49-
59+
log.warning("Unrecognized package file: %s",
60+
thing, exc_info=True)

langserver/fs.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import base64
21
import os
32
import os.path
43
from abc import ABC, abstractmethod
@@ -54,7 +53,6 @@ def open(self, path, parent_span=None):
5453
return open_file.read()
5554

5655
def listdir(self, path, parent_span=None):
57-
entries = []
5856
names = os.listdir(path)
5957
# TODO: prepend `path` to each name?
6058
return names
@@ -124,7 +122,7 @@ def walk(self, path):
124122

125123
def batch_open(self, paths, parent_span):
126124
with opentracing.start_child_span(
127-
parent_span, "RemoteFileSystem.batch_open") as batch_open_span:
125+
parent_span, "RemoteFileSystem.batch_open"):
128126
# We need to read the iterator paths twice, so convert to list
129127
paths = list(paths)
130128
responses = self.conn.send_request_batch(("textDocument/xcontent",
@@ -136,7 +134,8 @@ def batch_open(self, paths, parent_span):
136134
}) for path in paths)
137135
for path, resp in zip(paths, responses):
138136
if "error" in resp:
139-
# Consume rest of generator to ensure resources are shutdown
137+
# Consume rest of generator to ensure resources are
138+
# shutdown
140139
for _ in responses:
141140
pass
142141
raise FileException(resp["error"])
@@ -174,8 +173,9 @@ def listdir(self, path: str, parent_span) -> List[Entry]:
174173
return entries.values()
175174

176175

177-
# TODO(aaron): determine whether this extra filesystem is really necessary, or if we could have just used a local fs
178-
# I suspect not, because the new workspace indexing/importing code wasn't written with a local fs in mind
176+
# TODO(aaron): determine whether this extra filesystem is really necessary, or if we could have
177+
# just used a local fs I suspect not, because the new workspace indexing/importing code wasn't
178+
# written with a local fs in mind
179179
class TestFileSystem(FileSystem):
180180
def __init__(self, local_root_path: str):
181181
self.root = os.path.abspath(local_root_path)
@@ -194,7 +194,9 @@ def batch_open(self, paths, parent_span):
194194

195195
def listdir(self, path: str, parent_span=None):
196196
path = os.path.abspath(path)
197-
if not path.startswith(self.root): # need this check for namespace imports, for which we get a relative path
197+
# need this check for namespace imports, for which we get a relative
198+
# path
199+
if not path.startswith(self.root):
198200
if path.startswith("/"):
199201
path = path[1:]
200202
path = os.path.join(self.root, path)

langserver/imports.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44

55

66
def get_imports(fs, root_path, parent_span):
7-
# TODO: consider crawling over the main project files only; ignore examples, tests, etc
7+
# TODO: consider crawling over the main project files only; ignore
8+
# examples, tests, etc
89
py_paths = (path for path in fs.walk(root_path) if path.endswith(".py"))
910
py_srces = fs.batch_open(py_paths, parent_span)
1011
with multiprocessing.Pool() as p:
1112
import_chunks = p.imap_unordered(
1213
_imap_extract_imports, py_srces, chunksize=10)
13-
imports = {i.split(".")[0] for i in itertools.chain.from_iterable(import_chunks)}
14+
imports = {i.split(".")[0]
15+
for i in itertools.chain.from_iterable(import_chunks)}
1416
return imports
1517

1618

@@ -41,7 +43,9 @@ def visit_Import(self, node, container):
4143
yield n.name
4244

4345
def visit_ImportFrom(self, node, container):
44-
if not node.level: # we only care about top-level imports, and definitely want to ignore internal imports
46+
# we only care about top-level imports, and definitely want to
47+
# ignore internal imports
48+
if not node.level:
4549
yield node.module
4650

4751
# Based on ast.NodeVisitor.visit

0 commit comments

Comments
 (0)