Thanks Jeremy! Here is the function I use to find out how many callables in a module and how many items are included inside module.__all__ if available. But compared with __all__, checking out all the callables isn’t very useful after all.
def countFunc(mo, # module, e.g., `import fastcore.all as fa`, use `fa` here
dun:bool=False, # print items in __all__
cal:bool=False # print all callables
):
'count how many callables are in the module and how many items included in __all__'
full = dir(mo)
all_func = [getattr(mo, i) for i in full]
count = 0
for i in all_func:
if callable(i):
count = count + 1
else:
all_func.remove(i)
num_all = 0 if hasattr(mo, "__all__") == False else len(mo.__all__)
print(f"there are {count} callables in {mo.__name__} and {num_all} items in its __all__")
if hasattr(mo, "__all__") == True and dun: pprint(mo.__all__)
if cal: pprint(all_func)
Now, I have upgraded this function to be able to tell you everything you may want to know about a module.
def whatinside(mo, # module, e.g., `import fastcore.all as fa`, use `fa` here
dun:bool=False, # print all items in __all__
func:bool=False, # print all user defined functions
clas:bool=False, # print all class objects
bltin:bool=False, # print all builtin funcs or methods
lib:bool=False, # print all the modules of the library it belongs to
cal:bool=False # print all callables
):
'Check what inside a module: __all__, functions, classes, builtins, and callables'
dun_all = len(mo.__all__) if hasattr(mo, "__all__") else 0
funcs = getmembers(mo, isfunction)
classes = getmembers(mo, isclass)
builtins = getmembers(mo, isbuiltin)
callables = getmembers(mo, callable)
pkgpath = os.path.dirname(mo.__file__)
print(f"{mo.__name__} has: \n{dun_all} items in its __all__, and \n{len(funcs)} user defined functions, \n{len(classes)} classes or class objects, \n{len(builtins)} builtin funcs and methods, and\n{len(callables)} callables.\n")
if hasattr(mo, "__all__") and dun: pprint(mo.__all__)
if func:
print(f'The user defined functions are:')
pprint([i[0] for i in funcs])
if clas:
print(f'The class objects are:')
pprint([i[0] for i in classes])
if bltin:
print(f'The builtin functions or methods are:')
pprint([i[0] for i in builtins])
if cal:
print(f'The callables are: ')
pprint([i[0] for i in callables])
if lib:
modules = [name for _, name, _ in pkgutil.iter_modules([pkgpath])]
print(f'The library has {len(modules)} modules')
pprint(modules)
I am exploring the source on _mk_param and use_kwargs_dic of fastcore, and like the idea of forcing Parameter to change kind from POSITIONAL_OR_KEYWORD to KEYWORD_ONLY. I think this may help to solve a tiny problem of fastcore.meta.delegates I noticed when exploring it.
The problem is presented in the first image below, and the solution learnt from _mk_param and use_kwargs_dict is in the second image.
Thanks for the sharing! They seem very helpful. I will look into them later.
At the moment, my nbdev project is broken and I can’t update the site for you to read the experiment I was doing. I will update the link here as soon as I fix it.
I have pushed a PR, and I realised I need to make a few more changes to make the PR right
I need to change my current python 3.9 to become fastcore’s python>=3.7
remove the table of content of 07_meta.ipynb
Besides nbdev_prepare and nbdev_preview, should I run the 07_meta.ipynb to update all the outputs? When I check the PR for difference, there are many other files have been changed as a result, should I be worried about them?
How to setup base environment and install fastai with python>=3.7?
The steps I took to setup everything are:
0. remove mambaforge folder
bash Mambaforge-*.sh -b and ~/mambaforge/bin/conda init $SHELL_NAME
mamba install -c fastchan fastai
Note: up to this point, the python is version 3.9 in base env and 3.7 in ipython, and fastai is not available in ipython
mamba install jupyter
Note: up to this point, the python is version 3.9 in ipython too, and fastai is available in ipython
mamba install -c fastai nbdev
pip install jupyter_contrib_nbextensions
How do I get my python version to 3.7 for fastai and fastcore developement?
Thank you Jeremy! Your code review is very helpful, and I have shortened the code with your recommendation, and pushed again without rerunning all the cells so that it didn’t generate all the differences in cell outputs.
For total bigginer I recommend this course : https://www.py4e.com
Everything is free and it is more practical than other bigger friendly courses.
I have flashcard for this book and some of python documentation. Feel free to contact me I will share it with you.However I put sometime way more stuff in one card than I should. (I did not obey flashcard rule).
If you ever read the source code of fastcore and have found concepts like metaclass, super, __new__, __call__ intimidating. The following tutorials should give you a good understanding to move on in reading the source, as they did for me.
Here is the code I use to achieve the incorrectly aligned version. Could anyone help me to get the alignment right? Thanks
blocks = """
if to is None:
to_f,from_f = f.__base__.__init__,f.__init__
else:
to_f,from_f = to.__init__ if isinstance(to,type) else to,f
"""
lst = blocks.split('\n')
for l in lst:
print('{:>157}'.format(l))