Skip to content
This repository was archived by the owner on Feb 29, 2024. It is now read-only.

Fix more PEP 8 findings and warnings#723

Open
Cerno-b wants to merge 15 commits intoHumanSignal:masterfrom
Cerno-b:pep-8_stage_2
Open

Fix more PEP 8 findings and warnings#723
Cerno-b wants to merge 15 commits intoHumanSignal:masterfrom
Cerno-b:pep-8_stage_2

Conversation

@Cerno-b
Copy link
Copy Markdown
Contributor

@Cerno-b Cerno-b commented Mar 22, 2021

See #725 for general details.

I added comments to explain why I changed something.

For ease of review please use the "Files changed" tab.

Comment thread labelImg.py
__appname__ = 'labelImg'


class WindowMixin(object):
Copy link
Copy Markdown
Contributor Author

@Cerno-b Cerno-b Mar 22, 2021

Choose a reason for hiding this comment

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

Rationale: I integrated the WindowMixin into the main window class since this seemed the simpler solution. If you had a specific purpose in mind for it, let me know

Comment thread labelImg.py
return menu

def toolbar(self, title, actions=None):
def add_toolbar(self, title, actions=None):
Copy link
Copy Markdown
Contributor Author

@Cerno-b Cerno-b Mar 22, 2021

Choose a reason for hiding this comment

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

Rationale: I renamed the function to make it consistent with add_menu

Comment thread labelImg.py
self.settings.load()
settings = self.settings

self.image_data = None
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: members should be initialized in the init-function

Comment thread labelImg.py

# Load string bundle for i18n
self.string_bundle = StringBundle.get_bundle()
get_str = lambda str_id: self.string_bundle.get_string(str_id)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: Fix warning that lambas should not be assigned, instead define a function

Comment thread labelImg.py

# Actions
action = partial(new_action, self)
quit = action(get_str('quit'), self.close,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: Avoid using reserved names as variables.
For consistency I prepended "action_" to all action variables

Comment thread labelImg.py
action_save = action(get_str('save'), self.save_file,
'Ctrl+S', 'save', get_str('saveDetail'), enabled=False)

def get_format_meta(format):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: Avoid reserved names for variables

Comment thread labelImg.py
self.draw_squares_option.setChecked(settings.get(SETTING_DRAW_SQUARE, False))
self.draw_squares_option.triggered.connect(self.toggle_draw_square)

# Store actions for further handling.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This change might be a bit controversial.

Rationale: The Struct class injects members into a class in a way that linters cannot resolve, therefore they produce a lot of warnings. The does not seem to be a really good alternative to the Struct class after some research, so I opted to simply write a normal class manually and fill it with the actions.

I would suggest to eventually replace all this setup stuff by using the QtDesigner as it will generate the code and therefore significantly reduce the amount of manual code to be reviewed.

Comment thread labelImg.py
recent_file_qstring_list = settings.get(SETTING_RECENT_FILES)
self.recent_files = [ustr(i) for i in recent_file_qstring_list]
else:
self.recent_files = recent_file_qstring_list = settings.get(SETTING_RECENT_FILES)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: removed unused variable

Comment thread labelImg.py
self.load_file(filename)

# Add chris
def button_state(self, item=None):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: removed unused function argument

Comment thread labelImg.py

try:
shape = self.items_to_shapes[item]
except:
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: The second try/catch does not catch anything that the first did not catch anyway, so I integrated them into a single try/except block

Comment thread labelImg.py
annotation_file_path += XML_EXT
self.label_file.save_pascal_voc_format(annotation_file_path, shapes, self.file_path, self.image_data,
self.line_color.getRgb(), self.fill_color.getRgb())
self.label_file.save_pascal_voc_format(annotation_file_path, shapes, self.file_path, self.image_data)
Copy link
Copy Markdown
Contributor Author

@Cerno-b Cerno-b Mar 22, 2021

Choose a reason for hiding this comment

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

Rationale: The line and fill colors are not supported by the voc format, so I removed the call here. The same goes for the yolo and createML format

Having these arguments here may be a preparation for a future change to the code, but I followed the YAGNI principle here

Comment thread labelImg.py
elif self.label_file_format == LabelFileFormat.CREATE_ML:
if annotation_file_path[-5:].lower() != ".json":
annotation_file_path += JSON_EXT
self.label_file.save_create_ml_format(annotation_file_path, shapes, self.file_path, self.image_data,
Copy link
Copy Markdown
Contributor Author

@Cerno-b Cerno-b Mar 22, 2021

Choose a reason for hiding this comment

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

Finding: The CreateML format is currently not supported in the tool. It can be selected, but saving and loading does not work. I assume that this is a temporary fix for some incompatibility, but I would suggest either fixing it or getting rid of the format altogether to not have unexpected behavior in the tool.

I added an issue for this: #724

Comment thread labelImg.py

h_bar.setValue(new_h_bar_value)
v_bar.setValue(new_v_bar_value)
h_bar.setValue(int(new_h_bar_value))
Copy link
Copy Markdown
Contributor Author

@Cerno-b Cerno-b Mar 22, 2021

Choose a reason for hiding this comment

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

Rationale: There was an implicit conversion from float to int.

I changed it so that this is now explicit.

Both the implicit and the explicit conversions round down. If you want to have proper rounding up at 0.5, this needs to be changed.

To do:

  • Review and change if necessary

Comment thread labelImg.py
if unicode_file_path and os.path.exists(unicode_file_path):
if LabelFile.is_label_file(unicode_file_path):
try:
self.label_file = LabelFile(unicode_file_path)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: Removed unused constructor argument. Seems like an older artifact from a past refactoring step

Comment thread labelImg.py
self.label_list.setCurrentItem(self.label_list.item(self.label_list.count() - 1))
self.label_list.item(self.label_list.count() - 1).setSelected(True)

self.canvas.setFocus(True)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Finding: The setFocus function expects an enum, not a bool.
I looked up the corresponding value to True == 1 == Qt.TabFocusReason, so the behavior should be unchanged.

However, you might want to check out whether this does what you want it to do.

To do:

  • check if the enum value is what's intended here.

Comment thread labelImg.py
filename = filename[0]
self.load_pascal_xml_by_filename(filename)

def open_dir_dialog(self, _value=False, dir_path=None, silent=False):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: Remove unused argument

Comment thread labelImg.py
if not self.may_continue():
return

default_open_dir_path = dir_path if dir_path else '.'
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: This variable is overwritten in all following paths so I removed it

Comment thread labelImg.py


def get_main_app(argv=[]):
def get_main_app(argv=None):
Copy link
Copy Markdown
Contributor Author

@Cerno-b Cerno-b Mar 22, 2021

Choose a reason for hiding this comment

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

Rationale: Function arguments should not be mutable.

Comment thread libs/canvas.py

left_index = (index + 1) % 4
right_index = (index + 3) % 4
left_shift = None
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: Variables are overwritten in all following paths, so they can be removed

Comment thread libs/canvas.py
p.setPen(QColor(0, 0, 0))
p.drawLine(self.prev_point.x(), 0, self.prev_point.x(), self.pixmap.height())
p.drawLine(0, self.prev_point.y(), self.pixmap.width(), self.prev_point.y())
p.drawLine(int(self.prev_point.x()), 0, int(self.prev_point.x()), int(self.pixmap.height()))
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: There was an implicit conversion from float to int.

I changed it so that this is now explicit.

Both the implicit and the explicit conversions round down. If you want to have proper rounding up at 0.5, this needs to be changed.

To do:

  • Review and change if necessary

Comment thread libs/combo_box.py

class ComboBox(QWidget):
def __init__(self, parent=None, items=[]):
def __init__(self, parent=None, items=None):
Copy link
Copy Markdown
Contributor Author

@Cerno-b Cerno-b Mar 22, 2021

Choose a reason for hiding this comment

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

Rationale: Function arguments should not be mutable

Comment thread libs/label_file.py
@@ -32,13 +30,13 @@ class LabelFile(object):
# suffix = '.lif'
suffix = XML_EXT

def __init__(self, filename=None):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: Removed unused function argument

Comment thread libs/label_file.py
self.shapes = ()
self.image_path = None
self.image_data = None
self.verified = False

def save_create_ml_format(self, filename, shapes, image_path, image_data, class_list, line_color=None, fill_color=None, database_src=None):
Copy link
Copy Markdown
Contributor Author

@Cerno-b Cerno-b Mar 22, 2021

Choose a reason for hiding this comment

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

Rationale: Removed unused function arguments (also for yolo and pascal formats)

This might be a preparation for new functionality or an artifact from old code. Since you can choose box colors, but are unable to save them, I assume it's from old code and I think it makes sense to decide to either drop the box color support althogether or re-introduce saving the colors to the output files.

Following the YAGNI principle, I removed this. If you want to keep it, I can revert the change. I would suggest adding an issue about saving box colors in that case so it is not forgotten.

Comment thread libs/pascal_voc_io.py
return top

def add_bnd_box(self, x_min, y_min, x_max, y_max, name, difficult):
bnd_box = {'xmin': x_min, 'ymin': y_min, 'xmax': x_max, 'ymax': y_max}
Copy link
Copy Markdown
Contributor Author

@Cerno-b Cerno-b Mar 22, 2021

Choose a reason for hiding this comment

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

Rationale: Unified the definition into a single dictionary creation call

Comment thread libs/pascal_voc_io.py
def save(self, target_file=None):
root = self.gen_xml()
self.append_objects(root)
out_file = None
Copy link
Copy Markdown
Contributor Author

@Cerno-b Cerno-b Mar 22, 2021

Choose a reason for hiding this comment

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

Rationale: Variable is overwritten in all paths, so it can be removed

Comment thread libs/pascal_voc_io.py
assert self.file_path.endswith(XML_EXT), "Unsupported file format"
parser = etree.XMLParser(encoding=ENCODE_METHOD)
xml_tree = ElementTree.parse(self.file_path, parser=parser).getroot()
filename = xml_tree.find('filename').text
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: Variable is never used. Not sure whether this is a code artifact or points to a bug. May make sense to look into it

To do:

  • check if this is correct behavior

Comment thread libs/string_bundle.py
key = key_value[0].strip()
value = PROP_SEPERATOR.join(key_value[1:]).strip().strip('"')
self.id_to_message[key] = value
while not text.atEnd():
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: This would have lead to a crash if f.open() failed.

Comment thread libs/utils.py
return QRegExpValidator(QRegExp(r'^[^ \t].+'), None)


class Struct(object):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Comment thread libs/utils.py
"""p3/qt5 get rid of QString wrapper as py3 has native unicode str type"""
return not (sys.version_info.major >= 3 or QT_VERSION_STR.startswith('5.'))

def util_qt_strlistclass():
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: Remove unused function

Comment thread libs/utils.py
def util_qt_strlistclass():
return QStringList if have_qstring() else list

def natural_sort(list, key=lambda s:s):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: Avoid using reserved names in variables

Comment thread libs/utils.py
"""
Sort the list into natural alphanumeric order.
"""
def get_alphanum_key_func(key):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: Avoid using reserved names in variables

Comment thread libs/utils.py
return lambda s: [convert(c) for c in re.split('([0-9]+)', key(s))]
def get_alphanum_key_func(internal_key):

def convert(text):
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rationale: Avoid assigning a lambda expression, prefer using a function instead

@Cerno-b Cerno-b changed the title Fix warnings Fix more PEP 8 findings and warnings Mar 22, 2021
@Cerno-b Cerno-b mentioned this pull request Mar 22, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant