From 655207200a64ce7fab7a29317061b4dcd9daceba Mon Sep 17 00:00:00 2001 From: Ben Zwick Date: Thu, 20 Dec 2018 22:28:50 +0800 Subject: [PATCH 1/2] Ensure that a unique problem module exists before importing This fixes unexpected behaviour that occurs if a problem module exists in more than one location or if a problem module throws an exception during import. Previously, there were two things that could go wrong: 1. The problem module is defined in both the examples directory and the current directory in which case the user might be unaware that the example problem takes precedence over the one in the current directory. 2. If the module exists but raises an exception during import then that exception is caught and an attempt is made to import the module from the current directory instead. Further exceptions are then caught and a RuntimeError is raised which (misleadingly) informs the user that the module could not be found. --- oasis/NSCoupled.py | 23 ++++++++++++++++------- oasis/NSfracStep.py | 22 ++++++++++++++++------ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/oasis/NSCoupled.py b/oasis/NSCoupled.py index 468de910..e8285105 100755 --- a/oasis/NSCoupled.py +++ b/oasis/NSCoupled.py @@ -25,15 +25,24 @@ commandline_kwargs = parse_command_line() +# Import the problem module default_problem = 'DrivenCavity' -#exec('from problems.NSCoupled.{} import *'.format(commandline_kwargs.get('problem', default_problem))) problemname = commandline_kwargs.get('problem', default_problem) -try: - problemmod = importlib.import_module('.'.join(('oasis.problems.NSCoupled', problemname))) -except ImportError: - problemmod = importlib.import_module(problemname) -except: - raise RuntimeError(problemname+' not found') +# Check if problem module exists in example problems directory and/or current directory +problemspec1 = importlib.util.find_spec('.'.join(('oasis.problems.NSCoupled', problemname))) +problemspec2 = importlib.util.find_spec(problemname) +if problemspec1 and problemspec2: + raise RuntimeError(problemname+" found in example problems directory AND current directory (ambiguous).") +elif problemspec1: + problemspec = problemspec1 + print("Found problem '"+problemname+"' in example problems directory.") +elif problemspec2: + problemspec = problemspec2 + print("Found problem '"+problemname+"' in current directory.") +else: + raise RuntimeError("Problem '"+problemname+"' not found.") +problemmod = importlib.util.module_from_spec(problemspec) +problemspec.loader.exec_module(problemmod) vars().update(**vars(problemmod)) diff --git a/oasis/NSfracStep.py b/oasis/NSfracStep.py index a8eb0349..638e11ec 100755 --- a/oasis/NSfracStep.py +++ b/oasis/NSfracStep.py @@ -37,14 +37,24 @@ commandline_kwargs = parse_command_line() +# Import the problem module default_problem = 'DrivenCavity' problemname = commandline_kwargs.get('problem', default_problem) -try: - problemmod = importlib.import_module('.'.join(('oasis.problems.NSfracStep', problemname))) -except ImportError: - problemmod = importlib.import_module(problemname) -except: - raise RuntimeError(problemname+' not found') +# Check if problem module exists in example problems directory and/or current directory +problemspec1 = importlib.util.find_spec('.'.join(('oasis.problems.NSfracStep', problemname))) +problemspec2 = importlib.util.find_spec(problemname) +if problemspec1 and problemspec2: + raise RuntimeError(problemname+" found in example problems directory AND current directory (ambiguous).") +elif problemspec1: + problemspec = problemspec1 + print("Found problem '"+problemname+"' in example problems directory.") +elif problemspec2: + problemspec = problemspec2 + print("Found problem '"+problemname+"' in current directory.") +else: + raise RuntimeError("Problem '"+problemname+"' not found.") +problemmod = importlib.util.module_from_spec(problemspec) +problemspec.loader.exec_module(problemmod) vars().update(**vars(problemmod)) From 4c0360ef5c6e10c799fae4a923d3bc34f5b25c01 Mon Sep 17 00:00:00 2001 From: Ben Zwick Date: Fri, 21 Dec 2018 20:19:49 +0800 Subject: [PATCH 2/2] Simplify problem module import The previous commit didn't consider the case where a problem module is found on Python's path elsewhere than the problems directory or the current directory. Instead of checking if multiple problem modules are found; simply print the origin of the module that is imported. In the future (Python >= 3.7) we could use ModuleNotFoundError instead. --- oasis/NSCoupled.py | 23 +++++++++-------------- oasis/NSfracStep.py | 23 +++++++++-------------- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/oasis/NSCoupled.py b/oasis/NSCoupled.py index e8285105..f7e7fae5 100755 --- a/oasis/NSCoupled.py +++ b/oasis/NSCoupled.py @@ -25,22 +25,17 @@ commandline_kwargs = parse_command_line() -# Import the problem module +# Find the problem module default_problem = 'DrivenCavity' problemname = commandline_kwargs.get('problem', default_problem) -# Check if problem module exists in example problems directory and/or current directory -problemspec1 = importlib.util.find_spec('.'.join(('oasis.problems.NSCoupled', problemname))) -problemspec2 = importlib.util.find_spec(problemname) -if problemspec1 and problemspec2: - raise RuntimeError(problemname+" found in example problems directory AND current directory (ambiguous).") -elif problemspec1: - problemspec = problemspec1 - print("Found problem '"+problemname+"' in example problems directory.") -elif problemspec2: - problemspec = problemspec2 - print("Found problem '"+problemname+"' in current directory.") -else: - raise RuntimeError("Problem '"+problemname+"' not found.") +problemspec = importlib.util.find_spec('.'.join(('oasis.problems.NSCoupled', problemname))) +if problemspec is None: + problemspec = importlib.util.find_spec(problemname) +if problemspec is None: + raise RuntimeError(problemname+' not found') + +# Import the problem module +print('Importing problem module '+problemname+':\n'+problemspec.origin) problemmod = importlib.util.module_from_spec(problemspec) problemspec.loader.exec_module(problemmod) diff --git a/oasis/NSfracStep.py b/oasis/NSfracStep.py index 638e11ec..800bbcf8 100755 --- a/oasis/NSfracStep.py +++ b/oasis/NSfracStep.py @@ -37,22 +37,17 @@ commandline_kwargs = parse_command_line() -# Import the problem module +# Find the problem module default_problem = 'DrivenCavity' problemname = commandline_kwargs.get('problem', default_problem) -# Check if problem module exists in example problems directory and/or current directory -problemspec1 = importlib.util.find_spec('.'.join(('oasis.problems.NSfracStep', problemname))) -problemspec2 = importlib.util.find_spec(problemname) -if problemspec1 and problemspec2: - raise RuntimeError(problemname+" found in example problems directory AND current directory (ambiguous).") -elif problemspec1: - problemspec = problemspec1 - print("Found problem '"+problemname+"' in example problems directory.") -elif problemspec2: - problemspec = problemspec2 - print("Found problem '"+problemname+"' in current directory.") -else: - raise RuntimeError("Problem '"+problemname+"' not found.") +problemspec = importlib.util.find_spec('.'.join(('oasis.problems.NSfracStep', problemname))) +if problemspec is None: + problemspec = importlib.util.find_spec(problemname) +if problemspec is None: + raise RuntimeError(problemname+' not found') + +# Import the problem module +print('Importing problem module '+problemname+':\n'+problemspec.origin) problemmod = importlib.util.module_from_spec(problemspec) problemspec.loader.exec_module(problemmod)