| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1611,10 +1611,10 @@ def get_font(font_filepaths, hinting_factor=None): | |||
| 1611 | 1611 | ||
| 1612 | 1612 | Parameters | |
| 1613 | 1613 | ---------- | |
| 1614 | - font_filepaths : Iterable[str, Path, bytes], str, Path, bytes | ||
| 1614 | + font_filepaths : Iterable[str, bytes, os.PathLike], str, bytes, os.PathLike | ||
| 1615 | 1615 | Relative or absolute paths to the font files to be used. | |
| 1616 | 1616 | ||
| 1617 | - If a single string, bytes, or `pathlib.Path`, then it will be treated | ||
| 1617 | + If a single string, bytes, or `os.PathLike`, then it will be treated | ||
| 1618 | 1618 | as a list with that entry only. | |
| 1619 | 1619 | ||
| 1620 | 1620 | If more than one filepath is passed, then the returned FT2Font object | |
@@ -1626,7 +1626,7 @@ def get_font(font_filepaths, hinting_factor=None): | |||
| 1626 | 1626 | `.ft2font.FT2Font` | |
| 1627 | 1627 | ||
| 1628 | 1628 | """ | |
| 1629 | - if isinstance(font_filepaths, (str, Path, bytes)): | ||
| 1629 | + if isinstance(font_filepaths, (str, bytes, os.PathLike)): | ||
| 1630 | 1630 | paths = (_cached_realpath(font_filepaths),) | |
| 1631 | 1631 | else: | |
| 1632 | 1632 | paths = tuple(_cached_realpath(fname) for fname in font_filepaths) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,7 +24,7 @@ def list_fonts(directory: str, extensions: Iterable[str]) -> list[str]: ... | |||
| 24 | 24 | def win32FontDirectory() -> str: ... | |
| 25 | 25 | def _get_fontconfig_fonts() -> list[Path]: ... | |
| 26 | 26 | def findSystemFonts( | |
| 27 | - fontpaths: Iterable[str | os.PathLike | Path] | None = ..., fontext: str = ... | ||
| 27 | + fontpaths: Iterable[str | os.PathLike] | None = ..., fontext: str = ... | ||
| 28 | 28 | ) -> list[str]: ... | |
| 29 | 29 | @dataclass | |
| 30 | 30 | class FontEntry: | |
@@ -50,7 +50,7 @@ class FontProperties: | |||
| 50 | 50 | weight: int | str | None = ..., | |
| 51 | 51 | stretch: int | str | None = ..., | |
| 52 | 52 | size: float | str | None = ..., | |
| 53 | - fname: str | os.PathLike | Path | None = ..., | ||
| 53 | + fname: str | os.PathLike | None = ..., | ||
| 54 | 54 | math_fontfamily: str | None = ..., | |
| 55 | 55 | ) -> None: ... | |
| 56 | 56 | def __hash__(self) -> int: ... | |
@@ -72,7 +72,7 @@ class FontProperties: | |||
| 72 | 72 | def set_weight(self, weight: int | str | None) -> None: ... | |
| 73 | 73 | def set_stretch(self, stretch: int | str | None) -> None: ... | |
| 74 | 74 | def set_size(self, size: float | str | None) -> None: ... | |
| 75 | - def set_file(self, file: str | os.PathLike | Path | None) -> None: ... | ||
| 75 | + def set_file(self, file: str | os.PathLike | None) -> None: ... | ||
| 76 | 76 | def set_fontconfig_pattern(self, pattern: str) -> None: ... | |
| 77 | 77 | def get_math_fontfamily(self) -> str: ... | |
| 78 | 78 | def set_math_fontfamily(self, fontfamily: str | None) -> None: ... | |
@@ -83,8 +83,8 @@ class FontProperties: | |||
| 83 | 83 | set_slant = set_style | |
| 84 | 84 | get_size_in_points = get_size | |
| 85 | 85 | ||
| 86 | - def json_dump(data: FontManager, filename: str | Path | os.PathLike) -> None: ... | ||
| 87 | - def json_load(filename: str | Path | os.PathLike) -> FontManager: ... | ||
| 86 | + def json_dump(data: FontManager, filename: str | os.PathLike) -> None: ... | ||
| 87 | + def json_load(filename: str | os.PathLike) -> FontManager: ... | ||
| 88 | 88 | ||
| 89 | 89 | class FontManager: | |
| 90 | 90 | __version__: str | |
@@ -93,7 +93,7 @@ class FontManager: | |||
| 93 | 93 | afmlist: list[FontEntry] | |
| 94 | 94 | ttflist: list[FontEntry] | |
| 95 | 95 | def __init__(self, size: float | None = ..., weight: str = ...) -> None: ... | |
| 96 | - def addfont(self, path: str | Path | os.PathLike) -> None: ... | ||
| 96 | + def addfont(self, path: str | os.PathLike) -> None: ... | ||
| 97 | 97 | @property | |
| 98 | 98 | def defaultFont(self) -> dict[str, str]: ... | |
| 99 | 99 | def get_default_weight(self) -> str: ... | |
@@ -120,7 +120,7 @@ class FontManager: | |||
| 120 | 120 | ||
| 121 | 121 | def is_opentype_cff_font(filename: str) -> bool: ... | |
| 122 | 122 | def get_font( | |
| 123 | - font_filepaths: Iterable[str | Path | bytes] | str | Path | bytes, | ||
| 123 | + font_filepaths: Iterable[str | bytes | os.PathLike] | str | bytes | os.PathLike, | ||
| 124 | 124 | hinting_factor: int | None = ..., | |
| 125 | 125 | ) -> ft2font.FT2Font: ... | |
| 126 | 126 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,4 +1,5 @@ | |||
| 1 | 1 | from enum import Enum, Flag | |
| 2 | + from os import PathLike | ||
| 2 | 3 | import sys | |
| 3 | 4 | from typing import BinaryIO, Literal, NewType, TypeAlias, TypedDict, cast, final, overload | |
| 4 | 5 | from typing_extensions import Buffer # < Py 3.12 | |
@@ -194,7 +195,7 @@ class _SfntPcltDict(TypedDict): | |||
| 194 | 195 | class FT2Font(Buffer): | |
| 195 | 196 | def __init__( | |
| 196 | 197 | self, | |
| 197 | - filename: str | BinaryIO, | ||
| 198 | + filename: str | bytes | PathLike | BinaryIO, | ||
| 198 | 199 | hinting_factor: int = ..., | |
| 199 | 200 | *, | |
| 200 | 201 | _fallback_list: list[FT2Font] | None = ..., | |
@@ -261,7 +262,7 @@ class FT2Font(Buffer): | |||
| 261 | 262 | @property | |
| 262 | 263 | def family_name(self) -> str: ... | |
| 263 | 264 | @property | |
| 264 | - def fname(self) -> str: ... | ||
| 265 | + def fname(self) -> str | bytes: ... | ||
| 265 | 266 | @property | |
| 266 | 267 | def height(self) -> int: ... | |
| 267 | 268 | @property | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,4 +1,4 @@ | |||
| 1 | - from io import BytesIO, StringIO | ||
| 1 | + from io import BytesIO | ||
| 2 | 2 | import gc | |
| 3 | 3 | import multiprocessing | |
| 4 | 4 | import os | |
@@ -137,6 +137,32 @@ def test_find_noto(): | |||
| 137 | 137 | fig.savefig(BytesIO(), format=fmt) | |
| 138 | 138 | ||
| 139 | 139 | ||
| 140 | + def test_find_valid(): | ||
| 141 | + class PathLikeClass: | ||
| 142 | + def __init__(self, filename): | ||
| 143 | + self.filename = filename | ||
| 144 | + | ||
| 145 | + def __fspath__(self): | ||
| 146 | + return self.filename | ||
| 147 | + | ||
| 148 | + file_str = findfont('DejaVu Sans') | ||
| 149 | + file_bytes = os.fsencode(file_str) | ||
| 150 | + | ||
| 151 | + font = get_font(file_str) | ||
| 152 | + assert font.fname == file_str | ||
| 153 | + font = get_font(file_bytes) | ||
| 154 | + assert font.fname == file_bytes | ||
| 155 | + font = get_font(PathLikeClass(file_str)) | ||
| 156 | + assert font.fname == file_str | ||
| 157 | + font = get_font(PathLikeClass(file_bytes)) | ||
| 158 | + assert font.fname == file_bytes | ||
| 159 | + | ||
| 160 | + # Note, fallbacks are not currently accessible. | ||
| 161 | + font = get_font([file_str, file_bytes, | ||
| 162 | + PathLikeClass(file_str), PathLikeClass(file_bytes)]) | ||
| 163 | + assert font.fname == file_str | ||
| 164 | + | ||
| 165 | + | ||
| 140 | 166 | def test_find_invalid(tmp_path): | |
| 141 | 167 | ||
| 142 | 168 | with pytest.raises(FileNotFoundError): | |
@@ -148,11 +174,6 @@ def test_find_invalid(tmp_path): | |||
| 148 | 174 | with pytest.raises(FileNotFoundError): | |
| 149 | 175 | get_font(bytes(tmp_path / 'non-existent-font-name.ttf')) | |
| 150 | 176 | ||
| 151 | - # Not really public, but get_font doesn't expose non-filename constructor. | ||
| 152 | - from matplotlib.ft2font import FT2Font | ||
| 153 | - with pytest.raises(TypeError, match='font file or a binary-mode file'): | ||
| 154 | - FT2Font(StringIO()) # type: ignore[arg-type] | ||
| 155 | - | ||
| 156 | 177 | ||
| 157 | 178 | @pytest.mark.skipif(sys.platform != 'linux' or not has_fclist, | |
| 158 | 179 | reason='only Linux with fontconfig installed') | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,5 +1,6 @@ | |||
| 1 | 1 | import itertools | |
| 2 | 2 | import io | |
| 3 | + import os | ||
| 3 | 4 | from pathlib import Path | |
| 4 | 5 | from typing import cast | |
| 5 | 6 | ||
@@ -134,6 +135,27 @@ def test_ft2font_stix_bold_attrs(): | |||
| 134 | 135 | assert font.bbox == (4, -355, 1185, 2095) | |
| 135 | 136 | ||
| 136 | 137 | ||
| 138 | + def test_ft2font_valid_args(): | ||
| 139 | + class PathLikeClass: | ||
| 140 | + def __init__(self, filename): | ||
| 141 | + self.filename = filename | ||
| 142 | + | ||
| 143 | + def __fspath__(self): | ||
| 144 | + return self.filename | ||
| 145 | + | ||
| 146 | + file_str = fm.findfont('DejaVu Sans') | ||
| 147 | + file_bytes = os.fsencode(file_str) | ||
| 148 | + | ||
| 149 | + font = ft2font.FT2Font(file_str) | ||
| 150 | + assert font.fname == file_str | ||
| 151 | + font = ft2font.FT2Font(file_bytes) | ||
| 152 | + assert font.fname == file_bytes | ||
| 153 | + font = ft2font.FT2Font(PathLikeClass(file_str)) | ||
| 154 | + assert font.fname == file_str | ||
| 155 | + font = ft2font.FT2Font(PathLikeClass(file_bytes)) | ||
| 156 | + assert font.fname == file_bytes | ||
| 157 | + | ||
| 158 | + | ||
| 137 | 159 | def test_ft2font_invalid_args(tmp_path): | |
| 138 | 160 | # filename argument. | |
| 139 | 161 | with pytest.raises(TypeError, match='to a font file or a binary-mode file object'): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -424,7 +424,7 @@ close_file_callback(FT_Stream stream) | |||
| 424 | 424 | const char *PyFT2Font_init__doc__ = R"""( | |
| 425 | 425 | Parameters | |
| 426 | 426 | ---------- | |
| 427 | - filename : str or file-like | ||
| 427 | + filename : str, bytes, os.PathLike, or io.BinaryIO | ||
| 428 | 428 | The source of the font data in a format (ttf or ttc) that FreeType can read. | |
| 429 | 429 | ||
| 430 | 430 | hinting_factor : int, optional | |
@@ -488,7 +488,10 @@ PyFT2Font_init(py::object filename, long hinting_factor = 8, | |||
| 488 | 488 | open_args.flags = FT_OPEN_STREAM; | |
| 489 | 489 | open_args.stream = &self->stream; | |
| 490 | 490 | ||
| 491 | - if (py::isinstance<py::bytes>(filename) || py::isinstance<py::str>(filename)) { | ||
| 491 | + auto PathLike = py::module_::import("os").attr("PathLike"); | ||
| 492 | + if (py::isinstance<py::bytes>(filename) || py::isinstance<py::str>(filename) || | ||
| 493 | + py::isinstance(filename, PathLike)) | ||
| 494 | + { | ||
| 492 | 495 | self->py_file = py::module_::import("io").attr("open")(filename, "rb"); | |
| 493 | 496 | self->stream.close = &close_file_callback; | |
| 494 | 497 | } else { | |
@@ -511,13 +514,13 @@ PyFT2Font_init(py::object filename, long hinting_factor = 8, | |||
| 511 | 514 | return self; | |
| 512 | 515 | } | |
| 513 | 516 | ||
| 514 | - static py::str | ||
| 517 | + static py::object | ||
| 515 | 518 | PyFT2Font_fname(PyFT2Font *self) | |
| 516 | 519 | { | |
| 517 | - if (self->stream.close) { // Called passed a filename to the constructor. | ||
| 520 | + if (self->stream.close) { // User passed a filename to the constructor. | ||
| 518 | 521 | return self->py_file.attr("name"); | |
| 519 | 522 | } else { | |
| 520 | - return py::cast<py::str>(self->py_file); | ||
| 523 | + return self->py_file; | ||
| 521 | 524 | } | |
| 522 | 525 | } | |
| 523 | 526 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments