feat: Remove .py suffix from scripts

BREAKING CHANGE:
- The .py suffix is deprecated for the following scripts:
  - esptool
  - espefuse
  - espsecure
  - esp_rfc2217_server
This commit is contained in:
Peter Dragun
2025-06-17 14:18:41 +02:00
parent 33711c46e1
commit 635cde1ef0
8 changed files with 109 additions and 10 deletions

View File

@@ -5,6 +5,46 @@
This document describes the breaking changes made to esptool.py, espsecure.py and espefuse.py in the major release ``v5``. It provides guidance on adapting existing workflows and scripts to ensure compatibility when updating from ``v4.*``.
Command-Line Tool Invocation Changes
************************************
The preferred way to invoke esptool command-line tools has changed. Instead of running the scripts with `.py` suffix, you should now use the console scripts without the `.py` suffix.
**Affected Tools:**
- ``esptool.py````esptool``
- ``espefuse.py````espefuse``
- ``espsecure.py````espsecure``
- ``esp_rfc2217_server.py````esp_rfc2217_server``
**Migration Steps:**
1. Update your command-line invocations to use the new names without `.py`:
**Before:**
.. code-block:: bash
esptool.py chip_id
espefuse.py summary
espsecure.py sign_data --keyfile key.pem data.bin
**After:**
.. code-block:: bash
esptool chip_id
espefuse summary
espsecure sign-data --keyfile key.pem data.bin
2. Update scripts to use the new command names.
.. note::
Scripts with ``.py`` suffix are still available for backward compatibility, but they will produce deprecation warning and will be removed in the next major release.
esptool.py ``v5`` Migration Guide
*********************************

View File

@@ -21,6 +21,7 @@ from espefuse.efuse_interface import (
SUPPORTED_READ_COMMANDS,
SUPPORTED_CHIPS,
)
from esptool.util import check_deprecated_py_suffix
__all__ = [
"get_esp",
@@ -38,7 +39,7 @@ __all__ = [
chain=True, # allow using multiple commands in a single run
no_args_is_help=True,
context_settings=dict(help_option_names=["-h", "--help"], max_content_width=120),
help=f"espefuse.py v{esptool.__version__} - ESP32xx eFuse get/set tool",
help=f"espefuse v{esptool.__version__} - ESP32xx eFuse get/set tool",
)
@click.option(
"--chip",
@@ -113,7 +114,7 @@ def cli(
postpone,
extend_efuse_table,
):
print(f"espefuse.py v{esptool.__version__}")
print(f"espefuse v{esptool.__version__}")
ctx.ensure_object(dict)
esp = ctx.obj.get("esp", None)
@@ -215,6 +216,7 @@ def main(argv: list[str] | None = None, esp: esptool.ESPLoader | None = None):
def _main():
check_deprecated_py_suffix(__name__)
try:
main()
except esptool.FatalError as e:

View File

@@ -20,7 +20,7 @@ from espefuse.efuse_interface import (
click.rich_click.USE_CLICK_SHORT_HELP = True
click.rich_click.COMMAND_GROUPS = {
"espefuse.py": [
"*": [
{
"name": "Burn commands",
"commands": SUPPORTED_BURN_COMMANDS,

View File

@@ -24,6 +24,7 @@ from cryptography.utils import int_to_bytes
from esptool.logger import log
import esptool
from esptool.util import check_deprecated_py_suffix
SIG_BLOCK_MAGIC = 0xE7
@@ -1579,11 +1580,11 @@ class Group(esptool.cli_util.Group):
cls=Group,
no_args_is_help=True,
context_settings=dict(help_option_names=["-h", "--help"], max_content_width=120),
help=f"espsecure.py v{esptool.__version__} - ESP32 Secure Boot & Flash Encryption "
help=f"espsecure v{esptool.__version__} - ESP32 Secure Boot & Flash Encryption "
"tool",
)
def cli():
log.print(f"espsecure.py v{esptool.__version__}")
log.print(f"espsecure v{esptool.__version__}")
@cli.command("digest-secure-bootloader")
@@ -1960,6 +1961,7 @@ def main(argv: list[str] | None = None):
def _main():
check_deprecated_py_suffix(__name__)
try:
main()
except esptool.FatalError as e:

View File

@@ -82,6 +82,7 @@ from esptool.targets import CHIP_DEFS, CHIP_LIST, ESP32ROM
from esptool.util import (
FatalError,
NotImplementedInROMError,
check_deprecated_py_suffix,
flash_size_bytes,
)
from itertools import chain, cycle, repeat
@@ -112,7 +113,7 @@ click.rich_click.STYLE_COMMANDS_TABLE_COLUMN_WIDTH_RATIO = (1, 3)
# Option group definitions, used for grouping options in the help output
# Similar to 'add_argument_group' from argparse
click.rich_click.OPTION_GROUPS = {
"esptool.py merge-bin": [
"* merge-bin": [
{
"name": "UF2 options",
"options": [
@@ -141,7 +142,7 @@ click.rich_click.OPTION_GROUPS = {
],
}
click.rich_click.COMMAND_GROUPS = {
"esptool.py": [
"*": [
{
"name": "Basic commands",
"commands": [
@@ -297,7 +298,7 @@ def check_flash_size(esp: ESPLoader, address: int, size: int) -> None:
cls=Group,
no_args_is_help=True,
context_settings=dict(help_option_names=["-h", "--help"], max_content_width=120),
help=f"esptool.py v{__version__} - serial utility for flashing, provisioning, "
help=f"esptool v{__version__} - serial utility for flashing, provisioning, "
"and interacting with Espressif SoCs.",
)
@click.option(
@@ -1172,6 +1173,7 @@ def get_default_connected_device(
def _main():
check_deprecated_py_suffix(__name__)
try:
main()
except FatalError as e:

View File

@@ -128,6 +128,19 @@ def get_key_from_value(dict, val):
return None
def check_deprecated_py_suffix(module_name: str) -> None:
"""Check if called with deprecated .py suffix"""
import sys
from esptool import log
script_name = sys.argv[0] if sys.argv else ""
if script_name.endswith(module_name + ".py"):
log.warning(
f"DEPRECATED: '{module_name}.py' is deprecated. Please use '{module_name}' "
"instead. The '.py' suffix will be removed in a future major release."
)
class PrintOnce:
"""
Class for printing messages just once. Can be useful when running in a loop

View File

@@ -2,12 +2,25 @@ import os
from setuptools import setup
if os.name != "nt":
# For backward compatibility with py suffix
scripts = ["esptool.py", "espefuse.py", "espsecure.py", "esp_rfc2217_server.py"]
entry_points = {}
entry_points = {
"console_scripts": [
"esptool=esptool.__init__:_main",
"espsecure=espsecure.__init__:_main",
"espefuse=espefuse.__init__:_main",
"esp_rfc2217_server=esp_rfc2217_server.__init__:main",
],
}
else:
scripts = []
entry_points = {
"console_scripts": [
"esptool=esptool.__init__:_main",
"espsecure=espsecure.__init__:_main",
"espefuse=espefuse.__init__:_main",
"esp_rfc2217_server=esp_rfc2217_server.__init__:main",
# For backward compatibility with py suffix
"esptool.py=esptool.__init__:_main",
"espsecure.py=espsecure.__init__:_main",
"espefuse.py=espefuse.__init__:_main",

View File

@@ -83,7 +83,7 @@ class ESPRFC2217Server(object):
self.port = rfc2217_port or self.get_free_port()
self.cmd = [
sys.executable,
os.path.join(TEST_DIR, "..", "esp_rfc2217_server.py"),
os.path.join(TEST_DIR, "..", "esp_rfc2217_server"),
"-p",
str(self.port),
arg_port,
@@ -1815,3 +1815,30 @@ class TestESPObjectOperations(EsptoolTestCase):
assert "Checksum: 0x83 (valid)" in output
assert "Wrote 0x2400 bytes to file 'output.bin'" in output
assert esptool.__version__ in output
@pytest.mark.host_test
class TestOldScripts:
def test_esptool_py(self):
output = subprocess.check_output(["esptool.py", "-h"])
decoded = output.decode("utf-8")
assert "esptool.py" in decoded
assert "DEPRECATED" in decoded
def test_espefuse_py(self):
output = subprocess.check_output(["espefuse.py", "-h"])
decoded = output.decode("utf-8")
assert "espefuse.py" in decoded
assert "DEPRECATED" in decoded
def test_espsecure_py(self):
output = subprocess.check_output(["espsecure.py", "-h"])
decoded = output.decode("utf-8")
assert "espsecure.py" in decoded
assert "DEPRECATED" in decoded
def test_esp_rfc2217_server_py(self):
output = subprocess.check_output(["esp_rfc2217_server.py", "-h"])
decoded = output.decode("utf-8")
assert "esp_rfc2217_server.py" in decoded
assert "DEPRECATED" in decoded