Skip to content

Commit ba1fd01

Browse files
authored
Merge pull request #964 from googlefonts/drop-py39
Drop support for Python 3.9 EOL
2 parents 99c4a40 + 7999191 commit ba1fd01

File tree

5 files changed

+50
-42
lines changed

5 files changed

+50
-42
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
if: "! contains(toJSON(github.event.commits.*.message), '[skip ci]')"
2828
strategy:
2929
matrix:
30-
python-version: ["3.9", "3.13"]
30+
python-version: ["3.10", "3.14"]
3131
platform: [ubuntu-latest, windows-latest]
3232
steps:
3333
- uses: actions/checkout@v4

Lib/ufo2ft/instantiator.py

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
from fontTools import designspaceLib, ufoLib, varLib
5555
from fontTools.ttLib.tables._n_a_m_e import NameRecord as ftNameRecord
5656
from fontTools.ttLib.tables._n_a_m_e import _makeWindowsName
57-
from ufoLib2.objects.info import NameRecord as ufoNameRecord
5857

5958
from ufo2ft.util import (
6059
_getNewGlyphFactory,
@@ -68,6 +67,9 @@
6867

6968
from ufoLib2.objects import Font, Glyph, Info
7069

70+
# Type alias for name records - can be dict (defcon) or NameRecord object (ufoLib2)
71+
NameRecordDict = Dict[str, Any]
72+
7173
logger = logging.getLogger(__name__)
7274

7375
# Use the same rounding function used by varLib to round things for the variable font
@@ -204,46 +206,53 @@ def process_rules_swaps(rules, location, glyphNames):
204206

205207

206208
def _override_name_record(
207-
openTypeNameRecords: list[ufoNameRecord],
208-
new_value: ufoNameRecord,
209-
) -> None:
210-
"""Override an existing name record in the list of OpenType name records."""
209+
openTypeNameRecords: list,
210+
new_value: NameRecordDict,
211+
) -> bool:
212+
"""Override an existing name record in the list of OpenType name records.
213+
214+
Records can be dicts (defcon) or NameRecord objects (ufoLib2). Both support
215+
dict-style read access via []. For writing, dicts use [] while NameRecord
216+
uses setattr since it's read-only for the Mapping interface.
217+
"""
211218
for record in openTypeNameRecords:
212219
if (
213-
record.platformID == new_value.platformID
214-
and record.encodingID == new_value.encodingID
215-
and record.languageID == new_value.languageID
216-
and record.nameID == new_value.nameID
220+
record["platformID"] == new_value["platformID"]
221+
and record["encodingID"] == new_value["encodingID"]
222+
and record["languageID"] == new_value["languageID"]
223+
and record["nameID"] == new_value["nameID"]
217224
):
218225
# Override existing name record
219-
record.string = new_value.string
226+
if isinstance(record, dict):
227+
record["string"] = new_value["string"]
228+
else:
229+
record.string = new_value["string"]
220230
return True
221231
return False
222232

223233

224-
def _make_ufo_name_record(
234+
def _make_name_record_dict(
225235
name_id: int,
226236
value: str,
227237
language_tag: str = "en",
228-
) -> None:
229-
"""Add a name to the list of OpenType name records, or override an existing one."""
238+
) -> NameRecordDict:
239+
"""Create a name record dict from name ID, value, and language tag."""
230240
temp_name_record: ftNameRecord = _makeWindowsName(value, name_id, language_tag)
231-
new_name_record: ufoNameRecord = ufoNameRecord(
232-
platformID=temp_name_record.platformID,
233-
encodingID=temp_name_record.platEncID,
234-
languageID=temp_name_record.langID,
235-
nameID=temp_name_record.nameID,
236-
string=value.strip(),
237-
)
238-
return new_name_record
241+
return {
242+
"platformID": temp_name_record.platformID,
243+
"encodingID": temp_name_record.platEncID,
244+
"languageID": temp_name_record.langID,
245+
"nameID": temp_name_record.nameID,
246+
"string": value.strip(),
247+
}
239248

240249

241250
def merge_public_font_info(
242251
font: Font,
243252
override_public_font_info: Dict[str, Any],
244253
instance_location: Location,
245254
) -> None:
246-
"""Merge the public.fontInfo dict into the ufoLib2.Font's info object (fontinfo.plist)."""
255+
"""Merge the public.fontInfo dict into the font's info object (fontinfo.plist)."""
247256
for key, value in override_public_font_info.items():
248257
try:
249258
if key == "openTypeNameRecords":
@@ -260,17 +269,17 @@ def merge_public_font_info(
260269

261270
# merge the existing openTypeNameRecords with the new ones
262271
for dict_name_record in value:
263-
ufo_name_record = ufoNameRecord(
264-
platformID=dict_name_record["platformID"],
265-
encodingID=dict_name_record["encodingID"],
266-
languageID=dict_name_record["languageID"],
267-
nameID=dict_name_record["nameID"],
268-
string=dict_name_record["string"].strip(),
269-
)
272+
name_record = {
273+
"platformID": dict_name_record["platformID"],
274+
"encodingID": dict_name_record["encodingID"],
275+
"languageID": dict_name_record["languageID"],
276+
"nameID": dict_name_record["nameID"],
277+
"string": dict_name_record["string"].strip(),
278+
}
270279
if not _override_name_record(
271-
font.info.openTypeNameRecords, ufo_name_record
280+
font.info.openTypeNameRecords, name_record
272281
):
273-
font.info.openTypeNameRecords.append(ufo_name_record)
282+
font.info.openTypeNameRecords.append(name_record)
274283
else:
275284
setattr(font.info, key, copy.deepcopy(value))
276285
except AttributeError:
@@ -800,7 +809,7 @@ def _generate_instance_info(
800809
if language_tag in instance.localisedFamilyName:
801810
# assume is Preferred Family Name (ID=16)
802811
mulitlingual_opentype_font_records.append(
803-
_make_ufo_name_record(
812+
_make_name_record_dict(
804813
OT_TYPOGRAPHIC_FAMILY_NAME_ID,
805814
instance.localisedFamilyName[language_tag],
806815
language_tag,
@@ -809,7 +818,7 @@ def _generate_instance_info(
809818
if language_tag in instance.localisedStyleName:
810819
# assume is Preferred Subfamily Name (ID=17)
811820
mulitlingual_opentype_font_records.append(
812-
_make_ufo_name_record(
821+
_make_name_record_dict(
813822
OT_TYPOGRAPHIC_SUBFAMILY_NAME_ID,
814823
instance.localisedStyleName[language_tag],
815824
language_tag,
@@ -818,7 +827,7 @@ def _generate_instance_info(
818827
if language_tag in instance.localisedStyleMapFamilyName:
819828
# Style Map Family Name (ID=1)
820829
mulitlingual_opentype_font_records.append(
821-
_make_ufo_name_record(
830+
_make_name_record_dict(
822831
OT_STYLE_MAP_FAMILY_NAME_ID,
823832
instance.localisedStyleMapFamilyName[language_tag],
824833
language_tag,
@@ -841,7 +850,7 @@ def _generate_instance_info(
841850
# add style name to ID=1
842851
full_family_name += " " + font.info.styleName
843852
mulitlingual_opentype_font_records.append(
844-
_make_ufo_name_record(
853+
_make_name_record_dict(
845854
OT_STYLE_MAP_FAMILY_NAME_ID,
846855
full_family_name,
847856
language_tag,
@@ -850,7 +859,7 @@ def _generate_instance_info(
850859
if language_tag in instance.localisedStyleMapStyleName:
851860
# Style Map Subfamily Name (ID=2)
852861
mulitlingual_opentype_font_records.append(
853-
_make_ufo_name_record(
862+
_make_name_record_dict(
854863
OT_STYLE_MAP_STYLE_NAME_ID,
855864
instance.localisedStyleMapStyleName[language_tag],
856865
language_tag,

pyproject.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ classifiers = [
2020
"Operating System :: OS Independent",
2121
"Programming Language :: Python",
2222
"Programming Language :: Python :: 3",
23-
"Programming Language :: Python :: 3.9",
2423
"Programming Language :: Python :: 3.10",
2524
"Programming Language :: Python :: 3.11",
2625
"Programming Language :: Python :: 3.12",
@@ -35,7 +34,7 @@ dependencies = [
3534
"booleanoperations>=0.9.0",
3635
"cffsubr>=0.3.0",
3736
"fontmath>=0.9.4",
38-
"fonttools[ufo]>=4.60.0",
37+
"fonttools[ufo]>=4.61.1",
3938
]
4039
description = "A bridge between UFOs and FontTools."
4140
dynamic = [
@@ -49,7 +48,7 @@ maintainers = [
4948
{ email = "cosimo@anthrotype.com", name = "Cosimo Lupo" },
5049
]
5150
name = "ufo2ft"
52-
requires-python = ">=3.9"
51+
requires-python = ">=3.10"
5352

5453
[project.optional-dependencies]
5554
compreffor = [

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ defcon==0.12.2
33
compreffor==0.5.6
44
booleanOperations==0.9.0
55
cffsubr==0.3.0
6-
skia-pathops==0.8.0.post2
6+
skia-pathops==0.9.1
77
fontMath==0.9.4
88

99
# alternative UFO implementation

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[tox]
2-
envlist = lint, py3{9,10,11,12,13}-cov, htmlcov
2+
envlist = lint, py3{10,11,12,13}-cov, htmlcov
33
skip_missing_interpreters = true
44

55
[testenv]

0 commit comments

Comments
 (0)