Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Socketify pynut #2792

Merged
merged 16 commits into from
Feb 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions COPYING
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,7 @@
or (at your option) any later version. See "LICENSE-GPL2" in the root of this
distribution.

The scripts/python/module/nut_telnetlib.py file is copied for fall-back
purposes from Python 3.10, and released under its original license (the
PSF License Version 2). It was only modified in the comment section to
describe the copy, purpose and provenance per section 3 of the license.
According to https://github.com/python/cpython/blob/3.10/LICENSE most of
the licenses Python was provided under over the years are GPL-compatible.

Other files in the scripts/python/ directory are released under GNU General
Files in the scripts/python/ directory are released under GNU General
Public License (GPL) version 3, or (at your option) any later version. See
"LICENSE-GPL3" in the root of this distribution.

Expand Down
2 changes: 1 addition & 1 deletion NEWS.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ relocated into new `shutdown.default` INSTCMD definitions. [#2670]

- the `PyNUTClient` module should no longer rely on presence of a `telnetlib`
module in the build or execution environment (deprecated in Python 3.11,
removed since Python 3.13). [#2183]
removed since Python 3.13). [issue #2183, PR #2792]

- the PyPI distribution of the `PyNUTClient` module tarball should now use a
lower-cased file name (and immediate versioned directory name inside) to
Expand Down
93 changes: 20 additions & 73 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2921,97 +2921,44 @@ if test x"${nut_with_nut_monitor}" != xno ; then
fi
dnl ### AC_MSG_NOTICE([nut_with_nut_monitor-6: ${nut_with_nut_monitor}])

dnl Check if we can use distributed or fallback telnetlib module for PyNUTClient
nut_have_telnetlib_py=""
nut_have_telnetlib_py2=""
nut_have_telnetlib_py3=""
dnl ${nut_with_pynut}: TODO: arg values to request python 2, 3 or both
AC_MSG_CHECKING([if we can and should install PyNUT module])
nut_with_pynut_py=""
nut_with_pynut_py2=""
nut_with_pynut_py3=""
if test x"${nut_with_pynut}" != xno \
-a -n "${PYTHON}${PYTHON2}${PYTHON3}" \
; then
if test -n "${PYTHON2_VERSION_INFO_REPORT}" ; then
AC_MSG_CHECKING([if we can use stock Python2 telnetlib module provided with interpreter ${PYTHON2}])
if ${PYTHON2} -c "import telnetlib" \
if test -n "${PYTHON2}" \
&& (command -v ${PYTHON2} || which ${PYTHON2}) >/dev/null 2>/dev/null \
; then
if ${PYTHON2} -c "import socket" \
; then
nut_have_telnetlib_py2="yes"
else
nut_have_telnetlib_py2="no"
nut_with_pynut_py2="yes"
fi
AC_MSG_RESULT([${nut_have_telnetlib_py2}])
fi

if test -n "${PYTHON3_VERSION_INFO_REPORT}" ; then
AC_MSG_CHECKING([if we can use stock Python3 telnetlib module for PyNUTClient provided with interpreter ${PYTHON3} (note for warnings from Python 3.11 and beyond: we have a fallback nut_telnetlib module just in case)])
if ${PYTHON3} -c "import telnetlib" \
if test -n "${PYTHON3}" \
&& (command -v ${PYTHON3} || which ${PYTHON3}) >/dev/null 2>/dev/null \
; then
if ${PYTHON3} -c "import socket" \
; then
nut_have_telnetlib_py3="yes"
else
nut_have_telnetlib_py3="no"
fi
AC_MSG_RESULT([${nut_have_telnetlib_py3}])

if test x"${nut_have_telnetlib_py3}" = x"no" ; then
dnl We have a stashed copy from Python 3.10, so
dnl this line essentially checks for presence of
dnl a usable interpreter implementation compatible
dnl with Python 3.x syntax.
AC_MSG_CHECKING([if we can use fallback Python3 nut_telnetlib module for PyNUTClient])
if (cd "${srcdir}"/scripts/python/module && ${PYTHON3} -c "import nut_telnetlib as telnetlib") \
; then
nut_have_telnetlib_py3="yes"
fi
AC_MSG_RESULT([${nut_have_telnetlib_py3}])
nut_with_pynut_py3="yes"
fi
fi

dnl Test same-ness of pythons with sys.version also?
if test -n "${PYTHON_VERSION_INFO_REPORT}" \
&& test x"${PYTHON_VERSION_INFO_REPORT}" != x"${PYTHON3_VERSION_INFO_REPORT}" \
&& test x"${PYTHON_VERSION_INFO_REPORT}" != x"${PYTHON2_VERSION_INFO_REPORT}" \
if test -n "${PYTHON}" \
&& (command -v ${PYTHON} || which ${PYTHON}) >/dev/null 2>/dev/null \
&& test "${PYTHON}" != "${PYTHON2}" -a "${PYTHON}" != "${PYTHON3}" \
; then
AC_MSG_CHECKING([if we can use stock Python telnetlib module for PyNUTClient provided with interpreter ${PYTHON} (note for warnings from Python 3.11 and beyond: we have a fallback nut_telnetlib module just in case)])
if ${PYTHON} -c "import telnetlib" \
if ${PYTHON} -c "import socket" \
; then
nut_have_telnetlib_py="yes"
else
nut_have_telnetlib_py="no"
fi
AC_MSG_RESULT([${nut_have_telnetlib_py}])

if test x"${nut_have_telnetlib_py}" = x"no" ; then
dnl See comments above
AC_MSG_CHECKING([if we can use fallback Python nut_telnetlib module for PyNUTClient])
if (cd "${srcdir}"/scripts/python/module && ${PYTHON} -c "import nut_telnetlib as telnetlib") \
; then
nut_have_telnetlib_py="yes"
fi
AC_MSG_RESULT([${nut_have_telnetlib_py}])
nut_with_pynut_py="yes"
fi
fi
fi

dnl ${nut_with_pynut}: TODO: arg values to request Python 2, 3 or both
dnl Note that per block above, nut_have_telnetlib_py* values are definitive
dnl if checked, or empty if skipped (no such Python, not nut_with_pynut, etc.)
AC_MSG_CHECKING([if we can and should install PyNUT module])
nut_with_pynut_py=""
nut_with_pynut_py2=""
nut_with_pynut_py3=""
if test x"${nut_with_pynut}" != xno \
-a -n "${PYTHON}${PYTHON2}${PYTHON3}" \
; then
if test x"${nut_have_telnetlib_py2}" = x"yes" ; then
nut_with_pynut_py2="yes"
fi

if test x"${nut_have_telnetlib_py3}" = x"yes" ; then
nut_with_pynut_py3="yes"
fi

if test x"${nut_have_telnetlib_py}" = x"yes" ; then
nut_with_pynut_py="yes"
fi
fi

if test -z "${nut_with_pynut_py}${nut_with_pynut_py2}${nut_with_pynut_py3}" ; then
dnl Not all prereqs are available...
case "${nut_with_pynut}" in
Expand Down
3 changes: 0 additions & 3 deletions scripts/python/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ NUT_MONITOR_COMMON = \
app/locale/it/LC_MESSAGES/NUT-Monitor.mo \
app/locale/ru/LC_MESSAGES/NUT-Monitor.mo

PYNUT_COMMON_CODE = \
module/nut_telnetlib.py

PYNUT_COMMON_MISC = \
module/README.adoc

Expand Down
15 changes: 0 additions & 15 deletions scripts/python/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,6 @@ and protocol support.

For one practical example, you can research `tests/NIT/nit.sh` in NUT sources.

telnetlib
^^^^^^^^^

Historically, the `PyNUTClient` class relied on `telnetlib` module for socket
communications with the NUT data server, which was provided as part of Python
core installation with tested 2.6+ and 3.* versions. The module was, however,
marked deprecated since Python 3.11 and not provided since 3.13. Due to this,
as a quick stop-gap solution, NUT sources provide `nut_telnetlib.py` -- a copy
of the module from Python 3.10 installation, and no longer should require its
presence in the Python deployment.

A better solution would be to find or create a new layer for the constrained
use-case of NUT client interactions with a data server, which do not need the
fully fledged Telnet-like capabilities.

app
~~~

Expand Down
10 changes: 2 additions & 8 deletions scripts/python/module/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ check-local:
tox: dist .pypi-tools-tox
tox

EXTRA_DIST = tox.ini MANIFEST.in nut_telnetlib.py
EXTRA_DIST = tox.ini MANIFEST.in

NUT_SOURCE_GITREV_NUMERIC = @NUT_SOURCE_GITREV_NUMERIC@
PYTHON = @PYTHON@
Expand Down Expand Up @@ -68,9 +68,7 @@ upload publish:
esac

# README.txt is also a part of module standard expectations
# nut_telnetlib.py is not converted from a .in template, it
# does not even have a shebang line.
.pypi-src: test_nutclient.py.in PyNUT.py.in setup.py.in nut_telnetlib.py README.adoc Makefile $(top_srcdir)/LICENSE-GPL3
.pypi-src: test_nutclient.py.in PyNUT.py.in setup.py.in README.adoc Makefile $(top_srcdir)/LICENSE-GPL3
@echo " PYPI Generate PyPI module source"
@rm -rf $(GENERATED_SRC) "$@"
@mkdir -p PyNUTClient
Expand All @@ -89,10 +87,6 @@ upload publish:
sed -e "s,[@]PYTHON[@],@PYTHON@," < "$(srcdir)/$${B}.in" > "PyNUTClient/$${B}" || exit ; \
if test -x "$(srcdir)/$${B}.in" ; then chmod +x "PyNUTClient/$${B}"; fi ; \
done ; \
cp -pf "$(srcdir)/nut_telnetlib.py" PyNUTClient/ || exit ; \
if [ x"$(abs_srcdir)" != x"$(abs_builddir)" ] ; then \
cp -pf "$(srcdir)/nut_telnetlib.py" . || exit ; \
fi ; \
cp -pf "$(srcdir)/README.adoc" README.txt || exit ; \
cp -pf "$(top_srcdir)/LICENSE-GPL3" . || exit ; \
echo "from . import PyNUT" > PyNUTClient/__init__.py || exit
Expand Down
Loading