.. This document was generated by tools/gen-cpydiff.py

Builtin types
=============
Generated Sat 07 Oct 2023 07:35:47 UTC

Exception
---------

.. _cpydiff_types_exception_attrs:

All exceptions have readable ``value`` and ``errno`` attributes, not just ``StopIteration`` and ``OSError``.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Cause:** MicroPython is optimised to reduce code size.

**Workaround:** Only use ``value`` on ``StopIteration`` exceptions, and ``errno`` on ``OSError`` exceptions.  Do not use or rely on these attributes on other exceptions.

Sample code::

    e = Exception(1)
    print(e.value)
    print(e.errno)

+-----------------------------------------------------------------+-------------+
| CPy output:                                                     | uPy output: |
+-----------------------------------------------------------------+-------------+
| ::                                                              | ::          |
|                                                                 |             |
|     Traceback (most recent call last):                          |     1       |
|       File "<stdin>", line 8, in <module>                       |     1       |
|     AttributeError: 'Exception' object has no attribute 'value' |             |
+-----------------------------------------------------------------+-------------+

.. _cpydiff_types_exception_chaining:

Exception chaining not implemented
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sample code::

    try:
        raise TypeError
    except TypeError:
        raise ValueError

+-------------------------------------------------------------------------+--------------------------------------------+
| CPy output:                                                             | uPy output:                                |
+-------------------------------------------------------------------------+--------------------------------------------+
| ::                                                                      | ::                                         |
|                                                                         |                                            |
|     Traceback (most recent call last):                                  |     Traceback (most recent call last):     |
|       File "<stdin>", line 8, in <module>                               |       File "<stdin>", line 10, in <module> |
|     TypeError                                                           |     ValueError:                            |
|                                                                         |                                            |
|     During handling of the above exception, another exception occurred: |                                            |
|                                                                         |                                            |
|     Traceback (most recent call last):                                  |                                            |
|       File "<stdin>", line 10, in <module>                              |                                            |
|     ValueError                                                          |                                            |
+-------------------------------------------------------------------------+--------------------------------------------+

.. _cpydiff_types_exception_instancevar:

User-defined attributes for builtin exceptions are not supported
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Cause:** MicroPython is highly optimized for memory usage.

**Workaround:** Use user-defined exception subclasses.

Sample code::

    e = Exception()
    e.x = 0
    print(e.x)

+-------------+-------------------------------------------------------------+
| CPy output: | uPy output:                                                 |
+-------------+-------------------------------------------------------------+
| ::          | ::                                                          |
|             |                                                             |
|     0       |     Traceback (most recent call last):                      |
|             |       File "<stdin>", line 8, in <module>                   |
|             |     AttributeError: 'Exception' object has no attribute 'x' |
+-------------+-------------------------------------------------------------+

.. _cpydiff_types_exception_loops:

Exception in while loop condition may have unexpected line number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Cause:** Condition checks are optimized to happen at the end of loop body, and that line number is reported.

Sample code::

    l = ["-foo", "-bar"]
    
    i = 0
    while l[i][0] == "-":
        print("iter")
        i += 1

+--------------------------------------------+--------------------------------------------+
| CPy output:                                | uPy output:                                |
+--------------------------------------------+--------------------------------------------+
| ::                                         | ::                                         |
|                                            |                                            |
|     iter                                   |     iter                                   |
|     iter                                   |     iter                                   |
|     Traceback (most recent call last):     |     Traceback (most recent call last):     |
|       File "<stdin>", line 10, in <module> |       File "<stdin>", line 12, in <module> |
|     IndexError: list index out of range    |     IndexError: list index out of range    |
+--------------------------------------------+--------------------------------------------+

.. _cpydiff_types_exception_subclassinit:

Exception.__init__ method does not exist.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Cause:** Subclassing native classes is not fully supported in MicroPython.

**Workaround:** Call using ``super()`` instead::

    class A(Exception):
        def __init__(self):
            super().__init__()

Sample code::

    
    
    class A(Exception):
        def __init__(self):
            Exception.__init__(self)
    
    
    a = A()

+-------------+-------------------------------------------------------------------------+
| CPy output: | uPy output:                                                             |
+-------------+-------------------------------------------------------------------------+
|             | ::                                                                      |
|             |                                                                         |
|             |     Traceback (most recent call last):                                  |
|             |       File "<stdin>", line 18, in <module>                              |
|             |       File "<stdin>", line 15, in __init__                              |
|             |     AttributeError: type object 'Exception' has no attribute '__init__' |
+-------------+-------------------------------------------------------------------------+

bytearray
---------

.. _cpydiff_types_bytearray_sliceassign:

Array slice assignment with unsupported RHS
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sample code::

    b = bytearray(4)
    b[0:1] = [1, 2]
    print(b)

+----------------------------------------+-------------------------------------------------------------+
| CPy output:                            | uPy output:                                                 |
+----------------------------------------+-------------------------------------------------------------+
| ::                                     | ::                                                          |
|                                        |                                                             |
|     bytearray(b'\x01\x02\x00\x00\x00') |     Traceback (most recent call last):                      |
|                                        |       File "<stdin>", line 8, in <module>                   |
|                                        |     NotImplementedError: array/bytes required on right side |
+----------------------------------------+-------------------------------------------------------------+

bytes
-----

.. _cpydiff_types_bytes_format:

bytes objects support .format() method
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Cause:** MicroPython strives to be a more regular implementation, so if both `str` and `bytes` support ``__mod__()`` (the % operator), it makes sense to support ``format()`` for both too. Support for ``__mod__`` can also be compiled out, which leaves only ``format()`` for bytes formatting.

**Workaround:** If you are interested in CPython compatibility, don't use ``.format()`` on bytes objects.

Sample code::

    print(b"{}".format(1))

+--------------------------------------------------------------+-------------+
| CPy output:                                                  | uPy output: |
+--------------------------------------------------------------+-------------+
| ::                                                           | ::          |
|                                                              |             |
|     Traceback (most recent call last):                       |     b'1'    |
|       File "<stdin>", line 7, in <module>                    |             |
|     AttributeError: 'bytes' object has no attribute 'format' |             |
+--------------------------------------------------------------+-------------+

.. _cpydiff_types_bytes_keywords:

bytes() with keywords not implemented
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Workaround:** Pass the encoding as a positional parameter, e.g. ``print(bytes('abc', 'utf-8'))``

Sample code::

    print(bytes("abc", encoding="utf8"))

+-------------+----------------------------------------------------------------------------------------+
| CPy output: | uPy output:                                                                            |
+-------------+----------------------------------------------------------------------------------------+
| ::          | ::                                                                                     |
|             |                                                                                        |
|     b'abc'  |     Traceback (most recent call last):                                                 |
|             |       File "<stdin>", line 7, in <module>                                              |
|             |     NotImplementedError: keyword argument(s) not implemented - use normal args instead |
+-------------+----------------------------------------------------------------------------------------+

.. _cpydiff_types_bytes_subscrstep:

Bytes subscription with step != 1 not implemented
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Cause:** MicroPython is highly optimized for memory usage.

**Workaround:** Use explicit loop for this very rare operation.

Sample code::

    print(b"123"[0:3:2])

+-------------+---------------------------------------------------------------------------+
| CPy output: | uPy output:                                                               |
+-------------+---------------------------------------------------------------------------+
| ::          | ::                                                                        |
|             |                                                                           |
|     b'13'   |     Traceback (most recent call last):                                    |
|             |       File "<stdin>", line 7, in <module>                                 |
|             |     NotImplementedError: only slices with step=1 (aka None) are supported |
+-------------+---------------------------------------------------------------------------+

dict
----

.. _cpydiff_types_dict_keys_set:

Dictionary keys view does not behave as a set.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Cause:** Not implemented.

**Workaround:** Explicitly convert keys to a set before using set operations.

Sample code::

    print({1: 2, 3: 4}.keys() & {1})

+-------------+------------------------------------------------------------------+
| CPy output: | uPy output:                                                      |
+-------------+------------------------------------------------------------------+
| ::          | ::                                                               |
|             |                                                                  |
|     {1}     |     Traceback (most recent call last):                           |
|             |       File "<stdin>", line 7, in <module>                        |
|             |     TypeError: unsupported types for __and__: 'dict_view', 'set' |
+-------------+------------------------------------------------------------------+

float
-----

.. _cpydiff_types_float_implicit_conversion:

uPy allows implicit conversion of objects in maths operations while CPython does not.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Workaround:** Objects should be wrapped in ``float(obj)`` for compatibility with CPython.

Sample code::

    
    
    class Test:
        def __float__(self):
            return 0.5
    
    
    print(2.0 * Test())

+----------------------------------------------------------------------+-------------+
| CPy output:                                                          | uPy output: |
+----------------------------------------------------------------------+-------------+
| ::                                                                   | ::          |
|                                                                      |             |
|     Traceback (most recent call last):                               |     1.0     |
|       File "<stdin>", line 14, in <module>                           |             |
|     TypeError: unsupported operand type(s) for *: 'float' and 'Test' |             |
+----------------------------------------------------------------------+-------------+

.. _cpydiff_types_float_rounding:

uPy and CPython outputs formats may differ
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sample code::

    print("%.1g" % -9.9)

+-------------+-------------+
| CPy output: | uPy output: |
+-------------+-------------+
| ::          | ::          |
|             |             |
|     -1e+01  |     -10     |
+-------------+-------------+

int
---

.. _cpydiff_types_int_bit_length:

``bit_length`` method doesn't exist.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Cause:** bit_length method is not implemented.

**Workaround:** Avoid using this method on MicroPython.

Sample code::

    
    x = 255
    print("{} is {} bits long.".format(x, x.bit_length()))

+-------------------------+----------------------------------------------------------------+
| CPy output:             | uPy output:                                                    |
+-------------------------+----------------------------------------------------------------+
| ::                      | ::                                                             |
|                         |                                                                |
|     255 is 8 bits long. |     Traceback (most recent call last):                         |
|                         |       File "<stdin>", line 9, in <module>                      |
|                         |     AttributeError: 'int' object has no attribute 'bit_length' |
+-------------------------+----------------------------------------------------------------+

.. _cpydiff_types_int_subclassconv:

No int conversion for int-derived types available
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Workaround:** Avoid subclassing builtin types unless really needed. Prefer https://en.wikipedia.org/wiki/Composition_over_inheritance .

Sample code::

    
    
    class A(int):
        __add__ = lambda self, other: A(int(self) + other)
    
    
    a = A(42)
    print(a + a)

+-------------+-------------------------------------------------------------+
| CPy output: | uPy output:                                                 |
+-------------+-------------------------------------------------------------+
| ::          | ::                                                          |
|             |                                                             |
|     84      |     Traceback (most recent call last):                      |
|             |       File "<stdin>", line 14, in <module>                  |
|             |       File "<stdin>", line 10, in <lambda>                  |
|             |     TypeError: unsupported types for __radd__: 'int', 'int' |
+-------------+-------------------------------------------------------------+

list
----

.. _cpydiff_types_list_delete_subscrstep:

List delete with step != 1 not implemented
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Workaround:** Use explicit loop for this rare operation.

Sample code::

    l = [1, 2, 3, 4]
    del l[0:4:2]
    print(l)

+-------------+-------------------------------------------+
| CPy output: | uPy output:                               |
+-------------+-------------------------------------------+
| ::          | ::                                        |
|             |                                           |
|     [2, 4]  |     Traceback (most recent call last):    |
|             |       File "<stdin>", line 8, in <module> |
|             |     NotImplementedError:                  |
+-------------+-------------------------------------------+

.. _cpydiff_types_list_store_noniter:

List slice-store with non-iterable on RHS is not implemented
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Cause:** RHS is restricted to be a tuple or list

**Workaround:** Use ``list(<iter>)`` on RHS to convert the iterable to a list

Sample code::

    l = [10, 20]
    l[0:1] = range(4)
    print(l)

+----------------------+-----------------------------------------------------+
| CPy output:          | uPy output:                                         |
+----------------------+-----------------------------------------------------+
| ::                   | ::                                                  |
|                      |                                                     |
|     [0, 1, 2, 3, 20] |     Traceback (most recent call last):              |
|                      |       File "<stdin>", line 8, in <module>           |
|                      |     TypeError: object 'range' isn't a tuple or list |
+----------------------+-----------------------------------------------------+

.. _cpydiff_types_list_store_subscrstep:

List store with step != 1 not implemented
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Workaround:** Use explicit loop for this rare operation.

Sample code::

    l = [1, 2, 3, 4]
    l[0:4:2] = [5, 6]
    print(l)

+------------------+-------------------------------------------+
| CPy output:      | uPy output:                               |
+------------------+-------------------------------------------+
| ::               | ::                                        |
|                  |                                           |
|     [5, 2, 6, 4] |     Traceback (most recent call last):    |
|                  |       File "<stdin>", line 8, in <module> |
|                  |     NotImplementedError:                  |
+------------------+-------------------------------------------+

str
---

.. _cpydiff_types_str_endswith:

Start/end indices such as str.endswith(s, start) not implemented
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sample code::

    print("abc".endswith("c", 1))

+-------------+--------------------------------------------+
| CPy output: | uPy output:                                |
+-------------+--------------------------------------------+
| ::          | ::                                         |
|             |                                            |
|     True    |     Traceback (most recent call last):     |
|             |       File "<stdin>", line 7, in <module>  |
|             |     NotImplementedError: start/end indices |
+-------------+--------------------------------------------+

.. _cpydiff_types_str_formatsubscr:

Attributes/subscr not implemented
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sample code::

    print("{a[0]}".format(a=[1, 2]))

+-------------+---------------------------------------------------+
| CPy output: | uPy output:                                       |
+-------------+---------------------------------------------------+
| ::          | ::                                                |
|             |                                                   |
|     1       |     Traceback (most recent call last):            |
|             |       File "<stdin>", line 7, in <module>         |
|             |     NotImplementedError: attributes not supported |
+-------------+---------------------------------------------------+

.. _cpydiff_types_str_keywords:

str(...) with keywords not implemented
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Workaround:** Input the encoding format directly. eg ``print(bytes('abc', 'utf-8'))``

Sample code::

    print(str(b"abc", encoding="utf8"))

+-------------+----------------------------------------------------------------------------------------+
| CPy output: | uPy output:                                                                            |
+-------------+----------------------------------------------------------------------------------------+
| ::          | ::                                                                                     |
|             |                                                                                        |
|     abc     |     Traceback (most recent call last):                                                 |
|             |       File "<stdin>", line 7, in <module>                                              |
|             |     NotImplementedError: keyword argument(s) not implemented - use normal args instead |
+-------------+----------------------------------------------------------------------------------------+

.. _cpydiff_types_str_ljust_rjust:

str.ljust() and str.rjust() not implemented
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Cause:** MicroPython is highly optimized for memory usage. Easy workarounds available.

**Workaround:** Instead of ``s.ljust(10)`` use ``"%-10s" % s``, instead of ``s.rjust(10)`` use ``"% 10s" % s``. Alternatively, ``"{:<10}".format(s)`` or ``"{:>10}".format(s)``.

Sample code::

    print("abc".ljust(10))

+-------------+-----------------------------------------------------------+
| CPy output: | uPy output:                                               |
+-------------+-----------------------------------------------------------+
| ::          | ::                                                        |
|             |                                                           |
|     abc     |     Traceback (most recent call last):                    |
|             |       File "<stdin>", line 7, in <module>                 |
|             |     AttributeError: 'str' object has no attribute 'ljust' |
+-------------+-----------------------------------------------------------+

.. _cpydiff_types_str_rsplitnone:

None as first argument for rsplit such as str.rsplit(None, n) not implemented
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sample code::

    print("a a a".rsplit(None, 1))

+------------------+-------------------------------------------+
| CPy output:      | uPy output:                               |
+------------------+-------------------------------------------+
| ::               | ::                                        |
|                  |                                           |
|     ['a a', 'a'] |     Traceback (most recent call last):    |
|                  |       File "<stdin>", line 7, in <module> |
|                  |     NotImplementedError: rsplit(None,n)   |
+------------------+-------------------------------------------+

.. _cpydiff_types_str_subscrstep:

Subscript with step != 1 is not yet implemented
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sample code::

    print("abcdefghi"[0:9:2])

+-------------+---------------------------------------------------------------------------+
| CPy output: | uPy output:                                                               |
+-------------+---------------------------------------------------------------------------+
| ::          | ::                                                                        |
|             |                                                                           |
|     acegi   |     Traceback (most recent call last):                                    |
|             |       File "<stdin>", line 7, in <module>                                 |
|             |     NotImplementedError: only slices with step=1 (aka None) are supported |
+-------------+---------------------------------------------------------------------------+

tuple
-----

.. _cpydiff_types_tuple_subscrstep:

Tuple load with step != 1 not implemented
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sample code::

    print((1, 2, 3, 4)[0:4:2])

+-------------+---------------------------------------------------------------------------+
| CPy output: | uPy output:                                                               |
+-------------+---------------------------------------------------------------------------+
| ::          | ::                                                                        |
|             |                                                                           |
|     (1, 3)  |     Traceback (most recent call last):                                    |
|             |       File "<stdin>", line 7, in <module>                                 |
|             |     NotImplementedError: only slices with step=1 (aka None) are supported |
+-------------+---------------------------------------------------------------------------+