From 6eaa366c765a363ddc8a505e7e55e2c65d9d8d40 Mon Sep 17 00:00:00 2001 From: Sai Asish Y Date: Mon, 18 May 2026 16:16:59 -0700 Subject: [PATCH] feat(url): accept path-like objects for the url parameter --- cairosvg/parser.py | 3 +++ cairosvg/surface.py | 2 +- cairosvg/test_api.py | 3 +++ cairosvg/url.py | 2 ++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/cairosvg/parser.py b/cairosvg/parser.py index 9d34c3e6..a6b7ce00 100644 --- a/cairosvg/parser.py +++ b/cairosvg/parser.py @@ -4,6 +4,7 @@ """ import gzip +import os import re from urllib.parse import urlunparse from xml.etree.ElementTree import Element @@ -345,6 +346,8 @@ def __init__(self, **kwargs): bytestring = kwargs.get('bytestring') file_obj = kwargs.get('file_obj') url = kwargs.get('url') + if isinstance(url, os.PathLike): + url = os.fspath(url) unsafe = kwargs.get('unsafe') parent = kwargs.get('parent') parent_children = kwargs.get('parent_children') diff --git a/cairosvg/surface.py b/cairosvg/surface.py index 15d6b069..ee7920f7 100644 --- a/cairosvg/surface.py +++ b/cairosvg/surface.py @@ -105,7 +105,7 @@ def convert(cls, bytestring=None, *, file_obj=None, url=None, dpi=96, :param bytestring: The SVG source as a byte-string. :param file_obj: A file-like object. - :param url: A filename. + :param url: A filename, given as a string or a path-like object. Give some options: diff --git a/cairosvg/test_api.py b/cairosvg/test_api.py index 72d55870..9f1da3f4 100644 --- a/cairosvg/test_api.py +++ b/cairosvg/test_api.py @@ -69,6 +69,9 @@ def test_api(tmp_path): assert svg2png(url=str(temp_0)) == expected_content assert svg2png(url=f'file://{temp_0}') == expected_content + # Read from a pathlib.Path + assert svg2png(url=temp_0) == expected_content + with temp_0.open('rb') as file_object: # Read from a real file object assert svg2png(file_obj=file_object) == expected_content diff --git a/cairosvg/url.py b/cairosvg/url.py index 13b079d4..658131c7 100644 --- a/cairosvg/url.py +++ b/cairosvg/url.py @@ -104,6 +104,8 @@ def parse_url(url, base=None): the "folder" part of it is prepended to the URL. """ + if isinstance(url, os.PathLike): + url = os.fspath(url) if url: match = URL.search(url) if match: