From ffe2a14432431005c89a7e5e12655c0fb614f9a4 Mon Sep 17 00:00:00 2001 From: Luthaf Date: Wed, 24 Aug 2022 16:48:56 +0200 Subject: [PATCH] Drop support for Python <3.7 --- .github/workflows/tests.yml | 2 +- examples/indexes.py | 2 +- src/chemfiles/__init__.py | 3 --- src/chemfiles/_c_lib.py | 1 - src/chemfiles/atom.py | 25 +++++++---------- src/chemfiles/cell.py | 7 +---- src/chemfiles/frame.py | 25 +++++++---------- src/chemfiles/misc.py | 54 +++++++++++++------------------------ src/chemfiles/property.py | 12 +++------ src/chemfiles/residue.py | 17 ++++++------ src/chemfiles/selection.py | 5 +--- src/chemfiles/topology.py | 18 ++++--------- src/chemfiles/trajectory.py | 26 ++++-------------- src/chemfiles/utils.py | 11 +------- tests/_utils.py | 2 -- tests/atom.py | 3 --- tests/cell.py | 3 --- tests/examples.py | 3 --- tests/frame.py | 3 --- tests/misc.py | 3 --- tests/property.py | 3 --- tests/residue.py | 3 --- tests/selection.py | 3 --- tests/topology.py | 3 --- tests/trajectory.py | 3 --- 25 files changed, 63 insertions(+), 177 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4edbbc4a..ee296a11 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: os: [ubuntu-20.04] - python-version: ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10"] + python-version: ["3.7", "3.8", "3.9", "3.10"] include: - os: windows-2019 python-version: "3.8" diff --git a/examples/indexes.py b/examples/indexes.py index cb2d8b3d..85b58d2a 100644 --- a/examples/indexes.py +++ b/examples/indexes.py @@ -14,4 +14,4 @@ print("Atoms with x < 5: ") for i in less_than_five: - print(" - {}".format(i)) + print(f" - {i}") diff --git a/src/chemfiles/__init__.py b/src/chemfiles/__init__.py index fb3d9fc3..4ded9680 100644 --- a/src/chemfiles/__init__.py +++ b/src/chemfiles/__init__.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - from .atom import Atom from .cell import CellShape, UnitCell from .frame import Frame diff --git a/src/chemfiles/_c_lib.py b/src/chemfiles/_c_lib.py index 6d6f9238..edc637fe 100644 --- a/src/chemfiles/_c_lib.py +++ b/src/chemfiles/_c_lib.py @@ -1,4 +1,3 @@ -# -* coding: utf-8 -* import os import sys from ctypes import POINTER, c_double, cdll diff --git a/src/chemfiles/atom.py b/src/chemfiles/atom.py index 008ec19c..84bc46f3 100644 --- a/src/chemfiles/atom.py +++ b/src/chemfiles/atom.py @@ -1,11 +1,8 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - from ctypes import c_char_p, c_double, c_uint64 from .misc import ChemfilesError from .property import Property -from .utils import CxxPointer, _call_with_growing_buffer, string_type +from .utils import CxxPointer, _call_with_growing_buffer class Atom(CxxPointer): @@ -38,12 +35,10 @@ def __copy__(self): return Atom.from_mutable_ptr(None, self.ffi.chfl_atom_copy(self.ptr)) def __repr__(self): - name = self.name - type = self.type - if type == name: - return "Atom('{}')".format(name) + if self.type == self.name: + return f"Atom('{self.name}')" else: - return "Atom('{}', '{}')".format(name, type) + return f"Atom('{self.name}', '{self.type}')" @property def mass(self): @@ -150,10 +145,11 @@ def __getitem__(self, name): Get a property of this atom with the given ``name``, or raise an error if the property does not exists. """ - if not isinstance(name, string_type): + if not isinstance(name, str): raise ChemfilesError( - "Invalid type {} for an atomic property name".format(type(name)) + f"Invalid type {type(name)} for an atomic property name" ) + ptr = self.ffi.chfl_atom_get_property(self.ptr, name.encode("utf8")) return Property.from_mutable_ptr(self, ptr).get() @@ -162,10 +158,9 @@ def __setitem__(self, name, value): Set a property of this atom, with the given ``name`` and ``value``. The new value overwrite any pre-existing property with the same name. """ - if not isinstance(name, string_type): - raise ChemfilesError( - "invalid type {} for a property name".format(type(name)) - ) + if not isinstance(name, str): + raise ChemfilesError(f"invalid type {type(name)} for a property name") + property = Property(value) self.ffi.chfl_atom_set_property(self.mut_ptr, name.encode("utf8"), property.ptr) diff --git a/src/chemfiles/cell.py b/src/chemfiles/cell.py index b708a360..a2227601 100644 --- a/src/chemfiles/cell.py +++ b/src/chemfiles/cell.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - from ctypes import ARRAY, c_double from enum import IntEnum @@ -63,9 +60,7 @@ def __init__(self, lengths, angles=(90.0, 90.0, 90.0)): else: if lengths.shape != (3, 3): raise ChemfilesError( - "expected the cell matrix to have 3x3 shape, got {}".format( - lengths.shape - ) + f"expected the cell matrix to have 3x3 shape, got {lengths.shape}" ) matrix = ARRAY(chfl_vector3d, (3))() matrix[0][0] = lengths[0, 0] diff --git a/src/chemfiles/frame.py b/src/chemfiles/frame.py index a2efc9b2..3ad6d107 100644 --- a/src/chemfiles/frame.py +++ b/src/chemfiles/frame.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - from ctypes import POINTER, c_bool, c_char_p, c_double, c_uint64 import numpy as np @@ -11,7 +8,7 @@ from .misc import ChemfilesError from .property import Property from .topology import Topology -from .utils import CxxPointer, string_type +from .utils import CxxPointer class FrameAtoms(object): @@ -32,9 +29,7 @@ def __getitem__(self, index): associated :py:class:`Frame`. """ if index >= len(self): - raise IndexError( - "atom index ({}) out of range for this frame".format(index) - ) + raise IndexError(f"atom index ({index}) out of range for this frame") else: ptr = self.frame.ffi.chfl_atom_from_frame( self.frame.mut_ptr, c_uint64(index) @@ -68,7 +63,7 @@ def __copy__(self): return Frame.from_mutable_ptr(None, self.ffi.chfl_frame_copy(self.ptr)) def __repr__(self): - return "Frame with {} atoms".format(len(self.atoms)) + return f"Frame with {len(self.atoms)} atoms" @property def atoms(self): @@ -325,10 +320,9 @@ def __getitem__(self, name): Get a property of this frame with the given ``name``, or raise an error if the property does not exists. """ - if not isinstance(name, string_type): - raise ChemfilesError( - "Invalid type {} for a frame property name".format(type(name)) - ) + if not isinstance(name, str): + raise ChemfilesError(f"Invalid type {type(name)} for a frame property name") + ptr = self.ffi.chfl_frame_get_property(self.ptr, name.encode("utf8")) return Property.from_mutable_ptr(self, ptr).get() @@ -337,10 +331,9 @@ def __setitem__(self, name, value): Set a property of this frame, with the given ``name`` and ``value``. The new value overwrite any pre-existing property with the same name. """ - if not isinstance(name, string_type): - raise ChemfilesError( - "Invalid type {} for a frame property name".format(type(name)) - ) + if not isinstance(name, str): + raise ChemfilesError(f"Invalid type {type(name)} for a frame property name") + property = Property(value) self.ffi.chfl_frame_set_property( self.mut_ptr, name.encode("utf8"), property.ptr diff --git a/src/chemfiles/misc.py b/src/chemfiles/misc.py index 5da04929..ecd5788b 100644 --- a/src/chemfiles/misc.py +++ b/src/chemfiles/misc.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - import warnings from ctypes import POINTER, c_uint64, create_string_buffer @@ -82,43 +79,28 @@ def _set_from_c(self, c_format_metadata): self.residues = c_format_metadata.residues def __repr__(self): - return """ -FormatMetadata for {name} --------------------{name_underline} -{description} + return f""" +FormatMetadata for {self.name} +-------------------{"-" * len(self.name)} +{self.description} -name = {name} -extension = {extension} -reference = {reference} +name = {self.name} +extension = {self.extension} +reference = {self.reference} Capacities: ----------- -read = {read} -write = {write} -memory = {memory} -positions = {positions} -velocities = {velocities} -unit_cell = {unit_cell} -atoms = {atoms} -bonds = {bonds} -residues = {residues} -""".format( - name=self.name, - name_underline="-" * len(self.name), - description=self.description, - extension=self.extension, - reference=self.reference, - read=self.read, - write=self.write, - memory=self.memory, - positions=self.positions, - velocities=self.velocities, - unit_cell=self.unit_cell, - atoms=self.atoms, - bonds=self.bonds, - residues=self.residues, - ) +read = {self.read} +write = {self.write} +memory = {self.memory} +positions = {self.positions} +velocities = {self.velocities} +unit_cell = {self.unit_cell} +atoms = {self.atoms} +bonds = {self.bonds} +residues = {self.residues} +""" def formats_list(): @@ -162,7 +144,7 @@ def callback(message): try: function(message.decode("utf8")) except Exception as e: - message = "exception raised in warning callback: {}".format(e) + message = f"exception raised in warning callback: {e}" warnings.warn(message, ChemfilesWarning) global _CURRENT_CALLBACK diff --git a/src/chemfiles/property.py b/src/chemfiles/property.py index d4849916..b0853fbc 100644 --- a/src/chemfiles/property.py +++ b/src/chemfiles/property.py @@ -1,14 +1,10 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - -import sys from ctypes import c_bool, c_double import numpy as np from ._c_api import chfl_property_kind, chfl_vector3d from .misc import ChemfilesError -from .utils import CxxPointer, _call_with_growing_buffer, string_type +from .utils import CxxPointer, _call_with_growing_buffer class Property(CxxPointer): @@ -26,16 +22,14 @@ def __init__(self, value): ptr = self.ffi.chfl_property_bool(c_bool(value)) elif isinstance(value, (float, int)): ptr = self.ffi.chfl_property_double(c_double(value)) - elif isinstance(value, string_type): + elif isinstance(value, str): ptr = self.ffi.chfl_property_string(value.encode("utf8")) elif _is_vector3d(value): value = chfl_vector3d(value[0], value[1], value[2]) ptr = self.ffi.chfl_property_vector3d(value) else: raise ChemfilesError( - "can not create a Property with a value of type '{}'".format( - type(value) - ) + f"can not create a Property with a value of type '{type(value)}'" ) super(Property, self).__init__(ptr, is_const=False) diff --git a/src/chemfiles/residue.py b/src/chemfiles/residue.py index 1996fa68..75ff1dc3 100644 --- a/src/chemfiles/residue.py +++ b/src/chemfiles/residue.py @@ -1,13 +1,10 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - from ctypes import c_bool, c_char_p, c_int64, c_uint64 import numpy as np from .misc import ChemfilesError from .property import Property -from .utils import CxxPointer, _call_with_growing_buffer, string_type +from .utils import CxxPointer, _call_with_growing_buffer class ResidueAtoms(object): @@ -90,7 +87,7 @@ def __copy__(self): return Residue.from_mutable_ptr(None, self.ffi.chfl_residue_copy(self.ptr)) def __repr__(self): - return "Residue('{}') with {} atoms".format(self.name, len(self.atoms)) + return f"Residue('{self.name}') with {len(self.atoms)} atoms" @property def name(self): @@ -120,10 +117,11 @@ def __getitem__(self, name): Get a property of this residude with the given ``name``, or raise an error if the property does not exists. """ - if not isinstance(name, string_type): + if not isinstance(name, str): raise ChemfilesError( - "Invalid type {} for a residue property name".format(type(name)) + f"Invalid type {type(name)} for a residue property name" ) + ptr = self.ffi.chfl_residue_get_property(self.ptr, name.encode("utf8")) return Property.from_mutable_ptr(self, ptr).get() @@ -132,10 +130,11 @@ def __setitem__(self, name, value): Set a property of this residue, with the given ``name`` and ``value``. The new value overwrite any pre-existing property with the same name. """ - if not isinstance(name, string_type): + if not isinstance(name, str): raise ChemfilesError( - "Invalid type {} for a residue property name".format(type(name)) + f"Invalid type {type(name)} for a residue property name" ) + property = Property(value) self.ffi.chfl_residue_set_property( self.mut_ptr, name.encode("utf8"), property.ptr diff --git a/src/chemfiles/selection.py b/src/chemfiles/selection.py index 79eb80b1..4994185a 100644 --- a/src/chemfiles/selection.py +++ b/src/chemfiles/selection.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - from ctypes import c_uint64 import numpy as np @@ -33,7 +30,7 @@ def __copy__(self): return Selection.from_mutable_ptr(None, self.ffi.chfl_selection_copy(self.ptr)) def __repr__(self): - return "Selection('{}')".format(self.string) + return f"Selection('{self.string}')" @property def size(self): diff --git a/src/chemfiles/topology.py b/src/chemfiles/topology.py index 93b2ba13..3b8a9de7 100644 --- a/src/chemfiles/topology.py +++ b/src/chemfiles/topology.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - from ctypes import c_bool, c_uint64 from enum import IntEnum @@ -54,9 +51,7 @@ def __getitem__(self, index): associated :py:class:`Topology`. """ if index >= len(self): - raise IndexError( - "atom index ({}) out of range for this topology".format(index) - ) + raise IndexError(f"atom index ({index}) out of range for this topology") else: ptr = self.topology.ffi.chfl_atom_from_topology( self.topology.mut_ptr, c_uint64(index) @@ -110,9 +105,7 @@ def __getitem__(self, index): topology does not necessarily match the residue id. """ if index >= len(self): - raise IndexError( - "residue index ({}) out of range for this topology".format(index) - ) + raise IndexError(f"residue index ({index}) out of range for this topology") else: ptr = self.topology.ffi.chfl_residue_from_topology( self.topology.ptr, c_uint64(index) @@ -151,7 +144,7 @@ def __copy__(self): return Topology.from_mutable_ptr(None, self.ffi.chfl_topology_copy(self.ptr)) def __repr__(self): - return "Topology with {} atoms".format(len(self.atoms)) + return f"Topology with {len(self.atoms)} atoms" @property def atoms(self): @@ -186,9 +179,8 @@ def residue_for_atom(self, index): atom is not part of a residue. """ if index >= len(self.atoms): - raise IndexError( - "residue index ({}) out of range for this topology".format(index) - ) + raise IndexError(f"residue index ({index}) out of range for this topology") + ptr = self.ffi.chfl_residue_for_atom(self.ptr, c_uint64(index)) if ptr: return Residue.from_const_ptr(self, ptr) diff --git a/src/chemfiles/trajectory.py b/src/chemfiles/trajectory.py index cb1b83cc..1773c864 100644 --- a/src/chemfiles/trajectory.py +++ b/src/chemfiles/trajectory.py @@ -1,21 +1,9 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - -import sys from ctypes import c_char_p, c_uint64 from .frame import Frame, Topology from .misc import ChemfilesError from .utils import CxxPointer, _call_with_growing_buffer -# Python 2 compatibility -if sys.hexversion >= 0x03000000: - unicode_string = str - bytes_string = bytes -else: - unicode_string = unicode # noqa - bytes_string = str - class BaseTrajectory(CxxPointer): def __init__(self, ptr): @@ -156,9 +144,7 @@ def __init__(self, path, mode="r", format=""): super(Trajectory, self).__init__(ptr) def __repr__(self): - return "Trajectory('{}', '{}', '{}')".format( - self.path, self.__mode, self.__format - ) + return f"Trajectory('{self.path}', '{self.__mode}', '{self.__format}')" class MemoryTrajectory(BaseTrajectory): @@ -185,9 +171,9 @@ def __init__(self, data="", mode="r", format=""): ) if mode == "r": - if isinstance(data, unicode_string): + if isinstance(data, str): data = data.encode("utf8") - elif not isinstance(data, bytes_string): + elif not isinstance(data, bytes): raise ChemfilesError("the 'data' parameter must be a string") ptr = self.ffi.chfl_trajectory_memory_reader( @@ -196,14 +182,12 @@ def __init__(self, data="", mode="r", format=""): elif mode == "w": ptr = self.ffi.chfl_trajectory_memory_writer(format.encode("utf8")) else: - raise ChemfilesError( - "invalid mode '{}' passed to MemoryTrajectory".format(mode) - ) + raise ChemfilesError(f"invalid mode '{mode}' passed to MemoryTrajectory") super(MemoryTrajectory, self).__init__(ptr) def __repr__(self): - return "MemoryTrajectory({}', '{}')".format(self.__mode, self.__format) + return f"MemoryTrajectory({self.__mode}', '{self.__format}')" def buffer(self): """ diff --git a/src/chemfiles/utils.py b/src/chemfiles/utils.py index e0153524..59584194 100644 --- a/src/chemfiles/utils.py +++ b/src/chemfiles/utils.py @@ -1,17 +1,8 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - -import sys from ctypes import c_uint64, create_string_buffer from ._c_lib import _get_c_library from .misc import ChemfilesError, _last_error -if sys.version_info >= (3, 0): - string_type = str -else: - string_type = basestring - class CxxPointer(object): # Used to prevent adding new attributes to chemfiles objects @@ -41,7 +32,7 @@ def __del__(self): def __setattr__(self, key, value): if self.__frozen and not hasattr(self, key): raise TypeError( - "Can not add new attributes to this {}".format(self.__class__.__name__) + f"Can not add new attributes to this {self.__class__.__name__}" ) object.__setattr__(self, key, value) diff --git a/tests/_utils.py b/tests/_utils.py index 1726ec64..546eaeee 100644 --- a/tests/_utils.py +++ b/tests/_utils.py @@ -1,5 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals import chemfiles diff --git a/tests/atom.py b/tests/atom.py index 5953b49a..9013ac28 100644 --- a/tests/atom.py +++ b/tests/atom.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - import copy import unittest diff --git a/tests/cell.py b/tests/cell.py index 0dac1867..f85f2430 100644 --- a/tests/cell.py +++ b/tests/cell.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - import copy import unittest diff --git a/tests/examples.py b/tests/examples.py index ce2792e1..7f33b3fa 100644 --- a/tests/examples.py +++ b/tests/examples.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - import os import shutil import tempfile diff --git a/tests/frame.py b/tests/frame.py index 58a96996..4caa943b 100644 --- a/tests/frame.py +++ b/tests/frame.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - import copy import math import unittest diff --git a/tests/misc.py b/tests/misc.py index f97b9d56..0a6c1452 100644 --- a/tests/misc.py +++ b/tests/misc.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - import unittest import warnings diff --git a/tests/property.py b/tests/property.py index 4a128103..63be6dba 100644 --- a/tests/property.py +++ b/tests/property.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - import copy import unittest diff --git a/tests/residue.py b/tests/residue.py index c839e751..57ff8fec 100644 --- a/tests/residue.py +++ b/tests/residue.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - import copy import unittest diff --git a/tests/selection.py b/tests/selection.py index 7b70cbff..a890257a 100644 --- a/tests/selection.py +++ b/tests/selection.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - import copy import unittest diff --git a/tests/topology.py b/tests/topology.py index 5b85a9a2..60551cf5 100644 --- a/tests/topology.py +++ b/tests/topology.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - import copy import unittest diff --git a/tests/trajectory.py b/tests/trajectory.py index c2d3c718..f738b7d8 100644 --- a/tests/trajectory.py +++ b/tests/trajectory.py @@ -1,6 +1,3 @@ -# -*- coding=utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals - import os import unittest