Files
meta-openembedded/meta-networking/recipes-devtools/python/python3-scapy/0002-main-initialize-banner-for-the-default-Python-shell.patch
Khem Raj c78566f4b0 python3-scapy: fix UnboundLocalError in interact()
The "Emulate interact()" UTScapy regression test failed:

    IPython requested but not found !
    Using the default Python shell: History is disabled.
    Traceback (most recent call last):
      File "/usr/lib/python3.14/site-packages/scapy/main.py", line 857, in interact
        banner += "\n"
    UnboundLocalError: cannot access local variable banner where it is
    not associated with a value

scapy.main.interact() only binds "banner" in the branches handling the
ipython, ptipython, ptpython and bpython shells. The test asks for
ipython, which is not in the image, so scapy falls back to the plain
Python shell and leaves "banner" unbound while still running the
unconditional "banner += \n" for the caller-supplied mybanner.

The test is correct and the bug is in scapy, which still has it in
master, so carry a patch initializing banner from banner_text before the
shell-specific chain.

meta-networking-image-ptest-python3-scapy now reports PASSED=319
FAILED=0, up from PASSED=318 FAILED=1.

Signed-off-by: Khem Raj <raj.khem@gmail.com>
2026-08-19 16:57:43 -07:00

45 lines
1.5 KiB
Diff

From 3d1f9f8043e239d6313d9b9c02a9d6ead6c32302 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Thu, 20 Aug 2026 00:14:29 +0200
Subject: [PATCH] main: initialize banner for the default Python shell
interact() only assigns the local variable "banner" in the branches that
handle the ipython, ptipython, ptpython and bpython shells. The plain
Python shell leaves it unbound, so the unconditional
banner += "\n"
in the "if mybanner is not None:" block raises
UnboundLocalError: cannot access local variable 'banner' where it is
not associated with a value
This is easy to hit: requesting an interpreter that is not installed
(e.g. conf.interactive_shell = "ipython" without IPython) falls back to
conf.interactive_shell = "python", and any caller passing mybanner then
crashes instead of getting a shell. The mybanneronly path happens to be
safe only because it assigns banner = "" first.
Initialize banner from banner_text before the shell-specific chain so it
is always bound.
Upstream-Status: Pending
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
scapy/main.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/scapy/main.py b/scapy/main.py
index 990f27f..924e6dc 100644
--- a/scapy/main.py
+++ b/scapy/main.py
@@ -828,6 +828,7 @@ def interact(mydict=None,
# repl.use_ui_colorscheme("scapy")
# Extend banner text
+ banner = banner_text
if conf.interactive_shell in ["ipython", "ptipython"]:
import IPython
if conf.interactive_shell == "ptipython":