Skip to content

Commit 2dd178f

Browse files
committed
ci: fix flake8 and pyupgrade lint findings in gpif.py + gpx.py
CI's `Lint` job runs `pyupgrade --py39-plus` and `flake8` on every PR. After the gp7→gpif rename and the GP6 GPX additions, several formatting issues surfaced: * Drop unused `typing.Optional` imports in both modules — replaced by the PEP 604 `X | None` syntax pyupgrade emits. * Collapse aligned-column dict/constant blocks to single-space spacing (E221/E241) so flake8 doesn't fight visual alignment. * Add the missing blank line after `_drum_articulation_default` (E305). * Insert the blank line before the nested `make_pitch` definition in `_fill_chord_degrees` (E306). * Drop the dead `root_doc = None` initialiser in `_read_master_bars` (F841). * Tighten the slice whitespace in `gpx.py` (E203). No behaviour changes; 1847/1847 tests pass.
1 parent 95e8466 commit 2dd178f

2 files changed

Lines changed: 46 additions & 47 deletions

File tree

src/guitarpro/gpif.py

Lines changed: 42 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -131,28 +131,27 @@
131131

132132
import io
133133
import zipfile
134-
from typing import Optional
135134
from xml.etree import ElementTree as ET
136135

137136
from . import models as gp
138137

139138

140139
# ── XML helpers ───────────────────────────────────────────────────────
141140

142-
def _text(elem: Optional[ET.Element], default: str = "") -> str:
141+
def _text(elem: ET.Element | None, default: str = "") -> str:
143142
if elem is None or elem.text is None:
144143
return default
145144
return elem.text.strip()
146145

147146

148-
def _int(elem: Optional[ET.Element], default: int = 0) -> int:
147+
def _int(elem: ET.Element | None, default: int = 0) -> int:
149148
try:
150149
return int(_text(elem, str(default)))
151150
except ValueError:
152151
return default
153152

154153

155-
def _float(elem: Optional[ET.Element], default: float = 0.0) -> float:
154+
def _float(elem: ET.Element | None, default: float = 0.0) -> float:
156155
if elem is None or elem.text is None:
157156
return default
158157
try:
@@ -214,7 +213,7 @@ def _split_tokens(text: str) -> list[str]:
214213
}
215214

216215

217-
def _music_font_symbol(token: str) -> "gp.MusicFontSymbol":
216+
def _music_font_symbol(token: str) -> gp.MusicFontSymbol:
218217
"""Map a GPIF music-font token (``noteheadHalf``, ``guitarGolpe``,
219218
…) onto PyGuitarPro's ``MusicFontSymbol`` enum.
220219
@@ -229,7 +228,7 @@ def _music_font_symbol(token: str) -> "gp.MusicFontSymbol":
229228
return gp.MusicFontSymbol.none
230229

231230

232-
def _technique_symbol_placement(token: str) -> "gp.TechniqueSymbolPlacement":
231+
def _technique_symbol_placement(token: str) -> gp.TechniqueSymbolPlacement:
233232
"""GPIF ``<TechniquePlacement>`` token → enum. Unknown tokens fall
234233
back to ``outside`` (alphaTab's default)."""
235234
try:
@@ -239,53 +238,53 @@ def _technique_symbol_placement(token: str) -> "gp.TechniqueSymbolPlacement":
239238

240239

241240
_DURATION_MAP = {
242-
"Long": -4, # Longa / QuadrupleWhole (4 whole notes)
241+
"Long": -4, # Longa / QuadrupleWhole (4 whole notes)
243242
"DoubleWhole": -2, # Breve; represented with AT's negative sentinel
244-
"Whole": 1,
245-
"Half": 2,
243+
"Whole": 1,
244+
"Half": 2,
246245
"Quarter": 4,
247-
"Eighth": 8,
248-
"16th": 16,
249-
"32nd": 32,
250-
"64th": 64,
251-
"128th": 128,
252-
"256th": 256,
246+
"Eighth": 8,
247+
"16th": 16,
248+
"32nd": 32,
249+
"64th": 64,
250+
"128th": 128,
251+
"256th": 256,
253252
}
254253

255254
_DYNAMIC_VELOCITY = {
256255
"PPP": 15,
257-
"PP": 31,
258-
"P": 47,
259-
"MP": 63,
260-
"MF": 79,
261-
"F": 95,
262-
"FF": 111,
256+
"PP": 31,
257+
"P": 47,
258+
"MP": 63,
259+
"MF": 79,
260+
"F": 95,
261+
"FF": 111,
263262
"FFF": 127,
264263
}
265264

266265
_CLEF_MAP = {
267-
"G2": 0, # treble
268-
"F4": 1, # bass
269-
"C4": 2, # tenor
270-
"C3": 3, # alto
266+
"G2": 0, # treble
267+
"F4": 1, # bass
268+
"C4": 2, # tenor
269+
"C3": 3, # alto
271270
"Neutral": 0, # neutral — use treble as default
272271
}
273272

274273
# Accent flag bits (<Accent>N</Accent> inside <Note>)
275-
_ACCENT_STACCATO = 0x01
276-
_ACCENT_HEAVY = 0x04
277-
_ACCENT_NORMAL = 0x08
278-
_ACCENT_TENUTO = 0x10
274+
_ACCENT_STACCATO = 0x01
275+
_ACCENT_HEAVY = 0x04
276+
_ACCENT_NORMAL = 0x08
277+
_ACCENT_TENUTO = 0x10
279278

280279
# Slide flag bits (<Property name="Slide">/<Flags>)
281-
_SLIDE_SHIFT = 0x01
282-
_SLIDE_LEGATO = 0x02
283-
_SLIDE_OUT_DOWN = 0x04
284-
_SLIDE_OUT_UP = 0x08
285-
_SLIDE_IN_FROM_BELOW = 0x10
286-
_SLIDE_IN_FROM_ABOVE = 0x20
287-
_SLIDE_PICK_DOWN = 0x40
288-
_SLIDE_PICK_UP = 0x80
280+
_SLIDE_SHIFT = 0x01
281+
_SLIDE_LEGATO = 0x02
282+
_SLIDE_OUT_DOWN = 0x04
283+
_SLIDE_OUT_UP = 0x08
284+
_SLIDE_IN_FROM_BELOW = 0x10
285+
_SLIDE_IN_FROM_ABOVE = 0x20
286+
_SLIDE_PICK_DOWN = 0x40
287+
_SLIDE_PICK_UP = 0x80
289288
# 0x40/0x80 = pick slides (no direct PyGuitarPro mapping)
290289

291290
# GP6 percussion mapping: (element, variation) → MIDI articulation number.
@@ -326,6 +325,7 @@ def _gp6_percussion_articulation(element: int, variation: int) -> int:
326325
return row[variation]
327326
return 38 # default: Snare (hit)
328327

328+
329329
# GPIF Target → PyGuitarPro direction-sign names (Coda/Segno/Fine "destinations")
330330
_DIRECTION_TARGETS = {
331331
"Coda": "Coda",
@@ -1233,7 +1233,8 @@ def _fill_chord_degrees(chord: gp.Chord, chord_info: ET.Element) -> None:
12331233
from <Chord>/<KeyNote>/<BassNote>/<Degree> GPIF structure."""
12341234
# Root and bass note
12351235
step_map = {"C": 0, "D": 2, "E": 4, "F": 5, "G": 7, "A": 9, "B": 11}
1236-
def make_pitch(node: Optional[ET.Element]) -> Optional[gp.PitchClass]:
1236+
1237+
def make_pitch(node: ET.Element | None) -> gp.PitchClass | None:
12371238
if node is None:
12381239
return None
12391240
step = node.get("step", "")
@@ -1493,8 +1494,6 @@ def _build_lookup_tables(self, root: ET.Element) -> None:
14931494

14941495
def _read_master_bars(self, song: gp.Song) -> None:
14951496
"""Build `song.measureHeaders` from <MasterBars>/<MasterBar>."""
1496-
# Cache nodes for later per-track walk.
1497-
root_doc = None
14981497
for mb in self._iter_master_bars(song):
14991498
pass # no-op; iteration finalises the list
15001499
# alphaTab's _buildModel clears hasDoubleBar on the last master
@@ -1521,7 +1520,7 @@ def _iter_master_bars(self, song: gp.Song):
15211520
previous_header = header
15221521
yield mb
15231522

1524-
def _root_from_song(self, song: gp.Song) -> Optional[ET.Element]:
1523+
def _root_from_song(self, song: gp.Song) -> ET.Element | None:
15251524
"""The reader kept the root element alive via closure — we need it
15261525
for master-bar/bar walks. Stash it on the instance instead."""
15271526
return getattr(self, "_root", None)
@@ -1779,7 +1778,7 @@ def _assemble_tracks(self, song: gp.Song) -> None:
17791778
measure = self._build_measure(track, header, bar_id)
17801779
track.measures.append(measure)
17811780

1782-
def _build_measure(self, track: gp.Track, header: gp.MeasureHeader, bar_id: Optional[str]) -> gp.Measure:
1781+
def _build_measure(self, track: gp.Track, header: gp.MeasureHeader, bar_id: str | None) -> gp.Measure:
17831782
measure = gp.Measure(track=track, header=header)
17841783
measure.voices = []
17851784

@@ -1934,7 +1933,7 @@ def _build_beat(self, voice: gp.Voice, beat_id: str) -> gp.Beat:
19341933

19351934
return beat
19361935

1937-
def _build_note(self, beat: gp.Beat, note_id: str, velocity: int) -> Optional[gp.Note]:
1936+
def _build_note(self, beat: gp.Beat, note_id: str, velocity: int) -> gp.Note | None:
19381937
raw = self._notes_raw.get(note_id)
19391938
if raw is None:
19401939
return None

src/guitarpro/gpx.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from __future__ import annotations
1616

1717
from dataclasses import dataclass
18-
from typing import Callable, Optional
18+
from typing import Callable
1919

2020

2121
class EndOfReader(Exception):
@@ -140,7 +140,7 @@ def write(self, source: bytes, offset: int, count: int) -> None:
140140
start = max(0, offset)
141141
actual = max(0, min(count, len(source) - start))
142142
if actual > 0:
143-
self._buf.extend(source[start : start + actual])
143+
self._buf.extend(source[start:start + actual])
144144
pad = count - actual
145145
if pad > 0:
146146
self._buf.extend(b"\x00" * pad)
@@ -157,7 +157,7 @@ class GpxFile:
157157

158158
file_name: str = ""
159159
file_size: int = 0
160-
data: Optional[bytes] = None
160+
data: bytes | None = None
161161

162162

163163
class GpxFileSystem:
@@ -216,7 +216,7 @@ def decompress(self, src: _BitReader, skip_header: bool = False) -> bytes:
216216
buffer = uncompressed.get_buffer()
217217
result_offset = 4 if skip_header else 0
218218
result_size = uncompressed.length - result_offset
219-
return bytes(buffer[result_offset : result_offset + result_size])
219+
return bytes(buffer[result_offset:result_offset + result_size])
220220

221221
def _read_block(self, data: _BitReader) -> None:
222222
header = self.read_header(data)

0 commit comments

Comments
 (0)