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

PR: Fix 3 bugs and add 4 improvements to Find in Files #6095

Merged
merged 18 commits into from
Jan 10, 2018

Conversation

jnsebgosselin
Copy link
Member

@jnsebgosselin jnsebgosselin commented Dec 30, 2017

Fixes #5306

- All the code related to the management of the search path for the
FindInFiles widget was isolated in a new class.
- The inheritance to the BaseComboBox was dropped since it was causing
problems.
- Dropped the custom model that was used for the combobox. Everything is
managed with the default model of the QComboBox class. This fixed
another issue with the previous implementation of the combo-box.
@ccordoba12 ccordoba12 added this to the v3.2.6 milestone Dec 30, 2017
When the combobox popup list is visible and the delete key is pressed,
the highlighted external path is removed from the list.
@ccordoba12 ccordoba12 changed the title PR: Fixes bugs (3) and adds improvements (4) to the find in files functionality. PR: Fix 3 bugs and add 4 improvements to Find in Files Dec 30, 2017
@jnsebgosselin
Copy link
Member Author

Mouse Over and Delete key press demo:

fif_demo1

Select other directory and Clear this list demo:

fif_demo2

@ccordoba12
Copy link
Member

Jean, could you also fix codecov to show failures only when coverage decreases in 1%? Thanks!

@pep8speaks
Copy link

pep8speaks commented Dec 30, 2017

Hello @jnsebgosselin! Thanks for updating the PR.

Cheers ! There are no PEP8 issues in this Pull Request. 🍻

Comment last updated on January 09, 2018 at 05:20 Hours UTC

@jnsebgosselin
Copy link
Member Author

@ccordoba12 While working on the tests for the FindInFiles plugin, I found out an additional bug.

The get_options method of the FindOptions widget is used for two things:

  • It is used to get the options when find is run. In this case, all=False and the options are defined here.
  • It is also used in the closing_plugin method of the FindInFiles plugin for saving the options to the config file. In this case, all=True and the options are defined here.

The problem is that there is safeguards within the get_options method to prevent the find method to be run if one of the parameters is not correct. However, these safeguards also prevent the find in files options to be saved to the config file when Spyder is closed.

For example, the options won't be saved to the config file if the Search pattern line edit is empty:

  1. Go in the FindInFiles plugin and add an external path to the Search in combobox.
  2. Leave the Search pattern line edit empty and close Spyder.
  3. Restart Spyder: the external path that was added in 1 does not appear in the list of the Search in combobox. It was not saved to the config file due to the safeguard here.

I think this should be fixed in another PR. I will built my tests around this issue for the moment.

@jnsebgosselin
Copy link
Member Author

jnsebgosselin commented Dec 31, 2017

@ccordoba12 I think this is ready to be reviewed. I'll go over it again tomorrow just to be sure. There is a lot of stuff to review in this, so feel free to push it back to 3.2.7 if you do not have the time for 3.2.6. I'll try to document a little better the changes I've made later in the description of this PR.

Also, I'm not sure I understand well the use of to_text_string. It was used everywhere in findinfiles.py, so I did the same in the changes I've made.

More than 350 lines of tests added for a meager 0.3% increase in coverage... damn :D

@jnsebgosselin jnsebgosselin self-assigned this Dec 31, 2017
from qtpy.QtCore import QMutex, QMutexLocker, Qt, QThread, Signal, Slot, QSize
from qtpy.QtWidgets import (QHBoxLayout, QLabel, QListWidget, QSizePolicy,
from qtpy.QtCore import (QMutex, QMutexLocker, Qt, QThread, Signal, Slot,
QSize, QEvent)
Copy link
Member

Choose a reason for hiding this comment

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

Please organize these imports in alphabetical order

QTreeWidgetItem, QVBoxLayout, QWidget,
QStyledItemDelegate, QStyleOptionViewItem,
QApplication, QStyle, QListWidgetItem)
QApplication, QStyle, QMessageBox)
Copy link
Member

Choose a reason for hiding this comment

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

These imports too

current position and added back at the end. If the maximum number of
paths is reached, the oldest external path is removed from the list.
"""
if not os.path.exists(path):
Copy link
Member

Choose a reason for hiding this comment

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

Change os.path to osp (that's our custom in Spyder).

return
self.removeItem(self.findText(path))
self.addItem(path)
self.setItemData(self.count()-1, path, Qt.ToolTipRole)
Copy link
Member

Choose a reason for hiding this comment

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

Spaces around -

self.removeItem(self.findText(path))
self.addItem(path)
self.setItemData(self.count()-1, path, Qt.ToolTipRole)
while self.count() > MAX_PATH_HISTORY+EXTERNAL_PATHS:
Copy link
Member

Choose a reason for hiding this comment

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

Spaces around +


def get_external_paths(self):
"""Returns a list of the external paths listed in the combobox."""
return [to_text_string(self.itemText(i))
Copy link
Member

Choose a reason for hiding this comment

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

We probably need to use here to_unicode_from_fs (from utils/encoding.py) to deal with non-ascii dirs on Windows that uses encodings like cp-1251 (Russian).

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, this is not the proper place to do it. I'll point to the right place below.

Copy link
Member Author

@jnsebgosselin jnsebgosselin Dec 31, 2017

Choose a reason for hiding this comment

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

Should I replace to_text_string(self.itemText(i) by self.itemText(i)?

I do not understand what to_text_string is doing here since self.itemText(i) is already returning a unicode str by default as stated, for instance, in the PySide documentation). Or is it returning a QString in some version of PyQt on python 2? In PySide, the QString class does not even exist I think.

All this encoding stuff is mumbo jumbo to me, no matter how many times I've read on this subject XD.

Copy link
Member Author

@jnsebgosselin jnsebgosselin Dec 31, 2017

Choose a reason for hiding this comment

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

Ok, I've seen that to_text_string was always used with itemText everywhere else. So maybe it is safer to keep it that way?

Copy link
Member Author

Choose a reason for hiding this comment

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

OK, I've read that Python 2, PyQt API #1 is returning a QString, so I'll keep the to_text_string.

Copy link
Member

Choose a reason for hiding this comment

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

Ok, good idea.

external_path = self.select_directory()
if len(external_path) > 0:
self.add_external_path(external_path)
self.setCurrentIndex(self.count()-1)
Copy link
Member

Choose a reason for hiding this comment

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

Spaces around -

directory = getexistingdirectory(
self, _("Select directory"), self.path)
if directory:
directory = to_text_string(osp.abspath(to_text_string(directory)))
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 the right place to use to_unicode_from_fs. So this should be

directory = encoding.to_unicode_from_fs(osp.abspath(directory))

if self.currentIndex() == PROJECT:
self.setCurrentIndex(CWD)
else:
path = to_text_string(osp.abspath(to_text_string(path)))
Copy link
Member

Choose a reason for hiding this comment

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

Change this to

path = encoding.to_unicode_from_fs(osp.abspath(path))

Could you add some tests to verity that this is correct in Python 2?

Copy link
Member

Choose a reason for hiding this comment

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

Mmmh, it seems we're not transforming to Unicode our project paths, so maybe this is for another PR.

Copy link
Member

Choose a reason for hiding this comment

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

I opened issue #6103 about this (which I'll fix for 3.2.6), so please change this line to

path = osp.abspath(path)

self.removeItem(index)
self.showPopup()
# Set the view selection so that it doesn't bounce around.
new_index = min(self.count()-1, index)
Copy link
Member

Choose a reason for hiding this comment

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

Spaces around -

@ccordoba12
Copy link
Member

I like a lot the new SearchInComboBox class you added. It makes the code more modular and easier to understand. And, of course, I also like the new tests you added!

I left some minor comments, except for the use of to_unicode_from_fs in one place. Then I'd say this is ready.

@jnsebgosselin
Copy link
Member Author

jnsebgosselin commented Dec 31, 2017

Thank you very much Carlos for this quick review, this is very nice!

To do:

  • Assert non-ASCII path in the tests.
  • Do the requested style changes.
  • Fix the to_unicode_from_fs and to_text_string.

self.clear_external_paths()
self.setCurrentIndex(0)
elif idx >= EXTERNAL_PATHS:
self.external_path = to_text_string(self.itemText(idx))
Copy link
Member Author

Choose a reason for hiding this comment

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

Same comment here, should I replace to_text_string(self.itemText(idx)) by self.itemText(idx).


def set_directory(self, directory):
self.path = to_text_string(osp.abspath(to_text_string(directory)))
self.path_selection_combo.path = to_text_string(osp.abspath(
to_text_string(directory)))
Copy link
Member Author

@jnsebgosselin jnsebgosselin Dec 31, 2017

Choose a reason for hiding this comment

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

Should to_text_string(osp.abspath(to_text_string(directory))) be changed to osp.abspath(directory) or to_unicode_from_fs(osp.abspath(directory))?

Copy link
Member

Choose a reason for hiding this comment

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

I see this is only used in one place:

https://github.com/jnsebgosselin/spyder/blob/8b9483d72967c4580143fde6adaeec38704f0dbd/spyder/plugins/findinfiles.py#L78

So this should be osp.abspath(directory) because getcwd_or_home already returns unicode.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok thank you. I'll remove the to_text_string here.


def set_file_path(self, path):
self.file_path = path
self.path_selection_combo.file_path = path
Copy link
Member Author

Choose a reason for hiding this comment

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

Should path be changed for osp.abspath(path) or to_unicode_from_fs(osp.abspath(path))?

Copy link
Member

Choose a reason for hiding this comment

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

Again, this is only used in one place

https://github.com/jnsebgosselin/spyder/blob/8b9483d72967c4580143fde6adaeec38704f0dbd/spyder/plugins/findinfiles.py#L86

and, since it sets the path of current file in the Editor, I think it's fine as it is, or you can change it to osp.abspath(path) if you want to be certain to have a full path.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, I'll leave it like that. If it ain't broke, don't fix it.

@jnsebgosselin
Copy link
Member Author

I added a non-ASCII path to the tests... and all hell breaks loose lol

The test is passing for Python3 in AppVeyor, but not for Python 2. I don't understand why the tests are failing on Travis though, I'm not sure it is related to this PR...

@jnsebgosselin
Copy link
Member Author

The "good news" is that I'm able to make the test crash locally with Python2, so I should be able to debug this... but probably not until next year XD

@jnsebgosselin
Copy link
Member Author

@ccordoba12 Just so you know, this is ready, but I would like you to check again carefully some of the places where we return a path.

So good thinking in pushing it back to 3.2.7. It wouldn't be a bad idea if you could play a little bit with the changes I've made locally also.

@ccordoba12
Copy link
Member

but I would like you to check again carefully some of the places where we return a path.

I left my comments above.

So good thinking in pushing it back to 3.2.7.

Yep, I agree too. If things go as planned, we'll release 3.2.7 by the end of January.

The directory is already unicode. So there is no need to use
to_text_string here.
Copy link
Member

@ccordoba12 ccordoba12 left a comment

Choose a reason for hiding this comment

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

Thanks a lot Jean, this is a really great improvement!

@ccordoba12 ccordoba12 merged commit 5b0a09e into spyder-ide:3.x Jan 10, 2018
ccordoba12 added a commit that referenced this pull request Jan 10, 2018
Fixes #5306

Conflicts:

- spyder/widgets/findinfiles.py
- spyder/widgets/tests/test_findinfiles.py
@jnsebgosselin jnsebgosselin deleted the some_find_in_files_fixes branch January 10, 2018 02:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants