Just deals with pathing concerns now.

This commit is contained in:
Sandy Walsh 2014-03-09 15:57:18 -03:00
parent f5cdec56df
commit 3c107fd54c
7 changed files with 148 additions and 23 deletions

View File

@ -2,3 +2,26 @@ simport
=======
Simple Import Library for Python
Supports importing functions or class methods from files
not in the Python Path.
Using Simport
=============
{{{
import simport
# For modules already in the Python Path
function = simport.load('mymodule.myfunction')
class_method = simport.load('mymodule:MyClass.mymethod')
# For modules not in the Python Path
function = simport.load('/path/to/file.py|module_name:myfunction')
class_method = simport.load('/path/to/file.py|module_name:MyClasss.mymethod')
}}}
Running Tests
=============
From the simport root directory, run `nosetests`

0
simport/__init__.py Normal file
View File

View File

@ -26,7 +26,7 @@ class MissingModule(Exception):
pass
class MissingFile(Exception):
class BadDirectory(Exception):
pass
@ -42,45 +42,47 @@ def _get_module(target):
".../file/path|module_name:function"
If a fully qualified file is specified, it implies the
file is not already on the Python Path. In this case,
the module name given will be assigned to this file.
file is not already on the Python Path, in which case
it will be added.
For example, if I import /home/foo/my_code.py (and
/home/foo is not in the python path) as
"/home/foo/my_code.py|mycode:MyClass.mymethod"
then the MyClass class will live under the newly created
mycode module and can be referenced as mycode.MyClass
then /home/foo will be added to the python path and
the module loaded as normal.
"""
filename, sep, namespace = target.rpartition('|')
# print "%s/%s/%s" % (filename, sep, namespace)
module, sep, klass_or_function = namespace.rpartition(':')
print "cwd:", os.getcwd()
directory, sep, namespace = target.rpartition('|')
module, sep, class_or_function = namespace.rpartition(':')
if not module:
raise MissingModule("Need a module path for %s (%s)" %
(namespace, target))
if filename:
if not module in sys.modules:
if os.path.isfile(filename):
imp.load_source(module, filename)
else:
raise MissingFile("Can not find %s" % filename)
if directory and directory not in sys.path:
print "add directory:", directory
if not os.path.isdir(directory):
raise BadDirectory("No such directory: '%s'" % directory)
sys.path.append(directory)
if not module in sys.modules:
__import__(module)
if not klass_or_function:
if not class_or_function:
raise MissingMethodOrFunction("No Method or Function specified")
klass, sep, function = klass_or_function.rpartition('.')
print "__IMPORT__"
__import__(module)
klass, sep, function = class_or_function.rpartition('.')
print "CLASS:", klass, "FUNCTION:", function
return module, klass, function
def simport(target):
def load(target):
"""Get the actual implementation of the target."""
module, klass, function = _get_module(target)
if not klass:
print "NOT CLASS"
return getattr(sys.modules[module], function)
klass_object = getattr(sys.modules[module], klass)
return getattr(klass_object, function)
print "DIR", dir(sys.modules[module])
class_object = getattr(sys.modules[module], klass)
return getattr(class_object, function)

0
tests/external/__init__.py vendored Normal file
View File

15
tests/external/externalmodule.py vendored Normal file
View File

@ -0,0 +1,15 @@
class Foo(object):
def method_a(self, a, b, c, d):
pass
class Blah(Foo):
def method_a(self, a, b, c, d):
pass
def method_b(self, a, b, c, e):
pass
def function_a(a, b, c, d):
pass

15
tests/localmodule.py Normal file
View File

@ -0,0 +1,15 @@
class Foo(object):
def method_a(self, a, b, c, d):
pass
class Blah(Foo):
def method_a(self, a, b, c, d):
pass
def method_b(self, a, b, c, e):
pass
def function_a(a, b, c):
return (a, b, c)

70
tests/test_simport.py Normal file
View File

@ -0,0 +1,70 @@
import sys
import unittest
from simport import simport
# Internal functions and classes.
def dummy_function():
pass
class DummyClass(object):
def method_a(self):
pass
class TestSimport(unittest.TestCase):
def test_bad_targets(self):
self.assertRaises(simport.MissingModule, simport._get_module,
"missing.py")
self.assertRaises(simport.MissingModule, simport._get_module,
"missing.py|")
self.assertRaises(simport.MissingModule, simport._get_module,
"simport_tests/localmodule.py|")
self.assertRaises(simport.MissingModule, simport._get_module,
"simport_tests/localmodule.py|Foo")
self.assertFalse("AnyModuleName" in sys.modules)
self.assertRaises(simport.MissingMethodOrFunction, simport._get_module,
"tests|AnyModuleName:")
self.assertFalse("AnyModuleName" in sys.modules)
def test_good_external_targets(self):
self.assertEquals(("localmodule", "Foo", "method_a"),
simport._get_module("tests|"
"localmodule:Foo.method_a"))
self.assertRaises(ImportError, simport._get_module,
"tests|that_module:function_a")
def test_bad_load(self):
self.assertRaises(AttributeError, simport.load,
"test_simport:missing")
def test_good_load_internal(self):
self.assertEquals(dummy_function,
simport.load("test_simport:dummy_function"))
self.assertEquals(DummyClass.method_a,
simport.load("test_simport:DummyClass.method_a"))
def test_good_load_local(self):
method = simport.load("tests|"
"localmodule:Foo.method_a")
import localmodule
self.assertEquals(method, localmodule.Foo.method_a)
self.assertEquals(localmodule.function_a,
simport.load("localmodule:function_a"))
def test_good_load_external(self):
method = simport.load("tests/external|"
"external.externalmodule:Blah.method_b")
self.assertTrue('external.externalmodule' in sys.modules)
old = sys.modules['external.externalmodule']
import external.externalmodule
self.assertEqual(external.externalmodule,
sys.modules['external.externalmodule'])
self.assertEqual(old, external.externalmodule)