Skip to content

Commit

Permalink
Update type annotations.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 575843122
  • Loading branch information
isingoo authored and copybara-github committed Oct 23, 2023
1 parent 337c2e7 commit a37ec88
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 26 deletions.
4 changes: 2 additions & 2 deletions nisaba/scripts/natural_translit/utils/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ py_library(
)

py_test(
name = "alignment_test_py",
name = "alignment_test",
srcs = ["alignment_test.py"],
main = "alignment_test.py",
deps = [
Expand Down Expand Up @@ -92,7 +92,7 @@ py_library(
)

py_test(
name = "type_op_test_py",
name = "type_op_test",
srcs = ["type_op_test.py"],
main = "type_op_test.py",
deps = [
Expand Down
46 changes: 25 additions & 21 deletions nisaba/scripts/natural_translit/utils/type_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ def value_from_list(some_list, index, exclude=UNSPECIFIED, instead=0):
"""

import logging
import numbers
from typing import Dict, Iterable, List, NamedTuple, Tuple, Union
from typing import Dict, Iterable, List, NamedTuple, Tuple, Union, Type
import pynini as pyn

# Custom types
Expand Down Expand Up @@ -98,10 +97,13 @@ def __init__(self, alias: str = '', text: str = ''):

# FstLike from pynini doesn't work in isinstance()
FstLike = Union[str, pyn.Fst]
Catalog = Union[Dict, List, NamedTuple]
# Restricted generic class to avoid using Any type.
Valid = Union[range, Thing, Catalog, numbers.Number, Tuple, set, FstLike]
Valid = Union[
bool, Dict, float, FstLike, int, List, NamedTuple, range, set, Thing, Tuple
]
# TODO: Update Opt names to fit the union types.
OptSet = Union[set, Thing]
OptType = Union[Type, Thing]

# Log functions

Expand Down Expand Up @@ -225,34 +227,36 @@ def not_exists(a: Valid, allow_none: bool = False) -> bool:
return not exists(a, allow_none)


def is_instance(a: Valid, want: Valid = UNSPECIFIED) -> bool:
def is_instance_dbg(a: Valid, want: OptType = UNSPECIFIED) -> bool:
"""Checks instance for logging purposes.
Args:
a: Object
want: Type. Default value is UNSPECIFIED to make type check optional in
functions that call is_instance, while the case of optional argument
functions that call is_instance_dbg, while the case of optional argument
and specifically checking for Null type as distinct cases.
Returns:
bool
"""
if not_specified(want):
debug_true('is_instance', 'type check not requested for %s' % text_of(a))
debug_true(
'is_instance_dbg', 'type check not requested for %s' % text_of(a)
)
return True
try:
if isinstance(a, want):
return True
else:
debug_false('is_instance', '%s not %s' % (text_of(a), want.__name__))
debug_false('is_instance_dbg', '%s not %s' % (text_of(a), want.__name__))
except TypeError:
debug_false('is_instance', 'invalid type')
debug_false('is_instance_dbg', 'invalid type')
return False


def not_instance(a: Valid, want: Valid = UNSPECIFIED) -> bool:
return not is_instance(a, want)
def not_instance(a: Valid, want: OptType = UNSPECIFIED) -> bool:
return not is_instance_dbg(a, want)


def make_thing(
Expand All @@ -267,7 +271,7 @@ def make_thing(

def enforce_thing(t: Valid) -> Thing:
"""Enforces thing type. If t is not Thing, puts t in value of a new Thing."""
if is_instance(t, Thing): return t
if isinstance(t, Thing): return t
debug_message(
'enforce_thing', 'Thing from %s: %s' % (class_of(t), text_of(t))
)
Expand All @@ -276,19 +280,19 @@ def enforce_thing(t: Valid) -> Thing:
# Attribute functions with type check.


def has_attribute(a: Valid, attr: str, want: Valid = UNSPECIFIED) -> bool:
def has_attribute(a: Valid, attr: str, want: OptType = UNSPECIFIED) -> bool:
"""Adds log and optional type check to hasattr()."""
if not_exists(a): return False
if not hasattr(a, attr):
debug_false(
'has_attribute', '%s not an attribute of %s' % (attr, text_of(a))
)
return False
return is_instance(getattr(a, attr), want)
return is_instance_dbg(getattr(a, attr), want)


def get_attribute(
a: Valid, attr: str, default: Valid = MISSING, want: Valid = UNSPECIFIED
a: Valid, attr: str, default: Valid = MISSING, want: OptType = UNSPECIFIED
) -> Valid:
"""Adds log and type check to getattr()."""
return getattr(a, attr) if has_attribute(a, attr, want) else default
Expand Down Expand Up @@ -361,7 +365,7 @@ def not_empty(a: Valid, allow_none: bool = False) -> bool:

def get_element(
search_in: Valid, index: int, default: Valid = MISSING
) -> bool:
) -> Valid:
"""Returns a[index] if possible, default value if not."""
if not_exists(search_in): return default
if not_instance(search_in, Iterable): return default
Expand Down Expand Up @@ -447,7 +451,7 @@ def in_range(

def enforce_list(
l: Valid, enf_dict: bool = True, allow_none: bool = False
) -> [Valid]:
) -> List[Valid]:
"""Enforces list type.
When l is a list, returns l. If l is an iterable returns `list(l)`, except
Expand Down Expand Up @@ -490,7 +494,7 @@ def in_list(

def enforce_dict(
d: Valid, add_key: Valid = 'default', allow_none: bool = False
) -> dict[Valid, []]:
) -> Dict[Valid, Valid]:
"""Enforces dict type.
Args:
Expand Down Expand Up @@ -575,11 +579,11 @@ def enforce_set(
if not_exists(s, allow_none):
debug_result('enforce_set', set(), 'empty set from nonexistent')
return set()
if is_instance(s, str): return {s}
if is_instance(s, dict):
if isinstance(s, str): return {s}
if isinstance(s, dict):
return set(enforce_list(s)) if enf_dict else {(k, v) for k, v in s.items()}
result = set()
if is_instance(s, Iterable):
if isinstance(s, Iterable):
for element in s:
try:
result.add(element)
Expand Down
6 changes: 3 additions & 3 deletions nisaba/scripts/natural_translit/utils/type_op_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,14 @@ def test_not_exists_nothing(self):
def test_not_exists_empty(self):
self.assertTrue(t.not_exists(t.MISSING))

def test_is_instance(self):
self.assertTrue(t.is_instance(1, int))
def test_is_instance_dbg(self):
self.assertTrue(t.is_instance_dbg(1, int))

def test_not_instance(self):
self.assertTrue(t.not_instance(1, str))

def test_not_instance_invalid_type(self):
self.assertTrue(t.not_instance(1, 'int'))
self.assertTrue(t.not_instance(1, t.MISSING))

def test_make_thing(self):
self.assertEqual(_T0.value, 0)
Expand Down

0 comments on commit a37ec88

Please sign in to comment.