From 9d340eec8417e4262e51c3ff20896631e7ae2723 Mon Sep 17 00:00:00 2001 From: KOLANICH Date: Tue, 5 Dec 2017 14:02:16 +0300 Subject: [PATCH] Added main module detection and command line construction, now should show the right name (instead of __main__.py) when called for modules Co-Authored-By: Henry Fredrick Schreiner --- plumbum/cli/application.py | 10 ++++++++-- plumbum/lib.py | 9 +++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/plumbum/cli/application.py b/plumbum/cli/application.py index d83e6f14e..387603fe8 100644 --- a/plumbum/cli/application.py +++ b/plumbum/cli/application.py @@ -1,13 +1,14 @@ import functools import inspect import os +import re import sys from collections import defaultdict from textwrap import TextWrapper from plumbum import colors, local from plumbum.cli.i18n import get_translation_for -from plumbum.lib import getdoc +from plumbum.lib import getdoc, get_main_module_frame from .switches import ( CountOf, @@ -77,6 +78,7 @@ def __repr__(self): # CLI Application base class # =================================================================================================== +main_module_ending_rx = re.compile("\.__main__$") class Application: """The base class for CLI applications; your "entry point" class should derive from it, @@ -182,7 +184,11 @@ def __init__(self, executable): # Filter colors if self.PROGNAME is None: - self.PROGNAME = os.path.basename(executable) + spec = get_main_module_frame().f_globals.get("__spec__", None) + if spec: + self.PROGNAME = " ".join(("python -m", main_module_ending_rx.sub("", spec.name))) + else: + self.PROGNAME = os.path.basename(executable) elif isinstance(self.PROGNAME, colors._style): self.PROGNAME = self.PROGNAME | os.path.basename(executable) elif colors.filter(self.PROGNAME) == "": diff --git a/plumbum/lib.py b/plumbum/lib.py index 9a489de57..4254d929e 100644 --- a/plumbum/lib.py +++ b/plumbum/lib.py @@ -77,3 +77,12 @@ def read_fd_decode_safely(fd, size=4096): data += os.read(fd.fileno(), 1) return data, data.decode("utf-8") + +def get_main_module_frame(): + """ + Gets the frame of the __main__ module (the one which is called with command line) of an app. + """ + fr = sys._getframe(0) + while fr and fr.f_globals["__name__"] != "__main__": + fr = fr.f_back + return fr