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
7
Merge Requests
7
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
Jérome Perrin
erp5
Commits
d936b141
Commit
d936b141
authored
Nov 04, 2019
by
Jérome Perrin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
jedi save point
parent
08c10242
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
281 additions
and
47 deletions
+281
-47
bt5/erp5_monaco_editor/ExtensionTemplateItem/portal_components/extension.erp5.Jedi.py
...sionTemplateItem/portal_components/extension.erp5.Jedi.py
+253
-47
bt5/erp5_monaco_editor/SkinTemplateItem/portal_skins/erp5_monaco_editor/ERP5Site_dumpModuleCode.xml
...rtal_skins/erp5_monaco_editor/ERP5Site_dumpModuleCode.xml
+28
-0
No files found.
bt5/erp5_monaco_editor/ExtensionTemplateItem/portal_components/extension.erp5.Jedi.py
View file @
d936b141
...
...
@@ -9,6 +9,7 @@ import inspect
logger
=
logging
.
getLogger
(
"erp5.extension.Jedi"
)
#logger.info('included plugin loaded')
import
os
import
jedi
import
zope.dottedname.resolve
import
time
...
...
@@ -48,8 +49,6 @@ except ImportError:
def
makeERP5Plugin
():
logger
.
info
(
'making erp5 plugin'
)
import
os
from
jedi.evaluate.context
import
ModuleContext
from
jedi.evaluate.lazy_context
import
LazyTreeContext
from
jedi.evaluate.helpers
import
get_str_or_none
...
...
@@ -119,7 +118,7 @@ def makeERP5Plugin():
return
wrapper
def
import_module
(
self
,
callback
):
def
not_used_
import_module
(
self
,
callback
):
"""
Handle ERP5 dynamic modules import.
"""
...
...
@@ -484,10 +483,24 @@ from Products.PythonScripts.PythonScript import PythonScript # pylint: disable
from
collections
import
namedtuple
,
defaultdict
def
SkinsTool_get
Stub
(
self
):
def
SkinsTool_get
ClassSet
(
self
):
portal
=
self
.
getPortalObject
()
sources
=
[]
print
(
'SkinsTool_getStub start'
)
class_set
=
set
([])
# TODO: sort by default skin selection and use the ones registered in skin selections
for
skin_folder
in
portal
.
portal_skins
.
objectValues
():
for
script
in
skin_folder
.
objectValues
(
spec
=
(
'Script (Python)'
,
'External Method'
)):
if
not
'_'
in
script
.
getId
():
logger
.
debug
(
'Skipping wrongly named script %s'
,
script
.
getId
())
continue
type_
=
script
.
getId
().
split
(
'_'
)[
0
]
class_set
.
add
(
type_
)
return
class_set
def
SkinsTool_getStubForClass
(
self
,
class_name
):
portal
=
self
.
getPortalObject
()
line_list
=
[]
SkinDefinition
=
namedtuple
(
'SkinDefinition'
,
'id,docstring,type_comment,skin_folder,params'
)
import
parso
...
...
@@ -504,8 +517,11 @@ def SkinsTool_getStub(self):
logger
.
debug
(
'Skipping wrongly named script %s'
,
script
.
getId
())
continue
type_
=
script
.
getId
().
split
(
'_'
)[
0
]
if
type_
!=
class_name
:
continue
docstring
=
'"""External method"""'
params
=
''
type_comment
=
''
if
script
.
meta_type
==
'Script (Python)'
:
body
=
script
.
body
()
params
=
script
.
params
()
...
...
@@ -514,14 +530,14 @@ def SkinsTool_getStub(self):
icon_path
=
script
.
om_icons
()[
0
][
'path'
]
icon_alt
=
script
.
om_icons
()[
0
][
'alt'
]
docstring_first_line
=
(
"![{icon_alt}]({portal_url}/{icon_path}) "
"[`{script_id}`]({portal_url}/portal_skins/{skin_folder_id}/{script_id}/manage_main)
\
n
"
).
format
(
"![{icon_alt}]({portal_url}/{icon_path}) "
"[`{script_id}`]({portal_url}/portal_skins/{skin_folder_id}/{script_id}/manage_main)
\
n
"
).
format
(
icon_alt
=
icon_alt
,
portal_url
=
portal
.
absolute_url
(),
icon_path
=
icon_path
,
script_id
=
script
.
getId
(),
skin_folder_id
=
skin_folder
.
getId
()
)
skin_folder_id
=
skin_folder
.
getId
())
docstring
=
'"""{}"""'
.
format
(
docstring_first_line
)
module
=
grammar
.
parse
(
body
)
if
next
(
iter
(
grammar
.
iter_errors
(
module
)),
None
)
is
not
None
:
...
...
@@ -536,14 +552,18 @@ def SkinsTool_getStub(self):
if
first_leaf
.
type
==
'string'
:
original_docstring
=
first_leaf
.
value
if
original_docstring
.
startswith
(
"'''"
):
docstring
=
"'''{}
\
n
{}"
.
format
(
docstring_first_line
,
original_docstring
[
3
:])
docstring
=
"'''{}
\
n
{}"
.
format
(
docstring_first_line
,
original_docstring
[
3
:])
elif
original_docstring
.
startswith
(
"'"
):
docstring
=
"'''{}
\
n
{}''"
.
format
(
docstring_first_line
,
original_docstring
[
1
:])
docstring
=
"'''{}
\
n
{}''"
.
format
(
docstring_first_line
,
original_docstring
[
1
:])
elif
original_docstring
.
startswith
(
'"""'
):
docstring
=
'"""{}
\
n
{}'
.
format
(
docstring_first_line
,
original_docstring
[
3
:])
docstring
=
'"""{}
\
n
{}'
.
format
(
docstring_first_line
,
original_docstring
[
3
:])
elif
original_docstring
.
startswith
(
'"'
):
docstring
=
'"""{}
\
n
{}""'
.
format
(
docstring_first_line
,
original_docstring
[
1
:])
docstring
=
'"""{}
\
n
{}""'
.
format
(
docstring_first_line
,
original_docstring
[
1
:])
skin_by_type
[
type_
].
append
(
SkinDefinition
(
script
.
getId
(),
...
...
@@ -553,12 +573,11 @@ def SkinsTool_getStub(self):
params
))
for
type_
,
skins
in
skin_by_type
.
items
():
sources
.
append
(
line_list
.
append
(
textwrap
.
dedent
(
"""
\
import erp5.portal_type
from erp5 import portal_type
from erp5.portal_type import Organisation as erp5_portal_type_Person
class {class_name}:
{docstring}
...
...
@@ -568,8 +587,9 @@ def SkinsTool_getStub(self):
docstring
=
safe_docstring
(
"Skins for {}"
.
format
(
type_
))))
for
skin
in
skins
:
skin
=
skin
# type: SkinDefinition
sources
.
append
(
# ( the comment is also here so that dedent keep indentation )
line_list
.
append
(
# the comment is also here so that dedent keep indentation, because this method block needs
# more indentation than class block
textwrap
.
dedent
(
"""
\
# {skin_id} in {skin_folder}
...
...
@@ -581,11 +601,10 @@ def SkinsTool_getStub(self):
params
=
skin
.
params
,
type_comment
=
skin
.
type_comment
,
docstring
=
skin
.
docstring
))
print
(
'SkinsTool_getStub finished'
)
return
"
\
n
"
.
join
(
sources
)
return
"
\
n
"
.
join
(
line_list
)
def
TypesTool_getStub
(
self
):
def
TypesTool_getStub
(
self
):
# XXX useless
print
(
'TypesTool_getStub start'
)
portal
=
self
.
getPortalObject
()
sources
=
[
TypesTool_getStubHeader
(
self
)]
...
...
@@ -635,6 +654,7 @@ def TypesTool_getStubHeader(self):
'''
)
# TODO: drop include_header
def
TypeInformation_getStub
(
self
,
include_header
=
True
):
# type: (ERP5TypeInformation) -> str
"""returns a .pyi stub file for this portal type
...
...
@@ -643,6 +663,9 @@ def TypeInformation_getStub(self, include_header=True):
"""
portal
=
self
.
getPortalObject
()
# TODO: getParentValue
# TODO: a class for magic things like getPortalObject ?
@
WorkflowMethod
.
disable
def
makeTempClass
():
# everything is allowed in portal trash so we create our
...
...
@@ -664,10 +687,10 @@ def TypeInformation_getStub(self, include_header=True):
parent_class_module
=
parent_class
.
__module__
include_private
=
False
imports
=
[
]
imports
=
[
'import erp5.portal_type'
]
# TODO: this can be a set (all imports)
header
=
""
if
include_header
:
header
=
portal
.
portal_types
.
TypesTool_getStubHeader
(
)
header
=
TypesTool_getStubHeader
(
self
.
getPortalObject
().
portal_types
)
methods
=
[]
debug
=
""
method_template_template
=
""" {decorator}
\
n
def {method_name}({method_args}) -> {return_type}:
\
n
{docstring}"""
...
...
@@ -680,6 +703,16 @@ def TypeInformation_getStub(self, include_header=True):
return_type
=
'str'
,
docstring
=
safe_docstring
(
self
.
getId
())))
imports
.
append
(
'from erp5.portal_type import ERP5Site'
)
methods
.
append
(
method_template_template
.
format
(
decorator
=
''
,
method_name
=
'getPortalObject'
,
method_args
=
"self"
,
return_type
=
'ERP5Site'
,
docstring
=
safe_docstring
(
getattr
(
temp_class
.
getPortalObject
,
'__doc__'
,
None
)
or
'...'
)))
# first class contain workflow and some constraints.
for
property_name
in
sorted
(
vars
(
temp_class
)):
if
property_name
[
0
]
==
'_'
and
not
include_private
:
...
...
@@ -853,6 +886,22 @@ def TypeInformation_getStub(self, include_header=True):
safe_python_identifier
(
pc
.
__name__
),
prefixed_class_name
))
base_classes
.
append
(
prefixed_class_name
)
# everything can use ERP5Site_ skins
imports
.
append
(
'from erp5.skins_tool import ERP5Site as skins_tool_ERP5Site'
)
base_classes
.
append
(
'skins_tool_ERP5Site'
)
base_classes
.
append
(
prefixed_class_name
)
# XXX special methods for some tools
if
self
.
getId
()
==
'Simulation Tool'
:
methods
.
append
(
method_template_template
.
format
(
decorator
=
''
,
method_name
=
'getInventoryList'
,
method_args
=
"self"
,
# TODO
return_type
=
'erp5.portal_type.Person'
,
docstring
=
safe_docstring
(
'TODO =)'
)))
class_template
=
textwrap
.
dedent
(
"""
\
{header}
...
...
@@ -1108,20 +1157,22 @@ from Products.ERP5.ERP5Site import ERP5Site # pylint: disable=unused-import
def
ERP5Site_getPortalStub
(
self
):
# type: (ERP5Site) -> str
# TODO:
module_stub_template
=
textwrap
.
dedent
(
'''
\
def __{module_id}(self):
from erp5.portal_type import {module_class_name}
return {module_class_name}()
{module_id} = property(__{module_id}
)
'''
)
'''
@property
def {module_id}(self):
from erp5.portal_type import {module_class_name}
return {module_class_name}(
)
'''
)
tool_stub_template
=
textwrap
.
dedent
(
'''
\
def __{tool_id}(self):
{tool_import}
return {tool_class}()
{tool_id} = property(__{tool_id}
)
'''
)
'''
@property
def {tool_id}(self):
{tool_import}
return {tool_class}(
)
'''
)
source
=
[]
for
m
in
self
.
objectValues
():
if
m
.
getPortalType
().
endswith
(
'Module'
):
...
...
@@ -1137,29 +1188,31 @@ def ERP5Site_getPortalStub(self):
m
.
__class__
.
__module__
,
tool_class
,)
if
m
.
getId
()
==
'portal_catalog'
:
tool_class
=
'ICatalogTool'
tool_import
=
''
tool_class
=
'ICatalogTool'
# XXX these I prefix are stupid
tool_import
=
'
from erp5.portal_type import ICatalogTool
'
source
.
extend
(
tool_stub_template
.
format
(
tool_id
=
m
.
getId
(),
tool_class
=
tool_class
,
tool_import
=
tool_import
).
splitlines
())
tool_import
=
tool_import
).
splitlines
(),
)
# TODO: tools with at least base categories for CategoryTool
return
textwrap
.
dedent
(
'''
\
from Products.ERP5Site.ERP5Site import ERP5Site
class IPortalObject(ERP5Site):
{}
'''
).
format
(
'
\
n
'
.
join
(
source
))
'''
from Products.ERP5Site.ERP5Site import ERP5Site as ERP5Site_parent_ERP5Site
from erp5.skins_tool import ERP5Site as skins_tool_ERP5Site
class ERP5Site(ERP5Site_parent_ERP5Site, skins_tool_ERP5Site):
{}
'''
).
format
(
'
\
n
'
.
join
(
source
))
def
CatalogTool_getStub
(
self
):
portal
=
self
.
getPortalObject
()
# type: IPortalObject
portal
=
self
.
getPortalObject
()
brain_class_list
=
[]
imports
=
[]
brain_template
=
textwrap
.
dedent
(
'''
\
from typing import TypeVar, Generic
from typing import TypeVar, Generic
, List, Union
T = TypeVar('T')
class Brain(Generic[T]):
id: str
...
...
@@ -1178,7 +1231,7 @@ def CatalogTool_getStub(self):
return
textwrap
.
dedent
(
'''
\
from Products.ERP5Catalog.Tool import ERP5CatalogTool
from Products.ERP5Catalog.Tool
.ERP5CatalogTool
import ERP5CatalogTool
{brain_template}
CatalogToolAllTypes = Union[{all_types}]
class ICatalogTool(ERP5CatalogTool):
...
...
@@ -1189,3 +1242,156 @@ def CatalogTool_getStub(self):
'''
).
format
(
brain_template
=
brain_template
,
all_types
=
all_types
)
def
ERP5Site_dumpModuleCode
(
self
,
component_or_script
=
None
):
"""Save code in filesystem for jedi to use it.
Generate stubs for erp5.* dynamic modules and copy the in-ZODB modules
to files.
"""
def
mkdir_p
(
path
):
if
not
os
.
path
.
exists
(
path
):
os
.
mkdir
(
path
,
0o700
)
portal
=
self
.
getPortalObject
()
# type: 'erp5.portal_type.ERP5Site'
module_dir
=
'/tmp/ahaha/erp5/'
# TODO
mkdir_p
(
module_dir
)
# generate erp5/__init__.py
with
open
(
os
.
path
.
join
(
module_dir
,
'__init__.py'
),
'w'
,)
as
erp5__init__f
:
for
module
in
(
'portal_type'
,
'accessor_holder'
,
'skins_tool'
,
'component'
,):
erp5__init__f
.
write
(
'from . import {module}
\
n
'
.
format
(
module
=
module
))
# TODO: accessor_holder real name ?
# TODO: component versions ?
mkdir_p
(
os
.
path
.
join
(
module_dir
,
module
))
if
module
==
'portal_type'
:
with
open
(
os
.
path
.
join
(
module_dir
,
module
,
'__init__.py'
,),
'w'
,)
as
module_f
:
for
ti
in
portal
.
portal_types
.
contentValues
():
class_name
=
safe_python_identifier
(
ti
.
getId
())
module_f
.
write
(
'from .{class_name} import {class_name}
\
n
'
.
format
(
class_name
=
class_name
))
with
open
(
os
.
path
.
join
(
module_dir
,
module
,
'{class_name}.pyi'
.
format
(
class_name
=
class_name
),
),
'w'
,
)
as
type_information_f
:
type_information_f
.
write
(
ti
.
TypeInformation_getStub
().
encode
(
'utf-8'
))
# tools XXX don't do here but in TypeInformation_getStub ?
#module_f.write('from .CatalogTool import CatalogTool')
module_f
.
write
(
'from .ICatalogTool import ICatalogTool
\
n
'
)
with
open
(
os
.
path
.
join
(
module_dir
,
module
,
'ICatalogTool.pyi'
,),
'w'
,)
as
portal_f
:
portal_f
.
write
(
CatalogTool_getStub
(
self
.
getPortalObject
().
portal_catalog
))
module_f
.
write
(
'from .SimulationTool import SimulationTool
\
n
'
)
# TOODO: simulation tool
# portal object
module_f
.
write
(
'from .ERP5Site import ERP5Site
\
n
'
)
module_f
.
write
(
'from .ERP5Site import ERP5Site as IPortalObject
\
n
'
)
# XXX what name for portal ? -> ERP5Site !
with
open
(
os
.
path
.
join
(
module_dir
,
module
,
'ERP5Site.pyi'
,),
'w'
,)
as
portal_f
:
portal_f
.
write
(
ERP5Site_getPortalStub
(
self
.
getPortalObject
()))
elif
module
==
'accessor_holder'
:
# TODO: real path is accessor_holder.something !?
with
open
(
os
.
path
.
join
(
module_dir
,
module
,
'__init__.py'
),
'w'
,)
as
accessor_holder_f
:
for
ps
in
portal
.
portal_property_sheets
.
contentValues
():
class_name
=
safe_python_identifier
(
ps
.
getId
())
accessor_holder_f
.
write
(
'from .{class_name} import {class_name}
\
n
'
.
format
(
class_name
=
class_name
))
with
open
(
os
.
path
.
join
(
module_dir
,
module
,
'{class_name}.pyi'
.
format
(
class_name
=
class_name
),
),
'w'
,
)
as
property_sheet_f
:
property_sheet_f
.
write
(
ps
.
PropertySheet_getStub
().
encode
(
'utf-8'
))
elif
module
==
'skins_tool'
:
skins_tool
=
portal
.
portal_skins
with
open
(
os
.
path
.
join
(
module_dir
,
module
,
'__init__.py'
),
'w'
,)
as
skins_tool_f
:
for
class_name
in
SkinsTool_getClassSet
(
skins_tool
):
skins_tool_f
.
write
(
'from {class_name} import {class_name}
\
n
'
.
format
(
class_name
=
class_name
))
with
open
(
os
.
path
.
join
(
module_dir
,
module
,
'{}.pyi'
.
format
(
class_name
),),
'w'
,
)
as
skin_f
:
skin_f
.
write
(
SkinsTool_getStubForClass
(
skins_tool
,
class_name
,).
encode
(
'utf-8'
))
elif
module
==
'component'
:
module_to_component_portal_type_mapping
=
{
'test'
:
'Test Component'
,
'document'
:
'Document Component'
,
'extension'
:
'Extension Component'
,
'tool'
:
'Tool Component'
,
'module'
:
'Module Component'
,
'interface'
:
'Interface Component'
,
}
with
open
(
os
.
path
.
join
(
module_dir
,
module
,
'__init__.py'
),
'w'
,)
as
component_module__init__f
:
for
sub_module
,
portal_type
in
module_to_component_portal_type_mapping
.
items
():
component_module__init__f
.
write
(
'from . import {}
\
n
'
.
format
(
sub_module
))
mkdir_p
(
os
.
path
.
join
(
module_dir
,
module
,
sub_module
))
with
open
(
os
.
path
.
join
(
module_dir
,
module
,
sub_module
,
'__init__.py'
),
'w'
,
)
as
component_sub_module_init_f
:
for
brain
in
portal
.
portal_catalog
(
portal_type
=
portal_type
,
validation_state
=
(
'validated'
,)):
component
=
brain
.
getObject
()
component_sub_module_init_f
.
write
(
"from {component_reference} import {component_reference}
\
n
"
.
format
(
component_reference
=
component
.
getReference
()))
with
open
(
os
.
path
.
join
(
module_dir
,
module
,
sub_module
,
'{}.py'
.
format
(
component
.
getReference
()),
),
'w'
,
)
as
component_f
:
component_f
.
write
(
component
.
getTextContent
())
#.encode('utf-8'))
return
'done'
bt5/erp5_monaco_editor/SkinTemplateItem/portal_skins/erp5_monaco_editor/ERP5Site_dumpModuleCode.xml
0 → 100644
View file @
d936b141
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ExternalMethod"
module=
"Products.ExternalMethod.ExternalMethod"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_function
</string>
</key>
<value>
<string>
ERP5Site_dumpModuleCode
</string>
</value>
</item>
<item>
<key>
<string>
_module
</string>
</key>
<value>
<string>
Jedi
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
ERP5Site_dumpModuleCode
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string></string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
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