Initial commit: Core packages

This commit is contained in:
Ernad Husremovic 2025-08-29 15:20:45 +02:00
commit 12c29a983b
9512 changed files with 8379910 additions and 0 deletions

View file

@ -0,0 +1,153 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pyjs.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pyjs.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/pyjs"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pyjs"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."

View file

@ -0,0 +1,55 @@
.. default-domain: python
.. _builtins:
Supported Python builtins
=========================
.. function:: py.type(object)
Gets the class of a provided object, if possible.
.. note:: currently doesn't work correctly when called on a class
object, will return the class itself (also, classes
don't currently have a type).
.. js:function:: py.type(name, bases, dict)
Not exactly a builtin as this form is solely javascript-level
(currently). Used to create new ``py.js`` types. See :doc:`types`
for its usage.
.. data:: py.None
.. data:: py.True
.. data:: py.False
.. data:: py.NotImplemented
.. class:: py.object
Base class for all types, even implicitly (if no bases are
provided to :js:func:`py.type`)
.. class:: py.bool([object])
.. class:: py.float([object])
.. class:: py.str([object])
.. class:: py.unicode([object])
.. class:: py.tuple()
.. class:: py.list()
.. class:: py.dict()
.. function:: py.len(object)
.. function:: py.isinstance(object, type)
.. function:: py.issubclass(type, other_type)
.. class:: py.classmethod

View file

@ -0,0 +1,247 @@
# -*- coding: utf-8 -*-
#
# py.js documentation build configuration file, created by
# sphinx-quickstart on Sun Sep 9 19:36:23 2012.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration -----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.todo']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'py.js'
copyright = u'2012, Xavier Morel'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.6'
# The full version, including alpha/beta/rc tags.
release = '0.6'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# Default sphinx domain
default_domain = 'js'
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# default code-block highlighting
highlight_language = 'javascript'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# -- Options for HTML output ---------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'pyjsdoc'
# -- Options for LaTeX output --------------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
('index', 'pyjs.tex', u'py.js Documentation',
u'Xavier Morel', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output --------------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'pyjs', u'py.js Documentation',
[u'Xavier Morel'], 1)
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output ------------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
('index', 'pyjs', u'py.js Documentation',
u'Xavier Morel', 'pyjs', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'

View file

@ -0,0 +1,64 @@
Differences with Python
=======================
* ``py.js`` completely ignores old-style classes as well as their
lookup details. All ``py.js`` types should be considered matching
the behavior of new-style classes
* New types can only have a single base. This is due to ``py.js``
implementing its types on top of Javascript's, and javascript being
a single-inheritance language.
This may change if ``py.js`` ever reimplements its object model from
scratch.
* Piggybacking on javascript's object model also means metaclasses are
not available (:js:func:`py.type` is a function)
* A python-level function (created through :js:class:`py.PY_def`) set
on a new type will not become a method, it'll remain a function.
* :js:func:`py.PY_parseArgs` supports keyword-only arguments (though
it's a Python 3 feature)
* Because the underlying type is a javascript ``String``, there
currently is no difference between :js:class:`py.str` and
:js:class:`py.unicode`. As a result, there also is no difference
between :js:func:`__str__` and :js:func:`__unicode__`.
Unsupported features
--------------------
These are Python features which are not supported at all in ``py.js``,
usually because they don't make sense or there is no way to support them
* The ``__delattr__``, ``__delete__`` and ``__delitem__``: as
``py.js`` only handles expressions and these are accessed via the
``del`` statement, there would be no way to call them.
* ``__del__`` the lack of cross-platform GC hook means there is no way
to know when an object is deallocated.
* ``__slots__`` are not handled
* Dedicated (and deprecated) slicing special methods are unsupported
Missing features
----------------
These are Python features which are missing because they haven't been
implemented yet:
* Class-binding of descriptors doesn't currently work.
* Instance and subclass checks can't be customized
* "poor" comparison methods (``__cmp__`` and ``__rcmp__``) are not
supported and won't be falled-back to.
* ``__coerce__`` is currently supported
* Context managers are not currently supported
* Unbound methods are not supported, instance methods can only be
accessed from instances.

View file

@ -0,0 +1,161 @@
.. py.js documentation master file, created by
sphinx-quickstart on Sun Sep 9 19:36:23 2012.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
py.js, a Python expressions parser and evaluator
================================================
``py.js`` is a parser and evaluator of Python expressions, written in
pure javascript.
``py.js`` is not intended to implement a full Python interpreter, its
specification document is the `Python 2.7 Expressions spec
<http://docs.python.org/reference/expressions.html>`_ (along with the
lexical analysis part) as well as the Python builtins.
.. toctree::
:maxdepth: 2
builtins
types
utility
differences
Usage
-----
To evaluate a Python expression, simply call
:func:`py.eval`. :func:`py.eval` takes a mandatory Python expression
parameter, as a string, and an optional evaluation context (namespace
for the expression's free variables), and returns a javascript value::
> py.eval("t in ('a', 'b', 'c') and foo", {t: 'c', foo: true});
true
If the expression needs to be repeatedly evaluated, or the result of
the expression is needed in its "python" form without being converted
back to javascript, you can use the underlying triplet of functions
:func:`py.tokenize`, :func:`py.parse` and :func:`py.evaluate`
directly.
API
---
Core functions
++++++++++++++
.. function:: py.eval(expr[, context])
"Do everything" function, to use for one-shot evaluation of Python
expressions. Chains tokenizing, parsing and evaluating the
expression then :ref:`converts the result back to javascript
<convert-js>`
:param expr: Python expression to evaluate
:type expr: String
:param context: evaluation context for the expression's free
variables
:type context: Object
:returns: the expression's result, converted back to javascript
.. function:: py.tokenize(expr)
Expression tokenizer
:param expr: Python expression to tokenize
:type expr: String
:returns: token stream
.. function:: py.parse(tokens)
Parses a token stream and returns the corresponding parse tree.
The parse tree is stateless and can be memoized and reused for
frequently evaluated expressions.
:param tokens: token stream from :func:`py.tokenize`
:returns: parse tree
.. function:: py.evaluate(tree[, context])
Evaluates the expression represented by the provided parse tree,
using the provided context for the exprssion's free variables.
:param tree: parse tree returned by :func:`py.parse`
:param context: evaluation context
:returns: the "python object" resulting from the expression's
evaluation
:rtype: :class:`py.object`
.. _convert-py:
Conversions from Javascript to Python
+++++++++++++++++++++++++++++++++++++
``py.js`` will automatically attempt to convert non-:class:`py.object`
values into their ``py.js`` equivalent in the following situations:
* Values passed through the context of :func:`py.eval` or
:func:`py.evaluate`
* Attributes accessed directly on objects
* Values of mappings passed to :class:`py.dict`
Notably, ``py.js`` will *not* attempt an automatic conversion of
values returned by functions or methods, these must be
:class:`py.object` instances.
The automatic conversions performed by ``py.js`` are the following:
* ``null`` is converted to :data:`py.None`
* ``true`` is converted to :data:`py.True`
* ``false`` is converted to :data:`py.False`
* numbers are converted to :class:`py.float`
* strings are converted to :class:`py.str`
* functions are wrapped into :class:`py.PY_dev`
* ``Array`` instances are converted to :class:`py.list`
The rest generates an error, except for ``undefined`` which
specifically generates a ``NameError``.
.. _convert-js:
Conversions from Python to Javascript
+++++++++++++++++++++++++++++++++++++
py.js types (extensions of :js:class:`py.object`) can be converted
back to javascript by calling their :js:func:`py.object.toJSON`
method.
The default implementation raises an error, as arbitrary objects can
not be converted back to javascript.
Most built-in objects provide a :js:func:`py.object.toJSON`
implementation out of the box.
Javascript-level exceptions
+++++++++++++++++++++++++++
Javascript allows throwing arbitrary things, but runtimes don't seem
to provide any useful information (when they ever do) if what is
thrown isn't a direct instance of ``Error``. As a result, while
``py.js`` tries to match the exception-throwing semantics of Python it
only ever throws bare ``Error`` at the javascript-level. Instead, it
prefixes the error message with the name of the Python expression, a
colon, a space, and the actual message.
For instance, where Python would throw ``KeyError("'foo'")`` when
accessing an invalid key on a ``dict``, ``py.js`` will throw
``Error("KeyError: 'foo'")``.
.. _Python Data Model: http://docs.python.org/reference/datamodel.html

View file

@ -0,0 +1,190 @@
@ECHO OFF
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
set I18NSPHINXOPTS=%SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. singlehtml to make a single large HTML file
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
echo. texinfo to make Texinfo files
echo. gettext to make PO message catalogs
echo. changes to make an overview over all changed/added/deprecated items
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "singlehtml" (
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\pyjs.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\pyjs.ghc
goto end
)
if "%1" == "devhelp" (
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
if errorlevel 1 exit /b 1
echo.
echo.Build finished.
goto end
)
if "%1" == "epub" (
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The epub file is in %BUILDDIR%/epub.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "text" (
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The text files are in %BUILDDIR%/text.
goto end
)
if "%1" == "man" (
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The manual pages are in %BUILDDIR%/man.
goto end
)
if "%1" == "texinfo" (
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
goto end
)
if "%1" == "gettext" (
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
if errorlevel 1 exit /b 1
echo.
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
if errorlevel 1 exit /b 1
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
if errorlevel 1 exit /b 1
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
if errorlevel 1 exit /b 1
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
:end

View file

@ -0,0 +1,248 @@
Implementing a custom type
==========================
To implement a custom python-level type, one can use the
:func:`py.type` builtin. At the JS-level, it is a function with the
same signature as the :py:class:`type` builtin [#bases]_. It returns a
child type of its one base (or :py:class:`py.object` if no base is
provided).
The ``dict`` parameter to :func:`py.type` can contain any
attribute, javascript-level or python-level: the default
``__getattribute__`` implementation will ensure they are converted to
Python-level attributes if needed. Most methods are also wrapped and
converted to :ref:`types-methods-python`, although there are a number
of special cases:
* Most "magic methods" of the data model ("dunder" methods) remain
javascript-level. See :ref:`the listing of magic methods and their
signatures <types-methods-dunder>`. As a result, they do not respect
the :ref:`types-methods-python-call`
* The ``toJSON`` and ``fromJSON`` methods are special-cased to remain
javascript-level and don't follow the
:ref:`types-methods-python-call`
* Functions which have been wrapped explicitly (via
:class:`py.PY_def`, :py:class:`py.classmethod` or
:py:class:`py.staticmethod`) are associated to the class
untouched. But due to their wrapper, they will use the
:ref:`types-methods-python-call` anyway
.. _types-methods-python:
Python-level callable
---------------------
Wrapped javascript function *or* the :func:`__call__` method itself
follow the :ref:`types-methods-python-call`. As a result, they can't
(easily) be called directly from javascript code. Because
:func:`__new__` and :func:`__init__` follow from :func:`__call__`,
they also follow the :ref:`types-methods-python-call`.
:func:`py.PY_call` should be used when interacting with them from
javascript is necessary.
Because ``__call__`` follows the :ref:`types-methods-python-call`,
instantiating a ``py.js`` type from javascript requires using
:func:`py.PY_call`.
.. _types-methods-python-call:
Python calling conventions
++++++++++++++++++++++++++
The python-level arguments should be considered completely opaque,
they should be interacted with through :func:`py.PY_parseArgs` (to
extract python-level arguments to javascript implementation code) and
:func:`py.PY_call` (to call :ref:`types-methods-python` from
javascript code).
A callable following the :ref:`types-methods-python-call` *must*
return a ``py.js`` object, an error will be generated when failing to
do so.
.. todo:: arguments forwarding when e.g. overriding methods?
.. _types-methods-dunder:
Magic methods
-------------
``py.js`` doesn't support calling magic ("dunder") methods of the
datamodel from Python code, and these methods remain javascript-level
(they don't follow the :ref:`types-methods-python-call`).
Here is a list of the understood datamodel methods, refer to `the
relevant Python documentation
<http://docs.python.org/reference/datamodel.html?highlight=data%20model#special-method-names>`_
for their roles.
Basic customization
+++++++++++++++++++
.. function:: __hash__()
:returns: String
.. function:: __eq__(other)
The default implementation tests for identity
:param other: :py:class:`py.object` to compare this object with
:returns: :py:class:`py.bool`
.. function:: __ne__(other)
The default implementation calls :func:`__eq__` and reverses
its result.
:param other: :py:class:`py.object` to compare this object with
:returns: :py:class:`py.bool`
.. function:: __lt__(other)
The default implementation simply returns
:data:`py.NotImplemented`.
:param other: :py:class:`py.object` to compare this object with
:returns: :py:class:`py.bool`
.. function:: __le__(other)
The default implementation simply returns
:data:`py.NotImplemented`.
:param other: :py:class:`py.object` to compare this object with
:returns: :py:class:`py.bool`
.. function:: __ge__(other)
The default implementation simply returns
:data:`py.NotImplemented`.
:param other: :py:class:`py.object` to compare this object with
:returns: :py:class:`py.bool`
.. function:: __gt__(other)
The default implementation simply returns
:data:`py.NotImplemented`.
:param other: :py:class:`py.object` to compare this object with
:returns: :py:class:`py.bool`
.. function:: __str__()
Simply calls :func:`__unicode__`. This method should not be
overridden, :func:`__unicode__` should be overridden instead.
:returns: :py:class:`py.str`
.. function:: __unicode__()
:returns: :py:class:`py.unicode`
.. function:: __nonzero__()
The default implementation always returns :data:`py.True`
:returns: :py:class:`py.bool`
Customizing attribute access
++++++++++++++++++++++++++++
.. function:: __getattribute__(name)
:param String name: name of the attribute, as a javascript string
:returns: :py:class:`py.object`
.. function:: __getattr__(name)
:param String name: name of the attribute, as a javascript string
:returns: :py:class:`py.object`
.. function:: __setattr__(name, value)
:param String name: name of the attribute, as a javascript string
:param value: :py:class:`py.object`
Implementing descriptors
++++++++++++++++++++++++
.. function:: __get__(instance)
.. note:: readable descriptors don't currently handle "owner
classes"
:param instance: :py:class:`py.object`
:returns: :py:class:`py.object`
.. function:: __set__(instance, value)
:param instance: :py:class:`py.object`
:param value: :py:class:`py.object`
Emulating Numeric Types
+++++++++++++++++++++++
* Non-in-place binary numeric methods (e.g. ``__add__``, ``__mul__``,
...) should all be supported including reversed calls (in case the
primary call is not available or returns
:py:data:`py.NotImplemented`). They take a single
:py:class:`py.object` parameter and return a single
:py:class:`py.object` parameter.
* Unary operator numeric methods are all supported:
.. function:: __pos__()
:returns: :py:class:`py.object`
.. function:: __neg__()
:returns: :py:class:`py.object`
.. function:: __invert__()
:returns: :py:class:`py.object`
* For non-operator numeric methods, support is contingent on the
corresponding :ref:`builtins <builtins>` being implemented
Emulating container types
+++++++++++++++++++++++++
.. function:: __len__()
:returns: :py:class:`py.int`
.. function:: __getitem__(name)
:param name: :py:class:`py.object`
:returns: :py:class:`py.object`
.. function:: __setitem__(name, value)
:param name: :py:class:`py.object`
:param value: :py:class:`py.object`
.. function:: __iter__()
:returns: :py:class:`py.object`
.. function:: __reversed__()
:returns: :py:class:`py.object`
.. function:: __contains__(other)
:param other: :py:class:`py.object`
:returns: :py:class:`py.bool`
.. [#bases] with the limitation that, because :ref:`py.js builds its
object model on top of javascript's
<details-object-model>`, only one base is allowed.

View file

@ -0,0 +1,248 @@
Utility functions for interacting with ``py.js`` objects
========================================================
Essentially the ``py.js`` version of the Python C API, these functions
are used to implement new ``py.js`` types or to interact with existing
ones.
They are prefixed with ``PY_``.
.. function:: py.PY_parseArgs(arguments, format)
Arguments parser converting from the :ref:`user-defined calling
conventions <types-methods-python-call>` to a JS object mapping
argument names to values. It serves the same role as
`PyArg_ParseTupleAndKeywords`_.
::
var args = py.PY_parseArgs(
arguments, ['foo', 'bar', ['baz', 3], ['qux', "foo"]]);
roughly corresponds to the argument spec:
.. code-block:: python
def func(foo, bar, baz=3, qux="foo"):
pass
.. note:: a significant difference is that "default values" will
be re-evaluated at each call, since they are within the
function.
:param arguments: array-like objects holding the args and kwargs
passed to the callable, generally the
``arguments`` of the caller.
:param format: mapping declaration to the actual arguments of the
function. A javascript array composed of five
possible types of elements:
* The literal string ``'*'`` marks all following
parameters as keyword-only, regardless of them
having a default value or not [#kwonly]_. Can
only be present once in the parameters list.
* A string prefixed by ``*``, marks the positional
variadic parameter for the function: gathers all
provided positional arguments left and makes all
following parameters keyword-only
[#star-args]_. ``*args`` is incompatible with
``*``.
* A string prefixed with ``**``, marks the
positional keyword variadic parameter for the
function: gathers all provided keyword arguments
left and closes the argslist. If present, this
must be the last parameter of the format list.
* A string defines a required parameter, accessible
positionally or through keyword
* A pair of ``[String, py.object]`` defines an
optional parameter and its default value.
For simplicity, when not using optional parameters
it is possible to use a simple string as the format
(using space-separated elements). The string will
be split on whitespace and processed as a normal
format array.
:returns: a javascript object mapping argument names to values
:raises: ``TypeError`` if the provided arguments don't match the
format
.. class:: py.PY_def(fn)
Type wrapping javascript functions into py.js callables. The
wrapped function follows :ref:`the py.js calling conventions
<types-methods-python-call>`
:param Function fn: the javascript function to wrap
:returns: a callable py.js object
Object Protocol
---------------
.. function:: py.PY_hasAttr(o, attr_name)
Returns ``true`` if ``o`` has the attribute ``attr_name``,
otherwise returns ``false``. Equivalent to Python's ``hasattr(o,
attr_name)``
:param o: A :class:`py.object`
:param attr_name: a javascript ``String``
:rtype: ``Boolean``
.. function:: py.PY_getAttr(o, attr_name)
Retrieve an attribute ``attr_name`` from the object ``o``. Returns
the attribute value on success, raises ``AttributeError`` on
failure. Equivalent to the python expression ``o.attr_name``.
:param o: A :class:`py.object`
:param attr_name: a javascript ``String``
:returns: A :class:`py.object`
:raises: ``AttributeError``
.. function:: py.PY_str(o)
Computes a string representation of ``o``, returns the string
representation. Equivalent to ``str(o)``
:param o: A :class:`py.object`
:returns: :class:`py.str`
.. function:: py.PY_isInstance(inst, cls)
Returns ``true`` if ``inst`` is an instance of ``cls``, ``false``
otherwise.
.. function:: py.PY_isSubclass(derived, cls)
Returns ``true`` if ``derived`` is ``cls`` or a subclass thereof.
.. function:: py.PY_call(callable[, args][, kwargs])
Call an arbitrary python-level callable from javascript.
:param callable: A ``py.js`` callable object (broadly speaking,
either a class or an object with a ``__call__``
method)
:param args: javascript Array of :class:`py.object`, used as
positional arguments to ``callable``
:param kwargs: javascript Object mapping names to
:class:`py.object`, used as named arguments to
``callable``
:returns: nothing or :class:`py.object`
.. function:: py.PY_isTrue(o)
Returns ``true`` if the object is considered truthy, ``false``
otherwise. Equivalent to ``bool(o)``.
:param o: A :class:`py.object`
:rtype: Boolean
.. function:: py.PY_not(o)
Inverse of :func:`py.PY_isTrue`.
.. function:: py.PY_size(o)
If ``o`` is a sequence or mapping, returns its length. Otherwise,
raises ``TypeError``.
:param o: A :class:`py.object`
:returns: ``Number``
:raises: ``TypeError`` if the object doesn't have a length
.. function:: py.PY_getItem(o, key)
Returns the element of ``o`` corresponding to the object
``key``. This is equivalent to ``o[key]``.
:param o: :class:`py.object`
:param key: :class:`py.object`
:returns: :class:`py.object`
:raises: ``TypeError`` if ``o`` does not support the operation, if
``key`` or the return value is not a :class:`py.object`
.. function:: py.PY_setItem(o, key, v)
Maps the object ``key`` to the value ``v`` in ``o``. Equivalent to
``o[key] = v``.
:param o: :class:`py.object`
:param key: :class:`py.object`
:param v: :class:`py.object`
:raises: ``TypeError`` if ``o`` does not support the operation, or
if ``key`` or ``v`` are not :class:`py.object`
Number Protocol
---------------
.. function:: py.PY_add(o1, o2)
Returns the result of adding ``o1`` and ``o2``, equivalent to
``o1 + o2``.
:param o1: :class:`py.object`
:param o2: :class:`py.object`
:returns: :class:`py.object`
.. function:: py.PY_subtract(o1, o2)
Returns the result of subtracting ``o2`` from ``o1``, equivalent
to ``o1 - o2``.
:param o1: :class:`py.object`
:param o2: :class:`py.object`
:returns: :class:`py.object`
.. function:: py.PY_multiply(o1, o2)
Returns the result of multiplying ``o1`` by ``o2``, equivalent to
``o1 * o2``.
:param o1: :class:`py.object`
:param o2: :class:`py.object`
:returns: :class:`py.object`
.. function:: py.PY_divide(o1, o2)
Returns the result of dividing ``o1`` by ``o2``, equivalent to
``o1 / o2``.
:param o1: :class:`py.object`
:param o2: :class:`py.object`
:returns: :class:`py.object`
.. function:: py.PY_negative(o)
Returns the negation of ``o``, equivalent to ``-o``.
:param o: :class:`py.object`
:returns: :class:`py.object`
.. function:: py.PY_positive(o)
Returns the "positive" of ``o``, equivalent to ``+o``.
:param o: :class:`py.object`
:returns: :class:`py.object`
.. [#kwonly] Python 2, which py.js currently implements, does not
support Python-level keyword-only parameters (it can be
done through the C-API), but it seemed neat and easy
enough so there.
.. [#star-args] due to this and contrary to Python 2, py.js allows
arguments other than ``**kwargs`` to follow ``*args``.
.. _PyArg_ParseTupleAndKeywords:
http://docs.python.org/c-api/arg.html#PyArg_ParseTupleAndKeywords