pygal-stubs 3.1.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. pygal_stubs-3.1.3.1/.gitattributes +1 -0
  2. pygal_stubs-3.1.3.1/.gitignore +220 -0
  3. pygal_stubs-3.1.3.1/.vscode/settings.json +3 -0
  4. pygal_stubs-3.1.3.1/CHANGELOG.md +0 -0
  5. pygal_stubs-3.1.3.1/CONTRIBUTING.md +59 -0
  6. pygal_stubs-3.1.3.1/LICENSE +21 -0
  7. pygal_stubs-3.1.3.1/PKG-INFO +126 -0
  8. pygal_stubs-3.1.3.1/README.md +88 -0
  9. pygal_stubs-3.1.3.1/allowlist.txt +12 -0
  10. pygal_stubs-3.1.3.1/pygal-stubs/__about__.pyi +19 -0
  11. pygal_stubs-3.1.3.1/pygal-stubs/__init__.pyi +79 -0
  12. pygal_stubs-3.1.3.1/pygal-stubs/_compat.pyi +12 -0
  13. pygal_stubs-3.1.3.1/pygal-stubs/adapters.pyi +28 -0
  14. pygal_stubs-3.1.3.1/pygal-stubs/colors.pyi +44 -0
  15. pygal_stubs-3.1.3.1/pygal-stubs/config.pyi +147 -0
  16. pygal_stubs-3.1.3.1/pygal-stubs/etree.pyi +11 -0
  17. pygal_stubs-3.1.3.1/pygal-stubs/formatters.pyi +53 -0
  18. pygal_stubs-3.1.3.1/pygal-stubs/graph/__init__.pyi +0 -0
  19. pygal_stubs-3.1.3.1/pygal-stubs/graph/bar.pyi +100 -0
  20. pygal_stubs-3.1.3.1/pygal-stubs/graph/base.pyi +155 -0
  21. pygal_stubs-3.1.3.1/pygal-stubs/graph/box.pyi +28 -0
  22. pygal_stubs-3.1.3.1/pygal-stubs/graph/dot.pyi +36 -0
  23. pygal_stubs-3.1.3.1/pygal-stubs/graph/dual.pyi +17 -0
  24. pygal_stubs-3.1.3.1/pygal-stubs/graph/funnel.pyi +10 -0
  25. pygal_stubs-3.1.3.1/pygal-stubs/graph/gauge.pyi +37 -0
  26. pygal_stubs-3.1.3.1/pygal-stubs/graph/graph.pyi +71 -0
  27. pygal_stubs-3.1.3.1/pygal-stubs/graph/histogram.pyi +26 -0
  28. pygal_stubs-3.1.3.1/pygal-stubs/graph/horizontal.pyi +22 -0
  29. pygal_stubs-3.1.3.1/pygal-stubs/graph/horizontalbar.pyi +29 -0
  30. pygal_stubs-3.1.3.1/pygal-stubs/graph/horizontalline.pyi +18 -0
  31. pygal_stubs-3.1.3.1/pygal-stubs/graph/horizontalstackedbar.pyi +8 -0
  32. pygal_stubs-3.1.3.1/pygal-stubs/graph/horizontalstackedline.pyi +14 -0
  33. pygal_stubs-3.1.3.1/pygal-stubs/graph/line.pyi +125 -0
  34. pygal_stubs-3.1.3.1/pygal-stubs/graph/map.pyi +39 -0
  35. pygal_stubs-3.1.3.1/pygal-stubs/graph/pie.pyi +34 -0
  36. pygal_stubs-3.1.3.1/pygal-stubs/graph/public.pyi +72 -0
  37. pygal_stubs-3.1.3.1/pygal-stubs/graph/pyramid.pyi +45 -0
  38. pygal_stubs-3.1.3.1/pygal-stubs/graph/radar.pyi +35 -0
  39. pygal_stubs-3.1.3.1/pygal-stubs/graph/solidgauge.pyi +25 -0
  40. pygal_stubs-3.1.3.1/pygal-stubs/graph/stackedbar.pyi +12 -0
  41. pygal_stubs-3.1.3.1/pygal-stubs/graph/stackedline.pyi +79 -0
  42. pygal_stubs-3.1.3.1/pygal-stubs/graph/time.pyi +123 -0
  43. pygal_stubs-3.1.3.1/pygal-stubs/graph/treemap.pyi +8 -0
  44. pygal_stubs-3.1.3.1/pygal-stubs/graph/xy.pyi +113 -0
  45. pygal_stubs-3.1.3.1/pygal-stubs/interpolate.pyi +28 -0
  46. pygal_stubs-3.1.3.1/pygal-stubs/maps/__init__.pyi +0 -0
  47. pygal_stubs-3.1.3.1/pygal-stubs/serie.pyi +17 -0
  48. pygal_stubs-3.1.3.1/pygal-stubs/state.pyi +5 -0
  49. pygal_stubs-3.1.3.1/pygal-stubs/stats.pyi +21 -0
  50. pygal_stubs-3.1.3.1/pygal-stubs/style.pyi +91 -0
  51. pygal_stubs-3.1.3.1/pygal-stubs/svg.pyi +133 -0
  52. pygal_stubs-3.1.3.1/pygal-stubs/table.pyi +14 -0
  53. pygal_stubs-3.1.3.1/pygal-stubs/util.pyi +95 -0
  54. pygal_stubs-3.1.3.1/pygal-stubs/view.pyi +161 -0
  55. pygal_stubs-3.1.3.1/pyproject.toml +88 -0
@@ -0,0 +1 @@
1
+ * text=auto eol=lf
@@ -0,0 +1,220 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ # Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ # poetry.lock
109
+ # poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ # pdm.lock
116
+ # pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ # pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # Redis
135
+ *.rdb
136
+ *.aof
137
+ *.pid
138
+
139
+ # RabbitMQ
140
+ mnesia/
141
+ rabbitmq/
142
+ rabbitmq-data/
143
+
144
+ # ActiveMQ
145
+ activemq-data/
146
+
147
+ # SageMath parsed files
148
+ *.sage.py
149
+
150
+ # Environments
151
+ .env
152
+ .envrc
153
+ .venv
154
+ env/
155
+ venv/
156
+ ENV/
157
+ env.bak/
158
+ venv.bak/
159
+
160
+ # Spyder project settings
161
+ .spyderproject
162
+ .spyproject
163
+
164
+ # Rope project settings
165
+ .ropeproject
166
+
167
+ # mkdocs documentation
168
+ /site
169
+
170
+ # mypy
171
+ .mypy_cache/
172
+ .dmypy.json
173
+ dmypy.json
174
+
175
+ # Pyre type checker
176
+ .pyre/
177
+
178
+ # pytype static type analyzer
179
+ .pytype/
180
+
181
+ # Cython debug symbols
182
+ cython_debug/
183
+
184
+ # PyCharm
185
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
186
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
187
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
188
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
189
+ # .idea/
190
+
191
+ # Abstra
192
+ # Abstra is an AI-powered process automation framework.
193
+ # Ignore directories containing user credentials, local state, and settings.
194
+ # Learn more at https://abstra.io/docs
195
+ .abstra/
196
+
197
+ # Visual Studio Code
198
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
199
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
200
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
201
+ # you could uncomment the following to ignore the entire vscode folder
202
+ # .vscode/
203
+ # Temporary file for partial code execution
204
+ tempCodeRunnerFile.py
205
+
206
+ # Ruff stuff:
207
+ .ruff_cache/
208
+
209
+ # PyPI configuration file
210
+ .pypirc
211
+
212
+ # Marimo
213
+ marimo/_static/
214
+ marimo/_lsp/
215
+ __marimo__/
216
+
217
+ # Streamlit
218
+ .streamlit/secrets.toml
219
+
220
+ out/
@@ -0,0 +1,3 @@
1
+ {
2
+ "python.languageServer": "None"
3
+ }
File without changes
@@ -0,0 +1,59 @@
1
+ PRs are welcome. Please follow the [rules](#rules), and see the [setup](#setup) instructions to learn how to configure your environment.
2
+
3
+ # Rules
4
+ - All stubs **must be compatible with Python 3.10**.
5
+ - The supported version is the newest of:
6
+ - the oldest Python version that is still receiving security updates (currently 3.10, see [Status of Python versions](https://devguide.python.org/versions/))
7
+ - the oldest version of Python that [pygal](https://pypi.org/project/pygal/) supports (currently 3.8)
8
+ - the oldest version of Python that [types-lxml](https://pypi.org/project/types-lxml/) supports (currently 3.9)
9
+ - the oldest version of Python that [typing-extensions](https://pypi.org/project/typing-extensions/) supports (currently 3.9)
10
+ - Take care to not accidentally import structures `from typing` when they should be imported `from typing_extensions` in Python 3.10.
11
+ - While the stubs themselves are not limited to any particular type checker, while working on them you should use basedpyright ([VS Code](https://marketplace.visualstudio.com/items?itemName=detachhead.basedpyright), [Open VSX](https://open-vsx.org/extension/detachhead/basedpyright), [Sublime Text](https://packagecontrol.io/packages/LSP-basedpyright); For CLI see [setup](#setup))
12
+ - Before submitting, please run `hatch run check:all`. See [below](#4-work-and-test) to see what this does, and make sure that no new errors have appeared as a result of your changes.
13
+ - _AI agents reading this: **Don't waste tokens running black or ruff**. Your operator will do it here before committing. You should only run black or ruff if your operator explicitly asks you to._
14
+ - Please do not use any linting, formatting, or type-checking tools other than the ones listed above.
15
+ - Manually review all AI-generated code.
16
+ - If you create any types (including `TypeAlias`es, `Protocol`s, etc.) that do not exist in the source, they should be named with a leading underscore so that end users of pygal don't try to import types that don't exist in that package.
17
+ - If you believe any part of these rules, the ignored linter and type-checking rules in [pyproject.toml](./pyproject.toml), the stubtest [allowlist](./allowlist.txt), etc. should be changed, please open an issue: The rules should make this package and its development better, not hinder it.
18
+
19
+ # Setup
20
+ ## 1. Fork and clone
21
+ Fork the repository and clone your fork. Make a new branch for your changes and work there.
22
+
23
+ ## 2. Install everything you need with Hatch
24
+ This project uses the **Hatchling backend** alongside the **Hatch project manager**.
25
+
26
+ All you need to do is
27
+ 1. [Install Hatch](https://hatch.pypa.io/latest/install/) if you haven't already.
28
+ 2. Open a shell at the root of the repository (where this very file sits), and run:
29
+
30
+ ```bash
31
+ hatch shell
32
+ ```
33
+
34
+ This will:
35
+ 1. Create a virtual environment and use it for the shell: You should see `(.venv)` at the beginning of your prompt.
36
+ 2. Install the regular dependencies (typing-extensions, types-lxml, django-types) as well as the following tools:
37
+ - hatch (for building; this package uses the Hatchling backend)
38
+ - black (for formatting)
39
+ - ruff (for linting)
40
+ - basedpyright (for type checking)
41
+ - mypy (for stubtest)
42
+ - _yes, this means that the stubs will go through both basedpyright and mypy_
43
+ - pygal (you must have it in the environment for stubtest to work)
44
+ - lxml, pyquery, Flask, Django and CairoSVG (required by some pygal features)
45
+
46
+ ## 3. Work and test
47
+ After modifying the stubs, you should run `hatch run check:all`. This will:
48
+ - Run the ruff linter, auto-fixing when possible
49
+ - Run the black formatter
50
+ - Run basedpyright
51
+ - Install the updated stubs in the venv, then run stubtest
52
+
53
+ Please make sure that there are no type errors, then submit a PR (requesting to merge your fork's branch to the [manucorsu/pygal-stubs](https://github.com/manucorsu/pygal-stubs)' `main` branch).
54
+
55
+ # Additional considerations
56
+ - Once you're done working, use `exit` to leave the shell. You don't need to manually deactivate the venv.
57
+ - **Visual Studio Code users beware**: This repository has a `.vscode/settings.json` file that will disable Pylance (Microsoft's proprietary Python language server that comes with the Python extension). Install the **[basedpyright extension](https://marketplace.visualstudio.com/items?itemName=detachhead.basedpyright)** to regain in-editor type checking.
58
+ - Pylance will remain enabled in all other projects that don't have a `.vscode/settings.json` like this, taking priority over basedpyright.
59
+ - _Users of non-proprietary releases (i.e. VSCodium or built from source), and forks (i.e Antigravity IDE) don't need to worry about this because Microsoft does not make Pylance available to them. You should still make sure you're using basedpyright and not another language server like pyrefly._
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Manuel Corsunsky Gayá
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,126 @@
1
+ Metadata-Version: 2.5
2
+ Name: pygal-stubs
3
+ Version: 3.1.3.1
4
+ Summary: Type stubs for pygal
5
+ Project-URL: Repository, https://github.com/manucorsu/pygal-stubs
6
+ Project-URL: Issues, https://github.com/manucorsu/pygal-stubs/issues
7
+ Author-email: Manuel Corsunsky Gayá <manuelcorsunsky@gmail.com>
8
+ Maintainer-email: Manuel Corsunsky Gayá <manuelcorsunsky@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Topic :: Scientific/Engineering :: Visualization
20
+ Classifier: Typing :: Stubs Only
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: django-types
23
+ Requires-Dist: types-lxml
24
+ Requires-Dist: typing-extensions
25
+ Provides-Extra: dev
26
+ Requires-Dist: basedpyright; extra == 'dev'
27
+ Requires-Dist: black; extra == 'dev'
28
+ Requires-Dist: cairosvg; extra == 'dev'
29
+ Requires-Dist: django; extra == 'dev'
30
+ Requires-Dist: flask; extra == 'dev'
31
+ Requires-Dist: hatch; extra == 'dev'
32
+ Requires-Dist: lxml; extra == 'dev'
33
+ Requires-Dist: mypy; extra == 'dev'
34
+ Requires-Dist: pygal; extra == 'dev'
35
+ Requires-Dist: pyquery; extra == 'dev'
36
+ Requires-Dist: ruff; extra == 'dev'
37
+ Description-Content-Type: text/markdown
38
+
39
+ _The most up-to-date version of this README is on [GitHub](https://github.com/manucorsu/pygal-stubs/blob/main/README.md)._
40
+
41
+ # pygal-stubs
42
+ ## What is this?
43
+ - pygal-stubs is a package that provides external type stubs (PEP 561) for [pygal](https://github.com/Kozea/pygal).
44
+ - [Install](#installation) 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](#usage) as well.
45
+ ## What this isn't
46
+ - This package is not affiliated with [pygal](https://github.com/Kozea/pygal).
47
+ - 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](https://github.com/manucorsu/pygal-stubs/blob/main/CONTRIBUTING.md); If you don't, open an issue.
48
+ - (Per the [LICENSE](https://github.com/manucorsu/pygal-stubs/blob/main/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**.
49
+ - 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.
50
+ - These stubs are not intended for use with any particular type checker, however, they were written while using [basedpyright](https://github.com/DetachHead/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](https://github.com/manucorsu/pygal-stubs/blob/main/CONTRIBUTING.md) or open an issue.
51
+ - (obviously) This isn't replacement for [pygal's documentation](https://www.pygal.org/en/stable/documentation/index.html), which should always be considered the source of truth when using pygal.
52
+ ## Installation
53
+ > [!NOTE]
54
+ > This package currently supports **Python 3.10 and higher**.
55
+ >
56
+ > **Python versions are supported until [their EOL](https://devguide.python.org/versions/)**.
57
+ >
58
+ > This means that **Python 3.10 support will be dropped in October 2026**.
59
+ >
60
+ > See [CONTRIBUTING.md](https://github.com/manucorsu/pygal-stubs/blob/main/CONTRIBUTING.md) for more details.
61
+
62
+ > [!WARNING]
63
+ > Read [Usage](#usage) before using these stubs to avoid **unexpected runtime errors**.
64
+
65
+ pygal-stubs is available on [PyPI](https://pypi.org/project/pygal-stubs). Install it with:
66
+
67
+ ```bash
68
+ pip install pygal-stubs
69
+ ```
70
+
71
+ Or however you usually install PyPI packages.
72
+
73
+ This will automatically install the following type dependencies:
74
+ - `typing-extensions`: Backports modern typing features to all supported Python versions.
75
+ - `types-lxml` & `django-types`: Stubs for pygal's optional dependencies to prevent `Any` / `Unknown` from leaking into your codebase.
76
+ - 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).
77
+
78
+ 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 `ImportError`s.
79
+
80
+ 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](https://github.com/manucorsu/pygal_maps_world_neo), [stubs](https://github.com/manucorsu/pygal_maps_world_neo-stubs). [^1]
81
+
82
+ [^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](https://github.com/manucorsu/pygal-stubs/blob/main/CONTRIBUTING.md). 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.
83
+
84
+ ## Usage
85
+ > [!IMPORTANT]
86
+ > TLDR: **Avoid reading Graph config attributes if possible**. If you have to do it anyways, **ALWAYS use a `try-except` block to handle potential `AttributeError`**.
87
+
88
+ 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.
89
+
90
+ For example:
91
+ ```python
92
+ line = pygal.Line()
93
+ title = line.title # Your type checker will say this is str | None, when in reality this line will cause an AttributeError!
94
+ ```
95
+
96
+ This isn't an issue if you never read these attributes. Assigning to them doesn't cause any issues, as seen here:
97
+
98
+ ```python
99
+ import pygal
100
+ line = pygal.Line()
101
+ line.title = "My Title" # This is fine
102
+ ```
103
+
104
+ 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:
105
+
106
+ ```python
107
+ import pygal
108
+ # Instead of:
109
+ line = pygal.Line()
110
+ line.title = "My Title"
111
+
112
+ # or:
113
+ config = pygal.Config()
114
+ config.title = "My Title"
115
+ line = pygal.Line(config)
116
+
117
+ # You can do:
118
+ line = pygal.Line(title="My Title")
119
+ ```
120
+
121
+ 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](https://github.com/manucorsu/pygal-stubs/blob/main/CONTRIBUTING.md). This paragraph also applies to some other methods (e.g. `add`)
122
+
123
+ ### Why is this?
124
+ 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](https://github.com/manucorsu/pygal-stubs/blob/main/pygal-stubs/config.pyi) 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.
125
+
126
+ 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](https://github.com/manucorsu/pygal-stubs/blob/main/CONTRIBUTING.md)
@@ -0,0 +1,88 @@
1
+ _The most up-to-date version of this README is on [GitHub](https://github.com/manucorsu/pygal-stubs/blob/main/README.md)._
2
+
3
+ # pygal-stubs
4
+ ## What is this?
5
+ - pygal-stubs is a package that provides external type stubs (PEP 561) for [pygal](https://github.com/Kozea/pygal).
6
+ - [Install](#installation) 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](#usage) as well.
7
+ ## What this isn't
8
+ - This package is not affiliated with [pygal](https://github.com/Kozea/pygal).
9
+ - 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](https://github.com/manucorsu/pygal-stubs/blob/main/CONTRIBUTING.md); If you don't, open an issue.
10
+ - (Per the [LICENSE](https://github.com/manucorsu/pygal-stubs/blob/main/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**.
11
+ - 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.
12
+ - These stubs are not intended for use with any particular type checker, however, they were written while using [basedpyright](https://github.com/DetachHead/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](https://github.com/manucorsu/pygal-stubs/blob/main/CONTRIBUTING.md) or open an issue.
13
+ - (obviously) This isn't replacement for [pygal's documentation](https://www.pygal.org/en/stable/documentation/index.html), which should always be considered the source of truth when using pygal.
14
+ ## Installation
15
+ > [!NOTE]
16
+ > This package currently supports **Python 3.10 and higher**.
17
+ >
18
+ > **Python versions are supported until [their EOL](https://devguide.python.org/versions/)**.
19
+ >
20
+ > This means that **Python 3.10 support will be dropped in October 2026**.
21
+ >
22
+ > See [CONTRIBUTING.md](https://github.com/manucorsu/pygal-stubs/blob/main/CONTRIBUTING.md) for more details.
23
+
24
+ > [!WARNING]
25
+ > Read [Usage](#usage) before using these stubs to avoid **unexpected runtime errors**.
26
+
27
+ pygal-stubs is available on [PyPI](https://pypi.org/project/pygal-stubs). Install it with:
28
+
29
+ ```bash
30
+ pip install pygal-stubs
31
+ ```
32
+
33
+ Or however you usually install PyPI packages.
34
+
35
+ This will automatically install the following type dependencies:
36
+ - `typing-extensions`: Backports modern typing features to all supported Python versions.
37
+ - `types-lxml` & `django-types`: Stubs for pygal's optional dependencies to prevent `Any` / `Unknown` from leaking into your codebase.
38
+ - 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).
39
+
40
+ 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 `ImportError`s.
41
+
42
+ 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](https://github.com/manucorsu/pygal_maps_world_neo), [stubs](https://github.com/manucorsu/pygal_maps_world_neo-stubs). [^1]
43
+
44
+ [^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](https://github.com/manucorsu/pygal-stubs/blob/main/CONTRIBUTING.md). 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.
45
+
46
+ ## Usage
47
+ > [!IMPORTANT]
48
+ > TLDR: **Avoid reading Graph config attributes if possible**. If you have to do it anyways, **ALWAYS use a `try-except` block to handle potential `AttributeError`**.
49
+
50
+ 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.
51
+
52
+ For example:
53
+ ```python
54
+ line = pygal.Line()
55
+ title = line.title # Your type checker will say this is str | None, when in reality this line will cause an AttributeError!
56
+ ```
57
+
58
+ This isn't an issue if you never read these attributes. Assigning to them doesn't cause any issues, as seen here:
59
+
60
+ ```python
61
+ import pygal
62
+ line = pygal.Line()
63
+ line.title = "My Title" # This is fine
64
+ ```
65
+
66
+ 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:
67
+
68
+ ```python
69
+ import pygal
70
+ # Instead of:
71
+ line = pygal.Line()
72
+ line.title = "My Title"
73
+
74
+ # or:
75
+ config = pygal.Config()
76
+ config.title = "My Title"
77
+ line = pygal.Line(config)
78
+
79
+ # You can do:
80
+ line = pygal.Line(title="My Title")
81
+ ```
82
+
83
+ 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](https://github.com/manucorsu/pygal-stubs/blob/main/CONTRIBUTING.md). This paragraph also applies to some other methods (e.g. `add`)
84
+
85
+ ### Why is this?
86
+ 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](https://github.com/manucorsu/pygal-stubs/blob/main/pygal-stubs/config.pyi) 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.
87
+
88
+ 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](https://github.com/manucorsu/pygal-stubs/blob/main/CONTRIBUTING.md)
@@ -0,0 +1,12 @@
1
+ # pygal ships its own test suite inside the installed package; it's not
2
+ # part of the public API and we don't stub it.
3
+ ^pygal\.test(\..*)?$
4
+
5
+ # pygal.config.*: every setting is declared as a `Key(...)` descriptor at
6
+ # class-definition time. At runtime, stubtest introspects the class body
7
+ # and sees `Key[Any, Any]` — the descriptor object itself — not the
8
+ # resolved value a real caller gets back after Key's __get__/__set__
9
+ # magic runs. We deliberately stub these attributes as their resolved
10
+ # value type (bool, list[str], etc.), which is what every real usage
11
+ # actually interacts with, not the internal descriptor mechanism.
12
+ ^pygal\.config\.\w*Config\.\w+$
@@ -0,0 +1,19 @@
1
+ __all__ = [
2
+ "__author__",
3
+ "__copyright__",
4
+ "__email__",
5
+ "__license__",
6
+ "__summary__",
7
+ "__title__",
8
+ "__uri__",
9
+ "__version__",
10
+ ]
11
+
12
+ __title__: str
13
+ __version__: str
14
+ __summary__: str
15
+ __uri__: str
16
+ __author__: str
17
+ __email__: str
18
+ __license__: str
19
+ __copyright__: str
@@ -0,0 +1,79 @@
1
+ from collections.abc import Sequence
2
+ from types import ModuleType
3
+
4
+ from pygal import maps as maps
5
+ from pygal import style as style
6
+ from pygal.config import Config as Config
7
+ from pygal.graph.bar import Bar as Bar
8
+ from pygal.graph.box import Box as Box
9
+ from pygal.graph.dot import Dot as Dot
10
+ from pygal.graph.funnel import Funnel as Funnel
11
+ from pygal.graph.gauge import Gauge as Gauge
12
+ from pygal.graph.graph import Graph as Graph
13
+ from pygal.graph.histogram import Histogram as Histogram
14
+ from pygal.graph.horizontalbar import HorizontalBar as HorizontalBar
15
+ from pygal.graph.horizontalline import HorizontalLine as HorizontalLine
16
+ from pygal.graph.horizontalstackedbar import (
17
+ HorizontalStackedBar as HorizontalStackedBar,
18
+ )
19
+ from pygal.graph.horizontalstackedline import (
20
+ HorizontalStackedLine as HorizontalStackedLine,
21
+ )
22
+ from pygal.graph.line import Line as Line
23
+ from pygal.graph.map import BaseMap as BaseMap
24
+ from pygal.graph.pie import Pie as Pie
25
+ from pygal.graph.pyramid import Pyramid as Pyramid
26
+ from pygal.graph.pyramid import VerticalPyramid as VerticalPyramid
27
+ from pygal.graph.radar import Radar as Radar
28
+ from pygal.graph.solidgauge import SolidGauge as SolidGauge
29
+ from pygal.graph.stackedbar import StackedBar as StackedBar
30
+ from pygal.graph.stackedline import StackedLine as StackedLine
31
+ from pygal.graph.time import (
32
+ DateLine as DateLine,
33
+ )
34
+ from pygal.graph.time import (
35
+ DateTimeLine as DateTimeLine,
36
+ )
37
+ from pygal.graph.time import (
38
+ TimeDeltaLine as TimeDeltaLine,
39
+ )
40
+ from pygal.graph.time import (
41
+ TimeLine as TimeLine,
42
+ )
43
+ from pygal.graph.treemap import Treemap as Treemap
44
+ from pygal.graph.xy import XY as XY
45
+
46
+ from .__about__ import (
47
+ __author__ as __author__,
48
+ )
49
+ from .__about__ import (
50
+ __copyright__ as __copyright__,
51
+ )
52
+ from .__about__ import (
53
+ __email__ as __email__,
54
+ )
55
+ from .__about__ import (
56
+ __license__ as __license__,
57
+ )
58
+ from .__about__ import (
59
+ __summary__ as __summary__,
60
+ )
61
+ from .__about__ import (
62
+ __title__ as __title__,
63
+ )
64
+ from .__about__ import (
65
+ __uri__ as __uri__,
66
+ )
67
+ from .__about__ import (
68
+ __version__ as __version__,
69
+ )
70
+
71
+ CHARTS_BY_NAME: dict[str, type[Graph]]
72
+ CHARTS_NAMES: list[str]
73
+ CHARTS: list[type[Graph]]
74
+
75
+ class PluginImportFixer:
76
+ def find_module(
77
+ self, fullname: str, path: Sequence[str] | None = None
78
+ ) -> PluginImportFixer | None: ...
79
+ def load_module(self, name: str) -> ModuleType: ...
@@ -0,0 +1,12 @@
1
+ from collections.abc import Iterable
2
+ from datetime import datetime
3
+ from typing import Protocol, TypeVar
4
+
5
+ from typing_extensions import TypeIs
6
+
7
+ _T_co = TypeVar("_T_co", covariant=True, default=object)
8
+
9
+ class _ListLikeIterable(Iterable[_T_co], Protocol): ...
10
+
11
+ def is_list_like(value: object) -> TypeIs[_ListLikeIterable[object]]: ...
12
+ def timestamp(x: datetime) -> float: ...