<feed xmlns='http://www.w3.org/2005/Atom'>
<title>unit.git/src/python, branch applog</title>
<subtitle>Universal Web Application Server</subtitle>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/'/>
<entry>
<title>Python: ASGI: Don't log asyncio.get_running_loop() errors.</title>
<updated>2023-02-07T14:59:34+00:00</updated>
<author>
<name>Andrew Clayton</name>
<email>a.clayton@nginx.com</email>
</author>
<published>2023-02-07T13:11:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=cbc01907fef6a028f02d9051b909def920c49f24'/>
<id>cbc01907fef6a028f02d9051b909def920c49f24</id>
<content type='text'>
This adds a check to nxt_python_asgi_get_event_loop() on the
event_loop_func name in the case that running that function fails, and
if it's get_running_loop() that failed we skip printing an error message
as this is an often expected behaviour since the previous commit and we
don't want users reporting erroneous bugs.

This check will always happen regardless of Python version while it
really only applies to Python &gt;= 3.7, there didn't seem much point
adding complexity to the code for this case and in what will be an ever
diminishing case of people running older Pythons.

Reviewed-by: Alejandro Colomar &lt;alx@nginx.com&gt;
Signed-off-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This adds a check to nxt_python_asgi_get_event_loop() on the
event_loop_func name in the case that running that function fails, and
if it's get_running_loop() that failed we skip printing an error message
as this is an often expected behaviour since the previous commit and we
don't want users reporting erroneous bugs.

This check will always happen regardless of Python version while it
really only applies to Python &gt;= 3.7, there didn't seem much point
adding complexity to the code for this case and in what will be an ever
diminishing case of people running older Pythons.

Reviewed-by: Alejandro Colomar &lt;alx@nginx.com&gt;
Signed-off-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Python: ASGI: Switch away from asyncio.get_event_loop().</title>
<updated>2023-02-07T14:59:26+00:00</updated>
<author>
<name>Andrew Clayton</name>
<email>a.clayton@nginx.com</email>
</author>
<published>2023-01-20T03:33:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=9c0a4a09978e0defbc6656c7866a7ca147236733'/>
<id>9c0a4a09978e0defbc6656c7866a7ca147236733</id>
<content type='text'>
Several users on GitHub reported issues with running Python ASGI apps on
Unit with Python 3.11.1 (this would also effect Python 3.10.9) with the
following error from Unit

  2023/01/15 22:43:22 [alert] 0#77128 [unit] Python failed to call 'asyncio.get_event_loop'

TL;DR

asyncio.get_event_loop() is currently broken due to the process of
deprecating part or all of it.

First some history.

In Unit we had this commit

  commit 8dcb0b9987033d0349a6ecf528014a9daa574787
  Author: Max Romanov &lt;max.romanov@nginx.com&gt;
  Date:   Thu Nov 5 00:04:59 2020 +0300

      Python: request processing in multiple threads.

One of things this did was to create a new asyncio event loop in each
thread using asyncio.new_event_loop().

It's perhaps worth noting that all these asyncio.* functions are Python
functions that we call from the C code in Unit.

Then we had this commit

  commit f27fbd9b4d2bdaddf1e7001d0d0bc5586ba04cd4
  Author: Max Romanov &lt;max.romanov@nginx.com&gt;
  Date:   Tue Jul 20 10:37:54 2021 +0300

      Python: using default event_loop for main thread for ASGI.

This changed things so that Unit calls asyncio.get_event_loop() in the
_main_ thread (but still calls asyncio.new_event_loop() in the other
threads).

asyncio.get_event_loop() up until recently would either return an
already running event loop or return a newly created one.

This was done for $reasons that the commit message and GitHub issue #560
hint at. But the intimation is that there can already be an event loop
running from the application (I assume it's referring to the users
application) at this point and if there is we should use it.

Now for the Python side of things.

On the main branch we had

  commit 172c0f2752d8708b6dda7b42e6c5a3519420a4e8
  Author: Serhiy Storchaka &lt;storchaka@gmail.com&gt;
  Date:   Sun Apr 25 13:40:44 2021 +0300

      bpo-39529: Deprecate creating new event loop in asyncio.get_event_loop() (GH-23554)

This commit began the deprecating of asyncio.get_event_loop().

  commit fd38a2f0ec03b4eec5e3cfd41241d198b1ee555a
  Author: Serhiy Storchaka &lt;storchaka@gmail.com&gt;
  Date:   Tue Dec 6 19:42:12 2022 +0200

      gh-93453: No longer create an event loop in get_event_loop() (#98440)

This turned asyncio.get_event_loop() into a RuntimeError _if_ there
isn't a current event loop.

  commit e5bd5ad70d9e549eeb80aadb4f3ccb0f2f23266d
  Author: Serhiy Storchaka &lt;storchaka@gmail.com&gt;
  Date:   Fri Jan 13 14:40:29 2023 +0200

      gh-100160: Restore and deprecate implicit creation of an event loop (GH-100410)

This re-creates the event loop if there wasn't one and emits a
deprecation warning.

After at least the last two commits Unit no longer works with the Python
_main_ branch.

Meanwhile on the 3.11 branch we had

  commit 3fae04b10e2655a20a3aadb5e0d63e87206d0c67
  Author: Serhiy Storchaka &lt;storchaka@gmail.com&gt;
  Date:   Tue Dec 6 17:15:44 2022 +0200

      [3.11] gh-93453: Only emit deprecation warning in asyncio.get_event_loop when a new event loop is created (#99949)

which is what caused our breakage, though perhaps unintentionally as we
get the following traceback

  Traceback (most recent call last):
    File "/usr/lib64/python3.11/asyncio/events.py", line 676, in get_event_loop
      f = sys._getframe(1)
          ^^^^^^^^^^^^^^^^
  ValueError: call stack is not deep enough
  2023/01/18 02:46:10 [alert] 0#180279 [unit] Python failed to call 'asyncio.get_event_loop'

However, regardless, it is clear we need to stop using
asyncio.get_event_loop().

One option is to switch to the higher level asyncio.run() API, however
that is a rather large change.

This commit takes the simpler approach of using
asyncio.get_running_loop() (which it seems get_event_loop() will
eventually be an alias of) in the _main_ thread to return the currently
running event loop, or if there is no current event loop, it will call
asyncio.new_event_loop() to return a newly created event loop.

I believe this mimics the current behaviour. In my testing
get_event_loop() seemed to always return a newly created loop, as when
just calling get_running_loop() it would return NULL and we would fail
out.

When running two processes each with 2 threads we would get the
following loops with Python 3.11.0 and unpatched Unit

  &lt;_UnixSelectorEventLoop running=False closed=False debug=False&gt;
  &lt;_UnixSelectorEventLoop running=False closed=False debug=False&gt;
  &lt;_UnixSelectorEventLoop running=False closed=False debug=False&gt;
  &lt;_UnixSelectorEventLoop running=False closed=False debug=False&gt;

and with Python 3.11.1 and a patched Unit we would get

  &lt;_UnixSelectorEventLoop running=False closed=False debug=False&gt;
  &lt;_UnixSelectorEventLoop running=False closed=False debug=False&gt;
  &lt;_UnixSelectorEventLoop running=False closed=False debug=False&gt;
  &lt;_UnixSelectorEventLoop running=False closed=False debug=False&gt;

Tested-by: Rafał Safin &lt;rafal.safin12@gmail.com&gt;
Reviewed-by: Alejandro Colomar &lt;alx@nginx.com&gt;
Signed-off-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Several users on GitHub reported issues with running Python ASGI apps on
Unit with Python 3.11.1 (this would also effect Python 3.10.9) with the
following error from Unit

  2023/01/15 22:43:22 [alert] 0#77128 [unit] Python failed to call 'asyncio.get_event_loop'

TL;DR

asyncio.get_event_loop() is currently broken due to the process of
deprecating part or all of it.

First some history.

In Unit we had this commit

  commit 8dcb0b9987033d0349a6ecf528014a9daa574787
  Author: Max Romanov &lt;max.romanov@nginx.com&gt;
  Date:   Thu Nov 5 00:04:59 2020 +0300

      Python: request processing in multiple threads.

One of things this did was to create a new asyncio event loop in each
thread using asyncio.new_event_loop().

It's perhaps worth noting that all these asyncio.* functions are Python
functions that we call from the C code in Unit.

Then we had this commit

  commit f27fbd9b4d2bdaddf1e7001d0d0bc5586ba04cd4
  Author: Max Romanov &lt;max.romanov@nginx.com&gt;
  Date:   Tue Jul 20 10:37:54 2021 +0300

      Python: using default event_loop for main thread for ASGI.

This changed things so that Unit calls asyncio.get_event_loop() in the
_main_ thread (but still calls asyncio.new_event_loop() in the other
threads).

asyncio.get_event_loop() up until recently would either return an
already running event loop or return a newly created one.

This was done for $reasons that the commit message and GitHub issue #560
hint at. But the intimation is that there can already be an event loop
running from the application (I assume it's referring to the users
application) at this point and if there is we should use it.

Now for the Python side of things.

On the main branch we had

  commit 172c0f2752d8708b6dda7b42e6c5a3519420a4e8
  Author: Serhiy Storchaka &lt;storchaka@gmail.com&gt;
  Date:   Sun Apr 25 13:40:44 2021 +0300

      bpo-39529: Deprecate creating new event loop in asyncio.get_event_loop() (GH-23554)

This commit began the deprecating of asyncio.get_event_loop().

  commit fd38a2f0ec03b4eec5e3cfd41241d198b1ee555a
  Author: Serhiy Storchaka &lt;storchaka@gmail.com&gt;
  Date:   Tue Dec 6 19:42:12 2022 +0200

      gh-93453: No longer create an event loop in get_event_loop() (#98440)

This turned asyncio.get_event_loop() into a RuntimeError _if_ there
isn't a current event loop.

  commit e5bd5ad70d9e549eeb80aadb4f3ccb0f2f23266d
  Author: Serhiy Storchaka &lt;storchaka@gmail.com&gt;
  Date:   Fri Jan 13 14:40:29 2023 +0200

      gh-100160: Restore and deprecate implicit creation of an event loop (GH-100410)

This re-creates the event loop if there wasn't one and emits a
deprecation warning.

After at least the last two commits Unit no longer works with the Python
_main_ branch.

Meanwhile on the 3.11 branch we had

  commit 3fae04b10e2655a20a3aadb5e0d63e87206d0c67
  Author: Serhiy Storchaka &lt;storchaka@gmail.com&gt;
  Date:   Tue Dec 6 17:15:44 2022 +0200

      [3.11] gh-93453: Only emit deprecation warning in asyncio.get_event_loop when a new event loop is created (#99949)

which is what caused our breakage, though perhaps unintentionally as we
get the following traceback

  Traceback (most recent call last):
    File "/usr/lib64/python3.11/asyncio/events.py", line 676, in get_event_loop
      f = sys._getframe(1)
          ^^^^^^^^^^^^^^^^
  ValueError: call stack is not deep enough
  2023/01/18 02:46:10 [alert] 0#180279 [unit] Python failed to call 'asyncio.get_event_loop'

However, regardless, it is clear we need to stop using
asyncio.get_event_loop().

One option is to switch to the higher level asyncio.run() API, however
that is a rather large change.

This commit takes the simpler approach of using
asyncio.get_running_loop() (which it seems get_event_loop() will
eventually be an alias of) in the _main_ thread to return the currently
running event loop, or if there is no current event loop, it will call
asyncio.new_event_loop() to return a newly created event loop.

I believe this mimics the current behaviour. In my testing
get_event_loop() seemed to always return a newly created loop, as when
just calling get_running_loop() it would return NULL and we would fail
out.

When running two processes each with 2 threads we would get the
following loops with Python 3.11.0 and unpatched Unit

  &lt;_UnixSelectorEventLoop running=False closed=False debug=False&gt;
  &lt;_UnixSelectorEventLoop running=False closed=False debug=False&gt;
  &lt;_UnixSelectorEventLoop running=False closed=False debug=False&gt;
  &lt;_UnixSelectorEventLoop running=False closed=False debug=False&gt;

and with Python 3.11.1 and a patched Unit we would get

  &lt;_UnixSelectorEventLoop running=False closed=False debug=False&gt;
  &lt;_UnixSelectorEventLoop running=False closed=False debug=False&gt;
  &lt;_UnixSelectorEventLoop running=False closed=False debug=False&gt;
  &lt;_UnixSelectorEventLoop running=False closed=False debug=False&gt;

Tested-by: Rafał Safin &lt;rafal.safin12@gmail.com&gt;
Reviewed-by: Alejandro Colomar &lt;alx@nginx.com&gt;
Signed-off-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Python: ASGI: Factor out event loop creation to its own function.</title>
<updated>2023-02-07T13:17:11+00:00</updated>
<author>
<name>Andrew Clayton</name>
<email>a.clayton@nginx.com</email>
</author>
<published>2023-01-20T03:27:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=4b7a95469cf309b437fc1a8201a93f14c33ce3a8'/>
<id>4b7a95469cf309b437fc1a8201a93f14c33ce3a8</id>
<content type='text'>
This is a preparatory patch that factors out the asyncio event loop
creation code from nxt_python_asgi_ctx_data_alloc() into its own
function, to facilitate being called multiple times.

This a part of the work to move away from using the
asyncio.get_event_loop() function due to it no longer creating event
loops if there wasn't one running.

See the following commit for the gory details.

Reviewed-by: Alejandro Colomar &lt;alx@nginx.com&gt;
Signed-off-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This is a preparatory patch that factors out the asyncio event loop
creation code from nxt_python_asgi_ctx_data_alloc() into its own
function, to facilitate being called multiple times.

This a part of the work to move away from using the
asyncio.get_event_loop() function due to it no longer creating event
loops if there wasn't one running.

See the following commit for the gory details.

Reviewed-by: Alejandro Colomar &lt;alx@nginx.com&gt;
Signed-off-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Python: Fix enabling of UTF-8 in some situations.</title>
<updated>2023-01-12T17:56:00+00:00</updated>
<author>
<name>Andrew Clayton</name>
<email>a.clayton@nginx.com</email>
</author>
<published>2023-01-05T22:04:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=f3d05bba525c048d8ca905831a7729d7f90c94bc'/>
<id>f3d05bba525c048d8ca905831a7729d7f90c94bc</id>
<content type='text'>
There was a couple of reports of Python applications failing due to the
following type of error

File "/opt/netbox/netbox/netbox/configuration.py", line 25, in _import
     print(f"\U0001f9ec loaded config '{path}'")
UnicodeEncodeError: 'ascii' codec can't encode character '\U0001f9ec' in
position 0: ordinal not in range(128)

due to the use of Unicode text in the print() statement.

This only happened for python 3.8+ when using the "home" configuration
option as this meant we were going through the new PyConfig
configuration.

When using this new configuration method with the 'isolated' specific
API (for embedded Python) UTF-8 is disabled by default,
PyPreConfig-&gt;utf8_mode = 0.

To fix this we need to setup the Python pre config and enable utf-8
mode. However rather than enable utf-8 unconditionally we can set to it
to -1 so that it will use the LC_CTYPE environment variable to determine
whether to enable utf-8 mode or not. utf-8 mode will be enabled if
LC_CTYPE is either: C, POSIX or some specific UTF-8 locale. This is the
default utf8_mode setting when using the non-isolated PyPreConfig API.

Reported-by: Tobias Genannt &lt;tobias.genannt@kappa-velorum.net&gt;
Tested-by: Tobias Genannt &lt;tobias.genannt@kappa-velorum.net&gt;
Link: &lt;https://peps.python.org/pep-0587/&gt;
Link: &lt;https://docs.python.org/3/c-api/init_config.html#c.PyPreConfig.utf8_mode&gt;
Fixes: 491d0f70 ("Python: Added support for Python 3.11.")
Closes: &lt;https://github.com/nginx/unit/issues/817&gt;
Reviewed-by: Alejandro Colomar &lt;alx@nginx.com&gt;
Signed-off-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
There was a couple of reports of Python applications failing due to the
following type of error

File "/opt/netbox/netbox/netbox/configuration.py", line 25, in _import
     print(f"\U0001f9ec loaded config '{path}'")
UnicodeEncodeError: 'ascii' codec can't encode character '\U0001f9ec' in
position 0: ordinal not in range(128)

due to the use of Unicode text in the print() statement.

This only happened for python 3.8+ when using the "home" configuration
option as this meant we were going through the new PyConfig
configuration.

When using this new configuration method with the 'isolated' specific
API (for embedded Python) UTF-8 is disabled by default,
PyPreConfig-&gt;utf8_mode = 0.

To fix this we need to setup the Python pre config and enable utf-8
mode. However rather than enable utf-8 unconditionally we can set to it
to -1 so that it will use the LC_CTYPE environment variable to determine
whether to enable utf-8 mode or not. utf-8 mode will be enabled if
LC_CTYPE is either: C, POSIX or some specific UTF-8 locale. This is the
default utf8_mode setting when using the non-isolated PyPreConfig API.

Reported-by: Tobias Genannt &lt;tobias.genannt@kappa-velorum.net&gt;
Tested-by: Tobias Genannt &lt;tobias.genannt@kappa-velorum.net&gt;
Link: &lt;https://peps.python.org/pep-0587/&gt;
Link: &lt;https://docs.python.org/3/c-api/init_config.html#c.PyPreConfig.utf8_mode&gt;
Fixes: 491d0f70 ("Python: Added support for Python 3.11.")
Closes: &lt;https://github.com/nginx/unit/issues/817&gt;
Reviewed-by: Alejandro Colomar &lt;alx@nginx.com&gt;
Signed-off-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Python: Do some cleanup in nxt_python3_init_config().</title>
<updated>2023-01-12T17:56:00+00:00</updated>
<author>
<name>Andrew Clayton</name>
<email>a.clayton@nginx.com</email>
</author>
<published>2022-12-30T00:07:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=a560cbf992724eb0195544729d67286fd81f4bac'/>
<id>a560cbf992724eb0195544729d67286fd81f4bac</id>
<content type='text'>
This is a preparatory patch for future work and cleans up the code a
little in the Python 3.8+ variant of nxt_python3_init_config().

The main advantage being we no longer have calls to PyConfig_Clear() in
two different paths.

The variables have a little extra space in their declarations to allow
for the next patch which introduces a variable with a longer type name,
which will help reduce the size of the diff.

Reviewed-by: Alejandro Colomar &lt;alx@nginx.com&gt;
Signed-off-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This is a preparatory patch for future work and cleans up the code a
little in the Python 3.8+ variant of nxt_python3_init_config().

The main advantage being we no longer have calls to PyConfig_Clear() in
two different paths.

The variables have a little extra space in their declarations to allow
for the next patch which introduces a variable with a longer type name,
which will help reduce the size of the diff.

Reviewed-by: Alejandro Colomar &lt;alx@nginx.com&gt;
Signed-off-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Python: Added "prefix" to configuration.</title>
<updated>2022-12-14T10:30:30+00:00</updated>
<author>
<name>OutOfFocus4</name>
<email>jeff.iadarola@gmail.com</email>
</author>
<published>2021-11-14T15:47:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=6dae517ebd20baa2066541e703d6aa594326dd69'/>
<id>6dae517ebd20baa2066541e703d6aa594326dd69</id>
<content type='text'>
This patch gives users the option to set a `"prefix"` attribute
for Python applications, either at the top level or for specific
`"target"`s. If the attribute is present, the value of `"prefix"`
must be a string beginning with `"/"`. If the value of the `"prefix"`
attribute is longer than 1 character and ends in `"/"`, the
trailing `"/"` is stripped.

The purpose of the `"prefix"` attribute is to set the `SCRIPT_NAME`
context value for WSGI applications and the `root_path` context
value for ASGI applications, allowing applications to properly route
requests regardless of the path that the server uses to expose the
application.

The context value is only set if the request's URL path begins with
the value of the `"prefix"` attribute. In all other cases, the
`SCRIPT_NAME` or `root_path` values are not set. In addition, for
WSGI applications, the value of `"prefix"` will be stripped from
the beginning of the request's URL path before it is sent to the
application.

Reviewed-by: Andrei Zeliankou &lt;zelenkov@nginx.com&gt;
Reviewed-by: Artem Konev &lt;artem.konev@nginx.com&gt;
Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This patch gives users the option to set a `"prefix"` attribute
for Python applications, either at the top level or for specific
`"target"`s. If the attribute is present, the value of `"prefix"`
must be a string beginning with `"/"`. If the value of the `"prefix"`
attribute is longer than 1 character and ends in `"/"`, the
trailing `"/"` is stripped.

The purpose of the `"prefix"` attribute is to set the `SCRIPT_NAME`
context value for WSGI applications and the `root_path` context
value for ASGI applications, allowing applications to properly route
requests regardless of the path that the server uses to expose the
application.

The context value is only set if the request's URL path begins with
the value of the `"prefix"` attribute. In all other cases, the
`SCRIPT_NAME` or `root_path` values are not set. In addition, for
WSGI applications, the value of `"prefix"` will be stripped from
the beginning of the request's URL path before it is sent to the
application.

Reviewed-by: Andrei Zeliankou &lt;zelenkov@nginx.com&gt;
Reviewed-by: Artem Konev &lt;artem.konev@nginx.com&gt;
Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Python: Added support for Python 3.11.</title>
<updated>2022-12-06T02:51:03+00:00</updated>
<author>
<name>Andrew Clayton</name>
<email>a.clayton@nginx.com</email>
</author>
<published>2022-11-17T21:56:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=491d0f700f5690eba0f1fcf2124f3a37ef73eb1a'/>
<id>491d0f700f5690eba0f1fcf2124f3a37ef73eb1a</id>
<content type='text'>
Python 3.8 added a new Python initialisation configuration API[0].

Python 3.11 marked the old API as deprecated resulting in the following
compiler warnings which we treat as errors, failing the build

src/python/nxt_python.c: In function ‘nxt_python_start’:
src/python/nxt_python.c:130:13: error: ‘Py_SetProgramName’ is deprecated [-Werror=deprecated-declarations]
  130 |             Py_SetProgramName(nxt_py_home);
      |             ^~~~~~~~~~~~~~~~~
In file included from /opt/python-3.11/include/python3.11/Python.h:94,
                 from src/python/nxt_python.c:7:
/opt/python-3.11/include/python3.11/pylifecycle.h:37:38: note: declared here
   37 | Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetProgramName(const wchar_t *);
      |                                      ^~~~~~~~~~~~~~~~~
src/python/nxt_python.c:134:13: error: ‘Py_SetPythonHome’ is deprecated [-Werror=deprecated-declarations]
  134 |             Py_SetPythonHome(nxt_py_home);
      |             ^~~~~~~~~~~~~~~~
/opt/python-3.11/include/python3.11/pylifecycle.h:40:38: note: declared here
   40 | Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetPythonHome(const wchar_t *);
      |                                      ^~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors

We actually have a few config scenarios: Python &lt; 3, Python &gt;= 3.0 &lt; 3.8
and for Python 3 we have two configs where we select one based on
virtual environment setup.

Factor out the Python 3 config initialisation into its own function.  We
actually create two functions, one for Python 3.8+ and one for older
Python 3.  We pick the right function to use at build time.

The new API also has error checking (where the old API doesn't) which we
handle.

[0]: https://peps.python.org/pep-0587/

Closes: &lt;https://github.com/nginx/unit/issues/710&gt;
[ Andrew: Expanded upon patch from @sandeep-gh ]
Signed-off-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Python 3.8 added a new Python initialisation configuration API[0].

Python 3.11 marked the old API as deprecated resulting in the following
compiler warnings which we treat as errors, failing the build

src/python/nxt_python.c: In function ‘nxt_python_start’:
src/python/nxt_python.c:130:13: error: ‘Py_SetProgramName’ is deprecated [-Werror=deprecated-declarations]
  130 |             Py_SetProgramName(nxt_py_home);
      |             ^~~~~~~~~~~~~~~~~
In file included from /opt/python-3.11/include/python3.11/Python.h:94,
                 from src/python/nxt_python.c:7:
/opt/python-3.11/include/python3.11/pylifecycle.h:37:38: note: declared here
   37 | Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetProgramName(const wchar_t *);
      |                                      ^~~~~~~~~~~~~~~~~
src/python/nxt_python.c:134:13: error: ‘Py_SetPythonHome’ is deprecated [-Werror=deprecated-declarations]
  134 |             Py_SetPythonHome(nxt_py_home);
      |             ^~~~~~~~~~~~~~~~
/opt/python-3.11/include/python3.11/pylifecycle.h:40:38: note: declared here
   40 | Py_DEPRECATED(3.11) PyAPI_FUNC(void) Py_SetPythonHome(const wchar_t *);
      |                                      ^~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors

We actually have a few config scenarios: Python &lt; 3, Python &gt;= 3.0 &lt; 3.8
and for Python 3 we have two configs where we select one based on
virtual environment setup.

Factor out the Python 3 config initialisation into its own function.  We
actually create two functions, one for Python 3.8+ and one for older
Python 3.  We pick the right function to use at build time.

The new API also has error checking (where the old API doesn't) which we
handle.

[0]: https://peps.python.org/pep-0587/

Closes: &lt;https://github.com/nginx/unit/issues/710&gt;
[ Andrew: Expanded upon patch from @sandeep-gh ]
Signed-off-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Refactored functions that set WSGI variables.</title>
<updated>2022-11-17T20:49:43+00:00</updated>
<author>
<name>OutOfFocus4</name>
<email>jeffrey_iadarola@urmc.rochester.edu</email>
</author>
<published>2022-11-06T14:08:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=6902cd14ad4e322be1c29564bc2e238d0a225e92'/>
<id>6902cd14ad4e322be1c29564bc2e238d0a225e92</id>
<content type='text'>
Splitting `nxt_python_add_sptr` into several functions will make future
additions easier.

Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Splitting `nxt_python_add_sptr` into several functions will make future
additions easier.

Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Removed dead code.</title>
<updated>2022-11-17T20:48:56+00:00</updated>
<author>
<name>OutOfFocus4</name>
<email>jeff.iadarola@gmail.com</email>
</author>
<published>2022-09-13T14:36:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=3b970ed9345ee2fe27f15b43ff827630d38cc124'/>
<id>3b970ed9345ee2fe27f15b43ff827630d38cc124</id>
<content type='text'>
Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Optimization for the "--no-unix-sockets" case.</title>
<updated>2022-11-15T00:17:32+00:00</updated>
<author>
<name>Andrei Zeliankou</name>
<email>zelenkov@nginx.com</email>
</author>
<published>2022-11-15T00:17:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=40d75c94a039f35505975736bb4f907ec456c9bd'/>
<id>40d75c94a039f35505975736bb4f907ec456c9bd</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
</feed>
