added a base class to have easier isinstance comparisons

This commit is contained in:
David Halter
2012-08-06 22:25:58 +02:00
parent bef8fca57d
commit 9072bd6f52
2 changed files with 27 additions and 19 deletions

View File

@@ -116,7 +116,7 @@ class CachedMetaClass(type):
return super(CachedMetaClass, self).__call__(*args, **kwargs) return super(CachedMetaClass, self).__call__(*args, **kwargs)
class Executable(object): class Executable(parsing.Base):
""" An instance is also an executable - because __init__ is called """ """ An instance is also an executable - because __init__ is called """
def __init__(self, base, var_args=parsing.Array(None, None)): def __init__(self, base, var_args=parsing.Array(None, None)):
self.base = base self.base = base
@@ -240,7 +240,7 @@ class Instance(Executable):
(self.__class__.__name__, self.base, len(self.var_args or [])) (self.__class__.__name__, self.base, len(self.var_args or []))
class InstanceElement(object): class InstanceElement():
def __init__(self, instance, var): def __init__(self, instance, var):
if isinstance(var, parsing.Function): if isinstance(var, parsing.Function):
var = Function(var) var = Function(var)
@@ -283,11 +283,14 @@ class InstanceElement(object):
def __getattr__(self, name): def __getattr__(self, name):
return getattr(self.var, name) return getattr(self.var, name)
def isinstance(self, *cls):
return isinstance(self.var, cls)
def __repr__(self): def __repr__(self):
return "<%s of %s>" % (self.__class__.__name__, self.var) return "<%s of %s>" % (self.__class__.__name__, self.var)
class Class(object): class Class(parsing.Base):
__metaclass__ = CachedMetaClass __metaclass__ = CachedMetaClass
def __init__(self, base): def __init__(self, base):
@@ -342,7 +345,7 @@ class Class(object):
return "<e%s of %s>" % (self.__class__.__name__, self.base) return "<e%s of %s>" % (self.__class__.__name__, self.base)
class Function(object): class Function(parsing.Base):
""" """
""" """
__metaclass__ = CachedMetaClass __metaclass__ = CachedMetaClass
@@ -679,7 +682,7 @@ class Execution(Executable):
(self.__class__.__name__, self.base) (self.__class__.__name__, self.base)
class Generator(object): class Generator(parsing.Base):
def __init__(self, func, var_args): def __init__(self, func, var_args):
super(Generator, self).__init__() super(Generator, self).__init__()
self.func = func self.func = func
@@ -719,7 +722,7 @@ class Generator(object):
return "<%s of %s>" % (self.__class__.__name__, self.func) return "<%s of %s>" % (self.__class__.__name__, self.func)
class Array(object): class Array(parsing.Base):
""" """
Used as a mirror to parsing.Array, if needed. It defines some getter Used as a mirror to parsing.Array, if needed. It defines some getter
methods which are important in this module. methods which are important in this module.
@@ -852,11 +855,8 @@ def get_names_for_scope(scope, position=None, star_search=True,
# `parsing.Class` is used, because the parent is never `Class`. # `parsing.Class` is used, because the parent is never `Class`.
# Ignore the Flows, because the classes and functions care for that. # Ignore the Flows, because the classes and functions care for that.
# InstanceElement of Class is ignored, if it is not the start scope. # InstanceElement of Class is ignored, if it is not the start scope.
if not (scope != start_scope and isinstance(scope, parsing.Class) if not (scope != start_scope and scope.isinstance(parsing.Class)
or isinstance(scope, parsing.Flow) or isinstance(scope, parsing.Flow)):
or scope != start_scope and isinstance(scope, InstanceElement)
and isinstance(scope.var, parsing.Class)):
try: try:
yield scope, get_defined_names_for_position(scope, position, yield scope, get_defined_names_for_position(scope, position,
in_scope) in_scope)
@@ -895,9 +895,7 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False):
""" """
res_new = [] res_new = []
for r in result: for r in result:
if isinstance(r, parsing.Statement) \ if r.isinstance(parsing.Statement):
or isinstance(r, InstanceElement) \
and isinstance(r.var, parsing.Statement):
# Global variables handling. # Global variables handling.
if r.is_global(): if r.is_global():
for token_name in r.token_list[1:]: for token_name in r.token_list[1:]:
@@ -920,8 +918,7 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False):
r = Class(r) r = Class(r)
elif isinstance(r, parsing.Function): elif isinstance(r, parsing.Function):
r = Function(r) r = Function(r)
if isinstance(r, Function) or isinstance(r, InstanceElement)\ if r.isinstance(Function):
and isinstance(r.var, Function):
try: try:
r = r.get_decorated_func() r = r.get_decorated_func()
except DecoratorNotFound: except DecoratorNotFound:
@@ -937,8 +934,7 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False):
and scope.var == name.parent.parent: and scope.var == name.parent.parent:
name = InstanceElement(scope.instance, name) name = InstanceElement(scope.instance, name)
par = name.parent par = name.parent
if isinstance(par, parsing.Flow) or isinstance(par, if par.isinstance(parsing.Flow):
InstanceElement) and isinstance(par.var, parsing.Flow) :
if par.command == 'for': if par.command == 'for':
# Take the first statement (for has always only # Take the first statement (for has always only
# one, remember `in`). And follow it. After that, # one, remember `in`). And follow it. After that,

View File

@@ -52,7 +52,19 @@ def indent_block(text, indention=" "):
return '\n'.join(map(lambda s: indention + s, lines)) + temp return '\n'.join(map(lambda s: indention + s, lines)) + temp
class Simple(object): class Base(object):
"""
This is just here to have an isinstance check, which is also used on
evaluate classes. But since they have sometimes a special type of
delegation, it is important for those classes to override this method.
I know that there is a chance to do such things with __instancecheck__, but
since Python 2.5 doesn't support it, I decided to do it this way.
"""
def isinstance(self, *cls):
return isinstance(self, cls)
class Simple(Base):
""" """
The super class for Scope, Import, Name and Statement. Every object in The super class for Scope, Import, Name and Statement. Every object in
the parser tree inherits from this class. the parser tree inherits from this class.