Commit 6487e06a authored by Ayush Tiwari's avatar Ayush Tiwari

erp5_data_notebook bt5: Use dictionary to save module imports instead of...

erp5_data_notebook bt5: Use dictionary to save module imports instead of saving it as list of strings.

Using dictinary its easier to update modules frequently.

For example, executing code:

'''
import numpy as np
import numpy
'''

would result as :
local_variable_dict['imports'] = {'numpy': 'numpy', 'np': 'numpy'}
which is what we expect to be saved in globals() also.
parent b4822340
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from StringIO import StringIO from StringIO import StringIO
from persistent.list import PersistentList
from Products.ERP5Type.Globals import PersistentMapping from Products.ERP5Type.Globals import PersistentMapping
import sys import sys
...@@ -14,14 +13,14 @@ def Base_compileJupyterCode(self, jupyter_code, old_local_variable_dict): ...@@ -14,14 +13,14 @@ def Base_compileJupyterCode(self, jupyter_code, old_local_variable_dict):
Code execution depends on 'interactivity', a.k.a , if the ast.node object has Code execution depends on 'interactivity', a.k.a , if the ast.node object has
ast.Expr instance(valid for expressions) or not. ast.Expr instance(valid for expressions) or not.
old_local_variable_dict should contain both variables dict and imports list. old_local_variable_dict should contain both variables dict and modules imports.
Here, imports list is basically a list of code lines which would be run Here, imports dict is key, value pair of modules and their name in sys.path,
executed separately everytime before execution of jupyter_code to populate executed separately everytime before execution of jupyter_code to populate
sys modules beforehand. sys modules beforehand.
For example : For example :
old_local_variable_dict = { old_local_variable_dict = {
'imports': ['import numpy as np', 'import sys as sys'], 'imports': {'numpy': 'np', 'sys': 'sys'},
'variables': {'np.split': <function split at 0x7f4e6eb48b90>} 'variables': {'np.split': <function split at 0x7f4e6eb48b90>}
} }
...@@ -65,9 +64,13 @@ def Base_compileJupyterCode(self, jupyter_code, old_local_variable_dict): ...@@ -65,9 +64,13 @@ def Base_compileJupyterCode(self, jupyter_code, old_local_variable_dict):
# Execute only if jupyter_code is not empty # Execute only if jupyter_code is not empty
if jupyter_code: if jupyter_code:
# Import all the modules from local_variable_dict['imports'] # Import all the modules from local_variable_dict['imports']
import_statement_code = '\n'.join(old_local_variable_dict['imports']) # While any execution, in locals() dict, a module is saved as:
# code : 'from os import path'
exec(import_statement_code, g, g) # {'path': <module 'posixpath'>}
# So, here we would try to get the name 'posixpath' and import it as 'path'
for k, v in old_local_variable_dict['imports'].iteritems():
import_statement_code = 'import %s as %s'%(v, k)
exec(import_statement_code, g, g)
# Create ast parse tree # Create ast parse tree
ast_node = ast.parse(jupyter_code) ast_node = ast.parse(jupyter_code)
...@@ -124,21 +127,20 @@ def Base_compileJupyterCode(self, jupyter_code, old_local_variable_dict): ...@@ -124,21 +127,20 @@ def Base_compileJupyterCode(self, jupyter_code, old_local_variable_dict):
local_variable_dict['variables'].update(local_variable_dict_new) local_variable_dict['variables'].update(local_variable_dict_new)
# Differentiate 'module' objects from local_variable_dict and save them as # Differentiate 'module' objects from local_variable_dict and save them as
# string in the dict as {'imports': ['import numpy as np', 'import matplotlib as mp']} # string in the dict as {'imports': {'numpy': 'np', 'matplotlib': 'mp']}
if 'variables' in local_variable_dict: if 'variables' and 'imports' in local_variable_dict:
for key, val in local_variable_dict['variables'].items(): for key, val in local_variable_dict['variables'].items():
# Check if the val in the dict is ModuleType and remove it in case it is # Check if the val in the dict is ModuleType and remove it in case it is
if isinstance(val, types.ModuleType): if isinstance(val, types.ModuleType):
# Update local_variable_dict['imports'] dictionary with key, value pairs
# with key corresponding to module name as its imported and value as the
# module name being stored in sys.path
# For example : 'np': <numpy module at ...> -- {'np': numpy}
local_variable_dict['imports'][key] = val.__name__
# XXX: The next line is mutating the dict, beware in case any reference # XXX: The next line is mutating the dict, beware in case any reference
# is made later on to local_variable_dict['variables'] dictionary # is made later on to local_variable_dict['variables'] dictionary
local_variable_dict['variables'].pop(key) local_variable_dict['variables'].pop(key)
# While any execution, in locals() dict, a module is saved as:
# code : 'from os import path'
# {'path': <module 'posixpath'>}
# So, here we would try to get the name 'posixpath' and import it as 'path'
module_name = val.__name__
import_statement = 'import %s as %s'%(module_name, key)
local_variable_dict['imports'].append(import_statement)
result = { result = {
'result_string': result_string, 'result_string': result_string,
...@@ -157,9 +159,9 @@ def AddNewLocalVariableDict(self): ...@@ -157,9 +159,9 @@ def AddNewLocalVariableDict(self):
""" """
new_dict = PersistentMapping() new_dict = PersistentMapping()
variable_dict = PersistentMapping() variable_dict = PersistentMapping()
import_list = PersistentList() module_dict = PersistentMapping()
new_dict['variables'] = variable_dict new_dict['variables'] = variable_dict
new_dict['imports'] = import_list new_dict['imports'] = module_dict
return new_dict return new_dict
def UpdateLocalVariableDict(self, existing_dict): def UpdateLocalVariableDict(self, existing_dict):
...@@ -169,6 +171,7 @@ def UpdateLocalVariableDict(self, existing_dict): ...@@ -169,6 +171,7 @@ def UpdateLocalVariableDict(self, existing_dict):
new_dict = self.Base_addLocalVariableDict() new_dict = self.Base_addLocalVariableDict()
for key, val in existing_dict['variables'].iteritems(): for key, val in existing_dict['variables'].iteritems():
new_dict['variables'][key] = val new_dict['variables'][key] = val
new_dict['imports'] = PersistentList(existing_dict['imports']) for key, val in existing_dict['imports'].iteritems():
new_dict['imports'][key] = val
return new_dict return new_dict
\ No newline at end of file
...@@ -46,9 +46,9 @@ ...@@ -46,9 +46,9 @@
<key> <string>text_content_warning_message</string> </key> <key> <string>text_content_warning_message</string> </key>
<value> <value>
<tuple> <tuple>
<string>W: 70, 4: Use of exec (exec-used)</string> <string>W: 73, 6: Use of exec (exec-used)</string>
<string>W: 99, 6: Use of exec (exec-used)</string> <string>W:102, 6: Use of exec (exec-used)</string>
<string>W:105, 6: Use of exec (exec-used)</string> <string>W:108, 6: Use of exec (exec-used)</string>
</tuple> </tuple>
</value> </value>
</item> </item>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment