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

error when autogenerated IDs are used with persistence or snapshots #1894

Merged
merged 11 commits into from
Jan 27, 2022

Conversation

alexcjohnson
Copy link
Collaborator

@alexcjohnson alexcjohnson commented Jan 19, 2022

also give set_random_id a leading underscore so it doesn't
need to become a reserved word (disallowed prop name)

  • I have run the tests locally and they passed. (refer to testing section in contributing)
  • I have added tests, or extended existing tests, to cover any new features or bugs fixed in this PR (didn't try to mock snapshots appearing in sys.modules though, that kind of scares me...)
  • I have added entry in the CHANGELOG.md

cc @chriddyp @emmeb seem like reasonable error messages? The traceback will point to the callback definition, and users CAN just set the component ID right there though probably better is to follow the variable reference back to where the component is first created and set the ID at that point.

also give set_random_id a leading underscore so it doesn't
need to become a reserved word (disallowed prop name)
including component IDs, and auto-generated IDs can easily change.
Callbacks referencing the new IDs will not work old snapshots.

Please assign an explicit ID to this component.
Copy link
Member

Choose a reason for hiding this comment

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

Is there any way for us to print out "which" component it is? Or any other identifier (besides the ID) like the component type? If a user has a ton of components or callbacks, it can be difficult for them to find out which component the error message is referring too.

Copy link
Member

Choose a reason for hiding this comment

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

See the error string prefix in __init__ as an example - might be able to reuse that. the id itself might not be helpful, but at least seeing the component name and type

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

good call, the callback definition will point to multiple components, including the type will help the user narrow it down.

Copy link
Member

@chriddyp chriddyp left a comment

Choose a reason for hiding this comment

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

Besides my comment about the error message, 💃🏼

def _set_random_id(self):

if hasattr(self, "id"):
return getattr(self, "id")
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

😅 I had this logic wrong at first - the whole point of this PR is to force folks to add this ID explicitly, so if it's already there we should skip the checks below! Now that case is tested

@@ -23,7 +23,6 @@
"UNDEFINED",
"REQUIRED",
"to_plotly_json",
"set_random_id",
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We really want to limit new additions to reserved_words, as these become ineligible as prop names for all dash components anyone ever makes. So I prepended an underscore to the method name.

def test_debc029_random_id_errors():
app = Dash(__name__)

input1 = dcc.Input(value="Hello Input 1", persistence=True)
Copy link
Contributor

@eff-kay eff-kay Jan 20, 2022

Choose a reason for hiding this comment

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

I am pretty sure its probably late, and not sure if its valid here. But we can force the user to always Instantiate Input with a defined id by making it a required keyword-arg. That way it will simply be a runtime error.

class Input():
        def __init__(self, value=None, style=None, *, id):
                ...
                
        
# The following line will throw an error 
# The error states that __init__ is missing a required keyword-arg 'id'

input1 = Input(value="something", style={'color': 'orange'})

              

Copy link
Contributor

@eff-kay eff-kay Jan 20, 2022

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Basically anything after the * becomes a required keyword arg. and its part of python 3.6.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Dash components do have the ability to specify required args - and this gets handled in each component's __init__ via the component generator. The challenge here is that it's coupled, though you're right that in principle we could handle that in __init__, but it would have to be explicit code. This would prevent creating the component and then later setting its ID, but not sure if that's really a pattern we want to promote.

@alexcjohnson alexcjohnson merged commit 3334c07 into dev Jan 27, 2022
@alexcjohnson alexcjohnson deleted the random-id-errors branch January 27, 2022 03:36
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