Permalink
Browse files

Use the new reflection API in asdl/py_meta.py too.

Also:

- Fix test_lib.AsdlEqual, and fix a test.  There was a bug in the previous attempt.
- Remove __eq__ on py_meta.CompoundObj.  Change a test to use
  test_lib.AsdlEqual.
  • Loading branch information...
Andy Chu
Andy Chu committed Dec 20, 2017
1 parent 157a9ca commit 12c1a58ffb65763f36ea0abdfeffd286e0f44f8b
Showing with 33 additions and 42 deletions.
  1. +13 −1 asdl/asdl_.py
  2. +6 −30 asdl/py_meta.py
  3. +3 −2 core/state_test.py
  4. +10 −8 core/test_lib.py
  5. +1 −1 osh/word_parse_test.py
View
@@ -103,7 +103,7 @@ def __init__(self, module, app_types=None):
if app_types is not None:
self.types.update(app_types)
# TODO: Fold this in
# TODO: Don't need a public constant.
self.types.update(DESCRIPTORS_BY_NAME)
def Get(self, field):
@@ -127,6 +127,7 @@ def _CheckFieldsAndWire(typ, type_lookup):
typ.type_lookup = type_lookup # wire it for lookup
def ResolveTypes(module, app_types=None):
# Walk the module, checking types, and adding the type_lookup attribute
# everywhere.
@@ -209,6 +210,12 @@ class _CompoundType(AST):
def __init__(self, fields):
self.fields = fields or []
# Add fake spids field.
# TODO: Only do this if 'attributes' are set.
if self.fields:
self.fields.append(Field('int', 'spids', seq=True))
self.field_lookup = {f.name: f for f in self.fields}
self.type_lookup = None # for runtime reflection
@@ -217,6 +224,11 @@ def GetFields(self):
field_name = f.name
yield field_name, self.LookupFieldType(field_name)
def GetFieldNames(self):
"""Only used by core/test_lib.py."""
for f in self.fields:
yield f.name
def LookupFieldType(self, field_name):
field = self.field_lookup[field_name]
return self.type_lookup.Get(field)
View
@@ -136,33 +136,8 @@ def __init__(self, *args, **kwargs):
if args or kwargs:
self._Init(args, kwargs)
def __eq__(self, other):
if not isinstance(other, CompoundObj):
return False
if self.tag != other.tag:
return False
for name in self.FIELDS:
# Special case: we are not testing locations right now.
if name == 'span_id':
continue
left = getattr(self, name)
right = getattr(other, name)
if left != right:
return False
return True
# Interesting difference: Python 3 automatically fills in __ne__ for you!
# https://docs.python.org/2/reference/datamodel.html
# https://docs.python.org/3/reference/datamodel.html#object.__ne__
def __ne__(self, other):
return not self.__eq__(other)
def _SetDefaults(self):
for name in self.FIELDS:
desc = self.DESCRIPTOR_LOOKUP[name]
for name, desc in self.ASDL_TYPE.GetFields():
if isinstance(desc, asdl.MaybeType):
child = desc.desc
@@ -178,8 +153,9 @@ def _SetDefaults(self):
self.__setattr__(name, [])
def _Init(self, args, kwargs):
field_names = list(self.ASDL_TYPE.GetFieldNames())
for i, val in enumerate(args):
name = self.FIELDS[i]
name = field_names[i]
self.__setattr__(name, val)
for name, val in kwargs.items():
@@ -189,7 +165,7 @@ def _Init(self, args, kwargs):
# Disable type checking here
#return
for name in self.FIELDS:
for name in field_names:
if not self._assigned[name]:
# If anything was set, then required fields raise an error.
raise ValueError("Field %r is required and wasn't initialized" % name)
@@ -200,7 +176,7 @@ def CheckUnassigned(self):
This is currently only used in unit tests.
"""
unassigned = []
for name in self.FIELDS:
for name in self.ASDL_TYPE.GetFieldNames():
if not self._assigned[name]:
desc = self.DESCRIPTOR_LOOKUP[name]
if not isinstance(desc, asdl.MaybeType):
@@ -214,7 +190,7 @@ def __setattr__(self, name, value):
self.__dict__[name] = value
return
try:
desc = self.DESCRIPTOR_LOOKUP[name]
desc = self.ASDL_TYPE.LookupFieldType(name)
except KeyError:
raise AttributeError('Object of type %r has no attribute %r' %
(self.__class__.__name__, name))
View
@@ -8,6 +8,7 @@
from core import runtime
from core import state # module under test
from core import util
from core import test_lib
scope_e = runtime.scope_e
value_e = runtime.value_e
@@ -192,10 +193,10 @@ def testGetVar(self):
scope_e.Dynamic)
val = mem.GetVar('a', scope_e.Dynamic)
self.assertEqual(runtime.Str('x'), val)
test_lib.AssertAsdlEqual(self, runtime.Str('x'), val)
val = mem.GetVar('undef', scope_e.Dynamic)
self.assertEqual(runtime.Undef(), val)
test_lib.AssertAsdlEqual(self, runtime.Undef(), val)
def testExportThenAssign(self):
"""Regression Test"""
View
@@ -10,6 +10,8 @@
"""
from core import alloc
from core.id_kind import Id
from asdl import py_meta
def TokensEqual(left, right):
@@ -29,7 +31,7 @@ def AsdlEqual(left, right):
We don't use equality in the actual code, so this is relegated to test_lib.
"""
if isinstance(left, (int, str, bool)):
if isinstance(left, (int, str, bool, Id)): # little hack for Id
return left == right
if isinstance(left, list):
@@ -40,26 +42,26 @@ def AsdlEqual(left, right):
return False
return True
if isinstance(other, asdl.CompoundObj):
if isinstance(left, py_meta.CompoundObj):
if left.tag != right.tag:
return False
for name in left.FIELDS:
for name in left.ASDL_TYPE.GetFieldNames():
# Special case: we are not testing locations right now.
#if name == 'span_id':
# continue
if name == 'span_id':
continue
a = getattr(left, name)
b = getattr(right, name)
if not AsdlEqual(left, right):
if not AsdlEqual(a, b):
return False
return True
raise AssertionError
raise AssertionError(left)
def AssertAsdlEqual(test, left, right):
test.assertTrue(left, right)
test.assertTrue(AsdlEqual(left, right), 'Expected %s, got %s' % (left, right))
def MakeArena(source_name):
View
@@ -473,7 +473,7 @@ def testMultiLine(self):
w = w_parser.ReadWord(lex_mode_e.OUTER)
t = ast.token(Id.Op_Newline, '\n')
test_lib.AssertAsdlEqual(self, ast.CompoundWord(parts), w)
test_lib.AssertAsdlEqual(self, ast.TokenWord(t), w)
w = w_parser.ReadWord(lex_mode_e.OUTER)
parts = [ast.LiteralPart(ast.token(Id.Lit_Chars, 'ls'))]

0 comments on commit 12c1a58

Please sign in to comment.