Skip to content

Commit

Permalink
Lots of Ruff
Browse files Browse the repository at this point in the history
  • Loading branch information
Nodd committed Sep 10, 2023
1 parent 38ba2d6 commit 5cb6875
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 43 deletions.
74 changes: 74 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Source = "https://github.com/Nodd/lineprofilergui"
pyqt5 = ["pyqt5"]
pyside2 = ["pyside2"]
test = ["pytest", "pytest-qt", "pytest-cov"]
dev = ["ruff>=0.0.273", "black>=23"]

[project.gui-scripts]
lineprofilergui = "lineprofilergui.main:main"
Expand All @@ -61,3 +62,76 @@ testpaths = ["tests"]
addopts = "--cov lineprofilergui"
# TODO: test with pyside too (use PYTEST_QT_API=pyside2 environment variable ?)
qt_api = "pyqt5"

[tool.ruff]
src = ["src", "tests"]
exclude = ["example"]
select = [
"F",
"E",
"W",
"C90",
"I",
"N",
"D",
"UP",
"YTT",
# "ANN", # Missing type annotations
"ASYNC",
"S",
"BLE",
# "FBT", # Boolean traps
"B",
"A",
"COM",
"C4",
"DTZ",
"T10",
"DJ",
"EM",
"EXE",
"FA",
"ISC",
"ICN",
"G",
"INP",
"PIE",
"T20",
"PYI",
"PT",
"Q",
"RSE",
"RET",
"SLF",
"SIM",
"TID",
"TCH",
"INT",
"ARG",
"PTH",
# "TD", # TODOs
# "ERA", # Found commented-out code
# "PD", # Pandas
"PGH",
"PL",
"TRY",
"FLY",
# "NPY", # Numpy
"RUF",
]
ignore = [
"ARG002", # Unused method argument
"COM812", # Trailing comma missing
"D1", # Missing docstring
"D203", # one-blank-line-before-class incompatible with no-blank-line-before-class
"D213", # multi-line-summary-second-line incompatible with multi-line-summary-first-line
"DTZ005", # The use of `datetime.datetime.now()` without `tz` argument is not allowed
"E501", # Line too long
"EM101", # Exception must not use a string literal, assign to variable first
"EM102", # Exception must not use an f-string literal, assign to variable first
"N802", # Function name should be lowercase
"N806", # Variable in function should be lowercase
"PLR2004", # Magic value used in comparison, consider replacing with a constant variable
"RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
"S101", # Use of `assert` detected
]
19 changes: 9 additions & 10 deletions src/lineprofilergui/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ def isvalid_warmup(self):
def stats(self):
if self.stats_tmp:
return os.fspath(Path(self.temp_dir) / f"{Path(self.script).stem}.lprof")
else:
return self.config_stats or self.default_stats
return self.config_stats or self.default_stats

@property
def default_stats(self):
Expand Down Expand Up @@ -115,7 +114,7 @@ def env(self):
@property
def isvalid_env(self):
try:
self.env
self.env # noqa: B018
except ValueError:
return False
return True
Expand All @@ -132,7 +131,7 @@ def isvalid(self):
)


class Ui_ConfigDialog(QtWidgets.QDialog):
class UiConfigDialog(QtWidgets.QDialog):
def __init__(self, parent, config):
self.config = config

Expand Down Expand Up @@ -188,7 +187,7 @@ def update_stats_enabled(self):
self.statsWidget.setEnabled(not stats_tmp)
self.statsButton.setEnabled(not stats_tmp)

def setup_ui(self):
def setup_ui(self): # noqa: PLR0915
# Dialog
self.setObjectName("self")
self.resize(600, 186)
Expand Down Expand Up @@ -477,18 +476,18 @@ def on_kernprofButton_clicked(self):


class ConfigValidator(QtGui.QValidator):
def __init__(self, configDialog, widgetID):
def __init__(self, config_dialog, widget_id):
super().__init__()
self.configDialog = configDialog
self.widgetID = widgetID
self.config_dialog = config_dialog
self.widget_id = widget_id

@QtCore.Slot(str, int)
def validate(self, text, pos):
config = Config()
self.configDialog.ui_to_config(config)
self.config_dialog.ui_to_config(config)
return (
QtGui.QValidator.Acceptable
if getattr(config, f"isvalid_{self.widgetID}")
if getattr(config, f"isvalid_{self.widget_id}")
else QtGui.QValidator.Intermediate,
text,
pos,
Expand Down
12 changes: 6 additions & 6 deletions src/lineprofilergui/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
from qtpy.QtCore import Qt

from . import __version__
from .config import Config, Ui_ConfigDialog
from .config import Config, UiConfigDialog
from .process import KernprofRun
from .settings import UI_SettingsDialog
from .settings import UISettingsDialog
from .theme import update_theme
from .tree import ResultsTreeWidget, load_profile_data
from .utils import ICONS, MONOSPACE_FONT, PIXMAPS
Expand All @@ -23,7 +23,7 @@
LINE_PROFILER_DOC_URL = "https://github.com/pyutils/line_profiler#id2"


class UI_MainWindow(QtWidgets.QMainWindow):
class UIMainWindow(QtWidgets.QMainWindow):
# Used for testing purposes
profile_finished = QtCore.Signal()

Expand All @@ -37,7 +37,7 @@ def __init__(self):

self.profile_start_time = None

def setup_ui(self):
def setup_ui(self): # noqa: PLR0915
# Main window
# app.setWindowIcon(QIcon(_WINDOW_ICON))
self.resize(800, 600)
Expand Down Expand Up @@ -148,7 +148,7 @@ def setup_ui(self):
self.statusbar_time = QtWidgets.QLabel()
self.statusbar.addWidget(self.statusbar_time)

self.settingsDialog = UI_SettingsDialog(self)
self.settingsDialog = UISettingsDialog(self)

# Finalization
self.retranslate_ui()
Expand Down Expand Up @@ -252,7 +252,7 @@ def selectLprof(self):

@QtCore.Slot()
def configure(self):
Ui_ConfigDialog(self, self.config).exec()
UiConfigDialog(self, self.config).exec()
self.update_window_title()

@QtCore.Slot()
Expand Down
5 changes: 2 additions & 3 deletions src/lineprofilergui/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from qtpy import QtCore, QtWidgets

from . import __version__
from .gui import UI_MainWindow
from .gui import UIMainWindow
from .utils import icons_factory


Expand All @@ -17,7 +17,6 @@ def positive_float(value):

def commandline_args(args):
"""Manage arguments with argparse."""

parser = argparse.ArgumentParser(
description="Run, profile a python script and display results."
)
Expand Down Expand Up @@ -56,7 +55,7 @@ def make_window(args=None):
QtCore.QCoreApplication.setApplicationName("Line Profiler Gui")

# Create main window
win = UI_MainWindow()
win = UIMainWindow()
win.show()

if options.lprof:
Expand Down
2 changes: 1 addition & 1 deletion src/lineprofilergui/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
]


class UI_SettingsDialog(QtWidgets.QDialog):
class UISettingsDialog(QtWidgets.QDialog):
def __init__(self, parent):
super().__init__(parent)
self.setup_ui()
Expand Down
24 changes: 11 additions & 13 deletions src/lineprofilergui/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def load_profile_data(filename):
# (line_no3, hits3, total_time3)]}
# stats.unit = time_factor
with open(filename, "rb") as fid:
stats = pickle.load(fid)
stats = pickle.load(fid) # noqa: S301

data = []
for func_info, func_stats in stats.timings.items():
Expand All @@ -49,7 +49,7 @@ def __init__(self, func_info, stats, time_unit):
self.parse_stats(stats)

@property
def id(self):
def func_id(self):
return (self.filename, self.name)

def load_code(self):
Expand All @@ -59,17 +59,17 @@ def load_code(self):
# the correct lines.
all_lines = linecache.getlines(self.filename)
self.code_lines = inspect.getblock(
all_lines[self.start_line_no :] # noqa: E203
all_lines[self.start_line_no :]
)

def parse_stats(self, stats):
self.line_data = []
self.total_time = 0.0
self.was_called = False
next_stat_index = 0
for line_no, code_line in enumerate(self.code_lines):
line_no += self.start_line_no + 1 # Lines start at 1
code_line = code_line.rstrip()
for func_line_no, code_line_raw in enumerate(self.code_lines):
line_no = func_line_no + self.start_line_no + 1 # Lines start at 1
code_line = code_line_raw.rstrip()

# stats contains data for runned lines only : (line_no, hits, total_time)
if next_stat_index >= len(stats) or line_no != stats[next_stat_index][0]:
Expand Down Expand Up @@ -100,22 +100,20 @@ def color(self):
+ 0.068 * color.blueF() ** 2
)
perceived_luminance /= 0.642 # Normalize to stay inside the RGB range
color = QtGui.QColor.fromRgbF(
return QtGui.QColor.fromRgbF(
color.redF() / perceived_luminance,
color.greenF() / perceived_luminance,
color.blueF() / perceived_luminance,
)

return color

def __iter__(self):
yield from self.line_data


class LineData:
__slots__ = "_func_data line_no code total_time hits filename".split()

def __init__(self, func_data, line_no, code, total_time, hits):
def __init__(self, func_data, line_no, code, total_time, hits): # noqa: PLR0913
self._func_data = func_data
self.line_no = line_no
self.code = code
Expand Down Expand Up @@ -264,7 +262,7 @@ def populate_tree(self, profiledata):
time_ms=func_data.total_time * 1e3,
),
)
func_item.setData(self.COL_0, Qt.UserRole, func_data.id)
func_item.setData(self.COL_0, Qt.UserRole, func_data.func_id)
func_item.setFirstColumnSpanned(True)
if not func_data.was_called:
func_item.setForeground(self.COL_0, self.CODE_NOT_RUN_COLOR)
Expand Down Expand Up @@ -340,9 +338,9 @@ def item_activated(self, item):

# Run
try:
subprocess.Popen(editor_command, shell=False)
subprocess.Popen(editor_command, shell=False) # noqa: S603
except FileNotFoundError:
subprocess.Popen(editor_command, shell=True)
subprocess.Popen(editor_command, shell=True) # noqa: S602

@QtCore.Slot(QtWidgets.QTreeWidgetItem)
def item_collapsed(self, item):
Expand Down
6 changes: 3 additions & 3 deletions tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
from lineprofilergui.config import Config, Ui_ConfigDialog
from lineprofilergui.config import Config, UiConfigDialog
from lineprofilergui.utils import icons_factory


class TestConfig:
def test_default_config(self, qtbot):
icons_factory()
config = Config()
config_dialog = Ui_ConfigDialog(None, config)
config_dialog = UiConfigDialog(None, config)

assert not config.isvalid
assert not config_dialog.profileButton.isEnabled()

def test_config_with_script(self, qtbot):
icons_factory()
config = Config()
config_dialog = Ui_ConfigDialog(None, config)
config_dialog = UiConfigDialog(None, config)
config_dialog.scriptWidget.setText(__file__)
config_dialog.ui_to_config()

Expand Down
2 changes: 1 addition & 1 deletion tests/test_mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ def long_running_function():

with tmp_path:
main.icons_factory()
win = main.UI_MainWindow()
win = main.UIMainWindow()
qtbot.addWidget(win)

win.config.script = str(scriptfile)
Expand Down
6 changes: 2 additions & 4 deletions tests/test_theme.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from qtpy.QtCore import Qt

from lineprofilergui import main, theme


Expand All @@ -8,12 +6,12 @@ class TestTheme:

def test_dark_theme(self, qtbot):
# Just check that the code runs without error
win = main.UI_MainWindow()
win = main.UIMainWindow()
qtbot.addWidget(win)
theme.apply_dark_theme()

def test_light_theme(self, qtbot):
# Just check that the code runs without error
win = main.UI_MainWindow()
win = main.UIMainWindow()
qtbot.addWidget(win)
theme.apply_default_theme()
4 changes: 2 additions & 2 deletions tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@


def run_code(code, tmp_path, qtbot):
"""Helper function to run profiled code from UI_MainWindow."""
"""Define helper function to run profiled code from UIMainWindow."""
scriptfile = tmp_path / "script.py"
scriptfile.write_text(textwrap.dedent(code))

with tmp_path:
main.icons_factory()
win = main.UI_MainWindow()
win = main.UIMainWindow()
qtbot.addWidget(win)

win.config.script = str(scriptfile)
Expand Down

0 comments on commit 5cb6875

Please sign in to comment.