Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed subpackage support.

  • Loading branch information...
commit 4088a72eabf2054cf38875242e12ab9713c21bc5 1 parent ffdb671
@mkleehammer authored
View
23 kelvin/__init__.py
@@ -325,18 +325,31 @@ def expand_packages(self, finder):
for dirpath, dirnames, filenames in os.walk(root):
if '__init__.py' not in filenames:
- del dirnames[:] # do not descend
+ # This directory does not have an __init__.py file, so it is not a Python package. Do not
+ # include the files here and do not descend into subdirectories. (os.walk descends into the
+ # subdirectories in dirnames and allows you to modify it, so remove all subdirectories.)
+ del dirnames[:]
continue
for filename in filenames:
if not filename.endswith('.py'):
continue
+
+ fqn = join(dirpath, filename)
+
if filename == '__init__.py':
- # Already in the list (is `package` actually).
- continue
+ # If the __init__.py is for a subpackage, we need it. If it is for the top-level package,
+ # we already have it since it is how we got here.
+ if dirpath == root:
+ continue
+
+ # Do not include the __init__ in the module name - it should just be the package name.
+ name = dirname(fqn)[prefixlen:].replace('\\', '.')
+
+ else:
+ # The name is the package plus the module.
+ name = fqn[prefixlen:-3].replace('\\', '.')
- fqn = join(dirpath, filename)
- name = fqn[prefixlen:-3].replace('\\', '.')
if name not in finder.modules:
finder.modules[name] = modulefinder.Module(name, fqn)
View
21 test/hello.py
@@ -9,11 +9,32 @@ def test_includes():
m = __import__('dynload')
m.test()
+
def test_extension():
import ssl
+
+def test_subpackage():
+ """
+ Ensure subpackages are automatically added by importing a module from sub1 then dynamically importing a module from
+ sub1.sub2. The sub1 import should cause Kelvin to include everything from sub1 down.
+ """
+ from sub1 import sub1mod
+ sub1mod.f()
+
+ pkg = 'sub1.sub2.sub2mod'
+ m = __import__(pkg)
+ # Python returns the top level.
+ for attr in pkg.split('.')[1:]:
+ m = getattr(m, attr)
+
+ m.f()
+
+
if __name__ == '__main__':
print('hello is main!')
test_includes()
test_extension()
+ test_subpackage()
+
View
1  test/sub1/__init__.py
@@ -0,0 +1 @@
+
View
4 test/sub1/sub1mod.py
@@ -0,0 +1,4 @@
+
+def f():
+ print('This is sub1!')
+
View
1  test/sub1/sub2/__init__.py
@@ -0,0 +1 @@
+
View
4 test/sub1/sub2/sub2mod.py
@@ -0,0 +1,4 @@
+
+def f():
+ print('This is sub2!')
+
Please sign in to comment.
Something went wrong with that request. Please try again.