pax_global_header00006660000000000000000000000064140426115420014511gustar00rootroot0000000000000052 comment=0b998e260ad50d8580b3ea19b856298cec8d93a4 pyls-spyder-0.4.0/000077500000000000000000000000001404261154200140055ustar00rootroot00000000000000pyls-spyder-0.4.0/.github/000077500000000000000000000000001404261154200153455ustar00rootroot00000000000000pyls-spyder-0.4.0/.github/workflows/000077500000000000000000000000001404261154200174025ustar00rootroot00000000000000pyls-spyder-0.4.0/.github/workflows/linux-tests.yml000066400000000000000000000021741404261154200224300ustar00rootroot00000000000000name: PyLS-Spyder tests on: push: branches: - master pull_request: branches: - master jobs: linux: name: Linux Py${{ matrix.PYTHON_VERSION }} runs-on: ubuntu-latest env: PYTHON_VERSION: ${{ matrix.PYTHON_VERSION }} RUNNER_OS: "ubuntu" strategy: fail-fast: false matrix: PYTHON_VERSION: ["3.6", "3.7", "3.8"] steps: - name: Checkout branch/PR uses: actions/checkout@v1 - name: Install Conda uses: conda-incubator/setup-miniconda@v2 with: activate-environment: test auto-update-conda: true auto-activate-base: false python-version: ${{ matrix.PYTHON_VERSION }} - name: Install build/test dependencies shell: bash -l {0} run: pip install python-lsp-server[all] pytest pytest-cov coverage mock - name: Run tests shell: bash -l {0} run: pytest -v -x --cov=pyls_spyder pyls_spyder/tests pyls-spyder-0.4.0/.gitignore000066400000000000000000000034421404261154200160000ustar00rootroot00000000000000# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ pip-wheel-metadata/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 db.sqlite3-journal # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # IPython profile_default/ ipython_config.py # pyenv .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don't work, or not # install all needed dependencies. #Pipfile.lock # PEP 582; used by e.g. github.com/David-OConnor/pyflow __pypackages__/ # Celery stuff celerybeat-schedule celerybeat.pid # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ # VSCode settings .vscode/pyls-spyder-0.4.0/CHANGELOG.md000066400000000000000000000120631404261154200156200ustar00rootroot00000000000000## Version 0.4.0 (2021/04/29) ### Issues Closed * [Issue 26](https://github.com/spyder-ide/pyls-spyder/issues/26) - Release v0.4.0 * [Issue 24](https://github.com/spyder-ide/pyls-spyder/issues/24) - Update dependencies to use python-lsp-server instead of python-language-server ([PR 25](https://github.com/spyder-ide/pyls-spyder/pull/25) by [@andfoy](https://github.com/andfoy)) In this release 2 issues were closed. ### Pull Requests Merged * [PR 25](https://github.com/spyder-ide/pyls-spyder/pull/25) - PR: Use python-lsp-server instead of python-language-server, by [@andfoy](https://github.com/andfoy) ([24](https://github.com/spyder-ide/pyls-spyder/issues/24)) In this release 1 pull request was closed. ## Version 0.3.2 (2021-02-16) ### Issues Closed * [Issue 22](https://github.com/spyder-ide/pyls-spyder/issues/22) - Release v0.3.2 * [Issue 20](https://github.com/spyder-ide/pyls-spyder/issues/20) - Fix code blocks regular expression ([PR 21](https://github.com/spyder-ide/pyls-spyder/pull/21) by [@andfoy](https://github.com/andfoy)) In this release 2 issues were closed. ### Pull Requests Merged * [PR 21](https://github.com/spyder-ide/pyls-spyder/pull/21) - PR: Ensure that block comments start by 4 dashes or number signs, by [@andfoy](https://github.com/andfoy) ([20](https://github.com/spyder-ide/pyls-spyder/issues/20)) In this release 1 pull request was closed. ## Version 0.3.1 (2021-02-15) ### Issues Closed * [Issue 19](https://github.com/spyder-ide/pyls-spyder/issues/19) - Release v0.3.1 In this release 1 issue was closed. ### Pull Requests Merged * [PR 18](https://github.com/spyder-ide/pyls-spyder/pull/18) - PR: Fix code folding of cells, by [@remisalmon](https://github.com/remisalmon) ([14730](https://github.com/spyder-ide/spyder/issues/14730)) In this release 1 pull request was closed. ## Version 0.3.0 (2020/12/11) ### Issues Closed * [Issue 16](https://github.com/spyder-ide/pyls-spyder/issues/16) - Release v0.3.0 In this release 1 issue was closed. ### Pull Requests Merged * [PR 15](https://github.com/spyder-ide/pyls-spyder/pull/15) - PR: Add support for textDocument/foldingRange call for code cells, by [@andfoy](https://github.com/andfoy) ([7846](https://github.com/spyder-ide/spyder/issues/7846)) In this release 1 pull request was closed. ## Version 0.2.1 (2020/11/24) ### Issues Closed * [Issue 14](https://github.com/spyder-ide/pyls-spyder/issues/14) - Release v0.2.1 In this release 1 issue was closed. ### Pull Requests Merged * [PR 13](https://github.com/spyder-ide/pyls-spyder/pull/13) - PR: Pin minimum Python version to 3.6, by [@andfoy](https://github.com/andfoy) In this release 1 pull request was closed. ############################################################################### ## Version 0.2.0 (2020/11/23) ### Issues Closed * [Issue 12](https://github.com/spyder-ide/pyls-spyder/issues/12) - Release v0.2.0 * [Issue 9](https://github.com/spyder-ide/pyls-spyder/issues/9) - Some cell patterns are not detected in the Outline explorer ([PR 10](https://github.com/spyder-ide/pyls-spyder/pull/10) by [@andfoy](https://github.com/andfoy)) * [Issue 8](https://github.com/spyder-ide/pyls-spyder/issues/8) - Some issues with special comments in the outline explorer ([PR 10](https://github.com/spyder-ide/pyls-spyder/pull/10) by [@andfoy](https://github.com/andfoy)) In this release 3 issues were closed. ### Pull Requests Merged * [PR 11](https://github.com/spyder-ide/pyls-spyder/pull/11) - Remove dependency on separate mock package, by [@bnavigator](https://github.com/bnavigator) * [PR 10](https://github.com/spyder-ide/pyls-spyder/pull/10) - PR: Add additional cases for code cells and block comments, by [@andfoy](https://github.com/andfoy) ([9](https://github.com/spyder-ide/pyls-spyder/issues/9), [8](https://github.com/spyder-ide/pyls-spyder/issues/8)) In this release 2 pull requests were closed. ## Version 0.1.1 (2020/10/28) ### Issues Closed * [Issue 7](https://github.com/spyder-ide/pyls-spyder/issues/7) - Release v0.1.1 In this release 1 issue was closed. ### Pull Requests Merged * [PR 6](https://github.com/spyder-ide/pyls-spyder/pull/6) - PR: Add options to group cells and disable/enable block comments, by [@andfoy](https://github.com/andfoy) In this release 1 pull request was closed. ## Version 0.1.0 (2020/09/29) ### Issues Closed * [Issue 4](https://github.com/spyder-ide/pyls-spyder/issues/4) - Add RELEASE instructions ([PR 5](https://github.com/spyder-ide/pyls-spyder/pull/5) by [@andfoy](https://github.com/andfoy)) * [Issue 3](https://github.com/spyder-ide/pyls-spyder/issues/3) - Release v0.1.0 In this release 2 issues were closed. ### Pull Requests Merged * [PR 5](https://github.com/spyder-ide/pyls-spyder/pull/5) - PR: Add RELEASE instructions and update source distribution contents, by [@andfoy](https://github.com/andfoy) ([4](https://github.com/spyder-ide/pyls-spyder/issues/4)) * [PR 2](https://github.com/spyder-ide/pyls-spyder/pull/2) - PR: Parse cells and block comments and include them as part of textDocument/symbol call, by [@andfoy](https://github.com/andfoy) In this release 2 pull requests were closed. pyls-spyder-0.4.0/LICENSE000066400000000000000000000020531404261154200150120ustar00rootroot00000000000000MIT License Copyright (c) 2020 Spyder IDE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. pyls-spyder-0.4.0/MANIFEST.in000066400000000000000000000001171404261154200155420ustar00rootroot00000000000000include CHANGELOG.md include LICENSE include README.md prune pyls_spyder/tests pyls-spyder-0.4.0/README.md000066400000000000000000000071121404261154200152650ustar00rootroot00000000000000# pyls-spyder [![Project License - MIT](https://img.shields.io/pypi/l/pyls-spyder.svg)](https://raw.githubusercontent.com/spyder-ide/pyls-spyder/master/LICENSE) [![pypi version](https://img.shields.io/pypi/v/pyls-spyder.svg)](https://pypi.org/project/pyls-spyder/) [![conda version](https://img.shields.io/conda/vn/conda-forge/pyls-spyder.svg)](https://www.anaconda.com/download/) [![download count](https://img.shields.io/conda/dn/conda-forge/pyls-spyder.svg)](https://www.anaconda.com/download/) [![Downloads](https://pepy.tech/badge/pyls-spyder)](https://pepy.tech/project/pyls-spyder) [![PyPI status](https://img.shields.io/pypi/status/pyls-spyder.svg)](https://github.com/spyder-ide/pyls-spyder) ![PyLS-Spyder tests](https://github.com/spyder-ide/pyls-spyder/workflows/PyLS-Spyder%20tests/badge.svg) *Copyright © 2020– Spyder Project Contributors* ## Overview Spyder extensions for the [python-lsp-server](https://github.com/python-lsp/python-lsp-server) (pylsp). This package provides Spyder-specific extras for the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/specifications/specification-current/) (LSP) on Python, such as document symbol searching and others. ## Installing To install pyls-spyder, you can use both conda or pip package managers: ```bash # Using conda (Recommended) conda install pyls-spyder -c spyder-ide # Using pip pip install pyls-spyder ``` ## Dependencies This package depends on the [python-lsp-server](https://github.com/python-lsp/python-lsp-server) to integrate the Spyder-specific extensions. ## Installing locally To install and develop spyder-pyls locally, you will need to install the python-lsp-server: ```bash # Using conda conda install python-lsp-server # Using pip pip install python-lsp-server ``` Then, you can install the package locally using pip: ```bash pip install -U -e . ``` ## Running tests We use pytest to run tests as it follows: ```bash pytest -x -v pyls_spyder/tests ``` ## Extended LSP calls | LSP method | Spyder extensions | |:-----------------------------:|:------------------------------------------------:| | `textDocument/documentSymbol` | Find code cells `# %%` and block comments `# --` | | `textDocument/foldingRange` | Return code cells `# %%` as code folding regions | ## Plugin configuration options This plugin can be configured by using the key `pyls_spyder` when calling `workspace/didChangeConfiguration` on the pyls. Each configuration option is described below:
LSP method Configuration Key Type Description
textDocument/documentSymbol group_cells bool Enable/Disable code cell grouping according to the total number of leading percentages
enable_block_comments bool Enable/disable block comment detection
## Changelog Please see our [CHANGELOG](https://github.com/spyder-ide/pyls-spyder/blob/master/CHANGELOG.md) file to learn more about our new features and improvements. ## Contribution guidelines We follow PEP8 and PEP257 for all Python modules. We use MyPy type annotations for all functions and classes declared on this package. Feel free to send a PR or create an issue if you have any problem/question. pyls-spyder-0.4.0/RELEASE.md000066400000000000000000000012611404261154200154070ustar00rootroot00000000000000To release a new version of pyls-spyder: 1. git fetch upstream && git checkout upstream/master 2. Close milestone on GitHub 3. git clean -xfdi 4. Update CHANGELOG.md with loghub 5. git add -A && git commit -m "Update Changelog" 6. Update release version in ``__init__.py`` (set release version, remove 'dev0') 7. git add -A && git commit -m "Release vX.X.X" 8. python setup.py sdist 9. python setup.py bdist_wheel --universal 10. twine check 11. twine upload 12. git tag -a vX.X.X -m "Release vX.X.X" 13. Update development version in ``__init__.py`` (add 'dev0' and increment minor) 14. git add -A && git commit -m "Back to work" 15. git push upstream master 16. git push upstream --tags pyls-spyder-0.4.0/pyls_spyder/000077500000000000000000000000001404261154200163625ustar00rootroot00000000000000pyls-spyder-0.4.0/pyls_spyder/__init__.py000066400000000000000000000006641404261154200205010ustar00rootroot00000000000000# -*- coding: utf-8 -*- # ---------------------------------------------------------------------------- # Copyright (c) Spyder Project Contributors # # Licensed under the terms of the MIT License # (see LICENSE.txt for details) # ---------------------------------------------------------------------------- """Spyder extensions for the python-language-server.""" VERSION_INFO = (0, 4, 0) __version__ = '.'.join(map(str, VERSION_INFO)) pyls-spyder-0.4.0/pyls_spyder/plugin.py000066400000000000000000000144351404261154200202410ustar00rootroot00000000000000# -*- coding: utf-8 -*- # ---------------------------------------------------------------------------- # Copyright (c) Spyder Project Contributors # # Licensed under the terms of the MIT License # (see LICENSE.txt for details) # ---------------------------------------------------------------------------- """pyls-spyder main plugin.""" # Standard library imports import re from typing import List, Dict, Tuple # PyLS imports from pylsp import hookimpl from pylsp.config.config import Config from pylsp.workspace import Workspace, Document # Local imports from pyls_spyder.utils import RegexEvaluator # Code cell regular expressions # 1. Cells declared with percentages, i.e., # %% Cell CELL_PERCENTAGE, CELL_PERCENTAGE_REGEX = ( 'CELL_PERCENTAGE', re.compile(r'^[\t ]*# ?(%%+)(.*)?$')) # 2. Cells declared with "", i.e., # CELL_CODECELL, CELL_CODECELL_REGEX = ( 'CELL_CODECELL', re.compile(r'^[\t ]*# ?()(.*)?$')) # 3. Cells declared with "In[.*], i.e., # In[23]" CELL_IN, CELL_IN_REGEX = ( 'CELL_IN', re.compile(r'^[\t ]*# ?(In\[)([^\]\r\n]*)?\]?$')) CELL_REGEX = RegexEvaluator({ CELL_PERCENTAGE: CELL_PERCENTAGE_REGEX, CELL_CODECELL: CELL_CODECELL_REGEX, CELL_IN: CELL_IN_REGEX }) # Block comment regular expressions # 1. Block comments declared with 4 dashes, i.e., # ---- Block comment BLOCK_DASH = ( 'BLOCK_DASH', re.compile(r'^[\t ]*# ?-{4}([^-\n\r].*)?$')) # 2. Block comments declared with 3 consecutive hashes, i.e., #### Comment BLOCK_HASH = ( 'BLOCK_HASH', re.compile(r'^[\t ]*##{3}([^\#\n\r].*)?$')) BLOCK_REGEX = RegexEvaluator(dict([BLOCK_DASH, BLOCK_HASH])) def peek_symbol(list: List) -> Tuple: if len(list) > 0: return list[0] else: return None, 0, '' def create_symbol(name: str, document: Document, start_line: int, end_line: int, cell=True) -> Dict: kind = 225 if cell else 224 return { 'name': name, 'containerName': '', 'location': { 'uri': document.uri, 'range': { 'start': { 'line': start_line, 'character': 0 }, 'end': { 'line': max(end_line - 1, 0), 'character': 0 } } }, 'kind': kind } def create_fold_region(start_line: int, end_line: int): return { 'startLine': start_line, 'endLine': end_line, } @hookimpl def pylsp_document_symbols(config: Config, workspace: Workspace, document: Document) -> List[Dict]: """Cell and block comment extraction.""" settings = config.plugin_settings('pyls_spyder') group_cells = settings.get('group_cells', True) enable_block_comments = settings.get('enable_block_comments', True) lines = document.lines cells = [] blocks = [] cell_stack = [] unnamed_cell = 1 unnamed_block = 1 for line_num, line in enumerate(lines): cell_rule, cell_match = CELL_REGEX.match(line) block_rule, block_match = BLOCK_REGEX.match(line) if cell_match is not None: percentages = cell_match.group(1) cell_name = cell_match.group(2).strip() if cell_name == '': cell_name = 'Unnamed cell {0}'.format(unnamed_cell) unnamed_cell += 1 if not group_cells or cell_rule != CELL_PERCENTAGE: cells.append(create_symbol( cell_name, document, line_num, line_num + 1)) else: current_line, current_level, current_name = peek_symbol( cell_stack) cell_level = len(percentages) - 1 if cell_level > current_level: cell_stack.insert(0, (line_num, cell_level, cell_name)) else: while current_level >= cell_level: cell_stack.pop(0) cells.append(create_symbol( current_name, document, current_line, line_num)) (current_line, current_level, current_name) = peek_symbol(cell_stack) cell_stack.insert(0, (line_num, cell_level, cell_name)) elif block_match is not None and enable_block_comments: block_name = block_match.group(1) if block_name is None: block_name = '' else: block_name = block_name.strip() if block_name == '': block_name = 'Unnamed comment {0}'.format(unnamed_block) unnamed_block += 1 blocks.append(create_symbol( block_name, document, line_num, line_num + 1, False)) for line, _, name in cell_stack: cells.append(create_symbol(name, document, line, line_num + 1)) spyder_symbols = cells + blocks spyder_symbols = sorted( spyder_symbols, key=lambda x: x['location']['range']['start']['line']) return spyder_symbols @hookimpl def pylsp_folding_range( config: Config, workspace: Workspace, document: Document) -> List[Dict]: lines = document.lines cell_stack = [] cells = [] for line_num, line in enumerate(lines): cell_rule, cell_match = CELL_REGEX.match(line) if cell_match is not None: percentages = cell_match.group(1) current_line, current_level, _ = peek_symbol(cell_stack) if cell_rule != CELL_PERCENTAGE: cell_level = current_level + 1 else: cell_level = len(percentages) - 1 if cell_level > current_level: cell_stack.insert(0, (line_num, cell_level, '')) else: while current_level >= cell_level: cell_stack.pop(0) cells.append(create_fold_region(current_line, line_num - 1)) current_line, current_level, _ = peek_symbol(cell_stack) cell_stack.insert(0, (line_num, cell_level, '')) for line, _, name in cell_stack: cells.append(create_fold_region(line, line_num)) cells = sorted(cells, key=lambda x: x['startLine']) return cells pyls-spyder-0.4.0/pyls_spyder/tests/000077500000000000000000000000001404261154200175245ustar00rootroot00000000000000pyls-spyder-0.4.0/pyls_spyder/tests/__init__.py000066400000000000000000000000001404261154200216230ustar00rootroot00000000000000pyls-spyder-0.4.0/pyls_spyder/tests/test_plugin.py000066400000000000000000000112371404261154200224370ustar00rootroot00000000000000# -*- coding: utf-8 -*- # ---------------------------------------------------------------------------- # Copyright (c) Spyder Project Contributors # # Licensed under the terms of the MIT License # (see LICENSE.txt for details) # ---------------------------------------------------------------------------- """pyls-spyder plugin tests.""" # PyLS imports from pylsp import uris from pylsp.workspace import Document # pytest imports import pytest from unittest.mock import MagicMock # Local imports from pyls_spyder.plugin import pylsp_document_symbols, pylsp_folding_range DOC_URI = uris.from_fs_path(__file__) DOC = """ # %% # ---- Imports import os import sys # Other cell # ---- def a(): #### Block comment on a # %%% Cell inside a for i in range(0, 10): # %%%% Cell pass # %%% def b(): #---- Pass inside b pass # In[25] #### #%% Invalid comments #---- # ---------- This should not work ###### This either #%% Empty cell """ @pytest.fixture def workspace(): return MagicMock() @pytest.fixture def config(): return MagicMock() def test_cell_block_symbols(config, workspace): document = Document(DOC_URI, workspace, DOC) symbols = pylsp_document_symbols(config, workspace, document) expected = [ ('Unnamed cell 1', 1, 22, 225), ('Imports', 2, 2, 224), ('Other cell', 6, 6, 225), ('Unnamed comment 1', 7, 7, 224), ('Block comment on a', 9, 9, 224), ('Cell inside a', 10, 14, 225), ('Cell', 12, 14, 225), ('Unnamed cell 2', 15, 22, 225), ('Pass inside b', 17, 17, 224), ('25', 20, 20, 225), ('Unnamed comment 2', 21, 21, 224), ('Invalid comments', 23, 26, 225), ('Unnamed comment 3', 24, 24, 224), ('Empty cell', 27, 27, 225) ] test_results = [] for symbol in symbols: name = symbol['name'] location = symbol['location'] sym_range = location['range'] start = sym_range['start']['line'] end = sym_range['end']['line'] kind = symbol['kind'] test_results.append((name, start, end, kind)) assert expected == test_results def test_ungroup_cell_symbols(config, workspace): document = Document(DOC_URI, workspace, DOC) config.plugin_settings = lambda _: {'group_cells': False} symbols = pylsp_document_symbols(config, workspace, document) expected = [ ('Unnamed cell 1', 1, 1, 225), ('Imports', 2, 2, 224), ('Other cell', 6, 6, 225), ('Unnamed comment 1', 7, 7, 224), ('Block comment on a', 9, 9, 224), ('Cell inside a', 10, 10, 225), ('Cell', 12, 12, 225), ('Unnamed cell 2', 15, 15, 225), ('Pass inside b', 17, 17, 224), ('25', 20, 20, 225), ('Unnamed comment 2', 21, 21, 224), ('Invalid comments', 23, 23, 225), ('Unnamed comment 3', 24, 24, 224), ('Empty cell', 27, 27, 225) ] test_results = [] for symbol in symbols: name = symbol['name'] location = symbol['location'] sym_range = location['range'] start = sym_range['start']['line'] end = sym_range['end']['line'] kind = symbol['kind'] test_results.append((name, start, end, kind)) assert expected == test_results def test_disable_block_comments(config, workspace): document = Document(DOC_URI, workspace, DOC) config.plugin_settings = lambda _: {'enable_block_comments': False} symbols = pylsp_document_symbols(config, workspace, document) expected = [ ('Unnamed cell 1', 1, 22, 225), ('Other cell', 6, 6, 225), ('Cell inside a', 10, 14, 225), ('Cell', 12, 14, 225), ('Unnamed cell 2', 15, 22, 225), ('25', 20, 20, 225), ('Invalid comments', 23, 26, 225), ('Empty cell', 27, 27, 225) ] test_results = [] for symbol in symbols: name = symbol['name'] location = symbol['location'] sym_range = location['range'] start = sym_range['start']['line'] end = sym_range['end']['line'] kind = symbol['kind'] test_results.append((name, start, end, kind)) assert expected == test_results def test_cell_folding_regions(config, workspace): document = Document(DOC_URI, workspace, DOC) regions = pylsp_folding_range(config, workspace, document) expected = [ (1, 22), (6, 9), (10, 14), (12, 14), (15, 22), (20, 22), (23, 26), (27, 27) ] test_results = [] for region in regions: start = region['startLine'] end = region['endLine'] test_results.append((start, end)) assert expected == test_results pyls-spyder-0.4.0/pyls_spyder/utils.py000066400000000000000000000027441404261154200201030ustar00rootroot00000000000000# -*- coding: utf-8 -*- # ---------------------------------------------------------------------------- # Copyright (c) Spyder Project Contributors # # Licensed under the terms of the MIT License # (see LICENSE.txt for details) # ---------------------------------------------------------------------------- """pyls-spyder misc utillites.""" # Standard library imports from typing import Tuple, Dict class RegexEvaluator: """Wrapper class around multiple regular expressions.""" def __init__(self, regex_map: Dict): self.regexes = regex_map def match(self, string: str) -> Tuple: """ Match a string `string` against a set of regular expressions. The regular expressions are applied in a short-circuit fashion. Parameters ---------- string: str Input string to match regexes against. Returns ------- output: Tuple[Optional[str], Optional[re.Match]] A tuple containing the regex identifier that first matched the input, alongside the corresponding regex match object. If no regex did matched the input, then a tuple containing `None` is returned. """ re_match = None re_rule = None for regex_name in self.regexes: regex = self.regexes[regex_name] re_match = regex.match(string) if re_match is not None: re_rule = regex_name break return re_rule, re_match pyls-spyder-0.4.0/setup.cfg000066400000000000000000000003111404261154200156210ustar00rootroot00000000000000[check-manifest] ignore = .checkignore .github .github/* .github/workflows/* .codecov.yml .coveragerc .coverage RELEASE.md doc doc/* ignore-bad-ideas = *.mo pyls-spyder-0.4.0/setup.py000066400000000000000000000044201404261154200155170ustar00rootroot00000000000000# -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright © Spyder Project Contributors # # Licensed under the terms of the MIT License # (see LICENSE.txt for details) # ----------------------------------------------------------------------------- """Setup script for pyls_spyder.""" # Standard library imports import ast import os import os.path as osp # Third party imports from setuptools import find_packages, setup HERE = osp.dirname(osp.abspath(__file__)) def get_version(module='pyls_spyder'): """Get version.""" with open(os.path.join(HERE, module, '__init__.py'), 'r') as f: data = f.read() lines = data.split('\n') for line in lines: if line.startswith('VERSION_INFO'): version_tuple = ast.literal_eval(line.split('=')[-1].strip()) version = '.'.join(map(str, version_tuple)) break return version def get_description(): """Get long description.""" with open(os.path.join(HERE, 'README.md'), 'r') as f: data = f.read() return data REQUIREMENTS = ['python-lsp-server >= 1.0.1'] setup( name='pyls-spyder', version=get_version(), keywords=['PyLSP', 'Plugin'], url='https://github.com/spyder-ide/pyls-spyder', license='MIT', author='Spyder Project Contributors', author_email='spyder.python@gmail.com', description='Spyder extensions for the python-lsp-server', long_description=get_description(), long_description_content_type='text/markdown', packages=find_packages(exclude=['contrib', 'docs', 'tests*']), python_requires='>= 3.6', install_requires=REQUIREMENTS, include_package_data=True, entry_points={"pylsp": ["pyls_spyder = pyls_spyder.plugin"]}, classifiers=[ 'Development Status :: 4 - Beta', 'Intended Audience :: Developers', 'Intended Audience :: Science/Research', 'License :: OSI Approved :: MIT License', 'Operating System :: MacOS', 'Operating System :: Microsoft :: Windows', 'Operating System :: POSIX :: Linux', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', ])