From 412879ff16a0aa5a1a16ae349ab51bf4002fcf86 Mon Sep 17 00:00:00 2001 From: Sylvain MARIE Date: Tue, 23 Jul 2019 17:54:08 +0200 Subject: [PATCH 1/3] Now raising more user-friendly exceptions when they happen during a command execution. Fixes #5 --- pymake/__init__.py | 4 ++-- pymake/_pymake.py | 25 +++++++++++++++++++++++-- pymake/tests/tests_main.py | 4 ++-- setup.py | 2 +- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/pymake/__init__.py b/pymake/__init__.py index 0406938..01e822f 100644 --- a/pymake/__init__.py +++ b/pymake/__init__.py @@ -1,7 +1,7 @@ from ._main import main from ._version import __version__ # NOQA from ._pymake import __author__, \ - PymakeTypeError, PymakeKeyError + PymakeTypeError, PymakeKeyError, CmdExecutionError __all__ = ['main', '__version__', '__author__', - 'PymakeTypeError', 'PymakeKeyError'] + 'PymakeTypeError', 'PymakeKeyError', 'CmdExecutionError'] diff --git a/pymake/_pymake.py b/pymake/_pymake.py index fdd21c8..5254a14 100644 --- a/pymake/_pymake.py +++ b/pymake/_pymake.py @@ -3,6 +3,7 @@ """ from __future__ import absolute_import # import compatibility functions and utilities +from six import raise_from from ._utils import ConfigParser, StringIO, shlex import io import re @@ -109,6 +110,24 @@ def parse_makefile_aliases(filepath): return commands, default_alias +class CmdExecutionError(Exception): + """ + Exception raised when a command execution returned an error. + + Instead of the cause being set as the python __cause__, it is hidden + and only the final message is displayed, together with the command. + """ + __slots__ = 'cause', 'parsed_cmd' + + def __init__(self, parsed_cmd, cause): + super(CmdExecutionError, self).__init__() + self.cause = cause + self.parsed_cmd = parsed_cmd + + def __str__(self): + return "Error executing CMD '%s': %s" % (self.parsed_cmd, self.cause) + + def execute_makefile_commands( commands, alias, silent=False, just_print=False, ignore_errors=False): """ @@ -141,6 +160,8 @@ def execute_makefile_commands( # Launch the command and wait to finish (synchronized call) try: check_call(parsed_cmd) - except: + except Exception as e: + # Raise a user-friendly exception if not ignore_errors: - raise + raise_from(CmdExecutionError(' '.join(parsed_cmd), e), + None) diff --git a/pymake/tests/tests_main.py b/pymake/tests/tests_main.py index 800fd17..b3bb4d3 100644 --- a/pymake/tests/tests_main.py +++ b/pymake/tests/tests_main.py @@ -1,7 +1,7 @@ import sys import subprocess from os import path -from pymake import main, PymakeKeyError, PymakeTypeError +from pymake import main, PymakeKeyError, PymakeTypeError, CmdExecutionError dn = path.dirname fname = path.join(dn(dn(dn(path.abspath(__file__)))), @@ -64,7 +64,7 @@ def test_ignore_errors(): """Test --ignore-errors""" try: main(['-s', '-f', fname, 'err']) - except OSError: + except CmdExecutionError: pass # test passed if file not found else: raise PymakeTypeError('err') diff --git a/setup.py b/setup.py index f332a2d..4662973 100755 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ maintainer_email='python.tqdm@gmail.com', platforms=['any'], packages=['pymake'], - install_requires=['docopt>=0.6.0'], + install_requires=['docopt>=0.6.0', 'six'], entry_points={'console_scripts': ['pymake=pymake._main:main'], }, package_data={'py-make': ['CONTRIBUTE', 'LICENCE', 'examples/*.py', 'examples/Makefile*']}, From e859333c18863fb236aee98f536de5a8a3c18e44 Mon Sep 17 00:00:00 2001 From: Sylvain MARIE Date: Wed, 24 Jul 2019 10:39:33 +0200 Subject: [PATCH 2/3] Minor update to increase coverage again --- pymake/tests/tests_main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pymake/tests/tests_main.py b/pymake/tests/tests_main.py index b3bb4d3..41047fe 100644 --- a/pymake/tests/tests_main.py +++ b/pymake/tests/tests_main.py @@ -64,8 +64,8 @@ def test_ignore_errors(): """Test --ignore-errors""" try: main(['-s', '-f', fname, 'err']) - except CmdExecutionError: - pass # test passed if file not found + except CmdExecutionError as e: + assert "Error executing CMD" in str(e) # test passed if file not found else: raise PymakeTypeError('err') From 26028a8f92d625f296faf7f50fe25033ee9207a3 Mon Sep 17 00:00:00 2001 From: Casper da Costa-Luis Date: Fri, 23 Aug 2019 04:22:03 +0100 Subject: [PATCH 3/3] make six optional --- pymake/_pymake.py | 8 +++----- pymake/_utils.py | 23 +++++++++++++++++++++++ setup.py | 2 +- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/pymake/_pymake.py b/pymake/_pymake.py index 5254a14..c8eb91c 100644 --- a/pymake/_pymake.py +++ b/pymake/_pymake.py @@ -3,8 +3,7 @@ """ from __future__ import absolute_import # import compatibility functions and utilities -from six import raise_from -from ._utils import ConfigParser, StringIO, shlex +from ._utils import ConfigParser, StringIO, shlex, raise_from import io import re from subprocess import check_call @@ -114,8 +113,8 @@ class CmdExecutionError(Exception): """ Exception raised when a command execution returned an error. - Instead of the cause being set as the python __cause__, it is hidden - and only the final message is displayed, together with the command. + The python __cause__ is hidden, + and only the command and final message is displayed. """ __slots__ = 'cause', 'parsed_cmd' @@ -161,7 +160,6 @@ def execute_makefile_commands( try: check_call(parsed_cmd) except Exception as e: - # Raise a user-friendly exception if not ignore_errors: raise_from(CmdExecutionError(' '.join(parsed_cmd), e), None) diff --git a/pymake/_utils.py b/pymake/_utils.py index 09b5259..6939364 100644 --- a/pymake/_utils.py +++ b/pymake/_utils.py @@ -20,6 +20,29 @@ except NameError: _unicode = str + try: + from six import raise_from + except ImportError: + if sys.version_info[:2] == (3, 2): + exec("""def raise_from(value, from_value): + try: + if from_value is None: + raise value + raise value from from_value + finally: + value = None + """) + elif sys.version_info[:2] > (3, 2): + exec("""def raise_from(value, from_value): + try: + raise value from from_value + finally: + value = None + """) + else: + def raise_from(value, from_value): + raise value + if sys.version_info >= (2, 7): # pragma: no cover import shlex else: # pragma: no cover diff --git a/setup.py b/setup.py index 4662973..f332a2d 100755 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ maintainer_email='python.tqdm@gmail.com', platforms=['any'], packages=['pymake'], - install_requires=['docopt>=0.6.0', 'six'], + install_requires=['docopt>=0.6.0'], entry_points={'console_scripts': ['pymake=pymake._main:main'], }, package_data={'py-make': ['CONTRIBUTE', 'LICENCE', 'examples/*.py', 'examples/Makefile*']},