1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
"""
fontlift — cross-platform font install/uninstall/list/cleanup for Python.
The heavy lifting is done by the Rust core compiled into `fontlift._native`
(a PyO3 extension). This module re-exports the public API and provides pure-
Python fallbacks so the package imports cleanly even when the native extension
is not built yet.
Platform mechanics (invisible to callers):
- macOS: copies the file to ~/Library/Fonts (user) or /Library/Fonts (system),
then calls CTFontManagerRegisterFontsForURL. Core Text notifies running apps
immediately — no reboot needed.
- Windows: copies to %LOCALAPPDATA%\\Microsoft\\Windows\\Fonts (user) or
C:\\Windows\\Fonts (system), writes a registry entry under
HKCU/HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts,
and broadcasts WM_FONTCHANGE via GDI so running apps see the change.
Scope terminology:
- "user" (default): font is visible to the current account only. No admin needed.
- "system": font is visible to all users. Requires sudo / Administrator rights.
Font name fields (on FontFaceInfo / dict output):
- postscript_name: stable programmatic ID used by apps (e.g. "HelveticaNeue-Bold")
- full_name: menu-friendly name (e.g. "Helvetica Neue Bold")
- family_name: groups all weights/styles (e.g. "Helvetica Neue")
- style: variant within the family (e.g. "Bold", "Italic")
"""
=
# pragma: no cover - exercised via importorskip
= None
=
= None
= # re-export
=
= # exposed for structured metadata
# pragma: no cover - importorskip handles runtime use without native module
= = = None
"""Normalise native FontFaceInfo objects into plain dictionaries."""
return
=
return
=
=
return
"""Return all fonts the OS currently knows about, one dict per face.
A collection file (.ttc / .otc) produces multiple entries — one per face
inside the file. Results are not limited to fonts installed by fontlift.
Each dict has these keys:
path – absolute path to the font file
postscript_name – stable programmatic name (e.g. "Arial-BoldMT")
full_name – menu display name (e.g. "Arial Bold")
family_name – family group (e.g. "Arial")
style – variant within the family (e.g. "Bold")
weight – numeric weight 100–900 (None if unknown)
italic – True/False (None if unknown)
format – file format string (e.g. "TTF", "OTF") or None
scope – "user" or "system"
source – nested dict with the above source-level fields
"""
return
= # alias for CLI parity
"""Install a font file so applications can use it.
Copies the file to the OS font directory for the chosen scope and
registers it with the OS font manager (Core Text on macOS, GDI +
Registry on Windows). The font is available to all running applications
immediately after this call — no reboot required.
Args:
font_path: Absolute or relative path to a .ttf, .otf, .ttc, .otc,
.woff, or .woff2 file.
admin: If True, install system-wide (all users). Requires sudo on
macOS or Administrator on Windows. Defaults to user scope.
dry_run: If True, return immediately without changing anything.
Raises:
RuntimeError: if the file does not exist, is not a valid font, the
process lacks the required privileges, or the OS
registration call fails.
"""
return
"""Remove a font's OS registration while keeping the file on disk.
Pass exactly one of ``font_path`` or ``name``. Name matching checks both
PostScript name and full name (case-sensitive).
fontlift tries the preferred scope first, then falls back to the other
scope if the first attempt fails — useful when you're not certain whether
a font was installed at user or system level.
Args:
font_path: Path to the font file to uninstall.
name: PostScript name or full name of the font to uninstall.
admin: Prefer system scope first. Without this flag user scope
is tried first.
dry_run: If True, resolve the target without changing anything.
Raises:
RuntimeError: if neither identifier is provided, both are provided,
the font is not found, or the OS call fails.
"""
"""Unregister a font and delete its file from disk.
This is the destructive counterpart to :func:`uninstall`. If
deregistration fails, fontlift still attempts to delete the file so the
font is fully gone. Use ``dry_run=True`` first to confirm what will be
deleted.
Args:
font_path: Path to the font file to remove.
name: PostScript name or full name of the font to remove.
admin: Prefer system scope first.
dry_run: If True, resolve the target without deleting anything.
Raises:
RuntimeError: same conditions as :func:`uninstall`, plus IO errors
when deleting the file.
"""
"""Prune stale font registrations and/or clear OS font caches.
Stale registrations point to files that no longer exist — they can
accumulate when fonts are deleted without going through fontlift. Cache
clearing asks the OS and common applications (Adobe, Microsoft Office) to
discard their cached font data so they see the current font set.
At least one of ``prune`` or ``cache`` must be True.
Args:
admin: Operate on system-wide registrations and caches. Requires
sudo / Administrator rights.
prune: Remove registrations whose backing files are missing.
cache: Clear OS font caches (Core Text on macOS, FontCache service
on Windows) and third-party app caches where supported.
dry_run: If True, return immediately without changing anything.
Raises:
RuntimeError: if both ``prune`` and ``cache`` are False, or if an
OS cache operation fails.
"""
=
# Maturin exposes __version__ from the Cargo crate metadata; keep a fallback so
# importorskip consumers degrade gracefully when the native module is missing.
=
=