Skip to content

Commit

Permalink
Bump Python and CMake versions (#3878)
Browse files Browse the repository at this point in the history
Description of changes:
- bump CMake version requirement from 3.10 to 3.11 to get full support for imported targets
    * fixes a cryptic error message when compiling ESPResSo with FFTW3 using CMake 3.10
- bump Python version requirement from 3.5 to 3.6 (NEP 29, see drop table in #3421)
    * enables f-strings
- fix flaw in `espressomd.utils.check_type_or_throw_except()` that lead to subtle errors when arrays had the wrong size
- add tests for functions in `espressomd.utils`
  • Loading branch information
kodiakhq[bot] committed Aug 28, 2020
2 parents 79b53f6 + 0d258c4 commit 2c47221
Show file tree
Hide file tree
Showing 19 changed files with 161 additions and 85 deletions.
5 changes: 2 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.11)
message(STATUS "CMake version: ${CMAKE_VERSION}")
if(POLICY CMP0076)
# make target_sources() convert relative paths to absolute
Expand Down Expand Up @@ -166,7 +166,7 @@ if(WITH_CUDA)
endif()
endif(WITH_CUDA)

find_package(PythonInterp 3.5 REQUIRED)
find_package(PythonInterp 3.6 REQUIRED)

if(WITH_PYTHON)
find_package(Cython 0.26 REQUIRED)
Expand Down Expand Up @@ -278,7 +278,6 @@ endif(WITH_STOKESIAN_DYNAMICS)
if(WITH_STOKESIAN_DYNAMICS)
set(CMAKE_INSTALL_LIBDIR
"${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTDIR}/espressomd")
cmake_minimum_required(VERSION 3.11)
include(FetchContent)
FetchContent_Declare(
stokesian_dynamics
Expand Down
2 changes: 1 addition & 1 deletion src/python/espressomd/actors.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ cdef class Actor:
if k in self.valid_keys():
self._params[k] = kwargs[k]
else:
raise KeyError("%s is not a valid key" % k)
raise KeyError(f"{k} is not a valid key")

def _activate(self):
inter = self._get_interaction_type()
Expand Down
11 changes: 5 additions & 6 deletions src/python/espressomd/analyze.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -186,12 +186,12 @@ class Analysis:
for i in range(len(p1)):
if not is_valid_type(p1[i], int):
raise TypeError(
"Particle types in p1 have to be of type int, got: " + repr(p1[i]))
f"Particle types in p1 have to be of type int, got: {repr(p1[i])}")

for i in range(len(p2)):
if not is_valid_type(p2[i], int):
raise TypeError(
"Particle types in p2 have to be of type int, got: " + repr(p2[i]))
f"Particle types in p2 have to be of type int, got: {repr(p2[i])}")

return analyze.mindist(analyze.partCfg(), p1, p2)

Expand Down Expand Up @@ -249,7 +249,7 @@ class Analysis:
"The p_type keyword argument must be provided (particle type)")
check_type_or_throw_except(p_type, 1, int, "p_type has to be an int")
if p_type < 0 or p_type >= analyze.max_seen_particle_type:
raise ValueError("Particle type {} does not exist!".format(p_type))
raise ValueError(f"Particle type {p_type} does not exist!")

return analyze.centerofmass(analyze.partCfg(), p_type)

Expand Down Expand Up @@ -736,8 +736,7 @@ class Analysis:
check_type_or_throw_except(
ptype, 1, int, "particle type has to be an int")
if ptype < 0 or ptype >= analyze.max_seen_particle_type:
raise ValueError(
"Particle type {} does not exist!".format(ptype))
raise ValueError(f"Particle type {ptype} does not exist!")
selection = self._system.part.select(lambda p: (p.type in p_type))
cm = np.mean(selection.pos, axis=0)
mat = np.zeros(shape=(3, 3))
Expand Down Expand Up @@ -787,7 +786,7 @@ class Analysis:
"The p_type keyword argument must be provided (particle type)")
check_type_or_throw_except(p_type, 1, int, "p_type has to be an int")
if p_type < 0 or p_type >= analyze.max_seen_particle_type:
raise ValueError("Particle type {} does not exist!".format(p_type))
raise ValueError(f"Particle type {p_type} does not exist!")

analyze.momentofinertiamatrix(
analyze.partCfg(), p_type, MofImatrix)
Expand Down
4 changes: 2 additions & 2 deletions src/python/espressomd/cellsystem.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ cdef class CellSystem:

def __set__(self, _node_grid):
if not np.prod(_node_grid) == n_nodes:
raise ValueError("Number of available nodes " + str(
n_nodes) + " and imposed node grid " + str(_node_grid) + " do not agree.")
raise ValueError(
f"Number of available nodes {n_nodes} and imposed node grid {_node_grid} do not agree.")
else:
node_grid[0] = _node_grid[0]
node_grid[1] = _node_grid[1]
Expand Down
14 changes: 7 additions & 7 deletions src/python/espressomd/checkpointing.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def __init__(self, checkpoint_id=None, checkpoint_path="."):
# update checkpoint counter
self.counter = 0
while os.path.isfile(os.path.join(
self.checkpoint_dir, "{}.checkpoint".format(self.counter))):
self.checkpoint_dir, f"{self.counter}.checkpoint")):
self.counter += 1

# init signals
Expand Down Expand Up @@ -134,11 +134,11 @@ def register(self, *args):
# if not a in dir(self.calling_module):
if not self.__hasattr_submodule(self.calling_module, a):
raise KeyError(
"The given object '{}' was not found in the current scope.".format(a))
f"The given object '{a}' was not found in the current scope.")

if a in self.checkpoint_objects:
raise KeyError(
"The given object '{}' is already registered for checkpointing.".format(a))
f"The given object '{a}' is already registered for checkpointing.")

self.checkpoint_objects.append(a)

Expand All @@ -154,7 +154,7 @@ def unregister(self, *args):
for a in args:
if not isinstance(a, str) or a not in self.checkpoint_objects:
raise KeyError(
"The given object '{}' was not registered for checkpointing yet.".format(a))
f"The given object '{a}' was not registered for checkpointing yet.")

self.checkpoint_objects.remove(a)

Expand Down Expand Up @@ -204,7 +204,7 @@ def save(self, checkpoint_index=None):
if checkpoint_index is None:
checkpoint_index = self.counter
filename = os.path.join(
self.checkpoint_dir, "{}.checkpoint".format(checkpoint_index))
self.checkpoint_dir, f"{checkpoint_index}.checkpoint")

tmpname = filename + ".__tmp__"
with open(tmpname, "wb") as checkpoint_file:
Expand All @@ -226,7 +226,7 @@ def load(self, checkpoint_index=None):
checkpoint_index = self.get_last_checkpoint_index()

filename = os.path.join(
self.checkpoint_dir, "{}.checkpoint".format(checkpoint_index))
self.checkpoint_dir, f"{checkpoint_index}.checkpoint")
with open(filename, "rb") as f:
checkpoint_data = pickle.load(f)

Expand Down Expand Up @@ -288,7 +288,7 @@ def register_signal(self, signum=None):

if signum in self.checkpoint_signals:
raise KeyError(
"The signal {} is already registered for checkpointing.".format(signum))
f"The signal {signum} is already registered for checkpointing.")

signal.signal(signum, self.__signal_handler)
self.checkpoint_signals.append(signum)
Expand Down
2 changes: 1 addition & 1 deletion src/python/espressomd/collision_detection.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ class CollisionDetection(ScriptInterfaceHelper):
for key in self._int_mode:
if self._int_mode[key] == int_mode:
return key
raise Exception("Unknown integer collision mode %d" % int_mode)
raise Exception(f"Unknown integer collision mode {int_mode}")

# Pickle support
def __reduce__(self):
Expand Down
6 changes: 3 additions & 3 deletions src/python/espressomd/electrokinetics.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ IF ELECTROKINETICS:
return ElectrokineticsRoutines(np.array(key))
else:
raise Exception(
"%s is not a valid key. Should be a point on the nodegrid e.g. ek[0,0,0]," % key)
f"{key} is not a valid key. Should be a point on the nodegrid e.g. ek[0,0,0].")

def validate_params(self):
"""
Expand Down Expand Up @@ -431,7 +431,7 @@ IF ELECTROKINETICS:
return SpecieRoutines(np.array(key), self.id)
else:
raise Exception(
"%s is not a valid key. Should be a point on the nodegrid e.g. species[0,0,0]," % key)
f"{key} is not a valid key. Should be a point on the nodegrid e.g. species[0,0,0].")

def __init__(self, **kwargs):
Species.py_number_of_species += 1
Expand All @@ -449,7 +449,7 @@ IF ELECTROKINETICS:
if k in self.valid_keys():
self._params[k] = kwargs[k]
else:
raise KeyError("%s is not a valid key" % k)
raise KeyError(f"{k} is not a valid key")

def valid_keys(self):
"""
Expand Down
3 changes: 1 addition & 2 deletions src/python/espressomd/highlander.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ def __init__(self, cls):
self._cls = cls

def __str__(self):
return "There can only be one instance of '{}' at any time.".format(
self._cls)
return f"There can only be one instance of '{self._cls}' at any time."


def highlander(klass):
Expand Down
24 changes: 12 additions & 12 deletions src/python/espressomd/interactions.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1825,37 +1825,37 @@ class BondedInteractionNotDefined:
self.__class__.__name__ + " not compiled into ESPResSo core")

def type_number(self):
raise Exception(("%s has to be defined in myconfig.hpp.") % self.name)
raise Exception(f"{self.name} has to be defined in myconfig.hpp.")

def type_name(self):
"""Name of interaction type.
"""
raise Exception(("%s has to be defined in myconfig.hpp.") % self.name)
raise Exception(f"{self.name} has to be defined in myconfig.hpp.")

def valid_keys(self):
"""All parameters that can be set.
"""
raise Exception(("%s has to be defined in myconfig.hpp.") % self.name)
raise Exception(f"{self.name} has to be defined in myconfig.hpp.")

def required_keys(self):
"""Parameters that have to be set.
"""
raise Exception(("%s has to be defined in myconfig.hpp.") % self.name)
raise Exception(f"{self.name} has to be defined in myconfig.hpp.")

def set_default_params(self):
"""Sets parameters that are not required to their default value.
"""
raise Exception(("%s has to be defined in myconfig.hpp.") % self.name)
raise Exception(f"{self.name} has to be defined in myconfig.hpp.")

def _get_params_from_es_core(self):
raise Exception(("%s has to be defined in myconfig.hpp.") % self.name)
raise Exception(f"{self.name} has to be defined in myconfig.hpp.")

def _set_params_in_es_core(self):
raise Exception(("%s has to be defined in myconfig.hpp.") % self.name)
raise Exception(f"{self.name} has to be defined in myconfig.hpp.")


class FeneBond(BondedInteraction):
Expand Down Expand Up @@ -2591,8 +2591,8 @@ class TabulatedAngle(_TabulatedBase):
"""
phi = [self._params["min"], self._params["max"]]
if abs(phi[0] - 0.) > 1e-5 or abs(phi[1] - self.pi) > 1e-5:
raise ValueError("Tabulated angle expects forces/energies "
"within the range [0, pi], got " + str(phi))
raise ValueError(f"Tabulated angle expects forces/energies "
f"within the range [0, pi], got {phi}")


class TabulatedDihedral(_TabulatedBase):
Expand Down Expand Up @@ -2631,8 +2631,8 @@ class TabulatedDihedral(_TabulatedBase):
"""
phi = [self._params["min"], self._params["max"]]
if abs(phi[0] - 0.) > 1e-5 or abs(phi[1] - 2 * self.pi) > 1e-5:
raise ValueError("Tabulated dihedral expects forces/energies "
"within the range [0, 2*pi], got " + str(phi))
raise ValueError(f"Tabulated dihedral expects forces/energies "
f"within the range [0, 2*pi], got {phi}")


IF TABULATED == 1:
Expand Down Expand Up @@ -3313,7 +3313,7 @@ class BondedInteractions:
# Check if the bonded interaction exists in ESPResSo core
if bond_type == -1:
raise ValueError(
"The bonded interaction with the id " + str(key) + " is not yet defined.")
f"The bonded interaction with the id {key} is not yet defined.")

# Find the appropriate class representing such a bond
bond_class = bonded_interaction_classes[bond_type]
Expand Down
2 changes: 1 addition & 1 deletion src/python/espressomd/lb.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ cdef class HydrodynamicInteraction(Actor):
return LBFluidRoutines(np.array(key))
else:
raise Exception(
"%s is not a valid key. Should be a point on the nodegrid e.g. lbf[0,0,0]," % key)
f"{key} is not a valid key. Should be a point on the nodegrid e.g. lbf[0,0,0].")

# validate the given parameters on actor initialization
####################################################
Expand Down
Loading

0 comments on commit 2c47221

Please sign in to comment.