Skip to content

Commit

Permalink
Start to remove the module keyword argument from the directive get() …
Browse files Browse the repository at this point in the history
…methods. Write down the edge cases for MODULE and CLASS_OR_MODULE scope directives and getting to default values.
  • Loading branch information
janwijbrand committed Jan 28, 2009
1 parent 33f3207 commit c14c3fd
Show file tree
Hide file tree
Showing 3 changed files with 251 additions and 9 deletions.
22 changes: 15 additions & 7 deletions src/martian/directive.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,11 @@ class ClassScope(object):
def check(self, frame):
return util.frame_is_class(frame) and not is_fake_module(frame)

def get(self, directive, component, module, get_default):
def get(self, directive, component, get_default):
result = directive.store.get(directive, component, _USE_DEFAULT)
if result is not _USE_DEFAULT:
return result
# we may be really dealing with an instance instead of a class
# We may be really dealing with an instance instead of a class.
if not util.isclass(component):
component = component.__class__
for base in inspect.getmro(component):
Expand All @@ -152,13 +152,21 @@ class ClassOrModuleScope(object):
def check(self, frame):
return util.frame_is_class(frame) or util.frame_is_module(frame)

def get(self, directive, component, module, get_default):
def get(self, directive, component, get_default):
# look up class-level directive on this class or its bases
# we don't need to loop through the __mro__ here as Python will
# do it for us
result = directive.store.get(directive, component, _USE_DEFAULT)
if result is not _USE_DEFAULT:
return result

# we may be really dealing with an instance or a module here
#if not util.isclass(component):
# result = directive.store.get(directive, component, _USE_DEFAULT)
# if result is not _USE_DEFAULT:
# return result
# return get_default(component, component)

# now we need to loop through the mro, potentially twice
mro = inspect.getmro(component)
# look up module-level directive for this class or its bases
Expand All @@ -184,11 +192,11 @@ class ModuleScope(object):
def check(self, frame):
return util.frame_is_module(frame) or is_fake_module(frame)

def get(self, directive, component, module, get_default):
result = directive.store.get(directive, module, _USE_DEFAULT)
def get(self, directive, component, get_default):
result = directive.store.get(directive, component, _USE_DEFAULT)
if result is not _USE_DEFAULT:
return result
return get_default(component, module)
return get_default(component, component)

MODULE = ModuleScope()

Expand Down Expand Up @@ -265,7 +273,7 @@ def get(self, component=None, module=None, **data):
directive = self.directive
def get_default(component, module):
return self.get_default(component, module, **data)
return directive.scope.get(directive, component, module,
return directive.scope.get(directive, component,
get_default=get_default)

class MultipleTimesDirective(Directive):
Expand Down
4 changes: 2 additions & 2 deletions src/martian/directive.txt
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ inheritance has no meaning there::
... multi('Two')
...
>>> from martiantest.fake import module_with_directive
>>> print multi.bind().get(module=module_with_directive)
>>> print multi.bind().get(module_with_directive)
['One', 'Two']

>>> from martian import MODULE
Expand All @@ -420,7 +420,7 @@ inheritance has no meaning there::
... multi(2, 'Two')
...
>>> from martiantest.fake import module_with_directive
>>> d = multi.bind().get(module=module_with_directive)
>>> d = multi.bind().get(module_with_directive)
>>> print sorted(d.items())
[(1, 'One'), (2, 'Two')]

Expand Down
234 changes: 234 additions & 0 deletions src/martian/edgecase.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,237 @@ directive:
>>> module_grokker.grok('module_with_directive', module_with_directive)
some_function 11
True

Directive scope and default edge cases
--------------------------------------

MODULE scope directive on a module, with no explicit value::

>>> class mydir(Directive):
... scope = MODULE
... store = ONCE
>>> class module_no_explicit_value(FakeModule):
... fake_module = True
>>> from martiantest.fake import module_no_explicit_value
>>> mydir.bind().get(module_no_explicit_value) is None
True

MODULE scope directive on a module, with an explicit value::

>>> class mydir2(Directive):
... scope = MODULE
... store = ONCE
>>> class module_with_explicit_value(FakeModule):
... fake_module = True
... mydir2('the explicit value')
>>> from martiantest.fake import module_with_explicit_value
>>> mydir2.bind().get(module_with_explicit_value)
'the explicit value'

MODULE scope directive on a module, with no explicit value, with a custom default::

>>> class mydir(Directive):
... scope = MODULE
... store = ONCE
>>> class module_custom_default(FakeModule):
... fake_module = True
>>> from martiantest.fake import module_custom_default
>>> def custom(component, module, **data):
... return 'a custom default value'
>>> mydir.bind(get_default=custom).get(module_custom_default)
'a custom default value'

CLASS scope directive on a class, with no explicit value::

>>> class mydir(Directive):
... scope = CLASS
... store = ONCE
>>> class module_get_from_class_no_explicit(FakeModule):
... class MyClass(object):
... pass
>>> from martiantest.fake import module_get_from_class_no_explicit
>>> mydir.bind().get(module_get_from_class_no_explicit.MyClass) is None
True

CLASS scope directive on an instance, with no explicit value::

>>> class mydir(Directive):
... scope = CLASS
... store = ONCE
>>> class module_get_from_instance_no_explicit(FakeModule):
... class MyClass(object):
... pass
... obj = MyClass()
>>> from martiantest.fake import module_get_from_instance_no_explicit
>>> mydir.bind().get(module_get_from_instance_no_explicit.obj) is None
True

CLASS scope directive on a class, with an explicit value::

>>> class mydir(Directive):
... scope = CLASS
... store = ONCE
>>> class module_get_from_class_with_explicit(FakeModule):
... class MyClass(object):
... mydir('explicitly set')
>>> from martiantest.fake import module_get_from_class_with_explicit
>>> mydir.bind().get(module_get_from_class_with_explicit.MyClass)
'explicitly set'

CLASS scope directive on an instance, with an explicit value::

>>> class mydir(Directive):
... scope = CLASS
... store = ONCE
>>> class module_get_from_instance_with_explicit(FakeModule):
... class MyClass(object):
... mydir('explicitly set')
... obj = MyClass()
>>> from martiantest.fake import module_get_from_instance_with_explicit
>>> mydir.bind().get(module_get_from_instance_with_explicit.obj)
'explicitly set'

CLASS scope directive on a class, with a custom default::

>>> class mydir(Directive):
... scope = CLASS
... store = ONCE
>>> class module_get_from_class_with_custom(FakeModule):
... class MyClass(object):
... pass
>>> from martiantest.fake import module_get_from_class_with_custom
>>> def custom_get_default(component, module, **data):
... return 'custom default'
>>> mydir.bind(get_default=custom_get_default).get(
... module_get_from_class_with_custom.MyClass)
'custom default'

CLASS scope directive on an instance, with a custom default::

>>> class mydir(Directive):
... scope = CLASS
... store = ONCE
>>> class module_get_from_instance_with_custom(FakeModule):
... class MyClass(object):
... pass
... obj = MyClass()
>>> from martiantest.fake import module_get_from_instance_with_custom
>>> mydir.bind(get_default=custom_get_default).get(
... module_get_from_instance_with_custom.obj)
'custom default'

CLASS_OR_MODULE scope directive on a module, with no explicit value::

>>> class mydir(Directive):
... scope = CLASS_OR_MODULE
... store = ONCE
>>> class module(FakeModule):
... fake_module = True
... pass
>>> from martiantest.fake import module
>>> mydir.bind().get(module) is None
True

CLASS_OR_MODULE scope directive on a class, with no explicit value::

>>> class mydir(Directive):
... scope = CLASS_OR_MODULE
... store = ONCE
>>> class module(FakeModule):
... fake_module = True
... class MyClass(object):
... pass
>>> from martiantest.fake import module
>>> mydir.bind().get(module.MyClass) is None
True

CLASS_OR_MODULE scope directive on an instance, with no explicit value::

>>> class mydir(Directive):
... scope = CLASS_OR_MODULE
... store = ONCE
>>> class module(FakeModule):
... fake_module = True
... class MyClass(object):
... pass
... obj = MyClass()
>>> from martiantest.fake import module
>>> mydir.bind().get(module.obj) is None
True

CLASS_OR_MODULE scope directive on a module, with an explicit value::

>>> class mydir(Directive):
... scope = CLASS_OR_MODULE
... store = ONCE
>>> class module(FakeModule):
... fake_module = True
... mydir('explicitly set, see?')
>>> from martiantest.fake import module
>>> mydir.bind().get(module)
'explicitly set, see?'

CLASS_OR_MODULE scope directive on a class, with an explicit value::

>>> class mydir(Directive):
... scope = CLASS_OR_MODULE
... store = ONCE
>>> class module(FakeModule):
... fake_module = True
... class MyClass(object):
... mydir('explicitly set, see?')
>>> from martiantest.fake import module
>>> mydir.bind().get(module.MyClass)
'explicitly set, see?'

CLASS_OR_MODULE scope directive on an instance, with an explicit value::

>>> class mydir(Directive):
... scope = CLASS_OR_MODULE
... store = ONCE
>>> class module(FakeModule):
... fake_module = True
... class MyClass(object):
... mydir('explicitly set, see?')
... obj = MyClass()
>>> from martiantest.fake import module
>>> mydir.bind().get(module.obj)
'explicitly set, see?'

CLASS_OR_MODULE scope directive on a module, with a custom default::

>>> class mydir(Directive):
... scope = CLASS_OR_MODULE
... store = ONCE
>>> class module(FakeModule):
... fake_module = True
>>> from martiantest.fake import module
>>> mydir.bind(get_default=custom_get_default).get(module)
'custom default'

CLASS_OR_MODULE scope directive on a class, with a custom default::

>>> class mydir(Directive):
... scope = CLASS_OR_MODULE
... store = ONCE
>>> class module(FakeModule):
... fake_module = True
... class MyClass(object):
... pass
>>> from martiantest.fake import module
>>> mydir.bind(get_default=custom_get_default).get(module.MyClass)
'custom default'

CLASS_OR_MODULE scope directive on an instance, with a custom default::

>>> class mydir(Directive):
... scope = CLASS_OR_MODULE
... store = ONCE
>>> class module(FakeModule):
... fake_module = True
... class MyClass(object):
... pass
... obj = MyClass()
>>> from martiantest.fake import module
>>> mydir.bind(get_default=custom_get_default).get(module.obj)
'custom default?'

0 comments on commit c14c3fd

Please sign in to comment.