Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
137
Merge Requests
137
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
nexedi
erp5
Commits
d52666e7
Commit
d52666e7
authored
Nov 04, 2015
by
Ayush Tiwari
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
erp5_data_notebook bt5: Handle case for jupyter_code as comments , giving empty nodelist
parent
e5184879
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
78 additions
and
77 deletions
+78
-77
bt5/erp5_data_notebook/ExtensionTemplateItem/portal_components/extension.erp5.JupyterCompile.py
...teItem/portal_components/extension.erp5.JupyterCompile.py
+74
-73
bt5/erp5_data_notebook/ExtensionTemplateItem/portal_components/extension.erp5.JupyterCompile.xml
...eItem/portal_components/extension.erp5.JupyterCompile.xml
+4
-4
No files found.
bt5/erp5_data_notebook/ExtensionTemplateItem/portal_components/extension.erp5.JupyterCompile.py
View file @
d52666e7
...
...
@@ -58,7 +58,7 @@ def Base_compileJupyterCode(self, jupyter_code, old_local_variable_dict):
# Saving the initial globals dict so as to compare it after code execution
globals_dict
=
globals
()
g
[
'context'
]
=
self
result_string
=
None
result_string
=
''
ename
,
evalue
,
tb_list
=
None
,
None
,
None
# Update globals dict and use it while running exec command
g
.
update
(
old_local_variable_dict
[
'variables'
])
...
...
@@ -69,87 +69,88 @@ def Base_compileJupyterCode(self, jupyter_code, old_local_variable_dict):
# TODO: This can be refactored by using client side error handling instead of
# catching errors on server/erp5.
status
=
u'ok'
local_variable_dict
=
old_local_variable_dict
# Execute only if jupyter_code is not empty
if
jupyter_code
:
# Import all the modules from local_variable_dict['imports']
# 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'
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
ast_node
=
ast
.
parse
(
jupyter_code
)
# Get the node list from the parsed tree
nodelist
=
ast_node
.
body
# If the last node is instance of ast.Expr, set its interactivity as 'last'
# This would be the case if the last node is expression
if
isinstance
(
nodelist
[
-
1
],
ast
.
Expr
):
interactivity
=
"last"
else
:
interactivity
=
"none"
# Here, we define which nodes to execute with 'single' and which to execute
# with 'exec' mode.
if
interactivity
==
'none'
:
to_run_exec
,
to_run_interactive
=
nodelist
,
[]
elif
interactivity
==
'last'
:
to_run_exec
,
to_run_interactive
=
nodelist
[:
-
1
],
nodelist
[
-
1
:]
old_stdout
=
sys
.
stdout
result
=
StringIO
()
sys
.
stdout
=
result
# Execute the nodes with 'exec' mode
for
node
in
to_run_exec
:
mod
=
ast
.
Module
([
node
])
code
=
compile
(
mod
,
'<string>'
,
"exec"
)
exec
(
code
,
g
,
g
)
# Execute the interactive nodes with 'single' mode
for
node
in
to_run_interactive
:
mod
=
ast
.
Interactive
([
node
])
code
=
compile
(
mod
,
'<string>'
,
"single"
)
exec
(
code
,
g
,
g
)
# Letting the code fail in case of error while executing the python script/code
# XXX: Need to be refactored so to acclimitize transactions failure as well as
# normal python code failure and show it to user on jupyter frontend.
# Decided to let this fail silently in backend without letting the frontend
# user know the error so as to let tranasction or its error be handled by ZODB
# in uniform way instead of just using half transactions.
sys
.
stdout
=
old_stdout
result_string
=
result
.
getvalue
()
else
:
result_string
=
jupyter_code
# Difference between the globals variable before and after exec/eval so that
# we don't have to save unnecessary variables in database which might or might
# not be picklabale
local_variable_dict
=
old_local_variable_dict
local_variable_dict_new
=
{
key
:
val
for
key
,
val
in
g
.
items
()
if
key
not
in
globals_dict
.
keys
()}
local_variable_dict
[
'variables'
].
update
(
local_variable_dict_new
)
# Differentiate 'module' objects from local_variable_dict and save them as
# string in the dict as {'imports': {'numpy': 'np', 'matplotlib': 'mp']}
if
'variables'
and
'imports'
in
local_variable_dict
:
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
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
# is made later on to local_variable_dict['variables'] dictionary
local_variable_dict
[
'variables'
].
pop
(
key
)
# Handle case for empty nodelist(in case of comments as jupyter_code)
if
nodelist
:
# Import all the modules from local_variable_dict['imports']
# 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'
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
)
# If the last node is instance of ast.Expr, set its interactivity as 'last'
# This would be the case if the last node is expression
if
isinstance
(
nodelist
[
-
1
],
ast
.
Expr
):
interactivity
=
"last"
else
:
interactivity
=
"none"
# Here, we define which nodes to execute with 'single' and which to execute
# with 'exec' mode.
if
interactivity
==
'none'
:
to_run_exec
,
to_run_interactive
=
nodelist
,
[]
elif
interactivity
==
'last'
:
to_run_exec
,
to_run_interactive
=
nodelist
[:
-
1
],
nodelist
[
-
1
:]
old_stdout
=
sys
.
stdout
result
=
StringIO
()
sys
.
stdout
=
result
# Execute the nodes with 'exec' mode
for
node
in
to_run_exec
:
mod
=
ast
.
Module
([
node
])
code
=
compile
(
mod
,
'<string>'
,
"exec"
)
exec
(
code
,
g
,
g
)
# Execute the interactive nodes with 'single' mode
for
node
in
to_run_interactive
:
mod
=
ast
.
Interactive
([
node
])
code
=
compile
(
mod
,
'<string>'
,
"single"
)
exec
(
code
,
g
,
g
)
# Letting the code fail in case of error while executing the python script/code
# XXX: Need to be refactored so to acclimitize transactions failure as well as
# normal python code failure and show it to user on jupyter frontend.
# Decided to let this fail silently in backend without letting the frontend
# user know the error so as to let tranasction or its error be handled by ZODB
# in uniform way instead of just using half transactions.
sys
.
stdout
=
old_stdout
result_string
=
result
.
getvalue
()
# Difference between the globals variable before and after exec/eval so that
# we don't have to save unnecessary variables in database which might or might
# not be picklabale
local_variable_dict_new
=
{
key
:
val
for
key
,
val
in
g
.
items
()
if
key
not
in
globals_dict
.
keys
()}
local_variable_dict
[
'variables'
].
update
(
local_variable_dict_new
)
# Differentiate 'module' objects from local_variable_dict and save them as
# string in the dict as {'imports': {'numpy': 'np', 'matplotlib': 'mp']}
if
'variables'
and
'imports'
in
local_variable_dict
:
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
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
# is made later on to local_variable_dict['variables'] dictionary
local_variable_dict
[
'variables'
].
pop
(
key
)
result
=
{
'result_string'
:
result_string
,
...
...
bt5/erp5_data_notebook/ExtensionTemplateItem/portal_components/extension.erp5.JupyterCompile.xml
View file @
d52666e7
...
...
@@ -47,10 +47,10 @@
<value>
<tuple>
<string>
W: 50, 2: Using the global statement (global-statement)
</string>
<string>
W:
82, 6
: Use of exec (exec-used)
</string>
<string>
W:11
1, 6
: Use of exec (exec-used)
</string>
<string>
W:1
17, 6
: Use of exec (exec-used)
</string>
<string>
W:21
2
, 4: Using the global statement (global-statement)
</string>
<string>
W:
91, 8
: Use of exec (exec-used)
</string>
<string>
W:11
5, 8
: Use of exec (exec-used)
</string>
<string>
W:1
21, 8
: Use of exec (exec-used)
</string>
<string>
W:21
3
, 4: Using the global statement (global-statement)
</string>
</tuple>
</value>
</item>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment