diff --git a/news/deprecate-parser-1.rst b/news/deprecate-parser-1.rst new file mode 100644 index 0000000..f6d7b3f --- /dev/null +++ b/news/deprecate-parser-1.rst @@ -0,0 +1,40 @@ +**Added:** + +* Added ``parse_lines`` method in ``p_auto.py`` +* Added ``parse_lines`` method in ``p_cif.py`` +* Added ``parse_lines`` method in ``p_discus.py`` +* Added ``parse_lines`` method in ``p_pdb.py`` +* Added ``parse_lines`` method in ``p_pdffit.py`` +* Added ``parse_lines`` method in ``p_rawxyz.py`` +* Added ``parse_lines`` method in ``p_xcfg.py`` +* Added ``parse_lines`` method in ``p_xyz.py`` +* Added ``parse_lines`` method in ``structureparser.py`` +* Added ``_suppress_cif_parser_output`` method in ``p_cif.py`` + +**Changed:** + +* + +**Deprecated:** + +* Deprecated ``parseLines`` method in ``p_auto.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_cif.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_discus.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_pdb.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_pdffit.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_rawxyz.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_xcfg.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``p_xyz.py`` for removal in version 4.0.0 +* Deprecated ``parseLines`` method in ``structureparser.py`` for removal in version 4.0.0 + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/src/diffpy/structure/parsers/p_auto.py b/src/diffpy/structure/parsers/p_auto.py index 681bb84..5d861f2 100644 --- a/src/diffpy/structure/parsers/p_auto.py +++ b/src/diffpy/structure/parsers/p_auto.py @@ -18,9 +18,20 @@ """ import os +from typing import Any from diffpy.structure.parsers import StructureParser, parser_index from diffpy.structure.structureerrors import StructureFormatError +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure.P_auto" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) class P_auto(StructureParser): @@ -76,7 +87,16 @@ def _get_ordered_formats(self): ofmts.insert(0, fmt) return ofmts + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_auto.parse_lines instead. + """ + return self.parse_lines(lines) + + def parse_lines(self, lines): """Detect format and create `Structure` instance from a list of lines. @@ -96,7 +116,7 @@ def parseLines(self, lines): ------ StructureFormatError """ - return self._wrap_parse_method("parseLines", lines) + return self._wrap_parse_method("parse_lines", lines) def parse(self, s): """Detect format and create `Structure` instance from a string. @@ -145,7 +165,7 @@ def parseFile(self, filename): self.filename = filename return self._wrap_parse_method("parseFile", filename) - def _wrap_parse_method(self, method, *args, **kwargs): + def _wrap_parse_method(self, method: object, *args: object, **kwargs: object) -> Any: """A helper evaluator method that try the specified parse method with each registered structure parser and return the first successful result. diff --git a/src/diffpy/structure/parsers/p_cif.py b/src/diffpy/structure/parsers/p_cif.py index 6086039..d3b3348 100644 --- a/src/diffpy/structure/parsers/p_cif.py +++ b/src/diffpy/structure/parsers/p_cif.py @@ -37,10 +37,21 @@ from diffpy.structure import Atom, Lattice, Structure from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError +from diffpy.utils._deprecator import build_deprecation_message, deprecated # ---------------------------------------------------------------------------- +base = "diffpy.structure.P_cif" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) + + class P_cif(StructureParser): """Simple parser for CIF structure format. @@ -330,7 +341,17 @@ def parse(self, s): rv = self._parseCifDataSource(fp) return rv + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_cif.parse_lines instead. + """ + return self.parse_lines(lines) + + @deprecated(parseLines_deprecation_msg) + def parse_lines(self, lines): """Parse list of lines in CIF format. Parameters @@ -400,7 +421,7 @@ def _parseCifDataSource(self, datasource): self.stru = None try: - with _suppressCifParserOutput(): + with _suppress_cif_parser_output(): # Use `grammar` option to digest values with curly-brackets. # Ref: https://bitbucket.org/jamesrhester/pycifrw/issues/19 self.ciffile = CifFile(datasource, grammar="auto") @@ -871,7 +892,7 @@ def getParser(eps=None): @contextmanager -def _suppressCifParserOutput(): +def _suppress_cif_parser_output(): """Context manager which suppresses diagnostic messages from CIF parser.""" from CifFile import yapps3_compiled_rt diff --git a/src/diffpy/structure/parsers/p_discus.py b/src/diffpy/structure/parsers/p_discus.py index 8039c7c..e239b16 100644 --- a/src/diffpy/structure/parsers/p_discus.py +++ b/src/diffpy/structure/parsers/p_discus.py @@ -134,6 +134,81 @@ def parseLines(self, lines): raise e.with_traceback(exc_traceback) return self.stru + def parse_lines(self, lines): + """Parse list of lines in DISCUS format. + + Parameters + ---------- + lines : list of str + List of lines from the input file. + + Returns + ------- + PDFFitStructure + Parsed `PDFFitStructure` instance. + + Raises + ------ + StructureFormatError + If the file is not in DISCUS format. + """ + self.lines = lines + ilines = self._linesIterator() + self.stru = PDFFitStructure() + record_parsers = { + "cell": self._parse_cell, + "format": self._parse_format, + "generator": self._parse_not_implemented, + "molecule": self._parse_not_implemented, + "ncell": self._parse_ncell, + "spcgr": self._parse_spcgr, + "symmetry": self._parse_not_implemented, + "title": self._parse_title, + "shape": self._parse_shape, + } + try: + # parse header + for self.line in ilines: + words = self.line.split() + if not words or words[0][0] == "#": + continue + if words[0] == "atoms": + break + rp = record_parsers.get(words[0], self._parse_unknown_record) + rp(words) + # check if cell has been defined + if not self.cell_read: + emsg = "%d: unit cell not defined" % self.nl + raise StructureFormatError(emsg) + # parse atoms + for self.line in ilines: + words = self.line.replace(",", " ").split() + if not words or words[0][0] == "#": + continue + self._parse_atom(words) + # self consistency check + exp_natoms = reduce(lambda x, y: x * y, self.stru.pdffit["ncell"]) + # only check if ncell record exists + if self.ncell_read and exp_natoms != len(self.stru): + emsg = "Expected %d atoms, read %d." % ( + exp_natoms, + len(self.stru), + ) + raise StructureFormatError(emsg) + # take care of superlattice + if self.stru.pdffit["ncell"][:3] != [1, 1, 1]: + latpars = list(self.stru.lattice.abcABG()) + superlatpars = [latpars[i] * self.stru.pdffit["ncell"][i] for i in range(3)] + latpars[3:] + superlattice = Lattice(*superlatpars) + self.stru.place_in_lattice(superlattice) + self.stru.pdffit["ncell"] = [1, 1, 1, exp_natoms] + except (ValueError, IndexError): + exc_type, exc_value, exc_traceback = sys.exc_info() + emsg = "%d: file is not in DISCUS format" % self.nl + e = StructureFormatError(emsg) + raise e.with_traceback(exc_traceback) + return self.stru + def toLines(self, stru): """Convert `Structure` stru to a list of lines in DISCUS format. diff --git a/src/diffpy/structure/parsers/p_pdb.py b/src/diffpy/structure/parsers/p_pdb.py index 7dc2f32..2264157 100644 --- a/src/diffpy/structure/parsers/p_pdb.py +++ b/src/diffpy/structure/parsers/p_pdb.py @@ -29,6 +29,16 @@ from diffpy.structure import Structure from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure.P_pdb" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) class P_pdb(StructureParser): @@ -111,7 +121,16 @@ def __init__(self): self.format = "pdb" return + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_pdb.parse_lines instead. + """ + return self.parse_lines(lines) + + def parse_lines(self, lines): """Parse list of lines in PDB format. Parameters diff --git a/src/diffpy/structure/parsers/p_pdffit.py b/src/diffpy/structure/parsers/p_pdffit.py index 822a8e2..d35f18a 100644 --- a/src/diffpy/structure/parsers/p_pdffit.py +++ b/src/diffpy/structure/parsers/p_pdffit.py @@ -22,6 +22,16 @@ from diffpy.structure import Lattice, PDFFitStructure from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure.P_pdffit" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) class P_pdffit(StructureParser): @@ -44,7 +54,16 @@ def __init__(self): self.stru = None return + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_pdffit.parse_lines instead. + """ + return self.parse_lines(lines) + + def parse_lines(self, lines): """Parse list of lines in PDFfit format. Parameters diff --git a/src/diffpy/structure/parsers/p_rawxyz.py b/src/diffpy/structure/parsers/p_rawxyz.py index ab28ec4..a3af581 100644 --- a/src/diffpy/structure/parsers/p_rawxyz.py +++ b/src/diffpy/structure/parsers/p_rawxyz.py @@ -24,6 +24,16 @@ from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.utils import isfloat +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure.P_rawxyz" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) class P_rawxyz(StructureParser): @@ -40,7 +50,16 @@ def __init__(self): self.format = "rawxyz" return + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_rawxyz.parse_lines instead. + """ + return self.parse_lines(lines) + + def parse_lines(self, lines): """Parse list of lines in RAWXYZ format. Parameters diff --git a/src/diffpy/structure/parsers/p_xcfg.py b/src/diffpy/structure/parsers/p_xcfg.py index ee62629..e8cfec6 100644 --- a/src/diffpy/structure/parsers/p_xcfg.py +++ b/src/diffpy/structure/parsers/p_xcfg.py @@ -29,6 +29,7 @@ from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError from diffpy.structure.utils import isfloat +from diffpy.utils._deprecator import build_deprecation_message, deprecated # Constants ------------------------------------------------------------------ @@ -151,6 +152,15 @@ # ---------------------------------------------------------------------------- +base = "diffpy.structure.P_xcfg" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) + class P_xcfg(StructureParser): """Parser for AtomEye extended CFG format. @@ -171,7 +181,16 @@ def __init__(self): self.format = "xcfg" return + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_xcfg.parse_lines instead. + """ + return self.parse_lines(lines) + + def parse_lines(self, lines): """Parse list of lines in XCFG format. Parameters diff --git a/src/diffpy/structure/parsers/p_xyz.py b/src/diffpy/structure/parsers/p_xyz.py index a91c431..a13af70 100644 --- a/src/diffpy/structure/parsers/p_xyz.py +++ b/src/diffpy/structure/parsers/p_xyz.py @@ -24,6 +24,16 @@ from diffpy.structure import Structure from diffpy.structure.parsers import StructureParser from diffpy.structure.structureerrors import StructureFormatError +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure.P_xyz" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) class P_xyz(StructureParser): @@ -40,7 +50,16 @@ def __init__(self): self.format = "xyz" return + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.P_xyz.parse_lines instead. + """ + return self.parse_lines(lines) + + def parse_lines(self, lines): """Parse list of lines in XYZ format. Parameters diff --git a/src/diffpy/structure/parsers/structureparser.py b/src/diffpy/structure/parsers/structureparser.py index f785b52..45eb204 100644 --- a/src/diffpy/structure/parsers/structureparser.py +++ b/src/diffpy/structure/parsers/structureparser.py @@ -14,6 +14,17 @@ ############################################################################## """Definition of StructureParser, a base class for specific parsers.""" +from diffpy.utils._deprecator import build_deprecation_message, deprecated + +base = "diffpy.structure.StructureParser" +removal_version = "4.0.0" +parseLines_deprecation_msg = build_deprecation_message( + base, + "parseLines", + "parse_lines", + removal_version, +) + class StructureParser(object): """Base class for all structure parsers. @@ -31,7 +42,16 @@ def __init__(self): self.filename = None return + @deprecated(parseLines_deprecation_msg) def parseLines(self, lines): + """This function has been deprecated and will be removed in + version 4.0.0. + + Please use diffpy.structure.StructureParser.parse_lines instead. + """ + return self.parse_lines(lines) + + def parse_lines(self, lines): """Create Structure instance from a list of lines. Return Structure object or raise StructureFormatError exception. @@ -40,7 +60,7 @@ def parseLines(self, lines): ---- This method has to be overloaded in derived class. """ - raise NotImplementedError("parseLines not defined for '%s' format" % self.format) + raise NotImplementedError("parse lines not defined for '%s' format" % self.format) return def toLines(self, stru): diff --git a/tests/test_p_cif.py b/tests/test_p_cif.py index 4558c39..e0c4a40 100644 --- a/tests/test_p_cif.py +++ b/tests/test_p_cif.py @@ -114,6 +114,22 @@ def test_parseLines(self): self.assertRaises(StructureFormatError, ptest2.parseLines, badlines) return + def test_parse_lines(self): + """Check P_cif.parseLines()""" + with open(self.pbteciffile) as fp1: + goodlines = fp1.readlines() + with open(self.badciffile) as fp2: + badlines = fp2.readlines() + pfile, ptest = self.pfile, self.ptest + stru_check = pfile.parseFile(self.pbteciffile) + stru = ptest.parse_lines(goodlines) + self.assertEqual(str(stru_check), str(stru)) + self.assertEqual(str(stru_check.lattice), str(stru.lattice)) + self.assertEqual(pfile.spacegroup.short_name, ptest.spacegroup.short_name) + ptest2 = P_cif() + self.assertRaises(StructureFormatError, ptest2.parse_lines, badlines) + return + def test_parseFile(self): """Check P_cif.parseFile()""" # pbteciffile