Skip to content
Open
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
37 changes: 14 additions & 23 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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`_).
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -164,18 +162,16 @@ 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.
Comment on lines +168 to +169
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we mention that it might work on older Python versions, but this is not tested / guaranteed to work ?


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
---------------
Expand Down Expand Up @@ -502,9 +498,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.

Expand Down Expand Up @@ -562,16 +558,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``

Expand All @@ -591,10 +586,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
Expand Down Expand Up @@ -784,7 +775,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).
Expand Down
5 changes: 0 additions & 5 deletions examples/menuconfig_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,6 @@
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)

Expand Down
13 changes: 2 additions & 11 deletions genconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,24 +131,15 @@ def main():
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()
43 changes: 12 additions & 31 deletions guiconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

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
Expand Down Expand Up @@ -55,23 +55,11 @@
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, \
Expand Down Expand Up @@ -395,8 +383,7 @@ def _init_misc_ui():
# Does misc. UI initialization, like setting the title, icon, and theme

_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)
Expand Down Expand Up @@ -514,9 +501,7 @@ def tree_select(_):
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"

Expand Down Expand Up @@ -1118,11 +1103,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)

Expand Down Expand Up @@ -1174,9 +1154,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")):
Expand All @@ -1187,7 +1168,7 @@ def ok(_=None):
dialog.destroy()

def cancel(_=None):
global _entry_res
nonlocal _entry_res
_entry_res = None
dialog.destroy()

Expand Down
Loading