Hi!
I'm pleased to announce the availability of wxGlade revision 1.0.1
Please download from https://sourceforge.net/projects/wxglade/files/wxglade/1.0.1/
wxGlade is a GUI builder for wxWidgets and wxPython.
The documentation includes a tutorial for people who have not used wxPython
before.
Included are also examples for integration with matplotlib.
A snapshot of the documentation is available at http://wxglade.sourceforge.net/docs/index.html
For support, there's a mailing list at https://sourceforge.net/p/wxglade/mailman/wxglade-general/
git repository and bug tracker are at https://github.com/wxGlade/wxGlade
(These pages are also linked from the help menu.)
Changes in revision 1.0.x:
==========================
Besides many improvements in usability, code generation and widget support,
this is also a major internal refactoring of the main data structure and how
widgets in the Design window are created / updated / destroyed.
*General:*
- sizers only required where wx requires them; not required e.g. for
Frame->Panel (used to be Frame->Sizer->Panel)
- better handling of display updates when properties are edited
- accessibility and usability improvements
- Dialog example
- documentation update
*Widgets:*
- all: separate class related properties into Class / Base Classes /
Instance Class
- Dialog: add StdDialogButtonSizer and standard buttons (stock items);
support SetAffirmativeId, SetEscapeId
- Button: support for image direction
- MenuBar: support lambda event handlers
- GridBagSizer: indicate overlapped slots in the Tree view
*Generated Code:*
- no separation into __set_properties/__do_layout any more
- support for instantiation classes
*Internal:*
- internal structures refactored
- add shell window and Tree Printer
wxGlade is released under the MIT license.
Happy New Year,
Dietmar Schwertberger
dietmar(a)schwertberger.de
<P><A HREF="https://sourceforge.net/projects/wxglade/files/wxglade/1.0.1/">wxGlade 1.0.1</A> - GUI builder for wxPython (31-Dec-20)
I am pleased to announce the release of SfePy 2021.1.
Description
-----------
SfePy (simple finite elements in Python) is a software for solving systems of
coupled partial differential equations by finite element methods. It is
distributed under the new BSD license.
Home page: https://sfepy.org
Mailing list: https://mail.python.org/mm3/mailman3/lists/sfepy.python.org/
Git (source) repository, issue tracker: https://github.com/sfepy/sfepy
Highlights of this release
--------------------------
- non-square homogenized coefficient matrices
- new implementation of multi-linear terms
- improved handling of Dirichlet and periodic boundary conditions in common
nodes
- terms in the term table document linked to examples
For full release notes see [1].
Cheers,
Robert Cimrman
[1] http://docs.sfepy.org/doc/release_notes.html#id1
---
Contributors to this release in alphabetical order:
Robert Cimrman
Antony Kamp
Vladimir Lukes
Hello,
imphook is a simple, small single-file module and a tool which allows
to easily and selectively override Python import machinery for
particular file types (including Python source files).
As an example of usage, recently on the python-ideas mailing list,
there was a discussion about "arrow functions" for Python (as a
syntactic alternative to lambda). A prototype implementation using
"imphook" was posted:
https://mail.python.org/archives/list/python-ideas@python.org/thread/VOVHZU…
The project is available from:
PyPI: https://pypi.org/project/imphook/ (package includes only the
module itself).
Github: https://github.com/pfalcon/python-imphook (assorted usage
examples are included in the git repository)
Below is a documentation snapshot:
imphook - Simple and clear import hooks for Python
==================================================
The ``imphook`` module allows to easily define per file type import
hooks, i.e. overload or extend import processing for particular file
types, without affecting processing of other file types, and at the
same time, while ensuring that new processing integrates as seamlessly
as possible with normal Python import rules.
Besides the Python-level API to install import hooks, the module also
provides command-line interface to run an existing Python script or
module with one or more import hooks preloaded (i.e. without modifying
existing script source code).
Some but not all things you can easily do using ``imphook`` (most
of these require additional modules to do the heavy lifting,
``imphook`` just allows to plug it seamlessly into the Python import
system):
* Override importing of (all or some) .py files, to support new
syntax or semantics in them.
* Import files written using a DSL (domain-specific language)
as if they were Python modules. E.g., config or data files.
* Import modules written in other language(s), assuming you have
an interpreter(s) for them.
* Import binary files, e.g. Java or LLVM bytecode.
``imphook`` works both with new, lightweight legacy-free Python
API, as promoted by the `Pycopy <https://github.com/pfalcon/pycopy>`_
Python dialect (the original source of the "easy import hooks" idea),
and CPython (the older, reference Python implementation), and with
other Python implementations which are CPython-compatible.
Quick Start
-----------
Make sure that you already installed ``imphook`` using::
pip3 install -U imphook
Below is a complete example of an import hook module to load
``key = value`` style config files::
import imphook
def hook(modname, filename):
with open(filename) as f:
# Create a module object which will be the result of import.
mod = type(imphook)(modname)
for l in f:
k, v = [x.strip() for x in l.split("=", 1)]
setattr(mod, k, v)
return mod
imphook.add_import_hook(hook, (".conf",))
Save this as the ``mod_conf.py`` file, and add the two following
files to test it:
``example_settings.conf``::
var1 = 123
var2 = hello
``example_conf.py``::
import example_settings as settings
print(settings.var1)
print(settings.var2)
Now run::
python3 -m imphook -i mod_conf example_conf.py
As you can see, the ``example_conf.py`` is able to import
``example_settings.conf`` as if it were a normal Python module.
Besides copy-pasting the above and other examples, you can also
clone the Git repository of ``imphook``, which contains various
ready-to-use examples::
git clone https://github.com/pfalcon/python-imphook
API to install hooks and hook structure
---------------------------------------
The API of the module consists of one function:
`imphook.add_import_hook(hook, ext_tuple)`. *hook* is a name of
hook function. *ext_tuple* is a tuple of file extensions
the hook function should handle (the leading dot should be included).
More often than not, you will want to handle just one extension,
so don't forget to use the usual Python syntax with a trailing
comma for 1-element tuple, e.g.: ``(".ext",)``. Python modules may
not contain a dot (``"."``) in their names (they are used to separate
subpackages), so the extension you register may contain multiple
dots, e.g. ``".foo.bar"``, with filename ``my_module.foo.bar``
matching it.
It is possible to call `imphook.add_import_hook(hook, ext_tuple)`
multiple times to install multiple hooks. The hooks are installed
in the stack-like fashion, the last installed will be called
first. It is possible to install multiple hooks for the same file
extension, and earlier installed hooks may still be called in this
case, because a hook function may skip processing a particular
file, and let other hooks to take a chance, with default processing
happening if no hook handled the import.
The signature and template of the actual hook function is::
def my_hook(modname, filename):
# Return None if you don't want to handle `filename`.
# Otherwise, load `filename`, create a Python module object,
# with name `modname`, populate it based on the loaded file
# contents, and return it.
The *modname* parameter is a full module name of the module to
import, in the usual dot-separated notation, e.g. ``my_module``
or ``pkg.subp.mod``. For relative imports originated from within
a package, this name is already resolved to full absolute name.
The *modname* should be used to create a module object with the
given name.
The *filename* parameter is a full pathname (with extension) of the
file which hook should import. This filename is known to exist, so
you may proceed to open it directly. You may skip processing this
file by returning ``None`` from the hook, then other hooks may be
tried, and default processing happens otherwise (e.g. ``.py`` files
are loaded as usual, or ImportError raised for non-standard
extensions). For package imports, the value of *filename* ends with
``/__init__.py``, and that is the way to distinguish module vs
package imports.
If the hook proceeds with the file, it should load it by whatever
means suitable for the file type. File types which are not natively
supported by Python would require installing and using other extension
modules (beyond ``imphook``). After loading the file, the hook should
create an empty Python module object which will be the result of the
import. There are a few ways to do that:
* The baseline is to call a module type as a constructor. To get
a module type, just apply the usual ``type()`` function to an
existing (imported) module. You'll definitely have ``imphook``
itself imported, which leads us to::
mod = type(imphook)(modname)
The parameter to constructor is the name of module to create,
as passed to the hook.
* If the above looks too magic for you, you can import symbolic
name for module type from the ``types`` module::
from types import ModuleType
mod = ModuleType(modname)
* Finally, you may use the ``imp`` module, which may be as well
the clearest (to the newbie) way of doing it::
import imp
mod = imp.new_module(modname)
But mind that the ``imp`` module is considered deprecated.
Of the choices above, the first is the most efficient - no need
to import additional modules, and it's just one line. And once
you saw and were explained what it does, it shouldn't be a problem
to remember and recognize it later.
Once the module object is created as discussed above, you should
populate it. A way to do that is by using ``setattr()`` builtin
to set a particular attribute of a module to a particular value.
Attributes usually represent variables with data values, but
may be also functions and classes.
Finally, you just return the populated module object.
In case you want to perform custom transformation on the Python
source, the process is usually somewhat different, where you
transform a representation of the source, and then execute it
in the context of a new module, which causes it to be populated.
Using import hooks in your applications
---------------------------------------
There are 2 ways to use import hook(s) in you Python programs:
either preloading them before starting your program using ``imphook``
command-line runner (next section) or load them explicitly at the
startup of your application. Crucial thing to remember that import
hooks apply: a) for imports only; b) for imports appearing after
the hook was installed.
The main file of our application is normally *not imported*, but
executed directly. This leads to the following pattern in structuring
your application source files:
* Have a "startup file", which is the one which user will actually
run, so name it appropriately. In that file, you load import hooks
and perform other baseline system-level initialization.
* The main functionality of your application is contained in seperate
module(s). The startup script imports such a main module and
executes it (e.g., by calling a function from it).
You already grasped how that works - as the "main" module is
*imported*, whatever hooks the "startup" script installed, will
apply to it.
This pattern is actually officially encoded in the structure of
Python *packages*. And any non-trivial Python application will
likely be a package with a few sub-modules in it, so you can as
well structure your applications this way (as a package), even
if they start simple (only one submodule initially). So, if you
try to "run" a package, what actually gets run is ``__main__``
submodule in that package. That's exactly the "startup" file
we discussed above. It installs the import hooks, and imports
a submodule with actual application's functionality.
Credits and licensing
---------------------
``imphook`` is (c) `Paul Sokolovsky <https://github.com/pfalcon>`_ and
is released under the MIT license.
--
Best regards,
Paul mailto:pmiscml@gmail.com
Charles R Harris <charlesr.harris(a)gmail.com>
Sun, Feb 7, 2:23 PM
to numpy-discussion, SciPy, SciPy-User, bcc: python-announce-list
Hi All,
On behalf of the NumPy team I am pleased to announce the release of NumPy
1.20.2. NumPy 1,20.2 is a bugfix release containing several fixes merged to
the main branch after the NumPy 1.20.1 release. The Python versions
supported for this release are 3.7-3.9. Wheels can be downloaded from PyPI
<https://pypi.org/project/numpy/1.20.2/>; source archives, release notes,
and wheel hashes are available on Github
<https://github.com/numpy/numpy/releases/tag/v1.20.2>. Linux users will
need pip >= 0.19.3 in order to install manylinux2010 and manylinux2014
wheels.
*Contributors*
A total of 7 people contributed to this release. People with a "+" by their
names contributed a patch for the first time.
- Allan Haldane
- Bas van Beek
- Charles Harris
- Christoph Gohlke
- Mateusz Sokół +
- Michael Lamparski
- Sebastian Berg
*Pull requests merged*
A total of 20 pull requests were merged for this release.
- #18382: MAINT: Update f2py from master.
- #18459: BUG: ``diagflat`` could overflow on windows or 32-bit platforms
- #18460: BUG: Fix refcount leak in f2py ``complex_double_from_pyobj``.
- #18461: BUG: Fix tiny memory leaks when ``like=`` overrides are used
- #18462: BUG: Remove temporary change of descr/flags in VOID functions
- #18469: BUG: Segfault in nditer buffer dealloc for Object arrays
- #18485: BUG: Remove suspicious type casting
- #18486: BUG: remove nonsensical comparison of pointer < 0
- #18487: BUG: verify pointer against NULL before using it
- #18488: BUG: check if PyArray_malloc succeeded
- #18546: BUG: incorrect error fallthrough in nditer
- #18559: CI: Backport CI fixes from main.
- #18599: MAINT: Add annotations for `dtype.__getitem__`, `__mul__`
and...
- #18611: BUG: NameError in numpy.distutils.fcompiler.compaq
- #18612: BUG: Fixed ``where`` keyword for ``np.mean`` & ``np.var``
methods
- #18617: CI: Update apt package list before Python install
- #18636: MAINT: Ensure that re-exported sub-modules are properly
annotated
- #18638: BUG: Fix ma coercion list-of-ma-arrays if they do not cast
to...
- #18661: BUG: Fix small valgrind-found issues
- #18671: BUG: Fix small issues found with pytest-leaks
Cheers,
Charles Harris
PyCA cryptography 3.4.7 has been released to PyPI. cryptography
includes both high level recipes and low level interfaces to common
cryptographic algorithms such as symmetric ciphers, asymmetric
algorithms, message digests, X509, key derivation functions, and much
more. We support Python 3.6+, and PyPy3.
Changelog (https://cryptography.io/en/latest/changelog.html#v3-4-7):
* Updated Windows, macOS, and manylinux wheels to be compiled with
OpenSSL 1.1.1k.
-Paul Kehrer (reaperhulk)
This year's conference will mark the 20th edition of the EuroPython
conference.
* EuroPython 2021 *
https://ep2021.europython.eu/
Since we started touring Europe in 2002 in Charleroi, Belgium, we have
come a long way. The conference has grown from the initial 240 to around
1200-1400 attendees every year. The organization had started with a
small group of people in a somewhat ad-hoc way and has now grown into a
well structured team backed by the non-profit EuroPython Society (EPS),
while still keeping the fun spirit of the early days.
EuroPython 2002 was the first major all volunteer run event for Python.
A lot of other conferences have since emerged in Europe and we're
actively trying to help them wherever we can, with our grants program,
growing conference knowledge base and our Organizers' Lunch, for which
we regularly invite representatives of all European Python conferences
to get together to network, exchange experience in organizing events
community building and understand how we can most effectively help each
other.
To celebrate the anniversary, we took a deep look into our archives and
have put together live website copies of the last few years, going back
all the way to EP2009, which was held in Birmingham, UK. For previous
years, archive.org stored some pages of the websites, so let's do a
quick tour of 20 years of EuroPython ...
https://blog.europython.eu/20th-anniversary-of-europython/
Help spread the word
--------------------
Please help us spread this message by sharing it on your social
networks as widely as possible. Thank you !
Link to the blog post:
https://blog.europython.eu/20th-anniversary-of-europython/
Tweet:
https://twitter.com/europython/status/1375077502851420160
Enjoy,
--
EuroPython 2021 Team
https://www.europython-society.org/
Hi all,
On behalf of the SciPy development team I'm pleased to announce
the release of SciPy 1.6.2, which is a bug fix release.
Sources and binary wheels can be found at:
https://pypi.org/project/scipy/
and at: https://github.com/scipy/scipy/releases/tag/v1.6.2
<https://github.com/scipy/scipy/releases/tag/v1.6.1>
One of a few ways to install this release with pip:
pip install scipy==1.6.2
=====================
SciPy 1.6.2 Release Notes
=====================
SciPy 1.6.2 is a bug-fix release with no new features
compared to 1.6.1. This is also the first SciPy release
to place upper bounds on some dependencies to improve
the long-term repeatability of source builds.
Authors
======
* Pradipta Ghosh +
* Tyler Reddy
* Ralf Gommers
* Martin K. Scherer +
* Robert Uhl
* Warren Weckesser
A total of 6 people contributed to this release.
People with a "+" by their names contributed a patch for the first time.
This list of names is automatically generated, and may not be fully
complete.
Issues closed for 1.6.2
------------------------------
* `#13512 <https://github.com/scipy/scipy/issues/13512>`__:
\`stats.gaussian_kde.evaluate\` broken on S390X
* `#13584 <https://github.com/scipy/scipy/issues/13584>`__:
rotation._compute_euler_from_matrix() creates an array with negative...
* `#13585 <https://github.com/scipy/scipy/issues/13585>`__: Behavior change
in coo_matrix when dtype=None
* `#13686 <https://github.com/scipy/scipy/issues/13686>`__: delta0 argument
of scipy.odr.ODR() ignored
Pull requests for 1.6.2
------------------------------
* `#12862 <https://github.com/scipy/scipy/pull/12862>`__: REL: put upper
bounds on versions of dependencies
* `#13575 <https://github.com/scipy/scipy/pull/13575>`__: BUG: fix
\`gaussian_kernel_estimate\` on S390X
* `#13586 <https://github.com/scipy/scipy/pull/13586>`__: BUG: sparse:
Create a utility function \`getdata\`
* `#13598 <https://github.com/scipy/scipy/pull/13598>`__: MAINT, BUG:
enforce contiguous layout for output array in Rotation.as_euler
* `#13687 <https://github.com/scipy/scipy/pull/13687>`__: BUG: fix
scipy.odr to consider given delta0 argument
Checksums
=========
MD5
~~~
fc81d43879a28270d593aaea37c74ff8
scipy-1.6.2-cp37-cp37m-macosx_10_9_x86_64.whl
9213533bfd3c2f1563d169009c39825c scipy-1.6.2-cp37-cp37m-manylinux1_i686.whl
2ddd03b89efdb1619fa995da7b83aa6f
scipy-1.6.2-cp37-cp37m-manylinux1_x86_64.whl
d378f725958bd6a83db7ef23e8659762
scipy-1.6.2-cp37-cp37m-manylinux2014_aarch64.whl
87bc2771b8a8ab1f10168b1563300415 scipy-1.6.2-cp37-cp37m-win32.whl
861dab18fe41e82c08c8f585f2710545 scipy-1.6.2-cp37-cp37m-win_amd64.whl
d2e2002b526adeebf94489aa95031f54
scipy-1.6.2-cp38-cp38-macosx_10_9_x86_64.whl
2dc36bfbe3938c492533604aba002c17 scipy-1.6.2-cp38-cp38-manylinux1_i686.whl
0114de2118d41f9440cf86fdd67434fc
scipy-1.6.2-cp38-cp38-manylinux1_x86_64.whl
ede6db56b1bf0a7fed0c75acac7dcb85
scipy-1.6.2-cp38-cp38-manylinux2014_aarch64.whl
191636ac3276da0ee9fd263b47927b73 scipy-1.6.2-cp38-cp38-win32.whl
8bdf7ab041b9115b379f043bb02d905f scipy-1.6.2-cp38-cp38-win_amd64.whl
608c82b227b6077d9a7871ac6278e64d
scipy-1.6.2-cp39-cp39-macosx_10_9_x86_64.whl
4c0313b2cccc85666b858ffd692a3c87 scipy-1.6.2-cp39-cp39-manylinux1_i686.whl
92da8ffe165034dbbe5f098d0ed58aec
scipy-1.6.2-cp39-cp39-manylinux1_x86_64.whl
b4b225fb1deeaaf0eda909fdd3bd6ca6
scipy-1.6.2-cp39-cp39-manylinux2014_aarch64.whl
662969220eadbb6efec99030e4d00268 scipy-1.6.2-cp39-cp39-win32.whl
f19186d6d91c7e37000e9f6ccd9b9b60 scipy-1.6.2-cp39-cp39-win_amd64.whl
cbcb9b39bd9d877ad3deeccc7c37bb7f scipy-1.6.2.tar.gz
b56e705c653ad808a9725dfe840d1258 scipy-1.6.2.tar.xz
6f615549670cd3d312dc9e4359d2436a scipy-1.6.2.zip
SHA256
~~~~~~
77f7a057724545b7e097bfdca5c6006bed8580768cd6621bb1330aedf49afba5
scipy-1.6.2-cp37-cp37m-macosx_10_9_x86_64.whl
e547f84cd52343ac2d56df0ab08d3e9cc202338e7d09fafe286d6c069ddacb31
scipy-1.6.2-cp37-cp37m-manylinux1_i686.whl
bc52d4d70863141bb7e2f8fd4d98e41d77375606cde50af65f1243ce2d7853e8
scipy-1.6.2-cp37-cp37m-manylinux1_x86_64.whl
adf7cee8e5c92b05f2252af498f77c7214a2296d009fc5478fc432c2f8fb953b
scipy-1.6.2-cp37-cp37m-manylinux2014_aarch64.whl
e3e9742bad925c421d39e699daa8d396c57535582cba90017d17f926b61c1552
scipy-1.6.2-cp37-cp37m-win32.whl
ffdfb09315896c6e9ac739bb6e13a19255b698c24e6b28314426fd40a1180822
scipy-1.6.2-cp37-cp37m-win_amd64.whl
6ca1058cb5bd45388041a7c3c11c4b2bd58867ac9db71db912501df77be2c4a4
scipy-1.6.2-cp38-cp38-macosx_10_9_x86_64.whl
993c86513272bc84c451349b10ee4376652ab21f312b0554fdee831d593b6c02
scipy-1.6.2-cp38-cp38-manylinux1_i686.whl
37f4c2fb904c0ba54163e03993ce3544c9c5cde104bcf90614f17d85bdfbb431
scipy-1.6.2-cp38-cp38-manylinux1_x86_64.whl
96620240b393d155097618bcd6935d7578e85959e55e3105490bbbf2f594c7ad
scipy-1.6.2-cp38-cp38-manylinux2014_aarch64.whl
03f1fd3574d544456325dae502facdf5c9f81cbfe12808a5e67a737613b7ba8c
scipy-1.6.2-cp38-cp38-win32.whl
0c81ea1a95b4c9e0a8424cf9484b7b8fa7ef57169d7bcc0dfcfc23e3d7c81a12
scipy-1.6.2-cp38-cp38-win_amd64.whl
c1d3f771c19af00e1a36f749bd0a0690cc64632783383bc68f77587358feb5a4
scipy-1.6.2-cp39-cp39-macosx_10_9_x86_64.whl
50e5bcd9d45262725e652611bb104ac0919fd25ecb78c22f5282afabd0b2e189
scipy-1.6.2-cp39-cp39-manylinux1_i686.whl
816951e73d253a41fa2fd5f956f8e8d9ac94148a9a2039e7db56994520582bf2
scipy-1.6.2-cp39-cp39-manylinux1_x86_64.whl
1fba8a214c89b995e3721670e66f7053da82e7e5d0fe6b31d8e4b19922a9315e
scipy-1.6.2-cp39-cp39-manylinux2014_aarch64.whl
e89091e6a8e211269e23f049473b2fde0c0e5ae0dd5bd276c3fc91b97da83480
scipy-1.6.2-cp39-cp39-win32.whl
d744657c27c128e357de2f0fd532c09c84cd6e4933e8232895a872e67059ac37
scipy-1.6.2-cp39-cp39-win_amd64.whl
e9da33e21c9bc1b92c20b5328adb13e5f193b924c9b969cd700c8908f315aa59
scipy-1.6.2.tar.gz
8fadc443044396283c48191d48e4e07a3c3b6e2ae320b1a56e76bb42929e84d2
scipy-1.6.2.tar.xz
2af283054d91865336b4579aa91f9e59d648d436cf561f96d4692008f795c750
scipy-1.6.2.zip
PyWeek is a twice-a-year game jam that has been running for the past 15 years. Starting on the first day of the jam (Sunday, March 28), you start coding, designing, and developing your game. This can be done as an individual or with a team. By Sunday, April 3rd you must submit your entry on the PyWeek website (pyweek.org) for it to be counted as a valid submission.
You can register on PyWeek.org. Head over to that webpage, click on the "Latest Challenge", and you should see an option to "Register an Entry". If you register now you can vote for what the theme of the game jam will be. Last's PyWeek had the theme of "Castaway."
If you have any questions, want to chat with other people participating, or find people to join a team, come hang out on Python Discord (https://discord.gg/python)! Feel free to tag me, Janine (kutiekatj9), if you have any questions in the server or feel free to just send me an email.
竜 TatSu is a tool that takes grammars in a variation of EBNF as input, and
outputs memoizing (Packrat) PEG parsers in Python.
竜 TatSu inspired the PEG parser in Python 3.9.
New in 竜 TatSu 5.6.0
* Several important refactorings in ``contexts.ParseContext``
* Make ``ignorecase`` settings apply to defined ``@@keywords``
* Move checking of keywords used as names into ``ParseContext``
* Output of generated parsers again matches that of model parsers
* Improve *"expecting one of:"* messages so elements are in declaration
order
* Stop code generation if there are closures over possibly empty
expressions
* Preserve name declaration order in returned ``AST``
* Update the bootstrap parser (``tatsu/bootstrap.py``) to the generated
parser
* Now generated parser's ``main()`` only outputs the JSON for the parse
``AST``
* Minor version bumped in case the many fixes break
backwards-compatibility
* Minor documentation issues fixed
* All tests run with Python 3.8, 3.9, 3.10
https://pypi.org/project/tatsu/https://tatsu.readthedocs.io/en/stable/https://github.com/neogeny/TatSu
---