Skip to main content

The most up-to-date version of this README is on GitHub.

pygal-stubs

What is this?

  • pygal-stubs is a package that provides external type stubs (PEP 561) for pygal.
  • Install it to get static analyisis, type-checking and autocompletion in your favorite IDE, so that you no longer have to pollute your "strict" codebase with # pyright: ignore[reportUnknownMemberType]. Be sure to read Usage as well.

What this isn't

  • This package is not affiliated with pygal.
  • It is almost certainly not perfect or 100% accurate. If you spot a mistake (any mistake) and know how to fix it, submit a PR; If you don't, open an issue.
  • (Per the LICENSE, this package comes with no warranty whatsoever, however there is one thing we know for a fact will not work at all) This package is not suitable for contributing to pygal itself. If you try to open pygal's source with pygal-stubs installed and your type checker on "strict", you will almost certainly get type-checking errors and could potentially be misled as to the real types of the objects you're dealing with.
    • This package is aimed at the end users of pygal and as such reflects the types that appear in the public API, which might differ from implementation details.
  • These stubs are not intended for use with any particular type checker, however, they were written while using basedpyright and were tested more thoroughly with it than with any other type checker. As such, it is this package's primary target type checker (it's extremely similar to Pylance so vanilla VS Code users should have no issues). If you have a specific issue with another type checker, please submit a PR or open an issue.
  • (obviously) This isn't replacement for pygal's documentation, which should always be considered the source of truth when using pygal.

Installation

pygal-stubs is available on PyPI. Install it with pip install pygal-stubs, uv add pygal-stubs, or however you usually install PyPI packages.

This will also install the following type dependencies automatically:

  • typing-extensions: Backports modern typing features to all supported Python versions.
  • types-lxml & django-types: Stubs for pygal's optional dependencies to prevent Any / Unknown from leaking into your codebase.
    • You might still get Unknown from other pygal dependencies that don't have type stubs available such as cairosvg and pyquery, as well as the map modules (see below).

Note that this package only installs the type stubs, not the optional runtime libraries themselves. If your code uses pygal features that rely on lxml or django, ensure you install those packages separately to avoid runtime ImportErrors.

This package does not include stubs for the separately packaged map modules. You'll need to download those separately. I have created type stubs for my active fork of the world map module. You can find them here: fork, stubs. 1

Usage

Reading and writing Graph attributes

If you already use a strict type checker, existing pygal code will continue to work. However, there is one key detail you must know: Graph attributes (used to configure graphs) are set dynamically at runtime via __setattr__, not defined explicitly on __init__. This means that if you try to access a Graph attribute you haven't set explicitly, you'll get an AttributeError at runtime that type checkers (and these stubs) have no way of knowing about.

For example:

line = pygal.Line()
title = line.title
# Your type checker will say this is str | None,
# when in reality this line will cause an AttributeError!

This isn't an issue if you never read these attributes.

We have also added the more popular (the ones found in the docs + a couple of others) attributes to the __init__ method stubs, so you can assign them directly at instantiation:

import pygal

# Instead of:
line = pygal.Line()
line.title = "My Title"

# or:
config = pygal.Config()
config.title = "My Title"
line = pygal.Line(config)

# You can do:
line = pygal.Line(title="My Title")

Values that aren't in the __init__ signature will be assigned just fine, but they won't be type checked as you'll be falling back to the untyped **kwargs. If you believe that more attributes should be added to an __init__ method signature, please submit a PR. This paragraph also applies to some other methods (e.g. add)

Note that some values passed via constructor kwargs (including the ones typed by these stubs) and Config instances might not actually be assigned until the graph is rendered, so if you must read a value, your safest option is to assign it directly: line.title = "My Title" and, as mentioned above, always use a try-except block to handle potential AttributeErrors.

Why is this?

pygal does not define which attributes each specific Graph type requires, instead providing all attributes, for all graphs, in the massive CommonConfig and Config classes for documentation purposes. Then, at runtime, all attributes are assigned arbitrarily (via __setattr__ from either explicit instance.attr = val asignment from the user or at instantiation time from the constructor **kwargs) to the graph instances.

This means that if we wanted type-checking for these values (instead of accepting anything for any key like __setattr__ normally does), we had to basically hardcode all config attributes for all graphs as properties of BaseGraph, the class that all graphs inherit from. If you know a better way to do this without erasing type checking for these attributes, please submit a PR

Graphs are now generic

Graph, the base class that all pygal graphs inherit from directly or indirectly, is now generic in ValueT, XLabelT, and YLabelT (with defaults Iterable[float], str and str respectively). For most usages this information is not relevant (the values you try to add will be checked for satisfaction of your specific chart class' _ValueT), but this pattern could cause unexpected behaviour in code that can deal with multiple graph types.

For example, say that you want to create a function that takes any pygal graph and renders it in the browser. Since all pygal graphs inherit from Graph, you might think of hinting it like this:

import pygal


def render_any_graph(g: pygal.Graph) -> None:
    g.render_in_browser()

But this is wrong. If you try to pass a graph instance whose values and labels types aren't exactly the same as Graph's defaults (see above), you will get a type checking error. An instance of Pie, for example, defines its _ValueT as Sequence[float] | float, which is not Iterable[float] and will therefore be rejected by the type checker.

Your options for typing code that needs to accept multiple graph types are:

  1. Narrow down the accepted types to only the graphs you need to handle, e.g.
def render_bar_or_line(g: pygal.Bar | pygal.Line) -> None:
    g.render_in_browser()
  1. If you truly need to accept all pygal graphs, you can use AnyGraph, a type alias (union of Graph and all its subclasses provided by pygal-stubs for convenience, but does not exist at runtime) to represent all graph types:
from pygal import AnyGraph


def render_any_graph(g: AnyGraph) -> None:
    g.render_in_browser()

Versioning

{pygal major}.{pygal minor}.{pygal patch}.{stubs revision (incremental)}

For example, the current version number 3.1.3.4 should be interpreted as "the fourth revision of the stubs for pygal version 3.1.3"

  1. I cannot currently work on stubs for other map modules (both the documented France and Switzerland maps nor the various non-Kozea ones you can find on PyPI). If you want to make your own type stubs for those, you're more than welcome to do so using pygal-stubs and my world map stubs as a base. If you'd like those stubs to be compatible with pygal-stubs and a mistake in the definition of BaseMap is causing problems, please submit a PR. Once you're done making your type stubs, make an issue so I can add your wonderful contribution to this README for all pygal-stubs users to see. ↩

Metadata

Release files for pygal-stubs 3.1.3.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pygal-stubs 3.1.3.4
File Size Uploaded
pygal_stubs-3.1.3.4.tar.gz 18.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pygal-stubs 3.1.3.4
File Interpreter ABI Platform
pygal_stubs-3.1.3.4-py3-none-any.whl Python 3 none any Details

Total release size: 53.8 kB

Release files / pygal_stubs-3.1.3.4.tar.gz

Download URL pygal_stubs-3.1.3.4.tar.gz
Size 18.0 kB
Tags Source
SHA-256 checksum
How to use checksums
3f586444c2704d8e79078fd2c5ba48370088a53469424783a9e548d25373f2f4
BLAKE2b-256 checksum
How to use checksums
faee1b860f454477a7958a0219e50bccf2b192f75059b3ccdc7408680af15377
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22.3","id":"zena","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / pygal_stubs-3.1.3.4-py3-none-any.whl

Download URL pygal_stubs-3.1.3.4-py3-none-any.whl
Size 35.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6392fe45811b03f5f99915a3a2a90b10a052ff3f45949187ab5b5b5aff87507f
BLAKE2b-256 checksum
How to use checksums
ab72774b4c1cf858e16f788bccc4107efee247ab18b0133ab678bd7b9a2166f3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22.3","id":"zena","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

3.1.3.4 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page