Skip to content

Commit

Permalink
Merge pull request #2501 from jimklimov/issue-2183-stashAcopy
Browse files Browse the repository at this point in the history
Provide a private copy of `telnetlib` for `PyNUTClient`
  • Loading branch information
jimklimov authored Jul 2, 2024
2 parents 7719a56 + 84c8dde commit 2cf52b0
Show file tree
Hide file tree
Showing 11 changed files with 755 additions and 9 deletions.
4 changes: 4 additions & 0 deletions NEWS.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ https://github.com/networkupstools/nut/milestone/11
as a service, have a help message, pass debug verbosity to launched NUT
programs...) and add a man page for it. [issue #2432, PR #2446]
- 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]
- enabled installation of built single-file PDF and HTML (including man page
renditions) under the configured `docdir`. It seems previously they were
only built (if requested) but not installed via `make`, unlike the common
Expand Down
5 changes: 5 additions & 0 deletions ci_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2047,6 +2047,11 @@ bindings)
CONFIG_OPTS+=("--with-debuginfo=auto")
fi

if [ -n "${PYTHON-}" ]; then
# WARNING: Watch out for whitespaces, not handled here!
CONFIG_OPTS+=("--with-python=${PYTHON}")
fi

${CONFIGURE_SCRIPT} "${CONFIG_OPTS[@]}"

# NOTE: Currently parallel builds are expected to succeed (as far
Expand Down
17 changes: 16 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2447,7 +2447,7 @@ if test x"${nut_with_nut_monitor}" != xno ; then
fi

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])
AC_MSG_CHECKING([if we can and should install PyNUT module (note for warnings from python 3.11 and beyond: we have a fallback nut_telnetlib module just in case)])
nut_with_pynut_py=""
nut_with_pynut_py2=""
nut_with_pynut_py3=""
Expand All @@ -2469,6 +2469,15 @@ if test x"${nut_with_pynut}" != xno \
if ${PYTHON3} -c "import telnetlib" \
; then
nut_with_pynut_py3="yes"
else
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.
if (cd script/python/module && ${PYTHON3} -c "import nut_telnetlib as telnetlib") \
; then
nut_with_pynut_py3="yes"
fi
fi
fi

Expand All @@ -2480,6 +2489,12 @@ if test x"${nut_with_pynut}" != xno \
if ${PYTHON} -c "import telnetlib" \
; then
nut_with_pynut_py="yes"
else
dnl See comments above
if (cd script/python/module && ${PYTHON} -c "import nut_telnetlib as telnetlib") \
; then
nut_with_pynut_py="yes"
fi
fi
fi
fi
Expand Down
3 changes: 2 additions & 1 deletion docs/nut.dict
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
personal_ws-1.1 en 3172 utf-8
personal_ws-1.1 en 3173 utf-8
AAC
AAS
ABI
Expand Down Expand Up @@ -2888,6 +2888,7 @@ tcsetattr
tcsh
td
tdriver
telnetlib
tempmax
tempmin
termios
Expand Down
1 change: 1 addition & 0 deletions scripts/python/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ NUT_MONITOR_COMMON = \
app/locale/ru/LC_MESSAGES/NUT-Monitor.mo

PYNUT_COMMON = \
module/nut_telnetlib.py \
module/README.adoc

# Note: we both distribute and install the generated *.mo translation files
Expand Down
15 changes: 15 additions & 0 deletions scripts/python/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,21 @@ 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
7 changes: 5 additions & 2 deletions scripts/python/module/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ check-local:
tox: dist .pypi-tools-tox
tox

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

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

# README.txt is also a part of module standard expectations
.pypi-src: test_nutclient.py.in PyNUT.py.in setup.py.in README.adoc Makefile $(top_srcdir)/LICENSE-GPL3
# 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
@echo " PYPI Generate PyPI module source"
@rm -rf $(GENERATED_SRC) "$@"
@mkdir -p PyNUTClient
Expand All @@ -83,6 +85,7 @@ 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 ; \
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
18 changes: 15 additions & 3 deletions scripts/python/module/PyNUT.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,20 @@
# 2023-01-18 Jim Klimov <[email protected]> - Version 1.6.0
# Added CheckUPSAvailable() method originally by Michal Hlavinka
# from 2013-01-07 RedHat/Fedora packaging
#
# 2024-07-01 Jim Klimov <[email protected]> - Version 1.7.0
# Re-arranged dependency on telnetlib module (deprecated/removed
# since Python 3.11/3.13), so we can fall back on a privately
# stashed copy until a better solution is developed.
#

import telnetlib
try:
import telnetlib
except ModuleNotFoundError:
import os
if "true" == os.getenv('DEBUG', 'false'):
print( "[DEBUG] Fall back to private copy of telnetlib for PyNUTClient\n" )
import nut_telnetlib as telnetlib

class PyNUTError( Exception ) :
""" Base class for custom exceptions """
Expand All @@ -73,8 +85,8 @@ class PyNUTClient :
__timeout = None
__srv_handler = None

__version = "1.6.0"
__release = "2023-01-18"
__version = "1.7.0"
__release = "2024-07-01"


def __init__( self, host="127.0.0.1", port=3493, login=None, password=None, debug=False, timeout=5 ) :
Expand Down
Loading

0 comments on commit 2cf52b0

Please sign in to comment.