Skip to content

Commit 36e2220

Browse files
committed
Better configuration setting, documentation
This is v0.1.2 of the plugin. It addresses some deficiencies in the documentation, and deals with configuration pass-through from the language server more correctly. * Adds docs/Configuration.md to detail what configuration options are supported * Updates docs/kate.md to detail how to pass settings from Kate's LSP config structure * Updates README.md with more precise details about the configuration * Updates README.md with more links, reflowed text, reorganised text * Updates the plugin to default the configuration as "enabled, but don't create pyre config" * Updates the plugin to log when the pyre config option is somehow missing * Moves the pyre config file creation out of the `initialize` hook and into the point before running Pyre * Decorates error messages with the plugin name
1 parent 04b914e commit 36e2220

File tree

5 files changed

+129
-57
lines changed

5 files changed

+129
-57
lines changed

README.md

+20-10
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
# python-lsp-pyre
22

3-
Implements support for calling Meta's [Pyre type checker](https://github.com/facebook/pyre-check) via a subprocess.
4-
53
This is a plugin for the [Python LSP Server](https://github.com/python-lsp/python-lsp-server).
64

7-
It was written to scratch an itch, so may not be quite what you're looking for.
5+
It implements support for calling Meta's [Pyre type checker](https://github.com/facebook/pyre-check) via a subprocess.
86

97
## Installation
108

@@ -20,16 +18,17 @@ or to make it a development requirement in Poetry
2018
poetry add -G dev python-lsp-pyre
2119
```
2220

23-
Then run `python-lsp-server` as usual, the plugin will be auto-discovered by
24-
`python-lsp-server` if you've installed it to the right environment. Refer to
25-
`python-lsp-server` and your IDE/text editor documentation on how to setup
26-
`python-lsp-server`. An example is provided for KDE's [Kate editor](/docs/kate.md).
21+
Then run `python-lsp-server` as usual, the plugin will be auto-discovered by `python-lsp-server` if you've installed it to the right environment. Refer to `python-lsp-server` and your IDE/text editor documentation on how to setup `python-lsp-server`. The plugin's default `enabled` status is `True`.
22+
23+
## Editor integration
24+
25+
* An example is provided for KDE's [Kate editor](/docs/kate.md)
2726

2827
## Configuration
2928

3029
Meta's Pyre uses `.pyre_configuration` files in your project to set up lint controls. It does not read `pyproject.toml`.
3130

32-
On first run of this plugin, it will detect a missing `.pyre_configuration`, and write out one for you. It relies on the workspace root passed to the language server for this write. This file is not immutable, and the [reference documentation](https://pyre-check.org/docs/configuration/) may be useful.
31+
On first run of this plugin, it will detect a missing `.pyre_configuration` and write out one for you if the `create-pyre-config` [configuration](docs/Configuration.md) option is enabled. It relies on the workspace root passed to the language server for this write. This file is not immutable, and the [reference documentation](https://pyre-check.org/docs/configuration/) may be useful.
3332

3433
You can also use `pyre init` instead to set up the configuration.
3534

@@ -50,9 +49,11 @@ The configuration written by this plugin is:
5049

5150
The noteable difference from `pyre init` is the change to the search strategy (pep561 to all).
5251

52+
If the file is not present, the LSP error log, LSP output, and your editor's LSP messages will display an ABEND message containing the error from Pyre as it fails to run.
53+
5354
## Features
5455

55-
This plugin adds the following features to `pylsp`:
56+
This plugin adds the following features to `python-lsp-server`:
5657

5758
- Type linting via Meta's Pyre (pyre-check)
5859

@@ -67,8 +68,17 @@ pip install -e '.[dev]'
6768
```
6869

6970
Alterately, if you use Poetry,
70-
```
71+
72+
```bash
73+
git clone https://github.com/cricalix/python-lsp-pyre python-lsp-pyre
74+
cd python-lsp-pyre
7175
poetry install
7276
```
7377

7478
will set up a virtualenv if necessary, install all dependencies, and then install this project in editable/development mode.
79+
80+
## Contributing
81+
82+
This plugin was written to scratch an itch. If you find it useful, great!
83+
84+
If something about it annoys you, or you think there's a better way to do something, you're welcome to send a PR.

docs/Configuration.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Configuration
2+
3+
Like other Python Language Server plugins, configuration of the plugin is achieved by sending settings to the server from the client via `workplace/didChangeConfiguration`.
4+
5+
This plugin recognises the following configuration options.
6+
7+
| Key | Type | Default | Purpose |
8+
| --- | --- | --- | --- |
9+
| `pylsp.plugins.pyre.enabled` | `boolean` | True | Enable or disable this plugin. |
10+
| `pylsp.plugins.pyre.create-pyre-config` | `boolean` | False | Whether to create a default .pyre_configuration file |
11+

docs/kate.md

+41-7
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,25 @@ In Settings > LSP Client > User Server Settings (normally found at `$USER/.confi
88

99
```json
1010
{
11-
"servers": {
12-
"python": {
13-
"command": ["poetry", "run", "pylsp", "--check-parent-process" ],
14-
"rootIndicationFileNames": ["poetry.lock", "pyproject.toml"],
15-
"url": "https://github.com/python-lsp/python-lsp-server",
16-
"highlightingModeRegex": "^Python$"
17-
}
11+
"servers": {
12+
"python": {
13+
"command": [
14+
"poetry",
15+
"run",
16+
"pylsp",
17+
"--check-parent-process",
18+
"--verbose",
19+
"--log-file",
20+
"/tmp/pylsp"
21+
],
22+
"rootIndicationFileNames": [
23+
"poetry.lock",
24+
"pyproject.toml"
25+
],
26+
"url": "https://github.com/python-lsp/python-lsp-server",
27+
"highlightingModeRegex": "^Python$"
1828
}
29+
}
1930
}
2031
```
2132

@@ -28,3 +39,26 @@ If you wish to have a log file then add `, "--log-file", "/tmp/pylsp"` after `--
2839
The Python Language Server documentation supercedes the above instructions.
2940

3041
The **rootIndicationFileNames** entry is used to ensure that the correct root directory is passed to the language server on requests for linting etcetera, assuming that the project has a **pyproject.toml** file.
42+
43+
To pass [configuration options](Configuration.md) to the server, use the `settings` sub-key, splitting out each component of the key on the dot to make it a JSON structure key.
44+
45+
For example, `pylsp.plugins.pyre.create-pyre-config` would be converted to:
46+
47+
```json
48+
{
49+
"servers": {
50+
"python": {
51+
"command": ["..."],
52+
"settings": {
53+
"pylsp": {
54+
"plugins": {
55+
"pyre": {
56+
"create-pyre-config": true
57+
}
58+
}
59+
}
60+
}
61+
}
62+
}
63+
}
64+
```

pylsp_pyre/plugin.py

+56-39
Original file line numberDiff line numberDiff line change
@@ -6,68 +6,44 @@
66

77
import lsprotocol.converters as lsp_con
88
import lsprotocol.types as lsp_types
9+
import pylsp.config.config as pylsp_conf
910
import pylsp.lsp as pylsp_lsp
1011
import pylsp.workspace as pylsp_ws
1112
import pyre_check.client.language_server.protocol as pyre_proto
1213
from pylsp import hookimpl
13-
from pylsp.config.config import Config
1414

1515
logger: logging.Logger = logging.getLogger(__name__)
16+
# A logging prefix.
17+
PLUGIN: str = "[python-lsp-pyre]"
1618

1719

1820
@hookimpl
19-
def pylsp_settings() -> Dict[str, Dict[str, Dict[str, bool]]]:
21+
def pylsp_settings(config: pylsp_conf.Config) -> Dict[str, Dict[str, Dict[str, bool]]]:
22+
"""
23+
Default configuration for the plugin. Ensures all keys are set.
24+
"""
2025
return {
2126
"plugins": {
2227
"pyre": {
2328
"enabled": True,
24-
"auto-config": True,
29+
"create-pyre-config": False,
2530
}
2631
}
2732
}
2833

2934

30-
@hookimpl
31-
def pylsp_initialize(config: Config, workspace: pylsp_ws.Workspace) -> None:
32-
"""
33-
Checks for a Pyre configuration existence.
34-
35-
Runs on plugin init, relies on the workspace document root to know where to look for
36-
the config file.
37-
"""
38-
default_config = json.loads(
39-
"""
40-
{
41-
"site_package_search_strategy": "all",
42-
"source_directories": [
43-
"."
44-
],
45-
"exclude": [
46-
"\/setup.py",
47-
".*\/build\/.*"
48-
]
49-
}
50-
"""
51-
)
52-
settings = config.plugin_settings("pyre")
53-
if settings["auto-config"]:
54-
docroot = workspace.root_path
55-
path = Path(docroot).joinpath(".pyre_configuration")
56-
if not path.exists():
57-
logger.info(f"Initializing {path}")
58-
with path.open(mode="w") as f:
59-
f.write(json.dumps(default_config, indent=4))
60-
f.write("\n")
61-
62-
6335
@hookimpl
6436
def pylsp_lint(
65-
config: Config, workspace: pylsp_ws.Workspace, document: pylsp_ws.Document, is_saved: bool
37+
config: pylsp_conf.Config,
38+
workspace: pylsp_ws.Workspace,
39+
document: pylsp_ws.Document,
40+
is_saved: bool,
6641
) -> List[Dict[str, Any]]:
6742
"""
6843
Lints files (saved, not in-progress) and returns found problems.
6944
"""
7045
logger.debug(f"Working with {document.path}, {is_saved=}")
46+
maybe_create_pyre_config(config=config, workspace=workspace)
7147
if is_saved:
7248
with workspace.report_progress("lint: pyre check", "running"):
7349
settings = config.plugin_settings("pyre")
@@ -86,8 +62,10 @@ def abend(message: str, workspace: pylsp_ws.Workspace) -> Dict[str, Any]:
8662
Basically, make it visible in as many ways as possible - logging, workspace messaging, and
8763
actual lint results.
8864
"""
89-
logger.exception(message)
90-
workspace.show_message(message=message, msg_type=pylsp_lsp.MessageType.Error)
65+
logger.exception(f"{PLUGIN} {message}")
66+
workspace.show_message(
67+
message=f"{PLUGIN} {message}", msg_type=pylsp_lsp.MessageType.Error
68+
)
9169
return {
9270
"source": "pyre",
9371
"severity": lsp_types.DiagnosticSeverity.Error,
@@ -156,3 +134,42 @@ def really_run_pyre(root_path: str) -> bytes:
156134
if e.returncode in (0, 1):
157135
return e.output
158136
raise
137+
138+
139+
def maybe_create_pyre_config(
140+
config: pylsp_conf.Config, workspace: pylsp_ws.Workspace
141+
) -> None:
142+
"""
143+
Initializes a .pyre_configuration file if `create-pyre-config` setting is enabled.
144+
145+
Only initializes if the file is missing.
146+
"""
147+
default_config = json.loads(
148+
"""
149+
{
150+
"site_package_search_strategy": "all",
151+
"source_directories": [
152+
"."
153+
],
154+
"exclude": [
155+
"\/setup.py",
156+
".*\/build\/.*"
157+
]
158+
}
159+
"""
160+
)
161+
settings = config.plugin_settings("pyre")
162+
try:
163+
if settings["create-pyre-config"]:
164+
docroot = workspace.root_path
165+
path = Path(docroot).joinpath(".pyre_configuration")
166+
if not path.exists():
167+
logger.info(f"Initializing {path}")
168+
with path.open(mode="w") as f:
169+
f.write(json.dumps(default_config, indent=4))
170+
f.write("\n")
171+
172+
except KeyError:
173+
message = f"{PLUGIN} create-pyre-config setting not found in dictionary"
174+
logger.exception(message)
175+
workspace.show_message(message=message, msg_type=pylsp_lsp.MessageType.Warning)

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "python-lsp-pyre"
3-
version = "0.1.1"
3+
version = "0.1.2"
44
description = "Pyre linting plugin for pylsp"
55
authors = ["Duncan Hill <python.projects@cricalix.net>"]
66
license = "MIT"

0 commit comments

Comments
 (0)