Merge branch 'master' of github.com:adafruit/circuitpython
This commit is contained in:
commit
90a09dba59
@ -6,13 +6,16 @@ PYTHON = python3
|
|||||||
SPHINXOPTS =
|
SPHINXOPTS =
|
||||||
SPHINXBUILD = sphinx-build
|
SPHINXBUILD = sphinx-build
|
||||||
PAPER =
|
PAPER =
|
||||||
BUILDDIR = build/$(MICROPY_PORT)
|
# path to build the generated docs
|
||||||
CPYDIFFDIR = ../tools
|
BUILDDIR = _build
|
||||||
CPYDIFF = gen-cpydiff.py
|
# path to source files to process
|
||||||
GENRSTDIR = genrst
|
SOURCEDIR = .
|
||||||
|
# path to conf.py
|
||||||
|
CONFDIR = .
|
||||||
# Run "make FORCE= ..." to avoid rebuilding from scratch (and risk
|
# Run "make FORCE= ..." to avoid rebuilding from scratch (and risk
|
||||||
# producing incorrect docs).
|
# producing incorrect docs).
|
||||||
FORCE = -E
|
FORCE = -E
|
||||||
|
VERBOSE = -v
|
||||||
|
|
||||||
# User-friendly check for sphinx-build
|
# User-friendly check for sphinx-build
|
||||||
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
|
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
|
||||||
@ -22,9 +25,10 @@ endif
|
|||||||
# Internal variables.
|
# Internal variables.
|
||||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||||
PAPEROPT_letter = -D latex_paper_size=letter
|
PAPEROPT_letter = -D latex_paper_size=letter
|
||||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
BASEOPTS = -c $(CONFDIR) $(PAPEROPT_$(PAPER)) $(FORCE) $(VERBOSE) $(SPHINXOPTS) $(SOURCEDIR)
|
||||||
|
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(BASEOPTS)
|
||||||
# the i18n builder cannot share the environment and doctrees with the others
|
# the i18n builder cannot share the environment and doctrees with the others
|
||||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
I18NSPHINXOPTS = $(BASEOPTS)
|
||||||
|
|
||||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
|
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
|
||||||
|
|
||||||
@ -52,19 +56,12 @@ help:
|
|||||||
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
|
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
|
||||||
@echo " linkcheck to check all external links for integrity"
|
@echo " linkcheck to check all external links for integrity"
|
||||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||||
@echo " cpydiff to generate the MicroPython differences from CPython"
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(BUILDDIR)/*
|
rm -rf $(BUILDDIR)/*
|
||||||
rm -f $(GENRSTDIR)/*
|
|
||||||
|
|
||||||
cpydiff:
|
html:
|
||||||
@echo "Generating MicroPython Differences."
|
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||||
rm -f $(GENRSTDIR)/*
|
|
||||||
cd $(CPYDIFFDIR) && $(PYTHON) $(CPYDIFF)
|
|
||||||
|
|
||||||
html: cpydiff
|
|
||||||
$(SPHINXBUILD) $(FORCE) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
|
||||||
@echo
|
@echo
|
||||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||||
|
|
||||||
@ -117,30 +114,34 @@ epub:
|
|||||||
@echo
|
@echo
|
||||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||||
|
|
||||||
latex: cpydiff
|
latex:
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||||
@echo
|
@echo
|
||||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||||
"(use \`make latexpdf' here to do that automatically)."
|
"(use \`make latexpdf' here to do that automatically)."
|
||||||
|
|
||||||
latexpdf: cpydiff
|
# seems to be malfunctioning
|
||||||
$(SPHINXBUILD) $(FORCE) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
latexpdf:
|
||||||
|
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||||
@echo "Running LaTeX files through pdflatex..."
|
@echo "Running LaTeX files through pdflatex..."
|
||||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||||
|
|
||||||
latexpdfja: cpydiff
|
# seems to be malfunctioning
|
||||||
|
latexpdfja:
|
||||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
@echo "Running LaTeX files through platex and dvipdfmx..."
|
||||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
||||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||||
|
|
||||||
|
# seems to be malfunctioning
|
||||||
text:
|
text:
|
||||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||||
@echo
|
@echo
|
||||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||||
|
|
||||||
|
# seems to be malfunctioning
|
||||||
man:
|
man:
|
||||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||||
@echo
|
@echo
|
22
README.rst
22
README.rst
@ -31,11 +31,14 @@ Designed for CircuitPython
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
- `Adafruit CircuitPlayground
|
- `Adafruit CircuitPlayground
|
||||||
Express <https://www.adafruit.com/product/3333>`__
|
Express <https://www.adafruit.com/product/3333>`__ (`CircuitPython Guide <https://learn.adafruit.com/adafruit-circuit-playground-express/circuitpython-quickstart>`__)
|
||||||
- `Adafruit Feather M0
|
- `Adafruit Feather M0
|
||||||
Express <https://www.adafruit.com/product/3403>`__
|
Express <https://www.adafruit.com/product/3403>`__ (`CircuitPython Guide <https://learn.adafruit.com/adafruit-feather-m0-express-designed-for-circuit-python-circuitpython/kattni-circuitpython>`__)
|
||||||
- `Adafruit Metro M0 Express <https://www.adafruit.com/product/3505>`__
|
- `Adafruit Metro M0 Express <https://www.adafruit.com/product/3505>`_ (`CircuitPython Guide <https://learn.adafruit.com/adafruit-metro-m0-express-designed-for-circuitpython/circuitpython>`__)
|
||||||
- `Adafruit Gemma M0 <https://www.adafruit.com/product/3501>`__
|
- `Adafruit Gemma M0 <https://www.adafruit.com/product/3501>`__ (`CircuitPython Guide <https://learn.adafruit.com/adafruit-gemma-m0/circuitpython>`__)
|
||||||
|
- `Adafruit ItsyBitsy M0 Express <https://www.adafruit.com/product/3727>`_ (no CircuitPython Guide yet!)
|
||||||
|
- `Adafruit Trinket M0 <https://www.adafruit.com/product/3500>`__ (`CircuitPython Guide <https://learn.adafruit.com/adafruit-trinket-m0-circuitpython-arduino/circuitpython>`__)
|
||||||
|
- `Adafruit Metro M4 <https://www.adafruit.com/product/3382>`__ (`CircuitPython Guide <https://learn.adafruit.com/adafruit-metro-m4-express-featuring-atsamd51/overview>`__)
|
||||||
|
|
||||||
Other
|
Other
|
||||||
~~~~~
|
~~~~~
|
||||||
@ -69,8 +72,15 @@ System <https://learn.adafruit.com/>`__ under the `CircuitPython
|
|||||||
category <https://learn.adafruit.com/category/circuitpython>`__ and
|
category <https://learn.adafruit.com/category/circuitpython>`__ and
|
||||||
`MicroPython
|
`MicroPython
|
||||||
category <https://learn.adafruit.com/category/micropython>`__. An API
|
category <https://learn.adafruit.com/category/micropython>`__. An API
|
||||||
reference is also available on `Read the
|
reference is also available on `Read the Docs
|
||||||
Docs <http://circuitpython.readthedocs.io/en/latest/?>`__.
|
<http://circuitpython.readthedocs.io/en/latest/?>`__. A collection of awesome
|
||||||
|
resources can be found at `Awesome CircuitPython <https://github.com/adafruit/awesome-circuitpython>`__.
|
||||||
|
|
||||||
|
Specifically useful documentation when starting out:
|
||||||
|
|
||||||
|
- `Welcome to CircuitPython <https://learn.adafruit.com/welcome-to-circuitpython>`__
|
||||||
|
- `CircuitPython Essentials <https://learn.adafruit.com/circuitpython-essentials>`__
|
||||||
|
- `Example Code <https://github.com/adafruit/Adafruit_Learning_System_Guides/tree/master/CircuitPython_Essentials>`__
|
||||||
|
|
||||||
Contributing
|
Contributing
|
||||||
------------
|
------------
|
||||||
|
@ -22,6 +22,27 @@ preferably in a virtualenv:
|
|||||||
|
|
||||||
In `circuitpython/`, build the docs:
|
In `circuitpython/`, build the docs:
|
||||||
|
|
||||||
sphinx-build -v -b html . _build/html
|
make html
|
||||||
|
|
||||||
You'll find the index page at `_build/html/index.html`.
|
You'll find the index page at `_build/html/index.html`.
|
||||||
|
|
||||||
|
### More flexibility
|
||||||
|
|
||||||
|
Running `make` by itself will list out the multiple doc generating commands available.
|
||||||
|
|
||||||
|
All commands will, by default, run with `-E` (forces a rebuild from scratch of docs) and `-v` (verbosity level 1). This can be customized as desired:
|
||||||
|
|
||||||
|
# will turn OFF the force rebuild
|
||||||
|
make html FORCE=
|
||||||
|
|
||||||
|
# will turn OFF the verbosity
|
||||||
|
make html VERBOSE=
|
||||||
|
|
||||||
|
# will turn OFF the force rebuild and make it doubly verbose when running
|
||||||
|
make html FORCE= VERBOSE="-v -v"
|
||||||
|
|
||||||
|
You can also pass other options to sphinx by using `SPHINXOPTS`.
|
||||||
|
|
||||||
|
make html SPHINXOPTS="-T"
|
||||||
|
|
||||||
|
For more flexibility and customization, take a look at the Makefile for all variables you can pass in and overwrite.
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
:mod:`ucollections` -- collection and container types
|
:mod:`collections` -- collection and container types
|
||||||
=====================================================
|
=====================================================
|
||||||
|
|
||||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
.. include:: ../templates/unsupported_in_circuitpython.inc
|
||||||
|
|
||||||
.. module:: ucollections
|
.. module:: collections
|
||||||
:synopsis: collection and container types
|
:synopsis: collection and container types
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:collections`.
|
|see_cpython_module| :mod:`cpython:collections`.
|
||||||
@ -24,7 +24,7 @@ Classes
|
|||||||
a string with space-separated field named (but this is less efficient).
|
a string with space-separated field named (but this is less efficient).
|
||||||
Example of use::
|
Example of use::
|
||||||
|
|
||||||
from ucollections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
MyTuple = namedtuple("MyTuple", ("id", "name"))
|
MyTuple = namedtuple("MyTuple", ("id", "name"))
|
||||||
t1 = MyTuple(1, "foo")
|
t1 = MyTuple(1, "foo")
|
||||||
@ -38,7 +38,7 @@ Classes
|
|||||||
added. When ordered dict is iterated over, keys/items are returned in
|
added. When ordered dict is iterated over, keys/items are returned in
|
||||||
the order they were added::
|
the order they were added::
|
||||||
|
|
||||||
from ucollections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
# To make benefit of ordered keys, OrderedDict should be initialized
|
# To make benefit of ordered keys, OrderedDict should be initialized
|
||||||
# from sequence of (key, value) pairs.
|
# from sequence of (key, value) pairs.
|
@ -21,7 +21,7 @@ Python standard libraries and micro-libraries
|
|||||||
gc.rst
|
gc.rst
|
||||||
sys.rst
|
sys.rst
|
||||||
binascii.rst
|
binascii.rst
|
||||||
ucollections.rst
|
collections.rst
|
||||||
uerrno.rst
|
uerrno.rst
|
||||||
hashlib.rst
|
hashlib.rst
|
||||||
uheapq.rst
|
uheapq.rst
|
||||||
|
@ -188,6 +188,8 @@ extern const struct _mp_obj_module_t usb_hid_module;
|
|||||||
#define MICROPY_PY_BUILTINS_FROZENSET (1)
|
#define MICROPY_PY_BUILTINS_FROZENSET (1)
|
||||||
#define MICROPY_PY_BUILTINS_STR_SPLITLINES (1)
|
#define MICROPY_PY_BUILTINS_STR_SPLITLINES (1)
|
||||||
#define MICROPY_PY_BUILTINS_REVERSED (1)
|
#define MICROPY_PY_BUILTINS_REVERSED (1)
|
||||||
|
#define MICROPY_PY_UERRNO (1)
|
||||||
|
#define MICROPY_PY_UERRNO_ERRORCODE (0)
|
||||||
#define MICROPY_PY_URE (1)
|
#define MICROPY_PY_URE (1)
|
||||||
#define MICROPY_PY_MICROPYTHON_MEM_INFO (1)
|
#define MICROPY_PY_MICROPYTHON_MEM_INFO (1)
|
||||||
#define MICROPY_PY_FRAMEBUF (1)
|
#define MICROPY_PY_FRAMEBUF (1)
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#if MICROPY_PY_COLLECTIONS
|
#if MICROPY_PY_COLLECTIONS
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t mp_module_collections_globals_table[] = {
|
STATIC const mp_rom_map_elem_t mp_module_collections_globals_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ucollections) },
|
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_collections) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_namedtuple), MP_ROM_PTR(&mp_namedtuple_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_namedtuple), MP_ROM_PTR(&mp_namedtuple_obj) },
|
||||||
#if MICROPY_PY_COLLECTIONS_ORDEREDDICT
|
#if MICROPY_PY_COLLECTIONS_ORDEREDDICT
|
||||||
{ MP_ROM_QSTR(MP_QSTR_OrderedDict), MP_ROM_PTR(&mp_type_ordereddict) },
|
{ MP_ROM_QSTR(MP_QSTR_OrderedDict), MP_ROM_PTR(&mp_type_ordereddict) },
|
||||||
|
@ -100,6 +100,20 @@ const mp_obj_module_t mp_module_uerrno = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
qstr mp_errno_to_str(mp_obj_t errno_val) {
|
qstr mp_errno_to_str(mp_obj_t errno_val) {
|
||||||
|
// For commonly encountered errors, return human readable strings
|
||||||
|
if (MP_OBJ_IS_SMALL_INT(errno_val)) {
|
||||||
|
switch (MP_OBJ_SMALL_INT_VALUE(errno_val)) {
|
||||||
|
case EPERM: return MP_QSTR_Permission_space_denied;
|
||||||
|
case ENOENT: return MP_QSTR_No_space_such_space_file_slash_directory;
|
||||||
|
case EIO: return MP_QSTR_Input_slash_output_space_error;
|
||||||
|
case EACCES: return MP_QSTR_Permission_space_denied;
|
||||||
|
case EEXIST: return MP_QSTR_File_space_exists;
|
||||||
|
case ENODEV: return MP_QSTR_Unsupported_space_operation;
|
||||||
|
case EINVAL: return MP_QSTR_Invalid_space_argument;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, return the Exxxx string for that error code
|
||||||
#if MICROPY_PY_UERRNO_ERRORCODE
|
#if MICROPY_PY_UERRNO_ERRORCODE
|
||||||
// We have the errorcode dict so can do a lookup using the hash map
|
// We have the errorcode dict so can do a lookup using the hash map
|
||||||
mp_map_elem_t *elem = mp_map_lookup((mp_map_t*)&errorcode_dict.map, errno_val, MP_MAP_LOOKUP);
|
mp_map_elem_t *elem = mp_map_lookup((mp_map_t*)&errorcode_dict.map, errno_val, MP_MAP_LOOKUP);
|
||||||
|
@ -151,7 +151,7 @@ STATIC const mp_rom_map_elem_t mp_builtin_module_table[] = {
|
|||||||
{ MP_ROM_QSTR(MP_QSTR_uio), MP_ROM_PTR(&mp_module_io) },
|
{ MP_ROM_QSTR(MP_QSTR_uio), MP_ROM_PTR(&mp_module_io) },
|
||||||
#endif
|
#endif
|
||||||
#if MICROPY_PY_COLLECTIONS
|
#if MICROPY_PY_COLLECTIONS
|
||||||
{ MP_ROM_QSTR(MP_QSTR_ucollections), MP_ROM_PTR(&mp_module_collections) },
|
{ MP_ROM_QSTR(MP_QSTR_collections), MP_ROM_PTR(&mp_module_collections) },
|
||||||
#endif
|
#endif
|
||||||
#if MICROPY_PY_STRUCT
|
#if MICROPY_PY_STRUCT
|
||||||
{ MP_ROM_QSTR(MP_QSTR_ustruct), MP_ROM_PTR(&mp_module_ustruct) },
|
{ MP_ROM_QSTR(MP_QSTR_ustruct), MP_ROM_PTR(&mp_module_ustruct) },
|
||||||
|
@ -5,11 +5,8 @@
|
|||||||
try:
|
try:
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
print("SKIP")
|
||||||
from ucollections import namedtuple
|
raise SystemExit
|
||||||
except ImportError:
|
|
||||||
print("SKIP")
|
|
||||||
raise SystemExit
|
|
||||||
|
|
||||||
import skip_if
|
import skip_if
|
||||||
skip_if.no_cpython_compat()
|
skip_if.no_cpython_compat()
|
||||||
|
@ -11,7 +11,10 @@ print(type(uerrno.EIO))
|
|||||||
|
|
||||||
# check that errors are rendered in a nice way
|
# check that errors are rendered in a nice way
|
||||||
msg = str(OSError(uerrno.EIO))
|
msg = str(OSError(uerrno.EIO))
|
||||||
print(msg[:7], msg[-5:])
|
print(msg[:7], msg[msg.find(']'):])
|
||||||
|
|
||||||
|
msg = str(OSError(uerrno.ENOBUFS))
|
||||||
|
print(msg[:7], msg[msg.find(']'):])
|
||||||
|
|
||||||
# check that unknown errno is still rendered
|
# check that unknown errno is still rendered
|
||||||
print(str(OSError(9999)))
|
print(str(OSError(9999)))
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
<class 'int'>
|
<class 'int'>
|
||||||
[Errno ] EIO
|
[Errno ] Input/output error
|
||||||
|
[Errno ] ENOBUFS
|
||||||
9999
|
9999
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
try:
|
try:
|
||||||
try:
|
from collections import namedtuple
|
||||||
from collections import namedtuple
|
|
||||||
except ImportError:
|
|
||||||
from ucollections import namedtuple
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print("SKIP")
|
print("SKIP")
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
|
@ -2,10 +2,7 @@ import skip_if
|
|||||||
skip_if.no_cpython_compat()
|
skip_if.no_cpython_compat()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
try:
|
from collections import namedtuple
|
||||||
from collections import namedtuple
|
|
||||||
except ImportError:
|
|
||||||
from ucollections import namedtuple
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
skip_if.skip()
|
skip_if.skip()
|
||||||
|
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
try:
|
try:
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
print("SKIP")
|
||||||
from ucollections import OrderedDict
|
raise SystemExit
|
||||||
except ImportError:
|
|
||||||
print("SKIP")
|
|
||||||
raise SystemExit
|
|
||||||
|
|
||||||
d = OrderedDict([(10, 20), ("b", 100), (1, 2)])
|
d = OrderedDict([(10, 20), ("b", 100), (1, 2)])
|
||||||
print(len(d))
|
print(len(d))
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
try:
|
try:
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
print("SKIP")
|
||||||
from ucollections import OrderedDict
|
raise SystemExit
|
||||||
except ImportError:
|
|
||||||
print("SKIP")
|
|
||||||
raise SystemExit
|
|
||||||
|
|
||||||
x = OrderedDict()
|
x = OrderedDict()
|
||||||
y = OrderedDict()
|
y = OrderedDict()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import bench
|
import bench
|
||||||
from ucollections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
T = namedtuple("Tup", ["num", "bar"])
|
T = namedtuple("Tup", ["num", "bar"])
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import bench
|
import bench
|
||||||
from ucollections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
T = namedtuple("Tup", ["foo1", "foo2", "foo3", "foo4", "num"])
|
T = namedtuple("Tup", ["foo1", "foo2", "foo3", "foo4", "num"])
|
||||||
|
|
||||||
|
@ -68,10 +68,7 @@ def board_not_in(*board):
|
|||||||
|
|
||||||
def no_cpython_compat():
|
def no_cpython_compat():
|
||||||
try:
|
try:
|
||||||
try:
|
from collections import namedtuple
|
||||||
from collections import namedtuple
|
|
||||||
except ImportError:
|
|
||||||
from ucollections import namedtuple
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
skip()
|
skip()
|
||||||
try:
|
try:
|
||||||
|
@ -1,226 +0,0 @@
|
|||||||
# This file is part of the MicroPython project, http://micropython.org/
|
|
||||||
#
|
|
||||||
# The MIT License (MIT)
|
|
||||||
#
|
|
||||||
# Copyright (c) 2016 Rami Ali
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
|
||||||
# in the Software without restriction, including without limitation the rights
|
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
|
||||||
# furnished to do so, subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be included in
|
|
||||||
# all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
|
|
||||||
""" gen-cpydiff generates documentation which outlines operations that differ between MicroPython
|
|
||||||
and CPython. This script is called by the docs Makefile for html and Latex and may be run
|
|
||||||
manually using the command make gen-cpydiff. """
|
|
||||||
|
|
||||||
import os
|
|
||||||
import errno
|
|
||||||
import subprocess
|
|
||||||
import time
|
|
||||||
import re
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
# MicroPython supports syntax of CPython 3.4 with some features from 3.5, and
|
|
||||||
# such version should be used to test for differences. If your default python3
|
|
||||||
# executable is of lower version, you can point MICROPY_CPYTHON3 environment var
|
|
||||||
# to the correct executable.
|
|
||||||
if os.name == 'nt':
|
|
||||||
CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3.exe')
|
|
||||||
MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../windows/micropython.exe')
|
|
||||||
else:
|
|
||||||
CPYTHON3 = os.getenv('MICROPY_CPYTHON3', 'python3')
|
|
||||||
MICROPYTHON = os.getenv('MICROPY_MICROPYTHON', '../unix/micropython')
|
|
||||||
|
|
||||||
TESTPATH = '../tests/cpydiff/'
|
|
||||||
DOCPATH = '../docs/genrst/'
|
|
||||||
INDEXTEMPLATE = '../docs/differences/index_template.txt'
|
|
||||||
INDEX = 'index.rst'
|
|
||||||
|
|
||||||
HEADER = '.. This document was generated by tools/gen-cpydiff.py\n\n'
|
|
||||||
UIMPORTLIST = {'struct', 'collections', 'json'}
|
|
||||||
CLASSMAP = {'Core': 'Core Language', 'Types': 'Builtin Types'}
|
|
||||||
INDEXPRIORITY = ['syntax', 'core_language', 'builtin_types', 'modules']
|
|
||||||
RSTCHARS = ['=', '-', '~', '`', ':']
|
|
||||||
SPLIT = '"""\n|categories: |description: |cause: |workaround: '
|
|
||||||
TAB = ' '
|
|
||||||
|
|
||||||
Output = namedtuple('output', ['name', 'class_', 'desc', 'cause', 'workaround', 'code',
|
|
||||||
'output_cpy', 'output_upy', 'status'])
|
|
||||||
|
|
||||||
def readfiles():
|
|
||||||
""" Reads test files """
|
|
||||||
tests = list(filter(lambda x: x.endswith('.py'), os.listdir(TESTPATH)))
|
|
||||||
tests.sort()
|
|
||||||
files = []
|
|
||||||
|
|
||||||
for test in tests:
|
|
||||||
text = open(TESTPATH + test, 'r').read()
|
|
||||||
|
|
||||||
try:
|
|
||||||
class_, desc, cause, workaround, code = [x.rstrip() for x in \
|
|
||||||
list(filter(None, re.split(SPLIT, text)))]
|
|
||||||
output = Output(test, class_, desc, cause, workaround, code, '', '', '')
|
|
||||||
files.append(output)
|
|
||||||
except IndexError:
|
|
||||||
print('Incorrect format in file ' + TESTPATH + test)
|
|
||||||
|
|
||||||
return files
|
|
||||||
|
|
||||||
def uimports(code):
|
|
||||||
""" converts CPython module names into MicroPython equivalents """
|
|
||||||
for uimport in UIMPORTLIST:
|
|
||||||
uimport = bytes(uimport, 'utf8')
|
|
||||||
code = code.replace(uimport, b'u' + uimport)
|
|
||||||
return code
|
|
||||||
|
|
||||||
def run_tests(tests):
|
|
||||||
""" executes all tests """
|
|
||||||
results = []
|
|
||||||
for test in tests:
|
|
||||||
with open(TESTPATH + test.name, 'rb') as f:
|
|
||||||
input_cpy = f.read()
|
|
||||||
input_upy = uimports(input_cpy)
|
|
||||||
|
|
||||||
process = subprocess.Popen(CPYTHON3, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
output_cpy = [com.decode('utf8') for com in process.communicate(input_cpy)]
|
|
||||||
|
|
||||||
process = subprocess.Popen(MICROPYTHON, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
output_upy = [com.decode('utf8') for com in process.communicate(input_upy)]
|
|
||||||
|
|
||||||
if output_cpy[0] == output_upy[0] and output_cpy[1] == output_upy[1]:
|
|
||||||
status = 'Supported'
|
|
||||||
print('Supported operation!\nFile: ' + TESTPATH + test.name)
|
|
||||||
else:
|
|
||||||
status = 'Unsupported'
|
|
||||||
|
|
||||||
output = Output(test.name, test.class_, test.desc, test.cause,
|
|
||||||
test.workaround, test.code, output_cpy, output_upy, status)
|
|
||||||
results.append(output)
|
|
||||||
|
|
||||||
results.sort(key=lambda x: x.class_)
|
|
||||||
return results
|
|
||||||
|
|
||||||
def indent(block, spaces):
|
|
||||||
""" indents paragraphs of text for rst formatting """
|
|
||||||
new_block = ''
|
|
||||||
for line in block.split('\n'):
|
|
||||||
new_block += spaces + line + '\n'
|
|
||||||
return new_block
|
|
||||||
|
|
||||||
def gen_table(contents):
|
|
||||||
""" creates a table given any set of columns """
|
|
||||||
xlengths = []
|
|
||||||
ylengths = []
|
|
||||||
for column in contents:
|
|
||||||
col_len = 0
|
|
||||||
for entry in column:
|
|
||||||
lines = entry.split('\n')
|
|
||||||
for line in lines:
|
|
||||||
col_len = max(len(line) + 2, col_len)
|
|
||||||
xlengths.append(col_len)
|
|
||||||
for i in range(len(contents[0])):
|
|
||||||
ymax = 0
|
|
||||||
for j in range(len(contents)):
|
|
||||||
ymax = max(ymax, len(contents[j][i].split('\n')))
|
|
||||||
ylengths.append(ymax)
|
|
||||||
|
|
||||||
table_divider = '+' + ''.join(['-' * i + '+' for i in xlengths]) + '\n'
|
|
||||||
table = table_divider
|
|
||||||
for i in range(len(ylengths)):
|
|
||||||
row = [column[i] for column in contents]
|
|
||||||
row = [entry + '\n' * (ylengths[i]-len(entry.split('\n'))) for entry in row]
|
|
||||||
row = [entry.split('\n') for entry in row]
|
|
||||||
for j in range(ylengths[i]):
|
|
||||||
k = 0
|
|
||||||
for entry in row:
|
|
||||||
width = xlengths[k]
|
|
||||||
table += ''.join(['| {:{}}'.format(entry[j], width - 1)])
|
|
||||||
k += 1
|
|
||||||
table += '|\n'
|
|
||||||
table += table_divider
|
|
||||||
return table + '\n'
|
|
||||||
|
|
||||||
def gen_rst(results):
|
|
||||||
""" creates restructured text documents to display tests """
|
|
||||||
|
|
||||||
# make sure the destination directory exists
|
|
||||||
try:
|
|
||||||
os.mkdir(DOCPATH)
|
|
||||||
except OSError as e:
|
|
||||||
if e.args[0] != errno.EEXIST and e.args[0] != errno.EISDIR:
|
|
||||||
raise
|
|
||||||
|
|
||||||
toctree = []
|
|
||||||
class_ = []
|
|
||||||
for output in results:
|
|
||||||
section = output.class_.split(',')
|
|
||||||
for i in range(len(section)):
|
|
||||||
section[i] = section[i].rstrip()
|
|
||||||
if section[i] in CLASSMAP:
|
|
||||||
section[i] = CLASSMAP[section[i]]
|
|
||||||
if i >= len(class_) or section[i] != class_[i]:
|
|
||||||
if i == 0:
|
|
||||||
filename = section[i].replace(' ', '_').lower()
|
|
||||||
rst = open(DOCPATH + filename + '.rst', 'w')
|
|
||||||
rst.write(HEADER)
|
|
||||||
rst.write(section[i] + '\n')
|
|
||||||
rst.write(RSTCHARS[0] * len(section[i]))
|
|
||||||
rst.write(time.strftime("\nGenerated %a %d %b %Y %X UTC\n\n", time.gmtime()))
|
|
||||||
toctree.append(filename)
|
|
||||||
else:
|
|
||||||
rst.write(section[i] + '\n')
|
|
||||||
rst.write(RSTCHARS[min(i, len(RSTCHARS)-1)] * len(section[i]))
|
|
||||||
rst.write('\n\n')
|
|
||||||
class_ = section
|
|
||||||
rst.write('.. _cpydiff_%s:\n\n' % output.name.rsplit('.', 1)[0])
|
|
||||||
rst.write(output.desc + '\n')
|
|
||||||
rst.write('~' * len(output.desc) + '\n\n')
|
|
||||||
if output.cause != 'Unknown':
|
|
||||||
rst.write('**Cause:** ' + output.cause + '\n\n')
|
|
||||||
if output.workaround != 'Unknown':
|
|
||||||
rst.write('**Workaround:** ' + output.workaround + '\n\n')
|
|
||||||
|
|
||||||
rst.write('Sample code::\n\n' + indent(output.code, TAB) + '\n')
|
|
||||||
output_cpy = indent(''.join(output.output_cpy[0:2]), TAB).rstrip()
|
|
||||||
output_cpy = ('::\n\n' if output_cpy != '' else '') + output_cpy
|
|
||||||
output_upy = indent(''.join(output.output_upy[0:2]), TAB).rstrip()
|
|
||||||
output_upy = ('::\n\n' if output_upy != '' else '') + output_upy
|
|
||||||
table = gen_table([['CPy output:', output_cpy], ['uPy output:', output_upy]])
|
|
||||||
rst.write(table)
|
|
||||||
|
|
||||||
template = open(INDEXTEMPLATE, 'r')
|
|
||||||
index = open(DOCPATH + INDEX, 'w')
|
|
||||||
index.write(HEADER)
|
|
||||||
index.write(template.read())
|
|
||||||
for section in INDEXPRIORITY:
|
|
||||||
if section in toctree:
|
|
||||||
index.write(indent(section + '.rst', TAB))
|
|
||||||
toctree.remove(section)
|
|
||||||
for section in toctree:
|
|
||||||
index.write(indent(section + '.rst', TAB))
|
|
||||||
|
|
||||||
def main():
|
|
||||||
""" Main function """
|
|
||||||
|
|
||||||
# set search path so that test scripts find the test modules (and no other ones)
|
|
||||||
os.environ['PYTHONPATH'] = TESTPATH
|
|
||||||
os.environ['MICROPYPATH'] = TESTPATH
|
|
||||||
|
|
||||||
files = readfiles()
|
|
||||||
results = run_tests(files)
|
|
||||||
gen_rst(results)
|
|
||||||
|
|
||||||
main()
|
|
Loading…
Reference in New Issue
Block a user