Subject: bug#66554: [PATCH] Add the public API of Compat to the core

From: Philip Kaludercic <[email-masked]>
Date: Thu, 11 Jan 2024 20:07:41 +0000

Stefan Kangas <[email-masked]> writes:

> Eli Zaretskii <[email-masked]> writes:
>
>> I don't mind, but it sounds like the details of adding compat.el to
>> core are not yet clear to all, and are still being discussed.
>
> OK, thanks.  There's no rush here, I think.  I hope that people will
> speak up so that we can get a handle on those details.
>
>> Also, it sounds like we would need to modify compat.el for every
>> release or something? if so, this should be in make-tarball.txt.
>>
>> It might be also a good idea to mention this in the ELisp manual
>> somewhere.
>
> Philip, could you take a look at this and amend the patch accordingly?
> Thanks in advance.

This would integrate my previous two suggestions:

>From 83743d8c407cf5ef8a34816b88e9b28d890bc7f6 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <[email-masked]>
Date: Wed, 13 Sep 2023 12:26:22 +0200
Subject: [PATCH] Add the public API of Compat to the core

* lisp/emacs-lisp/compat.el: Add stub file with minimal definitions,
so that core packages, that haven't been installed from ELPA, can make
use of the public API and use more recent function signatures.
* lisp/progmodes/python.el (compat): Remove 'noerror flag, because
Compat can now be required without the real package being available.
* admin/admin.el (set-version): Update the version in the package
header when setting the version.
* lisp/subr.el (version-regexp-alist): Add non-numeric version string
"compat", to ensure that the build-in compat is always
preferred. (Bug#66554)
---
 admin/admin.el            |  5 ++++
 lisp/emacs-lisp/compat.el | 61 +++++++++++++++++++++++++++++++++++++++
 lisp/progmodes/python.el  |  2 +-
 lisp/subr.el              |  4 +--
 4 files changed, 69 insertions(+), 3 deletions(-)
 create mode 100644 lisp/emacs-lisp/compat.el

diff --git a/admin/admin.el b/admin/admin.el
index 7fa2727aeb7..bcf1be6ff67 100644
--- a/admin/admin.el
+++ b/admin/admin.el
@@ -115,6 +115,11 @@ set-version
   (set-version-in-file root "nt/README.W32" version
 		       (rx (and "version" (1+ space)
 				(submatch (1+ (in "0-9."))))))
+  (set-version-in-file root "lisp/emacs-lisp/compat.el" version
+		       (rx (and bol ";; Version : " (1+ space)
+				(submatch (1+ (in "0-9.")))
+                                "compat")))
+
   ;; TODO: msdos could easily extract the version number from
   ;; configure.ac with sed, rather than duplicating the information.
   (set-version-in-file root "msdos/sed2v2.inp" version
diff --git a/lisp/emacs-lisp/compat.el b/lisp/emacs-lisp/compat.el
new file mode 100644
index 00000000000..b45b3ede633
--- /dev/null
+++ b/lisp/emacs-lisp/compat.el
@@ -0,0 +1,61 @@
+;;; compat.el --- Pseudo-Compatibility for Elisp -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021-2024 Free Software Foundation, Inc.
+
+;; Author:								\
+;;   Philip Kaludercic <[email-masked]>,				\
+;;   Daniel Mendler <[email-masked]>
+;; Maintainer:								\
+;;   Daniel Mendler <[email-masked]>,				\
+;;   Compat Development <~pkal/[email-masked]>,
+;;   [email-masked]
+;; URL: https://github.com/emacs-compat/compat
+;; Version: 30.1compat
+;; Keywords: lisp, maint
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; The Compat package on ELPA provides forward-compatibility
+;; definitions for other packages.  While mostly transparent, a
+;; minimal API is necessary whenever core definitions change calling
+;; conventions (e.g. `plist-get' can be invoked with a predicate from
+;; Emacs 29.1 onward).  For core packages on ELPA to be able to take
+;; advantage of this functionality, the macros `compat-function' and
+;; `compat-call' have to be available in the core, usable even if
+;; users do not have the Compat package installed, which this file
+;; ensures.
+
+;; Note that Compat is not a core package and this file is not
+;; available on GNU ELPA.
+
+;;; Code:
+
+(defmacro compat-function (fun)
+  "Return compatibility function symbol for FUN.
+This is a pseudo-compatibility stub for core packages on ELPA,
+that depend on the Compat package, whenever the user doesn't have
+the package installed on their current system."
+  `#',fun)
+
+(defmacro compat-call (fun &rest args)
+  "Call compatibility function or macro FUN with ARGS.
+This is a pseudo-compatibility stub for core packages on ELPA,
+that depend on the Compat package, whenever the user doesn't have
+the package installed on their current system."
+  (cons fun args))
+
+(provide 'compat)
+;;; compat.el ends here
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 1148da11a06..c3f18692f61 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -267,7 +267,7 @@
 (eval-when-compile (require 'subr-x))   ;For `string-empty-p' and `string-join'.
 (require 'treesit)
 (require 'pcase)
-(require 'compat nil 'noerror)
+(require 'compat)
 (require 'project nil 'noerror)
 (require 'seq)
 
diff --git a/lisp/subr.el b/lisp/subr.el
index df28989b399..007206ebf0e 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -6873,9 +6873,9 @@ version-separator
 
 Usually the separator is \".\", but it can be any other string.")
 
-
 (defconst version-regexp-alist
-  '(("^[-._+ ]?snapshot$"                                 . -4)
+  `(("^[-._+ ]?compat$"                                   . ,most-positive-fixnum)
+    ("^[-._+ ]?snapshot$"                                 . -4)
     ;; treat "1.2.3-20050920" and "1.2-3" as snapshot releases
     ("^[-._+]$"                                           . -4)
     ;; treat "1.2.3-CVS" as snapshot release
-- 
2.39.2