From ec1e9a10a73d9c5c3771a5797e9eceb62475b197 Mon Sep 17 00:00:00 2001 From: Peter Hinch Date: Sun, 12 Nov 2017 06:13:45 +0000 Subject: docs: Add notes on heap allocation caused by bound method refs. --- docs/reference/isr_rules.rst | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'docs/reference') diff --git a/docs/reference/isr_rules.rst b/docs/reference/isr_rules.rst index 2db261c09..dfdee048c 100644 --- a/docs/reference/isr_rules.rst +++ b/docs/reference/isr_rules.rst @@ -124,6 +124,32 @@ A means of creating an object without employing a class or globals is as follows The compiler instantiates the default ``buf`` argument when the function is loaded for the first time (usually when the module it's in is imported). +An instance of object creation occurs when a reference to a bound method is +created. This means that an ISR cannot pass a bound method to a function. One +solution is to create a reference to the bound method in the class constructor +and to pass that reference in the ISR. For example: + +.. code:: python + + class Foo(): + def __init__(self): + self.bar_ref = self.bar # Allocation occurs here + self.x = 0.1 + tim = pyb.Timer(4) + tim.init(freq=2) + tim.callback(self.cb) + + def bar(self, _): + self.x *= 1.2 + print(self.x) + + def cb(self, t): + # Passing self.bar would cause allocation. + micropython.schedule(self.bar_ref, 0) + +Other techniques are to define and instantiate the method in the constructor +or to pass :meth:`Foo.bar` with the argument *self*. + Use of Python objects ~~~~~~~~~~~~~~~~~~~~~ @@ -179,6 +205,9 @@ interrupt occurs while the previous callback is executing, a further instance of for execution; this will run after the current instance has completed. A sustained high interrupt repetition rate therefore carries a risk of unconstrained queue growth and eventual failure with a ``RuntimeError``. +If the callback to be passed to `schedule()` is a bound method, consider the +note in "Creation of Python objects". + Exceptions ---------- -- cgit v1.2.3 From 4fee35a32c600d603034b6eb077a55899513ba4d Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 3 Dec 2017 15:07:46 +0200 Subject: docs/glossary: Describe the callee-owned tuple concept. --- docs/library/uselect.rst | 4 ++-- docs/reference/glossary.rst | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) (limited to 'docs/reference') diff --git a/docs/library/uselect.rst b/docs/library/uselect.rst index 211b2a4a8..f88ab7d1d 100644 --- a/docs/library/uselect.rst +++ b/docs/library/uselect.rst @@ -78,8 +78,8 @@ Methods .. method:: poll.ipoll(timeout=-1, flags=0) - Like :meth:`poll.poll`, but instead returns an iterator which yields - `callee-owned tuples`. This function provides efficient, allocation-free + Like :meth:`poll.poll`, but instead returns an iterator which yields a + `callee-owned tuple`. This function provides an efficient, allocation-free way to poll on streams. If *flags* is 1, one-shot behavior for events is employed: streams for diff --git a/docs/reference/glossary.rst b/docs/reference/glossary.rst index 4cd3d84cc..b6153550c 100644 --- a/docs/reference/glossary.rst +++ b/docs/reference/glossary.rst @@ -15,6 +15,29 @@ Glossary may also refer to "boardless" ports like :term:`Unix port `). + callee-owned tuple + A tuple returned by some builtin function/method, containing data + which is valid for a limited time, usually until next call to the + same function (or a group of related functions). After next call, + data in the tuple may be changed. This leads to the following + restriction on the usage of callee-owned tuples - references to + them cannot be stored. The only valid operation is extracting + values from them (including making a copy). Callee-owned tuples + is a MicroPython-specific construct (not available in the general + Python language), introduced for memory allocation optimization. + The idea is that callee-owned tuple is allocated once and stored + on the callee side. Subsequent calls don't require allocation, + allowing to return multiple values when allocation is not possible + (e.g. in interrupt context) or not desirable (because allocation + inherently leads to memory fragmentation). Note that callee-owned + tuples are effectively mutable tuples, making an exception to + Python's rule that tuples are immutable. (It may be interesting + why tuples were used for such a purpose then, instead of mutable + lists - the reason for that is that lists are mutable from user + application side too, so a user could do things to a callee-owned + list which the callee doesn't expect and could lead to problems; + a tuple is protected from this.) + CPython CPython is the reference implementation of Python programming language, and the most well-known one, which most of the people -- cgit v1.2.3 From 8175f1608eddc61c495c9163aebcc3c90549b9c4 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sun, 3 Dec 2017 18:56:18 +0200 Subject: docs/glossary: Describe "stream" term. --- docs/reference/glossary.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'docs/reference') diff --git a/docs/reference/glossary.rst b/docs/reference/glossary.rst index b6153550c..d9650bdd8 100644 --- a/docs/reference/glossary.rst +++ b/docs/reference/glossary.rst @@ -120,6 +120,16 @@ Glossary from context, it's recommended to use full specification like one of the above. + stream + Also known as a "file-like object". An object which provides sequential + read-write access to the underlying data. A stream object implements + a corresponding interface, which consists of methods like ``read()``, + ``write()``, ``readinto()``, ``seek()``, ``flush()``, ``close()``, etc. + A stream is an important concept in MicroPython, many I/O objects + implement the stream interface, and thus can be used consistently and + interchangeably in different contexts. For more information on + streams in MicroPython, see `uio` module. + upip (Literally, "micro pip"). A package manage for MicroPython, inspired by :term:`CPython`'s pip, but much smaller and with reduced functionality. -- cgit v1.2.3 From 155ec21e4933f75ee98bbd3e125e4304fb188170 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 4 Dec 2017 01:01:03 +0200 Subject: docs/glossary: Describe string interning. --- docs/reference/glossary.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'docs/reference') diff --git a/docs/reference/glossary.rst b/docs/reference/glossary.rst index d9650bdd8..98a2a50d8 100644 --- a/docs/reference/glossary.rst +++ b/docs/reference/glossary.rst @@ -64,6 +64,22 @@ Glossary properties of these pins (e.g. controllable by the same register). + interned string + A string referenced by its (unique) identity rather than its + address. Interned strings are thus can be quickly compared just + by their identifiers, instead of comparing by content. The + drawbacks of interned strings are that interning operation takes + time (proportional to the number of existing interned strings, + i.e. becoming slower and slower over time) and that the space + used for interned strings is not reclaimable. String interning + is done automatically by MicroPython compiler and runtimer when + it's either required by the implementation (e.g. function keyword + arguments are represented by interned string id's) or deemed + beneficial (e.g. for short enough strings, which have a chance + to be repeated, and thus interning them would save memory on + copies). Most of string and I/O operations don't produce interned + strings due to drawbacks described above. + MCU Microcontroller. Microcontrollers usually have much less resources than a full-fledged computing system, but smaller, cheaper and -- cgit v1.2.3 From ca8034d6b888952dfb4401b867f5682ac683b5ff Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Wed, 6 Dec 2017 00:08:24 +0200 Subject: docs/glossary: Clarify wording for "baremetal". --- docs/reference/glossary.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docs/reference') diff --git a/docs/reference/glossary.rst b/docs/reference/glossary.rst index 98a2a50d8..9daf0dc3a 100644 --- a/docs/reference/glossary.rst +++ b/docs/reference/glossary.rst @@ -4,9 +4,10 @@ Glossary .. glossary:: baremetal - A system without (full-fledged) OS, like an :term:`MCU`. When - running on a baremetal system, MicroPython effectively becomes - its user-facing OS with a command interpreter (REPL). + A system without a (full-fledged) OS, for example an + :term:`MCU`-based system. When running on a baremetal system, + MicroPython effectively becomes its user-facing OS with a command + interpreter (REPL). board A PCB board. Oftentimes, the term is used to denote a particular -- cgit v1.2.3 From c60fc670ea9c2f525e16bb5a175db077b71b93e6 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 11 Dec 2017 00:06:38 +0200 Subject: docs/reference/packages: Add chapter on distribution packages and deployment. A long overdue overview of preparing packages, installing them with upip, freezing, dealing with resources. Initial version, more iterations required. --- docs/reference/index.rst | 1 + docs/reference/packages.rst | 274 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 275 insertions(+) create mode 100644 docs/reference/packages.rst (limited to 'docs/reference') diff --git a/docs/reference/index.rst b/docs/reference/index.rst index 4d822d6fa..9c5c164f3 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -24,6 +24,7 @@ implementation and the best practices to use them. isr_rules.rst speed_python.rst constrained.rst + packages.rst .. only:: port_pyboard diff --git a/docs/reference/packages.rst b/docs/reference/packages.rst new file mode 100644 index 000000000..28f5f9f48 --- /dev/null +++ b/docs/reference/packages.rst @@ -0,0 +1,274 @@ +Distribution packages, package management, and deploying applications +===================================================================== + +Just as the "big" Python, MicroPython supports creation of "third party" +packages, distributing them, and easily installing them in each user's +environment. This chapter discusses how these actions are achieved. +Some familiarity with Python packaging is recommended. + +Overview +-------- + +Steps below represent a high-level workflow when creating and consuming +packages: + +1. Python modules and packages are turned into distribution package + archives, and published at the Python Package Index (PyPI). +2. `upip` package manager can be used to install a distribution package + on a `MicroPython port` with networking capabilities (for example, + on the Unix port). +3. For ports without networking capabilities, an "installation image" + can be prepared on the Unix port, and transferred to a device by + suitable means. +4. For low-memory ports, the installation image can be frozen as the + bytecode into MicroPython executable, thus minimizing the memory + storage overheads. + +The sections below describe this process in details. + +Distribution packages +--------------------- + +Python modules and packages can be packaged into archives suitable for +transfer between systems, storing at the well-known location (PyPI), +and downloading on demand for deployment. These archives are known as +*distribution packages* (to differentiate them from Python packages +(means to organize Python source code)). + +The MicroPython distribution package format is a well-known tar.gz +format, with some adaptations however. The Gzip compressor, used as +an external wrapper for TAR archives, by default uses 32KB dictionary +size, which means that to uncompress a compressed stream, 32KB of +contguous memory needs to be allocated. This requirement may be not +satisfiable on low-memory devices, which may have total memory available +less than that amount, and even if not, a contiguous block like that +may be hard to allocate due to `memory fragmentation`. To accommodate +these constraints, MicroPython distribution packages use Gzip compression +with the dictionary size of 4K, which should be a suitable compromise +with still achieving some compression while being able to uncompressed +even by the smallest devices. + +Besides the small compression dictionary size, MicroPython distribution +packages also have other optimizations, like removing any files from +the archive which aren't used by the installation process. In particular, +`upip` package manager doesn't execute ``setup.py`` during installation +(see below), and thus that file is not included in the archive. + +At the same time, these optimizations make MicroPython distribution +packages not compatible with `CPython`'s package manager, ``pip``. +This isn't considered a big problem, because: + +1. Packages can be installed with `upip`, and then can be used with + CPython (if they are compatible with it). +2. In the other direction, majority of CPython packages would be + incompatible with MicroPython by various reasons, first of all, + the reliance on features not implemented by MicroPython. + +Summing up, the MicroPython distribution package archives are highly +optimized for MicroPython's target environments, which are highly +resource constrained devices. + + +``upip`` package manager +------------------------ + +MicroPython distribution packages are intended to be installed using +the `upip` package manager. `upip` is a Python application which is +usually distributed (as frozen bytecode) with network-enabled +`MicroPython ports `. At the very least, +`upip` is available in the `MicroPython Unix port`. + +On any `MicroPython port` providing `upip`, it can be accessed as +following:: + + import upip + upip.help() + upip.install(package_or_package_list, [path]) + +Where *package_or_package_list* is the name of a distribution +package to install, or a list of such names to install multiple +packages. Optional *path* parameter specifies filesystem +location to install under and defaults to the standard library +location (see below). + +An example of installing a specific package and then using it:: + + >>> import upip + >>> upip.install("micropython-pystone_lowmem") + [...] + >>> import pystone_lowmem + >>> pystone_lowmem.main() + +Note that the name of Python package and the name of distribution +package for it in general don't have to match, and oftentimes they +don't. This is because PyPI provides a central package repository +for all different Python implementations and versions, and thus +distribution package names may need to be namespaced for a particular +implementation. For example, all packages from `micropython-lib` +follow this naming convention: for a Python module or package named +``foo``, the distribution package name is ``micropython-foo``. + +For the ports which run MicroPython executable from the OS command +prompts (like the Unix port), `upip` can be (and indeed, usually is) +run from the command line instead of MicroPython's own REPL. The +commands which corresponds to the example above are:: + + micropython -m upip -h + micropython -m upip install [-p ] ... + micropython -m upip install micropython-pystone_lowmem + +[TODO: Describe installation path.] + + +Cross-installing packages +------------------------- + +For `MicroPython ports ` without native networking +capabilities, the recommend process is "cross-installing" them into a +"directory image" using the `MicroPython Unix port`, and then +transferring this image to a device by suitable means. + +Installing to a directory image involves using ``-p`` switch to `upip`:: + + micropython -m upip install -p install_image micropython-pystone_lowmem + +After this command, the package content (and contents of every depenency +packages) will be available in the ``install_image/`` subdirectory. You +would need to transfer contents of this directory (without the +``install_image/`` prefix) to the device, at the suitable location, where +it can be found by the Python ``import`` statement (see discussion of +the `upip` installation path above). + + +Cross-installing packages with freezing +--------------------------------------- + +For the low-memory `MicroPython ports `, the process +described in the previous section does not provide the most efficient +resource usage,because the packages are installed in the source form, +so need to be compiled to the bytecome on each import. This compilation +requires RAM, and the resulting bytecode is also stored in RAM, reducing +its amount available for storing application data. Moreover, the process +above requires presence of the filesystem on a device, and the most +resource-constrained devices may not even have it. + +The bytecode freezing is a process which resolves all the issues +mentioned above: + +* The source code is pre-compiled into bytecode and store as such. +* The bytecode is stored in ROM, not RAM. +* Filesystem is not required for frozen packages. + +Using frozen bytecode requires building the executable (firmware) +for a given `MicroPython port` from the C source code. Consequently, +the process is: + +1. Follow the instructions for a particular port on setting up a + toolchain and building the port. For example, for ESP8266 port, + study instructions in ``ports/esp8266/README.md`` and follow them. + Make sure you can build the port and deploy the resulting + executable/firmware successfully before proceeding to the next steps. +2. Build `MicroPython Unix port` and make sure it is in your PATH and + you can execute ``micropython``. +3. Change to port's directory (e.g. ``ports/esp8266/`` for ESP8266). +4. Run ``make clean-frozen``. This step cleans up any previous + modules which were installed for freezing (consequently, you need + to skip this step to add additional modules, instead of starting + from scratch). +5. Run ``micropython -m upip install -p modules ...`` to + install packages you want to freeze. +6. Run ``make clean``. +7. Run ``make``. + +After this, you should have the executable/firmware with modules as +the bytecode inside, which you can deploy the usual way. + +Few notes: + +1. Step 5 in the sequence above assumes that the distribution package + is available from PyPI. If that is not the case, you would need + to copy Python source files manually to ``modules/`` subdirectory + of the port port directory. (Note that upip does not support + installing from e.g. version control repositories). +2. The firmware for baremetal devices usually has size restrictions, + so adding too many frozen modules may overflow it. Usually, you + would get a linking error if this happens. However, in some cases, + an image may be produced, which is not runnable on a device. Such + cases are in general bugs, and should be reported and further + investigated. If you face such a situation, as an initial step, + you may want to decrease the amount of frozen modules included. + + +Application resources +--------------------- + +A complete application, besides the source code, oftentimes also consists +of data files, e.g. web page templates, game images, etc. It's clear how +to deal with those when application is installed manually - you just put +those data files in the filesystem at some location and use the normal +file access functions. + +The situation is different when deploying applications from packages - this +is more advanced, streamlined and flexible way, but also requires more +advanced approach to accessing data files. This approach is treating +the data files as "resources", and abstracting away access to them. + +Python supports resource access using its "setuptools" library, using +``pkg_resources`` module. MicroPython, following its usual approach, +implements subset of the functionality of that module, specifically +`pkg_resources.resource_stream(package, resource)` function. +The idea is that an application calls this function, passing a +resource identifier, which is a relative path to data file within +the specified package (usually top-level application package). It +returns a stream object which can be used to access resource contents. +Thus, the ``resource_stream()`` emulates interface of the standard +`open()` function. + +Implementation-wise, ``resource_stream()`` uses file operations +underlyingly, if distribution package is install in the filesystem. +However, it also supports functioning without the underlying filesystem, +e.g. if the package is frozen as the bytecode. This however requires +an extra intermediate step when packaging application - creation of +"Python resource module". + +The idea of this module is to convert binary data to a Python bytes +object, and put it into the dictionary, indexed by the resource name. +This conversion is done using ``tools/mpy_bin2res.py`` script from +the MicroPython distribution. + +Let's trace the complete process using the following example. Suppose +your application has the following structure:: + + my_app/ + __main__.py + utils.py + data/ + page.html + image.png + +``__main__.py`` and ``utils.py`` should access resources using the +following calls:: + + import pkg_resources + + pkg_resources.resource_stream(__name__, "data/page.html") + pkg_resources.resource_stream(__name__, "data/image.png") + +You can develop and debug using the `MicroPython Unix port` as usual. +When times come to make a distribution package out of it, you would +need to run following command, with ``my_app/`` being the current +directory (and assuming ``mpy_bin2res.py`` is in your path):: + + mpy_bin2res.py data/page.html data/image.png + +This will produce a Python resource module named ``R.py``. Afterwards, +you package the project for distribution as usual (using ``setup.py sdist``). +Prepared like this, your application will work both when deployed to +filesystem and as frozen bytecode. + +References +---------- + +* Python Packaging User Guide: https://packaging.python.org/ +* Setuptools documentation: https://setuptools.readthedocs.io/ +* Distutils documentation: https://docs.python.org/3/library/distutils.html -- cgit v1.2.3 From 54cd6e3e4bb45f5ff649e3d31521f9a78015fb6b Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Wed, 13 Dec 2017 00:12:37 +0200 Subject: docs/packages: Add quick "Creating distribution packages" section. Needs more details. --- docs/reference/packages.rst | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'docs/reference') diff --git a/docs/reference/packages.rst b/docs/reference/packages.rst index 28f5f9f48..d8d198e62 100644 --- a/docs/reference/packages.rst +++ b/docs/reference/packages.rst @@ -199,6 +199,32 @@ Few notes: you may want to decrease the amount of frozen modules included. +Creating distribution packages +------------------------------ + +Distribution packages for MicroPython are created in the same manner +as for CPython or any other Python implementation, see references at +the end of chapter. "Source distribution" (sdist) format is used for +packaging. The post-processing discussed above, (and pre-processing +discussed in the following section) is achieved by using custom +"sdist" command for distutils/setuptools. Thus, packaging steps +remain the same as for standard distutils/setuptools, the user just +need to override "sdist" command implementation by passing the +appropriate argument to ``setup()`` call:: + + from setuptools import setup + import sdist_upip + + setup( + ..., + cmdclass={'sdist': sdist_upip.sdist} + ) + +The sdist_upip.py module as referenced above can be found in +`micropython-lib`: +https://github.com/micropython/micropython-lib/blob/master/sdist_upip.py + + Application resources --------------------- -- cgit v1.2.3 From bf73ee114f4085e06181037305599fdfeba59523 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Thu, 14 Dec 2017 18:28:10 +0200 Subject: docs/packages: mpy_bin2res no longer required to create resources. Everything happens automagically with overridden "sdist" from sdist_upip.py. --- docs/reference/packages.rst | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'docs/reference') diff --git a/docs/reference/packages.rst b/docs/reference/packages.rst index d8d198e62..3d05f0b27 100644 --- a/docs/reference/packages.rst +++ b/docs/reference/packages.rst @@ -259,8 +259,8 @@ an extra intermediate step when packaging application - creation of The idea of this module is to convert binary data to a Python bytes object, and put it into the dictionary, indexed by the resource name. -This conversion is done using ``tools/mpy_bin2res.py`` script from -the MicroPython distribution. +This conversion is done automatically using overridden ``sdist`` command +described in the previous section. Let's trace the complete process using the following example. Suppose your application has the following structure:: @@ -281,17 +281,28 @@ following calls:: pkg_resources.resource_stream(__name__, "data/image.png") You can develop and debug using the `MicroPython Unix port` as usual. -When times come to make a distribution package out of it, you would -need to run following command, with ``my_app/`` being the current -directory (and assuming ``mpy_bin2res.py`` is in your path):: +When time comes to make a distribution package out of it, just use +overridden "sdist" command from sdist_upip.py module as described in +the previous section. - mpy_bin2res.py data/page.html data/image.png +This will create a Python resource module named ``R.py``, based on the +files declared in ``MANIFEST`` or ``MANIFEST.in`` files (any non-``.py`` +file will be considered a resource and added to ``R.py``) - before +proceeding with the normal packaging steps. -This will produce a Python resource module named ``R.py``. Afterwards, -you package the project for distribution as usual (using ``setup.py sdist``). Prepared like this, your application will work both when deployed to filesystem and as frozen bytecode. +If you would like to debug ``R.py`` creation, you can run:: + + python3 setup.py sdist --manifest-only + +Alternatively, you can use tools/mpy_bin2res.py script from the +MicroPython distribution, in which can you will need to pass paths +to all resource files:: + + mpy_bin2res.py data/page.html data/image.png + References ---------- -- cgit v1.2.3 From 448d93a04aff95dd300cf3485eb7e7a74cfdfcbf Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 15 Dec 2017 00:11:02 +0200 Subject: docs/glossary: micropython-lib: Clarify wording. --- docs/reference/glossary.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/reference') diff --git a/docs/reference/glossary.rst b/docs/reference/glossary.rst index 9daf0dc3a..a6abc8b9d 100644 --- a/docs/reference/glossary.rst +++ b/docs/reference/glossary.rst @@ -95,8 +95,8 @@ Glossary `micropython-lib `_ which provides implementations for many modules from CPython's standard library. However, large subset of these modules require - POSIX-like environment (Linux, MacOS, Windows may be partially - supported), and thus would work or make sense only with + POSIX-like environment (Linux, FreeBSD, MacOS, etc.; Windows may be + partially supported), and thus would work or make sense only with `MicroPython Unix port`. Some subset of modules is however usable for `baremetal` ports too. -- cgit v1.2.3 From 9251f1395efff46bb63f5010534452f4c437206f Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 16 Dec 2017 10:37:36 +0200 Subject: docs/packages: Use "install_dir/" in examples. --- docs/reference/packages.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/reference') diff --git a/docs/reference/packages.rst b/docs/reference/packages.rst index 3d05f0b27..efe119f71 100644 --- a/docs/reference/packages.rst +++ b/docs/reference/packages.rst @@ -130,12 +130,12 @@ transferring this image to a device by suitable means. Installing to a directory image involves using ``-p`` switch to `upip`:: - micropython -m upip install -p install_image micropython-pystone_lowmem + micropython -m upip install -p install_dir micropython-pystone_lowmem After this command, the package content (and contents of every depenency -packages) will be available in the ``install_image/`` subdirectory. You +packages) will be available in the ``install_dir/`` subdirectory. You would need to transfer contents of this directory (without the -``install_image/`` prefix) to the device, at the suitable location, where +``install_dir/`` prefix) to the device, at the suitable location, where it can be found by the Python ``import`` statement (see discussion of the `upip` installation path above). -- cgit v1.2.3 From e37ccfe59b88cbc0c1617ee1d0ec418d52ba6f76 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Sat, 16 Dec 2017 10:41:45 +0200 Subject: docs/packages: Explicitly recommend usage of setuptools instead of distutils. --- docs/reference/packages.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'docs/reference') diff --git a/docs/reference/packages.rst b/docs/reference/packages.rst index efe119f71..e1609985a 100644 --- a/docs/reference/packages.rst +++ b/docs/reference/packages.rst @@ -204,12 +204,13 @@ Creating distribution packages Distribution packages for MicroPython are created in the same manner as for CPython or any other Python implementation, see references at -the end of chapter. "Source distribution" (sdist) format is used for -packaging. The post-processing discussed above, (and pre-processing -discussed in the following section) is achieved by using custom -"sdist" command for distutils/setuptools. Thus, packaging steps -remain the same as for standard distutils/setuptools, the user just -need to override "sdist" command implementation by passing the +the end of chapter. Setuptools (instead of distutils) should be used, +because distutils do not support dependencies and other features. "Source +distribution" (``sdist``) format is used for packaging. The post-processing +discussed above, (and pre-processing discussed in the following section) +is achieved by using custom ``sdist`` command for setuptools. Thus, packaging +steps remain the same as for the standard setuptools, the user just +needs to override ``sdist`` command implementation by passing the appropriate argument to ``setup()`` call:: from setuptools import setup -- cgit v1.2.3 From 9cef2b03a7a7bae2adb91e42320efa3e2af33a22 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 9 Mar 2018 16:14:58 +1100 Subject: docs/reference/repl.rst: Fix some minor errors in the REPL tutorial. --- docs/reference/repl.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'docs/reference') diff --git a/docs/reference/repl.rst b/docs/reference/repl.rst index 7a683ca22..1eccb9a88 100644 --- a/docs/reference/repl.rst +++ b/docs/reference/repl.rst @@ -19,7 +19,7 @@ If your cursor is all the way back at the beginning, pressing RETURN will then execute the code that you've entered. The following shows what you'd see after entering a for statement (the underscore shows where the cursor winds up): - >>> for i in range(3): + >>> for i in range(30): ... _ If you then enter an if statement, an additional level of indentation will be @@ -58,9 +58,10 @@ Auto-completion While typing a command at the REPL, if the line typed so far corresponds to the beginning of the name of something, then pressing TAB will show -possible things that could be entered. For example type ``m`` and press TAB -and it should expand to ``machine``. Enter a dot ``.`` and press TAB again. You -should see something like: +possible things that could be entered. For example, first import the machine +module by entering ``import machine`` and pressing RETURN. +Then type ``m`` and press TAB and it should expand to ``machine``. +Enter a dot ``.`` and press TAB again. You should see something like: >>> machine. __name__ info unique_id reset @@ -151,7 +152,7 @@ method by which you're connected to the MicroPython board (USB-serial, or Wifi). You can perform a soft reset from the REPL by pressing Ctrl-D, or from your python code by executing: :: - raise SystemExit + machine.soft_reset() For example, if you reset your MicroPython board, and you execute a dir() command, you'd see something like this: -- cgit v1.2.3 From 0db49c37a4e8d2516ea0206f4e800b907cd4221f Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 15 Mar 2018 15:50:51 +1100 Subject: docs: Fix some references and RST markup to eliminate Sphinx warnings. --- docs/library/array.rst | 6 +++--- docs/library/lcd160cr.rst | 4 ++-- docs/library/pyb.Switch.rst | 2 +- docs/library/uio.rst | 4 ++-- docs/library/uselect.rst | 8 ++++---- docs/library/ussl.rst | 6 +++--- docs/reference/constrained.rst | 4 ++-- docs/reference/packages.rst | 4 ++-- docs/reference/speed_python.rst | 10 +++++----- 9 files changed, 24 insertions(+), 24 deletions(-) (limited to 'docs/reference') diff --git a/docs/library/array.rst b/docs/library/array.rst index d096c6ec4..f837b0343 100644 --- a/docs/library/array.rst +++ b/docs/library/array.rst @@ -16,14 +16,14 @@ Classes .. class:: array.array(typecode, [iterable]) Create array with elements of given type. Initial contents of the - array are given by an `iterable`. If it is not provided, an empty + array are given by *iterable*. If it is not provided, an empty array is created. .. method:: append(val) - Append new element to the end of array, growing it. + Append new element *val* to the end of array, growing it. .. method:: extend(iterable) - Append new elements as contained in an iterable to the end of + Append new elements as contained in *iterable* to the end of array, growing it. diff --git a/docs/library/lcd160cr.rst b/docs/library/lcd160cr.rst index 567994640..bb8e6da22 100644 --- a/docs/library/lcd160cr.rst +++ b/docs/library/lcd160cr.rst @@ -172,7 +172,7 @@ Drawing text ------------ To draw text one sets the position, color and font, and then uses -`write` to draw the text. +`LCD160CR.write` to draw the text. .. method:: LCD160CR.set_pos(x, y) @@ -279,7 +279,7 @@ Touch screen methods .. method:: LCD160CR.is_touched() Returns a boolean: ``True`` if there is currently a touch force on the screen, - `False` otherwise. + ``False`` otherwise. .. method:: LCD160CR.get_touch() diff --git a/docs/library/pyb.Switch.rst b/docs/library/pyb.Switch.rst index e5ab6bd84..1edcbf848 100644 --- a/docs/library/pyb.Switch.rst +++ b/docs/library/pyb.Switch.rst @@ -38,7 +38,7 @@ Methods .. method:: Switch.value() - Get the switch state. Returns `True` if pressed down, otherwise `False`. + Get the switch state. Returns ``True`` if pressed down, otherwise ``False``. .. method:: Switch.callback(fun) diff --git a/docs/library/uio.rst b/docs/library/uio.rst index 7e6c93228..81420702d 100644 --- a/docs/library/uio.rst +++ b/docs/library/uio.rst @@ -81,7 +81,7 @@ Functions Open a file. Builtin ``open()`` function is aliased to this function. All ports (which provide access to file system) are required to support - `mode` parameter, but support for other arguments vary by port. + *mode* parameter, but support for other arguments vary by port. Classes ------- @@ -103,7 +103,7 @@ Classes text-mode I/O (similar to a normal file opened with "t" modifier). `BytesIO` is used for binary-mode I/O (similar to a normal file opened with "b" modifier). Initial contents of file-like objects - can be specified with `string` parameter (should be normal string + can be specified with *string* parameter (should be normal string for `StringIO` or bytes object for `BytesIO`). All the usual file methods like ``read()``, ``write()``, ``seek()``, ``flush()``, ``close()`` are available on these objects, and additionally, a diff --git a/docs/library/uselect.rst b/docs/library/uselect.rst index fb43f7e63..77d458473 100644 --- a/docs/library/uselect.rst +++ b/docs/library/uselect.rst @@ -35,10 +35,10 @@ Methods Register `stream` *obj* for polling. *eventmask* is logical OR of: - * `uselect.POLLIN` - data available for reading - * `uselect.POLLOUT` - more data can be written + * ``uselect.POLLIN`` - data available for reading + * ``uselect.POLLOUT`` - more data can be written - Note that flags like `uselect.POLLHUP` and `uselect.POLLERR` are + Note that flags like ``uselect.POLLHUP`` and ``uselect.POLLERR`` are *not* valid as input eventmask (these are unsolicited events which will be returned from `poll()` regardless of whether they are asked for). This semantics is per POSIX. @@ -63,7 +63,7 @@ Methods tuple, depending on a platform and version, so don't assume that its size is 2. The ``event`` element specifies which events happened with a stream and is a combination of ``uselect.POLL*`` constants described above. Note that - flags `uselect.POLLHUP` and `uselect.POLLERR` can be returned at any time + flags ``uselect.POLLHUP`` and ``uselect.POLLERR`` can be returned at any time (even if were not asked for), and must be acted on accordingly (the corresponding stream unregistered from poll and likely closed), because otherwise all further invocations of `poll()` may return immediately with diff --git a/docs/library/ussl.rst b/docs/library/ussl.rst index 903a351f4..be84dc054 100644 --- a/docs/library/ussl.rst +++ b/docs/library/ussl.rst @@ -18,10 +18,10 @@ Functions Takes a `stream` *sock* (usually usocket.socket instance of ``SOCK_STREAM`` type), and returns an instance of ssl.SSLSocket, which wraps the underlying stream in an SSL context. Returned object has the usual `stream` interface methods like - `read()`, `write()`, etc. In MicroPython, the returned object does not expose - socket interface and methods like `recv()`, `send()`. In particular, a + ``read()``, ``write()``, etc. In MicroPython, the returned object does not expose + socket interface and methods like ``recv()``, ``send()``. In particular, a server-side SSL socket should be created from a normal socket returned from - `accept()` on a non-SSL listening server socket. + :meth:`~usocket.socket.accept()` on a non-SSL listening server socket. Depending on the underlying module implementation in a particular `MicroPython port`, some or all keyword arguments above may be not supported. diff --git a/docs/reference/constrained.rst b/docs/reference/constrained.rst index e7de459bc..edac0ae68 100644 --- a/docs/reference/constrained.rst +++ b/docs/reference/constrained.rst @@ -185,7 +185,7 @@ a file it will save RAM if this is done in a piecemeal fashion. Rather than creating a large string object, create a substring and feed it to the stream before dealing with the next. -The best way to create dynamic strings is by means of the string `format` +The best way to create dynamic strings is by means of the string ``format()`` method: .. code:: @@ -259,7 +259,7 @@ were a string. **Runtime compiler execution** The Python funcitons `eval` and `exec` invoke the compiler at runtime, which -requires significant amounts of RAM. Note that the `pickle` library from +requires significant amounts of RAM. Note that the ``pickle`` library from `micropython-lib` employs `exec`. It may be more RAM efficient to use the `ujson` library for object serialisation. diff --git a/docs/reference/packages.rst b/docs/reference/packages.rst index e1609985a..8be2461c2 100644 --- a/docs/reference/packages.rst +++ b/docs/reference/packages.rst @@ -42,7 +42,7 @@ size, which means that to uncompress a compressed stream, 32KB of contguous memory needs to be allocated. This requirement may be not satisfiable on low-memory devices, which may have total memory available less than that amount, and even if not, a contiguous block like that -may be hard to allocate due to `memory fragmentation`. To accommodate +may be hard to allocate due to memory fragmentation. To accommodate these constraints, MicroPython distribution packages use Gzip compression with the dictionary size of 4K, which should be a suitable compromise with still achieving some compression while being able to uncompressed @@ -243,7 +243,7 @@ the data files as "resources", and abstracting away access to them. Python supports resource access using its "setuptools" library, using ``pkg_resources`` module. MicroPython, following its usual approach, implements subset of the functionality of that module, specifically -`pkg_resources.resource_stream(package, resource)` function. +``pkg_resources.resource_stream(package, resource)`` function. The idea is that an application calls this function, passing a resource identifier, which is a relative path to data file within the specified package (usually top-level application package). It diff --git a/docs/reference/speed_python.rst b/docs/reference/speed_python.rst index 279a1bbcd..4db60ec14 100644 --- a/docs/reference/speed_python.rst +++ b/docs/reference/speed_python.rst @@ -63,8 +63,8 @@ used for communication with a device. A typical driver will create the buffer in constructor and use it in its I/O methods which will be called repeatedly. The MicroPython libraries typically provide support for pre-allocated buffers. For -example, objects which support stream interface (e.g., file or UART) provide `read()` -method which allocates new buffer for read data, but also a `readinto()` method +example, objects which support stream interface (e.g., file or UART) provide ``read()`` +method which allocates new buffer for read data, but also a ``readinto()`` method to read data into an existing buffer. Floating Point @@ -109,10 +109,10 @@ the 10K buffer go (be ready for garbage collection), instead of making a long-living memoryview and keeping 10K blocked for GC. Nonetheless, `memoryview` is indispensable for advanced preallocated buffer -management. `readinto()` method discussed above puts data at the beginning +management. ``readinto()`` method discussed above puts data at the beginning of buffer and fills in entire buffer. What if you need to put data in the middle of existing buffer? Just create a memoryview into the needed section -of buffer and pass it to `readinto()`. +of buffer and pass it to ``readinto()``. Identifying the slowest section of code --------------------------------------- @@ -326,7 +326,7 @@ standard approach would be to write mypin.value(mypin.value() ^ 1) # mypin was instantiated as an output pin -This involves the overhead of two calls to the `Pin` instance's :meth:`~machine.Pin.value()` +This involves the overhead of two calls to the :class:`~machine.Pin` instance's :meth:`~machine.Pin.value()` method. This overhead can be eliminated by performing a read/write to the relevant bit of the chip's GPIO port output data register (odr). To facilitate this the ``stm`` module provides a set of constants providing the addresses of the relevant registers. -- cgit v1.2.3