From debbugs-submit-bounces@debbugs.gnu.org Sun Sep 04 06:31:10 2022 Received: (at submit) by debbugs.gnu.org; 4 Sep 2022 10:31:10 +0000 Received: from localhost ([127.0.0.1]:43494 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oUmuD-0006WI-1u for submit@debbugs.gnu.org; Sun, 04 Sep 2022 06:31:09 -0400 Received: from lists.gnu.org ([209.51.188.17]:40474) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oUmuA-0006WA-E0 for submit@debbugs.gnu.org; Sun, 04 Sep 2022 06:31:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39870) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oUmuA-0000hm-15 for bug-gnu-emacs@gnu.org; Sun, 04 Sep 2022 06:31:06 -0400 Received: from mail-ed1-x532.google.com ([2a00:1450:4864:20::532]:41766) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oUmu7-0002DR-GE for bug-gnu-emacs@gnu.org; Sun, 04 Sep 2022 06:31:05 -0400 Received: by mail-ed1-x532.google.com with SMTP id r4so8007938edi.8 for ; Sun, 04 Sep 2022 03:31:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:user-agent:message-id:date:subject:to:from:from:to:cc :subject:date; bh=HXMV1h3GTl3ywePELUis4EAvqZRiCI66yCJRVQJGiyE=; b=Foa3gjYrOEcsUD/Oj1leIiQCgn6qYHf2u+nrwLHcONaD6ZuBfE/GoFCpC0bZpKwvIS NhBykrIvBAb6wvgZpPmy/x90zy9K8KUjVWlHSlbyRNZvKdUD4foVEDdrZpZiOojmaf7G NqthGl0FXRs5JhVJqE3CeCrWufcO43K7jDPmXmq57xshfL5D/bDcYQ6SAtoX5giDvrF4 6jDWLmRFOfVknf+AB7k7imR57r/EoXQctKNiY8NxPWjCFGFtmX3+kdKlaTS9c4tPBKXc yFSXGMpcCBVSUlD4Tki2kK4uVX7LrFu84hCzEfPj84xLfyTJN6uyX9UarzNVA+jeP7e6 lYrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=mime-version:user-agent:message-id:date:subject:to:from :x-gm-message-state:from:to:cc:subject:date; bh=HXMV1h3GTl3ywePELUis4EAvqZRiCI66yCJRVQJGiyE=; b=IWBbm2zI1rD9baW55f8PZwU5J/kgSmfPPCe/hnnkJXZGtC12wYeUYasr7Yh4b7Dk2c lTS+/366xlYnkVLbdfy19JDvp0mpSAfGCp33hRmDxsYvH5pfKgjg4eBARA3UfejGXmOy mM23KVh3U8pC3vf/wJc6Pw2V7j6NX8q0LAWIAhmgLsLEKnqdQDxM/jhJ844OoMsCfppr A/o5+YIoJlUda6OSpm1UHeqavvk18ye7kgiBy3vZXQQqXWUha1AXEsqyc2CQMi1QoL9y N2tnuBP056I3CIwSQ4dcjZkuVtNeZfEM9apTepbZ8kJkIznmROdH2LDcT42vut7dE2uZ C4Rg== X-Gm-Message-State: ACgBeo1Kntg17R1tcjNvTQgWZ4/ozkbbw8NeoQ5P8QTgJfUFNz90lXCY Nn4JChlopGSlIvVG44OrbX0AEmkQcMY= X-Google-Smtp-Source: AA6agR4ab7fjh+DRDl0L1VDJ9p6a4Z/GSeFgNzjWkhoF/6yGyaPgBQW/fdgIstlMs/3wcdQc5fd7LA== X-Received: by 2002:a05:6402:156:b0:440:b458:93df with SMTP id s22-20020a056402015600b00440b45893dfmr41012147edu.337.1662287460852; Sun, 04 Sep 2022 03:31:00 -0700 (PDT) Received: from ars3 ([2a02:8109:8ac0:56d0::157b]) by smtp.gmail.com with ESMTPSA id q3-20020a056402040300b004466f5375a5sm4584091edv.53.2022.09.04.03.30.59 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 04 Sep 2022 03:30:59 -0700 (PDT) From: Augusto Stoffel To: bug-gnu-emacs@gnu.org Subject: [PATCH] Add Python import management commands Date: Sun, 04 Sep 2022 12:30:58 +0200 Message-ID: <87fsh7l9ct.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Received-SPF: pass client-ip=2a00:1450:4864:20::532; envelope-from=arstoffel@gmail.com; helo=mail-ed1-x532.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: -1.3 (-) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) --=-=-= Content-Type: text/plain Tags: patch This patch adds a few commands to help managing import statements in Python projects. (I submitted equivalent code some time ago as a potential ELPA package, and it was noted that this fits better in python.el itself.) This patch should be applied after the patch of bug#56997, since it requires, in a rather substantial way, the project dependency. I also had to introduce a new `python-interpreter' defcustom. Here are two observations: 1) Its default value should perhaps coincide with that of `python-shell-interpreter'. But I disagree of the logic used there to pick python3 if present. There are only two reasons why `python' should point to the python2 interpreter: a. The user is working on a legacy project and carefully set the python executable to point to a python2 interpreter. b. The user's OS is woefully misconfigured. We should have a default that works with case a. instead of one that tries to fix case b. 2) For extra consistency, it might be better to have python-shell-interpreter be nil by default, and use (or python-shell-interpreter python-interpreter) when starting a shell. But this would be a minor improvement that might break third-party code. --=-=-= Content-Type: text/patch Content-Disposition: attachment; filename=0001-Add-Python-import-management-commands.patch >From d1cae36e5e2ee91c44286af46cf66b3e316a6639 Mon Sep 17 00:00:00 2001 From: Augusto Stoffel Date: Sun, 4 Sep 2022 10:17:42 +0200 Subject: [PATCH] Add Python import management commands * lisp/progmodes/python.el (python-interpreter): New variable (python-mode-map): Keybindings and menu entries for new commands (python--list-imports, python-import-history, python--query-import, python--do-isort): New variables and helper functions. (python-add-import, python-import-symbol-at-point, python-remove-import, python-sort-imports, python-fix-imports): New interactive commands. --- lisp/progmodes/python.el | 270 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 265 insertions(+), 5 deletions(-) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 6020d52b91..147c5f248d 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -34,7 +34,8 @@ ;; Implements Syntax highlighting, Indentation, Movement, Shell ;; interaction, Shell completion, Shell virtualenv support, Shell ;; package support, Shell syntax highlighting, Pdb tracking, Symbol -;; completion, Skeletons, FFAP, Code Check, ElDoc, Imenu. +;; completion, Skeletons, FFAP, Code Check, ElDoc, Imenu, Flymake, +;; Import management. ;; Syntax highlighting: Fontification of code is provided and supports ;; python's triple quoted strings properly. @@ -69,7 +70,7 @@ ;; variables. This example enables IPython globally: ;; (setq python-shell-interpreter "ipython" -;; python-shell-interpreter-args "-i") +;; python-shell-interpreter-args "--simple-prompt") ;; Using the "console" subcommand to start IPython in server-client ;; mode is known to fail intermittently due a bug on IPython itself @@ -240,6 +241,21 @@ ;; I'd recommend the first one since you'll get the same behavior for ;; all modes out-of-the-box. +;; Flymake: A Flymake backend, using the pyflakes program by default, +;; is provided. You can also use flake8 or pylint by customizing +;; `python-flymake-command'. + +;; Import management: The commands `python-sort-imports', +;; `python-add-import', `python-remove-import', and +;; `python-fix-imports' automate the editing of import statements at +;; the top of the buffer, which tend to be a tedious task in larger +;; projects. These commands require that the isort library is +;; available to the interpreter pointed at by `python-interpreter'. +;; The last command also requires pyflakes. These dependencies can be +;; installed, among other methods, with the following command: +;; +;; pip install isort pyflakes + ;;; Code: (require 'ansi-color) @@ -268,6 +284,12 @@ python :version "24.3" :link '(emacs-commentary-link "python")) +(defcustom python-interpreter "python" + "Python interpreter for noninteractive use. +To customize the Python shell, modify `python-shell-interpreter' +instead." + :version "29.1" + :type 'string) ;;; Bindings @@ -306,6 +328,11 @@ python-mode-map (define-key map "\C-c\C-v" #'python-check) (define-key map "\C-c\C-f" #'python-eldoc-at-point) (define-key map "\C-c\C-d" #'python-describe-at-point) + ;; Import management + (define-key map "\C-c\C-ia" #'python-add-import) + (define-key map "\C-c\C-if" #'python-fix-imports) + (define-key map "\C-c\C-ir" #'python-remove-import) + (define-key map "\C-c\C-is" #'python-sort-imports) ;; Utilities (substitute-key-definition #'complete-symbol #'completion-at-point map global-map) @@ -351,7 +378,17 @@ python-mode-map ["Help on symbol" python-eldoc-at-point :help "Get help on symbol at point"] ["Complete symbol" completion-at-point - :help "Complete symbol before point"])) + :help "Complete symbol before point"] + "-----" + ["Add import" python-add-import + :help "Add an import statement to the top of this buffer"] + ["Remove import" python-remove-import + :help "Remove an import statement from the top of this buffer"] + ["Sort imports" python-sort-imports + :help "Sort the import statements at the top of this buffer"] + ["Fix imports" python-fix-imports + :help "Add missing imports and remove unused ones from the current buffer"] + )) map) "Keymap for `python-mode'.") @@ -5852,6 +5889,225 @@ python-flymake (process-send-eof python--flymake-proc)))) +;;; Import management +(defconst python--list-imports "\ +from isort import find_imports_in_stream, find_imports_in_paths +from sys import argv, stdin + +query, files, result = argv[1] or None, argv[2:], {} + +if files: + imports = find_imports_in_paths(files, top_only=True) +else: + imports = find_imports_in_stream(stdin, top_only=True) + +for imp in imports: + if query is None or query == (imp.alias or imp.attribute or imp.module): + key = (imp.module, imp.attribute or '', imp.alias or '') + if key not in result: + result[key] = imp.statement() + +for key in sorted(result): + print(result[key]) +" + "Script to list import statements in Python code.") + +(defvar python-import-history nil + "History variable for `python-import' commands.") + +(defun python--import-sources () + "List files containing Python imports that may be useful in the current buffer." + (if-let (((featurep 'project)) ;For compatibility with Emacs < 26 + (proj (project-current))) + (seq-filter (lambda (s) (string-match-p "\\.py[ciw]?\\'" s)) + (project-files proj)) + (list default-directory))) + +(defun python--list-imports (name source) + "List all Python imports matching NAME in SOURCE. +If NAME is nil, list all imports. SOURCE can be a buffer or a +list of file names or directories; the latter are searched +recursively." + (let ((buffer (current-buffer))) + (with-temp-buffer + (let* ((temp (current-buffer)) + (status (if (bufferp source) + (with-current-buffer source + (call-process-region (point-min) (point-max) + python-interpreter + nil (list temp nil) nil + "-c" python--list-imports + (or name ""))) + (with-current-buffer buffer + (apply #'call-process + python-interpreter + nil (list temp nil) nil + "-c" python--list-imports + (or name "") + (mapcar #'file-local-name source))))) + lines) + (unless (eq 0 status) + (error "%s exited with status %s (maybe isort is missing?)" + python-interpreter status)) + (goto-char (point-min)) + (while (not (eobp)) + (push (buffer-substring-no-properties (point) (pos-eol)) + lines) + (forward-line 1)) + (nreverse lines))))) + +(defun python--query-import (name source prompt) + "Read a Python import statement defining NAME. +A list of candidates is produced by `python--list-imports' using +the NAME and SOURCE arguments. An interactive query, using the +PROMPT string, is made unless there is a single candidate." + (let* ((cands (python--list-imports name source)) + ;; Don't use DEF argument of `completing-read', so it is able + ;; to return the empty string. + (minibuffer-default-add-function + (lambda () + (setq minibuffer-default (with-minibuffer-selected-window + (thing-at-point 'symbol))))) + (statement (cond ((and name (length= cands 1)) + (car cands)) + (prompt + (completing-read prompt + (or cands python-import-history) + nil nil nil + 'python-import-history))))) + (unless (string-empty-p statement) + statement))) + +(defun python--do-isort (&rest args) + "Edit the current buffer using isort called with ARGS. +Return non-nil if the buffer was actually modified." + (let ((buffer (current-buffer))) + (with-temp-buffer + (let ((temp (current-buffer))) + (with-current-buffer buffer + (let ((status (apply #'call-process-region + (point-min) (point-max) + python-interpreter + nil (list temp nil) nil + "-m" "isort" "-" args)) + (tick (buffer-chars-modified-tick))) + (unless (eq 0 status) + (error "%s exited with status %s (maybe isort is missing?)" + python-interpreter status)) + (replace-buffer-contents temp) + (not (eq tick (buffer-chars-modified-tick))))))))) + +;;;###autoload +(defun python-add-import (name) + "Add an import statement to the current buffer. + +Interactively, ask for an import statement using all imports +found in the current project as suggestions. With a prefix +argument, restrict the suggestions to imports defining the symbol +at point. If there is only one such suggestion, act without +asking. + +When calling from Lisp, use a non-nil NAME to restrict the +suggestions to imports defining NAME." + (interactive (list (when current-prefix-arg (thing-at-point 'symbol)))) + (when-let ((statement (python--query-import name + (python--import-sources) + "Add import: "))) + (if (python--do-isort "--add" statement) + (message "Added `%s'" statement) + (message "(No changes in Python imports needed)")))) + +;;;###autoload +(defun python-import-symbol-at-point () + "Add an import statement for the symbol at point to the current buffer. +This works like `python-add-import', but with the opposite +behavior regarding the prefix argument." + (interactive nil) + (python-add-import (unless current-prefix-arg (thing-at-point 'symbol)))) + +;;;###autoload +(defun python-remove-import (name) + "Remove an import statement from the current buffer. + +Interactively, ask for an import statement to remove, displaying +the imports of the current buffer as suggestions. With a prefix +argument, restrict the suggestions to imports defining the symbol +at point. If there is only one such suggestion, act without +asking." + (interactive (list (when current-prefix-arg (thing-at-point 'symbol)))) + (when-let ((statement (python--query-import name (current-buffer) + "Remove import: "))) + (if (python--do-isort "--rm" statement) + (message "Removed `%s'" statement) + (message "(No changes in Python imports needed)")))) + +;;;###autoload +(defun python-sort-imports () + "Sort Python imports in the current buffer." + (interactive) + (if (python--do-isort) + (message "Sorted imports") + (message "(No changes in Python imports needed)"))) + +;;;###autoload +(defun python-fix-imports () + "Add missing imports and remove unused ones from the current buffer." + (interactive) + (let ((buffer (current-buffer)) + undefined unused add remove) + ;; Compute list of undefined and unused names + (with-temp-buffer + (let ((temp (current-buffer))) + (with-current-buffer buffer + (call-process-region (point-min) (point-max) + python-interpreter + nil temp nil + "-m" "pyflakes")) + (goto-char (point-min)) + (when (looking-at-p ".* No module named pyflakes$") + (error "%s couldn't find pyflakes" python-interpreter)) + (while (not (eobp)) + (cond ((looking-at ".* undefined name '\\([^']+\\)'$") + (push (match-string 1) undefined)) + ((looking-at ".*'\\([^']+\\)' imported but unused$") + (push (match-string 1) unused))) + (forward-line 1)))) + ;; Compute imports to be added + (dolist (name (seq-uniq undefined)) + (when-let ((statement (python--query-import name + (python--import-sources) + (format "\ +Add import for undefined name `%s' (empty to skip): " + name)))) + (push statement add))) + ;; Compute imports to be removed + (dolist (name (seq-uniq unused)) + ;; The unused imported names, as provided by pyflakes, are of + ;; the form "module.var" or "module.var as alias", independently + ;; of style of import statement used. + (let* ((filter + (lambda (statement) + (string= name + (thread-last + statement + (replace-regexp-in-string "^\\(from\\|import\\) " "") + (replace-regexp-in-string " import " "."))))) + (statements (seq-filter filter (python--list-imports nil buffer)))) + (when (length= statements 1) + (push (car statements) remove)))) + ;; Edit buffer and say goodbye + (if (not (or add remove)) + (message "(No changes in Python imports needed)") + (apply #'python--do-isort + (append (mapcan (lambda (x) (list "--add" x)) add) + (mapcan (lambda (x) (list "--rm" x)) remove))) + (message "%s" (concat (when add "Added ") + (when add (string-join add ", ")) + (when remove (if add " and removed " "Removed ")) + (when remove (string-join remove ", " ))))))) + + +;;; Major mode (defun python-electric-pair-string-delimiter () (when (and electric-pair-mode (memq last-command-event '(?\" ?\')) @@ -5973,8 +6229,10 @@ python-mode ;;; Completion predicates for M-x ;; Commands that only make sense when editing Python code -(dolist (sym '(python-check +(dolist (sym '(python-add-import + python-check python-fill-paragraph + python-fix-imports python-indent-dedent-line python-indent-dedent-line-backspace python-indent-guess-indent-offset @@ -5999,9 +6257,11 @@ python-mode python-nav-forward-statement python-nav-if-name-main python-nav-up-list + python-remove-import python-shell-send-buffer python-shell-send-defun - python-shell-send-statement)) + python-shell-send-statement + python-sort-imports)) (put sym 'completion-predicate #'python--completion-predicate)) (defun python-shell--completion-predicate (_ buffer) -- 2.37.2 --=-=-= Content-Type: text/plain PS: Wouldn't it be handy also in other places to have a macro that creates a temp buffer but doesn't switch to it? Maybe with signature (with-temp-buffers (NAMES &rest BODY)). --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Sun Sep 04 07:18:20 2022 Received: (at 57574) by debbugs.gnu.org; 4 Sep 2022 11:18:20 +0000 Received: from localhost ([127.0.0.1]:43564 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oUnds-0001WL-Jr for submit@debbugs.gnu.org; Sun, 04 Sep 2022 07:18:20 -0400 Received: from quimby.gnus.org ([95.216.78.240]:56930) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oUndq-0001W7-NH for 57574@debbugs.gnu.org; Sun, 04 Sep 2022 07:18:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnus.org; s=20200322; h=Content-Type:MIME-Version:Message-ID:Date:References: In-Reply-To:Subject:Cc:To:From:Sender:Reply-To:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=RR8hRZoWQ+Z8q2y2vajZdZMmsV5G3wdx5SKyMjhUVuw=; b=rh040MDU3jId1d2LRXSnr14EVa owSmFMhmjyH+FXtqDoSDDLVszGqtgtbBoxmN6cYPDEVcYk0MQgXwzjcSz8z94cq1JbzU+aW0AkR0E rZxSvB7zVuLb2PqbBG29dn5px0V2uz/B1DrIENiZapw074VPH41B1XgD5UumPUObmv38=; Received: from [84.212.220.105] (helo=joga) by quimby.gnus.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oUndi-0000nL-CU; Sun, 04 Sep 2022 13:18:12 +0200 From: Lars Ingebrigtsen To: Augusto Stoffel Subject: Re: bug#57574: [PATCH] Add Python import management commands In-Reply-To: <87fsh7l9ct.fsf@gmail.com> (Augusto Stoffel's message of "Sun, 04 Sep 2022 12:30:58 +0200") References: <87fsh7l9ct.fsf@gmail.com> X-Now-Playing: The Beatles's _The Beatles (2)_: "Yer Blues" Date: Sun, 04 Sep 2022 13:18:09 +0200 Message-ID: <87zgff8k26.fsf@gnus.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Report: Spam detection software, running on the system "quimby.gnus.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see @@CONTACT_ADDRESS@@ for details. Content preview: Augusto Stoffel writes: > This patch adds a few commands to help managing import statements in > Python projects. (I submitted equivalent code some time ago as a > potential ELPA package, and it was noted that this fits bett [...] Content analysis details: (-2.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 57574 Cc: 57574@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Augusto Stoffel writes: > This patch adds a few commands to help managing import statements in > Python projects. (I submitted equivalent code some time ago as a > potential ELPA package, and it was noted that this fits better in > python.el itself.) Thanks; pushed to Emacs 29. > PS: Wouldn't it be handy also in other places to have a macro that > creates a temp buffer but doesn't switch to it? Maybe with signature > (with-temp-buffers (NAMES &rest BODY)). Hm... I can see how that can be useful in some cases, but it's probably not a very common usage pattern. But I think there's a real problem that people would just be confused and mistake that for something that does the same thing as with-temp-buffer. From debbugs-submit-bounces@debbugs.gnu.org Sun Sep 04 07:18:26 2022 Received: (at control) by debbugs.gnu.org; 4 Sep 2022 11:18:26 +0000 Received: from localhost ([127.0.0.1]:43567 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oUndx-0001Wd-T2 for submit@debbugs.gnu.org; Sun, 04 Sep 2022 07:18:26 -0400 Received: from quimby.gnus.org ([95.216.78.240]:56944) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oUndv-0001WD-TM for control@debbugs.gnu.org; Sun, 04 Sep 2022 07:18:24 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnus.org; s=20200322; h=Subject:From:To:Message-Id:Date:Sender:Reply-To:Cc: MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=jx07ohCoOT/0eUgzIhTMIImtEjrN1IEm/YD/ulcRVRE=; b=EjfPuSwwW35T4PgvvKAJaSIJjq +MtiNK9c+kOeEougEDZkUgiGZpjK0vexKr7rpjnOjJuk4jO3hQf6rVlQa581aAYvkt68scH0Rs3fB MW+guaDQDs/CrDBI0hOHRlvXQypScTsYRaj+pW5Kx5UqBY+QFdjF8mBp4GGDl6dkKrEA=; Received: from [84.212.220.105] (helo=joga) by quimby.gnus.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oUndn-0000nV-LG for control@debbugs.gnu.org; Sun, 04 Sep 2022 13:18:17 +0200 Date: Sun, 04 Sep 2022 13:18:15 +0200 Message-Id: <87y1uz8k20.fsf@gnus.org> To: control@debbugs.gnu.org From: Lars Ingebrigtsen Subject: control message for bug #57574 X-Spam-Report: Spam detection software, running on the system "quimby.gnus.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see @@CONTACT_ADDRESS@@ for details. Content preview: close 57574 29.1 quit Content analysis details: (-2.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) close 57574 29.1 quit From unknown Sat Jun 21 12:22:10 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Sun, 02 Oct 2022 11:24:09 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator