differences_from_python.rst 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. .. _differences-from-python:
  2. Differences from Python
  3. =======================
  4. Mypyc aims to be sufficiently compatible with Python semantics so that
  5. migrating code to mypyc often doesn't require major code
  6. changes. There are various differences to enable performance gains
  7. that you need to be aware of, however.
  8. This section documents notable differences from Python. We discuss
  9. many of them also elsewhere, but it's convenient to have them here in
  10. one place.
  11. Running compiled modules
  12. ------------------------
  13. You can't use ``python3 <module>.py`` or ``python3 -m <module>``
  14. to run compiled modules. Use ``python3 -c "import <module>"`` instead,
  15. or write a wrapper script that imports your module.
  16. As a side effect, you can't rely on checking the ``__name__`` attribute in compiled
  17. code, like this::
  18. if __name__ == "__main__": # Can't be used in compiled code
  19. main()
  20. Type errors prevent compilation
  21. -------------------------------
  22. You can't compile code that generates mypy type check errors. You can
  23. sometimes ignore these with a ``# type: ignore`` comment, but this can
  24. result in bad code being generated, and it's considered dangerous.
  25. .. note::
  26. In the future, mypyc may reject ``# type: ignore`` comments that
  27. may be unsafe.
  28. Runtime type checking
  29. ---------------------
  30. Non-erased types in annotations will be type checked at runtime. For example,
  31. consider this function::
  32. def twice(x: int) -> int:
  33. return x * 2
  34. If you try to call this function with a ``float`` or ``str`` argument,
  35. you'll get a type error on the call site, even if the call site is not
  36. being type checked::
  37. twice(5) # OK
  38. twice(2.2) # TypeError
  39. twice("blah") # TypeError
  40. Also, values with *inferred* types will be type checked. For example,
  41. consider a call to the stdlib function ``socket.gethostname()`` in
  42. compiled code. This function is not compiled (no stdlib modules are
  43. compiled with mypyc), but mypyc uses a *library stub file* to infer
  44. the return type as ``str``. Compiled code calling ``gethostname()``
  45. will fail with ``TypeError`` if ``gethostname()`` would return an
  46. incompatible value, such as ``None``::
  47. import socket
  48. # Fail if returned value is not a str
  49. name = socket.gethostname()
  50. Note that ``gethostname()`` is defined like this in the stub file for
  51. ``socket`` (in typeshed)::
  52. def gethostname() -> str: ...
  53. Thus mypyc verifies that library stub files and annotations in
  54. non-compiled code match runtime values. This adds an extra layer of
  55. type safety.
  56. Casts such as ``cast(str, x)`` will also result in strict type
  57. checks. Consider this example::
  58. from typing import cast
  59. ...
  60. x = cast(str, y)
  61. The last line is essentially equivalent to this Python code when compiled::
  62. if not isinstance(y, str):
  63. raise TypeError(...)
  64. x = y
  65. In interpreted mode ``cast`` does not perform a runtime type check.
  66. Native classes
  67. --------------
  68. Native classes behave differently from Python classes. See
  69. :ref:`native-classes` for the details.
  70. Primitive types
  71. ---------------
  72. Some primitive types behave differently in compiled code to improve
  73. performance.
  74. ``int`` objects use an unboxed (non-heap-allocated) representation for small
  75. integer values. A side effect of this is that the exact runtime type of
  76. ``int`` values is lost. For example, consider this simple function::
  77. def first_int(x: List[int]) -> int:
  78. return x[0]
  79. print(first_int([True])) # Output is 1, instead of True!
  80. ``bool`` is a subclass of ``int``, so the above code is
  81. valid. However, when the list value is converted to ``int``, ``True``
  82. is converted to the corresponding ``int`` value, which is ``1``.
  83. Note that integers still have an arbitrary precision in compiled code,
  84. similar to normal Python integers.
  85. Fixed-length tuples are unboxed, similar to integers. The exact type
  86. and identity of fixed-length tuples is not preserved, and you can't
  87. reliably use ``is`` checks to compare tuples that are used in compiled
  88. code.
  89. .. _early-binding:
  90. Early binding
  91. -------------
  92. References to functions, types, most attributes, and methods in the
  93. same :ref:`compilation unit <compilation-units>` use *early binding*:
  94. the target of the reference is decided at compile time, whenever
  95. possible. This contrasts with normal Python behavior of *late
  96. binding*, where the target is found by a namespace lookup at
  97. runtime. Omitting these namespace lookups improves performance, but
  98. some Python idioms don't work without changes.
  99. Note that non-final module-level variables still use late binding.
  100. You may want to avoid these in very performance-critical code.
  101. Examples of early and late binding::
  102. from typing import Final
  103. import lib # "lib" is not compiled
  104. x = 0
  105. y: Final = 1
  106. def func() -> None:
  107. pass
  108. class Cls:
  109. def __init__(self, attr: int) -> None:
  110. self.attr = attr
  111. def method(self) -> None:
  112. pass
  113. def example() -> None:
  114. # Early binding:
  115. var = y
  116. func()
  117. o = Cls()
  118. o.x
  119. o.method()
  120. # Late binding:
  121. var = x # Module-level variable
  122. lib.func() # Accessing library that is not compiled
  123. Pickling and copying objects
  124. ----------------------------
  125. Mypyc tries to enforce that instances native classes are properly
  126. initialized by calling ``__init__`` implicitly when constructing
  127. objects, even if objects are constructed through ``pickle``,
  128. ``copy.copy`` or ``copy.deepcopy``, for example.
  129. If a native class doesn't support calling ``__init__`` without arguments,
  130. you can't pickle or copy instances of the class. Use the
  131. ``mypy_extensions.mypyc_attr`` class decorator to override this behavior
  132. and enable pickling through the ``serializable`` flag::
  133. from mypy_extensions import mypyc_attr
  134. import pickle
  135. @mypyc_attr(serializable=True)
  136. class Cls:
  137. def __init__(self, n: int) -> None:
  138. self.n = n
  139. data = pickle.dumps(Cls(5))
  140. obj = pickle.loads(data) # OK
  141. Additional notes:
  142. * All subclasses inherit the ``serializable`` flag.
  143. * If a class has the ``allow_interpreted_subclasses`` attribute, it
  144. implicitly supports serialization.
  145. * Enabling serialization may slow down attribute access, since compiled
  146. code has to be always prepared to raise ``AttributeError`` in case an
  147. attribute is not defined at runtime.
  148. * If you try to pickle an object without setting the ``serializable``
  149. flag, you'll get a ``TypeError`` about missing arguments to
  150. ``__init__``.
  151. Monkey patching
  152. ---------------
  153. Since mypyc function and class definitions are immutable, you can't
  154. perform arbitrary monkey patching, such as replacing functions or
  155. methods with mocks in tests.
  156. .. note::
  157. Each compiled module has a Python namespace that is initialized to
  158. point to compiled functions and type objects. This namespace is a
  159. regular ``dict`` object, and it *can* be modified. However,
  160. compiled code generally doesn't use this namespace, so any changes
  161. will only be visible to non-compiled code.
  162. Stack overflows
  163. ---------------
  164. Compiled code currently doesn't check for stack overflows. Your
  165. program may crash in an unrecoverable fashion if you have too many
  166. nested function calls, typically due to out-of-control recursion.
  167. .. note::
  168. This limitation will be fixed in the future.
  169. Final values
  170. ------------
  171. Compiled code replaces a reference to an attribute declared ``Final`` with
  172. the value of the attribute computed at compile time. This is an example of
  173. :ref:`early binding <early-binding>`. Example::
  174. MAX: Final = 100
  175. def limit_to_max(x: int) -> int:
  176. if x > MAX:
  177. return MAX
  178. return x
  179. The two references to ``MAX`` don't involve any module namespace lookups,
  180. and are equivalent to this code::
  181. def limit_to_max(x: int) -> int:
  182. if x > 100:
  183. return 100
  184. return x
  185. When run as interpreted, the first example will execute slower due to
  186. the extra namespace lookups. In interpreted code final attributes can
  187. also be modified.
  188. Unsupported features
  189. --------------------
  190. Some Python features are not supported by mypyc (yet). They can't be
  191. used in compiled code, or there are some limitations. You can
  192. partially work around some of these limitations by running your code
  193. in interpreted mode.
  194. Nested classes
  195. **************
  196. Nested classes are not supported.
  197. Conditional functions or classes
  198. ********************************
  199. Function and class definitions guarded by an if-statement are not supported.
  200. Dunder methods
  201. **************
  202. Native classes **cannot** use these dunders. If defined, they will not
  203. work as expected.
  204. * ``__del__``
  205. * ``__index__``
  206. * ``__getattr__``, ``__getattribute__``
  207. * ``__setattr__``
  208. * ``__delattr__``
  209. Generator expressions
  210. *********************
  211. Generator expressions are not supported. To make it easier to compile
  212. existing code, they are implicitly replaced with list comprehensions.
  213. *This does not always produce the same behavior.*
  214. To work around this limitation, you can usually use a generator
  215. function instead. You can sometimes replace the generator expression
  216. with an explicit list comprehension.
  217. Descriptors
  218. ***********
  219. Native classes can't contain arbitrary descriptors. Properties, static
  220. methods and class methods are supported.
  221. Introspection
  222. *************
  223. Various methods of introspection may break by using mypyc. Here's an
  224. non-exhaustive list of what won't work:
  225. - Instance ``__annotations__`` is usually not kept
  226. - Frames of compiled functions can't be inspected using ``inspect``
  227. - Compiled methods aren't considered methods by ``inspect.ismethod``
  228. - ``inspect.signature`` chokes on compiled functions
  229. Profiling hooks and tracing
  230. ***************************
  231. Compiled functions don't trigger profiling and tracing hooks, such as
  232. when using the ``profile``, ``cProfile``, or ``trace`` modules.
  233. Debuggers
  234. *********
  235. You can't set breakpoints in compiled functions or step through
  236. compiled functions using ``pdb``. Often you can debug your code in
  237. interpreted mode instead.