Skip to content

Commit

Permalink
fixed fakemodule under python3
Browse files Browse the repository at this point in the history
  • Loading branch information
Samuel Riolo committed Apr 15, 2015
1 parent 278ad0d commit 5d09f05
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 35 deletions.
4 changes: 2 additions & 2 deletions src/martian/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Let's look at the framework::
...
... Returns the rendered template
... """
... template = templating.extension_handlers[extension](data)
... template = extension_handlers[extension](data)
... return template.render(**kw)

Since normally we cannot create modules in a doctest, we have emulated
Expand Down Expand Up @@ -253,7 +253,7 @@ Martian style base class and annotations::
...
... def render(data, extension, **kw):
... # this hasn't changed
... template = templating.extension_handlers[extension](data)
... template = extension_handlers[extension](data)
... return template.render(**kw)
>>> from martiantest.fake import templating

Expand Down
6 changes: 3 additions & 3 deletions src/martian/core.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ extensions::
...
... def handle(filepath):
... name, ext = os.path.splitext(filepath)
... return filehandler.extension_handlers[ext](filepath)
... return extension_handlers[ext](filepath)
>>> from martiantest.fake import filehandler

Now let's try the ``handle`` function for a few file types::
Expand Down Expand Up @@ -191,7 +191,7 @@ original module and take out the manual registrations completely::
...
... def handle(filepath):
... name, ext = os.path.splitext(filepath)
... return filehandler.extension_handlers[ext](filepath)
... return extension_handlers[ext](filepath)
>>> from martiantest.fake import filehandler

Let's use martian to do the registrations for us::
Expand Down Expand Up @@ -403,7 +403,7 @@ Let's test our grokker::

We can create a snake now::

>>> animal.create_animal('snake')
>>> create_animal('snake')
<Animal snake>

Note that we can supply a different default value for the directive
Expand Down
42 changes: 12 additions & 30 deletions src/martian/testing.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import sys
from types import ModuleType
from types import FunctionType

def fake_import(fake_module):
module_name = 'martiantest.fake.' + fake_module.__name__
Expand Down Expand Up @@ -38,8 +39,11 @@ def fake_import(fake_module):
continue
obj = getattr(module, name)
try:
code = obj.func_code
new_func = new.function(code, glob, name)
if hasattr(obj, 'func_code'):
code = obj.func_code
else:
code = obj.__code__
new_func = FunctionType(code, glob, name)
new_func.__module__ = module.__name__
setattr(module, name, new_func)
glob[name] = new_func
Expand All @@ -54,44 +58,22 @@ def fake_import(fake_module):
sys.modules[module_name] = module
setattr(sys.modules['martiantest.fake'], module_name.split('.')[-1],
module)

return module

class FakeModuleMetaclass(type):
def __init__(cls, classname, bases, dict_):
fake_import(cls)
return type.__init__(cls, classname, bases, dict_)

if sys.version_info[0] < 3:
class FakeModule(object):
__metaclass__ = FakeModuleMetaclass
else:
class FakeModule(object, metaclass = FakeModuleMetaclass):
pass


class FakeModuleObjectMetaclass(type):
""" Base metaclass to replace object in a fake Module.
In python 3 we need to change the class name for
inner classes. So all test will run in python 2 and 3.
Without this class the name of fakemodule will be
shown double in the class name, like this:
<class 'martiantest.fake.basemodule.basemodule.A'>
If this class name is returned, the doctest will fail.
"""

def __init__(cls, classname, bases, dict_):
normalname = cls.__qualname__.split('.')[-1:][0]
dict_['__qualname__'] = normalname
cls.__qualname__ = dict_['__qualname__']
return type.__init__(cls, classname, bases, dict_)


if sys.version_info[0] < 3:
class FakeModuleObject(object):
pass

class FakeModule(object):
__metaclass__ = FakeModuleMetaclass
else:
class FakeModuleObject(object, metaclass = FakeModuleObjectMetaclass):
pass
from matian.testing_compat import FakeModule
from matian.testing_compat import FakeModuleObject


32 changes: 32 additions & 0 deletions src/martian/testing_compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import pdb;pdb.set_trace()
""" Just python classes that only work in
python3. In python < 3 you will get a syntax error.
"""

from martian.testing import FakeModuleMetaclass


class FakeModuleObjectMetaclass(type):
""" Base metaclass to replace object in a fake Module.
In python 3 we need to change the class name for
inner classes. So all test will run in python 2 and 3.
Without this class the name of fakemodule will be
shown double in the class name, like this:
<class 'martiantest.fake.basemodule.basemodule.A'>
If this class name is returned, the doctest will fail.
"""

def __init__(cls, classname, bases, dict_):
normalname = cls.__qualname__.split('.')[-1:][0]
dict_['__qualname__'] = normalname
cls.__qualname__ = dict_['__qualname__']
return type.__init__(cls, classname, bases, dict_)


class FakeModuleObject(object, metaclass = FakeModuleObjectMetaclass):
pass


class FakeModule(object, metaclass = FakeModuleMetaclass):
pass

0 comments on commit 5d09f05

Please sign in to comment.