Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-python-lsp-server for openSUSE:Factory checked in at 2021-11-27 00:51:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-python-lsp-server (Old) and /work/SRC/openSUSE:Factory/.python-python-lsp-server.new.1895 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-python-lsp-server" Sat Nov 27 00:51:46 2021 rev:8 rq:934152 version:1.3.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-python-lsp-server/python-python-lsp-server.changes 2021-11-20 22:48:30.583766893 +0100 +++ /work/SRC/openSUSE:Factory/.python-python-lsp-server.new.1895/python-python-lsp-server.changes 2021-11-27 00:52:41.926517340 +0100 @@ -1,0 +2,15 @@ +Fri Nov 26 18:40:47 UTC 2021 - Ben Greiner <c...@bnavigator.de> + +- Update to 1.3.1 + * Fix tests for Jedi 0.18.1 + * Option `jedi_completion.resolve_at_most_labels` was renamed to + `jedi_completion.resolve_at_most` because now it controls how + many labels and snippets will be resolved per request. + * Option `jedi_completion.cache_labels_for` was renamed to + `jedi_completion.cache_for` because now it controls the modules + for which labels and snippets should be cached. + * Update requirements on Pylint, flake8, pycodestyle, pyflakes + and autopep8. +- Drop python-lsp-server-pr102-unpin-flake8.patch + +------------------------------------------------------------------- Old: ---- python-lsp-server-1.2.4.tar.gz python-lsp-server-pr102-unpin-flake8.patch New: ---- python-lsp-server-1.3.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-python-lsp-server.spec ++++++ --- /var/tmp/diff_new_pack.cTYq1i/_old 2021-11-27 00:52:42.370515807 +0100 +++ /var/tmp/diff_new_pack.cTYq1i/_new 2021-11-27 00:52:42.370515807 +0100 @@ -19,14 +19,12 @@ %{?!python_module:%define python_module() python3-%{**}} %define skip_python2 1 Name: python-python-lsp-server -Version: 1.2.4 +Version: 1.3.1 Release: 0 Summary: Python Language Server for the Language Server Protocol License: MIT URL: https://github.com/python-lsp/python-lsp-server Source: https://files.pythonhosted.org/packages/source/p/python-lsp-server/python-lsp-server-%{version}.tar.gz -# PATCH-FIX-UPSTREAM python-lsp-server-pr102-unpin-flake8.patch -- gh#python-lsp/python-lsp-server#102 -Patch0: python-lsp-server-pr102-unpin-flake8.patch BuildRequires: %{python_module setuptools >= 39.0.0} BuildRequires: python-rpm-macros >= 20210628 # SECTION test requirements @@ -57,11 +55,15 @@ Requires: python-setuptools >= 39.0.0 Requires: python-ujson >= 3.0.0 Suggests: python-autopep8 >= 1.6.0 +Conflicts: python-autopep8 >= 1.7.0 Suggests: python-flake8 >= 4.0.0 +Conflicts: python-flake8 >= 4.1.0 Suggests: python-mccabe >= 0.6.0 Suggests: python-pycodestyle >= 2.8.0 +Conflicts: python-pycodestyle >= 2.9.0 Suggests: python-pydocstyle >= 2.0.0 Suggests: python-pyflakes >= 2.4.0 +Conflicts: python-pyflakes >= 2.5.0 Suggests: python-pylint >= 2.5.0 Suggests: python-rope >= 0.10.5 Suggests: python-yapf @@ -89,9 +91,6 @@ %prep %autosetup -p1 -n python-lsp-server-%{version} -# the only relevant changes from https://github.com/python-lsp/python-lsp-server/pull/94 -sed -i 's/pylint>=2.5.0,<2.10.0/pylint>=2.5.0/' setup.py -sed -i "s/open(document.path, 'w')/open(document.path, 'w', encoding='utf-8')/" test/plugins/test_pylint_lint.py %build %python_build ++++++ python-lsp-server-1.2.4.tar.gz -> python-lsp-server-1.3.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/.pylintrc new/python-lsp-server-1.3.1/.pylintrc --- old/python-lsp-server-1.2.4/.pylintrc 2021-04-14 23:02:42.000000000 +0200 +++ new/python-lsp-server-1.3.1/.pylintrc 2021-10-30 19:18:46.000000000 +0200 @@ -16,7 +16,8 @@ too-few-public-methods, too-many-arguments, too-many-instance-attributes, - import-error + import-error, + consider-using-f-string, [REPORTS] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/PKG-INFO new/python-lsp-server-1.3.1/PKG-INFO --- old/python-lsp-server-1.2.4/PKG-INFO 2021-10-11 18:12:19.847948300 +0200 +++ new/python-lsp-server-1.3.1/PKG-INFO 2021-11-22 18:31:07.002516300 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: python-lsp-server -Version: 1.2.4 +Version: 1.3.1 Summary: Python Language Server for the Language Server Protocol Home-page: https://github.com/python-lsp/python-lsp-server Author: Python Language Server Contributors @@ -67,7 +67,7 @@ Installing these plugins will add extra functionality to the language server: - [pyls-flake8](https://github.com/emanspeaks/pyls-flake8/): Error checking using [flake8](https://flake8.pycqa.org/en/latest/). -- [mypy-ls](https://github.com/Richardk2n/mypy-ls): [MyPy](http://mypy-lang.org/) type checking for Python 3. +- [pylsp-mypy](https://github.com/Richardk2n/pylsp-mypy): [MyPy](http://mypy-lang.org/) type checking for Python >=3.6. - [pyls-isort](https://github.com/paradoxxxzero/pyls-isort): code formatting using [isort](https://github.com/PyCQA/isort) (automatic import sorting). - [python-lsp-black](https://github.com/python-lsp/python-lsp-black): code formatting using [Black](https://github.com/psf/black). - [pyls-memestra](https://github.com/QuantStack/pyls-memestra): detecting the use of deprecated APIs. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/README.md new/python-lsp-server-1.3.1/README.md --- old/python-lsp-server-1.2.4/README.md 2021-10-04 18:16:59.000000000 +0200 +++ new/python-lsp-server-1.3.1/README.md 2021-10-30 19:18:46.000000000 +0200 @@ -44,7 +44,7 @@ Installing these plugins will add extra functionality to the language server: - [pyls-flake8](https://github.com/emanspeaks/pyls-flake8/): Error checking using [flake8](https://flake8.pycqa.org/en/latest/). -- [mypy-ls](https://github.com/Richardk2n/mypy-ls): [MyPy](http://mypy-lang.org/) type checking for Python 3. +- [pylsp-mypy](https://github.com/Richardk2n/pylsp-mypy): [MyPy](http://mypy-lang.org/) type checking for Python >=3.6. - [pyls-isort](https://github.com/paradoxxxzero/pyls-isort): code formatting using [isort](https://github.com/PyCQA/isort) (automatic import sorting). - [python-lsp-black](https://github.com/python-lsp/python-lsp-black): code formatting using [Black](https://github.com/psf/black). - [pyls-memestra](https://github.com/QuantStack/pyls-memestra): detecting the use of deprecated APIs. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/pylsp/__main__.py new/python-lsp-server-1.3.1/pylsp/__main__.py --- old/python-lsp-server-1.2.4/pylsp/__main__.py 2021-06-25 23:38:40.000000000 +0200 +++ new/python-lsp-server-1.3.1/pylsp/__main__.py 2021-10-30 19:18:46.000000000 +0200 @@ -92,7 +92,7 @@ root_logger = logging.root if log_config: - with open(log_config, 'r') as f: + with open(log_config, 'r', encoding='utf-8') as f: logging.config.dictConfig(json.load(f)) else: formatter = logging.Formatter(LOG_FORMAT) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/pylsp/_utils.py new/python-lsp-server-1.3.1/pylsp/_utils.py --- old/python-lsp-server-1.2.4/pylsp/_utils.py 2021-06-25 23:26:52.000000000 +0200 +++ new/python-lsp-server-1.3.1/pylsp/_utils.py 2021-10-30 19:18:46.000000000 +0200 @@ -144,8 +144,8 @@ Until we can find a fast enough way of discovering and parsing each format, we can do a little better by at least preserving indentation. """ - contents = contents.replace('\t', u'\u00A0' * 4) - contents = contents.replace(' ', u'\u00A0' * 2) + contents = contents.replace('\t', '\u00A0' * 4) + contents = contents.replace(' ', '\u00A0' * 2) return contents diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/pylsp/_version.py new/python-lsp-server-1.3.1/pylsp/_version.py --- old/python-lsp-server-1.2.4/pylsp/_version.py 2021-10-11 18:11:38.000000000 +0200 +++ new/python-lsp-server-1.3.1/pylsp/_version.py 2021-11-22 18:30:34.000000000 +0100 @@ -3,6 +3,5 @@ """PyLSP versioning information.""" - -VERSION_INFO = (1, 2, 4) +VERSION_INFO = (1, 3, 1) __version__ = '.'.join(map(str, VERSION_INFO)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/pylsp/plugins/_resolvers.py new/python-lsp-server-1.3.1/pylsp/plugins/_resolvers.py --- old/python-lsp-server-1.2.4/pylsp/plugins/_resolvers.py 1970-01-01 01:00:00.000000000 +0100 +++ new/python-lsp-server-1.3.1/pylsp/plugins/_resolvers.py 2021-11-15 18:31:52.000000000 +0100 @@ -0,0 +1,135 @@ +# Copyright 2017-2020 Palantir Technologies, Inc. +# Copyright 2021- Python Language Server Contributors. + +from collections import defaultdict +import logging +from time import time + +from jedi.api.classes import Completion + +from pylsp import lsp + + +log = logging.getLogger(__name__) + + +# ---- Base class +# ----------------------------------------------------------------------------- +class Resolver: + + def __init__(self, callback, resolve_on_error, time_to_live=60 * 30): + self.callback = callback + self.resolve_on_error = resolve_on_error + self._cache = {} + self._time_to_live = time_to_live + self._cache_ttl = defaultdict(set) + self._clear_every = 2 + # see https://github.com/davidhalter/jedi/blob/master/jedi/inference/helpers.py#L194-L202 + self._cached_modules = {'pandas', 'numpy', 'tensorflow', 'matplotlib'} + + @property + def cached_modules(self): + return self._cached_modules + + @cached_modules.setter + def cached_modules(self, new_value): + self._cached_modules = set(new_value) + + def clear_outdated(self): + now = self.time_key() + to_clear = [ + timestamp + for timestamp in self._cache_ttl + if timestamp < now + ] + for time_key in to_clear: + for key in self._cache_ttl[time_key]: + del self._cache[key] + del self._cache_ttl[time_key] + + def time_key(self): + return int(time() / self._time_to_live) + + def get_or_create(self, completion: Completion): + if not completion.full_name: + use_cache = False + else: + module_parts = completion.full_name.split('.') + use_cache = module_parts and module_parts[0] in self._cached_modules + + if use_cache: + key = self._create_completion_id(completion) + if key not in self._cache: + if self.time_key() % self._clear_every == 0: + self.clear_outdated() + + self._cache[key] = self.resolve(completion) + self._cache_ttl[self.time_key()].add(key) + return self._cache[key] + + return self.resolve(completion) + + def _create_completion_id(self, completion: Completion): + return ( + completion.full_name, completion.module_path, + completion.line, completion.column, + self.time_key() + ) + + def resolve(self, completion): + try: + sig = completion.get_signatures() + return self.callback(completion, sig) + except Exception as e: # pylint: disable=broad-except + log.warning( + 'Something went wrong when resolving label for {completion}: {e}', + completion=completion, e=e + ) + return self.resolve_on_error + + +# ---- Label resolver +# ----------------------------------------------------------------------------- +def format_label(completion, sig): + if sig and completion.type in ('function', 'method'): + params = ', '.join(param.name for param in sig[0].params) + label = '{}({})'.format(completion.name, params) + return label + return completion.name + + +LABEL_RESOLVER = Resolver(callback=format_label, resolve_on_error='') + + +# ---- Snippets resolver +# ----------------------------------------------------------------------------- +def format_snippet(completion, sig): + if not sig: + return {} + + snippet_completion = {} + + positional_args = [param for param in sig[0].params + if '=' not in param.description and + param.name not in {'/', '*'}] + + if len(positional_args) > 1: + # For completions with params, we can generate a snippet instead + snippet_completion['insertTextFormat'] = lsp.InsertTextFormat.Snippet + snippet = completion.name + '(' + for i, param in enumerate(positional_args): + snippet += '${%s:%s}' % (i + 1, param.name) + if i < len(positional_args) - 1: + snippet += ', ' + snippet += ')$0' + snippet_completion['insertText'] = snippet + elif len(positional_args) == 1: + snippet_completion['insertTextFormat'] = lsp.InsertTextFormat.Snippet + snippet_completion['insertText'] = completion.name + '($0)' + else: + snippet_completion['insertText'] = completion.name + '()' + + return snippet_completion + + +SNIPPET_RESOLVER = Resolver(callback=format_snippet, resolve_on_error={}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/pylsp/plugins/flake8_lint.py new/python-lsp-server-1.3.1/pylsp/plugins/flake8_lint.py --- old/python-lsp-server-1.2.4/pylsp/plugins/flake8_lint.py 2021-06-25 23:26:52.000000000 +0200 +++ new/python-lsp-server-1.3.1/pylsp/plugins/flake8_lint.py 2021-11-15 18:31:52.000000000 +0100 @@ -5,6 +5,7 @@ import logging import os.path import re +import sys from pathlib import PurePath from subprocess import PIPE, Popen @@ -79,10 +80,10 @@ try: cmd = [flake8_executable] cmd.extend(args) - p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) # pylint: disable=consider-using-with + p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) except IOError: - log.debug("Can't execute %s. Trying with 'python -m flake8'", flake8_executable) - cmd = ['python', '-m', 'flake8'] + log.debug("Can't execute %s. Trying with '%s -m flake8'", flake8_executable, sys.executable) + cmd = [sys.executable, '-m', 'flake8'] cmd.extend(args) p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) # pylint: disable=consider-using-with (stdout, stderr) = p.communicate(document.source.encode()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/pylsp/plugins/jedi_completion.py new/python-lsp-server-1.3.1/pylsp/plugins/jedi_completion.py --- old/python-lsp-server-1.2.4/pylsp/plugins/jedi_completion.py 2021-10-04 18:16:44.000000000 +0200 +++ new/python-lsp-server-1.3.1/pylsp/plugins/jedi_completion.py 2021-11-15 18:31:52.000000000 +0100 @@ -3,13 +3,11 @@ import logging import os.path as osp -from collections import defaultdict -from time import time -from jedi.api.classes import Completion import parso from pylsp import _utils, hookimpl, lsp +from pylsp.plugins._resolvers import LABEL_RESOLVER, SNIPPET_RESOLVER log = logging.getLogger(__name__) @@ -57,10 +55,11 @@ should_include_params = settings.get('include_params') should_include_class_objects = settings.get('include_class_objects', True) - max_labels_resolve = settings.get('resolve_at_most_labels', 25) - modules_to_cache_labels_for = settings.get('cache_labels_for', None) - if modules_to_cache_labels_for is not None: - LABEL_RESOLVER.cached_modules = modules_to_cache_labels_for + max_to_resolve = settings.get('resolve_at_most', 25) + modules_to_cache_for = settings.get('cache_for', None) + if modules_to_cache_for is not None: + LABEL_RESOLVER.cached_modules = modules_to_cache_for + SNIPPET_RESOLVER.cached_modules = modules_to_cache_for include_params = snippet_support and should_include_params and use_snippets(document, position) include_class_objects = snippet_support and should_include_class_objects and use_snippets(document, position) @@ -70,7 +69,7 @@ c, include_params, resolve=resolve_eagerly, - resolve_label=(i < max_labels_resolve) + resolve_label_or_snippet=(i < max_to_resolve) ) for i, c in enumerate(completions) ] @@ -83,7 +82,7 @@ c, False, resolve=resolve_eagerly, - resolve_label=(i < max_labels_resolve) + resolve_label_or_snippet=(i < max_to_resolve) ) completion_dict['kind'] = lsp.CompletionItemKind.TypeParameter completion_dict['label'] += ' object' @@ -175,9 +174,9 @@ return completion -def _format_completion(d, include_params=True, resolve=False, resolve_label=False): +def _format_completion(d, include_params=True, resolve=False, resolve_label_or_snippet=False): completion = { - 'label': _label(d, resolve_label), + 'label': _label(d, resolve_label_or_snippet), 'kind': _TYPE_MAP.get(d.type), 'sortText': _sort_text(d), 'insertText': d.name @@ -193,29 +192,8 @@ completion['insertText'] = path if include_params and not is_exception_class(d.name): - sig = d.get_signatures() - if not sig: - return completion - - positional_args = [param for param in sig[0].params - if '=' not in param.description and - param.name not in {'/', '*'}] - - if len(positional_args) > 1: - # For completions with params, we can generate a snippet instead - completion['insertTextFormat'] = lsp.InsertTextFormat.Snippet - snippet = d.name + '(' - for i, param in enumerate(positional_args): - snippet += '${%s:%s}' % (i + 1, param.name) - if i < len(positional_args) - 1: - snippet += ', ' - snippet += ')$0' - completion['insertText'] = snippet - elif len(positional_args) == 1: - completion['insertTextFormat'] = lsp.InsertTextFormat.Snippet - completion['insertText'] = d.name + '($0)' - else: - completion['insertText'] = d.name + '()' + snippet = _snippet(d, resolve_label_or_snippet) + completion.update(snippet) return completion @@ -229,6 +207,13 @@ return definition.name +def _snippet(definition, resolve=False): + if not resolve: + return {} + snippet = SNIPPET_RESOLVER.get_or_create(definition) + return snippet + + def _detail(definition): try: return definition.parent().full_name or '' @@ -244,86 +229,3 @@ # If its 'hidden', put it next last prefix = 'z{}' if definition.name.startswith('_') else 'a{}' return prefix.format(definition.name) - - -class LabelResolver: - - def __init__(self, format_label_callback, time_to_live=60 * 30): - self.format_label = format_label_callback - self._cache = {} - self._time_to_live = time_to_live - self._cache_ttl = defaultdict(set) - self._clear_every = 2 - # see https://github.com/davidhalter/jedi/blob/master/jedi/inference/helpers.py#L194-L202 - self._cached_modules = {'pandas', 'numpy', 'tensorflow', 'matplotlib'} - - @property - def cached_modules(self): - return self._cached_modules - - @cached_modules.setter - def cached_modules(self, new_value): - self._cached_modules = set(new_value) - - def clear_outdated(self): - now = self.time_key() - to_clear = [ - timestamp - for timestamp in self._cache_ttl - if timestamp < now - ] - for time_key in to_clear: - for key in self._cache_ttl[time_key]: - del self._cache[key] - del self._cache_ttl[time_key] - - def time_key(self): - return int(time() / self._time_to_live) - - def get_or_create(self, completion: Completion): - if not completion.full_name: - use_cache = False - else: - module_parts = completion.full_name.split('.') - use_cache = module_parts and module_parts[0] in self._cached_modules - - if use_cache: - key = self._create_completion_id(completion) - if key not in self._cache: - if self.time_key() % self._clear_every == 0: - self.clear_outdated() - - self._cache[key] = self.resolve_label(completion) - self._cache_ttl[self.time_key()].add(key) - return self._cache[key] - - return self.resolve_label(completion) - - def _create_completion_id(self, completion: Completion): - return ( - completion.full_name, completion.module_path, - completion.line, completion.column, - self.time_key() - ) - - def resolve_label(self, completion): - try: - sig = completion.get_signatures() - return self.format_label(completion, sig) - except Exception as e: # pylint: disable=broad-except - log.warning( - 'Something went wrong when resolving label for {completion}: {e}', - completion=completion, e=e - ) - return '' - - -def format_label(completion, sig): - if sig and completion.type in ('function', 'method'): - params = ', '.join(param.name for param in sig[0].params) - label = '{}({})'.format(completion.name, params) - return label - return completion.name - - -LABEL_RESOLVER = LabelResolver(format_label) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/pylsp/plugins/pylint_lint.py new/python-lsp-server-1.3.1/pylsp/plugins/pylint_lint.py --- old/python-lsp-server-1.2.4/pylsp/plugins/pylint_lint.py 2021-08-20 01:36:01.000000000 +0200 +++ new/python-lsp-server-1.3.1/pylsp/plugins/pylint_lint.py 2021-10-30 19:18:46.000000000 +0200 @@ -236,7 +236,7 @@ cmd = [pylint_executable] cmd.extend(flags) cmd.extend(['--from-stdin', document.path]) - p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) # pylint: disable=consider-using-with + p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) except IOError: log.debug("Can't execute %s. Trying with 'python -m pylint'", pylint_executable) cmd = ['python', '-m', 'pylint'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/pylsp/workspace.py new/python-lsp-server-1.3.1/pylsp/workspace.py --- old/python-lsp-server-1.2.4/pylsp/workspace.py 2021-08-01 21:49:22.000000000 +0200 +++ new/python-lsp-server-1.3.1/pylsp/workspace.py 2021-10-30 19:18:46.000000000 +0200 @@ -76,7 +76,7 @@ return self._root_uri def is_local(self): - return (self._root_uri_scheme == '' or self._root_uri_scheme == 'file') and os.path.exists(self._root_path) + return (self._root_uri_scheme in ['', 'file']) and os.path.exists(self._root_path) def get_document(self, doc_uri): """Return a managed document if-present, else create one pointing at disk. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/python_lsp_server.egg-info/PKG-INFO new/python-lsp-server-1.3.1/python_lsp_server.egg-info/PKG-INFO --- old/python-lsp-server-1.2.4/python_lsp_server.egg-info/PKG-INFO 2021-10-11 18:12:17.000000000 +0200 +++ new/python-lsp-server-1.3.1/python_lsp_server.egg-info/PKG-INFO 2021-11-22 18:31:06.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: python-lsp-server -Version: 1.2.4 +Version: 1.3.1 Summary: Python Language Server for the Language Server Protocol Home-page: https://github.com/python-lsp/python-lsp-server Author: Python Language Server Contributors @@ -67,7 +67,7 @@ Installing these plugins will add extra functionality to the language server: - [pyls-flake8](https://github.com/emanspeaks/pyls-flake8/): Error checking using [flake8](https://flake8.pycqa.org/en/latest/). -- [mypy-ls](https://github.com/Richardk2n/mypy-ls): [MyPy](http://mypy-lang.org/) type checking for Python 3. +- [pylsp-mypy](https://github.com/Richardk2n/pylsp-mypy): [MyPy](http://mypy-lang.org/) type checking for Python >=3.6. - [pyls-isort](https://github.com/paradoxxxzero/pyls-isort): code formatting using [isort](https://github.com/PyCQA/isort) (automatic import sorting). - [python-lsp-black](https://github.com/python-lsp/python-lsp-black): code formatting using [Black](https://github.com/psf/black). - [pyls-memestra](https://github.com/QuantStack/pyls-memestra): detecting the use of deprecated APIs. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/python_lsp_server.egg-info/SOURCES.txt new/python-lsp-server-1.3.1/python_lsp_server.egg-info/SOURCES.txt --- old/python-lsp-server-1.2.4/python_lsp_server.egg-info/SOURCES.txt 2021-10-11 18:12:17.000000000 +0200 +++ new/python-lsp-server-1.3.1/python_lsp_server.egg-info/SOURCES.txt 2021-11-22 18:31:06.000000000 +0100 @@ -19,6 +19,7 @@ pylsp/config/pycodestyle_conf.py pylsp/config/source.py pylsp/plugins/__init__.py +pylsp/plugins/_resolvers.py pylsp/plugins/autopep8_format.py pylsp/plugins/definition.py pylsp/plugins/flake8_lint.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/python_lsp_server.egg-info/requires.txt new/python-lsp-server-1.3.1/python_lsp_server.egg-info/requires.txt --- old/python-lsp-server-1.2.4/python_lsp_server.egg-info/requires.txt 2021-10-11 18:12:17.000000000 +0200 +++ new/python-lsp-server-1.3.1/python_lsp_server.egg-info/requires.txt 2021-11-22 18:31:06.000000000 +0100 @@ -5,42 +5,42 @@ setuptools>=39.0.0 [all] -autopep8 -flake8<4.0.0,>=3.8.0 +autopep8<1.7.0,>=1.6.0 +flake8<4.1.0,>=4.0.0 mccabe<0.7.0,>=0.6.0 -pycodestyle>=2.7.0 +pycodestyle<2.9.0,>=2.8.0 pydocstyle>=2.0.0 -pyflakes<2.4.0,>=2.3.0 -pylint<2.10.0,>=2.5.0 +pyflakes<2.5.0,>=2.4.0 +pylint>=2.5.0 rope>=0.10.5 yapf [autopep8] -autopep8 +autopep8<1.7.0,>=1.6.0 [flake8] -flake8<4.0.0,>=3.8.0 +flake8<4.1.0,>=4.0.0 [mccabe] mccabe<0.7.0,>=0.6.0 [pycodestyle] -pycodestyle>=2.7.0 +pycodestyle<2.9.0,>=2.8.0 [pydocstyle] pydocstyle>=2.0.0 [pyflakes] -pyflakes<2.4.0,>=2.3.0 +pyflakes<2.5.0,>=2.4.0 [pylint] -pylint<2.10.0,>=2.5.0 +pylint>=2.5.0 [rope] rope>0.10.5 [test] -pylint<2.10.0,>=2.5.0 +pylint>=2.5.0 pytest pytest-cov coverage diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/setup.py new/python-lsp-server-1.3.1/setup.py --- old/python-lsp-server-1.2.4/setup.py 2021-10-11 18:08:22.000000000 +0200 +++ new/python-lsp-server-1.3.1/setup.py 2021-11-15 18:31:52.000000000 +0100 @@ -46,26 +46,26 @@ python_requires='>=3.6', extras_require={ 'all': [ - 'autopep8', - 'flake8>=3.8.0,<4.0.0', + 'autopep8>=1.6.0,<1.7.0', + 'flake8>=4.0.0,<4.1.0', 'mccabe>=0.6.0,<0.7.0', - 'pycodestyle>=2.7.0', + 'pycodestyle>=2.8.0,<2.9.0', 'pydocstyle>=2.0.0', - 'pyflakes>=2.3.0,<2.4.0', - 'pylint>=2.5.0,<2.10.0', + 'pyflakes>=2.4.0,<2.5.0', + 'pylint>=2.5.0', 'rope>=0.10.5', 'yapf', ], - 'autopep8': ['autopep8'], - 'flake8': ['flake8>=3.8.0,<4.0.0'], + 'autopep8': ['autopep8>=1.6.0,<1.7.0'], + 'flake8': ['flake8>=4.0.0,<4.1.0'], 'mccabe': ['mccabe>=0.6.0,<0.7.0'], - 'pycodestyle': ['pycodestyle>=2.7.0'], + 'pycodestyle': ['pycodestyle>=2.8.0,<2.9.0'], 'pydocstyle': ['pydocstyle>=2.0.0'], - 'pyflakes': ['pyflakes>=2.3.0,<2.4.0'], - 'pylint': ['pylint>=2.5.0,<2.10.0'], + 'pyflakes': ['pyflakes>=2.4.0,<2.5.0'], + 'pylint': ['pylint>=2.5.0'], 'rope': ['rope>0.10.5'], 'yapf': ['yapf'], - 'test': ['pylint>=2.5.0,<2.10.0', 'pytest', 'pytest-cov', 'coverage', + 'test': ['pylint>=2.5.0', 'pytest', 'pytest-cov', 'coverage', 'numpy', 'pandas', 'matplotlib', 'pyqt5', 'flaky'], }, entry_points={ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/test/fixtures.py new/python-lsp-server-1.3.1/test/fixtures.py --- old/python-lsp-server-1.2.4/test/fixtures.py 2021-10-04 18:16:59.000000000 +0200 +++ new/python-lsp-server-1.3.1/test/fixtures.py 2021-10-30 19:18:46.000000000 +0200 @@ -101,7 +101,7 @@ def fn(files): def create_file(name, content): fn = os.path.join(workspace.root_path, name) - with open(fn, 'w') as f: + with open(fn, 'w', encoding='utf-8') as f: f.write(content) workspace.put_document(uris.from_fs_path(fn), content) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/test/plugins/test_completion.py new/python-lsp-server-1.3.1/test/plugins/test_completion.py --- old/python-lsp-server-1.2.4/test/plugins/test_completion.py 2021-10-04 18:16:44.000000000 +0200 +++ new/python-lsp-server-1.3.1/test/plugins/test_completion.py 2021-11-22 18:21:10.000000000 +0100 @@ -139,7 +139,7 @@ assert items labels = [i['label'] for i in items] - assert 'isabs(path)' in labels + assert 'isfile(path)' in labels # Test we don't throw with big character pylsp_jedi_completions(config, doc, {'line': 1, 'character': 1000}) @@ -149,7 +149,7 @@ # Over the blank line com_position = {'line': 8, 'character': 0} doc = Document(DOC_URI, workspace, DOC) - config.update({'plugins': {'jedi_completion': {'resolve_at_most_labels': math.inf}}}) + config.update({'plugins': {'jedi_completion': {'resolve_at_most': math.inf}}}) completions = pylsp_jedi_completions(config, doc, com_position) items = {c['label']: c for c in completions} @@ -175,7 +175,11 @@ items = pylsp_jedi_completions(config, doc, com_position) assert items - assert items[0]['label'] == 'commonprefix(list)' + + expected = 'commonprefix(m)' + if JEDI_VERSION == '0.18.0': + expected = 'commonprefix(list)' + assert items[0]['label'] == expected # Test we don't throw with big character pylsp_jedi_completions(config, doc, {'line': 1, 'character': 1000}) @@ -187,16 +191,16 @@ doc = Document(DOC_URI, workspace, DOC) # Do not resolve any labels - config.update({'plugins': {'jedi_completion': {'resolve_at_most_labels': 0}}}) + config.update({'plugins': {'jedi_completion': {'resolve_at_most': 0}}}) items = pylsp_jedi_completions(config, doc, com_position) labels = {i['label'] for i in items} assert 'isabs' in labels # Resolve all items - config.update({'plugins': {'jedi_completion': {'resolve_at_most_labels': math.inf}}}) + config.update({'plugins': {'jedi_completion': {'resolve_at_most': math.inf}}}) items = pylsp_jedi_completions(config, doc, com_position) labels = {i['label'] for i in items} - assert 'isabs(path)' in labels + assert 'isfile(path)' in labels def test_rope_completion(config, workspace): @@ -214,7 +218,7 @@ # Over the blank line com_position = {'line': 8, 'character': 0} doc = Document(DOC_URI, workspace, DOC) - config.update({'plugins': {'jedi_completion': {'resolve_at_most_labels': math.inf}}}) + config.update({'plugins': {'jedi_completion': {'resolve_at_most': math.inf}}}) completions = pylsp_jedi_completions(config, doc, com_position) items = {c['label']: c['sortText'] for c in completions} @@ -318,6 +322,20 @@ assert completions[0]['insertTextFormat'] == lsp.InsertTextFormat.Snippet +def test_snippets_completion_at_most(config, workspace): + doc_snippets = 'from collections import defaultdict \na=defaultdict' + doc = Document(DOC_URI, workspace, doc_snippets) + config.capabilities['textDocument'] = { + 'completion': {'completionItem': {'snippetSupport': True}}} + config.update({'plugins': {'jedi_completion': {'include_params': True}}}) + config.update({'plugins': {'jedi_completion': {'resolve_at_most': 0}}}) + + com_position = {'line': 1, 'character': len(doc_snippets)} + completions = pylsp_jedi_completions(config, doc, com_position) + assert completions[0]['insertText'] == 'defaultdict' + assert not completions[0].get('insertTextFormat', None) + + def test_completion_with_class_objects(config, workspace): doc_text = 'class FOOBAR(Object): pass\nFOOB' com_position = {'line': 1, 'character': 4} @@ -346,7 +364,10 @@ 'completion': {'completionItem': {'snippetSupport': True}}} config.update({'plugins': {'jedi_completion': {'include_params': True}}}) completions = pylsp_jedi_completions(config, doc, completion_position) - out = 'divmod(${1:a}, ${2:b})$0' + + out = 'divmod(${1:x}, ${2:y})$0' + if JEDI_VERSION == '0.18.0': + out = 'divmod(${1:a}, ${2:b})$0' assert completions[0]['insertText'] == out @@ -393,11 +414,11 @@ completions = pylsp_jedi_completions(config, doc, position) assert completions[0]['insertText'] == 'date' - document = 'from datetime import date; a = date' + document = 'from math import fmod; a = fmod' doc = Document(DOC_URI, workspace, document) position = {'line': 0, 'character': len(document)} completions = pylsp_jedi_completions(config, doc, position) - assert completions[0]['insertText'] == 'date(${1:year}, ${2:month}, ${3:day})$0' + assert completions[0]['insertText'] == 'fmod(${1:x}, ${2:y})$0' def test_jedi_completion_extra_paths(tmpdir, workspace): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/test/plugins/test_flake8_lint.py new/python-lsp-server-1.3.1/test/plugins/test_flake8_lint.py --- old/python-lsp-server-1.2.4/test/plugins/test_flake8_lint.py 2021-06-25 23:26:52.000000000 +0200 +++ new/python-lsp-server-1.3.1/test/plugins/test_flake8_lint.py 2021-10-30 19:18:46.000000000 +0200 @@ -93,7 +93,7 @@ This function creates a ``setup.cfg``; you'll have to delete it yourself. """ - with open(os.path.join(workspace.root_path, "setup.cfg"), "w+") as f: + with open(os.path.join(workspace.root_path, "setup.cfg"), "w+", encoding='utf-8') as f: f.write(config_str) workspace.update_config({"pylsp": {"configurationSources": ["flake8"]}}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/test/plugins/test_pycodestyle_lint.py new/python-lsp-server-1.3.1/test/plugins/test_pycodestyle_lint.py --- old/python-lsp-server-1.2.4/test/plugins/test_pycodestyle_lint.py 2021-04-14 23:02:42.000000000 +0200 +++ new/python-lsp-server-1.3.1/test/plugins/test_pycodestyle_lint.py 2021-10-30 19:18:46.000000000 +0200 @@ -91,7 +91,7 @@ for conf_file, (content, working) in list(content.items()): # Now we'll add config file to ignore it - with open(os.path.join(workspace.root_path, conf_file), 'w+') as f: + with open(os.path.join(workspace.root_path, conf_file), 'w+', encoding='utf-8') as f: f.write(content) workspace._config.settings.cache_clear() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/test/plugins/test_pyflakes_lint.py new/python-lsp-server-1.3.1/test/plugins/test_pyflakes_lint.py --- old/python-lsp-server-1.2.4/test/plugins/test_pyflakes_lint.py 2021-04-14 23:02:42.000000000 +0200 +++ new/python-lsp-server-1.3.1/test/plugins/test_pyflakes_lint.py 2021-11-15 18:31:52.000000000 +0100 @@ -1,6 +1,8 @@ # Copyright 2017-2020 Palantir Technologies, Inc. # Copyright 2021- Python Language Server Contributors. +import sys + from pylsp import lsp, uris from pylsp.workspace import Document from pylsp.plugins import pyflakes_lint @@ -21,7 +23,7 @@ DOC_UNDEFINED_NAME_ERR = "a = b" -DOC_ENCODING = u"""# encoding=utf-8 +DOC_ENCODING = """# encoding=utf-8 import sys """ @@ -42,7 +44,10 @@ doc = Document(DOC_URI, workspace, DOC_SYNTAX_ERR) diag = pyflakes_lint.pylsp_lint(doc)[0] - assert diag['message'] == 'invalid syntax' + if sys.version_info[:2] >= (3, 10): + assert diag['message'] == "expected ':'" + else: + assert diag['message'] == 'invalid syntax' assert diag['range']['start'] == {'line': 0, 'character': 12} assert diag['severity'] == lsp.DiagnosticSeverity.Error diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/test/plugins/test_pylint_lint.py new/python-lsp-server-1.3.1/test/plugins/test_pylint_lint.py --- old/python-lsp-server-1.2.4/test/plugins/test_pylint_lint.py 2021-06-25 23:26:52.000000000 +0200 +++ new/python-lsp-server-1.3.1/test/plugins/test_pylint_lint.py 2021-11-15 18:31:52.000000000 +0100 @@ -4,6 +4,7 @@ import contextlib import os +import sys import tempfile from test import py2_only, py3_only, IS_PY3 @@ -37,7 +38,7 @@ def write_temp_doc(document, contents): - with open(document.path, 'w') as temp_file: + with open(document.path, 'w', encoding='utf-8') as temp_file: temp_file.write(contents) @@ -71,7 +72,10 @@ with temp_document(DOC_SYNTAX_ERR, workspace) as doc: diag = pylint_lint.pylsp_lint(config, doc, True)[0] - assert diag['message'].startswith('[syntax-error] invalid syntax') + if sys.version_info[:2] >= (3, 10): + assert diag['message'].count("[syntax-error] expected ':'") + else: + assert diag['message'].startswith('[syntax-error] invalid syntax') # Pylint doesn't give column numbers for invalid syntax. assert diag['range']['start'] == {'line': 0, 'character': 12} assert diag['severity'] == lsp.DiagnosticSeverity.Error diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/test/test_document.py new/python-lsp-server-1.3.1/test/test_document.py --- old/python-lsp-server-1.2.4/test/test_document.py 2021-04-14 23:02:42.000000000 +0200 +++ new/python-lsp-server-1.3.1/test/test_document.py 2021-10-30 19:18:46.000000000 +0200 @@ -16,7 +16,7 @@ def test_document_source_unicode(workspace): - document_mem = Document(DOC_URI, workspace, u'my source') + document_mem = Document(DOC_URI, workspace, 'my source') document_disk = Document(DOC_URI, workspace) assert isinstance(document_mem.source, type(document_disk.source)) @@ -44,27 +44,27 @@ def test_document_empty_edit(workspace): - doc = Document('file:///uri', workspace, u'') + doc = Document('file:///uri', workspace, '') doc.apply_change({ 'range': { 'start': {'line': 0, 'character': 0}, 'end': {'line': 0, 'character': 0} }, - 'text': u'f' + 'text': 'f' }) - assert doc.source == u'f' + assert doc.source == 'f' def test_document_line_edit(workspace): - doc = Document('file:///uri', workspace, u'itshelloworld') + doc = Document('file:///uri', workspace, 'itshelloworld') doc.apply_change({ - 'text': u'goodbye', + 'text': 'goodbye', 'range': { 'start': {'line': 0, 'character': 3}, 'end': {'line': 0, 'character': 8} } }) - assert doc.source == u'itsgoodbyeworld' + assert doc.source == 'itsgoodbyeworld' def test_document_multiline_edit(workspace): @@ -73,8 +73,8 @@ " print a\n", " print b\n" ] - doc = Document('file:///uri', workspace, u''.join(old)) - doc.apply_change({'text': u'print a, b', 'range': { + doc = Document('file:///uri', workspace, ''.join(old)) + doc.apply_change({'text': 'print a, b', 'range': { 'start': {'line': 1, 'character': 4}, 'end': {'line': 2, 'character': 11} }}) @@ -89,8 +89,8 @@ "print 'a'\n", "print 'b'\n" ] - doc = Document('file:///uri', workspace, u''.join(old)) - doc.apply_change({'text': u'o', 'range': { + doc = Document('file:///uri', workspace, ''.join(old)) + doc.apply_change({'text': 'o', 'range': { 'start': {'line': 2, 'character': 0}, 'end': {'line': 2, 'character': 0} }}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-lsp-server-1.2.4/test/test_workspace.py new/python-lsp-server-1.3.1/test/test_workspace.py --- old/python-lsp-server-1.2.4/test/test_workspace.py 2021-07-28 07:34:07.000000000 +0200 +++ new/python-lsp-server-1.3.1/test/test_workspace.py 2021-10-30 19:18:46.000000000 +0200 @@ -51,7 +51,7 @@ os.mkdir(project_root) for metafile in metafiles: - with open(os.path.join(project_root, metafile), 'w+') as f: + with open(os.path.join(project_root, metafile), 'w+', encoding='utf-8') as f: f.write('# ' + metafile) test_uri = uris.from_fs_path(os.path.join(project_root, 'hello/test.py'))