forked from ipython/ipynb
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
228 additions
and
498 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,113 +1,119 @@ | ||
|
||
# coding: utf-8 | ||
|
||
# # The [Import Loader](https://docs.python.org/3/reference/import.html#loaders) | ||
|
||
# In[1]: | ||
|
||
|
||
try: | ||
from .compiler import Compile, AST | ||
from .exporter import Compile, AST | ||
except ModuleNotFoundError: | ||
from compiler import Compile, AST | ||
from exporter import Compile, AST | ||
import inspect, sys | ||
from importlib.machinery import SourceFileLoader | ||
from importlib._bootstrap_external import FileFinder | ||
from importlib import reload | ||
from traceback import print_exc | ||
|
||
|
||
# In[2]: | ||
|
||
|
||
def update_path_hooks(loader: SourceFileLoader, extensions: tuple=None, lazy=False): | ||
def update_path_hooks(loader: SourceFileLoader, extensions: tuple = None, lazy=False): | ||
"""Update the FileFinder loader in sys.path_hooks to accomodate a {loader} with the {extensions}""" | ||
from importlib.util import LazyLoader | ||
|
||
for id, hook in enumerate(sys.path_hooks): | ||
try: | ||
closure = inspect.getclosurevars(hook).nonlocals | ||
except TypeError: continue | ||
if issubclass(closure['cls'], FileFinder): | ||
except TypeError: | ||
continue | ||
if issubclass(closure["cls"], FileFinder): | ||
sys.path_hooks.pop(id) | ||
sys.path_hooks.insert(id, FileFinder.path_hook(*( | ||
((lazy and LazyLoader.factory(loader) or loader, extensions),) | ||
if (loader and extensions) | ||
else tuple() | ||
) + tuple( | ||
(cls, ext) | ||
for cls, ext in closure['loader_details'] | ||
if not issubclass(cls, loader) # Need to add logic for lazy loaders before they may be introduced. | ||
))) | ||
sys.path_hooks.insert( | ||
id, | ||
FileFinder.path_hook( | ||
*( | ||
((lazy and LazyLoader.factory(loader) or loader, extensions),) | ||
if (loader and extensions) | ||
else tuple() | ||
) | ||
+ tuple( | ||
(cls, ext) | ||
for cls, ext in closure["loader_details"] | ||
if not issubclass( | ||
cls, loader | ||
) # Need to add logic for lazy loaders before they may be introduced. | ||
) | ||
), | ||
) | ||
sys.path_importer_cache.clear() | ||
|
||
|
||
# In[3]: | ||
|
||
|
||
class ImportContextMixin: | ||
def __enter__(self): update_path_hooks(type(self), self.EXTENSION_SUFFIXES) | ||
def __exit__(self, exception_type=None, exception_value=None, traceback=None): update_path_hooks(type(self)) | ||
|
||
def __enter__(self): | ||
update_path_hooks(type(self), self.EXTENSION_SUFFIXES) | ||
|
||
# In[4]: | ||
def __exit__(self, exception_type=None, exception_value=None, traceback=None): | ||
update_path_hooks(type(self)) | ||
|
||
|
||
class Notebook(SourceFileLoader, ImportContextMixin): | ||
"""A SourceFileLoader for notebooks that provides line number debugginer in the JSON source.""" | ||
EXTENSION_SUFFIXES = '.ipynb', | ||
def __init__(self, fullname=None, path=None, *,capture=True): | ||
EXTENSION_SUFFIXES = ".ipynb", | ||
|
||
def __init__(self, fullname=None, path=None, *, capture=True): | ||
self.capture = capture | ||
super().__init__(fullname, path) | ||
|
||
def exec_module(Loader, module): | ||
module.__output__ = None | ||
if Loader.capture: return Loader.exec_module_capture(module) | ||
else: return super().exec_module(module) | ||
|
||
if Loader.capture: | ||
return Loader.exec_module_capture(module) | ||
else: | ||
return super().exec_module(module) | ||
|
||
def exec_module_capture(Loader, module): | ||
from IPython.utils.capture import capture_output | ||
with capture_output(stdout=False, stderr=False) as output: | ||
try: super().exec_module(module) | ||
except type('pass', (BaseException,), {}): ... | ||
finally: module.__output__ = output | ||
from IPython.utils.capture import capture_output | ||
|
||
with capture_output(stdout=False, stderr=False) as output: | ||
try: | ||
super().exec_module(module) | ||
except type("pass", (BaseException,), {}): | ||
... | ||
finally: | ||
module.__output__ = output | ||
return module | ||
|
||
def source_to_code(Notebook, data, path): | ||
with __import__('io').BytesIO(data) as stream: | ||
with __import__("io").BytesIO(data) as stream: | ||
return Compile().from_file(stream, filename=Notebook.path, name=Notebook.name) | ||
|
||
|
||
# In[5]: | ||
|
||
|
||
class Partial(Notebook): | ||
|
||
def exec_module(loader, module): | ||
try: super().exec_module(module) | ||
try: | ||
super().exec_module(module) | ||
except BaseException as exception: | ||
try: raise ImportWarning("""{name} from {file} failed to load completely.""".format( | ||
name=module.__name__, file=module.__file__ | ||
)) | ||
try: | ||
raise ImportWarning( | ||
"""{name} from {file} failed to load completely.""".format( | ||
name=module.__name__, file=module.__file__ | ||
) | ||
) | ||
except ImportWarning as error: | ||
if not loader.capture: print_exc() | ||
if not loader.capture: | ||
print_exc() | ||
module.__exception__ = exception | ||
return module | ||
|
||
|
||
# # IPython Extensions | ||
|
||
# In[6]: | ||
|
||
|
||
def load_ipython_extension(ip=None): Notebook().__enter__() | ||
def unload_ipython_extension(ip=None): Notebook().__exit__() | ||
|
||
def load_ipython_extension(ip=None): | ||
Notebook().__enter__() | ||
|
||
# # Developer | ||
|
||
# In[7]: | ||
def unload_ipython_extension(ip=None): | ||
Notebook().__exit__() | ||
|
||
|
||
if __name__ == '__main__': | ||
get_ipython().system('jupyter nbconvert --to script --TemplateExporter.exclude_input_prompt=True __init__.ipynb') | ||
if __name__ == "__main__": | ||
try: | ||
from .compiler_python import ScriptExporter | ||
except: | ||
from compiler_python import ScriptExporter | ||
from pathlib import Path | ||
|
||
Path("__init__.py").write_text(ScriptExporter().from_filename("__init__.ipynb")[0]) | ||
__import__("doctest").testmod() |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.