Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Below are the noteworthy changes from each release.
A more detailed list of changes is available in the corresponding milestones for each release in the Github issue tracker (https://github.com/googlefonts/fontbakery/milestones?state=closed).

## Upcoming release: 1.1.0 (2025-Jul-??)
- Replace deprecated `pkg_resources` by `importlib.resources` (issue #5028)
- ...


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,10 +307,10 @@ def rfn_exception(font):
been published previously with an RFN, or fonts which benefit from
an agreement with Google Fonts.
"""
from pkg_resources import resource_filename
from fontbakery.utils import get_resource_file_path

rfn_exceptions_txt = "data/googlefonts/reserved_font_name_exceptions.txt"
filename = resource_filename("fontbakery", rfn_exceptions_txt)
filename = get_resource_file_path(rfn_exceptions_txt)
for exception in open(filename, "r", encoding="utf-8").readlines():
exception = exception.split("#")[0].strip()
exception = exception.replace(" ", "")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
def check_family_name_compliance(ttFont):
"""Check family name for GF Guide compliance."""
import re
from pkg_resources import resource_filename
from fontbakery.utils import get_name_entries

from fontbakery.utils import get_name_entries, get_resource_file_path

camelcase_exceptions_txt = "data/googlefonts/camelcased_familyname_exceptions.txt"
abbreviations_exceptions_txt = (
Expand All @@ -45,7 +45,7 @@ def check_family_name_compliance(ttFont):
known_exception = False

# Process exceptions
filename = resource_filename("fontbakery", camelcase_exceptions_txt)
filename = get_resource_file_path(camelcase_exceptions_txt)
for exception in open(filename, "r", encoding="utf-8").readlines():
exception = exception.split("#")[0].strip()
if exception == "":
Expand All @@ -71,7 +71,7 @@ def check_family_name_compliance(ttFont):
known_exception = False

# Process exceptions
filename = resource_filename("fontbakery", abbreviations_exceptions_txt)
filename = get_resource_file_path(abbreviations_exceptions_txt)
for exception in open(filename, "r", encoding="utf-8").readlines():
exception = exception.split("#")[0].strip()
if exception == "":
Expand Down
7 changes: 2 additions & 5 deletions Lib/fontbakery/checks/vendorspecific/googlefonts/utils.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import re
from functools import lru_cache
from pkg_resources import resource_filename

from fontbakery.utils import exit_with_install_instructions
from fontbakery.utils import exit_with_install_instructions, get_resource_file_path


@lru_cache(maxsize=1)
Expand All @@ -22,9 +21,7 @@ def registered_vendor_ids():
exit_with_install_instructions("googlefonts")

registered_vendor_ids = {}
CACHED = resource_filename(
"fontbakery", "data/fontbakery-microsoft-vendorlist.cache"
)
CACHED = get_resource_file_path("data/fontbakery-microsoft-vendorlist.cache")
content = open(CACHED, encoding="utf-8").read()
# Strip all <A> HTML tags from the raw HTML. The current page contains a
# closing </A> for which no opening <A> is present, which causes
Expand Down
25 changes: 24 additions & 1 deletion Lib/fontbakery/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
from __future__ import annotations

import os
import subprocess
import sys
import traceback
from typing import Optional
from copy import deepcopy
from typing import TYPE_CHECKING, Optional

from fontTools.pens.basePen import BasePen
from fontTools.ttLib import TTFont
Expand All @@ -31,6 +33,27 @@
PANOSE_Family_Type,
)

if TYPE_CHECKING:
from pathlib import Path


def get_resource_file_path(sub_file_path: str) -> Path:
"""Return the full file path of a resource file inside the fontbakery
directory.

Args:
sub_file_path (str): The file path relative to the `fontbakery`
directory.

Returns:
Path: The full file path
"""
from importlib.resources import as_file, files

with as_file(files("fontbakery").joinpath(sub_file_path)) as path:
file_path = path
return file_path
Comment on lines +51 to +55
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically this is not correct, it will only work when fontbakery is loaded from a filesystem directory (e.g. when installed with pip). It's possible to import python modules from zip files as well, or tools can be used to embded them in a self-contained exe. To support use cases like this you should do what @m4rc1e did in

googlefonts/gftools#1131

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://docs.python.org/3/library/importlib.resources.html#importlib.resources.as_file

Exiting the context manager cleans up any temporary file or directory created when the resource was extracted from e.g. a zip file.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you want the temporary resource path to persist until python exits, you can do what Marc did in gftools tests/test_items.py in the PR above, i.e. use contextlib.ExitStack + atexit

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! I've updated the PR in #5045. I now return the file contents from the helper function, so no temporary files need to stick around.



def exit_with_install_instructions(profile_name):
sys.exit(
Expand Down
4 changes: 0 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,6 @@ exclude = [
minversion = "6.0"
testpaths = ["tests"]
addopts = "--color=yes --verbose"
filterwarnings = [
"ignore:pkg_resources is deprecated as an API:DeprecationWarning",
"ignore:Deprecated call to `pkg_resources.declare_namespace:DeprecationWarning",
]

# ============================================================================
[tool.pylint.master]
Expand Down