From c64fc009873a562700cb51a5c62c1b52c99fd033 Mon Sep 17 00:00:00 2001 From: Salvo 'LtWorf' Tomaselli Date: Wed, 21 Oct 2020 13:56:59 +0200 Subject: [PATCH] Localize strings --- relational/maintenance.py | 9 +++++---- relational/parser.py | 16 +++++++++------- relational/relation.py | 21 +++++++++++---------- relational/rtypes.py | 3 ++- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/relational/maintenance.py b/relational/maintenance.py index f72c3da..218850c 100644 --- a/relational/maintenance.py +++ b/relational/maintenance.py @@ -22,6 +22,7 @@ import os.path import pickle import base64 from typing import Optional, Tuple +from gettext import gettext as _ from relational.relation import Relation from relational import parser @@ -153,7 +154,7 @@ class UserInterface: def set_relation(self, name: str, rel: Relation) -> None: '''Sets the relation corresponding to name.''' if not is_valid_relation_name(name): - raise Exception('Invalid name for destination relation') + raise Exception(_('Invalid name for destination relation')) self.relations[name] = rel def suggest_name(self, filename: str) -> Optional[str]: @@ -184,7 +185,7 @@ class UserInterface: relname is not None, adds the result to the dictionary, with the name given in relname.''' if not is_valid_relation_name(relname): - raise Exception('Invalid name for destination relation') + raise Exception(_('Invalid name for destination relation')) expr = parser.parse(query) result = expr(self.relations) @@ -226,10 +227,10 @@ class UserInterface: try: r = self.execute(query, relname) except Exception as e: - raise Exception('Error in query: %s\n%s' % ( + raise Exception(_('Error in query: %s\n%s') % ( query, str(e) )) if r is None: - raise Exception('No query executed') + raise Exception(_('No query executed')) return r diff --git a/relational/parser.py b/relational/parser.py index af508bd..2bc1f26 100644 --- a/relational/parser.py +++ b/relational/parser.py @@ -26,6 +26,7 @@ # http://ltworf.github.io/relational/grammar.html from typing import Optional, Union, List, Any, Dict, Literal from dataclasses import dataclass +from gettext import gettext as _ from relational import rtypes @@ -55,6 +56,7 @@ __all__ = [ 'parse', ] + PRODUCT = '*' DIFFERENCE = '-' UNION = '∪' @@ -305,7 +307,7 @@ def parse_tokens(expression: List[Union[list, str]]) -> Node: expression = expression[0] if len(expression) == 0: - raise ParserException('Failed to parse empty expression') + raise ParserException(_('Failed to parse empty expression')) # The list contains only 1 string. Means it is the name of a relation if len(expression) == 1: @@ -330,28 +332,28 @@ def parse_tokens(expression: List[Union[list, str]]) -> Node: if len(expression[:i]) == 0: raise ParserException( - f'Expected left operand for {expression[i]!r}') + _(f'Expected left operand for {expression[i]!r}')) if len(expression[i + 1:]) == 0: raise ParserException( - f'Expected right operand for {expression[i]!r}') + _(f'Expected right operand for {expression[i]!r}')) return Binary(expression[i], parse_tokens(expression[:i]), parse_tokens(expression[i + 1:])) # type: ignore '''Searches for unary operators, parsing from right to left''' for i in range(len(expression)): if expression[i] in u_operators: # Unary operator if len(expression) <= i + 2: raise ParserException( - f'Expected more tokens in {expression[i]!r}') + _(f'Expected more tokens in {expression[i]!r}')) elif len(expression) > i + 3: raise ParserException( - f'Too many tokens in {expression[i]!r}') + _(f'Too many tokens in {expression[i]!r}')) return Unary( expression[i], # type: ignore prop=expression[1 + i].strip(), # type: ignore child=parse_tokens(expression[2 + i]) # type: ignore ) - raise ParserException(f'Parse error on {expression!r}') + raise ParserException(_(f'Parse error on {expression!r}')) def _find_matching_parenthesis(expression: str, start=0, openpar='(', closepar=')') -> Optional[int]: @@ -421,7 +423,7 @@ def tokenize(expression: str) -> list: end = _find_matching_parenthesis(expression) if end is None: raise TokenizerException( - "Missing matching ')' in '%s'" % expression) + _(f'Missing matching \')\' in \'{expression}\'')) # Appends the tokenization of the content of the parenthesis items.append(tokenize(expression[1:end])) # Removes the entire parentesis and content from the expression diff --git a/relational/relation.py b/relational/relation.py index 1984ec7..10c4c4c 100644 --- a/relational/relation.py +++ b/relational/relation.py @@ -24,6 +24,7 @@ from collections import deque from typing import FrozenSet, Iterable, List, Dict, Tuple, Optional from dataclasses import dataclass from pathlib import Path +from gettext import gettext as _ from relational.rtypes import * @@ -88,7 +89,7 @@ class Relation: content = [] for row in loaded['content']: if len(row) != len(header): - raise ValueError(f'Line {row} contains an incorrect amount of values') + raise ValueError(_(f'Line {row} contains an incorrect amount of values')) t_row: Tuple[Optional[Union[int, float, str, Rdate]], ...] = load( row, Tuple[Optional[Union[int, float, str, Rdate]], ...], # type: ignore @@ -136,7 +137,7 @@ class Relation: for row in content: if len(row) != len(header): - raise ValueError(f'Line {row} contains an incorrect amount of values') + raise ValueError(_(f'Line {row} contains an incorrect amount of values')) r_content.append(row) # Guess types @@ -169,7 +170,7 @@ class Relation: return other elif len(self.header) == len(other.header) and self.header.sharedAttributes(other.header) == len(self.header): return other.projection(self.header) - raise TypeError('Relations differ: [%s] [%s]' % ( + raise TypeError(_('Relations differ: [%s] [%s]') % ( ','.join(self.header), ','.join(other.header) )) @@ -180,7 +181,7 @@ class Relation: try: c_expr = compile(expr, 'selection', 'eval') except: - raise Exception(f'Failed to compile expression: {expr}') + raise Exception(_(f'Failed to compile expression: {expr}')) content = [] for i in self.content: @@ -193,7 +194,7 @@ class Relation: if eval(c_expr, attributes): content.append(i) except Exception as e: - raise Exception(f'Failed to evaluate {expr} with {i}\n{e}') + raise Exception(_(f'Failed to evaluate {expr} with {i}\n{e}')) return Relation(self.header, frozenset(content)) def product(self, other: 'Relation') -> 'Relation': @@ -205,7 +206,7 @@ class Relation: raise Exception('Operand must be a relation') if self.header.sharedAttributes(other.header) != 0: raise Exception( - 'Unable to perform product on relations with colliding attributes' + _('Unable to perform product on relations with colliding attributes') ) header = Header(self.header + other.header) @@ -231,7 +232,7 @@ class Relation: ids = self.header.getAttributesId(attributes) if len(ids) == 0: - raise Exception('Invalid attributes for projection') + raise Exception(_('Invalid attributes for projection')) header = Header((self.header[i] for i in ids)) content = frozenset(tuple((i[j] for j in ids)) for i in self.content) @@ -472,7 +473,7 @@ class Header(tuple): for i in self: if not is_valid_relation_name(i): - raise Exception(f'"{i}" is not a valid attribute name') + raise Exception(_(f'"{i}" is not a valid attribute name')) if len(self) != len(set(self)): raise Exception('Attribute names must be unique') @@ -488,12 +489,12 @@ class Header(tuple): attrs = list(self) for old, new in params.items(): if not is_valid_relation_name(new): - raise Exception(f'{new} is not a valid attribute name') + raise Exception(_(f'{new} is not a valid attribute name')) try: id_ = attrs.index(old) attrs[id_] = new except: - raise Exception(f'Field not found: {old}') + raise Exception(_(f'Field not found: {old}')) return Header(attrs) def sharedAttributes(self, other: 'Header') -> int: diff --git a/relational/rtypes.py b/relational/rtypes.py index 29f9aae..69944a3 100644 --- a/relational/rtypes.py +++ b/relational/rtypes.py @@ -25,6 +25,7 @@ import keyword import re from typing import Union, Set, Any, Callable, Type, Optional from dataclasses import dataclass +from gettext import gettext as _ RELATION_NAME_REGEXP = re.compile(r'^[_a-z][_a-z0-9]*$', re.IGNORECASE) @@ -83,7 +84,7 @@ class Rdate: '''date: A string representing a date YYYY-MM-DD''' r = _date_regexp.match(date) if not r: - raise ValueError(f'{date} is not a valid date') + raise ValueError(_(f'{date} is not a valid date')) year = int(r.group(1)) month = int(r.group(3))