Skip to content

Commit

Permalink
Add parent class for Nothing and Thing. Unify common methods and remo…
Browse files Browse the repository at this point in the history
…ve redundant methods from child classes.

PiperOrigin-RevId: 609677248
  • Loading branch information
isingoo authored and copybara-github committed Feb 23, 2024
1 parent 0d17512 commit 9bf2490
Show file tree
Hide file tree
Showing 13 changed files with 146 additions and 142 deletions.
3 changes: 1 addition & 2 deletions nisaba/scripts/natural_translit/brahmic/derom_inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,7 @@ def __init__(
TODO: remove fields when graphemes have the corresponding methods.
"""

super().__init__()
self.set_alias(alias)
super().__init__(alias)
self.rom_list = fl.FstList(rom_list)
self.rom = self.rom_list.concat()
self.brh_list = fl.FstList(brh_list)
Expand Down
2 changes: 1 addition & 1 deletion nisaba/scripts/natural_translit/brahmic/deromanizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def __init__(self):
self._init_supls()

def _add_fst_list(self, alias: str, *fsts) -> None:
self.add_item(fl.FstList.with_alias(alias, *fsts))
self.add_item(fl.FstList(*fsts, alias=alias))

def _make_mapping_group(
self, alias: str, value: ... = ty.UNSPECIFIED
Expand Down
8 changes: 5 additions & 3 deletions nisaba/scripts/natural_translit/utils/expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

"""Interfaces for generating fsts from objects."""
from typing import Union
from nisaba.scripts.natural_translit.utils import log_op as log
from nisaba.scripts.natural_translit.utils import type_op as ty

Expand Down Expand Up @@ -47,8 +48,7 @@ def __init__(
):
# TODO: Move alias to Thing's init() and remove set_alias() from child
# classes.
super().__init__()
self.set_alias(alias)
super().__init__(alias=alias)
self.text = text if text else self.alias
self.raw = raw
self.index = index if ty.is_specified(index) else hash(self)
Expand All @@ -72,7 +72,9 @@ def __str__(self) -> str:
class Atomic(Expression, Symbol):
"""An instance of a single symbol."""

def __init__(self, symbol: Symbol, alias: str = ''):
OR_SYMBOL = Union[Symbol, 'Atomic']

def __init__(self, symbol: 'Atomic.OR_SYMBOL', alias: str = ''):
Expression.__init__(self, symbol.alias)
Symbol.__init__(self, symbol.alias, symbol.text, symbol.raw, symbol.index)
self._item_type = Atomic
Expand Down
31 changes: 8 additions & 23 deletions nisaba/scripts/natural_translit/utils/feature.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@ class Feature(ty.Thing):
ERROR_DISTANCE = 1_000_000

def __init__(self, alias: str, text: str = ''):
super().__init__()
self.set_alias(alias)
super().__init__(alias)
self.text = text if text else alias
self.aspect = inventory2.Inventory.EMPTY
self.inventory = inventory2.Inventory.EMPTY
Expand Down Expand Up @@ -196,6 +195,7 @@ class Set(ty.IterableThing):

def __init__(self, *features, alias: str = ''):
super().__init__(alias=alias)
if alias: self.text = alias
self._items = set()
self._item_type = Feature
self.add(*features)
Expand All @@ -207,12 +207,6 @@ def __str__(self):
self.alias, ', '.join(items)
)

@classmethod
def with_alias(cls, alias: str, *features) -> 'Feature.Set':
new = cls(*features, alias=alias)
new.text = alias
return new

@classmethod
def aspect_dict(
cls, *features: 'Feature.ITERABLE'
Expand All @@ -223,17 +217,6 @@ def aspect_dict(
distances.update({feature.aspect: value_set.add(feature)})
return distances

# TODO: Decide what to do with any and n_a in add/remove/replace
def add(self, *features) -> 'Feature.Set':
"""Adds features to the set, flattens tree structures in arguments."""
for f in features:
if isinstance(f, Feature):
self._items.add(f)
elif isinstance(f, Iterable):
for item in f:
self.add(item)
return self

def remove(self, *features) -> 'Feature.Set':
for feature in Feature.Set(*features):
self._items.discard(feature)
Expand Down Expand Up @@ -389,6 +372,9 @@ def populate(self, aspect: 'Feature.Aspect') -> None:
item.parent_list = self
if isinstance(item, Feature) and item not in aspect:
aspect.add_feature(item)
if item in aspect:
if hasattr(aspect, 'any'): del aspect.any
if hasattr(aspect, 'n_a'): del aspect.n_a
elif isinstance(item, Feature.ValueList):
item.populate(aspect)
for item2 in self._items[i+1:]:
Expand Down Expand Up @@ -482,9 +468,8 @@ def __init__(
self,
feature_list: 'Feature.ValueList'
):
super().__init__()
super().__init__(feature_list.alias)
self.root_list = feature_list
self.set_alias(feature_list.alias)
self.text = feature_list.text
self.inventory = ty.UNASSIGNED
self.max_dist = 0
Expand Down Expand Up @@ -528,7 +513,7 @@ def _make_set(
) -> 'Feature.Set':
filtered = self.filter(*features)
to_add = filtered if not negation else self.all.difference(filtered)
return Feature.Set.with_alias(alias, to_add)
return Feature.Set(to_add, alias=alias)

def set(self, alias: str, *features) -> None:
self.add_supl(self._make_set(alias, *features))
Expand Down Expand Up @@ -648,7 +633,7 @@ def __init__(
param_dict = Feature.Set.aspect_dict(*params)
for aspect in self.inventory:
value = param_dict.get(aspect, aspect.any)
self.add_item(Feature.Set.with_alias(aspect.alias, value))
self.add_item(Feature.Set(value, alias=aspect.alias))
self.max_dist += aspect.max_dist

def __str__(self):
Expand Down
4 changes: 4 additions & 0 deletions nisaba/scripts/natural_translit/utils/feature_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ def test_list_as_supl(self):
def test_set_empty(self):
self.assertEmpty(f.Set())

def test_set_alias_text(self):
self.assertEqual(r.warmth.all.alias, 'all')
self.assertEqual(r.warmth.all.text, 'all')

def test_set_reset(self):
self.assertEmpty(f.Set(r.warmth.cold).reset())

Expand Down
5 changes: 0 additions & 5 deletions nisaba/scripts/natural_translit/utils/fst_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ def __init__(self, *fsts, alias: str = ''):
self._item_type = pyn.Fst
self.add(*fsts)

@classmethod
def with_alias(cls, alias: str, *args):
new = FstList(*args, alias=alias)
return new

def add(self, *args) -> 'FstList':
"""Adds fsts to self.
Expand Down
4 changes: 3 additions & 1 deletion nisaba/scripts/natural_translit/utils/fst_list_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ def test_bool_true(self):
self.assertTrue(f.FstList('a'))

def test_with_alias(self):
self.assertEqual(f.FstList.with_alias('a').alias, 'a')
fst_list = f.FstList(alias='a')
self.assertEqual(fst_list.alias, 'a')
self.assertEmpty(fst_list)

def test_add_nothing(self):
self.assertEmpty(f.FstList(ty.UNSPECIFIED))
Expand Down
19 changes: 9 additions & 10 deletions nisaba/scripts/natural_translit/utils/inventory2.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class Inventory(ty.IterableThing):
The items of an inventory, eg. the graphemes in a Grapheme Inventory, can be
accessed by their aliases. For example, if
`A = ty.Thing.with_alias_and_value('a_uc', 'A')` is added to an inventory
`A = ty.Thing(alias='a_uc', value_from='A')` is added to an inventory
such as `ltn` as an item, `ltn.a_uc` will point to A. All items are included
when iterating over the inventory and the len of the inventory is the number
of its items.
Expand All @@ -41,8 +41,9 @@ class Inventory(ty.IterableThing):

_HAS_DYNAMIC_ATTRIBUTES = True

def __init__(self, alias: str = ''):
def __init__(self, alias: str = '', typed: ty.TypeOrNothing = ty.UNSPECIFIED):
super().__init__(alias=alias)
if ty.not_nothing(typed): self._item_type = typed
self.text = alias if alias else 'New Inventory'
self.item_aliases = []
self.supl_aliases = []
Expand All @@ -57,9 +58,9 @@ def from_list(
alias: str = '',
) -> 'Inventory':
"""Makes an Inventory from a list of things."""
new = cls(alias)
new = cls(alias, typed)
for item in items:
new.add_item(item, attr, typed)
new.add_item(item, attr)
for s in ty.enforce_list(supls):
new.add_supl(s)
return new
Expand All @@ -83,7 +84,7 @@ def _get_field_value(
typed: Optional type restriction for the value.
Returns:
Given `N1 = ty.Thing.with_alias_and_value('n', 1)`
Given `N1 = ty.Thing(alias='n', value_from=1)`
`self._get_field_value(N1)` returns `N1`
`self._get_field_value(N1, typed=int)` returns `ty.MISSING`
`self._get_field_value(N1, 'value')` returns `1`
Expand All @@ -99,10 +100,9 @@ def add(self, *args) -> 'Inventory':

def add_item(
self, thing: ty.Thing, attr: str = '',
typed: ty.TypeOrNothing = ty.UNSPECIFIED
) -> bool:
field_value = self._get_field_value(thing, attr, typed)
if ty.is_nothing(field_value) or field_value in self: return False
field_value = self._get_field_value(thing, attr)
if self.invalid_item(field_value) or field_value in self: return False
added = self._add_field(thing.alias, field_value)
if added:
self._items.append(field_value)
Expand All @@ -115,8 +115,7 @@ def add_supl(self, supl: ty.Thing) -> None:

def make_supl(self, alias: str, value: ...) -> None:
"""Adds the value as a supplement."""
if self._add_field(alias, value):
self.supl_aliases.append(alias)
if self._add_field(alias, value): self.supl_aliases.append(alias)

def get(self, alias: str, default: ... = ty.MISSING) -> ...:
if alias in self.item_aliases or alias in self.supl_aliases:
Expand Down
19 changes: 9 additions & 10 deletions nisaba/scripts/natural_translit/utils/inventory2_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@
_C_STR = 'c'
_D_INT = 4

_T_A_FST = ty.Thing.with_alias_and_value('a', _A_FST)
_T_B_STR = ty.Thing.with_alias_and_value('b', _B_STR)
_T_BC_STR = ty.Thing.with_alias_and_value('b', _C_STR)
_T_CB_STR = ty.Thing.with_alias_and_value('c', _B_STR)
_T_C_STR = ty.Thing.with_alias_and_value('c', _C_STR)
_T_D_INT = ty.Thing.with_alias_and_value('d', _D_INT)
_T_A_FST = ty.Thing('a', value_from=_A_FST)
_T_B_STR = ty.Thing('b', value_from=_B_STR)
_T_BC_STR = ty.Thing('b', value_from=_C_STR)
_T_CB_STR = ty.Thing('c', value_from=_B_STR)
_T_C_STR = ty.Thing('c', value_from=_C_STR)
_T_D_INT = ty.Thing('d', value_from=_D_INT)

_i1 = i.Inventory.from_list([_T_B_STR])

_i2 = i.Inventory.from_list(
[_T_B_STR, _T_C_STR], 'value', typed=str, supls=[_T_D_INT]
)
Expand Down Expand Up @@ -80,11 +79,11 @@ def test_add_item_recurring_alias_return_false(self):
self.assertFalse(_i1.add_item(_T_BC_STR))

def test_add_item_wrong_type(self):
_i1.add_item(_T_A_FST, typed=str)
self.assertNotIn(_T_A_FST, _i1)
_i2.add_item(_T_A_FST)
self.assertNotIn(_T_A_FST, _i2)

def test_add_item_wrong_type_return_false(self):
self.assertFalse(_i1.add_item(_T_A_FST, typed=str))
self.assertFalse(_i2.add_item(_T_A_FST))

def test_add_supl(self):
_i1.add_supl(_T_D_INT)
Expand Down
8 changes: 4 additions & 4 deletions nisaba/scripts/natural_translit/utils/list_op_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
_D_INT = 4

_THINGS = [
ls.ty.Thing.from_value_of(_A_FST),
ls.ty.Thing.from_value_of(_B_STR),
ls.ty.Thing.from_value_of(_C_STR),
ls.ty.Thing.from_value_of(_D_INT),
ls.ty.Thing(value_from=_A_FST),
ls.ty.Thing(value_from=_B_STR),
ls.ty.Thing(value_from=_C_STR),
ls.ty.Thing(value_from=_D_INT),
]


Expand Down
10 changes: 5 additions & 5 deletions nisaba/scripts/natural_translit/utils/log_op_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@

D = collections.namedtuple('D', ['k'])
_D1 = D('v')
_T1 = t.Thing.with_alias('T1')
_T3 = t.Thing.with_alias_and_value('', _T1)
_T5 = t.Thing.with_alias_and_value('T5', t.pyn.accep(''))
_T1 = t.Thing('T1')
_T3 = t.Thing(value_from=_T1)
_T5 = t.Thing('T5', value_from=t.pyn.accep(''))
Named = collections.namedtuple('Named', ['name'])
_NAMED = Named('Jane')

Expand Down Expand Up @@ -61,7 +61,7 @@ def test_text_of_none(self):
self.assertEqual(log.text_of(None), 'None')

def test_text_of_nothing(self):
self.assertEqual(log.text_of(t.UNSPECIFIED), 'Unspecified')
self.assertEqual(log.text_of(t.UNSPECIFIED), 'Nothing_unspecified')

def test_alias_of_thing(self):
self.assertEqual(log.alias_of(_T1), 'T1')
Expand All @@ -87,7 +87,7 @@ def test_name_of_thing(self):
def test_class_and_texts(self):
self.assertEqual(
log.class_and_texts(1, t.MISSING, ''),
'int_1, Nothing_Missing, str_<no_text>'
'int_1, Nothing_Nothing_missing, str_<no_text>'
)

def test_frame(self):
Expand Down
Loading

0 comments on commit 9bf2490

Please sign in to comment.