summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Cabé <benjamin@zephyrproject.org>2025-10-23 17:25:08 +0200
committerTorsten Tejlmand Rasmussen <torsten.rasmussen@nordicsemi.no>2026-02-02 08:22:15 +0100
commit24aef157aead07f813f874f43ee471b057e622cb (patch)
tree57cbb867898e31f9efb3fcce0997ecd3267ea1cc
parentffb54593b899c42fe70e55d26e02d4cd4a9ca53d (diff)
drop support for Python 2.x as it is very much EOL
A follow-up to b96a5ad562deffa697d966c29546650aae645f48 where we stopped having CI run tests on Python 2.x. This actually drops the few remaining Python 2.x compatibility bits as Python 2.x has EOL'd a long time ago. Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org> Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
-rw-r--r--README.rst40
-rwxr-xr-xexamples/menuconfig_example.py5
-rwxr-xr-xgenconfig.py13
-rwxr-xr-xguiconfig.py43
-rw-r--r--kconfiglib.py132
-rwxr-xr-xlistnewconfig.py7
-rwxr-xr-xmenuconfig.py30
-rwxr-xr-xoldconfig.py5
-rw-r--r--setup.cfg4
-rw-r--r--setup.py23
-rwxr-xr-xtests/reltest8
-rw-r--r--testsuite.py27
12 files changed, 85 insertions, 252 deletions
diff --git a/README.rst b/README.rst
index a3469f5..8d31730 100644
--- a/README.rst
+++ b/README.rst
@@ -33,7 +33,7 @@ Overview
Kconfiglib is a `Kconfig
<https://github.com/torvalds/linux/blob/master/Documentation/kbuild/kconfig-language.rst>`__
-implementation in Python 2/3. It started out as a helper library, but now has a
+implementation in Python 3. It started out as a helper library, but now has a
enough functionality to also work well as a standalone Kconfig implementation
(including `terminal and GUI menuconfig interfaces <Menuconfig interfaces_>`_
and `Kconfig extensions`_).
@@ -121,9 +121,7 @@ available in the C tools.
the configuration and (optionally) information that can be used to rebuild only
files that reference Kconfig symbols that have changed value.
-Starting with Kconfiglib version 12.2.0, all utilities are compatible with both
-Python 2 and Python 3. Previously, ``menuconfig.py`` only ran under Python 3
-(i.e., it's now more backwards compatible than before).
+All utilities run under Python 3.
**Note:** If you install Kconfiglib with ``pip``'s ``--user`` flag, make sure
that your ``PATH`` includes the directory where the executables end up. You can
@@ -164,18 +162,13 @@ Installation for the Linux kernel
See the module docstring at the top of `kconfiglib.py <https://github.com/zephyrproject-rtos/Kconfiglib/blob/master/kconfiglib.py>`_.
-Python version compatibility (2.7/3.2+)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Python version compatibility
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Kconfiglib and all utilities run under both Python 2.7 and Python 3.2 and
-later. The code mostly uses basic Python features and has no third-party
-dependencies, so keeping it backwards-compatible is pretty low effort.
+Kconfiglib and all utilities run under Python 3.9 and later. The code mostly
+uses basic Python features and has no third-party dependencies.
-The 3.2 requirement comes from ``argparse``. ``format()`` with unnumbered
-``{}`` is used as well.
-
-A recent Python 3 version is recommended if you have a choice, as it'll give
-you better Unicode handling.
+A recent Python 3 version is recommended for better Unicode handling.
Getting started
---------------
@@ -502,9 +495,9 @@ Other features
- **Windows support**
- Nothing Linux-specific is used. Universal newlines mode is used for both
- Python 2 and Python 3.
-
+ Nothing Linux-specific is used. Universal newlines mode is used for
+ interoperability between Linux and Windows.
+
The `Zephyr <https://www.zephyrproject.org/>`_ project uses Kconfiglib to
generate ``.config`` files and C headers on Linux as well as Windows.
@@ -562,16 +555,15 @@ Three configuration interfaces are currently available:
the terminal menuconfig. Only this mode distinguishes between symbols defined
with ``config`` and symbols defined with ``menuconfig``.
- ``guiconfig.py`` has been tested on X11, Windows, and macOS, and is
- compatible with both Python 2 and Python 3.
+ ``guiconfig.py`` has been tested on X11, Windows, and macOS.
Despite being part of the Python standard library, ``tkinter`` often isn't
included by default in Python installations on Linux. These commands will
install it on a few different distributions:
- - Ubuntu: ``sudo apt install python-tk``/``sudo apt install python3-tk``
+ - Ubuntu: ``sudo apt install python3-tk``
- - Fedora: ``dnf install python2-tkinter``/``dnf install python3-tkinter``
+ - Fedora: ``dnf install python3-tkinter``
- Arch: ``sudo pacman -S tk``
@@ -591,10 +583,6 @@ Three configuration interfaces are currently available:
I did my best with the images, but some are definitely only art adjacent.
Touch-ups are welcome. :)
-- `pymenuconfig <https://github.com/RomaVis/pymenuconfig>`_, built by `RomaVis
- <https://github.com/RomaVis>`_, is an older portable Python 2/3 TkInter
- menuconfig implementation.
-
Screenshot below:
.. image:: https://raw.githubusercontent.com/RomaVis/pymenuconfig/master/screenshot.PNG
@@ -784,7 +772,7 @@ configurations generated by the C tools, for a number of cases. See
for the available options.
The `tests/reltest <https://github.com/zephyrproject-rtos/Kconfiglib/blob/master/tests/reltest>`_ script runs the test suite
-and all the example scripts for both Python 2 and Python 3, verifying that everything works.
+and all the example scripts, verifying that everything works.
Rarely, the output from the C tools is changed slightly (most recently due to a
`change <https://www.spinics.net/lists/linux-kbuild/msg17074.html>`_ I added).
diff --git a/examples/menuconfig_example.py b/examples/menuconfig_example.py
index 606f756..9221e4c 100755
--- a/examples/menuconfig_example.py
+++ b/examples/menuconfig_example.py
@@ -130,11 +130,6 @@ from kconfiglib import Kconfig, \
TRI_TO_STR
-# Python 2/3 compatibility hack
-if sys.version_info[0] < 3:
- input = raw_input
-
-
def indent_print(s, indent):
print(indent*" " + s)
diff --git a/genconfig.py b/genconfig.py
index 62f065b..aa0b472 100755
--- a/genconfig.py
+++ b/genconfig.py
@@ -131,24 +131,15 @@ only supported for backwards compatibility).
kconf.sync_deps(args.sync_deps)
if args.file_list is not None:
- with _open_write(args.file_list) as f:
+ with open(args.file_list, "w", encoding="utf-8") as f:
for path in kconf.kconfig_filenames:
f.write(path + "\n")
if args.env_list is not None:
- with _open_write(args.env_list) as f:
+ with open(args.env_list, "w", encoding="utf-8") as f:
for env_var in kconf.env_vars:
f.write("{}={}\n".format(env_var, os.environ[env_var]))
-def _open_write(path):
- # Python 2/3 compatibility. io.open() is available on both, but makes
- # write() expect 'unicode' strings on Python 2.
-
- if sys.version_info[0] < 3:
- return open(path, "w")
- return open(path, "w", encoding="utf-8")
-
-
if __name__ == "__main__":
main()
diff --git a/guiconfig.py b/guiconfig.py
index 21f034e..da3b486 100755
--- a/guiconfig.py
+++ b/guiconfig.py
@@ -9,7 +9,7 @@ Overview
A Tkinter-based menuconfig implementation, based around a treeview control and
a help display. The interface should feel familiar to people used to qconf
-('make xconfig'). Compatible with both Python 2 and Python 3.
+('make xconfig').
The display can be toggled between showing the full tree and showing just a
single menu (like menuconfig.py). Only single-menu mode distinguishes between
@@ -55,23 +55,11 @@ $srctree is supported through Kconfiglib.
import errno
import os
import re
-import sys
-
-_PY2 = sys.version_info[0] < 3
-
-if _PY2:
- # Python 2
- from Tkinter import *
- import ttk
- import tkFont as font
- import tkFileDialog as filedialog
- import tkMessageBox as messagebox
-else:
- # Python 3
- from tkinter import *
- import tkinter.ttk as ttk
- import tkinter.font as font
- from tkinter import filedialog, messagebox
+
+from tkinter import *
+import tkinter.ttk as ttk
+import tkinter.font as font
+from tkinter import filedialog, messagebox
from kconfiglib import Symbol, Choice, MENU, COMMENT, MenuNode, \
BOOL, TRISTATE, STRING, INT, HEX, \
@@ -438,8 +426,7 @@ def _init_misc_ui():
_dark_mode = _detect_system_dark_mode()
_root.title(_kconf.mainmenu_text)
- # iconphoto() isn't available in Python 2's Tkinter
- _root.tk.call("wm", "iconphoto", _root._w, "-default", _icon_img)
+ _root.iconphoto(True, _icon_img)
# Reducing the width of the window to 1 pixel makes it move around, at
# least on GNOME. Prevent weird stuff like that.
_root.minsize(128, 128)
@@ -616,9 +603,7 @@ def _create_kconfig_tree_and_desc(parent):
desc["state"] = "disabled"
return
- # Text.replace() is not available in Python 2's Tkinter
- desc.delete("1.0", "end")
- desc.insert("end", _info_str(_id_to_node[sel[0]]))
+ desc.replace("1.0", "end", _info_str(_id_to_node[sel[0]]))
desc["state"] = "disabled"
@@ -1230,11 +1215,6 @@ def _change_node(node, parent):
if sc.type in (INT, HEX, STRING):
s = _set_val_dialog(node, parent)
- # Tkinter can return 'unicode' strings on Python 2, which Kconfiglib
- # can't deal with. UTF-8-encode the string to work around it.
- if _PY2 and isinstance(s, unicode):
- s = s.encode("utf-8", "ignore")
-
if s is not None:
_set_val(sc, s)
@@ -1286,9 +1266,10 @@ def _set_val_dialog(node, parent):
# Pops up a dialog for setting the value of the string/int/hex
# symbol at node 'node'. 'parent' is the parent window.
+ _entry_res = None
+
def ok(_=None):
- # No 'nonlocal' in Python 2
- global _entry_res
+ nonlocal _entry_res
s = entry.get()
if sym.type == HEX and not s.startswith(("0x", "0X")):
@@ -1299,7 +1280,7 @@ def _set_val_dialog(node, parent):
dialog.destroy()
def cancel(_=None):
- global _entry_res
+ nonlocal _entry_res
_entry_res = None
dialog.destroy()
diff --git a/kconfiglib.py b/kconfiglib.py
index ce40eb7..2bbc517 100644
--- a/kconfiglib.py
+++ b/kconfiglib.py
@@ -5,7 +5,7 @@
Overview
========
-Kconfiglib is a Python 2/3 library for scripting and extracting information
+Kconfiglib is a Python 3 library for scripting and extracting information
from Kconfig (https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt)
configuration systems.
@@ -52,17 +52,14 @@ sections.
make kmenuconfig
----------------
-This target runs the curses menuconfig interface with Python 3. As of
-Kconfiglib 12.2.0, both Python 2 and Python 3 are supported (previously, only
-Python 3 was supported, so this was a backport).
+This target runs the curses menuconfig interface with Python 3.
make guiconfig
--------------
-This target runs the Tkinter menuconfig interface. Both Python 2 and Python 3
-are supported. To change the Python interpreter used, pass
-PYTHONCMD=<executable> to 'make'. The default is 'python'.
+This target runs the Tkinter menuconfig interface. To change the Python
+interpreter used, pass PYTHONCMD=<executable> to 'make'. The default is 'python'.
make [ARCH=<arch>] iscriptconfig
@@ -878,11 +875,8 @@ class Kconfig(object):
Raises KconfigError on syntax/semantic errors, and OSError or (possibly
a subclass of) IOError on IO errors ('errno', 'strerror', and
- 'filename' are available). Note that IOError is an alias for OSError on
- Python 3, so it's enough to catch OSError there. If you need Python 2/3
- compatibility, it's easiest to catch EnvironmentError, which is a
- common base class of OSError/IOError on Python 2 and an alias for
- OSError on Python 3.
+ 'filename' are available). Note that IOError is an alias for OSError in
+ Python 3, so it's enough to catch OSError.
filename (default: "Kconfig"):
The Kconfig file to load. For the Linux kernel, you'll want "Kconfig"
@@ -925,11 +919,6 @@ class Kconfig(object):
The "utf-8" default avoids exceptions on systems that are configured
to use the C locale, which implies an ASCII encoding.
- This parameter has no effect on Python 2, due to implementation
- issues (regular strings turning into Unicode strings, which are
- distinct in Python 2). Python 2 doesn't decode regular strings
- anyway.
-
Related PEP: https://www.python.org/dev/peps/pep-0538/
suppress_traceback (default: False):
@@ -2118,18 +2107,12 @@ class Kconfig(object):
try:
return self._open(join(self.srctree, filename), "r")
except EnvironmentError as e2:
- # This is needed for Python 3, because e2 is deleted after
- # the try block:
- #
- # https://docs.python.org/3/reference/compound_stmts.html#the-try-statement
- e = e2
-
- raise _KconfigIOError(
- e, "Could not open '{}' ({}: {}). Check that the $srctree "
- "environment variable ({}) is set correctly."
- .format(filename, errno.errorcode[e.errno], e.strerror,
- "set to '{}'".format(self.srctree) if self.srctree
- else "unset or blank"))
+ raise _KconfigIOError(
+ e2, "Could not open '{}' ({}: {}). Check that the $srctree "
+ "environment variable ({}) is set correctly."
+ .format(filename, errno.errorcode[e.errno], e.strerror,
+ "set to '{}'".format(self.srctree) if self.srctree
+ else "unset or blank"))
def _enter_file(self, filename):
# Jumps to the beginning of a sourced Kconfig file, saving the previous
@@ -3895,41 +3878,8 @@ class Kconfig(object):
self._parse_error("extra tokens at end of line")
def _open(self, filename, mode):
- # open() wrapper:
- #
- # - Enable universal newlines mode on Python 2 to ease
- # interoperability between Linux and Windows. It's already the
- # default on Python 3.
- #
- # The "U" flag would currently work for both Python 2 and 3, but it's
- # deprecated on Python 3, so play it future-safe.
- #
- # io.open() defaults to universal newlines on Python 2 (and is an
- # alias for open() on Python 3), but it returns 'unicode' strings and
- # slows things down:
- #
- # Parsing x86 Kconfigs on Python 2
- #
- # with open(..., "rU"):
- #
- # real 0m0.930s
- # user 0m0.905s
- # sys 0m0.025s
- #
- # with io.open():
- #
- # real 0m1.069s
- # user 0m1.040s
- # sys 0m0.029s
- #
- # There's no appreciable performance difference between "r" and
- # "rU" for parsing performance on Python 2.
- #
- # - For Python 3, force the encoding. Forcing the encoding on Python 2
- # turns strings into Unicode strings, which gets messy. Python 2
- # doesn't decode regular strings anyway.
- return open(filename, "rU" if mode == "r" else mode) if _IS_PY2 else \
- open(filename, mode, encoding=self._encoding)
+ # open() wrapper that forces the encoding
+ return open(filename, mode, encoding=self._encoding)
def _check_undef_syms(self):
# Prints warnings for all references to undefined symbols within the
@@ -3958,7 +3908,7 @@ class Kconfig(object):
return True
- for sym in (self.syms.viewvalues if _IS_PY2 else self.syms.values)():
+ for sym in self.syms.values():
# - sym.nodes empty means the symbol is undefined (has no
# definition locations)
#
@@ -6513,16 +6463,9 @@ def _save_old(path):
if islink(path):
# Preserve symlinks
copy_fn = copy
- elif hasattr(os, "replace"):
- # Python 3 (3.3+) only. Best choice when available, because it
- # removes <filename>.old on both *nix and Windows.
- copy_fn = os.replace
- elif os.name == "posix":
- # Removes <filename>.old on POSIX systems
- copy_fn = os.rename
else:
- # Fall back on copying
- copy_fn = copy
+ # atomic replace of <filename>.old
+ copy_fn = os.replace
try:
copy_fn(path, path + ".old")
@@ -6894,30 +6837,21 @@ def _error_if_fn(kconf, _, cond, msg):
def _shell_fn(kconf, _, command):
import subprocess # Only import as needed, to save some startup time
- stdout, stderr = subprocess.Popen(
- command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
- ).communicate()
-
- if not _IS_PY2:
- try:
- stdout = stdout.decode(kconf._encoding)
- stderr = stderr.decode(kconf._encoding)
- except UnicodeDecodeError as e:
- _decoding_error(e, kconf.filename, kconf.linenr)
+ result = subprocess.run(
+ command,
+ shell=True,
+ capture_output=True,
+ text=True,
+ encoding=kconf._encoding
+ )
- if stderr:
+ if result.stderr:
kconf._warn("'{}' wrote to stderr: {}".format(
- command, "\n".join(stderr.splitlines())),
+ command, "\n".join(result.stderr.splitlines())),
kconf.loc)
- # Universal newlines with splitlines() (to prevent e.g. stray \r's in
- # command output on Windows), trailing newline removal, and
- # newline-to-space conversion.
- #
- # On Python 3 versions before 3.6, it's not possible to specify the
- # encoding when passing universal_newlines=True to Popen() (the 'encoding'
- # parameter was added in 3.6), so we do this manual version instead.
- return "\n".join(stdout.splitlines()).rstrip("\n").replace("\n", " ")
+ # Trailing newline removal, and newline-to-space conversion.
+ return result.stdout.rstrip("\n").replace("\n", " ")
#
# Global constants
@@ -6940,9 +6874,6 @@ STR_TO_TRI = {
# Symbol will do. We test this with 'is'.
_NO_CACHED_SELECTION = 0
-# Are we running on Python 2?
-_IS_PY2 = sys.version_info[0] < 3
-
try:
_UNAME_RELEASE = os.uname()[2]
except AttributeError:
@@ -7231,15 +7162,14 @@ KIND_TO_STR = {
# Helper functions for getting compiled regular expressions, with the needed
# matching function returned directly as a small optimization.
#
-# Use ASCII regex matching on Python 3. It's already the default on Python 2.
-
+# Use ASCII regex matching on Python 3.
def _re_match(regex):
- return re.compile(regex, 0 if _IS_PY2 else re.ASCII).match
+ return re.compile(regex, re.ASCII).match
def _re_search(regex):
- return re.compile(regex, 0 if _IS_PY2 else re.ASCII).search
+ return re.compile(regex, re.ASCII).search
# Various regular expressions used during parsing
diff --git a/listnewconfig.py b/listnewconfig.py
index 8276de1..18209ce 100755
--- a/listnewconfig.py
+++ b/listnewconfig.py
@@ -15,6 +15,7 @@ from __future__ import print_function
import argparse
import sys
+import textwrap
from kconfiglib import Kconfig, BOOL, TRISTATE, INT, HEX, STRING, TRI_TO_STR
@@ -65,10 +66,8 @@ def main():
if args.show_help:
for node in sym.nodes:
if node.help is not None:
- # Indent by two spaces. textwrap.indent() is not
- # available in Python 2 (it's 3.3+).
- print("\n".join(" " + line
- for line in node.help.split("\n")))
+ # Indent by two spaces.
+ print(textwrap.indent(node.help, " "))
break
diff --git a/menuconfig.py b/menuconfig.py
index 178fbc1..01ac624 100755
--- a/menuconfig.py
+++ b/menuconfig.py
@@ -7,7 +7,7 @@
Overview
========
-A curses-based Python 2/3 menuconfig implementation. The interface should feel
+A curses-based Python 3 menuconfig implementation. The interface should feel
familiar to people used to mconf ('make menuconfig').
Supports the same keys as mconf, and also supports a set of keybindings
@@ -989,12 +989,7 @@ def _init():
# Looking for this in addition to KEY_BACKSPACE (which is unreliable) makes
# backspace work with TERM=vt100. That makes it likely to work in sane
# environments.
- _ERASE_CHAR = curses.erasechar()
- if sys.version_info[0] >= 3:
- # erasechar() returns a one-byte bytes object on Python 3. This sets
- # _ERASE_CHAR to a blank string if it can't be decoded, which should be
- # harmless.
- _ERASE_CHAR = _ERASE_CHAR.decode("utf-8", "ignore")
+ _ERASE_CHAR = curses.erasechar().decode("utf-8", "ignore")
_init_styles()
@@ -2141,11 +2136,7 @@ def _jump_to_dialog():
except re.error as e:
# Bad regex. Remember the error message so we can show it.
- bad_re = "Bad regular expression"
- # re.error.msg was added in Python 3.5
- if hasattr(e, "msg"):
- bad_re += ": " + e.msg
-
+ bad_re = f"Bad regular expression: {e.msg}"
matches = []
# Reset scroll and jump to the top of the list of matches
@@ -2648,7 +2639,7 @@ def _help_info(sc):
for node in sc.nodes:
if node.help is not None:
- s += "Help:\n\n{}\n\n".format(_indent(node.help, 2))
+ s += "Help:\n\n{}\n\n".format(textwrap.indent(node.help, " "))
return s
@@ -2790,7 +2781,7 @@ def _kconfig_def_info(item):
.format(node.filename, node.linenr,
_include_path_info(node),
_menu_path_info(node),
- _indent(node.custom_str(_name_and_val_str), 2))
+ textwrap.indent(node.custom_str(_name_and_val_str), " "))
return s
@@ -2822,13 +2813,6 @@ def _menu_path_info(node):
return "(Top)" + path
-def _indent(s, n):
- # Returns 's' with each line indented 'n' spaces. textwrap.indent() is not
- # available in Python 2 (it's 3.3+).
-
- return "\n".join(n*" " + line for line in s.split("\n"))
-
-
def _name_and_val_str(sc):
# Custom symbol/choice printer that shows symbol values after symbols
@@ -3155,9 +3139,7 @@ def _is_num(name):
def _getch_compat(win):
- # Uses get_wch() if available (Python 3.3+) and getch() otherwise.
- #
- # Also falls back on getch() if get_wch() raises curses.error, to work
+ # Fall back on getch() if get_wch() raises curses.error, to work
# around an issue when resizing the terminal on at least macOS Catalina.
# See https://github.com/ulfalizer/Kconfiglib/issues/84.
#
diff --git a/oldconfig.py b/oldconfig.py
index 53434b2..b66c842 100755
--- a/oldconfig.py
+++ b/oldconfig.py
@@ -32,11 +32,6 @@ import sys
from kconfiglib import Symbol, Choice, BOOL, TRISTATE, HEX, standard_kconfig
-# Python 2/3 compatibility hack
-if sys.version_info[0] < 3:
- input = raw_input
-
-
def _main():
# Earlier symbols in Kconfig files might depend on later symbols and become
# visible if their values change. This flag is set to True if the value of
diff --git a/setup.cfg b/setup.cfg
index 185845e..7604a2c 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,7 +1,3 @@
-[bdist_wheel]
-# We support both Python 2 and Python 3
-universal = 1
-
[metadata]
# Include the license file in wheels
license_file = LICENSE.txt
diff --git a/setup.py b/setup.py
index 6b8d905..ca308d2 100644
--- a/setup.py
+++ b/setup.py
@@ -9,17 +9,11 @@ setuptools.setup(
# MAJOR.MINOR.PATCH, per http://semver.org
version="14.1.1a4",
description="A flexible Python Kconfig implementation",
-
- # Make sure that README.rst decodes on Python 3 in environments that use
+ # Make sure that README.rst decodes correctly in environments that use
# the C locale (which implies ASCII), by explicitly giving the encoding.
- #
- # io.open() has the 'encoding' parameter on both Python 2 and 3. open()
- # doesn't have it on Python 2. This lets us use the same code for both.
long_description=io.open(
- os.path.join(os.path.dirname(__file__), "README.rst"),
- encoding="utf-8"
+ os.path.join(os.path.dirname(__file__), "README.rst"), encoding="utf-8"
).read(),
-
url="https://github.com/zephyrproject-rtos/Kconfiglib",
author='Zephyr Project',
author_email="ci@zephyrproject.org",
@@ -64,9 +58,7 @@ setuptools.setup(
# Note: windows-curses is not automatically installed on Windows anymore,
# because it made Kconfiglib impossible to install on MSYS2 with pip
- # Needs support for unnumbered {} in format() and argparse
- python_requires=">=2.7,!=3.0.*,!=3.1.*",
-
+ python_requires=">=3.9",
project_urls={
"GitHub repository": "https://github.com/zephyrproject-rtos/Kconfiglib",
"Examples": "https://github.com/zephyrproject-rtos/Kconfiglib/tree/master/examples",
@@ -80,16 +72,7 @@ setuptools.setup(
"License :: OSI Approved :: ISC License (ISCL)",
"Operating System :: POSIX",
"Operating System :: Microsoft :: Windows",
- "Programming Language :: Python :: 2",
- "Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.2",
- "Programming Language :: Python :: 3.3",
- "Programming Language :: Python :: 3.4",
- "Programming Language :: Python :: 3.5",
- "Programming Language :: Python :: 3.6",
- "Programming Language :: Python :: 3.7",
- "Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
diff --git a/tests/reltest b/tests/reltest
index f0c0645..2a1d8db 100755
--- a/tests/reltest
+++ b/tests/reltest
@@ -1,8 +1,8 @@
#!/usr/bin/env bash
-# Runs the test suite and all examples scripts with Python 2 and Python 3,
-# bailing immediately if anything fails. For the examples that aren't tested in
-# the test suite, we just confirm that they at least run.
+# Runs the test suite and all examples scripts, bailing immediately if anything
+# fails. For the examples that aren't tested in the test suite, we just confirm
+# that they at least run.
#
# Should be run from the kernel root with $ Kconfiglib/tests/reltest
@@ -21,7 +21,7 @@ test_script() {
}
if [ $# == "0" ]; then
- py_execs="python2 python3"
+ py_execs="python3"
else
py_execs=$@
fi
diff --git a/testsuite.py b/testsuite.py
index b4f5e2b..7bc9804 100644
--- a/testsuite.py
+++ b/testsuite.py
@@ -2699,16 +2699,12 @@ config PRINT_ME_TOO
sys.path.pop(0)
- # This test can fail on older Python 3.x versions, because they don't
- # preserve dict insertion order during iteration. The output is still
- # correct, just different.
- if not (3, 0) <= sys.version_info <= (3, 5):
- print("Testing KCONFIG_WARN_UNDEF")
+ print("Testing KCONFIG_WARN_UNDEF")
- os.environ["KCONFIG_WARN_UNDEF"] = "y"
- c = Kconfig("Kconfiglib/tests/Kundef", warn_to_stderr=False)
+ os.environ["KCONFIG_WARN_UNDEF"] = "y"
+ c = Kconfig("Kconfiglib/tests/Kundef", warn_to_stderr=False)
- verify_equal("\n".join(c.warnings), """
+ verify_equal("\n".join(c.warnings), """
warning: the int symbol INT (defined at Kconfiglib/tests/Kundef:8) has a non-int range [UNDEF_2 (undefined), 8 (undefined)]
warning: undefined symbol UNDEF_1:
@@ -2747,7 +2743,7 @@ menu "menu"
visible if UNDEF_3
"""[1:-1])
- os.environ.pop("KCONFIG_WARN_UNDEF")
+ os.environ.pop("KCONFIG_WARN_UNDEF")
print("\nAll selftests passed\n" if all_passed else
@@ -2760,8 +2756,8 @@ def run_compatibility_tests():
# Referenced inside the kernel Kconfig files.
#
- # The str() makes the type of the value 'str' on both Python 2 and Python 3,
- # which is nice for some later dictionary key sanity checks.
+ # The str() makes the type of the value 'str', which is nice for some later
+ # dictionary key sanity checks.
os.environ["KERNELVERSION"] = str(
subprocess.check_output("make kernelversion", shell=True)
@@ -2932,13 +2928,10 @@ def test_sanity(arch, srcarch):
kconf.write_autoconf("/dev/null")
- # No tempfile.TemporaryDirectory in Python 2
- tmpdir = tempfile.mkdtemp()
- kconf.sync_deps(os.path.join(tmpdir, "deps")) # Create
- kconf.sync_deps(os.path.join(tmpdir, "deps")) # Update
- shutil.rmtree(tmpdir)
+ with tempfile.TemporaryDirectory() as tmpdir:
+ kconf.sync_deps(os.path.join(tmpdir, "deps")) # Create
+ kconf.sync_deps(os.path.join(tmpdir, "deps")) # Update
- # Python 2/3 compatible
for key, sym in kconf.syms.items():
verify(isinstance(key, str), "weird key '{}' in syms dict".format(key))