Show More
@@ -154,6 +154,17 b' def is_importable(module, attr, only_modules):' | |||
|
154 | 154 | else: |
|
155 | 155 | return not(attr[:2] == '__' and attr[-2:] == '__') |
|
156 | 156 | |
|
157 | def is_possible_submodule(module, attr): | |
|
158 | try: | |
|
159 | obj = getattr(module, attr) | |
|
160 | except AttributeError: | |
|
161 | # Is possilby an unimported submodule | |
|
162 | return True | |
|
163 | except TypeError: | |
|
164 | # https://github.com/ipython/ipython/issues/9678 | |
|
165 | return False | |
|
166 | return inspect.ismodule(obj) | |
|
167 | ||
|
157 | 168 | |
|
158 | 169 | def try_import(mod: str, only_modules=False) -> List[str]: |
|
159 | 170 | """ |
@@ -172,7 +183,12 b' def try_import(mod: str, only_modules=False) -> List[str]:' | |||
|
172 | 183 | completions.extend( [attr for attr in dir(m) if |
|
173 | 184 | is_importable(m, attr, only_modules)]) |
|
174 | 185 | |
|
175 |
|
|
|
186 | m_all = getattr(m, "__all__", []) | |
|
187 | if only_modules: | |
|
188 | completions.extend(attr for attr in m_all if is_possible_submodule(m, attr)) | |
|
189 | else: | |
|
190 | completions.extend(m_all) | |
|
191 | ||
|
176 | 192 | if m_is_init: |
|
177 | 193 | completions.extend(module_list(os.path.dirname(m.__file__))) |
|
178 | 194 | completions_set = {c for c in completions if isinstance(c, str)} |
@@ -157,6 +157,11 b' def test_bad_module_all():' | |||
|
157 | 157 | nt.assert_in('puppies', results) |
|
158 | 158 | for r in results: |
|
159 | 159 | nt.assert_is_instance(r, str) |
|
160 | ||
|
161 | # bad_all doesn't contain submodules, but this completion | |
|
162 | # should finish without raising an exception: | |
|
163 | results = module_completion("import bad_all.") | |
|
164 | nt.assert_equal(results, []) | |
|
160 | 165 | finally: |
|
161 | 166 | sys.path.remove(testsdir) |
|
162 | 167 | |
@@ -176,3 +181,14 b' def test_module_without_init():' | |||
|
176 | 181 | assert s == [] |
|
177 | 182 | finally: |
|
178 | 183 | sys.path.remove(tmpdir) |
|
184 | ||
|
185 | ||
|
186 | def test_valid_exported_submodules(): | |
|
187 | """ | |
|
188 | Test checking exported (__all__) objects are submodules | |
|
189 | """ | |
|
190 | results = module_completion("import os.pa") | |
|
191 | # ensure we get a valid submodule: | |
|
192 | nt.assert_in("os.path", results) | |
|
193 | # ensure we don't get objects that aren't submodules: | |
|
194 | nt.assert_not_in("os.pathconf", results) |
General Comments 0
You need to be logged in to leave comments.
Login now