Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Initial version of updated code for R transpiler #449

Closed
wants to merge 27 commits into from
Closed

Conversation

rpkyle
Copy link
Contributor

@rpkyle rpkyle commented Nov 5, 2018

No description provided.

@rpkyle rpkyle changed the title Initial version of updated code for R transpiler WIP Initial version of updated code for R transpiler Nov 5, 2018
Copy link
Contributor

@T4rk1n T4rk1n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look good so far, couple things to remove as I don't think they translate from python to R.

Also, I'd like those methods (and the python generation too) to be in a separate file as it should be the file for the python component class and associated methods. But that can be in another PR.

def generate_class_string_r(typename, props, description, namespace):
"""
Dynamically generate class strings to have nicely formatted docstrings,
keyword arguments, and repr
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can update this docstring to reflect that it generate R components. docstring, keywords arguments, repr are python things that may not relate to R.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, this makes sense. When I first started editing, I think I was trying too hard to maintain parity between the existing code and the R-related bits I introduced. I'll revise so that my additions reflect R conventions when appropriate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P.S. Thanks for having a look!

# whether a property is None because the user explicitly wanted
# it to be `null` or whether that was just the default value.
# The solution might be to deal with default values better although
# not all component authors will supply those.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove those comments, they contains todo's that are specifics to python classes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do. I'll also finish commenting my additions where appropriate.

component_name=typename,
props=filtered_props,
events=parse_events(props),
description=description).replace('\r\n', '\n')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added that .replace('\r\n', '\n') for generating the docstring on windows because git doesn't auto replace them when they are in docstring. Not sure this problem is the same with R.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it is a consideration in R as well, though I think I should remove the \n and replace with a single space, since R's help viewer does its own line wrapping without adding linefeeds.

events=parse_events(props),
description=description).replace('\r\n', '\n')

# pylint: disable=unused-variable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'{:s}=NULL'.format(p))
for p in prop_keys
if not p.endswith("-*") and
p not in keyword.kwlist and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚡ This keyword list filter is for python keywords, won't be the same in R.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually now we manually maintain a file of python keywords (https://github.com/plotly/dash/blob/master/dash/development/_all_keywords.py). Perhaps we can re-name that to python_keywords and make a new one called R_keywords.

That is, if this problem even exists in R. Can you define a function with argument names that are the same as a reserved keyword in R?

Copy link
Contributor Author

@rpkyle rpkyle Nov 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is, if this problem even exists in R. Can you define a function with argument names that are the same as a reserved keyword in R?

If the function argument matches a reserved word (which is not first escaped with backticks), the R parser will throw an error:

Error: unexpected 'if' in "myfun <- function(if"

The help page (also produced when you type ?reserved) is here:

https://stat.ethz.ch/R-manual/R-devel/library/base/html/Reserved.html

I've gone ahead and produced a GitHub gist including reserved words in R, similar to the keyword list already available for Python. I can submit it as a pull request if it would be helpful.

https://gist.github.com/rpkyle/622155e24f603fc54a664b06f8036f3d

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can include those keywords in https://github.com/plotly/dash/blob/master/dash/development/_all_keywords.py as a new variable r_keywords and use it in this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, will do.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm in the process of updating the code I've written, so please hold off on reviewing the updates to this PR for a day or so. Nicolas suggested remerging my new branch with R, so that we can keep the current PR alive.

Copy link
Contributor Author

@rpkyle rpkyle Nov 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I think I've made the minimal sufficient set of changes required to base_component.py necessary to load dashR with the current version of dash-html-components and dash-core-components. Mind having another look at the changes?

@rmarren1
@T4rk1n

@@ -445,6 +589,27 @@ def generate_class(typename, props, description, namespace):
result = scope[typename]
return result

def generate_class_r(typename, props, description, namespace):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚡ the generate_class for python is for dynamically loaded components, we don't do that in R.

props = reorder_props(props=props)

desctext = ''
desctext += "\n".join(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to append, just do desctext = "\n".join(

@@ -1,9 +1,12 @@
import collections
import json
import os
#from dash.development.base_component import generate_class
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


from .base_component import generate_class_r
from .base_component import generate_class_file_r
#from dash.development.base_component import generate_class_file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


# Add an import statement for this component
# RK: need to add import statements in R namespace file also
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that still todo ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added export() statements to the NAMESPACE file for the R package, don't think we'll need to provide an import statement. Will remove the comment.

[('#\' @param {:s} {:s}'.format(p, props[p]['description'].replace('\n', ' ')))
for p in props.keys()
if not p.endswith("-*") and
p not in keyword.kwlist and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -550,6 +758,25 @@ def parse_wildcards(props):
list_of_valid_wildcard_attr_prefixes.append(wildcard_attr[:-1])
return list_of_valid_wildcard_attr_prefixes

def parse_wildcards_r(props):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐫 I do not think this function is necessary, it is the same as parse_wildcards currently. We can keep this as one function used by the R and Python generation until we have a reason to re-write it.

@@ -837,3 +1064,8 @@ def js_to_py_type(type_object, is_flow_type=False, indent_num=0):
# All other types
return js_to_py_types[js_type_name]()
return ''

def make_package_name(namestring):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it be make_package_name_r to be more explicit?

@@ -837,3 +1064,8 @@ def js_to_py_type(type_object, is_flow_type=False, indent_num=0):
# All other types
return js_to_py_types[js_type_name]()
return ''

def make_package_name(namestring):
# first, *rest = namestring.split('_') Python 3
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

# >>> import keyword
# >>> keyword.kwlist

kwlist = set([
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should change this to python_keywords then to be consistent. I think we should do it here, it's only 4 lines and I don't think it needs its own PR.

p not in ['dashEvents', 'fireEvent', 'setProps']] + ['**kwargs']
)

required_args = required_props(props)
return c.format(**locals())
return c.format(typename=typename,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐱

@rpkyle
Copy link
Contributor Author

rpkyle commented Dec 6, 2018

Closing this PR in favour of #483.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants