Skip to content
14 changes: 14 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,20 @@ jobs:
pip install virtualenv nox
nox -f noxfile.py -s type_check

compatibility-3-13:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y libjpeg-dev
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
- run: |
pip install virtualenv nox
nox -f noxfile.py -s compatibility

compatibility-3-12:
runs-on: ubuntu-latest
steps:
Expand Down
27 changes: 16 additions & 11 deletions build_golden_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import json
import os
import os.path
import pkg_resources
import importlib.resources

import pybadges
from tests import image_server
Expand Down Expand Up @@ -46,17 +46,22 @@ def main():
parser = argparse.ArgumentParser(
description='generate a github-style badge given some text and colors')

parser.add_argument(
'--source-path',
default=pkg_resources.resource_filename(__name__,
'tests/test-badges.json'),
help='the text to show on the left-hand-side of the badge')
with importlib.resources.as_file(
importlib.resources.files('tests') /
'test-badges.json') as test_badges_path:
parser.add_argument(
'--source-path',
default=str(test_badges_path),
help='the text to show on the left-hand-side of the badge')

with importlib.resources.as_file(
importlib.resources.files('tests') /
'golden-images') as golden_images_path:
parser.add_argument(
'--destination-dir',
default=str(golden_images_path),
help='the text to show on the left-hand-side of the badge')

parser.add_argument(
'--destination-dir',
default=pkg_resources.resource_filename(__name__,
'tests/golden-images'),
help='the text to show on the left-hand-side of the badge')
args = parser.parse_args()
generate_images(args.source_path, args.destination_dir)

Expand Down
2 changes: 1 addition & 1 deletion noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def unit(session):
'install',
[
'Jinja2==3.0.0',
'Pillow==8.3.2', # Oldest version that supports Python 3.7 to 3.10.
'Pillow==11.2.1',
Comment thread
shenxianpeng marked this conversation as resolved.
Outdated
'requests>=2.25.0,<3.0.0',
'urllib3>=1.25.0,<2.0.0', # urllib3 2.0.0+ requires Python 3.8+
'xmldiff==2.4'
Expand Down
5 changes: 3 additions & 2 deletions pybadges/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@
"""

import base64
import imghdr
import mimetypes
from typing import Optional
import urllib.parse
from xml.dom import minidom

import filetype
import jinja2
import requests

Expand Down Expand Up @@ -102,7 +102,8 @@ def _embed_image(url: str) -> str:
else:
with open(url, 'rb') as f:
image_data = f.read()
image_type = imghdr.what(None, image_data)
kind = filetype.guess(image_data)
image_type = kind.extension if kind is not None else None
if not image_type:
mime_type, _ = mimetypes.guess_type(url, strict=False)
if not mime_type:
Expand Down
37 changes: 21 additions & 16 deletions pybadges/precalculated_text_measurer.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@

import io
import json
import pkg_resources
import importlib.resources
import lzma
from typing import cast, Mapping, TextIO, Type

from pybadges import text_measurer
Expand Down Expand Up @@ -74,19 +75,23 @@ def default(cls) -> 'PrecalculatedTextMeasurer':
if cls._default_cache is not None:
return cls._default_cache

if pkg_resources.resource_exists(__name__, 'default-widths.json.xz'):
import lzma
with pkg_resources.resource_stream(__name__,
'default-widths.json.xz') as f:
with lzma.open(f, "rt") as g:
cls._default_cache = PrecalculatedTextMeasurer.from_json(
cast(TextIO, g))
try:
if importlib.resources.is_resource(__package__,
'default-widths.json.xz'):
with importlib.resources.open_binary(
__package__, 'default-widths.json.xz') as f:
with lzma.open(f, "rt") as g:
cls._default_cache = PrecalculatedTextMeasurer.from_json(
cast(TextIO, g))
return cls._default_cache
elif importlib.resources.is_resource(__package__,
'default-widths.json'):
with importlib.resources.open_text(__package__,
'default-widths.json',
encoding='utf-8') as f:
cls._default_cache = PrecalculatedTextMeasurer.from_json(f)
return cls._default_cache
elif pkg_resources.resource_exists(__name__, 'default-widths.json'):
with pkg_resources.resource_stream(__name__,
'default-widths.json') as f:
cls._default_cache = PrecalculatedTextMeasurer.from_json(
io.TextIOWrapper(f, encoding='utf-8'))
return cls._default_cache
else:
raise ValueError('could not load default-widths.json')
else:
raise ValueError('could not load default-widths.json')
except Exception as e:
Comment thread
shenxianpeng marked this conversation as resolved.
raise ValueError(f'Error loading default-widths.json: {e}')
9 changes: 3 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,11 @@ def replace_relative_with_absolute(match):
'Intended Audience :: Developers',
'Intended Audience :: Developers',
'License :: OSI Approved :: Apache Software License',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
'Programming Language :: Python :: 3.13',
'Operating System :: OS Independent',
],
description='A library and command-line tool for generating Github-style ' +
Expand All @@ -67,8 +64,8 @@ def replace_relative_with_absolute(match):
},
long_description=get_long_description(),
long_description_content_type='text/markdown',
python_requires='>=3.4',
install_requires=['Jinja2>=3,<4', 'requests>=2.22.0,<3'],
python_requires='>=3.9',
install_requires=['Jinja2>=3,<4', 'requests>=2.22.0,<3', 'filetype'],
Comment thread
shenxianpeng marked this conversation as resolved.
Outdated
extras_require={
'pil-measurement': ['Pillow>=6,<10'],
'dev': [
Expand Down