Hello community,

here is the log from the commit of package python-python-language-server for 
openSUSE:Factory checked in at 2020-07-05 01:22:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-python-language-server (Old)
 and      /work/SRC/openSUSE:Factory/.python-python-language-server.new.3060 
(New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-python-language-server"

Sun Jul  5 01:22:10 2020 rev:11 rq:818619 version:0.34.1

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-python-language-server/python-python-language-server.changes
      2020-05-29 21:35:56.706394122 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-python-language-server.new.3060/python-python-language-server.changes
    2020-07-05 01:23:34.645973576 +0200
@@ -1,0 +2,21 @@
+Fri Jul  3 15:26:09 UTC 2020 - Benjamin Greiner <[email protected]>
+
+- Update to Version 0.34.1
+  * Make flake8 plugin use stdin.
+  * Fix error when formatting if continuation lines are incorrectly 
+    indented when using autopep8. 
+- Changelog for Version 0.34.0
+  * Add option to configure flake8 executable.
+  * Read pycodestyle and flake8 configurations per workspace.
+  * Parse ignore arguments in flake8 to avoid issues with Atom.
+- Changelog for Version 0.33.3
+  * Do not start shutdown sequence on TCP when not checking parent
+    process
+- Changelog for Version 0.33.2
+  * Do not create documents from a textDocument/rename
+  * Fix some code quality and bug-risk issues
+- Changelog for Version 0.33.1
+  * Add support for autopep8 aggressive option from config file
+- skip tests in Leap 15.2
+
+-------------------------------------------------------------------

Old:
----
  python-language-server-0.33.0.tar.gz

New:
----
  python-language-server-0.34.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-python-language-server.spec ++++++
--- /var/tmp/diff_new_pack.DYTlwB/_old  2020-07-05 01:23:35.733976820 +0200
+++ /var/tmp/diff_new_pack.DYTlwB/_new  2020-07-05 01:23:35.733976820 +0200
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %bcond_without python2
 Name:           python-python-language-server
-Version:        0.33.0
+Version:        0.34.1
 Release:        0
 Summary:        Python Language Server for the Language Server Protocol
 License:        MIT
@@ -56,12 +56,12 @@
 Recommends:     python-rope >= 0.10.5
 BuildArch:      noarch
 # SECTION test requirements
+BuildRequires:  %{python_module future >= 0.14.0}
 BuildRequires:  %{python_module jedi >= 0.17}
 BuildRequires:  %{python_module mock}
 BuildRequires:  %{python_module pluggy}
 BuildRequires:  %{python_module pytest}
 BuildRequires:  %{python_module python-jsonrpc-server >= 0.3.2}
-BuildRequires:  %{python_module future >= 0.14.0}
 %if %{with python2}
 BuildRequires:  python2-backports.functools_lru_cache
 BuildRequires:  python2-configparser
@@ -113,13 +113,22 @@
 %check
 # Remove pytest addopts
 rm setup.cfg
+# define custom macros to skip tests in pytest
+%define pytest_addskiptest() \
+   for t in %{**}; do \
+     pytest_skippedtests+="${pytest_skippedtests:+ or }${t}"; \
+   done
+%define pytest_skiptests ${pytest_skippedtests:+-k "not 
(${pytest_skippedtests})"}
 %if 0%{?sle_version} == 150100 && 0%{?is_opensuse}
   # Test failure on Leap 15.1 due to different pylint version
-  skip_tests+="test_syntax_error_pylint_py"
-  # Test failure on Leap 15.1 due to mock hiccup
-  skip_tests+=" or test_flake8_config_param"
+  %pytest_addskiptest test_syntax_error_pylint_py
+%endif
+%if 0%{?sle_version} >= 150000 && 0%{?is_opensuse}
+  # Test failure on Leap 15 due to mock hiccup
+  %pytest_addskiptest test_flake8_config_param
+  %pytest_addskiptest test_flake8_executable_param
 %endif
-%pytest ${skip_tests:+-k "not ( $skip_tests )"}
+%pytest %{pytest_skiptests}
 
 %files %{python_files}
 %doc README.rst

++++++ python-language-server-0.33.0.tar.gz -> 
python-language-server-0.34.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-language-server-0.33.0/PKG-INFO 
new/python-language-server-0.34.1/PKG-INFO
--- old/python-language-server-0.33.0/PKG-INFO  2020-05-25 20:16:22.000000000 
+0200
+++ new/python-language-server-0.34.1/PKG-INFO  2020-07-02 18:36:00.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: python-language-server
-Version: 0.33.0
+Version: 0.34.1
 Summary: Python Language Server for the Language Server Protocol
 Home-page: https://github.com/palantir/python-language-server
 Author: Palantir Technologies, Inc.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-language-server-0.33.0/pyls/_version.py 
new/python-language-server-0.34.1/pyls/_version.py
--- old/python-language-server-0.33.0/pyls/_version.py  2020-05-25 
20:16:22.000000000 +0200
+++ new/python-language-server-0.34.1/pyls/_version.py  2020-07-02 
18:36:00.000000000 +0200
@@ -8,11 +8,11 @@
 
 version_json = '''
 {
- "date": "2020-05-25T13:08:44-0500",
+ "date": "2020-07-02T11:29:43-0500",
  "dirty": false,
  "error": null,
- "full-revisionid": "2dc19c2acf8acc412ae8e49a1e865e6664427201",
- "version": "0.33.0"
+ "full-revisionid": "78dee3d03fd6027804588fd204df06b2ac57d7d3",
+ "version": "0.34.1"
 }
 '''  # END VERSION_JSON
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-language-server-0.33.0/pyls/config/config.py 
new/python-language-server-0.34.1/pyls/config/config.py
--- old/python-language-server-0.33.0/pyls/config/config.py     2020-05-25 
20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/pyls/config/config.py     2020-07-02 
18:35:59.000000000 +0200
@@ -106,6 +106,13 @@
         settings = {}
         sources = self._settings.get('configurationSources', 
DEFAULT_CONFIG_SOURCES)
 
+        # Plugin configuration
+        settings = _utils.merge_dicts(settings, self._plugin_settings)
+
+        # LSP configuration
+        settings = _utils.merge_dicts(settings, self._settings)
+
+        # User configuration
         for source_name in reversed(sources):
             source = self._config_sources.get(source_name)
             if not source:
@@ -113,14 +120,8 @@
             source_conf = source.user_config()
             log.debug("Got user config from %s: %s", 
source.__class__.__name__, source_conf)
             settings = _utils.merge_dicts(settings, source_conf)
-        log.debug("With user configuration: %s", settings)
-
-        settings = _utils.merge_dicts(settings, self._plugin_settings)
-        log.debug("With plugin configuration: %s", settings)
-
-        settings = _utils.merge_dicts(settings, self._settings)
-        log.debug("With lsp configuration: %s", settings)
 
+        # Project configuration
         for source_name in reversed(sources):
             source = self._config_sources.get(source_name)
             if not source:
@@ -128,7 +129,8 @@
             source_conf = source.project_config(document_path or 
self._root_path)
             log.debug("Got project config from %s: %s", 
source.__class__.__name__, source_conf)
             settings = _utils.merge_dicts(settings, source_conf)
-        log.debug("With project configuration: %s", settings)
+
+        log.debug("With configuration: %s", settings)
 
         return settings
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-language-server-0.33.0/pyls/config/pycodestyle_conf.py 
new/python-language-server-0.34.1/pyls/config/pycodestyle_conf.py
--- old/python-language-server-0.33.0/pyls/config/pycodestyle_conf.py   
2020-05-25 20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/pyls/config/pycodestyle_conf.py   
2020-07-02 18:35:59.000000000 +0200
@@ -15,6 +15,7 @@
     ('ignore', 'plugins.pycodestyle.ignore', list),
     ('max-line-length', 'plugins.pycodestyle.maxLineLength', int),
     ('select', 'plugins.pycodestyle.select', list),
+    ('aggressive', 'plugins.pycodestyle.aggressive', int),
 ]
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-language-server-0.33.0/pyls/plugins/autopep8_format.py 
new/python-language-server-0.34.1/pyls/plugins/autopep8_format.py
--- old/python-language-server-0.33.0/pyls/plugins/autopep8_format.py   
2020-05-25 20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/pyls/plugins/autopep8_format.py   
2020-07-02 18:35:59.000000000 +0200
@@ -1,6 +1,7 @@
 # Copyright 2018 Palantir Technologies, Inc.
 import logging
-from autopep8 import fix_code
+import pycodestyle
+from autopep8 import fix_code, continued_indentation as autopep8_c_i
 from pyls import hookimpl
 
 log = logging.getLogger(__name__)
@@ -31,8 +32,16 @@
     if line_range:
         options['line_range'] = list(line_range)
 
+    # Temporarily re-monkey-patch the continued_indentation checker - #771
+    del pycodestyle._checks['logical_line'][pycodestyle.continued_indentation]
+    pycodestyle.register_check(autopep8_c_i)
+
     new_source = fix_code(document.source, options=options)
 
+    # Switch it back
+    del pycodestyle._checks['logical_line'][autopep8_c_i]
+    pycodestyle.register_check(pycodestyle.continued_indentation)
+
     if new_source == document.source:
         return []
 
@@ -57,6 +66,7 @@
         'ignore': settings.get('ignore'),
         'max_line_length': settings.get('maxLineLength'),
         'select': settings.get('select'),
+        'aggressive': settings.get('aggressive'),
     }
 
     # Filter out null options
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-language-server-0.33.0/pyls/plugins/flake8_lint.py 
new/python-language-server-0.34.1/pyls/plugins/flake8_lint.py
--- old/python-language-server-0.33.0/pyls/plugins/flake8_lint.py       
2020-05-25 20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/pyls/plugins/flake8_lint.py       
2020-07-02 18:35:59.000000000 +0200
@@ -7,6 +7,7 @@
 from pyls import hookimpl, lsp
 
 log = logging.getLogger(__name__)
+FIX_IGNORES_RE = re.compile(r'([^a-zA-Z0-9_,]*;.*(\W+||$))')
 
 
 @hookimpl
@@ -16,7 +17,8 @@
 
 
 @hookimpl
-def pyls_lint(config, document):
+def pyls_lint(workspace, document):
+    config = workspace._config
     settings = config.plugin_settings('flake8')
     log.debug("Got flake8 settings: %s", settings)
 
@@ -39,39 +41,44 @@
         log.debug("using flake8 with config: %s", opts['config'])
 
     # Call the flake8 utility then parse diagnostics from stdout
-    args = build_args(opts, document.path)
-    output = run_flake8(args)
+    flake8_executable = settings.get('executable', 'flake8')
+
+    args = build_args(opts)
+    output = run_flake8(flake8_executable, args, document)
     return parse_stdout(document, output)
 
 
-def run_flake8(args):
+def run_flake8(flake8_executable, args, document):
     """Run flake8 with the provided arguments, logs errors
     from stderr if any.
     """
-    log.debug("Calling flake8 with args: '%s'", args)
+    # a quick temporary fix to deal with Atom
+    args = [(i if not i.startswith('--ignore=') else FIX_IGNORES_RE.sub('', i))
+            for i in args if i is not None]
+
+    log.debug("Calling %s with args: '%s'", flake8_executable, args)
     try:
-        cmd = ['flake8']
+        cmd = [flake8_executable]
         cmd.extend(args)
-        p = Popen(cmd, stdout=PIPE, stderr=PIPE)
+        p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
     except IOError:
-        log.debug("Can't execute flake8. Trying with 'python -m flake8'")
+        log.debug("Can't execute %s. Trying with 'python -m flake8'", 
flake8_executable)
         cmd = ['python', '-m', 'flake8']
         cmd.extend(args)
-        p = Popen(cmd, stdout=PIPE, stderr=PIPE)
-    (stdout, stderr) = p.communicate()
+        p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
+    (stdout, stderr) = p.communicate(document.source.encode())
     if stderr:
         log.error("Error while running flake8 '%s'", stderr.decode())
     return stdout.decode()
 
 
-def build_args(options, doc_path):
+def build_args(options):
     """Build arguments for calling flake8.
 
     Args:
         options: dictionary of argument names and their values.
-        doc_path: path of the document to lint.
     """
-    args = [doc_path]
+    args = ['-']  # use stdin
     for arg_name, arg_val in options.items():
         if arg_val is None:
             continue
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-language-server-0.33.0/pyls/plugins/jedi_completion.py 
new/python-language-server-0.34.1/pyls/plugins/jedi_completion.py
--- old/python-language-server-0.33.0/pyls/plugins/jedi_completion.py   
2020-05-25 20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/pyls/plugins/jedi_completion.py   
2020-07-02 18:35:59.000000000 +0200
@@ -181,7 +181,7 @@
 def _label(definition):
     sig = definition.get_signatures()
     if definition.type in ('function', 'method') and sig:
-        params = ', '.join([param.name for param in sig[0].params])
+        params = ', '.join(param.name for param in sig[0].params)
         return '{}({})'.format(definition.name, params)
 
     return definition.name
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-language-server-0.33.0/pyls/plugins/jedi_rename.py 
new/python-language-server-0.34.1/pyls/plugins/jedi_rename.py
--- old/python-language-server-0.33.0/pyls/plugins/jedi_rename.py       
2020-05-25 20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/pyls/plugins/jedi_rename.py       
2020-07-02 18:35:59.000000000 +0200
@@ -17,30 +17,29 @@
         raise Exception('No support for renaming in Python 2/3.5 with Jedi. '
                         'Consider using the rope_rename plugin instead')
     log.debug('Finished rename: %s', refactoring.get_diff())
-
-    return {
-        'documentChanges': [
-            {
-                'textDocument': {
-                    'uri': uris.uri_with(document.uri, path=file_path),
-                    'version': workspace.get_document(document.uri).version,
-                },
-                'edits': [
-                    {
-                        'range': {
-                            'start': {'line': 0, 'character': 0},
-                            'end': {
-                                'line': 
_num_lines(changed_file.get_new_code()),
-                                'character': 0,
-                            },
+    changes = []
+    for file_path, changed_file in refactoring.get_changed_files().items():
+        uri = uris.from_fs_path(file_path)
+        doc = workspace.get_maybe_document(uri)
+        changes.append({
+            'textDocument': {
+                'uri': uri,
+                'version': doc.version if doc else None
+            },
+            'edits': [
+                {
+                    'range': {
+                        'start': {'line': 0, 'character': 0},
+                        'end': {
+                            'line': _num_lines(changed_file.get_new_code()),
+                            'character': 0,
                         },
-                        'newText': changed_file.get_new_code(),
-                    }
-                ],
-            }
-            for file_path, changed_file in 
refactoring.get_changed_files().items()
-        ],
-    }
+                    },
+                    'newText': changed_file.get_new_code(),
+                }
+            ],
+        })
+    return {'documentChanges': changes}
 
 
 def _num_lines(file_contents):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-language-server-0.33.0/pyls/plugins/pycodestyle_lint.py 
new/python-language-server-0.34.1/pyls/plugins/pycodestyle_lint.py
--- old/python-language-server-0.33.0/pyls/plugins/pycodestyle_lint.py  
2020-05-25 20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/pyls/plugins/pycodestyle_lint.py  
2020-07-02 18:35:59.000000000 +0200
@@ -19,7 +19,8 @@
 
 
 @hookimpl
-def pyls_lint(config, document):
+def pyls_lint(workspace, document):
+    config = workspace._config
     settings = config.plugin_settings('pycodestyle')
     log.debug("Got pycodestyle settings: %s", settings)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-language-server-0.33.0/pyls/plugins/rope_rename.py 
new/python-language-server-0.34.1/pyls/plugins/rope_rename.py
--- old/python-language-server-0.33.0/pyls/plugins/rope_rename.py       
2020-05-25 20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/pyls/plugins/rope_rename.py       
2020-07-02 18:35:59.000000000 +0200
@@ -1,6 +1,5 @@
 # Copyright 2017 Palantir Technologies, Inc.
 import logging
-import os
 
 from rope.base import libutils
 from rope.refactor.rename import Rename
@@ -30,23 +29,29 @@
     log.debug("Executing rename of %s to %s", 
document.word_at_position(position), new_name)
     changeset = rename.get_changes(new_name, in_hierarchy=True, docs=True)
     log.debug("Finished rename: %s", changeset.changes)
-    return {
-        'documentChanges': [{
+    changes = []
+    for change in changeset.changes:
+        uri = uris.from_fs_path(change.resource.path)
+        doc = workspace.get_maybe_document(uri)
+        changes.append({
             'textDocument': {
-                'uri': uris.uri_with(
-                    document.uri, path=os.path.join(workspace.root_path, 
change.resource.path)
-                ),
-                'version': workspace.get_document(document.uri).version
+                'uri': uri,
+                'version': doc.version if doc else None
             },
-            'edits': [{
-                'range': {
-                    'start': {'line': 0, 'character': 0},
-                    'end': {'line': _num_lines(change.resource), 'character': 
0},
-                },
-                'newText': change.new_contents
-            }]
-        } for change in changeset.changes]
-    }
+            'edits': [
+                {
+                    'range': {
+                        'start': {'line': 0, 'character': 0},
+                        'end': {
+                            'line': _num_lines(change.resource),
+                            'character': 0,
+                        },
+                    },
+                    'newText': change.new_contents,
+                }
+            ]
+        })
+    return {'documentChanges': changes}
 
 
 def _num_lines(resource):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-language-server-0.33.0/pyls/python_ls.py 
new/python-language-server-0.34.1/pyls/python_ls.py
--- old/python-language-server-0.33.0/pyls/python_ls.py 2020-05-25 
20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/pyls/python_ls.py 2020-07-02 
18:35:59.000000000 +0200
@@ -52,12 +52,13 @@
     if not issubclass(handler_class, PythonLanguageServer):
         raise ValueError('Handler class must be an instance of 
PythonLanguageServer')
 
-    def shutdown_server(*args):
+    def shutdown_server(check_parent_process, *args):
         # pylint: disable=unused-argument
-        log.debug('Shutting down server')
-        # Shutdown call must be done on a thread, to prevent deadlocks
-        stop_thread = threading.Thread(target=server.shutdown)
-        stop_thread.start()
+        if check_parent_process:
+            log.debug('Shutting down server')
+            # Shutdown call must be done on a thread, to prevent deadlocks
+            stop_thread = threading.Thread(target=server.shutdown)
+            stop_thread.start()
 
     # Construct a custom wrapper class around the user's handler_class
     wrapper_class = type(
@@ -65,7 +66,7 @@
         (_StreamHandlerWrapper,),
         {'DELEGATE_CLASS': partial(handler_class,
                                    check_parent_process=check_parent_process),
-         'SHUTDOWN_CALL': shutdown_server}
+         'SHUTDOWN_CALL': partial(shutdown_server, check_parent_process)}
     )
 
     server = socketserver.TCPServer((bind_addr, port), wrapper_class, 
bind_and_activate=False)
@@ -357,7 +358,7 @@
         self.config.update((settings or {}).get('pyls', {}))
         for workspace_uri in self.workspaces:
             workspace = self.workspaces[workspace_uri]
-            workspace.update_config(self.config)
+            workspace.update_config(settings)
             for doc_uri in workspace.documents:
                 self.lint(doc_uri, is_saved=False)
 
@@ -375,14 +376,20 @@
         for added_info in added:
             if 'uri' in added_info:
                 added_uri = added_info['uri']
-                self.workspaces[added_uri] = Workspace(added_uri, 
self._endpoint, self.config)
+                workspace_config = config.Config(
+                    added_uri, self.config._init_opts,
+                    self.config._process_id, self.config._capabilities)
+                self.workspaces[added_uri] = Workspace(
+                    added_uri, self._endpoint, workspace_config)
 
         root_workspace_removed = any(removed_info['uri'] == self.root_uri for 
removed_info in removed)
         workspace_added = len(added) > 0 and 'uri' in added[0]
         if root_workspace_removed and workspace_added:
             added_uri = added[0]['uri']
             self.root_uri = added_uri
-            self.workspace = self.workspaces[added_uri]
+            new_root_workspace = self.workspaces[added_uri]
+            self.config = new_root_workspace._config
+            self.workspace = new_root_workspace
         elif root_workspace_removed:
             # NOTE: Removing the root workspace can only happen when the server
             # is closed, thus the else condition of this if can never happen.
@@ -390,8 +397,10 @@
                 log.debug('Root workspace deleted!')
                 available_workspaces = sorted(self.workspaces)
                 first_workspace = available_workspaces[0]
+                new_root_workspace = self.workspaces[first_workspace]
                 self.root_uri = first_workspace
-                self.workspace = self.workspaces[first_workspace]
+                self.config = new_root_workspace._config
+                self.workspace = new_root_workspace
 
         # Migrate documents that are on the root workspace and have a better
         # match now
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-language-server-0.33.0/pyls/workspace.py 
new/python-language-server-0.34.1/pyls/workspace.py
--- old/python-language-server-0.33.0/pyls/workspace.py 2020-05-25 
20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/pyls/workspace.py 2020-07-02 
18:35:59.000000000 +0200
@@ -71,6 +71,9 @@
         """
         return self._docs.get(doc_uri) or self._create_document(doc_uri)
 
+    def get_maybe_document(self, doc_uri):
+        return self._docs.get(doc_uri)
+
     def put_document(self, doc_uri, source, version=None):
         self._docs[doc_uri] = self._create_document(doc_uri, source=source, 
version=version)
 
@@ -81,10 +84,10 @@
         self._docs[doc_uri].apply_change(change)
         self._docs[doc_uri].version = version
 
-    def update_config(self, config):
-        self._config = config
+    def update_config(self, settings):
+        self._config.update((settings or {}).get('pyls', {}))
         for doc_uri in self.documents:
-            self.get_document(doc_uri).update_config(config)
+            self.get_document(doc_uri).update_config(settings)
 
     def apply_edit(self, edit):
         return self._endpoint.request(self.M_APPLY_EDIT, {'edit': edit})
@@ -98,28 +101,30 @@
     def source_roots(self, document_path):
         """Return the source roots for the given document."""
         files = _utils.find_parents(self._root_path, document_path, 
['setup.py', 'pyproject.toml']) or []
-        return list(set((os.path.dirname(project_file) for project_file in 
files))) or [self._root_path]
+        return list({os.path.dirname(project_file) for project_file in files}) 
or [self._root_path]
 
     def _create_document(self, doc_uri, source=None, version=None):
         path = uris.to_fs_path(doc_uri)
         return Document(
-            doc_uri, self, source=source, version=version,
+            doc_uri,
+            self,
+            source=source,
+            version=version,
             extra_sys_path=self.source_roots(path),
             rope_project_builder=self._rope_project_builder,
-            config=self._config,
         )
 
 
 class Document(object):
 
     def __init__(self, uri, workspace, source=None, version=None, local=True, 
extra_sys_path=None,
-                 rope_project_builder=None, config=None):
+                 rope_project_builder=None):
         self.uri = uri
         self.version = version
         self.path = uris.to_fs_path(uri)
         self.filename = os.path.basename(self.path)
 
-        self._config = config
+        self._config = workspace._config
         self._workspace = workspace
         self._local = local
         self._source = source
@@ -144,8 +149,8 @@
                 return f.read()
         return self._source
 
-    def update_config(self, config):
-        self._config = config
+    def update_config(self, settings):
+        self._config.update((settings or {}).get('pyls', {}))
 
     def apply_change(self, change):
         """Apply a change to the document."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-language-server-0.33.0/python_language_server.egg-info/PKG-INFO 
new/python-language-server-0.34.1/python_language_server.egg-info/PKG-INFO
--- old/python-language-server-0.33.0/python_language_server.egg-info/PKG-INFO  
2020-05-25 20:16:22.000000000 +0200
+++ new/python-language-server-0.34.1/python_language_server.egg-info/PKG-INFO  
2020-07-02 18:36:00.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: python-language-server
-Version: 0.33.0
+Version: 0.34.1
 Summary: Python Language Server for the Language Server Protocol
 Home-page: https://github.com/palantir/python-language-server
 Author: Palantir Technologies, Inc.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-language-server-0.33.0/test/fixtures.py 
new/python-language-server-0.34.1/test/fixtures.py
--- old/python-language-server-0.33.0/test/fixtures.py  2020-05-25 
20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/test/fixtures.py  2020-07-02 
18:35:59.000000000 +0200
@@ -39,7 +39,9 @@
 @pytest.fixture
 def workspace(tmpdir):
     """Return a workspace."""
-    return Workspace(uris.from_fs_path(str(tmpdir)), Mock())
+    ws = Workspace(uris.from_fs_path(str(tmpdir)), Mock())
+    ws._config = Config(ws.root_uri, {}, 0, {})
+    return ws
 
 
 @pytest.fixture
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-language-server-0.33.0/test/plugins/test_autopep8_format.py 
new/python-language-server-0.34.1/test/plugins/test_autopep8_format.py
--- old/python-language-server-0.33.0/test/plugins/test_autopep8_format.py      
2020-05-25 20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/test/plugins/test_autopep8_format.py      
2020-07-02 18:35:59.000000000 +0200
@@ -15,6 +15,25 @@
 
 GOOD_DOC = """A = ['hello', 'world']\n"""
 
+INDENTED_DOC = """def foo():
+    print('asdf',
+    file=None
+    )
+
+bar = { 'foo': foo
+}
+"""
+
+CORRECT_INDENTED_DOC = """def foo():
+    print('asdf',
+          file=None
+          )
+
+
+bar = {'foo': foo
+       }
+"""
+
 
 def test_format(config, workspace):
     doc = Document(DOC_URI, workspace, DOC)
@@ -42,3 +61,11 @@
 def test_no_change(config, workspace):
     doc = Document(DOC_URI, workspace, GOOD_DOC)
     assert not pyls_format_document(config, doc)
+
+
+def test_hanging_indentation(config, workspace):
+    doc = Document(DOC_URI, workspace, INDENTED_DOC)
+    res = pyls_format_document(config, doc)
+
+    assert len(res) == 1
+    assert res[0]['newText'] == CORRECT_INDENTED_DOC
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-language-server-0.33.0/test/plugins/test_completion.py 
new/python-language-server-0.34.1/test/plugins/test_completion.py
--- old/python-language-server-0.33.0/test/plugins/test_completion.py   
2020-05-25 20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/test/plugins/test_completion.py   
2020-07-02 18:35:59.000000000 +0200
@@ -2,7 +2,6 @@
 import os
 import sys
 
-from test.test_utils import MockWorkspace
 import pytest
 
 from pyls import uris, lsp
@@ -278,7 +277,7 @@
     assert completions[0]['insertText'] == 'date(${1:year}, ${2:month}, 
${3:day})$0'
 
 
-def test_jedi_completion_extra_paths(config, tmpdir, workspace):
+def test_jedi_completion_extra_paths(tmpdir, workspace):
     # Create a tempfile with some content and pass to extra_paths
     temp_doc_content = '''
 def spam():
@@ -296,42 +295,42 @@
 
     # After 'foo.s' without extra paths
     com_position = {'line': 1, 'character': 5}
-    completions = pyls_jedi_completions(config, doc, com_position)
+    completions = pyls_jedi_completions(doc._config, doc, com_position)
     assert completions is None
 
     # Update config extra paths
-    config.update({'plugins': {'jedi': {'extra_paths': extra_paths}}})
-    doc.update_config(config)
+    settings = {'pyls': {'plugins': {'jedi': {'extra_paths': extra_paths}}}}
+    doc.update_config(settings)
 
     # After 'foo.s' with extra paths
     com_position = {'line': 1, 'character': 5}
-    completions = pyls_jedi_completions(config, doc, com_position)
+    completions = pyls_jedi_completions(doc._config, doc, com_position)
     assert completions[0]['label'] == 'spam()'
 
 
 @pytest.mark.skipif(PY2 or not LINUX or not CI, reason="tested on linux and 
python 3 only")
-def test_jedi_completion_environment(config):
+def test_jedi_completion_environment(workspace):
     # Content of doc to test completion
     doc_content = '''import logh
 '''
-    doc = Document(DOC_URI, MockWorkspace(), doc_content)
+    doc = Document(DOC_URI, workspace, doc_content)
 
     # After 'import logh' with default environment
     com_position = {'line': 0, 'character': 11}
 
     assert os.path.isdir('/tmp/pyenv/')
 
-    config.update({'plugins': {'jedi': {'environment': None}}})
-    doc.update_config(config)
-    completions = pyls_jedi_completions(config, doc, com_position)
+    settings = {'pyls': {'plugins': {'jedi': {'environment': None}}}}
+    doc.update_config(settings)
+    completions = pyls_jedi_completions(doc._config, doc, com_position)
     assert completions is None
 
     # Update config extra environment
     env_path = '/tmp/pyenv/bin/python'
-    config.update({'plugins': {'jedi': {'environment': env_path}}})
-    doc.update_config(config)
+    settings = {'pyls': {'plugins': {'jedi': {'environment': env_path}}}}
+    doc.update_config(settings)
 
     # After 'import logh' with new environment
-    completions = pyls_jedi_completions(config, doc, com_position)
+    completions = pyls_jedi_completions(doc._config, doc, com_position)
     assert completions[0]['label'] == 'loghub'
     assert 'changelog generator' in completions[0]['documentation'].lower()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-language-server-0.33.0/test/plugins/test_flake8_lint.py 
new/python-language-server-0.34.1/test/plugins/test_flake8_lint.py
--- old/python-language-server-0.33.0/test/plugins/test_flake8_lint.py  
2020-05-25 20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/test/plugins/test_flake8_lint.py  
2020-07-02 18:35:59.000000000 +0200
@@ -1,7 +1,6 @@
 # Copyright 2019 Palantir Technologies, Inc.
 import tempfile
 import os
-from test.test_utils import MockWorkspace
 from mock import patch
 from pyls import lsp, uris
 from pyls.plugins import flake8_lint
@@ -19,29 +18,33 @@
 """
 
 
-def temp_document(doc_text):
+def temp_document(doc_text, workspace):
     temp_file = tempfile.NamedTemporaryFile(mode='w', delete=False)
     name = temp_file.name
     temp_file.write(doc_text)
     temp_file.close()
-    doc = Document(uris.from_fs_path(name), MockWorkspace())
+    doc = Document(uris.from_fs_path(name), workspace)
 
     return name, doc
 
 
-def test_flake8_no_checked_file(config, workspace):
-    # A bad uri or a non-saved file may cause the flake8 linter to do nothing.
-    # In this situtation, the linter will return an empty list.
-
+def test_flake8_unsaved(workspace):
     doc = Document('', workspace, DOC)
-    diags = flake8_lint.pyls_lint(config, doc)
-    assert 'Error' in diags[0]['message']
+    diags = flake8_lint.pyls_lint(workspace, doc)
+    msg = 'local variable \'a\' is assigned to but never used'
+    unused_var = [d for d in diags if d['message'] == msg][0]
+
+    assert unused_var['source'] == 'flake8'
+    assert unused_var['code'] == 'F841'
+    assert unused_var['range']['start'] == {'line': 5, 'character': 1}
+    assert unused_var['range']['end'] == {'line': 5, 'character': 11}
+    assert unused_var['severity'] == lsp.DiagnosticSeverity.Warning
 
 
-def test_flake8_lint(config):
+def test_flake8_lint(workspace):
     try:
-        name, doc = temp_document(DOC)
-        diags = flake8_lint.pyls_lint(config, doc)
+        name, doc = temp_document(DOC, workspace)
+        diags = flake8_lint.pyls_lint(workspace, doc)
         msg = 'local variable \'a\' is assigned to but never used'
         unused_var = [d for d in diags if d['message'] == msg][0]
 
@@ -55,14 +58,29 @@
         os.remove(name)
 
 
-def test_flake8_config_param(config):
+def test_flake8_config_param(workspace):
     with patch('pyls.plugins.flake8_lint.Popen') as popen_mock:
         mock_instance = popen_mock.return_value
         mock_instance.communicate.return_value = [bytes(), bytes()]
         flake8_conf = '/tmp/some.cfg'
-        config.update({'plugins': {'flake8': {'config': flake8_conf}}})
-        _name, doc = temp_document(DOC)
-        flake8_lint.pyls_lint(config, doc)
+        workspace._config.update({'plugins': {'flake8': {'config': 
flake8_conf}}})
+        _name, doc = temp_document(DOC, workspace)
+        flake8_lint.pyls_lint(workspace, doc)
         call_args = popen_mock.call_args.args[0]
         assert 'flake8' in call_args
         assert '--config={}'.format(flake8_conf) in call_args
+
+
+def test_flake8_executable_param(workspace):
+    with patch('pyls.plugins.flake8_lint.Popen') as popen_mock:
+        mock_instance = popen_mock.return_value
+        mock_instance.communicate.return_value = [bytes(), bytes()]
+
+        flake8_executable = '/tmp/flake8'
+        workspace._config.update({'plugins': {'flake8': {'executable': 
flake8_executable}}})
+
+        _name, doc = temp_document(DOC, workspace)
+        flake8_lint.pyls_lint(workspace, doc)
+
+        call_args = popen_mock.call_args.args[0]
+        assert flake8_executable in call_args
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-language-server-0.33.0/test/plugins/test_jedi_rename.py 
new/python-language-server-0.34.1/test/plugins/test_jedi_rename.py
--- old/python-language-server-0.33.0/test/plugins/test_jedi_rename.py  
2020-05-25 20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/test/plugins/test_jedi_rename.py  
2020-07-02 18:35:59.000000000 +0200
@@ -17,10 +17,18 @@
     pass
 '''
 
+DOC_NAME_EXTRA = 'test2.py'
+DOC_EXTRA = '''from test1 import Test1
+x = Test1()
+'''
+
 
 @pytest.fixture
 def tmp_workspace(temp_workspace_factory):
-    return temp_workspace_factory({DOC_NAME: DOC})
+    return temp_workspace_factory({
+        DOC_NAME: DOC,
+        DOC_NAME_EXTRA: DOC_EXTRA
+    })
 
 
 @pytest.mark.skipif(LT_PY36, reason='Jedi refactoring isnt supported on Python 
2.x/3.5')
@@ -34,10 +42,11 @@
     assert len(result.keys()) == 1
 
     changes = result.get('documentChanges')
-    assert len(changes) == 1
-    changes = changes[0]
+    assert len(changes) == 2
 
-    assert changes.get('edits') == [
+    assert changes[0]['textDocument']['uri'] == doc.uri
+    assert changes[0]['textDocument']['version'] == doc.version
+    assert changes[0].get('edits') == [
         {
             'range': {
                 'start': {'line': 0, 'character': 0},
@@ -46,3 +55,23 @@
             'newText': 'class ShouldBeRenamed():\n    pass\n\nclass 
Test2(ShouldBeRenamed):\n    pass\n',
         }
     ]
+    path = os.path.join(tmp_workspace.root_path, DOC_NAME_EXTRA)
+    uri_extra = uris.from_fs_path(path)
+    assert changes[1]['textDocument']['uri'] == uri_extra
+    # This also checks whether documents not yet added via textDocument/didOpen
+    # but that do need to be renamed in the project have a `null` version
+    # number.
+    assert changes[1]['textDocument']['version'] is None
+    expected = 'from test1 import ShouldBeRenamed\nx = ShouldBeRenamed()\n'
+    if os.name == 'nt':
+        # The .write method in the temp_workspace_factory functions writes
+        # Windows-style line-endings.
+        expected = expected.replace('\n', '\r\n')
+    assert changes[1].get('edits') == [
+        {
+            'range': {
+                'start': {'line': 0, 'character': 0},
+                'end': {'line': 2, 'character': 0}},
+            'newText': expected
+        }
+    ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-language-server-0.33.0/test/plugins/test_pycodestyle_lint.py 
new/python-language-server-0.34.1/test/plugins/test_pycodestyle_lint.py
--- old/python-language-server-0.33.0/test/plugins/test_pycodestyle_lint.py     
2020-05-25 20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/test/plugins/test_pycodestyle_lint.py     
2020-07-02 18:35:59.000000000 +0200
@@ -1,7 +1,6 @@
 # Copyright 2017 Palantir Technologies, Inc.
 import os
 from pyls import lsp, uris
-from pyls.config.config import Config
 from pyls.workspace import Document
 from pyls.plugins import pycodestyle_lint
 
@@ -20,9 +19,9 @@
 """
 
 
-def test_pycodestyle(config, workspace):
+def test_pycodestyle(workspace):
     doc = Document(DOC_URI, workspace, DOC)
-    diags = pycodestyle_lint.pyls_lint(config, doc)
+    diags = pycodestyle_lint.pyls_lint(workspace, doc)
 
     assert all([d['source'] == 'pycodestyle' for d in diags])
 
@@ -78,10 +77,9 @@
     doc_uri = uris.from_fs_path(os.path.join(workspace.root_path, 'test.py'))
     workspace.put_document(doc_uri, DOC)
     doc = workspace.get_document(doc_uri)
-    config = Config(workspace.root_uri, {}, 1234, {})
 
     # Make sure we get a warning for 'indentation contains tabs'
-    diags = pycodestyle_lint.pyls_lint(config, doc)
+    diags = pycodestyle_lint.pyls_lint(workspace, doc)
     assert [d for d in diags if d['code'] == 'W191']
 
     content = {
@@ -93,10 +91,10 @@
         # Now we'll add config file to ignore it
         with open(os.path.join(workspace.root_path, conf_file), 'w+') as f:
             f.write(content)
-        config.settings.cache_clear()
+        workspace._config.settings.cache_clear()
 
         # And make sure we don't get any warnings
-        diags = pycodestyle_lint.pyls_lint(config, doc)
+        diags = pycodestyle_lint.pyls_lint(workspace, doc)
         assert len([d for d in diags if d['code'] == 'W191']) == (0 if working 
else 1)
         assert len([d for d in diags if d['code'] == 'E201']) == (0 if working 
else 1)
         assert [d for d in diags if d['code'] == 'W391']
@@ -104,9 +102,9 @@
         os.unlink(os.path.join(workspace.root_path, conf_file))
 
     # Make sure we can ignore via the PYLS config as well
-    config.update({'plugins': {'pycodestyle': {'ignore': ['W191', 'E201']}}})
+    workspace._config.update({'plugins': {'pycodestyle': {'ignore': ['W191', 
'E201']}}})
     # And make sure we only get one warning
-    diags = pycodestyle_lint.pyls_lint(config, doc)
+    diags = pycodestyle_lint.pyls_lint(workspace, doc)
     assert not [d for d in diags if d['code'] == 'W191']
     assert not [d for d in diags if d['code'] == 'E201']
     assert [d for d in diags if d['code'] == 'W391']
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-language-server-0.33.0/test/plugins/test_pylint_lint.py 
new/python-language-server-0.34.1/test/plugins/test_pylint_lint.py
--- old/python-language-server-0.33.0/test/plugins/test_pylint_lint.py  
2020-05-25 20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/test/plugins/test_pylint_lint.py  
2020-07-02 18:35:59.000000000 +0200
@@ -4,7 +4,6 @@
 import tempfile
 
 from test import py2_only, py3_only
-from test.test_utils import MockWorkspace
 from pyls import lsp, uris
 from pyls.workspace import Document
 from pyls.plugins import pylint_lint
@@ -24,13 +23,13 @@
 
 
 @contextlib.contextmanager
-def temp_document(doc_text):
+def temp_document(doc_text, workspace):
     try:
         temp_file = tempfile.NamedTemporaryFile(mode='w', delete=False)
         name = temp_file.name
         temp_file.write(doc_text)
         temp_file.close()
-        yield Document(uris.from_fs_path(name), MockWorkspace())
+        yield Document(uris.from_fs_path(name), workspace)
     finally:
         os.remove(name)
 
@@ -40,8 +39,8 @@
         temp_file.write(contents)
 
 
-def test_pylint(config):
-    with temp_document(DOC) as doc:
+def test_pylint(config, workspace):
+    with temp_document(DOC, workspace) as doc:
         diags = pylint_lint.pyls_lint(config, doc, True)
 
         msg = '[unused-import] Unused import sys'
@@ -52,8 +51,8 @@
 
 
 @py3_only
-def test_syntax_error_pylint_py3(config):
-    with temp_document(DOC_SYNTAX_ERR) as doc:
+def test_syntax_error_pylint_py3(config, workspace):
+    with temp_document(DOC_SYNTAX_ERR, workspace) as doc:
         diag = pylint_lint.pyls_lint(config, doc, True)[0]
 
         assert diag['message'].startswith('[syntax-error] invalid syntax')
@@ -63,8 +62,8 @@
 
 
 @py2_only
-def test_syntax_error_pylint_py2(config):
-    with temp_document(DOC_SYNTAX_ERR) as doc:
+def test_syntax_error_pylint_py2(config, workspace):
+    with temp_document(DOC_SYNTAX_ERR, workspace) as doc:
         diag = pylint_lint.pyls_lint(config, doc, True)[0]
 
         assert diag['message'].startswith('[syntax-error] invalid syntax')
@@ -81,7 +80,7 @@
         config, Document(uris.from_fs_path(__file__), workspace), True)
 
 
-def test_lint_caching():
+def test_lint_caching(workspace):
     # Pylint can only operate on files, not in-memory contents. We cache the
     # diagnostics after a run so we can continue displaying them until the file
     # is saved again.
@@ -92,7 +91,7 @@
     # file has capital letters in its name.
 
     flags = '--disable=invalid-name'
-    with temp_document(DOC) as doc:
+    with temp_document(DOC, workspace) as doc:
         # Start with a file with errors.
         diags = pylint_lint.PylintLinter.lint(doc, True, flags)
         assert diags
@@ -111,7 +110,7 @@
 
 def test_per_file_caching(config, workspace):
     # Ensure that diagnostics are cached per-file.
-    with temp_document(DOC) as doc:
+    with temp_document(DOC, workspace) as doc:
         assert pylint_lint.pyls_lint(config, doc, True)
 
     assert not pylint_lint.pyls_lint(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-language-server-0.33.0/test/plugins/test_rope_rename.py 
new/python-language-server-0.34.1/test/plugins/test_rope_rename.py
--- old/python-language-server-0.33.0/test/plugins/test_rope_rename.py  
2020-05-25 20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/test/plugins/test_rope_rename.py  
2020-07-02 18:35:59.000000000 +0200
@@ -31,6 +31,8 @@
     assert len(changes) == 1
     changes = changes[0]
 
+    # Note that this test differs from test_jedi_rename, because rope does not
+    # seem to modify files that haven't been opened with textDocument/didOpen.
     assert changes.get("edits") == [
         {
             "range": {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-language-server-0.33.0/test/plugins/test_symbols.py 
new/python-language-server-0.34.1/test/plugins/test_symbols.py
--- old/python-language-server-0.33.0/test/plugins/test_symbols.py      
2020-05-25 20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/test/plugins/test_symbols.py      
2020-07-02 18:35:59.000000000 +0200
@@ -2,7 +2,6 @@
 import os
 import sys
 
-from test.test_utils import MockWorkspace
 import pytest
 
 from pyls import uris
@@ -80,12 +79,12 @@
 
 
 @pytest.mark.skipif(PY2 or not LINUX or not CI, reason="tested on linux and 
python 3 only")
-def test_symbols_all_scopes_with_jedi_environment(config):
-    doc = Document(DOC_URI, MockWorkspace(), DOC)
+def test_symbols_all_scopes_with_jedi_environment(workspace):
+    doc = Document(DOC_URI, workspace, DOC)
 
     # Update config extra environment
     env_path = '/tmp/pyenv/bin/python'
-    config.update({'plugins': {'jedi': {'environment': env_path}}})
-    doc.update_config(config)
-    symbols = pyls_document_symbols(config, doc)
+    settings = {'pyls': {'plugins': {'jedi': {'environment': env_path}}}}
+    doc.update_config(settings)
+    symbols = pyls_document_symbols(doc._config, doc)
     helper_check_symbols_all_scope(symbols)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-language-server-0.33.0/test/test_utils.py 
new/python-language-server-0.34.1/test/test_utils.py
--- old/python-language-server-0.33.0/test/test_utils.py        2020-05-25 
20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/test/test_utils.py        2020-07-02 
18:35:59.000000000 +0200
@@ -1,26 +1,11 @@
 # Copyright 2017 Palantir Technologies, Inc.
 import time
-import sys
 
 import mock
 
 from pyls import _utils
 
 
-class MockWorkspace(object):
-    """Mock workspace used by tests that use jedi environment."""
-
-    def __init__(self):
-        """Mock workspace used by tests that use jedi environment."""
-        self._environments = {}
-
-        # This is to avoid pyling tests of the variable not being used
-        sys.stdout.write(str(self._environments))
-
-        # This necessary for the new Jedi 0.17+ API.
-        self.root_path = ''
-
-
 def test_debounce():
     interval = 0.1
     obj = mock.Mock()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-language-server-0.33.0/test/test_workspace.py 
new/python-language-server-0.34.1/test/test_workspace.py
--- old/python-language-server-0.33.0/test/test_workspace.py    2020-05-25 
20:16:20.000000000 +0200
+++ new/python-language-server-0.34.1/test/test_workspace.py    2020-07-02 
18:35:59.000000000 +0200
@@ -121,20 +121,20 @@
     assert workspace1_uri not in pyls.workspaces
 
 
-def test_multiple_workspaces_wrong_removed_uri(pyls):
-    workspace = {'uri': 'Test123'}
+def test_multiple_workspaces_wrong_removed_uri(pyls, tmpdir):
+    workspace = {'uri': str(tmpdir.mkdir('Test123'))}
     event = {'added': [], 'removed': [workspace]}
     pyls.m_workspace__did_change_workspace_folders(event)
     assert workspace['uri'] not in pyls.workspaces
 
 
-def test_root_workspace_changed(pyls):
-    test_uri = 'Test123'
+def test_root_workspace_changed(pyls, tmpdir):
+    test_uri = str(tmpdir.mkdir('Test123'))
     pyls.root_uri = test_uri
     pyls.workspace._root_uri = test_uri
 
     workspace1 = {'uri': test_uri}
-    workspace2 = {'uri': 'NewTest456'}
+    workspace2 = {'uri': str(tmpdir.mkdir('NewTest456'))}
 
     event = {'added': [workspace2], 'removed': [workspace1]}
     pyls.m_workspace__did_change_workspace_folders(event)
@@ -143,19 +143,19 @@
     assert workspace2['uri'] == pyls.root_uri
 
 
-def test_root_workspace_not_changed(pyls):
+def test_root_workspace_not_changed(pyls, tmpdir):
     # removed uri != root_uri
-    test_uri_1 = 'Test12'
+    test_uri_1 = str(tmpdir.mkdir('Test12'))
     pyls.root_uri = test_uri_1
     pyls.workspace._root_uri = test_uri_1
-    workspace1 = {'uri': 'Test1234'}
-    workspace2 = {'uri': 'NewTest456'}
+    workspace1 = {'uri': str(tmpdir.mkdir('Test1234'))}
+    workspace2 = {'uri': str(tmpdir.mkdir('NewTest456'))}
     event = {'added': [workspace2], 'removed': [workspace1]}
     pyls.m_workspace__did_change_workspace_folders(event)
     assert test_uri_1 == pyls.workspace._root_uri
     assert test_uri_1 == pyls.root_uri
     # empty 'added' list
-    test_uri_2 = 'Test123'
+    test_uri_2 = str(tmpdir.mkdir('Test123'))
     new_root_uri = workspace2['uri']
     pyls.root_uri = test_uri_2
     pyls.workspace._root_uri = test_uri_2
@@ -197,3 +197,47 @@
     # the root workspace
     assert pyls.root_uri == path_as_uri(str(workspace1_dir))
     assert pyls.workspace._root_uri == path_as_uri(str(workspace1_dir))
+
+
+def test_workspace_loads_pycodestyle_config(pyls, tmpdir):
+    workspace1_dir = tmpdir.mkdir('Test123')
+    pyls.root_uri = str(workspace1_dir)
+    pyls.workspace._root_uri = str(workspace1_dir)
+
+    # Test that project settings are loaded
+    workspace2_dir = tmpdir.mkdir('NewTest456')
+    cfg = workspace2_dir.join("pycodestyle.cfg")
+    cfg.write(
+        "[pycodestyle]\n"
+        "max-line-length = 1000"
+    )
+
+    workspace1 = {'uri': str(workspace1_dir)}
+    workspace2 = {'uri': str(workspace2_dir)}
+
+    event = {'added': [workspace2], 'removed': [workspace1]}
+    pyls.m_workspace__did_change_workspace_folders(event)
+
+    seetings = pyls.workspaces[str(workspace2_dir)]._config.settings()
+    assert seetings['plugins']['pycodestyle']['maxLineLength'] == 1000
+
+    # Test that project settings prevail over server ones.
+    server_settings = {'pyls': {'plugins': {'pycodestyle': {'maxLineLength': 
10}}}}
+    pyls.m_workspace__did_change_configuration(server_settings)
+    assert seetings['plugins']['pycodestyle']['maxLineLength'] == 1000
+
+    # Test switching to another workspace with different settings
+    workspace3_dir = tmpdir.mkdir('NewTest789')
+    cfg1 = workspace3_dir.join("pycodestyle.cfg")
+    cfg1.write(
+        "[pycodestyle]\n"
+        "max-line-length = 20"
+    )
+
+    workspace3 = {'uri': str(workspace3_dir)}
+
+    event = {'added': [workspace3], 'removed': [workspace2]}
+    pyls.m_workspace__did_change_workspace_folders(event)
+
+    seetings = pyls.workspaces[str(workspace3_dir)]._config.settings()
+    assert seetings['plugins']['pycodestyle']['maxLineLength'] == 20


Reply via email to