Tab completion
Closed this issue · 3 comments
If I open ipython/similar and do
import cofi_espresso
cofi_espresso.<TAB>
or
from cofi_espresso import <TAB>
I see a list containing both modules and classes (e.g. both xray_tomography
and XrayTomography
). I think this is confusing and it would be better just to see the class.
I think this is related to this SO issue.
I'm not sure what the best solution is. However, I found the following email that I had sent Hannes when he first started looking into how to do this:
Re. importlib: I think you can do something like the following.
inversiontestproblems/
| __init__.py <— (A)
| contrib/
| | __init__.py <— (blank)
| | first-example-directory/
| | | __init__.py <— (B)
| | another-directory/
| | | __init__.py <— (C)
| | | data/
| | | | __init__.py <— (blank)
| | | | data.dat
with the following __init__.py files
__init__.py (A):
import importlib
# Get the object ‘Ex1’ from ‘first-example-directory’ and rename it ‘ExampleOne'
ExampleOne = getattr(importlib.import_module("inversiontestproblems.contrib.first-example-directory”), “Ex1”)
# Get the object ‘MyTestProblem’ from ‘another-directory’ and rename it ‘ExampleTwo'
ExampleTwo = getattr(importlib.import_module(“inversiontestproblems.contrib.another-directory”),”MyTestProblem”)
__init__.py (B):
class Ex1:
def __init__(self):
…….
__init__.py (C):
from importlib.resources import open_text
def loaddata(file):
# Code to read a data file
with open(file,’r’) as fp:
fp.readlines()
…..
return data
class MyTestProblem:
def __init__(self):
…..
def _getdata(self):
# Automagically resolve location/type of distributed data and hand to loaddata()
data = loaddata(open_text(__package__+”.data”,”data.dat”))
…...
Then users can do something like:
from inversiontestproblems import ExampleOne as example
ex = example()
ex.forward()
and simply changing ‘ExampleOne’ to ‘ExampleTwo’ should work seamlessly.
I think there are variations on this theme, e.g. you can do something like
import module as ClassName
ClassName = ClassName.ClassName
Keen to hear thoughts -- I'm not sure what the right thing to do is!
This SO answer looks promising.
But this only helps
import cofi_espresso
cofi_espresso.<TAB>
not
from cofi_espresso import <TAB>
An experimental implementation can be found in this tab_completion branch.
I think importlib
can fix this, just not entirely sure if it's worth it (not following the convention to achieve this). Maybe there isn't really a convention thing in Python anyway. Will update with importlib
soon.
Using importlib to manually import the contribution classes doesn't quite work. Am I missing something here? @valentineap
The change for using importlib
is here: 0c76f75
The previous change with del <contrib_path>
is here: f8f652b
I'll take another look next week.
This SO answer looks promising.
But this only helps
import cofi_espresso cofi_espresso.<TAB>not
from cofi_espresso import <TAB>An experimental implementation can be found in this tab_completion branch.
I think
importlib
can fix this, just not entirely sure if it's worth it (not following the convention to achieve this). Maybe there isn't really a convention thing in Python anyway. Will update withimportlib
soon.
It seems impossible to hide the files and folders when you do from cofi_espresso import <TAB>
. Because when you do from <module> import <something>
, it checks files/folders under the module, instead of checking the namespaces (names available after you import the module).
Alternatively, adding underscores to the contrib folder names might make sense (so that even though they are still displayed, they are not at the front):
In [1]: from cofi_espresso import <TAB>
EspressoProblem GravityDensity SimpleRegression _espresso_problem _simple_regression __all__ __name__
exceptions list_problem_names() utils _fmm_tomography _version __doc__ __package__
FmmTomography list_problems XrayTomography _gravity_density _xray_tomography __file__ __version__