Speed increases, more typing, cleanup

Pull all playlist row info in one database query when loading a
playlist.

Fixup some type hints in models.

Comment out stackprinter calls - they mostly get in the way
interactively.
This commit is contained in:
Keith Edmunds 2023-10-15 19:04:58 +01:00
parent ae87ac82ba
commit 3513c32a62
7 changed files with 122 additions and 85 deletions

View File

@ -33,7 +33,7 @@ engine = create_engine(
echo=Config.DISPLAY_SQL,
pool_pre_ping=True,
future=True,
connect_args={"encoding": "utf-8"},
connect_args={"charset": "utf8mb4"},
)

View File

@ -75,8 +75,8 @@ def log_uncaught_exceptions(_ex_cls, ex, tb):
print("\033[1;31;47m")
logging.critical(''.join(traceback.format_tb(tb)))
print("\033[1;37;40m")
print(stackprinter.format(ex, show_vals="all", add_summary=True,
style="darkbg"))
# print(stackprinter.format(ex, show_vals="all", add_summary=True,
# style="darkbg"))
if os.environ["MM_ENV"] == "PRODUCTION":
msg = stackprinter.format(ex)
send_mail(Config.ERRORS_TO, Config.ERRORS_FROM,

View File

@ -6,7 +6,7 @@ from config import Config
from dbconfig import scoped_session
from datetime import datetime
from typing import List, Optional
from typing import List, Optional, Sequence
from sqlalchemy.ext.associationproxy import association_proxy
@ -172,7 +172,7 @@ class Playdates(Base):
return Config.EPOCH
@staticmethod
def played_after(session: scoped_session, since: datetime) -> List["Playdates"]:
def played_after(session: scoped_session, since: datetime) -> Sequence["Playdates"]:
"""Return a list of Playdates objects since passed time"""
return (
@ -256,7 +256,7 @@ class Playlists(Base):
session.flush()
@classmethod
def get_all(cls, session: scoped_session) -> List["Playlists"]:
def get_all(cls, session: scoped_session) -> Sequence["Playlists"]:
"""Returns a list of all playlists ordered by last use"""
return (
@ -270,7 +270,7 @@ class Playlists(Base):
)
@classmethod
def get_all_templates(cls, session: scoped_session) -> List["Playlists"]:
def get_all_templates(cls, session: scoped_session) -> Sequence["Playlists"]:
"""Returns a list of all templates ordered by name"""
return (
@ -282,7 +282,7 @@ class Playlists(Base):
)
@classmethod
def get_closed(cls, session: scoped_session) -> List["Playlists"]:
def get_closed(cls, session: scoped_session) -> Sequence["Playlists"]:
"""Returns a list of all closed playlists ordered by last use"""
return (
@ -300,7 +300,7 @@ class Playlists(Base):
)
@classmethod
def get_open(cls, session: scoped_session) -> List[Optional["Playlists"]]:
def get_open(cls, session: scoped_session) -> Sequence[Optional["Playlists"]]:
"""
Return a list of loaded playlists ordered by tab order.
"""
@ -435,6 +435,23 @@ class PlaylistRows(Base):
)
session.flush()
@classmethod
def deep_rows(cls, session: scoped_session, playlist_id: int) -> Sequence["PlaylistRows"]:
"""
Return a list of playlist rows that include full track and lastplayed data for
given playlist_id., Sequence
"""
stmt = (
select(PlaylistRows)
.options(joinedload(cls.track))
.where(PlaylistRows.playlist_id == playlist_id)
.order_by(PlaylistRows.plr_rownum)
# .options(joinedload(Tracks.playdates))
)
return session.scalars(stmt).unique().all()
@staticmethod
def fixup_rownumbers(session: scoped_session, playlist_id: int) -> None:
"""
@ -460,7 +477,7 @@ class PlaylistRows(Base):
@classmethod
def plrids_to_plrs(
cls, session: scoped_session, playlist_id: int, plr_ids: List[int]
) -> List["PlaylistRows"]:
) -> Sequence["PlaylistRows"]:
"""
Take a list of PlaylistRows ids and return a list of corresponding
PlaylistRows objects
@ -506,7 +523,7 @@ class PlaylistRows(Base):
@classmethod
def get_played_rows(
cls, session: scoped_session, playlist_id: int
) -> List["PlaylistRows"]:
) -> Sequence["PlaylistRows"]:
"""
For passed playlist, return a list of rows that
have been played.
@ -531,7 +548,7 @@ class PlaylistRows(Base):
playlist_id: int,
from_row: Optional[int] = None,
to_row: Optional[int] = None,
) -> List["PlaylistRows"]:
) -> Sequence["PlaylistRows"]:
"""
For passed playlist, return a list of rows that
contain tracks
@ -552,7 +569,7 @@ class PlaylistRows(Base):
@classmethod
def get_unplayed_rows(
cls, session: scoped_session, playlist_id: int
) -> List["PlaylistRows"]:
) -> Sequence["PlaylistRows"]:
"""
For passed playlist, return a list of playlist rows that
have not been played.
@ -613,6 +630,20 @@ class Settings(Base):
session.add(self)
session.flush()
@classmethod
def all_as_dict(cls, session):
"""
Return all setting in a dictionary keyed by name
"""
result = {}
settings = session.execute(select(cls)).scalars().all()
for setting in settings:
result[setting.name] = setting
return result
@classmethod
def get_int_settings(cls, session: scoped_session, name: str) -> "Settings":
"""Get setting for an integer or return new setting record"""
@ -713,7 +744,7 @@ class Tracks(Base):
return None
@classmethod
def search_artists(cls, session: scoped_session, text: str) -> List["Tracks"]:
def search_artists(cls, session: scoped_session, text: str) -> Sequence["Tracks"]:
"""
Search case-insenstively for artists containing str
@ -735,7 +766,7 @@ class Tracks(Base):
)
@classmethod
def search_titles(cls, session: scoped_session, text: str) -> List["Tracks"]:
def search_titles(cls, session: scoped_session, text: str) -> Sequence["Tracks"]:
"""
Search case-insenstively for titles containing str

View File

@ -545,19 +545,20 @@ class Window(QMainWindow, Ui_MainWindow):
)
else:
with Session() as session:
record = Settings.get_int_settings(session, "mainwindow_height")
settings = Settings.all_as_dict(session)
record = settings["mainwindow_height"]
if record.f_int != self.height():
record.update(session, {"f_int": self.height()})
record = Settings.get_int_settings(session, "mainwindow_width")
record = settings["mainwindow_width"]
if record.f_int != self.width():
record.update(session, {"f_int": self.width()})
record = Settings.get_int_settings(session, "mainwindow_x")
record = settings["mainwindow_x"]
if record.f_int != self.x():
record.update(session, {"f_int": self.x()})
record = Settings.get_int_settings(session, "mainwindow_y")
record = settings["mainwindow_y"]
if record.f_int != self.y():
record.update(session, {"f_int": self.y()})
@ -566,16 +567,16 @@ class Window(QMainWindow, Ui_MainWindow):
assert len(splitter_sizes) == 2
splitter_top, splitter_bottom = splitter_sizes
record = Settings.get_int_settings(session, "splitter_top")
record = settings["splitter_top"]
if record.f_int != splitter_top:
record.update(session, {"f_int": splitter_top})
record = Settings.get_int_settings(session, "splitter_bottom")
record = settings["splitter_bottom"]
if record.f_int != splitter_bottom:
record.update(session, {"f_int": splitter_bottom})
# Save current tab
record = Settings.get_int_settings(session, "active_tab")
record = settings["active_tab"]
record.update(session, {"f_int": self.tabPlaylist.currentIndex()})
event.accept()
@ -1484,18 +1485,19 @@ class Window(QMainWindow, Ui_MainWindow):
"""Set size of window from database"""
with Session() as session:
record = Settings.get_int_settings(session, "mainwindow_x")
settings = Settings.all_as_dict(session)
record = settings["mainwindow_x"]
x = record.f_int or 1
record = Settings.get_int_settings(session, "mainwindow_y")
record = settings["mainwindow_y"]
y = record.f_int or 1
record = Settings.get_int_settings(session, "mainwindow_width")
record = settings["mainwindow_width"]
width = record.f_int or 1599
record = Settings.get_int_settings(session, "mainwindow_height")
record = settings["mainwindow_height"]
height = record.f_int or 981
self.setGeometry(x, y, width, height)
record = Settings.get_int_settings(session, "splitter_top")
record = settings["splitter_top"]
splitter_top = record.f_int or 256
record = Settings.get_int_settings(session, "splitter_bottom")
record = settings["splitter_bottom"]
splitter_bottom = record.f_int or 256
self.splitter.setSizes([splitter_top, splitter_bottom])
return
@ -2161,6 +2163,6 @@ if __name__ == "__main__":
msg,
)
print("\033[1;31;47mUnhandled exception starts")
stackprinter.show(style="darkbg")
print("Unhandled exception ends\033[1;37;40m")
# print("\033[1;31;47mUnhandled exception starts")
# stackprinter.show(style="darkbg")
# print("Unhandled exception ends\033[1;37;40m")

View File

@ -613,8 +613,6 @@ class PlaylistTab(QTableWidget):
if played:
bold = False
_ = self._set_row_userdata(row_number, self.PLAYED, True)
if plr.note is None:
plr.note = ""
self._set_row_note_text(session, row_number, plr.note)
else:
# This is a section header so it must have note text
@ -745,7 +743,7 @@ class PlaylistTab(QTableWidget):
stackprinter.format(),
)
print("playlists:play_started:current_row is None")
stackprinter.show(add_summary=True, style="darkbg")
# stackprinter.show(add_summary=True, style="darkbg")
return
# Mark current row as played
@ -797,10 +795,10 @@ class PlaylistTab(QTableWidget):
stackprinter.format(),
)
print("playlists:populate_display:no playlist")
stackprinter.show(add_summary=True, style="darkbg")
# stackprinter.show(add_summary=True, style="darkbg")
return
for plr in playlist.rows:
for plr in PlaylistRows.deep_rows(session, playlist_id):
self.insert_row(
session,
plr,
@ -817,7 +815,6 @@ class PlaylistTab(QTableWidget):
# Set widths
self._set_column_widths(session)
self.save_playlist(session)
# Queue up time calculations to take place after UI has
# updated
self._update_start_end_times(session)
@ -1143,6 +1140,7 @@ class PlaylistTab(QTableWidget):
"""
with Session() as session:
settings = Settings.all_as_dict(session)
for column_name, data in columns.items():
idx = data.idx
if idx == len(columns) - 1:
@ -1151,7 +1149,7 @@ class PlaylistTab(QTableWidget):
continue
width = self.columnWidth(idx)
attribute_name = f"playlist_{column_name}_col_width"
record = Settings.get_int_settings(session, attribute_name)
record = settings[attribute_name]
if record.f_int != self.columnWidth(idx):
record.update(session, {"f_int": width})
@ -1896,6 +1894,8 @@ class PlaylistTab(QTableWidget):
def _set_column_widths(self, session: scoped_session) -> None:
"""Column widths from settings"""
settings = Settings.all_as_dict(session)
for column_name, data in columns.items():
idx = data.idx
if idx == len(columns) - 1:
@ -1903,7 +1903,7 @@ class PlaylistTab(QTableWidget):
self.setColumnWidth(idx, 0)
continue
attr_name = f"playlist_{column_name}_col_width"
record: Settings = Settings.get_int_settings(session, attr_name)
record = settings[attr_name]
if record and record.f_int >= 0:
self.setColumnWidth(idx, record.f_int)
else:
@ -2080,8 +2080,10 @@ class PlaylistTab(QTableWidget):
"playlists:_set_row_header_text() called on track row",
stackprinter.format(),
)
print("playists:_set_row_header_text() called on track row")
stackprinter.show(add_summary=True, style="darkbg")
print(
f"playists:_set_row_header_text() called on track row ({row_number=}, {text=}"
)
# stackprinter.show(add_summary=True, style="darkbg")
return
# Set text
@ -2120,8 +2122,10 @@ class PlaylistTab(QTableWidget):
"playlists:_set_row_note_colour() on header row",
stackprinter.format(),
)
print("playists:_set_row_note_colour() called on header row")
stackprinter.show(add_summary=True, style="darkbg")
# stackprinter.show(add_summary=True, style="darkbg")
print(
f"playists:_set_row_note_colour() called on track row ({row_number=}"
)
return
# Set colour
@ -2146,8 +2150,10 @@ class PlaylistTab(QTableWidget):
"playlists:_set_row_note_text() called on header row",
stackprinter.format(),
)
print("playists:_set_row_note_text() called on header row")
stackprinter.show(add_summary=True, style="darkbg")
print(
f"playists:_set_row_note_text() called on header row ({row_number=}, {text=}"
)
# stackprinter.show(add_summary=True, style="darkbg")
return
# Set text
@ -2388,9 +2394,11 @@ class PlaylistTab(QTableWidget):
_ = self._set_row_bitrate(row, track.bitrate)
_ = self._set_row_duration(row, track.duration)
_ = self._set_row_end_time(row, None)
_ = self._set_row_last_played_time(
row, Playdates.last_played(session, track.id)
)
if track.playdates:
last_play = max([a.lastplayed for a in track.playdates])
else:
last_play = Config.EPOCH
_ = self._set_row_last_played_time(row, last_play)
_ = self._set_row_start_gap(row, track.start_gap)
_ = self._set_row_start_time(row, None)
_ = self._set_row_title(row, track.title)

68
poetry.lock generated
View File

@ -847,53 +847,49 @@ files = [
[[package]]
name = "mypy"
version = "0.991"
version = "1.6.0"
description = "Optional static typing for Python"
category = "dev"
optional = false
python-versions = ">=3.7"
python-versions = ">=3.8"
files = [
{file = "mypy-0.991-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7d17e0a9707d0772f4a7b878f04b4fd11f6f5bcb9b3813975a9b13c9332153ab"},
{file = "mypy-0.991-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0714258640194d75677e86c786e80ccf294972cc76885d3ebbb560f11db0003d"},
{file = "mypy-0.991-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c8f3be99e8a8bd403caa8c03be619544bc2c77a7093685dcf308c6b109426c6"},
{file = "mypy-0.991-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc9ec663ed6c8f15f4ae9d3c04c989b744436c16d26580eaa760ae9dd5d662eb"},
{file = "mypy-0.991-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4307270436fd7694b41f913eb09210faff27ea4979ecbcd849e57d2da2f65305"},
{file = "mypy-0.991-cp310-cp310-win_amd64.whl", hash = "sha256:901c2c269c616e6cb0998b33d4adbb4a6af0ac4ce5cd078afd7bc95830e62c1c"},
{file = "mypy-0.991-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d13674f3fb73805ba0c45eb6c0c3053d218aa1f7abead6e446d474529aafc372"},
{file = "mypy-0.991-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1c8cd4fb70e8584ca1ed5805cbc7c017a3d1a29fb450621089ffed3e99d1857f"},
{file = "mypy-0.991-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:209ee89fbb0deed518605edddd234af80506aec932ad28d73c08f1400ef80a33"},
{file = "mypy-0.991-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37bd02ebf9d10e05b00d71302d2c2e6ca333e6c2a8584a98c00e038db8121f05"},
{file = "mypy-0.991-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:26efb2fcc6b67e4d5a55561f39176821d2adf88f2745ddc72751b7890f3194ad"},
{file = "mypy-0.991-cp311-cp311-win_amd64.whl", hash = "sha256:3a700330b567114b673cf8ee7388e949f843b356a73b5ab22dd7cff4742a5297"},
{file = "mypy-0.991-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:1f7d1a520373e2272b10796c3ff721ea1a0712288cafaa95931e66aa15798813"},
{file = "mypy-0.991-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:641411733b127c3e0dab94c45af15fea99e4468f99ac88b39efb1ad677da5711"},
{file = "mypy-0.991-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3d80e36b7d7a9259b740be6d8d906221789b0d836201af4234093cae89ced0cd"},
{file = "mypy-0.991-cp37-cp37m-win_amd64.whl", hash = "sha256:e62ebaad93be3ad1a828a11e90f0e76f15449371ffeecca4a0a0b9adc99abcef"},
{file = "mypy-0.991-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b86ce2c1866a748c0f6faca5232059f881cda6dda2a893b9a8373353cfe3715a"},
{file = "mypy-0.991-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac6e503823143464538efda0e8e356d871557ef60ccd38f8824a4257acc18d93"},
{file = "mypy-0.991-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0cca5adf694af539aeaa6ac633a7afe9bbd760df9d31be55ab780b77ab5ae8bf"},
{file = "mypy-0.991-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12c56bf73cdab116df96e4ff39610b92a348cc99a1307e1da3c3768bbb5b135"},
{file = "mypy-0.991-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:652b651d42f155033a1967739788c436491b577b6a44e4c39fb340d0ee7f0d70"},
{file = "mypy-0.991-cp38-cp38-win_amd64.whl", hash = "sha256:4175593dc25d9da12f7de8de873a33f9b2b8bdb4e827a7cae952e5b1a342e243"},
{file = "mypy-0.991-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:98e781cd35c0acf33eb0295e8b9c55cdbef64fcb35f6d3aa2186f289bed6e80d"},
{file = "mypy-0.991-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6d7464bac72a85cb3491c7e92b5b62f3dcccb8af26826257760a552a5e244aa5"},
{file = "mypy-0.991-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c9166b3f81a10cdf9b49f2d594b21b31adadb3d5e9db9b834866c3258b695be3"},
{file = "mypy-0.991-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8472f736a5bfb159a5e36740847808f6f5b659960115ff29c7cecec1741c648"},
{file = "mypy-0.991-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e80e758243b97b618cdf22004beb09e8a2de1af481382e4d84bc52152d1c476"},
{file = "mypy-0.991-cp39-cp39-win_amd64.whl", hash = "sha256:74e259b5c19f70d35fcc1ad3d56499065c601dfe94ff67ae48b85596b9ec1461"},
{file = "mypy-0.991-py3-none-any.whl", hash = "sha256:de32edc9b0a7e67c2775e574cb061a537660e51210fbf6006b0b36ea695ae9bb"},
{file = "mypy-0.991.tar.gz", hash = "sha256:3c0165ba8f354a6d9881809ef29f1a9318a236a6d81c690094c5df32107bde06"},
{file = "mypy-1.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:091f53ff88cb093dcc33c29eee522c087a438df65eb92acd371161c1f4380ff0"},
{file = "mypy-1.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb7ff4007865833c470a601498ba30462b7374342580e2346bf7884557e40531"},
{file = "mypy-1.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49499cf1e464f533fc45be54d20a6351a312f96ae7892d8e9f1708140e27ce41"},
{file = "mypy-1.6.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4c192445899c69f07874dabda7e931b0cc811ea055bf82c1ababf358b9b2a72c"},
{file = "mypy-1.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:3df87094028e52766b0a59a3e46481bb98b27986ed6ded6a6cc35ecc75bb9182"},
{file = "mypy-1.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c8835a07b8442da900db47ccfda76c92c69c3a575872a5b764332c4bacb5a0a"},
{file = "mypy-1.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:24f3de8b9e7021cd794ad9dfbf2e9fe3f069ff5e28cb57af6f873ffec1cb0425"},
{file = "mypy-1.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:856bad61ebc7d21dbc019b719e98303dc6256cec6dcc9ebb0b214b81d6901bd8"},
{file = "mypy-1.6.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:89513ddfda06b5c8ebd64f026d20a61ef264e89125dc82633f3c34eeb50e7d60"},
{file = "mypy-1.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:9f8464ed410ada641c29f5de3e6716cbdd4f460b31cf755b2af52f2d5ea79ead"},
{file = "mypy-1.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:971104bcb180e4fed0d7bd85504c9036346ab44b7416c75dd93b5c8c6bb7e28f"},
{file = "mypy-1.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ab98b8f6fdf669711f3abe83a745f67f50e3cbaea3998b90e8608d2b459fd566"},
{file = "mypy-1.6.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a69db3018b87b3e6e9dd28970f983ea6c933800c9edf8c503c3135b3274d5ad"},
{file = "mypy-1.6.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:dccd850a2e3863891871c9e16c54c742dba5470f5120ffed8152956e9e0a5e13"},
{file = "mypy-1.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:f8598307150b5722854f035d2e70a1ad9cc3c72d392c34fffd8c66d888c90f17"},
{file = "mypy-1.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fea451a3125bf0bfe716e5d7ad4b92033c471e4b5b3e154c67525539d14dc15a"},
{file = "mypy-1.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e28d7b221898c401494f3b77db3bac78a03ad0a0fff29a950317d87885c655d2"},
{file = "mypy-1.6.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4b7a99275a61aa22256bab5839c35fe8a6887781862471df82afb4b445daae6"},
{file = "mypy-1.6.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7469545380dddce5719e3656b80bdfbb217cfe8dbb1438532d6abc754b828fed"},
{file = "mypy-1.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:7807a2a61e636af9ca247ba8494031fb060a0a744b9fee7de3a54bed8a753323"},
{file = "mypy-1.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d2dad072e01764823d4b2f06bc7365bb1d4b6c2f38c4d42fade3c8d45b0b4b67"},
{file = "mypy-1.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b19006055dde8a5425baa5f3b57a19fa79df621606540493e5e893500148c72f"},
{file = "mypy-1.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31eba8a7a71f0071f55227a8057468b8d2eb5bf578c8502c7f01abaec8141b2f"},
{file = "mypy-1.6.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e0db37ac4ebb2fee7702767dfc1b773c7365731c22787cb99f507285014fcaf"},
{file = "mypy-1.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:c69051274762cccd13498b568ed2430f8d22baa4b179911ad0c1577d336ed849"},
{file = "mypy-1.6.0-py3-none-any.whl", hash = "sha256:9e1589ca150a51d9d00bb839bfeca2f7a04f32cd62fad87a847bc0818e15d7dc"},
{file = "mypy-1.6.0.tar.gz", hash = "sha256:4f3d27537abde1be6d5f2c96c29a454da333a2a271ae7d5bc7110e6d4b7beb3f"},
]
[package.dependencies]
mypy-extensions = ">=0.4.3"
mypy-extensions = ">=1.0.0"
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
typing-extensions = ">=3.10"
typing-extensions = ">=4.1.0"
[package.extras]
dmypy = ["psutil (>=4.0)"]
install-types = ["pip"]
python2 = ["typed-ast (>=1.4.0,<2)"]
reports = ["lxml"]
[[package]]
@ -2174,4 +2170,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
[metadata]
lock-version = "2.0"
python-versions = "^3.9"
content-hash = "b9312f2126e81b0d924d6f1ae5c73d49f45c74c046cc6dfc18be391f23c04f07"
content-hash = "e972b690d5534b2c916475727d2f843a09391007d333b4989787246274cd5e7e"

View File

@ -35,7 +35,6 @@ pytest-qt = "^4.0.2"
pydub-stubs = "^0.25.1"
line-profiler = "^4.0.2"
flakehell = "^0.9.0"
mypy = "^0.991"
[tool.poetry.group.dev.dependencies]
pudb = "^2022.1.3"
@ -43,6 +42,7 @@ sphinx = "^7.0.1"
furo = "^2023.5.20"
black = "^23.3.0"
flakehell = "^0.9.0"
mypy = "^1.6.0"
[build-system]
requires = ["poetry-core>=1.0.0"]