From ce836b5b74d830ba258ffe7d5f38ea0faf395cfe Mon Sep 17 00:00:00 2001 From: znapy <1570970+znapy@users.noreply.github.com> Date: Mon, 11 Mar 2024 16:30:37 +0000 Subject: [PATCH 1/4] refactoring: move the environment into a separate function and test it --- spyder/plugins/pylint/main_widget.py | 35 ++++++++++++---------- spyder/plugins/pylint/tests/test_pylint.py | 20 +++++++++++++ 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/spyder/plugins/pylint/main_widget.py b/spyder/plugins/pylint/main_widget.py index f3246dd08b7..eb82f0249a3 100644 --- a/spyder/plugins/pylint/main_widget.py +++ b/spyder/plugins/pylint/main_widget.py @@ -373,21 +373,7 @@ def _start(self): lambda ec, es=QProcess.ExitStatus: self._finished(ec, es)) command_args = self.get_command(self.get_filename()) - processEnvironment = QProcessEnvironment() - processEnvironment.insert("PYTHONIOENCODING", "utf8") - - if os.name == 'nt': - # Needed due to changes in Pylint 2.14.0 - # See spyder-ide/spyder#18175 - home_dir = get_home_dir() - user_profile = os.environ.get("USERPROFILE", home_dir) - processEnvironment.insert("USERPROFILE", user_profile) - # Needed for Windows installations using standalone Python and pip. - # See spyder-ide/spyder#19385 - if not is_conda_env(sys.prefix): - processEnvironment.insert("APPDATA", os.environ.get("APPDATA")) - - process.setProcessEnvironment(processEnvironment) + process.setProcessEnvironment(self.get_environment()) process.start(sys.executable, command_args) running = process.waitForStarted() if not running: @@ -946,6 +932,25 @@ def get_command(self, filename): command_args.append(filename) return command_args + @staticmethod + def get_environment() -> QProcessEnvironment: + """Get evironment variables for pylint command.""" + process_environment = QProcessEnvironment() + process_environment.insert("PYTHONIOENCODING", "utf8") + + if os.name == 'nt': + # Needed due to changes in Pylint 2.14.0 + # See spyder-ide/spyder#18175 + home_dir = get_home_dir() + user_profile = os.environ.get("USERPROFILE", home_dir) + process_environment.insert("USERPROFILE", user_profile) + # Needed for Windows installations using standalone Python and pip. + # See spyder-ide/spyder#19385 + if not is_conda_env(sys.prefix): + process_environment.insert("APPDATA", os.environ.get("APPDATA")) + + return process_environment + def parse_output(self, output): """ Parse output and return current revious rate and results. diff --git a/spyder/plugins/pylint/tests/test_pylint.py b/spyder/plugins/pylint/tests/test_pylint.py index da8b79500a2..8f11aa30672 100644 --- a/spyder/plugins/pylint/tests/test_pylint.py +++ b/spyder/plugins/pylint/tests/test_pylint.py @@ -9,6 +9,7 @@ # Standard library imports from io import open +import os import os.path as osp import sys from unittest.mock import Mock, MagicMock @@ -335,5 +336,24 @@ def test_custom_interpreter(pylint_plugin, tmp_path, qtbot, assert errors +def test_get_environment(mocker): + """Test that the environment variables depend on the OS.""" + if os.name == 'nt': + mocker.patch("spyder.plugins.pylint.main_widget.is_conda_based_app", + return_value=False) + mocker.patch("spyder.plugins.pylint.main_widget.is_anaconda", + return_value=False) + mocker.patch("spyder.plugins.pylint.main_widget.get_home_dir", + return_value='') + + etalon = { + "nt": ["APPDATA", "PYTHONIOENCODING", "USERPROFILE"], + "posix": ["PYTHONIOENCODING"]} + + process_environment = Pylint.WIDGET_CLASS.get_environment() + + assert process_environment.keys() == etalon[os.name] + + if __name__ == "__main__": pytest.main([osp.basename(__file__), '-vv', '-rw']) From f995ad7fd91a9d4628715513c519861ed43eaa22 Mon Sep 17 00:00:00 2001 From: znapy <1570970+znapy@users.noreply.github.com> Date: Wed, 24 Apr 2024 09:12:25 +0000 Subject: [PATCH 2/4] pylint: add the pythonpath environment from pythonpath-manager --- spyder/plugins/pylint/main_widget.py | 13 +++++++++++-- spyder/plugins/pylint/tests/test_pylint.py | 7 ++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/spyder/plugins/pylint/main_widget.py b/spyder/plugins/pylint/main_widget.py index eb82f0249a3..de1cd333557 100644 --- a/spyder/plugins/pylint/main_widget.py +++ b/spyder/plugins/pylint/main_widget.py @@ -373,7 +373,10 @@ def _start(self): lambda ec, es=QProcess.ExitStatus: self._finished(ec, es)) command_args = self.get_command(self.get_filename()) - process.setProcessEnvironment(self.get_environment()) + pythonpath_manager_values = self.get_conf( + 'spyder_pythonpath', default=[], section='pythonpath_manager') + process.setProcessEnvironment( + self.get_environment(pythonpath_manager_values)) process.start(sys.executable, command_args) running = process.waitForStarted() if not running: @@ -933,11 +936,17 @@ def get_command(self, filename): return command_args @staticmethod - def get_environment() -> QProcessEnvironment: + def get_environment(pythonpath_manager_values: list + ) -> QProcessEnvironment: """Get evironment variables for pylint command.""" process_environment = QProcessEnvironment() process_environment.insert("PYTHONIOENCODING", "utf8") + if pythonpath_manager_values: + pypath = os.pathsep.join(pythonpath_manager_values) + # See PR spyder-ide/spyder#21891 + process_environment.insert("PYTHONPATH", pypath) + if os.name == 'nt': # Needed due to changes in Pylint 2.14.0 # See spyder-ide/spyder#18175 diff --git a/spyder/plugins/pylint/tests/test_pylint.py b/spyder/plugins/pylint/tests/test_pylint.py index 8f11aa30672..144ec6112ac 100644 --- a/spyder/plugins/pylint/tests/test_pylint.py +++ b/spyder/plugins/pylint/tests/test_pylint.py @@ -347,10 +347,11 @@ def test_get_environment(mocker): return_value='') etalon = { - "nt": ["APPDATA", "PYTHONIOENCODING", "USERPROFILE"], - "posix": ["PYTHONIOENCODING"]} + "nt": ["APPDATA", "PYTHONIOENCODING", "PYTHONPATH", "USERPROFILE"], + "posix": ["PYTHONIOENCODING", "PYTHONPATH"]} - process_environment = Pylint.WIDGET_CLASS.get_environment() + process_environment = Pylint.WIDGET_CLASS.get_environment( + pythonpath_manager_values=["project_dir"]) assert process_environment.keys() == etalon[os.name] From a460e7080de877cc7aeb29d2d3fbfa9f5804d9b4 Mon Sep 17 00:00:00 2001 From: alic <1570970+znapy@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:54:10 +0300 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: Carlos Cordoba --- spyder/plugins/pylint/main_widget.py | 15 +++++++---- spyder/plugins/pylint/tests/test_pylint.py | 30 ++++++++++++++-------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/spyder/plugins/pylint/main_widget.py b/spyder/plugins/pylint/main_widget.py index de1cd333557..d88bbafc922 100644 --- a/spyder/plugins/pylint/main_widget.py +++ b/spyder/plugins/pylint/main_widget.py @@ -374,9 +374,11 @@ def _start(self): command_args = self.get_command(self.get_filename()) pythonpath_manager_values = self.get_conf( - 'spyder_pythonpath', default=[], section='pythonpath_manager') + 'spyder_pythonpath', default=[], section='pythonpath_manager' + ) process.setProcessEnvironment( - self.get_environment(pythonpath_manager_values)) + self.get_environment(pythonpath_manager_values) + ) process.start(sys.executable, command_args) running = process.waitForStarted() if not running: @@ -936,8 +938,9 @@ def get_command(self, filename): return command_args @staticmethod - def get_environment(pythonpath_manager_values: list - ) -> QProcessEnvironment: + def get_environment( + pythonpath_manager_values: list + ) -> QProcessEnvironment: """Get evironment variables for pylint command.""" process_environment = QProcessEnvironment() process_environment.insert("PYTHONIOENCODING", "utf8") @@ -956,7 +959,9 @@ def get_environment(pythonpath_manager_values: list # Needed for Windows installations using standalone Python and pip. # See spyder-ide/spyder#19385 if not is_conda_env(sys.prefix): - process_environment.insert("APPDATA", os.environ.get("APPDATA")) + process_environment.insert( + "APPDATA", os.environ.get("APPDATA") + ) return process_environment diff --git a/spyder/plugins/pylint/tests/test_pylint.py b/spyder/plugins/pylint/tests/test_pylint.py index 144ec6112ac..e755dff0190 100644 --- a/spyder/plugins/pylint/tests/test_pylint.py +++ b/spyder/plugins/pylint/tests/test_pylint.py @@ -339,21 +339,29 @@ def test_custom_interpreter(pylint_plugin, tmp_path, qtbot, def test_get_environment(mocker): """Test that the environment variables depend on the OS.""" if os.name == 'nt': - mocker.patch("spyder.plugins.pylint.main_widget.is_conda_based_app", - return_value=False) - mocker.patch("spyder.plugins.pylint.main_widget.is_anaconda", - return_value=False) - mocker.patch("spyder.plugins.pylint.main_widget.get_home_dir", - return_value='') - - etalon = { + mocker.patch( + "spyder.plugins.pylint.main_widget.is_conda_based_app", + return_value=False + ) + mocker.patch( + "spyder.plugins.pylint.main_widget.is_anaconda", + return_value=False + ) + mocker.patch( + "spyder.plugins.pylint.main_widget.get_home_dir", + return_value='' + ) + + expected_vars = { "nt": ["APPDATA", "PYTHONIOENCODING", "PYTHONPATH", "USERPROFILE"], - "posix": ["PYTHONIOENCODING", "PYTHONPATH"]} + "posix": ["PYTHONIOENCODING", "PYTHONPATH"] + } process_environment = Pylint.WIDGET_CLASS.get_environment( - pythonpath_manager_values=["project_dir"]) + pythonpath_manager_values=["project_dir"] + ) - assert process_environment.keys() == etalon[os.name] + assert process_environment.keys() == expected_vars[os.name] if __name__ == "__main__": From ec7d5e464732cc2e155a4f2ccf96bfd712404c34 Mon Sep 17 00:00:00 2001 From: znapy <1570970+znapy@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:47:32 +0000 Subject: [PATCH 4/4] fix test for windows environment --- spyder/plugins/pylint/tests/test_pylint.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/spyder/plugins/pylint/tests/test_pylint.py b/spyder/plugins/pylint/tests/test_pylint.py index e755dff0190..d03b39e9e1d 100644 --- a/spyder/plugins/pylint/tests/test_pylint.py +++ b/spyder/plugins/pylint/tests/test_pylint.py @@ -340,11 +340,7 @@ def test_get_environment(mocker): """Test that the environment variables depend on the OS.""" if os.name == 'nt': mocker.patch( - "spyder.plugins.pylint.main_widget.is_conda_based_app", - return_value=False - ) - mocker.patch( - "spyder.plugins.pylint.main_widget.is_anaconda", + "spyder.plugins.pylint.main_widget.is_conda_env", return_value=False ) mocker.patch(