Skip to content

Commit

Permalink
BREAKING: glossary_v2.py: raise Error exception instead of `log.criti…
Browse files Browse the repository at this point in the history
…cal` and `return None`
  • Loading branch information
ilius committed Oct 5, 2024
1 parent df97b9d commit 38f8f91
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 232 deletions.
13 changes: 11 additions & 2 deletions pyglossary/glossary.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
# with this program. Or on Debian systems, from /usr/share/common-licenses/GPL
# If not, see <http://www.gnu.org/licenses/gpl.txt>.

from os.path import relpath
from time import perf_counter as now
from typing import TYPE_CHECKING

from .core import log
from .glossary_v2 import ConvertArgs, Error, GlossaryCommon
from .glossary_v2 import ConvertArgs, Error, GlossaryCommon, ReadError, WriteError
from .sort_keys import lookupSortKey

if TYPE_CHECKING:
Expand Down Expand Up @@ -186,6 +187,14 @@ def convert( # noqa: PLR0913
infoOverride=infoOverride,
),
)
except ReadError as e:
log.critical(str(e))
log.critical(f"Reading file {relpath(inputFilename)!r} failed.")
except WriteError as e:
log.critical(str(e))
log.critical(f"Writing file {relpath(outputFilename)!r} failed.")
except Error as e:
log.critical(str(e))
return None

self.cleanup()
return None
9 changes: 8 additions & 1 deletion pyglossary/glossary_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,18 @@
MAX_EXT_LEN = 4 # FIXME



class Error(Exception):
pass


class ReadError(Error):
pass


class WriteError(Error):
pass


def splitFilenameExt(
filename: str = "",
) -> "tuple[str, str, str, str]":
Expand Down
110 changes: 35 additions & 75 deletions pyglossary/glossary_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
GlossaryType,
RawEntryType,
)
from .glossary_utils import Error, splitFilenameExt
from .glossary_utils import Error, ReadError, WriteError, splitFilenameExt
from .info import c_name
from .os_utils import rmtree, showMemoryUsage
from .plugin_manager import PluginManager
Expand Down Expand Up @@ -199,6 +199,7 @@ def __init__(
self.setInfo(key, value)

def cleanup(self) -> None:
self._closeReaders()
if not self._cleanupPathList:
return
if not self._config.get("cleanup", True):
Expand Down Expand Up @@ -639,8 +640,7 @@ def _createReader(
) -> "Any":
readerClass = self.plugins[format].readerClass
if readerClass is None:
log.critical("_createReader: readerClass is None")
return None
raise ReadError("_createReader: readerClass is None")
reader = readerClass(self)
for name, value in options.items():
setattr(reader, f"_{name}", value)
Expand Down Expand Up @@ -680,7 +680,7 @@ def _validateReadoptions(
)
del options[key]

def _openReader(self, reader: "Any", filename: str) -> bool:
def _openReader(self, reader: "Any", filename: str):
# reader.open returns "Iterator[tuple[int, int]] | None"
progressbar: bool = self.progressbar
try:
Expand All @@ -694,19 +694,14 @@ def _openReader(self, reader: "Any", filename: str) -> bool:
lastPos = pos
self.progressEnd()
except (FileNotFoundError, LookupError) as e:
log.critical(str(e))
return False
except Exception:
log.exception("")
return False
raise ReadError(str(e)) from e

hasTitleStr = self._info.get("definition_has_headwords", "")
if hasTitleStr:
if hasTitleStr.lower() == "true":
self._defiHasWordTitle = True
else:
log.error(f"bad info value: definition_has_headwords={hasTitleStr!r}")
return True

def directRead(
self,
Expand Down Expand Up @@ -756,8 +751,7 @@ def _read(
self.updateEntryFilters()

reader = self._createReader(format, options)
if not self._openReader(reader, filename):
return False
self._openReader(reader, filename)

self._readOptions = options

Expand Down Expand Up @@ -799,8 +793,7 @@ def _createWriter(
) -> "Any":
validOptions = self.formatsWriteOptions.get(format)
if validOptions is None:
log.critical(f"No write support for {format!r} format")
return None
raise WriteError(f"No write support for {format!r} format")
validOptionKeys = list(validOptions.keys())
for key in list(options.keys()):
if key not in validOptionKeys:
Expand All @@ -811,8 +804,7 @@ def _createWriter(

writerClass = self.plugins[format].writerClass
if writerClass is None:
log.critical("_createWriter: writerClass is None")
return None
raise WriteError("_createWriter: writerClass is None")
writer = writerClass(self)
for name, value in options.items():
setattr(writer, f"_{name}", value)
Expand All @@ -823,7 +815,7 @@ def write(
filename: str,
format: str,
**kwargs,
) -> "str | None":
) -> str:
"""
Write to a given glossary file, with given format (optional).
Return absolute path of output file, or None if failed.
Expand Down Expand Up @@ -891,29 +883,23 @@ def _writeEntries(
def _openWriter(
writer: "Any",
filename: str,
) -> bool:
):
try:
writer.open(filename)
except (FileNotFoundError, LookupError) as e:
log.critical(str(e))
return False
except Exception:
log.exception("")
return False
return True
raise WriteError(str(e)) from e

def _write(
self,
filename: str,
format: str,
sort: bool = False,
**options,
) -> "str | None":
) -> str:
filename = os.path.abspath(filename)

if format not in self.plugins or not self.plugins[format].canWrite:
log.critical(f"No Writer class found for plugin {format}")
return None
raise WriteError(f"No Writer class found for plugin {format}")

if self._readers and sort:
log.warning(
Expand All @@ -938,20 +924,15 @@ def _write(
self._iter = self._readersEntryGen()
else:
self._iter = self._loadedEntryGen()
if not self._openWriter(writer, filename):
return None
self._openWriter(writer, filename)

showMemoryUsage()

writerList = [writer]
try:
self._writeEntries(writerList, filename)
except (FileNotFoundError, LookupError) as e:
log.critical(str(e))
return None
except Exception:
log.exception("Exception while calling plugin's write function")
return None
raise WriteError(str(e)) from e
finally:
showMemoryUsage()
log.debug("Running writer.finish()")
Expand Down Expand Up @@ -983,17 +964,13 @@ def _switchToSQLite(
log.info(f"Removing and re-creating {sq_fpath!r}")
os.remove(sq_fpath)

try:
self._data = SqEntryList(
entryToRaw=self._entryToRaw,
entryFromRaw=self._entryFromRaw,
filename=sq_fpath,
create=True,
persist=True,
)
except Exception:
log.exception("Failed to create SQLite file")
return
self._data = SqEntryList(
entryToRaw=self._entryToRaw,
entryFromRaw=self._entryFromRaw,
filename=sq_fpath,
create=True,
persist=True,
)
self._cleanupPathList.add(sq_fpath)

if not self.alts:
Expand All @@ -1007,7 +984,7 @@ def _switchToSQLite(
def _checkSortFlag(
plugin: "PluginProp",
sort: "bool | None",
) -> "bool | None":
) -> bool:
sortOnWrite = plugin.sortOnWrite
if sortOnWrite == ALWAYS:
if sort is False:
Expand Down Expand Up @@ -1035,11 +1012,11 @@ def _resolveSortParams(
self,
args: ConvertArgs,
plugin: "PluginProp",
) -> "tuple[bool, bool] | None":
) -> "tuple[bool, bool]":
"""
sortKeyName: see doc/sort-key.md.
returns (sort, direct) or None if fails
returns (sort, direct)
"""
if args.direct and args.sqlite:
raise ValueError(
Expand Down Expand Up @@ -1069,8 +1046,6 @@ def _resolveSortParams(
args.sortKeyName,
args.sortEncoding,
)
if sortKeyTuple is None:
return None
namedSortKey, sortEncoding = sortKeyTuple

if sqlite:
Expand All @@ -1091,17 +1066,16 @@ def _checkSortKey(
plugin: "PluginProp",
sortKeyName: "str | None",
sortEncoding: "str | None",
) -> "tuple[NamedSortKey, str] | None":
) -> "tuple[NamedSortKey, str]":
"""
Check sortKeyName, sortEncoding and (output) plugin's params
returns (namedSortKey, sortEncoding) or None.
returns (namedSortKey, sortEncoding).
"""
writerSortKeyName = plugin.sortKeyName
writerSortEncoding = getattr(plugin, "sortEncoding", None)
if plugin.sortOnWrite == ALWAYS:
if not writerSortKeyName:
log.critical("No sortKeyName was found in plugin")
return None
raise Error("No sortKeyName was found in plugin")

if sortKeyName and sortKeyName != writerSortKeyName:
log.warning(
Expand All @@ -1117,8 +1091,7 @@ def _checkSortKey(

namedSortKey = lookupSortKey(sortKeyName)
if namedSortKey is None:
log.critical(f"invalid {sortKeyName = }")
return None
raise Error(f"invalid {sortKeyName = }")

log.info(f"Using sortKeyName = {namedSortKey.name!r}")

Expand Down Expand Up @@ -1146,19 +1119,16 @@ def _convertPrepare(
outputFormat: str = "",
) -> "bool | None":
if isdir(outputFilename) and os.listdir(outputFilename):
log.critical(
raise Error(
f"Directory already exists and not empty: {relpath(outputFilename)}",
)
return None

outputPlugin = self.plugins[outputFormat]

sortParams = self._resolveSortParams(
args=args,
plugin=outputPlugin,
)
if sortParams is None:
return None
direct, sort = sortParams

showMemoryUsage()
Expand All @@ -1167,21 +1137,18 @@ def _convertPrepare(

readOptions = args.readOptions or {}

if not self._read(
self._read(
args.inputFilename,
format=args.inputFormat,
direct=direct,
**readOptions,
):
log.critical(f"Reading file {relpath(args.inputFilename)!r} failed.")
self.cleanup()
return None
)

self.detectLangsFromName()

return sort

def convertV2(self, args: ConvertArgs) -> "str | None":
def convertV2(self, args: ConvertArgs) -> str:
"""
Return absolute path of output file, or None if failed.
Expand All @@ -1198,8 +1165,7 @@ def convertV2(self, args: ConvertArgs) -> "str | None":
"""
self._convertValidateStrings(args)
if args.outputFilename == args.inputFilename:
log.critical("Input and output files are the same")
return None
raise Error("Input and output files are the same")

tm0 = now()

Expand All @@ -1209,8 +1175,7 @@ def convertV2(self, args: ConvertArgs) -> "str | None":
inputFilename=args.inputFilename,
)
if not outputArgs:
log.critical(f"Writing file {relpath(args.outputFilename)!r} failed.")
return None
raise Error(f"Writing file {relpath(args.outputFilename)!r} failed.")
outputFilename, outputFormat, compression = outputArgs

sort = self._convertPrepare(
Expand All @@ -1236,11 +1201,6 @@ def convertV2(self, args: ConvertArgs) -> "str | None":
sort=sort,
**writeOptions,
)
if not finalOutputFile:
log.critical(f"Writing file {relpath(outputFilename)!r} failed.")
self._closeReaders()
self.cleanup()
return None

if compression:
finalOutputFile = self._compressOutput(finalOutputFile, compression)
Expand Down
Loading

0 comments on commit 38f8f91

Please sign in to comment.