File: interop.rst

package info (click to toggle)
hy 1.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,604 kB
  • sloc: python: 7,161; makefile: 38; sh: 27
file content (125 lines) | stat: -rw-r--r-- 5,347 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
.. _interop:

=======================
Python interoperability
=======================

This chapter describes how to interact with Python code from Hy code and vice
versa.

.. contents:: Contents
   :local:

Mangling
========

:ref:`Mangling <mangling>` allows variable names to be spelled differently in
Hy and Python. For example, Python's ``str.format_map`` can be written
``str.format-map`` in Hy, and a Hy function named ``valid?`` would be called
``hyx_valid_Xquestion_markX`` in Python. You can call :hy:func:`hy.mangle` and
:hy:func:`hy.unmangle` from either language.

Keyword mincing
---------------

Another kind of mangling may be necessary in Python to refer to variables with
the same name as reserved words. For example, while ``(setv break 13)`` is
legal Hy, ``import hy, my_hy_module; print(my_hy_module.break)`` is
syntactically invalid Python. String literals work, as in
``getattr(my_hy_module, "break")``, but to use what is syntactically a Python
identifier, you'll have to take advantage of Python's Unicode normalization
(via NFKC) and write something like ``my_hy_module.๐›reak``. Here are all the
MATHEMATICAL BOLD SMALL letters (U+1D41A through U+1D433) for convenient
copying:

.. code-block:: text

   ๐š๐›๐œ๐๐ž๐Ÿ๐ ๐ก๐ข๐ฃ๐ค๐ฅ๐ฆ๐ง๐จ๐ฉ๐ช๐ซ๐ฌ๐ญ๐ฎ๐ฏ๐ฐ๐ฑ๐ฒ๐ณ

Libraries that expect Python
============================

There are various means by which Hy may interact poorly with a Python library because the library doesn't account for the possibility of Hy. For example,
when you run the program :ref:`hy-cli`, ``sys.executable`` will be set to
this program rather than the original Python binary. This is helpful more often
than not, but will lead to trouble if e.g. the library tries to call
:py:data:`sys.executable` with the ``-c`` option. In this case, you can try
setting :py:data:`sys.executable` back to ``hy.sys-executable``, which is a
saved copy of the original value. More generally, you can use :ref:`hy2py`, or you
can put a simple Python wrapper script like ``import hy, my_hy_program`` in
front of your code.

See `the wiki
<https://github.com/hylang/hy/wiki/Compatibility-tips>`_ for tips
on using specific packages.

Packaging a Hy library
======================

Generally, the same infrastructure used for Python packages, such as
``setup.py`` files and the `Python Package Index (PyPI) <https://pypi.org/>`__,
is applicable to Hy. Don't write the setup file itself in Hy, since you'll be
declaring your package's dependence on Hy there, likely in the
``install_requires`` argument of ``setup``. Similarly, at the top level of the
package, use ``__init__.py`` rather than ``__init__.hy``, and begin it with
``import hy`` to set up the import hooks for Hy. You can still import a Hy file
from there in order to write the real logic in Hy. If you want allow users to import or require from the top level of your module, as in ``from my_module import my_function`` or ``(require my-module [my-macro])``, use an ``__init__.py`` such as

.. code-block:: python

   import hy
   from my_module.hy_init import *
   hy.eval(hy.read('(require my-module.hy-init :macros * :readers *)'))

If you want to compile your Hy code into Python bytecode at installation-time
(in case e.g. the code is being installed to a directory where the bytecode
can't be automatically written later, due to permissions issues), see Hy's own
``setup.py`` for an example.

For PyPI packages, use the trove classifier ``Programming Language :: Hy`` for
libraries meant to be useful for Hy specifically (e.g., a library that provides
Hy macros) or other projects that are about Hy somehow (e.g., an instructive
example Hy program). Don't use it for a package that just happens to be written
in Hy.

Using Python from Hy
====================

To use a Python module from Hy, just :hy:func:`import` it. In most cases, no
additional ceremony is required.

You can embed Python code directly into a Hy program with the macros
:hy:func:`py <py>` and :hy:func:`pys <pys>`, and you can use standard Python
tools like :func:`eval` or :func:`exec` to execute or manipulate Python code in
strings.

To translate Python code to Hy, see `py2hy <https://github.com/hylang/py2hy>`__.

.. _using-hy-from-python:

Using Hy from Python
====================

To use a Hy module from Python, you can just :py:keyword:`import` it, provided
that ``hy`` has already been imported first, whether in the current module or
in some earlier module executed by the current Python process. As mentioned
previously, you can put ``import hy`` in a package's ``__init__.py`` to make
this happen automatically.

You can use :ref:`hy2py` to convert a Hy program to Python. The output will
still import ``hy``, and thus require Hy to be installed in order to run; see
:ref:`implicit-names` for details and workarounds.

To execute Hy code from a string, use :hy:func:`hy.read-many` to convert it to
:ref:`models <models>` and :hy:func:`hy.eval` to evaluate it:

.. code-block:: python

   >>> hy.eval(hy.read_many("(setv x 1) (+ x 1)"))
   2

There is no Hy equivalent of :func:`exec` because :hy:func:`hy.eval` works
even when the input isn't equivalent to a single Python expression.

You can use :meth:`hy.REPL.run` to launch the Hy REPL from Python, as in
``hy.REPL(locals = {**globals(), **locals()}).run()``.