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

Fix #14 #142

Merged
merged 13 commits into from
Jul 1, 2018
Merged

Fix #14 #142

merged 13 commits into from
Jul 1, 2018

Conversation

rassouly
Copy link
Contributor

@rassouly rassouly commented May 17, 2018

  • Enforce unique names when creating a task
  • Enforce unique names when renaming a task
  • Update/add tests

Known issues:

  • Right click->Add after in the task tree bypasses uniqueness checks.
  • Copy-pasting doesn't work: the pasted task has the same name as the initial task. This seems hard to fix in a nice way because the behavior of PasteAction (in qt_tree_menu.enaml) is not overridable. EDIT: Found a hacky solution. EDIT2: Found a nicer solution.

Comment are welcome.

@@ -177,7 +177,10 @@ def exit_rename(self, obj, label):

"""
label_name = self.label
if label_name[:1] != '=':
Copy link
Member

Choose a reason for hiding this comment

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

This is not from my point of view the way to do it. It is better to override exit_rename in the task tree nodes (declared in the measure_editor). Those function exist to allow such customizations.

exit_rename => (obj, label):
forbidden_names = obj.root.get_used_names()
if label not in forbidden_names:
obj.name = label
Copy link
Member

Choose a reason for hiding this comment

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

We could consider showing a popup explaining why renaming failed... But do not bother with this, opening an issue will be enough.

@rassouly rassouly changed the title [WIP] Fix #14 Fix #14 May 25, 2018
@codecov
Copy link

codecov bot commented May 25, 2018

Codecov Report

Merging #142 into master will decrease coverage by 0.01%.
The diff coverage is 93.44%.

@@            Coverage Diff             @@
##           master     #142      +/-   ##
==========================================
- Coverage   98.38%   98.37%   -0.02%     
==========================================
  Files         157      157              
  Lines       12292    12335      +43     
==========================================
+ Hits        12093    12134      +41     
- Misses        199      201       +2

Copy link
Member

@MatthieuDartiailh MatthieuDartiailh left a comment

Choose a reason for hiding this comment

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

I realized (a bit late) that this deviates a bit from my initial design. I would prefer to work with the direct parent rather than the root and to be future-proof it would be interesting to also pass the future index of the task in its parent. Sorry for the noticing so late.

@@ -783,8 +783,7 @@ def _on_nid_changed(self, nid, col):
if new_label != old_label:
if new_label != '':
node.exit_rename(obj, new_label)
else:
self._set_label(nid, old_label)
self._set_label(nid, node.get_label(obj))
Copy link
Member

Choose a reason for hiding this comment

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

Why this change ?

Copy link
Contributor Author

@rassouly rassouly May 25, 2018

Choose a reason for hiding this comment

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

When the new name is invalid (because it's not unique), exit_rename doesn't set obj.name to new_label. The issue is, without this patch, the name displayed in the tree would be stuck on the new_label, even though it's invalid and doesn't reflect the actual name.
The systematic call to _set_label syncs up the two.

@@ -88,13 +88,11 @@ enamldef RootTaskView(BaseTaskView): main:
BaseTaskView.refresh(self)
editor.refresh()

# TODO pass the future parent task so that config can do name inspections
# and avoid duplicate names.
func create_new_task():
Copy link
Member

Choose a reason for hiding this comment

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

Looking at the full diff, I realized I would prefer to follow more closely what I was suggesting in this TODO and pass the future parent rather than the node in case we decide to ever use a different validation or need it for specific config.

Copy link
Contributor Author

@rassouly rassouly May 25, 2018

Choose a reason for hiding this comment

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

I don't want to pass the future parent because I want the names to be unique in the entire tree. This makes moving nodes in the tree easier.

Copy link
Member

Choose a reason for hiding this comment

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

You can easily get the root from the parent and having the parent offer more possibilities.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, makes sense, I am reworking the PR.

Copy link
Member

Choose a reason for hiding this comment

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

Ok let me know if you need help with anything.

@@ -47,15 +50,15 @@ class BaseTaskConfig(Atom):

def __init__(self, **kwargs):
super(BaseTaskConfig, self).__init__(**kwargs)
# Force check to ensure that the possible default value of task_name
# is tested.
self.check_parameters()
Copy link
Member

Choose a reason for hiding this comment

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

From my point of view this could be problematic in subclasses if we need to validate something else than the name. It is not the job of the default value builder to validate the name.

Copy link
Contributor Author

@rassouly rassouly May 25, 2018

Choose a reason for hiding this comment

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

I needed to remove the check_parameters to prevent an infinite loop. I can't exactly remember why it happened but moving the check from __init__ to _default_task_name solved the issue.
I can look at this more closely if you want.

Copy link
Contributor Author

@rassouly rassouly May 25, 2018

Choose a reason for hiding this comment

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

It seems that reworking the PR fixed the issue so I am putting the check_parameters back.

@@ -78,7 +81,10 @@ def _post_setattr_task_name(self, old, new):
def _default_task_name(self):
names = self.manager.auto_task_names
if names:
return random.choice(names)
name = random.choice(names)
Copy link
Member

Choose a reason for hiding this comment

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

See my above comment.

names = []
if self.root:
names = self.root.get_used_names()
self.ready = self.task_name != "" and self.task_name not in names
Copy link
Member

Choose a reason for hiding this comment

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

To help the user, it would be nice if the UI could provide some feedback (such as a red background for the name). This would require to be able to only validate the name (not hard since you can store the name on the config to make the check cheap).

Copy link
Member

Choose a reason for hiding this comment

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

Alternatively you can add a valid_name Bool member.

@@ -38,6 +38,8 @@ enamldef BuilderView(Dialog): dial:
#: Reference to the task manager.
alias manager : selector.manager

attr root
Copy link
Member

Choose a reason for hiding this comment

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

This would be nicer with a comment.

- Replace the root attribute in the task configuration window by a
future_parent attribute which contains the future parent of the task
being created.

- Add visual feedback when the name is not valid (this information is
also stored in the config object)

- Readd the check_parameters call in the BaseConfig constructor.
@rassouly
Copy link
Contributor Author

rassouly commented May 26, 2018

The tests fail on Python 3.5. It seems that future_parent is set before manager in
config = PyTaskConfig(manager=plugin, task_class=plugin.get_task('exopy.ComplexTask'), future_parent=root)
How can I get atom to set manager before future_parent? Is it undefined behavior?

@MatthieuDartiailh
Copy link
Member

No you can't since keywords arguments are not ordered. I will look at this either tomorrow or Monday.

@rassouly
Copy link
Contributor Author

Please note that this issue doesn't apply to the actual code of exopy but only to the tests. Indeed, in the code, the future_parent is set after the config object has been created (see building.enaml line 58).

Copy link
Member

@MatthieuDartiailh MatthieuDartiailh left a comment

Choose a reason for hiding this comment

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

I made a small that should allow tests to always pass. I left two minor comments but otherwise this is good to go I believe.

@@ -34,6 +35,7 @@ enamldef BaseConfigView(Container):
Field: t_f:
text := config.task_name
submit_triggers = ['lost_focus', 'return_pressed', 'auto_sync']
background << parse_color("#FFFFFF") if config.name_valid else parse_color("#FF000030")
Copy link
Member

Choose a reason for hiding this comment

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

I believe that 'white' and 'red' would have been fine too (and easier to read).

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 used some transparency to make the red softer and I used the HTML notation for the white for constency.

Copy link
Member

Choose a reason for hiding this comment

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

Ok

def __init__(self, **kwargs):
super(BaseTaskConfig, self).__init__(**kwargs)
# Force check to ensure that the possible default value of task_name
# is tested.
Copy link
Member

Choose a reason for hiding this comment

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

Could you put those two lines back ?

@MatthieuDartiailh
Copy link
Member

I added two blank space by editing on Github (loop_cofig) Can you remove them along the other minor edits ?

@MatthieuDartiailh
Copy link
Member

Thanks @rassouly I will try to review one last time before merging but I believe that this is good to go if Travis comes back green.

@MatthieuDartiailh
Copy link
Member

I read through again and it looks good, but I will try to test directly before merging.

@rassouly rassouly mentioned this pull request Jun 20, 2018
@MatthieuDartiailh MatthieuDartiailh merged commit 170ad2d into Exopy:master Jul 1, 2018
@MatthieuDartiailh
Copy link
Member

Thanks @rassouly

@rassouly rassouly deleted the fix-14 branch July 2, 2018 09:39
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.

2 participants