From debbugs-submit-bounces@debbugs.gnu.org Fri Apr 17 23:00:13 2020 Received: (at submit) by debbugs.gnu.org; 18 Apr 2020 03:00:13 +0000 Received: from localhost ([127.0.0.1]:41907 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPdiH-0002OY-1f for submit@debbugs.gnu.org; Fri, 17 Apr 2020 23:00:13 -0400 Received: from lists.gnu.org ([209.51.188.17]:40768) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPdiF-0002OM-6t for submit@debbugs.gnu.org; Fri, 17 Apr 2020 23:00:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45185) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jPdi9-00087U-FU for bug-gnu-emacs@gnu.org; Fri, 17 Apr 2020 23:00:09 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,FREEMAIL_FROM, URIBL_BLOCKED autolearn=disabled version=3.3.2 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jPdi4-0001lR-Uo for bug-gnu-emacs@gnu.org; Fri, 17 Apr 2020 23:00:05 -0400 Received: from mail-io1-xd36.google.com ([2607:f8b0:4864:20::d36]:35174) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jPdi3-0001iK-OG for bug-gnu-emacs@gnu.org; Fri, 17 Apr 2020 23:00:00 -0400 Received: by mail-io1-xd36.google.com with SMTP id w20so4670187iob.2 for ; Fri, 17 Apr 2020 19:59:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:content-transfer-encoding:mime-version:subject:message-id:date :to; bh=w8kvDL0CtZ2YCmPBWjQtM4vVYrdk/O4HMKeS1HsZnJ4=; b=HdZbpNKFJ9Oqcz81jphMX5YQ83/7Rs520MwbHY/TSIV3Gte2d7LpbGOL+0IRmaeN0z aDiRoIXWBZGEu6QVGtYTQytMMOdTAScw4I/zsOFRnbELXEptJr5ZBeAlJT9HCP/mtjjB 6UspsPt6BXV2zimXsz6i/98XfI94TpsWRS0CpRaDrU3eKmNxdeOfx57l2+kdNGaamUQ3 WhdOym6u/jOrHvaeJF+3/4iy+UKur3FbgGblydfASia9yjS5YYsR3eqUViTf0VYOJXGE JavcL+1Fa+xkTgw4dzjYieRVDpPfb8rNIfWJ50qWEa/89a4aPWRV8QsCJGejJ9IPPQwX jQNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:content-transfer-encoding:mime-version :subject:message-id:date:to; bh=w8kvDL0CtZ2YCmPBWjQtM4vVYrdk/O4HMKeS1HsZnJ4=; b=UM7jPpF6HFN0LYYJ2bi5EtvS8qCppxjSeW6X7COV5jjHTW27foDXcmDKQn3fs4vvlw eT/Tg1KEJ4kx40dScT9TbKM06Pbc/JuQYyFsIoqBh+pIrD/Wjkv64SReYtLcAAuYmf0l 4shTTTK4qqtN/LoE0NYN+pDApzwY+Xwb1GHUK3q64fqXFr5QBm4+fwMKWa5vxgJFXECE uje7dOVUhkDLhD5DvDQvEoFuANcLYIEogTsa3S9bk23Rg3YGO6DCZOfflrjP9LZc/bWw zXgjU1zxw1+8friizai6V4vRg8Q+iWnBFIGOa46nsdeh6o8gatvGrcTJgJAKmILkMurm Qzyg== X-Gm-Message-State: AGi0PuZbLqhVEyFw72Dn+ecp0D+q67Z0K23u9j/DZQoocZeonf2n8C2n RAP0kgbXTK7/sPRhHDe4+jKbrcD+UEU= X-Google-Smtp-Source: APiQypJTpyG+Y1p3LVDSravZKk9BhDV1+aq41ny1NFcFWLjFfxZcsi0tdUXMsNR+pkz3lajo8UGTRw== X-Received: by 2002:a5d:9c46:: with SMTP id 6mr6155267iof.146.1587178796798; Fri, 17 Apr 2020 19:59:56 -0700 (PDT) Received: from [192.150.23.4] (67-2-50-168.slkc.qwest.net. [67.2.50.168]) by smtp.gmail.com with ESMTPSA id k22sm1968714iot.32.2020.04.17.19.59.55 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 17 Apr 2020 19:59:56 -0700 (PDT) From: Ivan Andrus Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.14\)) Subject: 28.0.50; json-encode-alist changes alist Message-Id: Date: Fri, 17 Apr 2020 20:59:54 -0600 To: bug-gnu-emacs@gnu.org X-Mailer: Apple Mail (2.3445.104.14) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::d36 X-Spam-Score: 0.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: -0.7 (/) I recently filed #40692 = (https://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D40692) about a problem = I was having with magit forge using creating the wrong title because an = alist created in a function contained a single constant at the end and = it was being changed every time. I still find it surprising that a = back-quoted list would behave that way, but I suspect it will be = considered desired, or at least expected behavior. I was able to track it down to the actual function that was causing the = change: json-encode-alist when json-encoding-object-sort-predicate is = set. I have it set, and indeed it's extremely useful to view JSON that = in a meaningful order. I don't think that anyone would expect that = encoding json would change the underlying data, so I think = json-encode-alist should be changed to make a copy to avoid this = situation. (require 'json) (defun fun-withdraw (amount) (json-encode-alist `((tamount . , amount) (const . some-constant)))) (fun-withdraw 12) ;; Run this a few times and nothing will change (setq json-encoding-object-sort-predicate #'string<) (fun-withdraw 12) ;; Now it will change every time It's late now, but if I have some time in the next few days, I may = submit a patch since it seems like a simple enough change. -Ivan In GNU Emacs 28.0.50 (build 18, x86_64-apple-darwin18.7.0, NS = appkit-1671.60 Version 10.14.6 (Build 18G4032)) of 2020-04-10 built on iandrus-macOS Repository revision: 965390ca5f206c6358014574fe5140ba40850391 Repository branch: master Windowing system distributor 'Apple', version 10.3.1671 System Description: Mac OS X 10.14.6 Configured using: 'configure = PKG_CONFIG_PATH=3D/opt/X11/lib/pkgconfig:/usr/local/opt/libxml2/lib/pkgcon= fig --with-sound=3Dyes --with-ns --with-modules --with-file-notification=3Dyes= --enable-gcc-warnings=3Dwarn-only --with-xpm --with-jpeg --with-tiff --with-gif --with-png --with-rsvg --with-xml2 --with-imagemagick --with-json --with-xft --with-libotf --with-gnutls=3Dno --with-makeinfo --with-libgmp' Configured features: RSVG IMAGEMAGICK GLIB NOTIFY KQUEUE ACL LIBXML2 ZLIB TOOLKIT_SCROLL_BARS XIM NS MODULES THREADS JSON PDUMPER GMP Important settings: value of $LANG: en_US.UTF-8 locale-coding-system: utf-8-unix Features: (mailalias mailclient shadow emacsbug sendmail calc-bin calc-yank gap-smie gap-mode gap-process sage-shell-mode deferred cursor-sensor ess-r-mode ess-r-flymake ess-r-xref ess-trns ess-r-package ess-r-completion ess-roxy ess-r-syntax ess-rd ess-s-lang ess-help ess-mode ess-inf ess-tracebug ess ess-utils ess-custom disass calc-vec calccomp calc-aent all-the-icons-faces data-material data-weathericons data-octicons data-fileicons data-faicons data-alltheicons buttercup-compat cider-find cider-scratch apropos array jsonrpc jupyter-org-extensions jupyter-rest-api jupyter-org-client jupyter-repl jupyter-kernel-manager jupyter-channel jupyter-widget-client websocket simple-httpd jupyter-kernelspec jupyter-env jupyter-client jupyter-comm-layer jupyter-messages hmac-def jupyter-mime jupyter-base lsp-html lsp-mode em-glob bindat treemacs org-inlinetask gnus-art mm-uu mml2015 mm-view mml-smime smime dig ol-bibtex nnir gnus-sum gnus-group gnus-undo gnus-start gnus-cloud nnimap nnmail mail-source utf7 netrc nnoo gnus-spec gnus-int gnus-range gnus-win esh-mode doc-view bibtex ob-octave eshell esh-cmd esh-ext esh-opt esh-proc esh-io esh-arg esh-module esh-groups esh-util ebnf2ps ps-print ps-print-loaddefs ps-def lpr cider cider-debug cider-inspector cider-browse-ns cider-mode cider-completion cider-profile cider-eval cider-repl-history cider-repl cider-resolve cider-test cider-overlays cider-stacktrace cider-doc cider-browse-spec cider-clojuredocs cider-popup cider-eldoc cider-client cider-common cider-util cider-connection sesman-browser nrepl-client queue nrepl-dict cider-compat sesman clojure-mode parseedn parseclj-parser parseclj-lex a ob-clojure calc-store calc-trail org-attach finder perl6-repl pkg-info epl leaf treemacs-compatibility treemacs-mode treemacs-bookmarks hydra lv thunk treemacs-interface treemacs-extensions treemacs-persistence treemacs-mouse-interface treemacs-tag-follow-mode treemacs-filewatch-mode treemacs-tags treemacs-visuals treemacs-fringe-indicator pulse treemacs-faces treemacs-follow-mode treemacs-rendering treemacs-async treemacs-icons treemacs-themes treemacs-workspaces treemacs-scope treemacs-dom treemacs-core-utils treemacs-macros treemacs-customization ace-window pfuture inline term ehelp mail-extr compare-w axle vcursor texnfo-upd texinfo mc-mark-more rnc-mode goto-last-change mc-separate-operations align info-colors elisp-depmap-exec elisp-depmap-graph elisp-depmap-parse elisp-depmap-secondhelp xwwp-follow-link xwwp xwidget async-await iter2 promise promise-rejection-tracking promise-finally promise-done promise-es6-extensions promise-core autoload tar-mode arc-mode archive-mode lisp-mnt php-mode etags fileloop xref cc-langs php-face php php-project projectile ibuf-ext ibuffer ibuffer-loaddefs cmake-mode writeroom-mode visual-fill-column mixed-pitch vc-annotate poly-markdown dockerfile-mode forge-list forge-commands forge-semi forge-bitbucket buck forge-gogs gogs forge-gitea gtea forge-gitlab glab forge-github ghub-graphql treepy gsexp ghub let-alist forge-notify forge-revnote forge-pullreq forge-issue forge-topic forge-post forge-repo forge forge-core forge-db closql emacsql-sqlite emacsql emacsql-compiler snout-mode mhtml-mode css-mode eww mm-url gnus nnheader url-queue shr svg find-file whitespace make-mode magit-imenu git-rebase log-view novice vc-svn vc-cvs project deadgrep spinner lua-mode timezone mm-archive plantuml-mode gnuplot-gui gnuplot python markdown-mode edit-indirect conf-mode yaml-mode json-mode json-reformat json-snatcher js sql view dabbrev inflections mc-edit-lines multiple-cursors-core sort calc-arith calc-misc calc-math macros rot13 disp-table cperl-mode hippie-exp org-forms cl-print calc-alg calc-menu calc-ext calc calc-loaddefs calc-macs artist picture reporter rect ffap skeleton tabify cal-move org-datetree org-capture sh-script org-duration cal-julian lunar solar cal-dst cal-iso face-remap perl6-mode perl6-imenu perl6-indent smie perl6-font-lock char-fold misearch multi-isearch cap-words superword subword two-column executable bug-reference magit-extras magit-bookmark magit-submodule magit-obsolete magit-popup magit-blame magit-stash magit-reflog magit-bisect magit-push magit-pull magit-fetch magit-clone magit-remote magit-commit magit-sequence magit-notes magit-worktree magit-tag magit-merge magit-branch magit-reset magit-files magit-refs magit-status magit magit-repos magit-apply magit-wip magit-log magit-diff smerge-mode diff magit-core magit-autorevert magit-margin magit-transient magit-process magit-mode git-commit transient magit-git magit-section magit-utils writegood-mode log-edit message rfc822 mml mml-sec gnus-util rmail rmail-loaddefs mm-decode mm-bodies mailabbrev gmm-utils mailheader pcvs-util with-editor async-bytecomp async vc vc-dispatcher add-log ido-completing-read+ memoize cus-edit minibuf-eldef gvol-light-theme elide-head highlight-tail hl-sexp highlight-symbol adafruit-wisdom org-eldoc reveal epa-file epa epg epg-config request mail-utils flyspell ispell poly-org polymode derived poly-lock polymode-base polymode-weave polymode-export polymode-compat polymode-methods polymode-core polymode-classes eieio-custom color org-archive eieio-opt speedbar dframe tls gnutls network-stream url-http url-gw nsm rmc puny url-cache url-auth url url-proxy url-privacy url-expand url-methods url-history url-cookie url-domsuf dad-joke time semantic/idle semantic/analyze semantic/sort semantic/scope semantic/analyze/fcn semantic/db eieio-base semantic/format ezimage semantic/tag-ls semantic/find semantic/ctxt org-drill persist org-id org-tempo tempo org-protocol org-mouse org-habit org-ctags ob-latex ob-gnuplot ob-plantuml ob-js vc-git diff-mode rng-xsd xsd-regexp rng-cmpct hideshow rng-nxml rng-valid nxml-mode nxml-outln nxml-rap sgml-mode dom perl6-detect which-func paren semantic/util-modes semantic/util semantic semantic/tag semantic/lex semantic/fw mode-local cedet saveplace msb mb-depth icomplete gud hl-line autorevert filenotify cus-start cus-load helpful imenu trace edebug f dash-functional help-fns radix-tree elisp-refs loop avy autoinsert cl-extra yasnippet find-file-in-repository smex ido flycheck-clang-analyzer flycheck rtags popup repeat docker-tramp kubernetes-tramp tramp-cache tramp-okta tramp-sh tramp tramp-loaddefs trampver tramp-integration files-x tramp-compat parse-time iso8601 ls-lisp asm-mode info-look cc-mode cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs bookmark text-property-search beacon fold ripgrep wgrep grep literal-string ox-pandoc ht ox-org ox-odt rng-loc rng-uri rng-parse rng-match rng-dt rng-util rng-pttrn nxml-parse nxml-ns nxml-enc xmltok nxml-util ox-latex ox-icalendar ox-html table ox-ascii ox-publish ox org-element avl-tree generator org-wc idle-org-agenda org-mac-link org-mobile org-agenda diary-lib diary-loaddefs org-crypt ob-obxml oberon-shell-mode ob-shell shell ob-python org-clock orgtbl-ascii-plot org ob ob-tangle ob-ref ob-lob ob-table ob-exp org-macro org-footnote org-src ob-comint org-pcomplete pcomplete org-list org-faces org-entities time-date noutline outline org-version ob-emacs-lisp ob-core ob-eval org-table ol org-keys org-compat org-macs org-loaddefs cal-menu calendar cal-loaddefs sage jka-compr xml preview prv-emacs tex-buf latex latex-flymake flymake-proc flymake compile comint ansi-color ring warnings thingatpt tex-ispell tex-style tex crm edit-server elnode dired+ image-dired image-mode exif format-spec image-file dired-x dired-aux dired dired-loaddefs db web time-stamp s url-util mailcap mm-encode mail-parse rfc2231 rfc2047 rfc2045 mm-util ietf-drums mail-prsvr fakir dotassoc kv noflet cl-indent dash ert ewoc debug backtrace help-mode find-func savehist desktop frameset drag-stuff recentf tree-widget wid-edit browse-kill-ring delsel backtr keyfreq uptimes pp server assoc advice windmove finder-inf package-x tab-line pcase easy-mmode cl rx tex-site info edmacro kmacro package easymenu browse-url url-handlers url-parse auth-source cl-seq eieio eieio-core cl-macs eieio-loaddefs password-cache json subr-x map url-vars seq byte-opt gv bytecomp byte-compile cconv cl-loaddefs cl-lib tooltip eldoc electric uniquify ediff-hook vc-hooks lisp-float-type mwheel term/ns-win ns-win ucs-normalize mule-util term/common-win tool-bar dnd fontset image regexp-opt fringe tabulated-list replace newcomment text-mode elisp-mode lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch timer select scroll-bar mouse jit-lock font-lock syntax facemenu font-core term/tty-colors frame minibuffer cl-generic cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european ethiopic indian cyrillic chinese composite charscript charprop case-table epa-hook jka-cmpr-hook help simple abbrev obarray cl-preloaded nadvice loaddefs button faces cus-face macroexp files text-properties overlay sha1 md5 base64 format env code-pages mule custom widget hashtable-print-readable backquote threads kqueue cocoa ns multi-tty make-network-process emacs) From debbugs-submit-bounces@debbugs.gnu.org Sat Apr 18 13:29:14 2020 Received: (at 40693) by debbugs.gnu.org; 18 Apr 2020 17:29:14 +0000 Received: from localhost ([127.0.0.1]:43534 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPrHG-0007EN-6g for submit@debbugs.gnu.org; Sat, 18 Apr 2020 13:29:14 -0400 Received: from mail-wr1-f44.google.com ([209.85.221.44]:35445) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPrHE-0007E9-1A for 40693@debbugs.gnu.org; Sat, 18 Apr 2020 13:29:12 -0400 Received: by mail-wr1-f44.google.com with SMTP id x18so6797586wrq.2 for <40693@debbugs.gnu.org>; Sat, 18 Apr 2020 10:29:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:subject:to:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=YPrb6/Jxk0KUL0/TSmxaWKNnHZdxL/4Q5cubk8UFGVI=; b=o48Ik4vAKOWRvJbxD6Mo+k+8qVvahmbNm83m6CNqUwv+SpNqPRwzHjWqPlBBKo7b+k XrxX2XfYiDf4wWGVrAvQuXy6NBGX05efLnXqMGNnYinNXbYa8MUi03M8WsD/HR0T51eb 1om6QmHpNsua59bV6mOXpH1QblxSQlFo5tFJhTmRJBEl8bycsJn8hci37K1XHm8NMu2/ tehJELpA6bvVg5S+sKMj1CgQ2tcc6qkgbo4w7ZO6l4S4K7R1lEnIPmvL48p8UPzjAyIN JnoogYAV5Nqofiu0bpWUcIEDpxLV3W7ieB2H7QV4igu1QYmNKKfaQj/bZ7c9fApZ1tQ4 UqMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:subject:to:references:from:message-id :date:user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=YPrb6/Jxk0KUL0/TSmxaWKNnHZdxL/4Q5cubk8UFGVI=; b=YvNiyBX4t5o07lCM3ihxkr4GlSD3TIoWPskq1HneQHoCb6VpfeC7IbzL3uoPdVewr1 fZRhNMJZR5fimjcbALG0jB5LYwO3wmP5yciGwjafB7uagYPwSDb6xK6IJRgg2rn+UH4/ 9WayT3QwrUNiDO8aXm54XFzIYNAzIwCI7S+fMTb1GhRPquuim5GMOPqmENLxuM+hvtep CsyQiZ5JTZECkGCSAWgSlh+juaGYQ8dcTSu1rteg4CakAiAVoLxN7SvGncvCs9zsPuW+ UU5yLcCjDpoxhwgd+PAe69726RPEIMdTN5L1UkYDKPoYNQAMlpLLM5ofFssU0hCUfarb bJnA== X-Gm-Message-State: AGi0PuYkw638zLD47aUsUvap4Mc8YzDSJnF+jW3oeKm1n4bDXmfjDEwb Va7mVm4MxckQpEtWnE+rM6ExzoH2pMM= X-Google-Smtp-Source: APiQypIsgWZBF5fDzpOXaEAj5Cs4RJ+s4jZn9d+TTVKBT4zzLOVBZ3zrYZGOD0RCCXAECLCMtVBTWw== X-Received: by 2002:adf:b1d1:: with SMTP id r17mr7932394wra.85.1587230945775; Sat, 18 Apr 2020 10:29:05 -0700 (PDT) Received: from [192.168.0.2] ([66.205.73.129]) by smtp.googlemail.com with ESMTPSA id q8sm12298401wmg.22.2020.04.18.10.29.04 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 18 Apr 2020 10:29:05 -0700 (PDT) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist To: Ivan Andrus , 40693@debbugs.gnu.org References: From: Dmitry Gutov Message-ID: Date: Sat, 18 Apr 2020 20:29:03 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.4.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Score: -0.3 (/) X-Debbugs-Envelope-To: 40693 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: -1.3 (-) Hi Ivan, thanks for the report. On 18.04.2020 05:59, Ivan Andrus wrote: > It's late now, but if I have some time in the next few days, I may submit a patch since it seems like a simple enough change. How about this one? diff --git a/lisp/json.el b/lisp/json.el index 18d7fda882..b65884f913 100644 --- a/lisp/json.el +++ b/lisp/json.el @@ -564,9 +564,10 @@ json-encode-alist "Return a JSON representation of ALIST." (when json-encoding-object-sort-predicate (setq alist - (sort alist (lambda (a b) - (funcall json-encoding-object-sort-predicate - (car a) (car b)))))) + (sort (copy-sequence alist) + (lambda (a b) + (funcall json-encoding-object-sort-predicate + (car a) (car b)))))) (format "{%s%s}" (json-join (json--with-indentation From debbugs-submit-bounces@debbugs.gnu.org Sat Apr 18 17:00:44 2020 Received: (at 40693) by debbugs.gnu.org; 18 Apr 2020 21:00:44 +0000 Received: from localhost ([127.0.0.1]:43682 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPuZw-0004Fn-9c for submit@debbugs.gnu.org; Sat, 18 Apr 2020 17:00:44 -0400 Received: from mail-io1-f49.google.com ([209.85.166.49]:41586) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPuZu-0004FY-DO for 40693@debbugs.gnu.org; Sat, 18 Apr 2020 17:00:43 -0400 Received: by mail-io1-f49.google.com with SMTP id b12so6432972ion.8 for <40693@debbugs.gnu.org>; Sat, 18 Apr 2020 14:00:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=a3Dkfmnb8hV1cjOu1vq0wWWOuBQ9fGX+C09tPgwGL8o=; b=ZwDRyltbNNqJfMK9owqYxFz8lOAWYLL3VsZLSti6ZRl/ajlZut8T5RQ2weHVAOKRh7 fm0uMVygUsKc/T/QTPwe9gpHXotZzoIf4B/+CthG8E2nfHMkUCHcUr+SWhn8wgE6VD0k XqnjcIgGyVNVtSGkpH8G0SBgROl6tfUn/NzYe6PykZ/R9SKj/lA1uPFRnAWJI6JqFDDH OmTxB3hFhTrL6fg1EMRf+7+5xzteDFAh/iQfJg7/ka+8AexULBuPPkv71Lzs9ddLxXAr eOkZBkWFtMTqJfDbNdg7k3UWnPW0lPedThMSwKEgi0rBpPpXBTaLXKxw9+h2LaSK3HZO 6KzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=a3Dkfmnb8hV1cjOu1vq0wWWOuBQ9fGX+C09tPgwGL8o=; b=dHx9UzCxjmAbU5GNmQAoeAv3u4Hhhz8wfDVWIaCIYazz8RfbJK8dgvk6OmVKCHV8nW uCg4gG1iHxgYebw4LSYDB2KycBRf80kdenOxRYDalqzv8fhqaa4k0FdXqC8Boxl802lo cWfi7GRsNMTAVwiQu7Hta/RirLnCYly3pBFG8Q9Kq98XlAasE0hmKxwTQ7hYA7hKluVp rJ5gA7BR3ISYZJmB5+F0Mc2U803Ef/JglFV3eJFO8xc7emoD6+0d8MGQfkfHZQ/ZPyX7 x/fD2BnwZ5GmuEPRPnJbZrjdcS8lHB0gR08hNuojU/FvwsDoDFPVKLPjtGC7//3QtiVS F5yQ== X-Gm-Message-State: AGi0Puag+lkI/ak39GLezhHxsorIyw8zyANnECGZKW6KMy1xgiZrwOl2 KihjIBQqzbuhNrmyKMPfSLU= X-Google-Smtp-Source: APiQypJlUUCVJblgzSjPjIrlOFUDcAgakduHzHQn9IDd/PEMU0kEq4/Y3hQbI+Y7MTOLdiLYCoMXWw== X-Received: by 2002:a5e:c64d:: with SMTP id s13mr9309493ioo.44.1587243636723; Sat, 18 Apr 2020 14:00:36 -0700 (PDT) Received: from [192.150.23.4] (67-2-50-168.slkc.qwest.net. [67.2.50.168]) by smtp.gmail.com with ESMTPSA id e66sm9496956ild.14.2020.04.18.14.00.34 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 18 Apr 2020 14:00:35 -0700 (PDT) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.14\)) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist From: Ivan Andrus In-Reply-To: Date: Sat, 18 Apr 2020 15:00:33 -0600 Content-Transfer-Encoding: quoted-printable Message-Id: <61141C1F-84EB-4FD7-80C2-10CA2D581434@gmail.com> References: To: Dmitry Gutov X-Mailer: Apple Mail (2.3445.104.14) X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 40693 Cc: 40693@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: -1.0 (-) That's basically what I had in mind, though I was also going to check = other json-encode functions (which you may have already done) to make = sure they didn't do something similar. -Ivan > On Apr 18, 2020, at 11:29 AM, Dmitry Gutov wrote: >=20 > Hi Ivan, >=20 > thanks for the report. >=20 > On 18.04.2020 05:59, Ivan Andrus wrote: >> It's late now, but if I have some time in the next few days, I may = submit a patch since it seems like a simple enough change. >=20 > How about this one? >=20 > diff --git a/lisp/json.el b/lisp/json.el > index 18d7fda882..b65884f913 100644 > --- a/lisp/json.el > +++ b/lisp/json.el > @@ -564,9 +564,10 @@ json-encode-alist > "Return a JSON representation of ALIST." > (when json-encoding-object-sort-predicate > (setq alist > - (sort alist (lambda (a b) > - (funcall json-encoding-object-sort-predicate > - (car a) (car b)))))) > + (sort (copy-sequence alist) > + (lambda (a b) > + (funcall json-encoding-object-sort-predicate > + (car a) (car b)))))) > (format "{%s%s}" > (json-join > (json--with-indentation From debbugs-submit-bounces@debbugs.gnu.org Sat Apr 18 19:13:11 2020 Received: (at 40693) by debbugs.gnu.org; 18 Apr 2020 23:13:11 +0000 Received: from localhost ([127.0.0.1]:43762 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPwe7-0007k8-Im for submit@debbugs.gnu.org; Sat, 18 Apr 2020 19:13:11 -0400 Received: from mout.web.de ([212.227.15.3]:45185) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPwe5-0007jr-DI for 40693@debbugs.gnu.org; Sat, 18 Apr 2020 19:13:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1587251582; bh=3ygIdZUry1gSP6RWSQkQBWz+pbUZDzBkNI0/tsHM9Eg=; h=X-UI-Sender-Class:From:To:Cc:Subject:References:Date:In-Reply-To; b=NSAe4TXyOCmRYdrWz65ftp2/ZhO4OMxkzuWKCB7+2eneyd7PNenGd/rBV7Ugkdtaw FZSJ86aHu267/1IpYs9Zm0n8dgLnfLwZoS9uNa1+yfv0g4OyaoF0GfCDXFMK3HUfwh ZQ1eoif2K/pV7P3CKyTg7/8vJqjo0qzWqhNhTziA= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from drachen.dragon ([188.98.99.7]) by smtp.web.de (mrweb003 [213.165.67.108]) with ESMTPSA (Nemesis) id 0Lp712-1inKdG1xFE-00eqUs; Sun, 19 Apr 2020 01:13:02 +0200 From: Michael Heerdegen To: Dmitry Gutov Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: Date: Sun, 19 Apr 2020 01:13:04 +0200 In-Reply-To: (Dmitry Gutov's message of "Sat, 18 Apr 2020 20:29:03 +0300") Message-ID: <87o8roxu9r.fsf@web.de> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Provags-ID: V03:K1:7WxnKm5WhM3N+Ab9rp1f0eQ81m9BdVR7Scf4IK86/7r+9om8GcB J8yHxpbcFupqQPpsAPwvNN/+QiQItzngdEo8igiRbmfEw63Vje/t+vYhP3l4jwpqbwe6CC/ AdhwiahlcSpCiu+7P/SKpm6cLMyaCNge4JVVpprmPqjVZq+PDEXvPFwua5nSPKax8d3TaIP 0h9KBbj9OqzN8pjCCA3mg== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:NWfliVxU9SM=:vgp09/hm68OwBvrA93Xgx/ psfAqp89YVD+PvFgY37sD20YMsuPW1TwMhrD4ptIt7MPfkmmqxAjb0fFrGtlulutfNEpn1eDm Xo56pYPrzfoJ2pMQwNCkv2OUAGF77gA5YdVzwh0kzuk22TJd9zwEucWmajBrLPdXVJobQKpNl hIYqSulVBMrMB0WkwH6J2KekKKJuD/VtLFS0TdPMFutN3T+xNPfmeh71fYldhU1GeM6K88M/k yHahlUozuwBpqxUNCVYBzT+IrCLJwO5vuDdcsXRhWMkqEYYkwEWzqjYsYq9H8HgPG4uTjuvml XFKpSGFako9KWNgCf5Gtxd9/3HBpjix2vgYGoqOgGDIm2LWQcM8yCTzAmPTvAt05oAW19eZ1s 6+cxh5twR67daoMDlwpVDkwTPEWQqtvo+iE4Wo39naaFOKPMiwwfLaupBvEgJHkPAv7UC6LW4 Rc3LVtUQjf6rQeK58KRXExM5QZ80x5Vy3CHjOBylLX4dUTGExbuHB9TBwdt5N8N4xdcf+mu3u 6SR3+LuNHg1srbWREnWM8Vk7Df59Jdfjjjnf5Sc1Le2cp/4rk3+CCelD+WNj7s7txKSJirA5c PrFSZRWySMBzxMD8TgOpVv7dbhfnAj7CE07Jpy1oY2lvxslcexkf4AUp9LyGqYMm6kEk9ICi6 FHIoBiGWPp2kfuva8JpoWkolmmWi7mpCbddFwbgBYjuPrCL0SbbRfxx5QC7e5o8pdPNYLigHT D1gKYKZH1TLjiaA4mgU/gnnDzKxNlJrLcMB9dZBE1NEdQ4TYgIWjRH8WdBpGWNogTc5ws/v+2 O8Mpn8mIphDl2sJfadB9khbzZPwYWVDnJ2pMOkC7FTzU5ZVX1g6gzuNxogt1lQ67MukfZgtfy W675mBuElgSCvyTvf5H0o8mmPN6Iu4St8+QbQGmQ27sBnHJBDqxqew8baFegWksJpb8RFWKmS YiXrmCERqTxcSthSyFvoxaE3Yjv0bww4URrPsaYfYUnwIxGq361hycqx2uGTvsGdIu5R3/EMq 8zEA4afVpQb9wVY7ev6xDmUM8HDJ1jchqyW8HhQapZz8TmzlZZnsWvuroDJTWB71iGdt7zcSm X3HwrvWb5EVoTMS2bt3k1d7a8XfuLefGe8A8bRbIDbwi+hJh8jyI/vx5JbYSBsn/0htoFzg+/ VdIlwixF+YWDcgqU5LESKqZczBwFjJPp1lVdTqTqvfO/vJypN7oNGgVntOzRsy2KTSeEyrPuc M+evSQtFWXWF9UV48 X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 40693 Cc: Ivan Andrus , 40693@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: -1.7 (-) Dmitry Gutov writes: > diff --git a/lisp/json.el b/lisp/json.el > index 18d7fda882..b65884f913 100644 > --- a/lisp/json.el > +++ b/lisp/json.el > @@ -564,9 +564,10 @@ json-encode-alist > "Return a JSON representation of ALIST." > (when json-encoding-object-sort-predicate > (setq alist > - (sort alist (lambda (a b) > - (funcall json-encoding-object-sort-predicate > - (car a) (car b)))))) > + (sort (copy-sequence alist) > + (lambda (a b) > + (funcall json-encoding-object-sort-predicate > + (car a) (car b)))))) > (format "{%s%s}" > (json-join > (json--with-indentation Why? Isn't this a classical example of modifiable code? After some iterations (symbol-function 'fun-withdraw) => (closure (t) (amount) (json-encode-alist (cons (cons 'tamount amount) '((const . some-constant) (tamount . 12) (tamount . 12) (tamount . 12))))) So the problem is in the implementation of `fun-withdraw', not in that of `json-encode-alist' or `sort'. I mean, it's really an example of an ugly trap, but how is `json-encode-alist' different from other functions working with lists that would exploit the same problem? Michael. From debbugs-submit-bounces@debbugs.gnu.org Sat Apr 18 20:10:23 2020 Received: (at 40693) by debbugs.gnu.org; 19 Apr 2020 00:10:23 +0000 Received: from localhost ([127.0.0.1]:43800 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPxXT-0000ni-Cs for submit@debbugs.gnu.org; Sat, 18 Apr 2020 20:10:23 -0400 Received: from mail-wr1-f41.google.com ([209.85.221.41]:35666) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPxXR-0000nT-S8 for 40693@debbugs.gnu.org; Sat, 18 Apr 2020 20:10:22 -0400 Received: by mail-wr1-f41.google.com with SMTP id x18so7567417wrq.2 for <40693@debbugs.gnu.org>; Sat, 18 Apr 2020 17:10:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=DVjFsHhSKf3QFFiXozLI7IG8RocnyA2wuGr4CE/zvws=; b=TdRhqltgYbFGjuO9vGBmxjq5Ayomev1C/VzBfgrPcj19KImqTQ2OKWbevSW4N1XI3g cU67GHZ4dcHcqQpqgS1t17GQ0dVsLHgf6ftJ0bryfWeZinepgo3feO2JrBjasIWWeXtV FxLNasjNvVM7g0wE3dnicj811i9tm30Oi8+djm7Pd7Hl4TEEi83woCQNnhojlpDjS+SY a9zVvLLvqpee5aDvZSFm3k4M2CGnJrxHs2IByKncLRbPfCRfaqEMaljneHoevRnbmgIL X5TYEhb+aijMLLdvTRwY1K0SS1+uJeipgyID2tb1EjnHz2VTWBlLt5nPttmHD5ciaV0M afjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:subject:to:cc:references:from:message-id :date:user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=DVjFsHhSKf3QFFiXozLI7IG8RocnyA2wuGr4CE/zvws=; b=gA8mUjgrz10kdWKMxaQYx3lwQihGtujGoEdSptUwpKCJ5nXy4gbVrftNFqGVWogzz3 BPfEvl9FtrrPk5feNwOhb1zC/4GNyZg5dJEDs1fOM5qY3Nk7/8JUtz8qD3XMJd05EriS ez4ktojnEkYoyyXSS4B96k+MUJZRhxMvRYqmCulnKKaTGZoOI53FPmXOSBnj9qclTzrp RGWjDYGePcjfkDmUGyEvM3zMgF3bNwfaTY6EeyA5izX6/AjayqmCWH3Kse7V7RZjfY8K 4z9D1rsBkj8aFEn72Skmj9x0X+EK9ZVzZNMycf4n8d6lduiDymCOwpNMfYDXW9Vpj139 bNDA== X-Gm-Message-State: AGi0PuZSnO74T4i5mtv+p9eHILXQGAyF+uDs7d+gfELEZi0dLaJtgDU+ x9G+yYWS21DEoAhX3W4Mn5eQr+yodNU= X-Google-Smtp-Source: APiQypKKxIK2A2YTB8sRrQXcT8NfPw69PT+9z6TT+UT+FO1pOhQKEzsSWAmzeIt3wZ7l7eR/OBOKQA== X-Received: by 2002:adf:f708:: with SMTP id r8mr10683212wrp.424.1587255015988; Sat, 18 Apr 2020 17:10:15 -0700 (PDT) Received: from [192.168.0.2] ([66.205.73.129]) by smtp.googlemail.com with ESMTPSA id z76sm653015wmc.9.2020.04.18.17.10.14 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 18 Apr 2020 17:10:15 -0700 (PDT) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist To: Michael Heerdegen References: <87o8roxu9r.fsf@web.de> From: Dmitry Gutov Message-ID: <5771055f-ddee-40e7-6d9e-79e0b39ff3dd@yandex.ru> Date: Sun, 19 Apr 2020 03:10:14 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.4.1 MIME-Version: 1.0 In-Reply-To: <87o8roxu9r.fsf@web.de> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Score: 0.5 (/) X-Debbugs-Envelope-To: 40693 Cc: Ivan Andrus , 40693@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: -0.5 (/) On 19.04.2020 02:13, Michael Heerdegen wrote: > I mean, it's really an example of an ugly trap, but how is > `json-encode-alist' different from other functions working with lists > that would exploit the same problem? It's a difference between cl-delete and cl-remove. For example. But unlike both of them, the semantics of json-encode-alist give no indication that the argument is going to be modified. From debbugs-submit-bounces@debbugs.gnu.org Sat Apr 18 20:30:04 2020 Received: (at 40693) by debbugs.gnu.org; 19 Apr 2020 00:30:04 +0000 Received: from localhost ([127.0.0.1]:43810 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPxqV-0001I8-Vo for submit@debbugs.gnu.org; Sat, 18 Apr 2020 20:30:04 -0400 Received: from mout.web.de ([212.227.15.3]:52361) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPxqT-0001HC-RC for 40693@debbugs.gnu.org; Sat, 18 Apr 2020 20:30:03 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1587256195; bh=447o3LRaiYxGtRSmIUaor3grxfY62gLjXZ/9IdxoY5o=; h=X-UI-Sender-Class:From:To:Cc:Subject:References:Date:In-Reply-To; b=doCzJ2fEcIZ1Tr1c+BAS5aR+P1wBUX8B2vgq31jKkvPR9YKgCQWQwcgTiQwv1BbTc +KvGrkaJk7hz9SknWXlmYptK54HqzmepkgAvXscsgIeq43yfvSURZk/O3Su01y11Dq jKYNhgT5cDWeIi9dWUnkz3dODwLiOQzRF1vVupiw= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from drachen.dragon ([188.98.99.7]) by smtp.web.de (mrweb004 [213.165.67.108]) with ESMTPSA (Nemesis) id 0M69CU-1j17RA3noI-00y6AR; Sun, 19 Apr 2020 02:29:55 +0200 From: Michael Heerdegen To: Dmitry Gutov Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87o8roxu9r.fsf@web.de> <5771055f-ddee-40e7-6d9e-79e0b39ff3dd@yandex.ru> Date: Sun, 19 Apr 2020 02:29:56 +0200 In-Reply-To: <5771055f-ddee-40e7-6d9e-79e0b39ff3dd@yandex.ru> (Dmitry Gutov's message of "Sun, 19 Apr 2020 03:10:14 +0300") Message-ID: <87d084qpvf.fsf@web.de> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Provags-ID: V03:K1:HNLD1NmHowcob19Ygpp/9Z/xp66pzg9OP/bpDwxEzLMrioQp7cm aThaHJsduHPQ3MeHdhaHydMM7qE6KY9a+WLZSIhVcwUkyVXTDLa+9on/85f9LfBS5h/Gclw LzC/4znBNR8Vnbg/rhOKxRP+gjKDP7vJTBu86PAPVY7jOTEWHAO2A5a1+D3Qf+uynjWurWq T9IOFILOiaawGG3vnL+/Q== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:fjqPhV+KHv0=:xTWBT/J5FyOyCB21YlN/qN NTUtXmW5ldc+0iG0hVqekwyjhMCXz3bjrukRPnf6gRedDzKVWVuE2v2UsJS3OqGmZDIMD93fU rCh7bIDiVMLR2De5TeYVxs4o9K65RxWhEFXogEY+NWhLL3vZ9lhkrBaYzVoB27UD8ypTpqcmO roNi3979usfhnUNzUB9kO7nKo9E/UQZqhDHoYul2//LElX8GPSXNYSrhYm4iMlGWeDbBdQM6X q9bbHHF8AI+b5t5L5MbSKpz1Od6jl9iRZpl1ULXWLHEpMAjTOilnreGRE0EM8zPvwaKk1MbKx QiVGqFG7oBZKSoW35VwjKaHn/2sUNpbh8rcpR9orVzNHXWeT1TYJWxJ0gvTr6ki/fcCo2UrjQ PAV1+J/dUwVfLvTCB2biUvA/8VmKQYuvfto4YgdUoX30CYUtOmgvp7L+zmr8vL/Vn+ZSY18Hv 2xqCt9eaC63qmjgZ7i41JBuG/jabWianeZBZornQ2DMp2w2lPpj+NyUVAnMLeVXhHXXSTdc7Z purp4PbDB+wmydLX4WVdA5yv+k/ZVg+/M2PFQ7C0k+HRzBKmkxWotMe2wfyiTpNvjlrWpBN4W uop3CaUekpKrE6vYpuhsXhKQRYIoRkazSI3pdjEA79SW9nffoGfvPEiT12mKZOZCq5K6Omhpe DB4nCIj8Cn9Clv5ye/l3sx8kHXpbGCctz9hYj8SO7EpmpRaAvaZJdoEUvnCxXbKaJpL3RtkmF eSp/cQytqNje3xSzsRWx8VeWbgwUZX4mtwUlPttE5A7PGV+Xh+Fa1bNIQTS6CEYA/pujK1OJN wnsOwYbP6/Nn8RBZAtfvtMwLbfUOMEOclNul1bq7f00Qv6Lh0DCwuGEwIhvMMBBa+kWdesscl nF6kA0xTHr7vMIxdxIx4UP1iFqyCxPsrHZ0Azb/rh8iRr2tveYwSBMeZUwvahpFnMieMrU8qy UHdqKo5q6o2xssl9zPAZAvrEaXBxdCji8A3uivPDqjFzAZoaMZqvVL/ljLFqnXrgS/ZqJvlxq PGl6rCTg0+KHzOGEUWXW1wsY3eaimtTbkluNJWYRzCrxigyJ8e95AsEc1V6ulCKnKLMeCS7V+ IK5O+t2wiSccDiZ9oGQPPB1S0L0iVapExAttW+jzFN++p6aex4EsTFqYHlrkMxiNboH/wzlFp ylhAEERtq7GUsOWNQbIrEalf5hnFHIA3pHlTllnbZqzydQbn8M6O31cgraDf3QScr+PiAaH0f MMZBh+FfJM0/TYmG+ X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 40693 Cc: Ivan Andrus , 40693@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: -1.7 (-) Dmitry Gutov writes: > [...] the semantics of json-encode-alist give no indication that the > argument is going to be modified. Ok, I missed that aspect of the issue. Michael. From debbugs-submit-bounces@debbugs.gnu.org Sat Apr 18 20:34:05 2020 Received: (at 40693) by debbugs.gnu.org; 19 Apr 2020 00:34:05 +0000 Received: from localhost ([127.0.0.1]:43815 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPxuP-0001P6-5o for submit@debbugs.gnu.org; Sat, 18 Apr 2020 20:34:05 -0400 Received: from mail-wr1-f49.google.com ([209.85.221.49]:34723) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPxuN-0001Oc-9R for 40693@debbugs.gnu.org; Sat, 18 Apr 2020 20:34:03 -0400 Received: by mail-wr1-f49.google.com with SMTP id j1so2137904wrt.1 for <40693@debbugs.gnu.org>; Sat, 18 Apr 2020 17:34:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tcd-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=D+uPPYsxWjqrJr6wo0Q3egPN2QbimRN1JvrHWgG7ZKA=; b=GqRuscVdHCayItVbxfSBrS7LCl8lTmt8ik4xeqs92WKO+zJful+BSdAxBMdUtxMxYx A7euvFKFQMkWmUdIEIpgN9gXMwZLk7YIRbRZ4tG71aaYZyL9eklfioDAkJNoQ6UlNmoe apFj0mLhMeRhq83PfyUBgFasnPUM9H5rRSpqZMMZCpXoMyMzY3n1TXCCCE4H6pw6Cw0l wg8wzyY2ltESletkBR7z/SeufWHZndSei+iW91NHdbpI+TyNjvVul2QQdHCDV9VFPBFU H8UUX9E3r7VWrW5ZIycbYOf1/ZYklEjo08xESi0BjnhS0hHJxo3t/7yMnjyCkupk8TWu Y3mg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=D+uPPYsxWjqrJr6wo0Q3egPN2QbimRN1JvrHWgG7ZKA=; b=W/BToLDEL1uQ3WUJhsim8rpGlK5u2Bt6kcqiFaK/akdtnoPWDFOwbYzup51Zk2I3Og S3H918fLeTIDgFqL+xLyevQIPbIeP9HNI21KgGcoIrVK1F/2BYv/dmIYU5lMMQk9CM04 TS6D/9ZZxTEcuadT7stgKd+U2urt0tfjeGpnb/MzAc3VpZOmfXxhwshA3bKIiyV1VoYP Y6IksZPmavhgzGYzlzLQFlALIlVso8UPujep+NSH9bQPGYVeJMbY9uELmvZLILRmOBaS kJjc9zqUFYtOlVDdovI8Mjoq1CX66dfMJdGtMfz2W9HGa7bduqhFM3Zxfo5L1IHjj8He We0Q== X-Gm-Message-State: AGi0PuZR1fqRis4UUVgCV1/rVJyiFNEu43zmOyh+5ouFc5oZYMbi2FTr 0XyMWzoFbBYa/KgnNng/AWC3fw== X-Google-Smtp-Source: APiQypKS62G2g2L/X5zusjV68bRldkG+IJ1Uc2SeualFCq6cKjGI0bK8CxsWvocVLlB7WKwX2DojjQ== X-Received: by 2002:adf:fe0e:: with SMTP id n14mr11998887wrr.247.1587256437418; Sat, 18 Apr 2020 17:33:57 -0700 (PDT) Received: from localhost ([2a02:8084:20e2:c380:92bd:1bfd:38fc:fae2]) by smtp.gmail.com with ESMTPSA id l5sm38058167wrm.66.2020.04.18.17.33.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Apr 2020 17:33:56 -0700 (PDT) From: "Basil L. Contovounesios" To: Michael Heerdegen Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87o8roxu9r.fsf@web.de> Date: Sun, 19 Apr 2020 01:33:55 +0100 In-Reply-To: <87o8roxu9r.fsf@web.de> (Michael Heerdegen's message of "Sun, 19 Apr 2020 01:13:04 +0200") Message-ID: <87d084jouk.fsf@tcd.ie> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -0.8 (/) X-Debbugs-Envelope-To: 40693 Cc: Ivan Andrus , 40693@debbugs.gnu.org, Dmitry Gutov 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: -1.8 (-) Michael Heerdegen writes: > Why? Isn't this a classical example of modifiable code? After some > iterations > > (symbol-function 'fun-withdraw) > > => > > (closure > (t) > (amount) > (json-encode-alist > (cons > (cons 'tamount amount) > '((const . some-constant) > (tamount . 12) > (tamount . 12) > (tamount . 12))))) > > So the problem is in the implementation of `fun-withdraw', not in that > of `json-encode-alist' or `sort'. > > I mean, it's really an example of an ugly trap, but how is > `json-encode-alist' different from other functions working with lists > that would exploit the same problem? A library function that encodes arbitrary Elisp objects as JSON shouldn't destructively modify its argument; it should be possible to call json-encode on the same object twice and get the same result. -- Basil From debbugs-submit-bounces@debbugs.gnu.org Sat Apr 18 20:34:48 2020 Received: (at 40693) by debbugs.gnu.org; 19 Apr 2020 00:34:48 +0000 Received: from localhost ([127.0.0.1]:43818 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPxv6-0001QE-DV for submit@debbugs.gnu.org; Sat, 18 Apr 2020 20:34:48 -0400 Received: from mail-wr1-f51.google.com ([209.85.221.51]:42958) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jPxv4-0001Q1-JZ for 40693@debbugs.gnu.org; Sat, 18 Apr 2020 20:34:47 -0400 Received: by mail-wr1-f51.google.com with SMTP id j2so7544822wrs.9 for <40693@debbugs.gnu.org>; Sat, 18 Apr 2020 17:34:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tcd-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=eTIyVYiGl9vC0MKBLbPziW+Li8FTdlsDmHyp+VSPS/I=; b=wvp3169KMVlVoVLBOrQCqqf67e+ILCsoYYwzwdfO2lqmKAqyZ0vmRuHbI8THIre8uT VOVqITKo6im6Ysw3jyrTIDdaFlSEzvyrEfcvNIykhsJd1TI4rmKBIX6afEs9HhW73c5l /An1dGZ2xaWUaRd6CKbjN+PJa9+I6uWv++H0WtCTQKAMR7dNen9HLHO+D/vkTWM7YdMg ItIH1QwFuZTHDYjlHZW4J0ii5Yn//T2DTEarSuofDaGQVOKsKsc3Ga/FTBfC6nsx8oVo Pv4oGcV8flipRaUQGmGgxj8X/U3DhkQslNIogWdO2y0jJ1yZoxdnM3u5n8bzW7SxwuDO iy9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=eTIyVYiGl9vC0MKBLbPziW+Li8FTdlsDmHyp+VSPS/I=; b=Qgfx+hHKznLvNXjJTINWwGVLxopfGHkgQIW9nF3tl2yAYS234agUwYQfmyyXKR0rp7 BCPkAXuW/2KW2kJfeZ6++UpVobaeJw3HBXtEgHXxpCSJYcKioMalRPuNZgiJRuBfQC8e BUseX/xKgB2DMOvC/cixm6hngU0fqbiATDcD/RIw5ohCPqgSqpNjq2hoLtkEb5aLYLrN TqHoBZmOxRoGi4k/uo8hzjYnMiyzW7264IKCOPoT61YeJeU2AcvmFFqpMpujJj42AXZ5 mSBdCnsErY51+H0tKjryv5Nwm4qYDk4nqY1uCUnvCH4EVAmjUq1It7u8k6ebixPjI7wD esBA== X-Gm-Message-State: AGi0PubzGeuPrnOW9qp5fnSYNPgrhBDXZ5P9hYMGyWyy31RjQqicUAv5 MgY8Aikvif8Q743KBpKSKDqcjg== X-Google-Smtp-Source: APiQypLKRH7W+VN+V9+NvYRDlREAnGdtMLxZFpXX7QKHEKW3+XpFLZsIfIC+kul4qQd+xBaZoN0Z4Q== X-Received: by 2002:adf:afdf:: with SMTP id y31mr11094818wrd.120.1587256480946; Sat, 18 Apr 2020 17:34:40 -0700 (PDT) Received: from localhost ([2a02:8084:20e2:c380:92bd:1bfd:38fc:fae2]) by smtp.gmail.com with ESMTPSA id v1sm33995375wrv.19.2020.04.18.17.34.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Apr 2020 17:34:39 -0700 (PDT) From: "Basil L. Contovounesios" To: Dmitry Gutov Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: Date: Sun, 19 Apr 2020 01:34:38 +0100 In-Reply-To: (Dmitry Gutov's message of "Sat, 18 Apr 2020 20:29:03 +0300") Message-ID: <87a738jotd.fsf@tcd.ie> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: -0.8 (/) X-Debbugs-Envelope-To: 40693 Cc: Ivan Andrus , 40693@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: -1.8 (-) --=-=-= Content-Type: text/plain Dmitry Gutov writes: > How about this one? > > diff --git a/lisp/json.el b/lisp/json.el > index 18d7fda882..b65884f913 100644 > --- a/lisp/json.el > +++ b/lisp/json.el > @@ -564,9 +564,10 @@ json-encode-alist > "Return a JSON representation of ALIST." > (when json-encoding-object-sort-predicate > (setq alist > - (sort alist (lambda (a b) > - (funcall json-encoding-object-sort-predicate > - (car a) (car b)))))) > + (sort (copy-sequence alist) > + (lambda (a b) > + (funcall json-encoding-object-sort-predicate > + (car a) (car b)))))) > (format "{%s%s}" > (json-join > (json--with-indentation LGTM. Perhaps add a test as well: --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=json-tests.diff diff --git a/test/lisp/json-tests.el b/test/lisp/json-tests.el index 05837e83f9..9d7ffd5feb 100644 --- a/test/lisp/json-tests.el +++ b/test/lisp/json-tests.el @@ -269,10 +269,13 @@ test-json-encode-plist-with-sort-predicate (should (equal (json-encode plist) "{\"a\":1,\"b\":2,\"c\":3}")))) (ert-deftest test-json-encode-alist-with-sort-predicate () - (let ((alist '((:c . 3) (:a . 1) (:b . 2))) - (json-encoding-object-sort-predicate 'string<) - (json-encoding-pretty-print nil)) - (should (equal (json-encode alist) "{\"a\":1,\"b\":2,\"c\":3}")))) + (let* ((alist '((:c . 3) (:a . 1) (:b . 2))) + (clone (copy-sequence alist)) + (json-encoding-object-sort-predicate #'string<) + (json-encoding-pretty-print nil)) + (should (equal (json-encode alist) "{\"a\":1,\"b\":2,\"c\":3}")) + ;; Ensure sorting isn't destructive (bug#40693). + (should (equal alist clone)))) (ert-deftest test-json-encode-list () (let ((json-encoding-pretty-print nil)) --=-=-= Content-Type: text/plain Eli, would this be okay for emacs-27? Thanks, -- Basil --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Sun Apr 19 16:35:38 2020 Received: (at 40693) by debbugs.gnu.org; 19 Apr 2020 20:35:39 +0000 Received: from localhost ([127.0.0.1]:46079 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQGfC-0008ID-MP for submit@debbugs.gnu.org; Sun, 19 Apr 2020 16:35:38 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:59138) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQGf9-0008Hz-Ll for 40693@debbugs.gnu.org; Sun, 19 Apr 2020 16:35:36 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 9C741160054; Sun, 19 Apr 2020 13:35:29 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id q1oGnQ1B9Zgk; Sun, 19 Apr 2020 13:35:28 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id D0EF5160065; Sun, 19 Apr 2020 13:35:28 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id ycff1FZnO_29; Sun, 19 Apr 2020 13:35:28 -0700 (PDT) Received: from [192.168.1.9] (cpe-23-242-74-103.socal.res.rr.com [23.242.74.103]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id AAE5E160054; Sun, 19 Apr 2020 13:35:28 -0700 (PDT) To: Ivan Andrus From: Paul Eggert Subject: Re: 28.0.50; json-encode-alist changes alist Organization: UCLA Computer Science Department Message-ID: <7b043ea4-2633-45dc-8e7f-79f86ff00d95@cs.ucla.edu> Date: Sun, 19 Apr 2020 13:35:25 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------53E1963C4DD79E529F79A7B1" Content-Language: en-US X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 40693 Cc: 40693@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 (---) This is a multi-part message in MIME format. --------------53E1963C4DD79E529F79A7B1 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit > I still find it surprising that a back-quoted list would behave that way Me too. This should be documented better, and to try to do that I installed the attached patch into the emacs-27 branch (this should appear on the master branch after the next merge). --------------53E1963C4DD79E529F79A7B1 Content-Type: text/x-patch; charset=UTF-8; name="0001-Document-that-quoting-yields-constants.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0001-Document-that-quoting-yields-constants.patch" >From 81e7d7f111872c9f2aaf8885db50a22ed746d7b5 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 19 Apr 2020 09:37:51 -0700 Subject: [PATCH] Document that quoting yields constants * doc/lispref/eval.texi (Quoting, Backquote): Mention that quoted expressions yield a constant (Bug#40693). --- doc/lispref/eval.texi | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/lispref/eval.texi b/doc/lispref/eval.texi index f6f36ed342..46cfab164b 100644 --- a/doc/lispref/eval.texi +++ b/doc/lispref/eval.texi @@ -558,6 +558,7 @@ and vectors.) @defspec quote object This special form returns @var{object}, without evaluating it. +The returned value is a constant, and should not be modified. @end defspec @cindex @samp{'} for quoting @@ -612,10 +613,12 @@ only part of a list, while computing and substituting other parts. @dfn{Backquote constructs} allow you to quote a list, but selectively evaluate elements of that list. In the simplest case, it -is identical to the special form @code{quote} +is identical to the special form @iftex +@code{quote}. @end iftex @ifnottex +@code{quote} (described in the previous section; @pxref{Quoting}). @end ifnottex For example, these two forms yield identical results: @@ -693,6 +696,9 @@ Here are some examples: @end group @end example +If a subexpression of a backquote construct has no substitutions or +splices, it acts like @code{quote} in that it yields a constant that +should not be modified. @node Eval @section Eval -- 2.17.1 --------------53E1963C4DD79E529F79A7B1-- From debbugs-submit-bounces@debbugs.gnu.org Sun Apr 19 17:01:52 2020 Received: (at 40693) by debbugs.gnu.org; 19 Apr 2020 21:01:52 +0000 Received: from localhost ([127.0.0.1]:46095 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQH4a-0000Sl-Ht for submit@debbugs.gnu.org; Sun, 19 Apr 2020 17:01:52 -0400 Received: from userp2130.oracle.com ([156.151.31.86]:58336) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQH4Y-0000SQ-Si for 40693@debbugs.gnu.org; Sun, 19 Apr 2020 17:01:51 -0400 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 03JKw63c081020; Sun, 19 Apr 2020 21:01:38 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=mime-version : message-id : date : from : sender : to : cc : subject : references : in-reply-to : content-type : content-transfer-encoding; s=corp-2020-01-29; bh=CA+/v3dAB89PMFhNq1wd3aBGQhhj07tEYBYDMedwOLc=; b=oq1YCRha4y1Vu/y/5RbAABC6HqzPhlozU7b9gaZoWMD+IMPDUIqrGMBgZvjB7xYdTNil bwZovk5zdwI1V9lugM/0OFe6E1fpJkM02OS9yhP4n1sCh74k503Gdl/9xlIzur2LDI87 MOfjXCqYDP6/4fgkVDYsPWwzL2vm6B6bMP6BjR1jpx6mo4yo+VtPwCYdLWVVjYPgdTKc tvM/V01Uw5YM5zGqz5mkGQxfy0PTL0QdRoqoMHvkT3vgMAuBkM0ZQ0M5Pmu5QFoKlBLB VcfA97+V1e87efr2OuA+9xzVFDP6VLskRY9EtvnwLQvXafEOLRQ6W/l5B4VhYvPG3B+o vg== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by userp2130.oracle.com with ESMTP id 30grpg8jfv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 19 Apr 2020 21:01:37 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 03JKwMti127122; Sun, 19 Apr 2020 21:01:37 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserp3020.oracle.com with ESMTP id 30gbb83sp7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 19 Apr 2020 21:01:37 +0000 Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id 03JL1Yur000707; Sun, 19 Apr 2020 21:01:35 GMT MIME-Version: 1.0 Message-ID: Date: Sun, 19 Apr 2020 14:01:33 -0700 (PDT) From: Drew Adams To: Paul Eggert , Ivan Andrus Subject: RE: bug#40693: 28.0.50; json-encode-alist changes alist References: <7b043ea4-2633-45dc-8e7f-79f86ff00d95@cs.ucla.edu> In-Reply-To: <7b043ea4-2633-45dc-8e7f-79f86ff00d95@cs.ucla.edu> X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.9.1 (1003210) [OL 16.0.4966.0 (x86)] Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9596 signatures=668686 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 malwarescore=0 suspectscore=0 mlxlogscore=992 adultscore=0 mlxscore=0 phishscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004190180 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9596 signatures=668686 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 mlxscore=0 lowpriorityscore=0 adultscore=0 suspectscore=0 bulkscore=0 clxscore=1011 malwarescore=0 phishscore=0 spamscore=0 priorityscore=1501 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004190180 X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 40693 Cc: 40693@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 (---) > @defspec quote object > This special form returns @var{object}, without evaluating it. > +The returned value is a constant, and should not be modified. > @end defspec Not true. The returned value _can be_ a constant, e.g., if the code is byte-compiled, and depending on the kind of object that's returned. 'foo returns the symbol foo. Depending on the context, you can certainly modify the properties of that symbol - its `symbol-value', `symbol-function', and `symbol-plist'. This kind of wholesale change risks making things less clear instead of more clear. See also Eli's message about the purpose of the manual, and the need to handle this overall message (about the byte-compiler sometimes causing a return value to become a constant) in a single place. The message should be about not _depending_ on a quoted value returning a new object (e.g. new list structure). The message should not be that `quote' never returns a new object. > +If a subexpression of a backquote construct has > +no substitutions or splices, it acts like > +@code{quote} in that it yields a constant that > +should not be modified. A constant is not something that _should not_ be modified. It's something that _cannot_ be modified. And something that should not be modified is not a constant. For a constant, there's zero reason to tell users not to modify it or tell them that they should not modify it - they _cannot_. From debbugs-submit-bounces@debbugs.gnu.org Sun Apr 19 18:14:22 2020 Received: (at 40693) by debbugs.gnu.org; 19 Apr 2020 22:14:22 +0000 Received: from localhost ([127.0.0.1]:46131 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQICj-00029u-N3 for submit@debbugs.gnu.org; Sun, 19 Apr 2020 18:14:22 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:41702) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQICh-00029f-74 for 40693@debbugs.gnu.org; Sun, 19 Apr 2020 18:14:20 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 1C01D160065; Sun, 19 Apr 2020 15:14:13 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id wT-mSZLKMTU3; Sun, 19 Apr 2020 15:14:12 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 1CEC016008E; Sun, 19 Apr 2020 15:14:12 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 9eOAESFMZe9g; Sun, 19 Apr 2020 15:14:12 -0700 (PDT) Received: from [192.168.1.9] (cpe-23-242-74-103.socal.res.rr.com [23.242.74.103]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id E4041160065; Sun, 19 Apr 2020 15:14:11 -0700 (PDT) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist To: Drew Adams , Ivan Andrus References: <7b043ea4-2633-45dc-8e7f-79f86ff00d95@cs.ucla.edu> From: Paul Eggert Organization: UCLA Computer Science Department Message-ID: Date: Sun, 19 Apr 2020 15:14:11 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/mixed; boundary="------------D1BD5F742FE72AAB903461C1" Content-Language: en-US X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 40693 Cc: 40693@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 (---) This is a multi-part message in MIME format. --------------D1BD5F742FE72AAB903461C1 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit On 4/19/20 2:01 PM, Drew Adams wrote: > 'foo returns the symbol foo. Depending on the > context, you can certainly modify the properties of > that symbol - its `symbol-value', `symbol-function', > and `symbol-plist'. Thanks for catching that. I installed the attached further patch to fix that. > The message should be about not _depending_ on a > quoted value returning a new object (e.g. new list > structure). The message should not be that `quote' > never returns a new object. The message is already in the new "Constants and Mutability" section in the emacs-27 branch. No doubt the wording could be improved.... > A constant is not something that _should not_ be > modified. It's something that _cannot_ be modified. This is merely a terminology issue; feel free to come up with better terminology. --------------D1BD5F742FE72AAB903461C1 Content-Type: text/x-patch; charset=UTF-8; name="0001-Fix-mutability-glitches-reported-by-Drew-Adams.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-Fix-mutability-glitches-reported-by-Drew-Adams.patch" >From e1d42da0d686e93534ee2abebe79bff95f18cb4d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 19 Apr 2020 15:09:02 -0700 Subject: [PATCH] Fix mutability glitches reported by Drew Adams See Bug#40693#32. * doc/lispref/eval.texi (Self-Evaluating Forms, Backquote): Say that these yield constant conses, vectors and strings, not constant symbols. * doc/lispref/objects.texi (Constants and Mutability): Say that an attempt to modify a constant variable signals an error, instead of saying that it has undefined behavior. --- doc/lispref/eval.texi | 8 ++++---- doc/lispref/objects.texi | 10 ++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/doc/lispref/eval.texi b/doc/lispref/eval.texi index deb288943a..f33c2faac1 100644 --- a/doc/lispref/eval.texi +++ b/doc/lispref/eval.texi @@ -158,8 +158,8 @@ contents unchanged. @end group @end example - A self-evaluating form yields a constant, and you should not attempt -to modify the constant's contents via @code{setcar}, @code{aset} or + A self-evaluating form yields constant conses, vectors and strings, and you +should not attempt to modify their contents via @code{setcar}, @code{aset} or similar primitives. The Lisp interpreter might unify the constants yielded by your program's self-evaluating forms, so that these constants might share structure. @xref{Constants and Mutability}. @@ -704,8 +704,8 @@ Here are some examples: @end example If a subexpression of a backquote construct has no substitutions or -splices, it acts like @code{quote} in that it yields a constant that -should not be modified. +splices, it acts like @code{quote} in that it yields constant conses, +vectors and strings that should not be modified. @node Eval @section Eval diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi index 98b001afd2..b45eb7ad8a 100644 --- a/doc/lispref/objects.texi +++ b/doc/lispref/objects.texi @@ -2395,17 +2395,19 @@ somewhere else. Although numbers are always constants and markers are always mutable, some types contain both constant and mutable members. These -types include conses, vectors, and strings. For example, the string +types include conses, vectors, strings, and symbols. For example, the string literal @code{"aaa"} yields a constant string, whereas the function call @code{(make-string 3 ?a)} yields a mutable string that can be changed via later calls to @code{aset}. - A program should not attempt to modify a constant because the + Modifying a constant symbol signals an error (@pxref{Constant Variables}). +A program should not attempt to modify other types of constants because the resulting behavior is undefined: the Lisp interpreter might or might not detect the error, and if it does not detect the error the interpreter can behave unpredictably thereafter. Another way to put -this is that mutable objects are safe to change, whereas constants are -not safely mutable: if you try to change a constant your program might +this is that although mutable objects are safe to change and constant +symbols reliably reject attempts to change them, other constants are +not safely mutable: if you try to change one your program might behave as you expect but it might crash or worse. This problem occurs with types that have both constant and mutable members, and that have mutators like @code{setcar} and @code{aset} that are valid on mutable -- 2.17.1 --------------D1BD5F742FE72AAB903461C1-- From debbugs-submit-bounces@debbugs.gnu.org Sun Apr 19 18:30:16 2020 Received: (at 40693) by debbugs.gnu.org; 19 Apr 2020 22:30:16 +0000 Received: from localhost ([127.0.0.1]:46165 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQIS7-0002aT-S4 for submit@debbugs.gnu.org; Sun, 19 Apr 2020 18:30:16 -0400 Received: from mout.web.de ([212.227.15.4]:35203) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQIS5-0002aA-CX for 40693@debbugs.gnu.org; Sun, 19 Apr 2020 18:30:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1587335379; bh=dIFa29yNbO24s11yHV46371Udl2IBTF50KesDd4NjyI=; h=X-UI-Sender-Class:From:To:Cc:Subject:References:Date:In-Reply-To; b=rblMx2p51Pl95FoDzTbJ6SHLPPTwCmKPX4SnVyTUmS6ja4AW7TMH8ZFQP9eUmQt/q kgGIxqe1BxuGBXP3XtakiG4RYUH9fKxhb9dM7Qe2dKnx3vgCj0ifIvrlu0clMS/X1k Ah1S+loXJvPNTQEvI+oSwpCA42nmSg1OFu0Tevdc= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from drachen.dragon ([188.98.99.7]) by smtp.web.de (mrweb001 [213.165.67.108]) with ESMTPSA (Nemesis) id 0MK2JZ-1jPTd93Lz3-001P5h; Mon, 20 Apr 2020 00:29:38 +0200 From: Michael Heerdegen To: Paul Eggert Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <7b043ea4-2633-45dc-8e7f-79f86ff00d95@cs.ucla.edu> Date: Mon, 20 Apr 2020 00:29:40 +0200 In-Reply-To: (Paul Eggert's message of "Sun, 19 Apr 2020 15:14:11 -0700") Message-ID: <87ftcz6re3.fsf@web.de> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Provags-ID: V03:K1:qTCbPMtsdU3XZwRVKFLxbdaziDvnVidexC2b3zOIsrbd0VpBUNU vjaJSxaXzwa5Q7nrJGwJOoODfDi7Q7Uv0TGk2e8UbbmGkg1lzdZN2kqKeEEtNCGgrSnYC+s /582rtvMsHCURPQjGfChgw8ehZetHX45zzMHs6pYuDNZ7jrJZDlGMIILjg5hH3snmlqUIxB KIPFHCI/FlWEHfUUBI1xA== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:Oe7p1x570dI=:q9X9wtT/b4fKlqY88gcIhj MCJJ+mN8r9Hx2eKzefF/0qS4IqErP2CM1RCOH34QM8eDCDVaAGqVTKpFws/TCV//LRlQmv2Fm zzP9c1NlGMjYuYvELSN5cF7HAoHFxWdZUVHw53i7MTMl25K8G6r597C4UVP/8yX41Vdk4hcYh BmI9ZO2Ese/4JNq+iqQsP2xzBhS2jBhdWwCf8nGmGtYqcQs06B5Hw7NsNPx/Y05DsJy+l/Kgz FP06+25/YNMdaHr17hqc67NEJW2+tu2wKXW+UMJbnpNQVjh1RFWwscB100Nnf51Btv9MKmmRG oPWKAeTXFu0SVl3vpe/70VMqu7bonPE2OrpRiAIxe6KyvVlxL3bvWb+efwpUyZOeWnjwey51Q zEYGvMw0U1XfiMdtbSYAqwVt2wnsli3mNo9k+ICKKg2iaESw9tVixYNvC7ZLd96aH4zf0aWOT f/1jvN8Jegj8i7368P1HPYpjRfNA8WSuy06m3wijSBkksOdtvylowF5sKIKHv7gLO2XwrEsq4 DNrEzsshK6+05k8ue05beIFZkVls1J2HEng1FIJ/iZFCAUCsxESKr18zXOZwshEs2crsz5e5U JcpwCvh8k/ac7mrMQteBhL851HfP/aRuYRnQ8jecJMQWsTyALNAMj1TjHeK87W7reECe0wo1E IX5LgNFDU8TsQmmsVl2WkpKC6JgLBwfnY4XtNQz7+eGMj8ppD4vRlT7l0mUvoSlze3/2hgK24 dUYtjhCh+OE5POMytX8qCUIHD/VIZqQjTJps+GsDjAFtLjhnnXkXSj1JbTbmectfTQ+FGBQJ5 keIoSlCYSrYtUGGVQFmo10sBJiLJz0TdrpRVyfSjj5kzcuOgNsSkkTiXTuPLR4HDL+uQ9qizq KsymefVe/zcwd5YZSaDxKCWyfU8ry1Nzda/yiyAWj9KSPCVrPI/xHHuxT+Qo6MXOHTgDoZZd9 bjEB7vRDiOcfQ/sBV1CBtmbnui0c55fBpdRpyRiWWDQfMNFjXzu6J/tcMBaSLKPCke2tOsx4G WQ8OEy9rghAp/yorNsuTMsXsR9HB+RBRwmIC2dXwCk2yYRkaBl96890xWED7RjwG/k4AV5Okp Ew8DkX8eSdoMYLfYAG0nSi7N7USRIsUM2LZNwxFgd0oztuDG+B5MlkXTzUZvdJTPAFxW4IWwf f8fOPwQWbRG09ydMpSPrSZtJalNNLRjqnLuQzkRPH4edz+xLljfWZOFoQrQHKwFTSn/h2qyoG VjTO14YhYH67ldsCD X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 40693 Cc: Ivan Andrus , 40693@debbugs.gnu.org, Drew Adams 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: -1.7 (-) Paul Eggert writes: > +types include conses, vectors, strings, and symbols. For example, the string > literal @code{"aaa"} yields a constant string, whereas the function > call @code{(make-string 3 ?a)} yields a mutable string that can be > changed via later calls to @code{aset}. > - A program should not attempt to modify a constant because the > + Modifying a constant symbol signals an error (@pxref{Constant Variables}). > +A program should not attempt to modify other types of constants because the Do you speak about symbols or the binding of symbols here? Michael. From debbugs-submit-bounces@debbugs.gnu.org Sun Apr 19 20:00:10 2020 Received: (at 40693) by debbugs.gnu.org; 20 Apr 2020 00:00:10 +0000 Received: from localhost ([127.0.0.1]:46247 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQJr7-0004gu-TE for submit@debbugs.gnu.org; Sun, 19 Apr 2020 20:00:10 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:52950) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQJr5-0004et-By for 40693@debbugs.gnu.org; Sun, 19 Apr 2020 20:00:08 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 0BE9C160054; Sun, 19 Apr 2020 17:00:01 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id 4ME3GT8c0FUE; Sun, 19 Apr 2020 17:00:00 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 33105160065; Sun, 19 Apr 2020 17:00:00 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id VHHqHmhm-s27; Sun, 19 Apr 2020 17:00:00 -0700 (PDT) Received: from [192.168.1.9] (cpe-23-242-74-103.socal.res.rr.com [23.242.74.103]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 073A1160054; Sun, 19 Apr 2020 17:00:00 -0700 (PDT) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist To: Michael Heerdegen References: <7b043ea4-2633-45dc-8e7f-79f86ff00d95@cs.ucla.edu> <87ftcz6re3.fsf@web.de> From: Paul Eggert Organization: UCLA Computer Science Department Message-ID: <83579d76-f2aa-a3f7-3b10-1839199002f1@cs.ucla.edu> Date: Sun, 19 Apr 2020 16:59:59 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <87ftcz6re3.fsf@web.de> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 40693 Cc: Ivan Andrus , 40693@debbugs.gnu.org, Drew Adams 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 (---) On 4/19/20 3:29 PM, Michael Heerdegen wrote: >> - A program should not attempt to modify a constant because the >> + Modifying a constant symbol signals an error (@pxref{Constant Variables}). >> +A program should not attempt to modify other types of constants because the > Do you speak about symbols or the binding of symbols here? I meant the symbol's value (what symbol-value returns). I could change the wording to "Modifying the value of a constant symbol..." From debbugs-submit-bounces@debbugs.gnu.org Sun Apr 19 20:26:07 2020 Received: (at 40693) by debbugs.gnu.org; 20 Apr 2020 00:26:07 +0000 Received: from localhost ([127.0.0.1]:46255 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQKGF-0005G9-8k for submit@debbugs.gnu.org; Sun, 19 Apr 2020 20:26:07 -0400 Received: from mout.web.de ([217.72.192.78]:46391) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQKGD-0005Ff-Jc for 40693@debbugs.gnu.org; Sun, 19 Apr 2020 20:26:06 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1587342345; bh=dMiXMwR71CJZS3FxPclJFaF2SbmNti0H25a0RRwXeEo=; h=X-UI-Sender-Class:From:To:Cc:Subject:References:Date:In-Reply-To; b=GHoxh+3Bg8nMrO5WiE+Uji6CHVSAYVGNkcv9fbJbbILVj4JBq3yr1KbeuWPzipHTH xiWZxZUG18cq4MYtAB8Xwu6bwhKPUOT6gKC0Cic5+6p2FoHoec+g2o3ESkN6DUoVR0 OYbBofCCXO8BL42V41ufMKt2fe8OIR0pPZvdUQKA= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from drachen.dragon ([188.98.99.7]) by smtp.web.de (mrweb101 [213.165.67.124]) with ESMTPSA (Nemesis) id 0MF3nL-1jTKPD3OGJ-00GIEN; Mon, 20 Apr 2020 02:25:44 +0200 From: Michael Heerdegen To: Paul Eggert Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <7b043ea4-2633-45dc-8e7f-79f86ff00d95@cs.ucla.edu> <87ftcz6re3.fsf@web.de> <83579d76-f2aa-a3f7-3b10-1839199002f1@cs.ucla.edu> Date: Mon, 20 Apr 2020 02:25:46 +0200 In-Reply-To: <83579d76-f2aa-a3f7-3b10-1839199002f1@cs.ucla.edu> (Paul Eggert's message of "Sun, 19 Apr 2020 16:59:59 -0700") Message-ID: <87sggzatpx.fsf@web.de> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Provags-ID: V03:K1:fWARWJg18koN4/hX6AXqp3l+l52m5+VYDBSTBG5XoZclQjmeR6u 9pYYe8Q+/b9A9EUAIvvhZV/haZuXyGsNq1RSPtIVMLPl1MV+5jHweTlsk0xRcYYHPJOvL2X 3yXukqPZYxtREyA0EBflg29UPhSEFzCEo7lyVY7Z/aByyz1Z8VCGNhE9aP062Q9ZmzR2QhH 5kREmbMwxXntNtP1fuiGA== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:PKay1Pg/6HM=:2fbqc/gToAFTQ4z5hzV4Zz b0yFHOHSChkb6nUyRPfB8oI45JmF1nTgyE5XPQ0ru0htJ8ZDIshvnNXyLsaVC6oSsYyIwY9yg 9VuKWS46HZoFZ4gmGkN+Sxl0xekdCjoElD4c3WuHqaJv0i5fvpLj6RDFHIwD8c9YBy7JAT6e9 vdyYKapnSm2zDlqXTT61jyDB7N58D9o4wuejT7eOMWKUbZnw2wC33aPyd/DjUQ9vjF1KlLsUq RM50Oo2Zv8pppjHp7IG7KzVlrz6AA0EqnieZRb8iLDtwek8jnq6+i2C8L2LWr9ME+jxV1Vjpb Y9nU5kepP9lOZxTs5UU5G6WLCoKA8QxmLsXVUoXxobPg9Z0vz79QYr8HzzKQQmg2FtajOtVo+ NMOF0DYP9FtcNPPuRMPYaY25IoUQznrHFiCTOdY49OThvvLAW8tYxKwBw+AmZCMK3bX/NmNao dSJFL6uYHKC887EYHVFNK6kl8AzlTAxc4Bj9JCJQMPbkdXkYLdQTRpltttHrJmOyDLbKBZ5p2 T5AfxfZaHrwz8LLK0aHj06ABGyWuUIo01M1sPIiHVawc598jdPoy7bFCu6Rs9XmG/2j1BGyJH TIlczxSQTp4c6isMaH3HLEmUn0LPuPX0HNZmxCnAXUtjAKYLQltwUBpGWZv8d6yDew+GU6Xdf Ci0qkrTB7PIglr5onXogQ97QJSRJDiYukYpgbx7BeuY1L7SYPy6T7ZzFLarj2RK/JizHE9JYH uluEiMaxYuebr5yyjT/yz17LMP0RU3Dwb72XcLEe+TMuRCKYm92uftdvD92gixsXQYquVSveF cKGvgVQ+qCuF0kfgyabiAr+XRLPHX745fAiNJZyrbR73qknVUwXwJjMoPZ3HtPJ7ok9NeYD4/ rqLMTTjZfY7W6dZbu2EmV/bzDixu71n7yyRg7fxmYt44CMdHqAzULo0yRzV/1x04ZXmdAYNrq l1lHa/0QPNklv33yTs+dvdXNTt3KQ8jqM2p0Mjsz5bkmsWZ/t1FcJ/VKxRLlOrskgleQ0ns9V jaGVQ3gOTe6nc84r7yulZZwR+8QxmoNjvo1VTcaOxDOuwhaqa2D8RCbrmOTgl7oabmoh0cmJS hSHf+H3r2m0OMUcVEe8GZt4F0iCRN9mrF4N5MqvCZhGG9iiCIU7kKm1FnCwn1J+UvNppDbaiY DB3c1rpLc9dV5K98mMNnOgpggldz/IL8i/1yY69kP2iOmDZf17KqpeIS6JO0vbB8kcEX5/iFM UPis0Bo5zG8xRjaxv X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 40693 Cc: Ivan Andrus , 40693@debbugs.gnu.org, Drew Adams 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: -1.7 (-) Paul Eggert writes: > On 4/19/20 3:29 PM, Michael Heerdegen wrote: > >> - A program should not attempt to modify a constant because the > >> + Modifying a constant symbol signals an error (@pxref{Constant > >> Variables}). > >> +A program should not attempt to modify other types of constants > >> because the > > Do you speak about symbols or the binding of symbols here? > > I meant the symbol's value (what symbol-value returns). I could change > the wording to "Modifying the value of a constant symbol..." This can be confused with variables declared with `defconst' - these are declared constants but it is possible to change their bindings. You are speaking about self-evaluating symbols like nil and t, right? Because all symbols are constants, try to change the symbol `foo', there is no way to change it in any way from Lisp. But you can evaluate it, and the binding is not always the same, unlike self-evaluating symbols like nil or :keyword. Michael. From debbugs-submit-bounces@debbugs.gnu.org Sun Apr 19 20:32:22 2020 Received: (at 40693) by debbugs.gnu.org; 20 Apr 2020 00:32:22 +0000 Received: from localhost ([127.0.0.1]:46265 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQKMI-0005Q7-78 for submit@debbugs.gnu.org; Sun, 19 Apr 2020 20:32:22 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:56822) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQKMG-0005Pt-5n for 40693@debbugs.gnu.org; Sun, 19 Apr 2020 20:32:20 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id E4F05160065; Sun, 19 Apr 2020 17:32:13 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id FsMY5FMDI1Dy; Sun, 19 Apr 2020 17:32:13 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 3FADD160079; Sun, 19 Apr 2020 17:32:13 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id i-iTHAvyyBIt; Sun, 19 Apr 2020 17:32:13 -0700 (PDT) Received: from [192.168.1.9] (cpe-23-242-74-103.socal.res.rr.com [23.242.74.103]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 10F91160065; Sun, 19 Apr 2020 17:32:13 -0700 (PDT) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist To: Michael Heerdegen References: <7b043ea4-2633-45dc-8e7f-79f86ff00d95@cs.ucla.edu> <87ftcz6re3.fsf@web.de> <83579d76-f2aa-a3f7-3b10-1839199002f1@cs.ucla.edu> <87sggzatpx.fsf@web.de> From: Paul Eggert Organization: UCLA Computer Science Department Message-ID: <769bd2ed-5844-86b1-e822-a91609130664@cs.ucla.edu> Date: Sun, 19 Apr 2020 17:32:12 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <87sggzatpx.fsf@web.de> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 40693 Cc: Ivan Andrus , 40693@debbugs.gnu.org, Drew Adams 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 (---) On 4/19/20 5:25 PM, Michael Heerdegen wrote: > This can be confused with variables declared with `defconst' - these are > declared constants but it is possible to change their bindings. You are > speaking about self-evaluating symbols like nil and t, right? Yes, and this includes symbols that start with : in the initial obarray (though there's a weird exception for (set :foo :foo)). How about if we change "Modifying a constant symbol signals an error..." to "Changing a self-evaluating symbol's value signals an error..."? From debbugs-submit-bounces@debbugs.gnu.org Sun Apr 19 20:57:18 2020 Received: (at 40693) by debbugs.gnu.org; 20 Apr 2020 00:57:18 +0000 Received: from localhost ([127.0.0.1]:46279 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQKkP-0005yt-Vn for submit@debbugs.gnu.org; Sun, 19 Apr 2020 20:57:18 -0400 Received: from mout.web.de ([212.227.15.14]:48441) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQKkO-0005yf-7t for 40693@debbugs.gnu.org; Sun, 19 Apr 2020 20:57:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1587344220; bh=JYOTEpdiZIIoei54dFjZs42rjUhXQqURus7ujzJhGsI=; h=X-UI-Sender-Class:From:To:Cc:Subject:References:Date:In-Reply-To; b=D1ueMwWTnC41pIU3YUkF+DAgdr4T+HrRZ9UxVwXUCWPKq2CXe+mwjAKCTqllhroHX MRyhooChDrUCLeY/Qhe9L6Kjj0iU/NaVilAw5c7zNla+VaQTVBNB1ei+Jy2B9M2cBr SkVy+5H0S1p3C7hiawA3nrstJEhRiC3JsIA1DT94= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from drachen.dragon ([188.98.99.7]) by smtp.web.de (mrweb004 [213.165.67.108]) with ESMTPSA (Nemesis) id 0MAjet-1jXjGx1pxT-00BxNA; Mon, 20 Apr 2020 02:57:00 +0200 From: Michael Heerdegen To: Paul Eggert Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <7b043ea4-2633-45dc-8e7f-79f86ff00d95@cs.ucla.edu> <87ftcz6re3.fsf@web.de> <83579d76-f2aa-a3f7-3b10-1839199002f1@cs.ucla.edu> <87sggzatpx.fsf@web.de> <769bd2ed-5844-86b1-e822-a91609130664@cs.ucla.edu> Date: Mon, 20 Apr 2020 02:57:01 +0200 In-Reply-To: <769bd2ed-5844-86b1-e822-a91609130664@cs.ucla.edu> (Paul Eggert's message of "Sun, 19 Apr 2020 17:32:12 -0700") Message-ID: <87k12bas9u.fsf@web.de> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Provags-ID: V03:K1:ct08gsI/9kfhVKmUfmbLNqT6uC/i+Gzfa1Gh2PAFvvbBmro0I1I apPYa6Y3MbJEwaRL6cfdk9vS36pSh9gmZ+8F41rW6HFmEje5IA9kH8MPbM1J/6/qbeXoGF1 T+zueH7K/yS1GzAh855/Mcj1JHpK2asNgEbo9p8aCZh6oiZdr7XVsoXXh1gO7jwZQrhkfER 3srwzix02uKNBFB2YEx7g== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1;V03:K0:CSkJ4raLgGQ=:ZlZ0Kj0l6jkjMqb3NQwOo4 QoyfquIWrRoDv4gpo1k/y0Vg9+JVmSLs+8yKPVbRNuZYaEsJvG7FSk+U3pWpObGfjzDLvnUC9 3xDqRr/JbfS3d3J70yHR/Lkp+kfiwDe+JCegNZRm1Xfy9gvrNRJvZ4RIfurC7H3QM7D2C3rIB +Lx0+CYJPmuuCwRiOrK1B07KVsfIQfG0l85ahArlDYzB2sjZ6gz/a5z/XUJ47SNLNSBSgHEWe V1lLAx1yBeS15zcWvEoD8BMRsFssoL+r68bCYio8oO6hud44gMoWKNAxnfMO7IjyTkmWVD96e SCOX3B+3vXkTIclbkjegebq0nNsW763N+Jgh+BKcEIi2WiRMoooL4pMeS6pIMak538WHD14s8 asA7/F5Kkao1izOYtSs5d3Y2HMNHFqiG2dARWZJSjDXgADG+guIu6BUDd7FZWVAbYw2j4KvQV 1J5wyotioHAjUsCzaRUt5z1VrA/aq08sGIL0Hx84lBi3CZ/4Zn3Gonwb4P6rQI7edCxVVMHzA eKGNtgfjL7JdOxGeoOQidXgQN4dtXR7WdNK5r4iMW8CYAVAdSlLncHdZX442mkoRWoIdFxzjJ 4dC+2MVR7bcosefBVbEdNzQVcbUgx8Hxj7gcOn2ZFQAhdGwBMROaAilaMpQRFK4CDN2ojM1MS 8kwAbJLmjOt/kKHK6A7/13hjad6trvQ+54hS03anoBt0oyK2bx/NG7ZUVgozVlPja9mb3nhkc aEHoCEsePqZesK846PumrUmi0xzmd2ELT6A4GcGk0ddDsLLbJtwbXgYONJh2PSvRkdKyVRbcF mHJN9++T/c0CveX11SA5XDnAbMZ30S3IqGp49UXpJ3firPKz9VgeY7eqfnAYTbeLSfrVsv+P5 bKjxPdMAMZJmDYjMFxCP9arxhca71U0NUmC0AqX0xBam5OdiW7h90b5fI5KNeTQeA9XecxK9f h4N/1l8OzYmIg1ufqna5rASUsbvQe4e0Lp6GEJo4a7EAX2itzmqz9qRrLUQjdi71siw4TPC2N HKOqTUmISWAA3uvkhRT4ZT/dfERdoLi85F7etc6qd/2XbGoKG61757VWB8R+uZWsdyysKf7Re SfhQzmPQSijX8xtgfTOm2BS+0axfjbx5Am4V03XiexEY65/EUsui7gKEXwq1PYelpkz3fsySg ccXXYYnlLv+7EzS2BFcRIyrpBmrwa50Um/jd7s+cPeTrTGFOo9p5r9CSjYVF2PX7HyKS/rBCU uyCbmGdGEgal4Sz79 X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 40693 Cc: Ivan Andrus , 40693@debbugs.gnu.org, Drew Adams 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: -1.7 (-) Paul Eggert writes: > How about if we change "Modifying a constant symbol signals an > error..." to "Changing a self-evaluating symbol's value signals an > error..."? Yes, better (though I would rather say "Trying to..." or "Attempting to..." - Emacs doesn't let you do this, i.e. you get the error before it's too late). Michael. From debbugs-submit-bounces@debbugs.gnu.org Sun Apr 19 22:55:59 2020 Received: (at 40693) by debbugs.gnu.org; 20 Apr 2020 02:55:59 +0000 Received: from localhost ([127.0.0.1]:46348 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQMbH-0000Mv-1p for submit@debbugs.gnu.org; Sun, 19 Apr 2020 22:55:59 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:42154) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQMbE-0000Me-8v for 40693@debbugs.gnu.org; Sun, 19 Apr 2020 22:55:57 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 2DC6E160065; Sun, 19 Apr 2020 19:55:49 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id Ly8o0V4nVIrG; Sun, 19 Apr 2020 19:55:48 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 7A5A9160079; Sun, 19 Apr 2020 19:55:48 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id ppnd3YMNANzM; Sun, 19 Apr 2020 19:55:48 -0700 (PDT) Received: from [192.168.1.9] (cpe-23-242-74-103.socal.res.rr.com [23.242.74.103]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 4C47B160065; Sun, 19 Apr 2020 19:55:48 -0700 (PDT) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist To: Michael Heerdegen References: <7b043ea4-2633-45dc-8e7f-79f86ff00d95@cs.ucla.edu> <87ftcz6re3.fsf@web.de> <83579d76-f2aa-a3f7-3b10-1839199002f1@cs.ucla.edu> <87sggzatpx.fsf@web.de> <769bd2ed-5844-86b1-e822-a91609130664@cs.ucla.edu> <87k12bas9u.fsf@web.de> From: Paul Eggert Organization: UCLA Computer Science Department Message-ID: Date: Sun, 19 Apr 2020 19:55:47 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <87k12bas9u.fsf@web.de> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 40693 Cc: Ivan Andrus , 40693@debbugs.gnu.org, Drew Adams 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 (---) On 4/19/20 5:57 PM, Michael Heerdegen wrote: >> How about if we change "Modifying a constant symbol signals an >> error..." to "Changing a self-evaluating symbol's value signals an >> error..."? > Yes, better (though I would rather say "Trying to..." or "Attempting > to..." - Emacs doesn't let you do this, i.e. you get the error before > it's too late). OK, I put it in with "Trying to". Also, I changed "self-evaluating symbol" to "Constant variable" because the latter class includes the former, and also includes a few variables like most-positive-fixnum that are not self-evaluating but still cannot be modified. Who came up with the term "Constant variable", anyway? They must have had an odd sense of humor. From debbugs-submit-bounces@debbugs.gnu.org Mon Apr 20 01:45:58 2020 Received: (at 40693) by debbugs.gnu.org; 20 Apr 2020 05:45:58 +0000 Received: from localhost ([127.0.0.1]:46461 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQPFm-0004VA-Ct for submit@debbugs.gnu.org; Mon, 20 Apr 2020 01:45:58 -0400 Received: from userp2130.oracle.com ([156.151.31.86]:52142) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQPFk-0004Uw-4Y for 40693@debbugs.gnu.org; Mon, 20 Apr 2020 01:45:56 -0400 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 03K5iFpF033855; Mon, 20 Apr 2020 05:45:49 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=mime-version : message-id : date : from : sender : to : cc : subject : references : in-reply-to : content-type : content-transfer-encoding; s=corp-2020-01-29; bh=ou8ROfaIyBfwTvz+LKOo7ZznYez6eM9cRkFIXBuXDw4=; b=bm99MXFd7X6uR8EfxAvtsIpnhqF8ZbLsksaL1H1ryDbzeuTgEv5UMHiEfHOFY9/vBLW7 ZFXkTyAm0w7746ldwuzQsMXnsuoxAMGQK3qajrwbcWKV1Q5RAYiBPSpBEViZ3IJXni+s 4JQNfopaE4gdNczdYe8BT85ed2EKRhUWatYAlzmdx4IrOAXPQWZoun7iFozNFPaHv/jP 9wsH/zQl0DUaxDSrkYo37heXw7pwxYk9w1CEsMs1FZ5t43P/+S/baOe6ypLNC5AYHZmD JEdyZjlvloB4iS6AVt1ax7kkaQIOCiTVZAARF7FUJ3CEUEtZQwDSAIye11lNiapx6DNn Yw== Received: from userp3020.oracle.com (userp3020.oracle.com [156.151.31.79]) by userp2130.oracle.com with ESMTP id 30grpg9ea0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 20 Apr 2020 05:45:49 +0000 Received: from pps.filterd (userp3020.oracle.com [127.0.0.1]) by userp3020.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 03K5hOTm091982; Mon, 20 Apr 2020 05:45:48 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userp3020.oracle.com with ESMTP id 30gb8vkep0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 20 Apr 2020 05:45:48 +0000 Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id 03K5jgb3017485; Mon, 20 Apr 2020 05:45:42 GMT MIME-Version: 1.0 Message-ID: Date: Sun, 19 Apr 2020 22:45:41 -0700 (PDT) From: Drew Adams To: Michael Heerdegen , Paul Eggert Subject: RE: bug#40693: 28.0.50; json-encode-alist changes alist References: <7b043ea4-2633-45dc-8e7f-79f86ff00d95@cs.ucla.edu> <87ftcz6re3.fsf@web.de> <83579d76-f2aa-a3f7-3b10-1839199002f1@cs.ucla.edu> <87sggzatpx.fsf@web.de> <769bd2ed-5844-86b1-e822-a91609130664@cs.ucla.edu> <87k12bas9u.fsf@web.de> In-Reply-To: <87k12bas9u.fsf@web.de> X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.9.1 (1003210) [OL 16.0.4966.0 (x86)] Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9596 signatures=668686 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 adultscore=0 bulkscore=0 suspectscore=0 malwarescore=0 phishscore=0 spamscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004200050 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9596 signatures=668686 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 mlxscore=0 lowpriorityscore=0 adultscore=0 suspectscore=0 bulkscore=0 clxscore=1015 malwarescore=0 phishscore=0 spamscore=0 priorityscore=1501 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004200050 X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 40693 Cc: Ivan Andrus , 40693@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 (---) > > How about if we change "Modifying a constant symbol signals an > > error..." to "Changing a self-evaluating symbol's value signals an > > error..."? >=20 > Yes, better (though I would rather say "Trying to..." or "Attempting > to..." - Emacs doesn't let you do this, i.e. you get the error before > it's too late). Yes. It's good to explicitly say that we're talking about changing a symbol's value here, and not just changing a symbol. The notion of "changing" a symbol can mean different things to different readers. Consider (put nil 'toto 42) or (put :foo 'toto 42). Did we change the symbol nil or :foo, both of which are self-evaluating? For some meaning of "change", we did - we changed its property list. The message should be just that you can't change the `symbol-value' of a self-evaluating symbol/variable. From debbugs-submit-bounces@debbugs.gnu.org Mon Apr 20 10:56:29 2020 Received: (at 40693) by debbugs.gnu.org; 20 Apr 2020 14:56:29 +0000 Received: from localhost ([127.0.0.1]:48258 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQXqW-0003Uw-Ri for submit@debbugs.gnu.org; Mon, 20 Apr 2020 10:56:29 -0400 Received: from eggs.gnu.org ([209.51.188.92]:50148 helo=eggs1p.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jQXqV-0003Ug-Ta for 40693@debbugs.gnu.org; Mon, 20 Apr 2020 10:56:28 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:48651) by eggs1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jQXqQ-0006on-8o; Mon, 20 Apr 2020 10:56:22 -0400 Received: from [176.228.60.248] (port=4212 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1jQXqP-0002hh-Kd; Mon, 20 Apr 2020 10:56:22 -0400 Date: Mon, 20 Apr 2020 17:56:19 +0300 Message-Id: <83o8rmgq98.fsf@gnu.org> From: Eli Zaretskii To: Paul Eggert In-Reply-To: (message from Paul Eggert on Sun, 19 Apr 2020 19:55:47 -0700) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <7b043ea4-2633-45dc-8e7f-79f86ff00d95@cs.ucla.edu> <87ftcz6re3.fsf@web.de> <83579d76-f2aa-a3f7-3b10-1839199002f1@cs.ucla.edu> <87sggzatpx.fsf@web.de> <769bd2ed-5844-86b1-e822-a91609130664@cs.ucla.edu> <87k12bas9u.fsf@web.de> X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 40693 Cc: michael_heerdegen@web.de, darthandrus@gmail.com, 40693@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: -1.7 (-) > From: Paul Eggert > Date: Sun, 19 Apr 2020 19:55:47 -0700 > Cc: Ivan Andrus , 40693@debbugs.gnu.org > > Who came up with the term "Constant variable", anyway? They must have had an odd > sense of humor. "Constants aren't, variables won't", right? From debbugs-submit-bounces@debbugs.gnu.org Wed Apr 29 06:11:50 2020 Received: (at 40693) by debbugs.gnu.org; 29 Apr 2020 10:11:50 +0000 Received: from localhost ([127.0.0.1]:42468 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jTjgz-0007Fm-O9 for submit@debbugs.gnu.org; Wed, 29 Apr 2020 06:11:49 -0400 Received: from mail-pj1-f52.google.com ([209.85.216.52]:51788) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jTjgx-0007FV-Iy for 40693@debbugs.gnu.org; Wed, 29 Apr 2020 06:11:48 -0400 Received: by mail-pj1-f52.google.com with SMTP id mq3so584173pjb.1 for <40693@debbugs.gnu.org>; Wed, 29 Apr 2020 03:11:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tcd-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=0PW8X/D9mgcgfPLKam1disCxZtfckp2CuUrgnhN6lXE=; b=otNKGmWRgYkA3mm2srwmLvRqfbVsHsQ+yjGplk0LXqyElS6njCab1FYOJhvGrAdYF5 sFkXlQJQtATHTlgLlDtOx0LGRT7LpLCnRgeu2ODn+esh3AMjabYRn+hb9lEy9Kj1bcyh jC0SwiLgLa3zcKd66Yfq9S9betS6NYwPu7CYKgAQsO6hy2ouc3uLnCQdXJGIiB6t3PAa 2Eo2brD3CI/CxuMdE91eSKIpJ1MkItobSRfoRZ1FhWWqGtLG6PT04E/6B7GLTcr5XLnZ DV63w7Er5yUlK0B+aPANvVkS7krrQYg8bXovr0YoBRKAdcEGu1sSpC0vDtC3zQo0B6N6 fJBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=0PW8X/D9mgcgfPLKam1disCxZtfckp2CuUrgnhN6lXE=; b=IrwECUDCAImFDYOVbYAN30S3DvgwaEemEBapqDPNyHbHdVjGqhcNfvq1oEVOU1IftB 7ew1oNg9Bo95vXtAHfpoczNOZUb2bxJJeMvXG2PbQn5jKCitYadxfXy5gfzbpEAaVb4I hYqbfrO4tGbyY71Nn0+4tYLdteQ+A9jpd10UlSYYCljQk+nubQpguC6nj9bNx4uCTrV0 tMQmn3K2BCDLLafev/50vg5G/dOKojIECI4HZBs4eWzP48eGzML1MutRrjSI7kF0V+xv L7FEga1uDdjaBIsfIJFzMbdgoC0xVHpxFrbbtWVZhhjlA8aFqzFNsImadhcj+6Oa0irs Hm3g== X-Gm-Message-State: AGi0Pua2jsycBSikmELsC/AZwCoj3e1X7+4BcVt53UkAxNWfvmQ0S2Gi LYhT+AgFB7BY3F/nHn2LUxLolQ== X-Google-Smtp-Source: APiQypLzdu9eVzaqqTUyIrgWBpdx77ccNZ4pny3Au4UjFtVTq5gj21phECQQV6KKjY64N19aqW4wjg== X-Received: by 2002:a17:90a:d17:: with SMTP id t23mr2370507pja.77.1588155101581; Wed, 29 Apr 2020 03:11:41 -0700 (PDT) Received: from localhost ([2a02:8084:20e2:c380:92bd:1bfd:38fc:fae2]) by smtp.gmail.com with ESMTPSA id w11sm794304pfq.100.2020.04.29.03.11.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Apr 2020 03:11:40 -0700 (PDT) From: "Basil L. Contovounesios" To: Dmitry Gutov Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> Date: Wed, 29 Apr 2020 11:11:38 +0100 In-Reply-To: <87a738jotd.fsf@tcd.ie> (Basil L. Contovounesios's message of "Sun, 19 Apr 2020 01:34:38 +0100") Message-ID: <87mu6utxd1.fsf@tcd.ie> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -0.0 (/) X-Debbugs-Envelope-To: 40693 Cc: Ivan Andrus , 40693@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: -1.0 (-) "Basil L. Contovounesios" writes: > Dmitry Gutov writes: > >> How about this one? >> >> diff --git a/lisp/json.el b/lisp/json.el >> index 18d7fda882..b65884f913 100644 >> --- a/lisp/json.el >> +++ b/lisp/json.el >> @@ -564,9 +564,10 @@ json-encode-alist >> "Return a JSON representation of ALIST." >> (when json-encoding-object-sort-predicate >> (setq alist >> - (sort alist (lambda (a b) >> - (funcall json-encoding-object-sort-predicate >> - (car a) (car b)))))) >> + (sort (copy-sequence alist) >> + (lambda (a b) >> + (funcall json-encoding-object-sort-predicate >> + (car a) (car b)))))) >> (format "{%s%s}" >> (json-join >> (json--with-indentation > > LGTM. Perhaps add a test as well: > > diff --git a/test/lisp/json-tests.el b/test/lisp/json-tests.el > index 05837e83f9..9d7ffd5feb 100644 > --- a/test/lisp/json-tests.el > +++ b/test/lisp/json-tests.el > @@ -269,10 +269,13 @@ test-json-encode-plist-with-sort-predicate > (should (equal (json-encode plist) "{\"a\":1,\"b\":2,\"c\":3}")))) > > (ert-deftest test-json-encode-alist-with-sort-predicate () > - (let ((alist '((:c . 3) (:a . 1) (:b . 2))) > - (json-encoding-object-sort-predicate 'string<) > - (json-encoding-pretty-print nil)) > - (should (equal (json-encode alist) "{\"a\":1,\"b\":2,\"c\":3}")))) > + (let* ((alist '((:c . 3) (:a . 1) (:b . 2))) > + (clone (copy-sequence alist)) > + (json-encoding-object-sort-predicate #'string<) > + (json-encoding-pretty-print nil)) > + (should (equal (json-encode alist) "{\"a\":1,\"b\":2,\"c\":3}")) > + ;; Ensure sorting isn't destructive (bug#40693). > + (should (equal alist clone)))) > > (ert-deftest test-json-encode-list () > (let ((json-encoding-pretty-print nil)) > > > Eli, would this be okay for emacs-27? Any chance of getting this fix in? Thanks, -- Basil From debbugs-submit-bounces@debbugs.gnu.org Wed Apr 29 06:31:29 2020 Received: (at 40693) by debbugs.gnu.org; 29 Apr 2020 10:31:29 +0000 Received: from localhost ([127.0.0.1]:42487 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jTk00-00080H-Ou for submit@debbugs.gnu.org; Wed, 29 Apr 2020 06:31:29 -0400 Received: from eggs.gnu.org ([209.51.188.92]:37874) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jTjzy-000800-Ty for 40693@debbugs.gnu.org; Wed, 29 Apr 2020 06:31:27 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:52158) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jTjzs-0006za-SL; Wed, 29 Apr 2020 06:31:20 -0400 Received: from [176.228.60.248] (port=4594 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1jTjzp-0005JI-Da; Wed, 29 Apr 2020 06:31:18 -0400 Date: Wed, 29 Apr 2020 13:30:58 +0300 Message-Id: <83r1w6ziql.fsf@gnu.org> From: Eli Zaretskii To: "Basil L. Contovounesios" In-Reply-To: <87mu6utxd1.fsf@tcd.ie> (contovob@tcd.ie) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 40693 Cc: darthandrus@gmail.com, 40693@debbugs.gnu.org, dgutov@yandex.ru 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 (---) > From: "Basil L. Contovounesios" > Date: Wed, 29 Apr 2020 11:11:38 +0100 > Cc: Ivan Andrus , 40693@debbugs.gnu.org > > > Eli, would this be okay for emacs-27? > > Any chance of getting this fix in? No one tried to come up with arguments why this has to be in emacs-27. From debbugs-submit-bounces@debbugs.gnu.org Wed Apr 29 08:09:08 2020 Received: (at 40693) by debbugs.gnu.org; 29 Apr 2020 12:09:08 +0000 Received: from localhost ([127.0.0.1]:42621 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jTlWW-00044t-2J for submit@debbugs.gnu.org; Wed, 29 Apr 2020 08:09:08 -0400 Received: from mail-wr1-f46.google.com ([209.85.221.46]:40511) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jTlWU-00044O-6g for 40693@debbugs.gnu.org; Wed, 29 Apr 2020 08:09:07 -0400 Received: by mail-wr1-f46.google.com with SMTP id k13so2216661wrw.7 for <40693@debbugs.gnu.org>; Wed, 29 Apr 2020 05:09:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=4wD9HXTgXjp/9Vxwyb4v8KoYsjD5+rci5bP5/63JWPs=; b=oxYiBFJx9nGumADp+ZPPRcNp9j0XebS1RCyNr5qvHI4LkHoBEY+t8itm6xrNgufR1l Zn28ApGtDahwYgiiaL3Qd+WpBqF3+RS5I+OSsh9x0voRKEznmgXd0w88942YHEHTRXyq Mz9gYKhF26yto2DX04ikIHM7jg+Qw6unbB8LX/kJi6FrkUIcH8pOyi7H8RxtGvzn0Yis znKo/9bEBN+fvZBt0KrPBbi2CVNYfEHfZFVdP2bpoV1Q+t7j0O+tM9QQnRowZ4Jq7Q4A mDpn/XwfKvKe9f+ybe11/+kQv0IzKBnW2RVzDjHc9Yb5vokKyyhFOu7tPANYe1Cz7OWK gFgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:subject:to:cc:references:from:message-id :date:user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=4wD9HXTgXjp/9Vxwyb4v8KoYsjD5+rci5bP5/63JWPs=; b=YOH4mJY9lKnYSbpYEN+nAqYqAH3xRiivsZepLXoOqD9qU0KkK1ieOPA8OjwWwH6jN2 3WBcYsRyu7UfUNhK0w5fT/ai1fgFhFYbSSrpcDVWoYuisFt0AflgY6MRC0oTstwziL6f F5K0j2nP7cW+V1C1GUxjeuOLQyk/fdh36vE0gm0V2mDBchINcEG/hY9Sgqxk7QDK+ElR GMkVMIBvG5NoZV3xYp1PNBTh0MtlSwbt/hpGNQs+L3Z0F10PST90ch//rTUQSoeEuD7W x9581RaMRagHSHENfqf49zdTJCWIKJ0FLqjaS2/Q9wWz6f0fGX8IJQ0/iKY16WgTzgmp OMNg== X-Gm-Message-State: AGi0PuYlDJkVDVzh7T4SEAYq5mL0Kd346bZntNSBp2GXxkGlXbqjTER5 BABDpuifd/j18Od8PxO31VdSvN15//g= X-Google-Smtp-Source: APiQypJXPXzp0D2JpTvdoDNAl6IILYhJDxn/Q/RUmX34g2kbC3JUXI3rHz0vH8YuCGbt1pPIu9J6IA== X-Received: by 2002:adf:cd84:: with SMTP id q4mr36717995wrj.320.1588162139915; Wed, 29 Apr 2020 05:08:59 -0700 (PDT) Received: from [192.168.0.2] ([66.205.73.129]) by smtp.googlemail.com with ESMTPSA id i17sm29712632wru.39.2020.04.29.05.08.58 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 29 Apr 2020 05:08:58 -0700 (PDT) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist To: Eli Zaretskii , "Basil L. Contovounesios" References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> From: Dmitry Gutov Message-ID: <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> Date: Wed, 29 Apr 2020 15:08:57 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <83r1w6ziql.fsf@gnu.org> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Score: 0.5 (/) X-Debbugs-Envelope-To: 40693 Cc: darthandrus@gmail.com, 40693@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: -0.5 (/) On 29.04.2020 13:30, Eli Zaretskii wrote: >> From: "Basil L. Contovounesios" >> Date: Wed, 29 Apr 2020 11:11:38 +0100 >> Cc: Ivan Andrus , 40693@debbugs.gnu.org >> >>> Eli, would this be okay for emacs-27? >> >> Any chance of getting this fix in? > > No one tried to come up with arguments why this has to be in emacs-27. Let me try: It fixes a bug, one which could be annoying to investigate, the fix is small and localized to the case when json-encoding-object-sort-predicate is non-nil (so pretty safe). It's not a regression from Emacs 26, though. From debbugs-submit-bounces@debbugs.gnu.org Wed Apr 29 08:22:11 2020 Received: (at 40693) by debbugs.gnu.org; 29 Apr 2020 12:22:11 +0000 Received: from localhost ([127.0.0.1]:42639 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jTlj8-0004Ns-Vi for submit@debbugs.gnu.org; Wed, 29 Apr 2020 08:22:11 -0400 Received: from eggs.gnu.org ([209.51.188.92]:51846) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jTlj7-0004Nf-A6 for 40693@debbugs.gnu.org; Wed, 29 Apr 2020 08:22:10 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:53739) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jTlj1-0005C9-Ml; Wed, 29 Apr 2020 08:22:03 -0400 Received: from [176.228.60.248] (port=3808 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1jTlj1-0002iN-3T; Wed, 29 Apr 2020 08:22:03 -0400 Date: Wed, 29 Apr 2020 15:21:45 +0300 Message-Id: <83blnazdly.fsf@gnu.org> From: Eli Zaretskii To: Dmitry Gutov In-Reply-To: <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> (message from Dmitry Gutov on Wed, 29 Apr 2020 15:08:57 +0300) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 40693 Cc: contovob@tcd.ie, darthandrus@gmail.com, 40693@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 (---) > Cc: darthandrus@gmail.com, 40693@debbugs.gnu.org > From: Dmitry Gutov > Date: Wed, 29 Apr 2020 15:08:57 +0300 > > > No one tried to come up with arguments why this has to be in emacs-27. > > Let me try: > > It fixes a bug, one which could be annoying to investigate, the fix is > small and localized to the case when json-encoding-object-sort-predicate > is non-nil (so pretty safe). It also makes the function slower. Which may be an important issue for JSON processing. Callers that don't care about the original list will be "punished" regardless. How about adding an optional argument instead, by default off, to request this behavior? then callers who care about the original alist could request a non-destructive operation, and others won't suffer any slowdown. > It's not a regression from Emacs 26, though. Right. From debbugs-submit-bounces@debbugs.gnu.org Wed Apr 29 10:28:27 2020 Received: (at 40693) by debbugs.gnu.org; 29 Apr 2020 14:28:27 +0000 Received: from localhost ([127.0.0.1]:44172 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jTnhK-0007kP-Nl for submit@debbugs.gnu.org; Wed, 29 Apr 2020 10:28:27 -0400 Received: from mail-wm1-f51.google.com ([209.85.128.51]:33967) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jTnh7-0007jy-Gd for 40693@debbugs.gnu.org; Wed, 29 Apr 2020 10:28:25 -0400 Received: by mail-wm1-f51.google.com with SMTP id v4so5071435wme.1 for <40693@debbugs.gnu.org>; Wed, 29 Apr 2020 07:28:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=aY45RHq+YqhW/30iSpWl9hlpAvW9uCFGhOIUbAuXTU4=; b=KkXNR75IRySXIhXuzZDaBEQR75bWEGZj7RfhfVJzdCOiVHjMuYkvQI/kLmA9tOY+b8 WkZS0D9r/ikmgnqo6WuxHI0Wevjy+YE1THpC6FbtYf+VFUaL1Iail+pEgv+VyM5il34j o7knOhj3rcLV3zNz5IGF9oR8cGZgrVEbIE7iFlfQb0oFjHRi1IaG5Ylq7IgGQiF87nOX vckUTIyyXF1WzE0gDxJdQm0BLPdgCRlQ1gIP3fkx6rP9gGDEH9zDEOXzKCRXRWQW8pKq ZWCJA7Qi+6mcK89iFpT4z1H0puW/kZFWjr/QJ4d5/NuUmgDn1IBbkwJ/jUEa4a4XeTJn TwTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:subject:to:cc:references:from:message-id :date:user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=aY45RHq+YqhW/30iSpWl9hlpAvW9uCFGhOIUbAuXTU4=; b=s11Cn2iK1F85SPylM3U7YuhiKZyj3woAVLB0dm5b63wAE/B0cZsjCBFvezwFE6S2nf WD9KeBNGdbVW/ahHdoxdw2g7tClbY636YiLy55T8hUsVhGhZ2vg7w+UmKp65CZNjQfED C8GEx8CuNYkOwQm5STenmNfA3Wrx6ZLUs1uZHz3uVYFZbI1Zp3jxFmlLgmrVwwnzlkb3 1HFnXpLJfZ6Ph9DRzzU20687yFNuQCH0YXZxvV9gGqCwUcrU3191OpkPbhukcS9jmX6J 7E1Uxw3Ppe7dQYTzYc2pZV2TJtkQUTjnKuyOF4QItDyx2K6LlWZXCwy6WRueJypeDV9Q vLvg== X-Gm-Message-State: AGi0PuaUm5SKB8RrgktckM7Ww+tm7LLlWJ6K0IhwKbMerXoTEHHPx0DT FaMnPZlMkCPmEpM7ehQb3mV03e/jf1M= X-Google-Smtp-Source: APiQypJsbOblikEY2kHSY2dLWlxVpJ3sEyZhGBvNQCz9hBrwcL/GKyl12Pa9svTX5wDkijGZ5JtUZg== X-Received: by 2002:a1c:2d14:: with SMTP id t20mr3731571wmt.28.1588170487361; Wed, 29 Apr 2020 07:28:07 -0700 (PDT) Received: from [192.168.0.2] ([66.205.73.129]) by smtp.googlemail.com with ESMTPSA id m14sm30192439wrs.76.2020.04.29.07.28.05 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 29 Apr 2020 07:28:06 -0700 (PDT) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist To: Eli Zaretskii References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> From: Dmitry Gutov Message-ID: <349d9b1b-4659-907e-c6e1-30cdf052c87f@yandex.ru> Date: Wed, 29 Apr 2020 17:28:05 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <83blnazdly.fsf@gnu.org> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Score: 1.5 (+) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.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 the administrator of that system for details. Content preview: On 29.04.2020 15:21, Eli Zaretskii wrote: >> Cc: darthandrus@gmail.com, 40693@debbugs.gnu.org >> From: Dmitry Gutov >> Date: Wed, 29 Apr 2020 15:08:57 +0300 >> >>> No one tried to come up with argum [...] Content analysis details: (1.5 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: gnu.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (dgutov[at]yandex.ru) 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different 0.2 FREEMAIL_FORGED_FROMDOMAIN 2nd level domains in From and EnvelopeFrom freemail headers are different 1.0 FREEMAIL_REPLY From and body contain different freemails X-Debbugs-Envelope-To: 40693 Cc: contovob@tcd.ie, darthandrus@gmail.com, 40693@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: -0.5 (/) On 29.04.2020 15:21, Eli Zaretskii wrote: >> Cc: darthandrus@gmail.com, 40693@debbugs.gnu.org >> From: Dmitry Gutov >> Date: Wed, 29 Apr 2020 15:08:57 +0300 >> >>> No one tried to come up with arguments why this has to be in emacs-27. >> >> Let me try: >> >> It fixes a bug, one which could be annoying to investigate, the fix is >> small and localized to the case when json-encoding-object-sort-predicate >> is non-nil (so pretty safe). > > It also makes the function slower. Which may be an important issue > for JSON processing. Callers that don't care about the original list > will be "punished" regardless. It's a somewhat fair point (copy-sequence is much faster than sort, usually, but if we include GC time, it can be significant). The way json-encoding-object-sort-predicate is implemented, though, it's not very performance-oriented. Applications like lsp-mode aren't going to use this variable, so they shouldn't be hit (and it isn't supported in native JSON either). On that subject, users really shouldn't set it either. Rather, any user-facing feature that outputs JSON, when this behavior could be desirable, should have its own tweaking knob. > How about adding an optional argument instead, by default off, to > request this behavior? then callers who care about the original alist > could request a non-destructive operation, and others won't suffer any > slowdown. The current behavior is unsafe, that's the problem. Also, json-encode-alist is called in a recursive fashion, so it'd have to be a global variable instead. From debbugs-submit-bounces@debbugs.gnu.org Wed Apr 29 10:40:34 2020 Received: (at 40693) by debbugs.gnu.org; 29 Apr 2020 14:40:34 +0000 Received: from localhost ([127.0.0.1]:44209 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jTnt4-00085K-8P for submit@debbugs.gnu.org; Wed, 29 Apr 2020 10:40:34 -0400 Received: from eggs.gnu.org ([209.51.188.92]:47092) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jTnt2-000856-Mt for 40693@debbugs.gnu.org; Wed, 29 Apr 2020 10:40:33 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:56362) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jTnsx-0006vw-1b; Wed, 29 Apr 2020 10:40:27 -0400 Received: from [176.228.60.248] (port=4408 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1jTnsw-0002mK-77; Wed, 29 Apr 2020 10:40:26 -0400 Date: Wed, 29 Apr 2020 17:40:04 +0300 Message-Id: <83368mz77f.fsf@gnu.org> From: Eli Zaretskii To: Dmitry Gutov In-Reply-To: <349d9b1b-4659-907e-c6e1-30cdf052c87f@yandex.ru> (message from Dmitry Gutov on Wed, 29 Apr 2020 17:28:05 +0300) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> <349d9b1b-4659-907e-c6e1-30cdf052c87f@yandex.ru> X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 40693 Cc: contovob@tcd.ie, darthandrus@gmail.com, 40693@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 (---) > Cc: contovob@tcd.ie, darthandrus@gmail.com, 40693@debbugs.gnu.org > From: Dmitry Gutov > Date: Wed, 29 Apr 2020 17:28:05 +0300 > > > How about adding an optional argument instead, by default off, to > > request this behavior? then callers who care about the original alist > > could request a non-destructive operation, and others won't suffer any > > slowdown. > > The current behavior is unsafe, that's the problem. Also, > json-encode-alist is called in a recursive fashion, so it'd have to be a > global variable instead. Sounds like a somewhat hairy issue. Then let's put this on master first. If this turns out to be a very popular change, and no one complains, we could later back-port it to some 27.x version. Thanks. From debbugs-submit-bounces@debbugs.gnu.org Wed Apr 29 10:41:29 2020 Received: (at 40693) by debbugs.gnu.org; 29 Apr 2020 14:41:29 +0000 Received: from localhost ([127.0.0.1]:44213 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jTntx-000870-I7 for submit@debbugs.gnu.org; Wed, 29 Apr 2020 10:41:29 -0400 Received: from mail-pg1-f194.google.com ([209.85.215.194]:43797) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jTntw-00086k-Sn for 40693@debbugs.gnu.org; Wed, 29 Apr 2020 10:41:29 -0400 Received: by mail-pg1-f194.google.com with SMTP id x26so1099827pgc.10 for <40693@debbugs.gnu.org>; Wed, 29 Apr 2020 07:41:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tcd-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=4tpI/d4LVeWBhHU/6PUXEPhl+cmffAW3U9FgH/ELXpw=; b=gC72wp2c8VdpM0qIg8WvGmSNbbHGpwA9Y6ok64+A4XEKYO0Z3VRpT7lp0sCs45pHGZ n8+jnBp9C94JceAZEt70NOR3Hoy1FQwCEcIBZjfQKhnxMY0n3uNeBR3jsLu5AuBWLEFZ T+RLRHdjzO2MGTCgAGv1CyyNIWNngz6lHKAYVqsYzY1Dqbd8yTP4fn1290WTBH8kUcUw caEib2Ewg3dM/KEovmuzzb4HffpcPPcgP0qQ/uACYTtct6BSi4DwFh0qBuzgfCW+fVLC tBlYkZQGYYz89OQLLGEq585Y9T5BiXSzYyM93m595irdjAHcqWjt+xsUCN7hYv2sSUf9 8JQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=4tpI/d4LVeWBhHU/6PUXEPhl+cmffAW3U9FgH/ELXpw=; b=eGa0KAbWTYdEPnq0ziJ13Gl8NLP2sHQeMM5XwwvU1gKp9sE/pHkuJ+F1YcWDHOx27l zPuhNuVh1qWCy1E2sURYl6wSS4ngfwoqsRMtJ06QFuz3kpupXvW9lV/rpsWWb+SNLfmH EJ+db1g8SyhT/q+UcnjrA06dvdhDvXSM8BxpHPVikQL1Jb6J+et+fmZr34gfWReMpZaa NjcapW//lpvwBMtbIxyW3KiwKDaNHkISnH2YHHKelXFcHDqz2pEkp5761ZE3sJp1yVpC jC6CJjlXEhKFCJuDfO3TjgUJ7bu1/YrXgI2MeOazXm49shRv/YT/51SwmMeOdR2sHeb5 ZMbg== X-Gm-Message-State: AGi0PuaDXgzZ6Dctx4HipVxWR46S9lStHftQkIwcpSE7GJ6NG7n4pfM8 Wq8orppDC19lhqEnz3YvVL8VcQ== X-Google-Smtp-Source: APiQypI4R20wHJ/IJyQ3D8f/olTtCYSaVeQZF+XsYJbbvODy6X4csAc0UeYg+yeDgIzZojMzDHfgQQ== X-Received: by 2002:a63:220a:: with SMTP id i10mr5816344pgi.364.1588171282950; Wed, 29 Apr 2020 07:41:22 -0700 (PDT) Received: from localhost ([2a02:8084:20e2:c380:92bd:1bfd:38fc:fae2]) by smtp.gmail.com with ESMTPSA id i25sm1187221pfo.196.2020.04.29.07.41.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Apr 2020 07:41:22 -0700 (PDT) From: "Basil L. Contovounesios" To: Eli Zaretskii Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> Date: Wed, 29 Apr 2020 15:41:19 +0100 In-Reply-To: <83blnazdly.fsf@gnu.org> (Eli Zaretskii's message of "Wed, 29 Apr 2020 15:21:45 +0300") Message-ID: <87wo5yqrqo.fsf@tcd.ie> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 40693 Cc: darthandrus@gmail.com, 40693@debbugs.gnu.org, Dmitry Gutov 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: -1.0 (-) Eli Zaretskii writes: >> Cc: darthandrus@gmail.com, 40693@debbugs.gnu.org >> From: Dmitry Gutov >> Date: Wed, 29 Apr 2020 15:08:57 +0300 >> >> > No one tried to come up with arguments why this has to be in emacs-27. >> >> Let me try: >> >> It fixes a bug, one which could be annoying to investigate, the fix is >> small and localized to the case when json-encoding-object-sort-predicate >> is non-nil (so pretty safe). > > It also makes the function slower. Which may be an important issue > for JSON processing. Callers that don't care about the original list > will be "punished" regardless. > > How about adding an optional argument instead, by default off, to > request this behavior? then callers who care about the original alist > could request a non-destructive operation, and others won't suffer any > slowdown. That was my first thought too. I have a local WIP branch where I am refactoring parts of json.el to improve performance, and avoiding the proposed copy-sequence is one of the fixes. I've also found a couple of test JSON files to benchmark against. >> It's not a regression from Emacs 26, though. > > Right. The reasons I thought the copy-sequence fix might be desirable in Emacs 27 are: 1. It's a simple enough fix to go into the release branch. 2. Users who enable json-encoding-object-sort-predicate are already trading off performance for sort order. In addition to the cost of sorting, hash table and plist objects have to first be converted to alists before they can be sorted. My guess is that an extra copy-sequence won't make a big difference here. 3. Users who care about sheer performance of JSON serialisation will either avoid json-encoding-object-sort-predicate or use the newer Jansson functions. I don't personally mind whether this gets into emacs-27; I just wanted to see what others thought. Thanks, -- Basil From debbugs-submit-bounces@debbugs.gnu.org Wed Apr 29 11:03:02 2020 Received: (at 40693) by debbugs.gnu.org; 29 Apr 2020 15:03:02 +0000 Received: from localhost ([127.0.0.1]:44276 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jToEo-0000Ge-3q for submit@debbugs.gnu.org; Wed, 29 Apr 2020 11:03:02 -0400 Received: from mail-wm1-f45.google.com ([209.85.128.45]:55372) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jToEm-0000GE-GS for 40693@debbugs.gnu.org; Wed, 29 Apr 2020 11:03:01 -0400 Received: by mail-wm1-f45.google.com with SMTP id e26so2392941wmk.5 for <40693@debbugs.gnu.org>; Wed, 29 Apr 2020 08:03:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=jJ0xlG/tSYvGitimE65NuyaeyhiHIfZubbynUXir/H8=; b=N62xN9i1or/hids5HZMeCzu8dUNyD4+f8VRb6nNMUU2YLrtLMssuwTANzwfjNssyKn bcQlVi4ovebFFD39kiB25hc9381pe3WHF3bXSUmJQJEnBsLnw3BWdQaWO2VChfIfR/dO O2NFP7bekTU+Xng0BItclbZNflvRyTHwGBoP2XWO3u4YazoQ8smfA3VX9ge2LdtQPawU uRfJ9xYXG3BYOcA2CppTy4HqhkMlGOiiv3/juYa3i7U+6lV7IOmXYPV+h1OsbSc5syKp Zz6epWIw6EJ/G1hcIv+RtR3AQcd14UYcSHpjtFYSGtvccg5pWS3tQsxkZsA8zSKtsS7t iswA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:subject:to:cc:references:from:message-id :date:user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=jJ0xlG/tSYvGitimE65NuyaeyhiHIfZubbynUXir/H8=; b=JhfUloGh/KzBnEkstVqNIi4KuZB4Opoy2byDVuwEswn8cvAOf+gXdv5mPrBrVE561x ePhCkpcgNaibqZpmsK9/Rlze8LD74+RZtDeIlfIVKq0rZS2bCO2BZRNOGIre7GN8YM5V 4agszPGH6BDAW0MnM7bD8sJr5Q3/ne4jXfQyf70EQDJCyxYtBVYvUdzxrUSAC4FIYQxr pqhkplkJxREObfwkrVm32+E3e/S9LgC+AtHn/+EGezAusLdSsVZuQ0lrtLKo8FFTxXgg DelqNtXj4sUYfQO6y4FpFHZzfU6Jeewg8h2nl9/E8ypaMpX/l9lt3Zv1OXVu6SsY6i09 xPlQ== X-Gm-Message-State: AGi0Puap1YZdu1Nm3VxG+S5iwD6Sr8TF52HH2XdXtozsw7qCp+xykUbw ioVR7ZBdE6jozrR9+Govd2M/D7o373c= X-Google-Smtp-Source: APiQypLrDeAk+PE2RGY37WPTCBCEMqn33VWVfaVRP41bxiXIjRinYmMfZZh1METLYKdw0W+OzEre1A== X-Received: by 2002:a1c:c345:: with SMTP id t66mr3958919wmf.189.1588172574236; Wed, 29 Apr 2020 08:02:54 -0700 (PDT) Received: from [192.168.0.2] ([66.205.73.129]) by smtp.googlemail.com with ESMTPSA id p6sm30470727wrt.3.2020.04.29.08.02.52 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 29 Apr 2020 08:02:53 -0700 (PDT) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist To: Eli Zaretskii References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> <349d9b1b-4659-907e-c6e1-30cdf052c87f@yandex.ru> <83368mz77f.fsf@gnu.org> From: Dmitry Gutov Message-ID: <4305317a-73ee-8d4e-dada-1a45ecacc9d6@yandex.ru> Date: Wed, 29 Apr 2020 18:02:52 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <83368mz77f.fsf@gnu.org> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Score: 1.5 (+) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.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 the administrator of that system for details. Content preview: On 29.04.2020 17:40, Eli Zaretskii wrote: >> Cc: contovob@tcd.ie, darthandrus@gmail.com, 40693@debbugs.gnu.org >> From: Dmitry Gutov >> Date: Wed, 29 Apr 2020 17:28:05 +0300 >> >>> How about adding [...] Content analysis details: (1.5 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: tcd.ie] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (raaahh[at]gmail.com) 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.128.45 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.128.45 listed in wl.mailspike.net] 0.2 FREEMAIL_FORGED_FROMDOMAIN 2nd level domains in From and EnvelopeFrom freemail headers are different 1.0 FREEMAIL_REPLY From and body contain different freemails X-Debbugs-Envelope-To: 40693 Cc: contovob@tcd.ie, darthandrus@gmail.com, 40693@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: -0.5 (/) On 29.04.2020 17:40, Eli Zaretskii wrote: >> Cc: contovob@tcd.ie, darthandrus@gmail.com, 40693@debbugs.gnu.org >> From: Dmitry Gutov >> Date: Wed, 29 Apr 2020 17:28:05 +0300 >> >>> How about adding an optional argument instead, by default off, to >>> request this behavior? then callers who care about the original alist >>> could request a non-destructive operation, and others won't suffer any >>> slowdown. >> >> The current behavior is unsafe, that's the problem. Also, >> json-encode-alist is called in a recursive fashion, so it'd have to be a >> global variable instead. > > Sounds like a somewhat hairy issue. Then let's put this on master > first. If this turns out to be a very popular change, and no one > complains, we could later back-port it to some 27.x version. *shrug*, I'm certainly not going to insist, but we could push the "slightly slower" simple patch to emacs-27, and go with Basil's refactor (sounds exciting!) on master. From debbugs-submit-bounces@debbugs.gnu.org Wed Apr 29 11:07:57 2020 Received: (at 40693) by debbugs.gnu.org; 29 Apr 2020 15:07:57 +0000 Received: from localhost ([127.0.0.1]:44293 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jToJZ-0000P8-4E for submit@debbugs.gnu.org; Wed, 29 Apr 2020 11:07:57 -0400 Received: from eggs.gnu.org ([209.51.188.92]:51514) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jToJX-0000Ov-HL for 40693@debbugs.gnu.org; Wed, 29 Apr 2020 11:07:55 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:56946) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jToJS-0006h9-0d; Wed, 29 Apr 2020 11:07:50 -0400 Received: from [176.228.60.248] (port=2108 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1jToJQ-0007SY-RO; Wed, 29 Apr 2020 11:07:49 -0400 Date: Wed, 29 Apr 2020 18:07:25 +0300 Message-Id: <83v9lixrde.fsf@gnu.org> From: Eli Zaretskii To: Dmitry Gutov In-Reply-To: <4305317a-73ee-8d4e-dada-1a45ecacc9d6@yandex.ru> (message from Dmitry Gutov on Wed, 29 Apr 2020 18:02:52 +0300) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> <349d9b1b-4659-907e-c6e1-30cdf052c87f@yandex.ru> <83368mz77f.fsf@gnu.org> <4305317a-73ee-8d4e-dada-1a45ecacc9d6@yandex.ru> X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 40693 Cc: contovob@tcd.ie, darthandrus@gmail.com, 40693@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 (---) > Cc: contovob@tcd.ie, darthandrus@gmail.com, 40693@debbugs.gnu.org > From: Dmitry Gutov > Date: Wed, 29 Apr 2020 18:02:52 +0300 > > > Sounds like a somewhat hairy issue. Then let's put this on master > > first. If this turns out to be a very popular change, and no one > > complains, we could later back-port it to some 27.x version. > > *shrug*, I'm certainly not going to insist, but we could push the > "slightly slower" simple patch to emacs-27, and go with Basil's refactor > (sounds exciting!) on master. I'd rather not risk an extra pretest just because of an issue that has been with us for a long time. Emacs 27 is already way too late. From debbugs-submit-bounces@debbugs.gnu.org Sun May 17 21:25:16 2020 Received: (at 40693) by debbugs.gnu.org; 18 May 2020 01:25:16 +0000 Received: from localhost ([127.0.0.1]:45208 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jaUWl-0004L6-17 for submit@debbugs.gnu.org; Sun, 17 May 2020 21:25:15 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:34387) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jaUWg-0004KN-A2 for 40693@debbugs.gnu.org; Sun, 17 May 2020 21:25:09 -0400 Received: by mail-wr1-f67.google.com with SMTP id y3so9900637wrt.1 for <40693@debbugs.gnu.org>; Sun, 17 May 2020 18:25:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tcd-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=rXIT5kr1LD8B+dOfZkyhpWHYxMMHhrcZr8TVt73MeEM=; b=HNd1IQq7ZGzGTrOYekQKZPKe9eu71jG9PHV9739gHkt71pOBlEuqqxzaWBLIWr01oR QZuIAcoHvXvFSQYoFmnPQTd1Cv+eAibFKFNwEpm8Rt13F6ChT11+YEXjWp+WQtvZng5N LNBrK2bkfLCit/RlasKjUMPTniKe9VvCYxNH9h0sCv9ZPy73OUvPKt4iBDmcvSG3T12t RHeL/MIe3F581gBMKreL/9vdfUaZ+g1bCZcqyZIQ9k9AA25yy0FBRii4FA74s6OTfImC MBIvWCy9MSXs7E+4Noz0uJW8gAHYeVDrkPzgPLwn8ogcEPe4JOW82UK/0oG+YdlF38FR Z4cQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=rXIT5kr1LD8B+dOfZkyhpWHYxMMHhrcZr8TVt73MeEM=; b=IxUAHX+5rpRPWa0hFesyjsJvVIdupA79K4adTLMgFB88uv7qp0SGG7F+ZAWaNpDocq hUojUWABtlTph8KSGCH5UOg7xMvFIlWgXC6JR2nOObzQnxRHndwb+UTTZI336o+S9cpG OGHErKPCn+DKJDTbBUK6cWyUc1pn2Zq+5gJyZc8akNZW3N/HIjA3WfJFltzIrTBpuXl1 I80RPAYaYnnR9X8vLlA9aVfAVTpD8g3CtAl3+nnz9GqoEXlWXe3KmB9KJC7V8mjQTvjd 4XzmIYhKZOFVIVYlxYUVCfXRBQBiQmhScw0bXzZ8S2T7wrKN+ikmgWwTePELifoq/6wn uXRQ== X-Gm-Message-State: AOAM533Dm1t++6reChlRIysTX4Gy9ePamc+XFVpxAnTi17hHLgmIvOzk Z8tGjyy9jjbDByb/zZbubIwo1w== X-Google-Smtp-Source: ABdhPJx9zbvs80QsUS2bmpzkfgJXX1y5cp2KQrYkgv2FrVP+SCOWzcYaUihSgia13x8XNWMxJmVPTQ== X-Received: by 2002:adf:8023:: with SMTP id 32mr17697780wrk.247.1589765100416; Sun, 17 May 2020 18:25:00 -0700 (PDT) Received: from localhost ([2a02:8084:20e2:c380:1f68:7ff5:120d:64e]) by smtp.gmail.com with ESMTPSA id 10sm14349180wmw.26.2020.05.17.18.24.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 17 May 2020 18:24:58 -0700 (PDT) From: "Basil L. Contovounesios" To: Eli Zaretskii Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> <87wo5yqrqo.fsf@tcd.ie> Date: Mon, 18 May 2020 02:24:57 +0100 In-Reply-To: <87wo5yqrqo.fsf@tcd.ie> (Basil L. Contovounesios's message of "Wed, 29 Apr 2020 15:41:19 +0100") Message-ID: <87ftbyavbq.fsf@tcd.ie> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 40693 Cc: darthandrus@gmail.com, 40693@debbugs.gnu.org, =?utf-8?B?Sm/Do28gVMOhdm9yYQ==?= , Dmitry Gutov 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: -1.0 (-) --=-=-= Content-Type: text/plain tags 40693 + patch quit --=-=-= Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename=0001-Various-json.el-improvements.patch Content-Transfer-Encoding: quoted-printable >From 74215f7c5eeb414273afa9dc2c3f51a47c7b6e75 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" Date: Sat, 16 May 2020 13:23:48 +0100 Subject: [PATCH] Various json.el improvements * etc/NEWS: Announce that json-read-number is now stricter. * json.el: Bump package version. (json-encoding-lisp-style-closings, json-pre-element-read-function) (json-post-element-read-function, json-advance, json-peek) (json--path): Clarify and improve style of doc strings. (json-join): Define as an obsolete alias of string-join. (json-alist-p, json-plist-p): Refactor for speed and declare as pure, side-effect-free, and error-free. (json--plist-reverse): Rename function... (json--plist-nreverse): ...to this, making it destructive for speed. All callers changed. (json--plist-to-alist): Remove, replacing single use with map-pairs. (json--with-indentation): Accept multiple forms as arguments, fix their indentation, and allow them to be instrumented for debugging. Add docstring. (json-pop, json-read-keyword, json-add-to-object) (json-encode-array): Simplify for speed. (json-skip-whitespace): Put newline before carriage return for likely frequency of occurrence, and so that the characters appear in increasing order. (json--check-position): Use 1+. (json-path-to-position): Open code apply-partially. (json-keywords): Turn into a defconst and mark as obsolete now that it is no longer used. (json--post-value, json--number, json--escape): New rx definitions. (json-encode-keyword): Declare as side-effect-free. (json-read-number): Reject leading zeros and plus signs, and make integer part mandatory in accordance with JSON standards and for consistency with native JSON parsing functions. Eagerly signal json-number-format when garbage follows a valid number, e.g., when reading "1.1.1", instead of leaving that up to the caller. Remove optional internal argument from advertised calling convention now that the function is no longer recursive. (json-encode-number): Define as an alias of number-to-string. (json-special-chars): Turn into a defconst. (json-read-escaped-char, json-new-object, json-read-file) (json-pretty-print): Simplify. (json-read-string): For consistency with other json.el error reporting, remove check for leading '"', and use the integer value rather than the printed representation of characters in error data. At EOB signal json-end-of-file instead of json-string-format. (json--long-string-threshold, json--string-buffer): New variables. (json-encode-string): Reimplement in terms of buffer manipulation for speed (bug#20154). (json-read-object): Escape ?\} properly. (json--encode-alist): New function extracted from json-encode-alist. (json-encode-hash-table, json-encode-alist, json-encode-plist): Use it to avoid destructively modifying the argument when json-encoding-object-sort-predicate is non-nil without incurring unnecessary copying (bug#40693). Encode empty object as "{}" even when pretty-printing. Simplify for speed. (json-read-array): Avoid recomputing list length on each iteration when json-pre-element-read-function is non-nil. Make first element of json-array-format error data a string for consistency with json-object-format and to make the displayed error message clearer. (json-readtable-dispatch): Accept any kind of argument, not just symbols. Generate the table in a simpler manner so the dispatch order is clearer. Remove dispatch on ?+ and ?. now that json-read-number is stricter and for consistency with native JSON parsing functions. Signal json-end-of-file if argument is nil. (json-read): Simplify accordingly. (json-encode): Avoid allocating a list on each invocation. * lisp/jsonrpc.el (jsonrpc--json-read, jsonrpc--json-encode): Check whether native JSON functions are fboundp only once, at load time. * lisp/progmodes/python.el (python--parse-json-array): New function. (python-shell-prompt-detect): Use it to parse JSON directly as a list rather than converting from a vector. * test/lisp/json-tests.el (json-tests--with-temp-buffer): Allow instrumenting for debugging. (test-json-join, test-json-plist-to-alist): Remove tests. (test-json-alist-p, test-json-plist-p, test-json-advance) (test-json-peek, test-json-pop, test-json-skip-whitespace) (test-json-read-keyword, test-json-encode-keyword) (test-json-encode-number, test-json-read-escaped-char) (test-json-read-string, test-json-encode-string) (test-json-encode-key, test-json-new-object) (test-json-encode-hash-table, test-json-encode-plist) (test-json-encode-list, test-json-read-array) (test-json-encode-array, test-json-read) (test-json-read-from-string, test-json-encode): Extend tests. (test-json-plist-reverse): Rename test... (test-json-plist-nreverse): ...to this and avoid modifying literal lists. (test-json-read-number): Rename test... (test-json-read-integer): ...to this, focusing on integers. (test-json-add-to-object): Rename test... (test-json-add-to-alist): ...to this, focusing on alists. (json-encode-simple-alist): Rename test... (test-json-encode-alist): ...to this, extending it. (test-json-encode-alist-with-sort-predicate): Rename test... (test-json-encode-alist-sort): ...to this, extending it. (test-json-encode-plist-with-sort-predicate): Rename test... (test-json-encode-plist-sort): ...to this, extending it. (test-json-read-keyword-invalid, test-json-read-fraction) (test-json-read-exponent, test-json-read-fraction-exponent) (test-json-read-number-invalid) (test-json-read-escaped-char-invalid, test-json-add-to-plist) (test-json-add-to-hash-table, test-json-read-object-empty) (test-json-read-object-invalid, test-json-read-object-function) (test-json-encode-hash-table-pretty) (test-json-encode-hash-table-lisp-style) (test-json-encode-hash-table-sort, test-json-encode-alist-pretty) (test-json-encode-alist-lisp-style, test-json-encode-plist-pretty) (test-json-encode-plist-lisp-style, test-json-read-array-function) (test-json-encode-array-pretty, test-json-encode-array-lisp-style) (test-json-read-invalid): New tests. (test-json-path-to-position-no-match): Use should-not. (test-json-read-object): Move error check to new test test-json-read-object-invalid. (test-json-pretty-print-object): Adapt test now that empty objects are pretty-printed as "{}". --- etc/NEWS | 9 + lisp/json.el | 569 +++++++++++++------------- lisp/jsonrpc.el | 48 ++- lisp/progmodes/python.el | 21 +- test/lisp/json-tests.el | 857 ++++++++++++++++++++++++++++++++------- 5 files changed, 1054 insertions(+), 450 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 303036ece3..e35ddddf9b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -353,6 +353,15 @@ symbol property to the browsing functions. With a new= command 'browse-url-with-browser-kind', an URL can explicitly be browsed with either an internal or external browser. =20 +** json.el + +--- +*** JSON number parsing is now stricter. +Numbers with a leading plus sign, leading zeros, or a missing integer +component are now rejected by 'json-read' and friends. This makes +them more compliant with the JSON specification and consistent with +the native JSON parsing functions. + * New Modes and Packages in Emacs 28.1 =20 diff --git a/lisp/json.el b/lisp/json.el index 6f3b791ed1..93874a2cb8 100644 --- a/lisp/json.el +++ b/lisp/json.el @@ -3,7 +3,7 @@ ;; Copyright (C) 2006-2020 Free Software Foundation, Inc. =20 ;; Author: Theresa O'Connor -;; Version: 1.4 +;; Version: 1.5 ;; Keywords: convenience =20 ;; This file is part of GNU Emacs. @@ -29,11 +29,11 @@ ;; Learn all about JSON here: . =20 ;; The user-serviceable entry points for the parser are the functions -;; `json-read' and `json-read-from-string'. The encoder has a single +;; `json-read' and `json-read-from-string'. The encoder has a single ;; entry point, `json-encode'. =20 ;; Since there are several natural representations of key-value pair -;; mappings in elisp (alist, plist, hash-table), `json-read' allows you +;; mappings in Elisp (alist, plist, hash-table), `json-read' allows you ;; to specify which you'd prefer (see `json-object-type' and ;; `json-array-type'). =20 @@ -113,8 +113,10 @@ json-encoding-pretty-print "If non-nil, then the output of `json-encode' will be pretty-printed.") =20 (defvar json-encoding-lisp-style-closings nil - "If non-nil, ] and } closings will be formatted lisp-style, -without indentation.") + "If non-nil, delimiters ] and } will be formatted Lisp-style. +This means they will be placed on the same line as the last +element of the respective array or object, without indentation. +Used only when `json-encoding-pretty-print' is non-nil.") =20 (defvar json-encoding-object-sort-predicate nil "Sorting predicate for JSON object keys during encoding. @@ -124,88 +126,81 @@ json-encoding-object-sort-predicate ordered alphabetically.") =20 (defvar json-pre-element-read-function nil - "Function called (if non-nil) by `json-read-array' and -`json-read-object' right before reading a JSON array or object, -respectively. The function is called with one argument, which is -the current JSON key.") + "If non-nil, a function to call before reading a JSON array or object. +It is called by `json-read-array' and `json-read-object', +respectively, with one argument, which is the current JSON key.") =20 (defvar json-post-element-read-function nil - "Function called (if non-nil) by `json-read-array' and -`json-read-object' right after reading a JSON array or object, -respectively.") + "If non-nil, a function to call after reading a JSON array or object. +It is called by `json-read-array' and `json-read-object', +respectively, with no arguments.") =20 =20 ;;; Utilities =20 -(defun json-join (strings separator) - "Join STRINGS with SEPARATOR." - (mapconcat 'identity strings separator)) +(define-obsolete-function-alias 'json-join #'string-join "28.1") =20 (defun json-alist-p (list) - "Non-null if and only if LIST is an alist with simple keys." - (while (consp list) - (setq list (if (and (consp (car list)) - (atom (caar list))) - (cdr list) - 'not-alist))) + "Non-nil if and only if LIST is an alist with simple keys." + (declare (pure t) (side-effect-free error-free)) + (while (and (consp (car-safe list)) + (atom (caar list)) + (setq list (cdr list)))) (null list)) =20 (defun json-plist-p (list) - "Non-null if and only if LIST is a plist with keyword keys." - (while (consp list) - (setq list (if (and (keywordp (car list)) - (consp (cdr list))) - (cddr list) - 'not-plist))) + "Non-nil if and only if LIST is a plist with keyword keys." + (declare (pure t) (side-effect-free error-free)) + (while (and (keywordp (car-safe list)) + (consp (cdr list)) + (setq list (cddr list)))) (null list)) =20 -(defun json--plist-reverse (plist) - "Return a copy of PLIST in reverse order. -Unlike `reverse', this keeps the property-value pairs intact." - (let (res) - (while plist - (let ((prop (pop plist)) - (val (pop plist))) - (push val res) - (push prop res))) - res)) +(defun json--plist-nreverse (plist) + "Return PLIST in reverse order. +Unlike `nreverse', this keeps the ordering of each property +relative to its value intact. Like `nreverse', this function may +destructively modify PLIST to produce the result." + (let (prev (next (cddr plist))) + (while next + (setcdr (cdr plist) prev) + (setq prev plist plist next next (cddr next)) + (setcdr (cdr plist) prev))) + plist) =20 -(defun json--plist-to-alist (plist) - "Return an alist of the property-value pairs in PLIST." - (let (res) - (while plist - (let ((prop (pop plist)) - (val (pop plist))) - (push (cons prop val) res))) - (nreverse res))) - -(defmacro json--with-indentation (body) +(defmacro json--with-indentation (&rest body) + "Evaluate BODY with the correct indentation for JSON encoding. +This macro binds `json--encoding-current-indentation' according +to `json-encoding-pretty-print' around BODY." + (declare (debug t) (indent 0)) `(let ((json--encoding-current-indentation (if json-encoding-pretty-print (concat json--encoding-current-indentation json-encoding-default-indentation) ""))) - ,body)) + ,@body)) =20 ;; Reader utilities =20 (define-inline json-advance (&optional n) - "Advance N characters forward." + "Advance N characters forward, or 1 character if N is nil. +On reaching the end of the accessible region of the buffer, stop +and signal an error." (inline-quote (forward-char ,n))) =20 (define-inline json-peek () - "Return the character at point." + "Return the character at point. +At the end of the accessible region of the buffer, return 0." (inline-quote (following-char))) =20 (define-inline json-pop () - "Advance past the character at point, returning it." + "Advance past the character at point, returning it. +Signal `json-end-of-file' if called at the end of the buffer." (inline-quote - (let ((char (json-peek))) - (if (zerop char) - (signal 'json-end-of-file nil) - (json-advance) - char)))) + (prog1 (or (char-after) + (signal 'json-end-of-file ())) + (json-advance)))) =20 (define-inline json-skip-whitespace () "Skip past the whitespace at point." @@ -213,7 +208,7 @@ json-skip-whitespace ;; https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-40= 4.pdf ;; or https://tools.ietf.org/html/rfc7159#section-2 for the ;; definition of whitespace in JSON. - (inline-quote (skip-chars-forward "\t\r\n "))) + (inline-quote (skip-chars-forward "\t\n\r "))) =20 =20 @@ -236,8 +231,8 @@ 'json-end-of-file ;;; Paths =20 (defvar json--path '() - "Used internally by `json-path-to-position' to keep track of -the path during recursive calls to `json-read'.") + "Keeps track of the path during recursive calls to `json-read'. +Used internally by `json-path-to-position'.") =20 (defun json--record-path (key) "Record the KEY to the current JSON path. @@ -248,7 +243,7 @@ json--check-position "Check if the last parsed JSON structure passed POSITION. Used internally by `json-path-to-position'." (let ((start (caar json--path))) - (when (< start position (+ (point) 1)) + (when (< start position (1+ (point))) (throw :json-path (list :path (nreverse (mapcar #'cdr json--path)) :match-start start :match-end (point))))) @@ -266,13 +261,13 @@ json-path-to-position :path -- A list of strings and numbers forming the path to the JSON element at the given position. Strings denote object names, while numbers denote array - indexes. + indices. =20 :match-start -- Position where the matched JSON element begins. =20 :match-end -- Position where the matched JSON element ends. =20 -This can for instance be useful to determine the path to a JSON +This can, for instance, be useful to determine the path to a JSON element in a deeply nested structure." (save-excursion (unless string @@ -280,7 +275,7 @@ json-path-to-position (let* ((json--path '()) (json-pre-element-read-function #'json--record-path) (json-post-element-read-function - (apply-partially #'json--check-position position)) + (lambda () (json--check-position position))) (path (catch :json-path (if string (json-read-from-string string) @@ -290,38 +285,33 @@ json-path-to-position =20 ;;; Keywords =20 -(defvar json-keywords '("true" "false" "null") +(defconst json-keywords '("true" "false" "null") "List of JSON keywords.") +(make-obsolete-variable 'json-keywords "it is no longer used." "28.1") =20 ;; Keyword parsing =20 +;; Characters that can follow a JSON value. +(rx-define json--post-value (| (in "\t\n\r ,]}") eos)) + (defun json-read-keyword (keyword) - "Read a JSON keyword at point. -KEYWORD is the keyword expected." - (unless (member keyword json-keywords) - (signal 'json-unknown-keyword (list keyword))) - (mapc (lambda (char) - (when (/=3D char (json-peek)) - (signal 'json-unknown-keyword - (list (save-excursion - (backward-word-strictly 1) - (thing-at-point 'word))))) - (json-advance)) - keyword) - (json-skip-whitespace) - (unless (looking-at "\\([],}]\\|$\\)") - (signal 'json-unknown-keyword - (list (save-excursion - (backward-word-strictly 1) - (thing-at-point 'word))))) - (cond ((string-equal keyword "true") t) - ((string-equal keyword "false") json-false) - ((string-equal keyword "null") json-null))) + "Read the expected JSON KEYWORD at point." + (prog1 (cond ((equal keyword "true") t) + ((equal keyword "false") json-false) + ((equal keyword "null") json-null) + (t (signal 'json-unknown-keyword (list keyword)))) + (or (looking-at-p keyword) + (signal 'json-unknown-keyword (list (thing-at-point 'word)))) + (json-advance (length keyword)) + (or (looking-at-p (rx json--post-value)) + (signal 'json-unknown-keyword (list (thing-at-point 'word)))) + (json-skip-whitespace))) =20 ;; Keyword encoding =20 (defun json-encode-keyword (keyword) "Encode KEYWORD as a JSON value." + (declare (side-effect-free t)) (cond ((eq keyword t) "true") ((eq keyword json-false) "false") ((eq keyword json-null) "null"))) @@ -330,37 +320,31 @@ json-encode-keyword =20 ;; Number parsing =20 -(defun json-read-number (&optional sign) - "Read the JSON number following point. -The optional SIGN argument is for internal use. +(rx-define json--number + (: (? ?-) ; Sign. + (| (: (in "1-9") (* digit)) ?0) ; Integer. + (? ?. (+ digit)) ; Fraction. + (? (in "Ee") (? (in ?+ ?-)) (+ digit)))) ; Exponent. =20 -N.B.: Only numbers which can fit in Emacs Lisp's native number -representation will be parsed correctly." - ;; If SIGN is non-nil, the number is explicitly signed. - (let ((number-regexp - "\\([0-9]+\\)?\\(\\.[0-9]+\\)?\\([Ee][+-]?[0-9]+\\)?")) - (cond ((and (null sign) (=3D (json-peek) ?-)) - (json-advance) - (- (json-read-number t))) - ((and (null sign) (=3D (json-peek) ?+)) - (json-advance) - (json-read-number t)) - ((and (looking-at number-regexp) - (or (match-beginning 1) - (match-beginning 2))) - (goto-char (match-end 0)) - (string-to-number (match-string 0))) - (t (signal 'json-number-format (list (point))))))) +(defun json-read-number (&optional _sign) + "Read the JSON number following point." + (declare (advertised-calling-convention () "28.1")) + (or (looking-at (rx json--number)) + (signal 'json-number-format (list (point)))) + (goto-char (match-end 0)) + (prog1 (string-to-number (match-string 0)) + (or (looking-at-p (rx json--post-value)) + (signal 'json-number-format (list (point)))) + (json-skip-whitespace))) =20 ;; Number encoding =20 -(defun json-encode-number (number) - "Return a JSON representation of NUMBER." - (format "%s" number)) +(defalias 'json-encode-number #'number-to-string + "Return a JSON representation of NUMBER.") =20 ;;; Strings =20 -(defvar json-special-chars +(defconst json-special-chars '((?\" . ?\") (?\\ . ?\\) (?b . ?\b) @@ -368,7 +352,7 @@ json-special-chars (?n . ?\n) (?r . ?\r) (?t . ?\t)) - "Characters which are escaped in JSON, with their elisp counterparts.") + "Characters which are escaped in JSON, with their Elisp counterparts.") =20 ;; String parsing =20 @@ -378,48 +362,47 @@ json--decode-utf-16-surrogates =20 (defun json-read-escaped-char () "Read the JSON string escaped character at point." - ;; Skip over the '\' + ;; Skip over the '\'. (json-advance) - (let* ((char (json-pop)) - (special (assq char json-special-chars))) + (let ((char (json-pop))) (cond - (special (cdr special)) - ((not (eq char ?u)) char) + ((cdr (assq char json-special-chars))) + ((/=3D char ?u) char) ;; Special-case UTF-16 surrogate pairs, ;; cf. . Note that ;; this clause overlaps with the next one and therefore has to ;; come first. ((looking-at - (rx (group (any "Dd") (any "89ABab") (=3D 2 (any xdigit))) - "\\u" (group (any "Dd") (any "C-Fc-f") (=3D 2 (any xdigit))))) + (rx (group (any "Dd") (any "89ABab") (=3D 2 xdigit)) + "\\u" (group (any "Dd") (any "C-Fc-f") (=3D 2 xdigit)))) (json-advance 10) (json--decode-utf-16-surrogates (string-to-number (match-string 1) 16) (string-to-number (match-string 2) 16))) ((looking-at (rx (=3D 4 xdigit))) - (let ((hex (match-string 0))) - (json-advance 4) - (string-to-number hex 16))) + (json-advance 4) + (string-to-number (match-string 0) 16)) (t (signal 'json-string-escape (list (point))))))) =20 (defun json-read-string () "Read the JSON string at point." - (unless (=3D (json-peek) ?\") - (signal 'json-string-format (list "doesn't start with `\"'!"))) - ;; Skip over the '"' + ;; Skip over the '"'. (json-advance) (let ((characters '()) (char (json-peek))) - (while (not (=3D char ?\")) + (while (/=3D char ?\") (when (< char 32) - (signal 'json-string-format (list (prin1-char char)))) + (if (zerop char) + (signal 'json-end-of-file ()) + (signal 'json-string-format (list char)))) (push (if (=3D char ?\\) (json-read-escaped-char) - (json-pop)) + (json-advance) + char) characters) (setq char (json-peek))) - ;; Skip over the '"' + ;; Skip over the '"'. (json-advance) (if characters (concat (nreverse characters)) @@ -427,29 +410,47 @@ json-read-string =20 ;; String encoding =20 +;; Escape only quotation mark, backslash, and the control +;; characters U+0000 to U+001F (RFC 4627, ECMA-404). +(rx-define json--escape (in ?\" ?\\ cntrl)) + +(defvar json--long-string-threshold 200 + "Length above which strings are considered long for JSON encoding. +It is generally faster to manipulate such strings in a buffer +rather than directly.") + +(defvar json--string-buffer nil + "Buffer used for encoding Lisp strings as JSON. +Initialized lazily by `json-encode-string'.") + (defun json-encode-string (string) "Return a JSON representation of STRING." - ;; Reimplement the meat of `replace-regexp-in-string', for - ;; performance (bug#20154). - (let ((l (length string)) - (start 0) - res mb) - ;; Only escape quotation mark, backslash and the control - ;; characters U+0000 to U+001F (RFC 4627, ECMA-404). - (while (setq mb (string-match "[\"\\[:cntrl:]]" string start)) - (let* ((c (aref string mb)) - (special (rassq c json-special-chars))) - (push (substring string start mb) res) - (push (if special - ;; Special JSON character (\n, \r, etc.). - (string ?\\ (car special)) - ;; Fallback: UCS code point in \uNNNN form. - (format "\\u%04x" c)) - res) - (setq start (1+ mb)))) - (push (substring string start l) res) - (push "\"" res) - (apply #'concat "\"" (nreverse res)))) + ;; Try to avoid buffer overhead in trivial cases, while also + ;; avoiding searching pathological strings for escape characters. + ;; Since `string-match-p' doesn't take a LIMIT argument, we use + ;; string length as our heuristic. See also bug#20154. + (if (and (< (length string) json--long-string-threshold) + (not (string-match-p (rx json--escape) string))) + (concat "\"" string "\"") + (with-current-buffer + (or json--string-buffer + (with-current-buffer (generate-new-buffer " *json-string*") + ;; This seems to afford decent performance gains. + (setq-local inhibit-modification-hooks t) + (setq json--string-buffer (current-buffer)))) + (insert ?\" string) + (goto-char (1+ (point-min))) + (while (re-search-forward (rx json--escape) nil 'move) + (let ((char (preceding-char))) + (delete-char -1) + (insert ?\\ (or + ;; Special JSON character (\n, \r, etc.). + (car (rassq char json-special-chars)) + ;; Fallback: UCS code point in \uNNNN form. + (format "u%04x" char))))) + (insert ?\") + ;; Empty buffer for next invocation. + (delete-and-extract-region (point-min) (point-max))))) =20 (defun json-encode-key (object) "Return a JSON representation of OBJECT. @@ -460,15 +461,13 @@ json-encode-key (signal 'json-key-format (list object))) encoded)) =20 -;;; JSON Objects +;;; Objects =20 (defun json-new-object () - "Create a new Elisp object corresponding to a JSON object. + "Create a new Elisp object corresponding to an empty JSON object. Please see the documentation of `json-object-type'." - (cond ((eq json-object-type 'hash-table) - (make-hash-table :test 'equal)) - (t - ()))) + (and (eq json-object-type 'hash-table) + (make-hash-table :test #'equal))) =20 (defun json-add-to-object (object key value) "Add a new KEY -> VALUE association to OBJECT. @@ -476,10 +475,10 @@ json-add-to-object (setq obj (json-add-to-object obj \"foo\" \"bar\")) Please see the documentation of `json-object-type' and `json-key-type'." (let ((json-key-type - (or json-key-type - (cdr (assq json-object-type '((hash-table . string) - (alist . symbol) - (plist . keyword))))))) + (cond (json-key-type) + ((eq json-object-type 'hash-table) 'string) + ((eq json-object-type 'alist) 'symbol) + ((eq json-object-type 'plist) 'keyword)))) (setq key (cond ((eq json-key-type 'string) key) @@ -499,13 +498,13 @@ json-add-to-object =20 (defun json-read-object () "Read the JSON object at point." - ;; Skip over the "{" + ;; Skip over the '{'. (json-advance) (json-skip-whitespace) - ;; read key/value pairs until "}" + ;; Read key/value pairs until '}'. (let ((elements (json-new-object)) key value) - (while (not (=3D (json-peek) ?})) + (while (/=3D (json-peek) ?\}) (json-skip-whitespace) (setq key (json-read-string)) (json-skip-whitespace) @@ -520,94 +519,94 @@ json-read-object (funcall json-post-element-read-function)) (setq elements (json-add-to-object elements key value)) (json-skip-whitespace) - (when (/=3D (json-peek) ?}) + (when (/=3D (json-peek) ?\}) (if (=3D (json-peek) ?,) (json-advance) (signal 'json-object-format (list "," (json-peek)))))) - ;; Skip over the "}" + ;; Skip over the '}'. (json-advance) (pcase json-object-type ('alist (nreverse elements)) - ('plist (json--plist-reverse elements)) + ('plist (json--plist-nreverse elements)) (_ elements)))) =20 ;; Hash table encoding =20 (defun json-encode-hash-table (hash-table) "Return a JSON representation of HASH-TABLE." - (if json-encoding-object-sort-predicate - (json-encode-alist (map-into hash-table 'list)) - (format "{%s%s}" - (json-join - (let (r) - (json--with-indentation - (maphash - (lambda (k v) - (push (format - (if json-encoding-pretty-print - "%s%s: %s" - "%s%s:%s") - json--encoding-current-indentation - (json-encode-key k) - (json-encode v)) - r)) - hash-table)) - r) - json-encoding-separator) - (if (or (not json-encoding-pretty-print) - json-encoding-lisp-style-closings) - "" - json--encoding-current-indentation)))) + (cond ((hash-table-empty-p hash-table) "{}") + (json-encoding-object-sort-predicate + (json--encode-alist (map-pairs hash-table) t)) + (t + (let ((kv-sep (if json-encoding-pretty-print ": " ":")) + result) + (json--with-indentation + (maphash + (lambda (k v) + (push (concat json--encoding-current-indentation + (json-encode-key k) + kv-sep + (json-encode v)) + result)) + hash-table)) + (concat "{" + (string-join (nreverse result) json-encoding-separator) + (and json-encoding-pretty-print + (not json-encoding-lisp-style-closings) + json--encoding-current-indentation) + "}"))))) =20 ;; List encoding (including alists and plists) =20 -(defun json-encode-alist (alist) - "Return a JSON representation of ALIST." +(defun json--encode-alist (alist &optional destructive) + "Return a JSON representation of ALIST. +DESTRUCTIVE non-nil means it is safe to modify ALIST by +side-effects." (when json-encoding-object-sort-predicate - (setq alist - (sort alist (lambda (a b) + (setq alist (sort (if destructive alist (copy-sequence alist)) + (lambda (a b) (funcall json-encoding-object-sort-predicate (car a) (car b)))))) - (format "{%s%s}" - (json-join - (json--with-indentation - (mapcar (lambda (cons) - (format (if json-encoding-pretty-print - "%s%s: %s" - "%s%s:%s") - json--encoding-current-indentation - (json-encode-key (car cons)) - (json-encode (cdr cons)))) - alist)) - json-encoding-separator) - (if (or (not json-encoding-pretty-print) - json-encoding-lisp-style-closings) - "" - json--encoding-current-indentation))) + (concat "{" + (let ((kv-sep (if json-encoding-pretty-print ": " ":"))) + (json--with-indentation + (mapconcat (lambda (cons) + (concat json--encoding-current-indentation + (json-encode-key (car cons)) + kv-sep + (json-encode (cdr cons)))) + alist + json-encoding-separator))) + (and json-encoding-pretty-print + (not json-encoding-lisp-style-closings) + json--encoding-current-indentation) + "}")) + +(defun json-encode-alist (alist) + "Return a JSON representation of ALIST." + (if alist (json--encode-alist alist) "{}")) =20 (defun json-encode-plist (plist) "Return a JSON representation of PLIST." - (if json-encoding-object-sort-predicate - (json-encode-alist (json--plist-to-alist plist)) - (let (result) - (json--with-indentation - (while plist - (push (concat - json--encoding-current-indentation - (json-encode-key (car plist)) - (if json-encoding-pretty-print - ": " - ":") - (json-encode (cadr plist))) + (cond ((null plist) "{}") + (json-encoding-object-sort-predicate + (json--encode-alist (map-pairs plist) t)) + (t + (let ((kv-sep (if json-encoding-pretty-print ": " ":")) result) - (setq plist (cddr plist)))) - (concat "{" - (json-join (nreverse result) json-encoding-separator) - (if (and json-encoding-pretty-print - (not json-encoding-lisp-style-closings)) - json--encoding-current-indentation - "") - "}")))) + (json--with-indentation + (while plist + (push (concat json--encoding-current-indentation + (json-encode-key (pop plist)) + kv-sep + (json-encode (pop plist))) + result))) + (concat "{" + (string-join (nreverse result) json-encoding-separator) + (and json-encoding-pretty-print + (not json-encoding-lisp-style-closings) + json--encoding-current-indentation) + "}"))))) =20 (defun json-encode-list (list) "Return a JSON representation of LIST. @@ -625,15 +624,17 @@ json-encode-list =20 (defun json-read-array () "Read the JSON array at point." - ;; Skip over the "[" + ;; Skip over the '['. (json-advance) (json-skip-whitespace) - ;; read values until "]" - (let (elements) - (while (not (=3D (json-peek) ?\])) + ;; Read values until ']'. + (let (elements + (len 0)) + (while (/=3D (json-peek) ?\]) (json-skip-whitespace) (when json-pre-element-read-function - (funcall json-pre-element-read-function (length elements))) + (funcall json-pre-element-read-function len) + (setq len (1+ len))) (push (json-read) elements) (when json-post-element-read-function (funcall json-post-element-read-function)) @@ -641,8 +642,8 @@ json-read-array (when (/=3D (json-peek) ?\]) (if (=3D (json-peek) ?,) (json-advance) - (signal 'json-array-format (list ?, (json-peek)))))) - ;; Skip over the "]" + (signal 'json-array-format (list "," (json-peek)))))) + ;; Skip over the ']'. (json-advance) (pcase json-array-type ('vector (nreverse (vconcat elements))) @@ -653,42 +654,43 @@ json-read-array (defun json-encode-array (array) "Return a JSON representation of ARRAY." (if (and json-encoding-pretty-print - (> (length array) 0)) + (not (seq-empty-p array))) (concat + "[" (json--with-indentation - (concat (format "[%s" json--encoding-current-indentation) - (json-join (mapcar 'json-encode array) - (format "%s%s" - json-encoding-separator + (concat json--encoding-current-indentation + (mapconcat #'json-encode array + (concat json-encoding-separator json--encoding-current-indentation)))) - (format "%s]" - (if json-encoding-lisp-style-closings - "" - json--encoding-current-indentation))) + (unless json-encoding-lisp-style-closings + json--encoding-current-indentation) + "]") (concat "[" - (mapconcat 'json-encode array json-encoding-separator) + (mapconcat #'json-encode array json-encoding-separator) "]"))) =20 =20 -;;; JSON reader. +;;; Reader =20 (defmacro json-readtable-dispatch (char) - "Dispatch reader function for CHAR." - (declare (debug (symbolp))) - (let ((table - '((?t json-read-keyword "true") - (?f json-read-keyword "false") - (?n json-read-keyword "null") - (?{ json-read-object) - (?\[ json-read-array) - (?\" json-read-string))) - res) - (dolist (c '(?- ?+ ?. ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)) - (push (list c 'json-read-number) table)) - (pcase-dolist (`(,c . ,rest) table) - (push `((eq ,char ,c) (,@rest)) res)) - `(cond ,@res (t (signal 'json-readtable-error (list ,char)))))) + "Dispatch reader function for CHAR at point. +If CHAR is nil, signal `json-end-of-file'." + (declare (debug t)) + (macroexp-let2 nil char char + `(cond ,@(map-apply + (lambda (key expr) + `((eq ,char ,key) ,expr)) + `((?\" ,#'json-read-string) + (?\[ ,#'json-read-array) + (?\{ ,#'json-read-object) + (?n ,#'json-read-keyword "null") + (?f ,#'json-read-keyword "false") + (?t ,#'json-read-keyword "true") + ,@(mapcar (lambda (c) (list c #'json-read-number)) + '(?- ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)))) + (,char (signal 'json-readtable-error (list ,char))) + (t (signal 'json-end-of-file ()))))) =20 (defun json-read () "Parse and return the JSON object following point. @@ -706,10 +708,7 @@ json-read ((c . :json-false))]) (b . \"foo\"))" (json-skip-whitespace) - (let ((char (json-peek))) - (if (zerop char) - (signal 'json-end-of-file nil) - (json-readtable-dispatch char)))) + (json-readtable-dispatch (char-after))) =20 ;; Syntactic sugar for the reader =20 @@ -724,12 +723,11 @@ json-read-file "Read the first JSON object contained in FILE and return it." (with-temp-buffer (insert-file-contents file) - (goto-char (point-min)) (json-read))) =20 =20 -;;; JSON encoder +;;; Encoder =20 (defun json-encode (object) "Return a JSON representation of OBJECT as a string. @@ -737,20 +735,21 @@ json-encode OBJECT should have a structure like one returned by `json-read'. If an error is detected during encoding, an error based on `json-error' is signaled." - (cond ((memq object (list t json-null json-false)) - (json-encode-keyword object)) - ((stringp object) (json-encode-string object)) - ((keywordp object) (json-encode-string - (substring (symbol-name object) 1))) - ((listp object) (json-encode-list object)) - ((symbolp object) (json-encode-string - (symbol-name object))) - ((numberp object) (json-encode-number object)) - ((arrayp object) (json-encode-array object)) - ((hash-table-p object) (json-encode-hash-table object)) - (t (signal 'json-error (list object))))) + (cond ((eq object t) (json-encode-keyword object)) + ((eq object json-null) (json-encode-keyword object)) + ((eq object json-false) (json-encode-keyword object)) + ((stringp object) (json-encode-string object)) + ((keywordp object) (json-encode-string + (substring (symbol-name object) 1))) + ((listp object) (json-encode-list object)) + ((symbolp object) (json-encode-string + (symbol-name object))) + ((numberp object) (json-encode-number object)) + ((arrayp object) (json-encode-array object)) + ((hash-table-p object) (json-encode-hash-table object)) + (t (signal 'json-error (list object))))) =20 -;; Pretty printing & minimizing +;;; Pretty printing & minimizing =20 (defun json-pretty-print-buffer (&optional minimize) "Pretty-print current buffer. @@ -769,9 +768,9 @@ json-pretty-print With prefix argument MINIMIZE, minimize it instead." (interactive "r\nP") (let ((json-encoding-pretty-print (null minimize)) - ;; Distinguish an empty objects from 'null' + ;; Distinguish an empty object from 'null'. (json-null :json-null) - ;; Ensure that ordering is maintained + ;; Ensure that ordering is maintained. (json-object-type 'alist) (orig-buf (current-buffer)) error) @@ -800,9 +799,7 @@ json-pretty-print ;; them. (let ((space (buffer-substring (point) - (+ (point) - (skip-chars-forward - " \t\n" (point-max))))) + (+ (point) (skip-chars-forward " \t\n")))) (json (json-read))) (setq pos (point)) ; End of last good json-read. (set-buffer tmp-buf) @@ -832,14 +829,14 @@ json-pretty-print-buffer-ordered "Pretty-print current buffer with object keys ordered. With prefix argument MINIMIZE, minimize it instead." (interactive "P") - (let ((json-encoding-object-sort-predicate 'string<)) + (let ((json-encoding-object-sort-predicate #'string<)) (json-pretty-print-buffer minimize))) =20 (defun json-pretty-print-ordered (begin end &optional minimize) "Pretty-print the region with object keys ordered. With prefix argument MINIMIZE, minimize it instead." (interactive "r\nP") - (let ((json-encoding-object-sort-predicate 'string<)) + (let ((json-encoding-object-sort-predicate #'string<)) (json-pretty-print begin end minimize))) =20 (provide 'json) diff --git a/lisp/jsonrpc.el b/lisp/jsonrpc.el index 293dfaa748..42e7701af1 100644 --- a/lisp/jsonrpc.el +++ b/lisp/jsonrpc.el @@ -37,7 +37,6 @@ ;;; Code: =20 (require 'cl-lib) -(require 'json) (require 'eieio) (eval-when-compile (require 'subr-x)) (require 'warnings) @@ -470,26 +469,35 @@ jsonrpc-stderr-buffer ;;; (define-error 'jsonrpc-error "jsonrpc-error") =20 -(defun jsonrpc--json-read () - "Read JSON object in buffer, move point to end of buffer." - ;; TODO: I guess we can make these macros if/when jsonrpc.el - ;; goes into Emacs core. - (cond ((fboundp 'json-parse-buffer) (json-parse-buffer - :object-type 'plist - :null-object nil - :false-object :json-false)) - (t (let ((json-object-type 'plist)) - (json-read))))) +(defalias 'jsonrpc--json-read + (if (fboundp 'json-parse-buffer) + (lambda () + (json-parse-buffer :object-type 'plist + :null-object nil + :false-object :json-false)) + (require 'json) + (defvar json-object-type) + (declare-function json-read "json" ()) + (lambda () + (let ((json-object-type 'plist)) + (json-read)))) + "Read JSON object in buffer, move point to end of buffer.") =20 -(defun jsonrpc--json-encode (object) - "Encode OBJECT into a JSON string." - (cond ((fboundp 'json-serialize) (json-serialize - object - :false-object :json-false - :null-object nil)) - (t (let ((json-false :json-false) - (json-null nil)) - (json-encode object))))) +(defalias 'jsonrpc--json-encode + (if (fboundp 'json-serialize) + (lambda (object) + (json-serialize object + :false-object :json-false + :null-object nil)) + (require 'json) + (defvar json-false) + (defvar json-null) + (declare-function json-encode "json" (object)) + (lambda (object) + (let ((json-false :json-false) + (json-null nil)) + (json-encode object)))) + "Encode OBJECT into a JSON string.") =20 (cl-defun jsonrpc--reply (connection id &key (result nil result-supplied-p) (error nil error-su= pplied-p)) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 67383b3415..1ca9f01963 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -261,7 +261,6 @@ (require 'ansi-color) (require 'cl-lib) (require 'comint) -(require 'json) (require 'tramp-sh) =20 ;; Avoid compiler warnings @@ -2276,6 +2275,18 @@ python-shell--prompt-calculated-output-regexp Do not set this variable directly, instead use `python-shell-prompt-set-calculated-regexps'.") =20 +(defalias 'python--parse-json-array + (if (fboundp 'json-parse-string) + (lambda (string) + (json-parse-string string :array-type 'list)) + (require 'json) + (defvar json-array-type) + (declare-function json-read-from-string "json" (string)) + (lambda (string) + (let ((json-array-type 'list)) + (json-read-from-string string)))) + "Parse the JSON array in STRING into a Lisp list.") + (defun python-shell-prompt-detect () "Detect prompts for the current `python-shell-interpreter'. When prompts can be retrieved successfully from the @@ -2324,11 +2335,11 @@ python-shell-prompt-detect (catch 'prompts (dolist (line (split-string output "\n" t)) (let ((res - ;; Check if current line is a valid JSON array - (and (string=3D (substring line 0 2) "[\"") + ;; Check if current line is a valid JSON array. + (and (string-prefix-p "[\"" line) (ignore-errors - ;; Return prompts as a list, not vector - (append (json-read-from-string line) nil))= ))) + ;; Return prompts as a list. + (python--parse-json-array line))))) ;; The list must contain 3 strings, where the first ;; is the input prompt, the second is the block ;; prompt and the last one is the output prompt. The diff --git a/test/lisp/json-tests.el b/test/lisp/json-tests.el index ac9706a8ae..a0e8c87c7b 100644 --- a/test/lisp/json-tests.el +++ b/test/lisp/json-tests.el @@ -21,11 +21,16 @@ =20 (require 'ert) (require 'json) +(require 'map) +(require 'seq) + +(eval-when-compile + (require 'cl-lib)) =20 (defmacro json-tests--with-temp-buffer (content &rest body) "Create a temporary buffer with CONTENT and evaluate BODY there. Point is moved to beginning of the buffer." - (declare (indent 1)) + (declare (debug t) (indent 1)) `(with-temp-buffer (insert ,content) (goto-char (point-min)) @@ -33,66 +38,107 @@ json-tests--with-temp-buffer =20 ;;; Utilities =20 -(ert-deftest test-json-join () - (should (equal (json-join '() ", ") "")) - (should (equal (json-join '("a" "b" "c") ", ") "a, b, c"))) - (ert-deftest test-json-alist-p () (should (json-alist-p '())) - (should (json-alist-p '((a 1) (b 2) (c 3)))) - (should (json-alist-p '((:a 1) (:b 2) (:c 3)))) - (should (json-alist-p '(("a" 1) ("b" 2) ("c" 3)))) + (should (json-alist-p '((())))) + (should (json-alist-p '((a)))) + (should (json-alist-p '((a . 1)))) + (should (json-alist-p '((a . 1) (b 2) (c)))) + (should (json-alist-p '((:a) (:b 2) (:c . 3)))) + (should (json-alist-p '(("a" . 1) ("b" 2) ("c")))) + (should-not (json-alist-p '(()))) + (should-not (json-alist-p '(a))) + (should-not (json-alist-p '(a . 1))) + (should-not (json-alist-p '((a . 1) . []))) + (should-not (json-alist-p '((a . 1) []))) (should-not (json-alist-p '(:a :b :c))) (should-not (json-alist-p '(:a 1 :b 2 :c 3))) - (should-not (json-alist-p '((:a 1) (:b 2) 3)))) + (should-not (json-alist-p '((:a 1) (:b 2) 3))) + (should-not (json-alist-p '((:a 1) (:b 2) ()))) + (should-not (json-alist-p '(((a) 1) (b 2) (c 3)))) + (should-not (json-alist-p [])) + (should-not (json-alist-p [(a . 1)])) + (should-not (json-alist-p #s(hash-table)))) =20 (ert-deftest test-json-plist-p () (should (json-plist-p '())) + (should (json-plist-p '(:a 1))) (should (json-plist-p '(:a 1 :b 2 :c 3))) + (should (json-plist-p '(:a :b))) + (should (json-plist-p '(:a :b :c :d))) + (should-not (json-plist-p '(a))) + (should-not (json-plist-p '(a 1))) (should-not (json-plist-p '(a 1 b 2 c 3))) (should-not (json-plist-p '("a" 1 "b" 2 "c" 3))) + (should-not (json-plist-p '(:a))) (should-not (json-plist-p '(:a :b :c))) - (should-not (json-plist-p '((:a 1) (:b 2) (:c 3))))) + (should-not (json-plist-p '(:a 1 :b 2 :c))) + (should-not (json-plist-p '((:a 1)))) + (should-not (json-plist-p '((:a 1) (:b 2) (:c 3)))) + (should-not (json-plist-p [])) + (should-not (json-plist-p [:a 1])) + (should-not (json-plist-p #s(hash-table)))) =20 -(ert-deftest test-json-plist-reverse () - (should (equal (json--plist-reverse '()) '())) - (should (equal (json--plist-reverse '(:a 1)) '(:a 1))) - (should (equal (json--plist-reverse '(:a 1 :b 2 :c 3)) +(ert-deftest test-json-plist-nreverse () + (should (equal (json--plist-nreverse '()) '())) + (should (equal (json--plist-nreverse (list :a 1)) '(:a 1))) + (should (equal (json--plist-nreverse (list :a 1 :b 2)) '(:b 2 :a 1))) + (should (equal (json--plist-nreverse (list :a 1 :b 2 :c 3)) '(:c 3 :b 2 :a 1)))) =20 -(ert-deftest test-json-plist-to-alist () - (should (equal (json--plist-to-alist '()) '())) - (should (equal (json--plist-to-alist '(:a 1)) '((:a . 1)))) - (should (equal (json--plist-to-alist '(:a 1 :b 2 :c 3)) - '((:a . 1) (:b . 2) (:c . 3))))) - (ert-deftest test-json-advance () (json-tests--with-temp-buffer "{ \"a\": 1 }" (json-advance 0) - (should (=3D (point) (point-min))) + (should (bobp)) + (json-advance) + (should (=3D (point) (1+ (point-min)))) + (json-advance 0) + (should (=3D (point) (1+ (point-min)))) + (json-advance 1) + (should (=3D (point) (+ (point-min) 2))) (json-advance 3) - (should (=3D (point) (+ (point-min) 3))))) + (should (=3D (point) (+ (point-min) 5))))) =20 (ert-deftest test-json-peek () (json-tests--with-temp-buffer "" (should (zerop (json-peek)))) (json-tests--with-temp-buffer "{ \"a\": 1 }" - (should (equal (json-peek) ?{)))) + (should (=3D (json-peek) ?\{)) + (goto-char (1- (point-max))) + (should (=3D (json-peek) ?\})) + (json-advance) + (should (zerop (json-peek))))) =20 (ert-deftest test-json-pop () (json-tests--with-temp-buffer "" (should-error (json-pop) :type 'json-end-of-file)) (json-tests--with-temp-buffer "{ \"a\": 1 }" - (should (equal (json-pop) ?{)) - (should (=3D (point) (+ (point-min) 1))))) + (should (=3D (json-pop) ?\{)) + (should (=3D (point) (1+ (point-min)))) + (goto-char (1- (point-max))) + (should (=3D (json-pop) ?\})) + (should-error (json-pop) :type 'json-end-of-file))) =20 (ert-deftest test-json-skip-whitespace () + (json-tests--with-temp-buffer "" + (json-skip-whitespace) + (should (bobp)) + (should (eobp))) + (json-tests--with-temp-buffer "{}" + (json-skip-whitespace) + (should (bobp)) + (json-advance) + (json-skip-whitespace) + (should (=3D (point) (1+ (point-min)))) + (json-advance) + (json-skip-whitespace) + (should (eobp))) (json-tests--with-temp-buffer "\t\r\n\f\b { \"a\": 1 }" (json-skip-whitespace) - (should (equal (char-after) ?\f))) + (should (=3D (json-peek) ?\f))) (json-tests--with-temp-buffer "\t\r\n\t { \"a\": 1 }" (json-skip-whitespace) - (should (equal (char-after) ?{)))) + (should (=3D (json-peek) ?\{)))) =20 ;;; Paths =20 @@ -113,59 +159,243 @@ test-json-path-to-position-with-arrays (ert-deftest test-json-path-to-position-no-match () (let* ((json-string "{\"foo\": {\"bar\": \"baz\"}}") (matched-path (json-path-to-position 5 json-string))) - (should (null matched-path)))) + (should-not matched-path))) =20 ;;; Keywords =20 (ert-deftest test-json-read-keyword () (json-tests--with-temp-buffer "true" - (should (json-read-keyword "true"))) + (should (eq (json-read-keyword "true") t)) + (should (eobp))) + (json-tests--with-temp-buffer "true " + (should (eq (json-read-keyword "true") t)) + (should (eobp))) + (json-tests--with-temp-buffer "true}" + (should (eq (json-read-keyword "true") t)) + (should (=3D (point) (+ (point-min) 4)))) + (json-tests--with-temp-buffer "true false" + (should (eq (json-read-keyword "true") t)) + (should (=3D (point) (+ (point-min) 5)))) + (json-tests--with-temp-buffer "true }" + (should (eq (json-read-keyword "true") t)) + (should (=3D (point) (+ (point-min) 5)))) + (json-tests--with-temp-buffer "true |" + (should (eq (json-read-keyword "true") t)) + (should (=3D (point) (+ (point-min) 5)))) + (json-tests--with-temp-buffer "false" + (let ((json-false 'false)) + (should (eq (json-read-keyword "false") 'false))) + (should (eobp))) + (json-tests--with-temp-buffer "null" + (let ((json-null 'null)) + (should (eq (json-read-keyword "null") 'null))) + (should (eobp)))) + +(ert-deftest test-json-read-keyword-invalid () + (json-tests--with-temp-buffer "" + (should (equal (should-error (json-read-keyword "")) + '(json-unknown-keyword ""))) + (should (equal (should-error (json-read-keyword "true")) + '(json-unknown-keyword ())))) (json-tests--with-temp-buffer "true" - (should-error - (json-read-keyword "false") :type 'json-unknown-keyword)) + (should (equal (should-error (json-read-keyword "false")) + '(json-unknown-keyword "true")))) (json-tests--with-temp-buffer "foo" - (should-error - (json-read-keyword "foo") :type 'json-unknown-keyword))) + (should (equal (should-error (json-read-keyword "foo")) + '(json-unknown-keyword "foo"))) + (should (equal (should-error (json-read-keyword "bar")) + '(json-unknown-keyword "bar")))) + (json-tests--with-temp-buffer " true" + (should (equal (should-error (json-read-keyword "true")) + '(json-unknown-keyword ())))) + (json-tests--with-temp-buffer "truefalse" + (should (equal (should-error (json-read-keyword "true")) + '(json-unknown-keyword "truefalse")))) + (json-tests--with-temp-buffer "true|" + (should (equal (should-error (json-read-keyword "true")) + '(json-unknown-keyword "true"))))) =20 (ert-deftest test-json-encode-keyword () (should (equal (json-encode-keyword t) "true")) - (should (equal (json-encode-keyword json-false) "false")) - (should (equal (json-encode-keyword json-null) "null"))) + (let ((json-false 'false)) + (should (equal (json-encode-keyword 'false) "false")) + (should (equal (json-encode-keyword json-false) "false"))) + (let ((json-null 'null)) + (should (equal (json-encode-keyword 'null) "null")) + (should (equal (json-encode-keyword json-null) "null")))) =20 ;;; Numbers =20 -(ert-deftest test-json-read-number () - (json-tests--with-temp-buffer "3" - (should (=3D (json-read-number) 3))) - (json-tests--with-temp-buffer "-5" - (should (=3D (json-read-number) -5))) - (json-tests--with-temp-buffer "123.456" - (should (=3D (json-read-number) 123.456))) - (json-tests--with-temp-buffer "1e3" - (should (=3D (json-read-number) 1e3))) - (json-tests--with-temp-buffer "2e+3" - (should (=3D (json-read-number) 2e3))) - (json-tests--with-temp-buffer "3E3" - (should (=3D (json-read-number) 3e3))) - (json-tests--with-temp-buffer "1e-7" - (should (=3D (json-read-number) 1e-7))) - (json-tests--with-temp-buffer "abc" - (should-error (json-read-number) :type 'json-number-format))) +(ert-deftest test-json-read-integer () + (json-tests--with-temp-buffer "0 " + (should (=3D (json-read-number) 0)) + (should (eobp))) + (json-tests--with-temp-buffer "-0 " + (should (=3D (json-read-number) 0)) + (should (eobp))) + (json-tests--with-temp-buffer "3 " + (should (=3D (json-read-number) 3)) + (should (eobp))) + (json-tests--with-temp-buffer "-10 " + (should (=3D (json-read-number) -10)) + (should (eobp))) + (json-tests--with-temp-buffer (format "%d " (1+ most-positive-fixnum)) + (should (=3D (json-read-number) (1+ most-positive-fixnum))) + (should (eobp))) + (json-tests--with-temp-buffer (format "%d " (1- most-negative-fixnum)) + (should (=3D (json-read-number) (1- most-negative-fixnum))) + (should (eobp)))) + +(ert-deftest test-json-read-fraction () + (json-tests--with-temp-buffer "0.0 " + (should (=3D (json-read-number) 0.0)) + (should (eobp))) + (json-tests--with-temp-buffer "-0.0 " + (should (=3D (json-read-number) 0.0)) + (should (eobp))) + (json-tests--with-temp-buffer "0.01 " + (should (=3D (json-read-number) 0.01)) + (should (eobp))) + (json-tests--with-temp-buffer "-0.01 " + (should (=3D (json-read-number) -0.01)) + (should (eobp))) + (json-tests--with-temp-buffer "123.456 " + (should (=3D (json-read-number) 123.456)) + (should (eobp))) + (json-tests--with-temp-buffer "-123.456 " + (should (=3D (json-read-number) -123.456)) + (should (eobp)))) + +(ert-deftest test-json-read-exponent () + (json-tests--with-temp-buffer "0e0 " + (should (=3D (json-read-number) 0e0)) + (should (eobp))) + (json-tests--with-temp-buffer "-0E0 " + (should (=3D (json-read-number) 0e0)) + (should (eobp))) + (json-tests--with-temp-buffer "-0E+0 " + (should (=3D (json-read-number) 0e0)) + (should (eobp))) + (json-tests--with-temp-buffer "0e-0 " + (should (=3D (json-read-number) 0e0)) + (should (eobp))) + (json-tests--with-temp-buffer "12e34 " + (should (=3D (json-read-number) 12e34)) + (should (eobp))) + (json-tests--with-temp-buffer "-12E34 " + (should (=3D (json-read-number) -12e34)) + (should (eobp))) + (json-tests--with-temp-buffer "-12E+34 " + (should (=3D (json-read-number) -12e34)) + (should (eobp))) + (json-tests--with-temp-buffer "12e-34 " + (should (=3D (json-read-number) 12e-34)) + (should (eobp)))) + +(ert-deftest test-json-read-fraction-exponent () + (json-tests--with-temp-buffer "0.0e0 " + (should (=3D (json-read-number) 0.0e0)) + (should (eobp))) + (json-tests--with-temp-buffer "-0.0E0 " + (should (=3D (json-read-number) 0.0e0)) + (should (eobp))) + (json-tests--with-temp-buffer "0.12E-0 " + (should (=3D (json-read-number) 0.12e0)) + (should (eobp))) + (json-tests--with-temp-buffer "-12.34e+56 " + (should (=3D (json-read-number) -12.34e+56)) + (should (eobp)))) + +(ert-deftest test-json-read-number-invalid () + (cl-flet ((read (str) + ;; Return error and point resulting from reading STR. + (json-tests--with-temp-buffer str + (cons (should-error (json-read-number)) (point))))) + ;; POS is where each of its STRINGS becomes invalid. + (pcase-dolist (`(,pos . ,strings) + '((1 "" "+" "-" "." "e" "e1" "abc" "++0" "++1" + "+0" "+0.0" "+12" "+12.34" "+12.34e56" + ".0" "+.0" "-.0" ".12" "+.12" "-.12" + ".e0" "+.e0" "-.e0" ".0e0" "+.0e0" "-.0e0") + (2 "01" "1ee1" "1e++1") + (3 "-01") + (4 "0.0.0" "1.1.1" "1e1e1") + (5 "-0.0.0" "-1.1.1"))) + ;; Expected error and point. + (let ((res `((json-number-format ,pos) . ,pos))) + (dolist (str strings) + (should (equal (read str) res))))))) =20 (ert-deftest test-json-encode-number () + (should (equal (json-encode-number 0) "0")) + (should (equal (json-encode-number -0) "0")) (should (equal (json-encode-number 3) "3")) (should (equal (json-encode-number -5) "-5")) - (should (equal (json-encode-number 123.456) "123.456"))) + (should (equal (json-encode-number 123.456) "123.456")) + (let ((bignum (1+ most-positive-fixnum))) + (should (equal (json-encode-number bignum) + (number-to-string bignum))))) =20 -;; Strings +;;; Strings =20 (ert-deftest test-json-read-escaped-char () (json-tests--with-temp-buffer "\\\"" - (should (equal (json-read-escaped-char) ?\")))) + (should (=3D (json-read-escaped-char) ?\")) + (should (eobp))) + (json-tests--with-temp-buffer "\\\\ " + (should (=3D (json-read-escaped-char) ?\\)) + (should (=3D (point) (+ (point-min) 2)))) + (json-tests--with-temp-buffer "\\b " + (should (=3D (json-read-escaped-char) ?\b)) + (should (=3D (point) (+ (point-min) 2)))) + (json-tests--with-temp-buffer "\\f " + (should (=3D (json-read-escaped-char) ?\f)) + (should (=3D (point) (+ (point-min) 2)))) + (json-tests--with-temp-buffer "\\n " + (should (=3D (json-read-escaped-char) ?\n)) + (should (=3D (point) (+ (point-min) 2)))) + (json-tests--with-temp-buffer "\\r " + (should (=3D (json-read-escaped-char) ?\r)) + (should (=3D (point) (+ (point-min) 2)))) + (json-tests--with-temp-buffer "\\t " + (should (=3D (json-read-escaped-char) ?\t)) + (should (=3D (point) (+ (point-min) 2)))) + (json-tests--with-temp-buffer "\\x " + (should (=3D (json-read-escaped-char) ?x)) + (should (=3D (point) (+ (point-min) 2)))) + (json-tests--with-temp-buffer "\\ud800\\uDC00 " + (should (=3D (json-read-escaped-char) #x10000)) + (should (=3D (point) (+ (point-min) 12)))) + (json-tests--with-temp-buffer "\\ud7ff\\udc00 " + (should (=3D (json-read-escaped-char) #xd7ff)) + (should (=3D (point) (+ (point-min) 6)))) + (json-tests--with-temp-buffer "\\uffff " + (should (=3D (json-read-escaped-char) #xffff)) + (should (=3D (point) (+ (point-min) 6)))) + (json-tests--with-temp-buffer "\\ufffff " + (should (=3D (json-read-escaped-char) #xffff)) + (should (=3D (point) (+ (point-min) 6))))) + +(ert-deftest test-json-read-escaped-char-invalid () + (json-tests--with-temp-buffer "" + (should-error (json-read-escaped-char))) + (json-tests--with-temp-buffer "\\" + (should-error (json-read-escaped-char) :type 'json-end-of-file)) + (json-tests--with-temp-buffer "\\ufff " + (should (equal (should-error (json-read-escaped-char)) + (list 'json-string-escape (+ (point-min) 2))))) + (json-tests--with-temp-buffer "\\ufffg " + (should (equal (should-error (json-read-escaped-char)) + (list 'json-string-escape (+ (point-min) 2)))))) =20 (ert-deftest test-json-read-string () + (json-tests--with-temp-buffer "" + (should-error (json-read-string))) (json-tests--with-temp-buffer "\"formfeed\f\"" - (should-error (json-read-string) :type 'json-string-format)) + (should (equal (should-error (json-read-string)) + '(json-string-format ?\f)))) + (json-tests--with-temp-buffer "\"\"" + (should (equal (json-read-string) ""))) (json-tests--with-temp-buffer "\"foo \\\"bar\\\"\"" (should (equal (json-read-string) "foo \"bar\""))) (json-tests--with-temp-buffer "\"abc=CE=B1=CE=B2=CE=B3\"" @@ -175,57 +405,117 @@ test-json-read-string ;; Bug#24784 (json-tests--with-temp-buffer "\"\\uD834\\uDD1E\"" (should (equal (json-read-string) "\U0001D11E"))) + (json-tests--with-temp-buffer "f" + (should-error (json-read-string) :type 'json-end-of-file)) (json-tests--with-temp-buffer "foo" - (should-error (json-read-string) :type 'json-string-format))) + (should-error (json-read-string) :type 'json-end-of-file))) =20 (ert-deftest test-json-encode-string () + (should (equal (json-encode-string "") "\"\"")) + (should (equal (json-encode-string "a") "\"a\"")) (should (equal (json-encode-string "foo") "\"foo\"")) (should (equal (json-encode-string "a\n\fb") "\"a\\n\\fb\"")) (should (equal (json-encode-string "\nasd=D1=84=D1=8B=D0=B2\u001f\u007ff= gh\t") "\"\\nasd=D1=84=D1=8B=D0=B2\\u001f\u007ffgh\\t\""))) =20 (ert-deftest test-json-encode-key () + (should (equal (json-encode-key "") "\"\"")) + (should (equal (json-encode-key '##) "\"\"")) + (should (equal (json-encode-key :) "\"\"")) (should (equal (json-encode-key "foo") "\"foo\"")) (should (equal (json-encode-key 'foo) "\"foo\"")) (should (equal (json-encode-key :foo) "\"foo\"")) - (should-error (json-encode-key 5) :type 'json-key-format) - (should-error (json-encode-key ["foo"]) :type 'json-key-format) - (should-error (json-encode-key '("foo")) :type 'json-key-format)) + (should (equal (should-error (json-encode-key 5)) + '(json-key-format 5))) + (should (equal (should-error (json-encode-key ["foo"])) + '(json-key-format ["foo"]))) + (should (equal (should-error (json-encode-key '("foo"))) + '(json-key-format ("foo"))))) =20 ;;; Objects =20 (ert-deftest test-json-new-object () (let ((json-object-type 'alist)) - (should (equal (json-new-object) '()))) + (should-not (json-new-object))) (let ((json-object-type 'plist)) - (should (equal (json-new-object) '()))) + (should-not (json-new-object))) (let* ((json-object-type 'hash-table) (json-object (json-new-object))) (should (hash-table-p json-object)) - (should (=3D (hash-table-count json-object) 0)))) + (should (map-empty-p json-object)) + (should (eq (hash-table-test json-object) #'equal)))) =20 -(ert-deftest test-json-add-to-object () +(ert-deftest test-json-add-to-alist () (let* ((json-object-type 'alist) - (json-key-type nil) (obj (json-new-object))) - (setq obj (json-add-to-object obj "a" 1)) - (setq obj (json-add-to-object obj "b" 2)) - (should (equal (assq 'a obj) '(a . 1))) - (should (equal (assq 'b obj) '(b . 2)))) + (let ((json-key-type nil)) + (setq obj (json-add-to-object obj "a" 1)) + (setq obj (json-add-to-object obj "b" 2)) + (should (equal (assq 'a obj) '(a . 1))) + (should (equal (assq 'b obj) '(b . 2)))) + (let ((json-key-type 'symbol)) + (setq obj (json-add-to-object obj "c" 3)) + (setq obj (json-add-to-object obj "d" 4)) + (should (equal (assq 'c obj) '(c . 3))) + (should (equal (assq 'd obj) '(d . 4)))) + (let ((json-key-type 'keyword)) + (setq obj (json-add-to-object obj "e" 5)) + (setq obj (json-add-to-object obj "f" 6)) + (should (equal (assq :e obj) '(:e . 5))) + (should (equal (assq :f obj) '(:f . 6)))) + (let ((json-key-type 'string)) + (setq obj (json-add-to-object obj "g" 7)) + (setq obj (json-add-to-object obj "h" 8)) + (should (equal (assoc "g" obj) '("g" . 7))) + (should (equal (assoc "h" obj) '("h" . 8)))))) + +(ert-deftest test-json-add-to-plist () (let* ((json-object-type 'plist) - (json-key-type nil) (obj (json-new-object))) - (setq obj (json-add-to-object obj "a" 1)) - (setq obj (json-add-to-object obj "b" 2)) - (should (=3D (plist-get obj :a) 1)) - (should (=3D (plist-get obj :b) 2))) + (let ((json-key-type nil)) + (setq obj (json-add-to-object obj "a" 1)) + (setq obj (json-add-to-object obj "b" 2)) + (should (=3D (plist-get obj :a) 1)) + (should (=3D (plist-get obj :b) 2))) + (let ((json-key-type 'keyword)) + (setq obj (json-add-to-object obj "c" 3)) + (setq obj (json-add-to-object obj "d" 4)) + (should (=3D (plist-get obj :c) 3)) + (should (=3D (plist-get obj :d) 4))) + (let ((json-key-type 'symbol)) + (setq obj (json-add-to-object obj "e" 5)) + (setq obj (json-add-to-object obj "f" 6)) + (should (=3D (plist-get obj 'e) 5)) + (should (=3D (plist-get obj 'f) 6))) + (let ((json-key-type 'string)) + (setq obj (json-add-to-object obj "g" 7)) + (setq obj (json-add-to-object obj "h" 8)) + (should (=3D (lax-plist-get obj "g") 7)) + (should (=3D (lax-plist-get obj "h") 8))))) + +(ert-deftest test-json-add-to-hash-table () (let* ((json-object-type 'hash-table) - (json-key-type nil) (obj (json-new-object))) - (setq obj (json-add-to-object obj "a" 1)) - (setq obj (json-add-to-object obj "b" 2)) - (should (=3D (gethash "a" obj) 1)) - (should (=3D (gethash "b" obj) 2)))) + (let ((json-key-type nil)) + (setq obj (json-add-to-object obj "a" 1)) + (setq obj (json-add-to-object obj "b" 2)) + (should (=3D (gethash "a" obj) 1)) + (should (=3D (gethash "b" obj) 2))) + (let ((json-key-type 'string)) + (setq obj (json-add-to-object obj "c" 3)) + (setq obj (json-add-to-object obj "d" 4)) + (should (=3D (gethash "c" obj) 3)) + (should (=3D (gethash "d" obj) 4))) + (let ((json-key-type 'symbol)) + (setq obj (json-add-to-object obj "e" 5)) + (setq obj (json-add-to-object obj "f" 6)) + (should (=3D (gethash 'e obj) 5)) + (should (=3D (gethash 'f obj) 6))) + (let ((json-key-type 'keyword)) + (setq obj (json-add-to-object obj "g" 7)) + (setq obj (json-add-to-object obj "h" 8)) + (should (=3D (gethash :g obj) 7)) + (should (=3D (gethash :h obj) 8))))) =20 (ert-deftest test-json-read-object () (json-tests--with-temp-buffer "{ \"a\": 1, \"b\": 2 }" @@ -238,94 +528,384 @@ test-json-read-object (let* ((json-object-type 'hash-table) (hash-table (json-read-object))) (should (=3D (gethash "a" hash-table) 1)) - (should (=3D (gethash "b" hash-table) 2)))) + (should (=3D (gethash "b" hash-table) 2))))) + +(ert-deftest test-json-read-object-empty () + (json-tests--with-temp-buffer "{}" + (let ((json-object-type 'alist)) + (should-not (save-excursion (json-read-object)))) + (let ((json-object-type 'plist)) + (should-not (save-excursion (json-read-object)))) + (let* ((json-object-type 'hash-table) + (hash-table (json-read-object))) + (should (hash-table-p hash-table)) + (should (map-empty-p hash-table))))) + +(ert-deftest test-json-read-object-invalid () + (json-tests--with-temp-buffer "{ \"a\" 1, \"b\": 2 }" + (should (equal (should-error (json-read-object)) + '(json-object-format ":" ?1)))) (json-tests--with-temp-buffer "{ \"a\": 1 \"b\": 2 }" - (should-error (json-read-object) :type 'json-object-format))) + (should (equal (should-error (json-read-object)) + '(json-object-format "," ?\"))))) + +(ert-deftest test-json-read-object-function () + (let* ((pre nil) + (post nil) + (keys '("b" "a")) + (json-pre-element-read-function + (lambda (key) + (setq pre 'pre) + (should (equal key (pop keys))))) + (json-post-element-read-function + (lambda () (setq post 'post)))) + (json-tests--with-temp-buffer "{ \"b\": 2, \"a\": 1 }" + (json-read-object) + (should (eq pre 'pre)) + (should (eq post 'post))))) =20 (ert-deftest test-json-encode-hash-table () - (let ((hash-table (make-hash-table)) - (json-encoding-object-sort-predicate 'string<) + (let ((json-encoding-object-sort-predicate nil) (json-encoding-pretty-print nil)) - (puthash :a 1 hash-table) - (puthash :b 2 hash-table) - (puthash :c 3 hash-table) - (should (equal (json-encode hash-table) - "{\"a\":1,\"b\":2,\"c\":3}")))) + (should (equal (json-encode-hash-table #s(hash-table)) "{}")) + (should (equal (json-encode-hash-table #s(hash-table data (a 1))) + "{\"a\":1}")) + (should (member (json-encode-hash-table #s(hash-table data (b 2 a 1))) + '("{\"a\":1,\"b\":2}" "{\"b\":2,\"a\":1}"))) + (should (member (json-encode-hash-table #s(hash-table data (c 3 b 2 a = 1))) + '("{\"a\":1,\"b\":2,\"c\":3}" + "{\"a\":1,\"c\":3,\"b\":2}" + "{\"b\":2,\"a\":1,\"c\":3}" + "{\"b\":2,\"c\":3,\"a\":1}" + "{\"c\":3,\"a\":1,\"b\":2}" + "{\"c\":3,\"b\":2,\"a\":1}"))))) =20 -(ert-deftest json-encode-simple-alist () - (let ((json-encoding-pretty-print nil)) - (should (equal (json-encode '((a . 1) (b . 2))) - "{\"a\":1,\"b\":2}")))) +(ert-deftest test-json-encode-hash-table-pretty () + (let ((json-encoding-object-sort-predicate nil) + (json-encoding-pretty-print t) + (json-encoding-default-indentation " ") + (json-encoding-lisp-style-closings nil)) + (should (equal (json-encode-hash-table #s(hash-table)) "{}")) + (should (equal (json-encode-hash-table #s(hash-table data (a 1))) + "{\n \"a\": 1\n}")) + (should (member (json-encode-hash-table #s(hash-table data (b 2 a 1))) + '("{\n \"a\": 1,\n \"b\": 2\n}" + "{\n \"b\": 2,\n \"a\": 1\n}"))) + (should (member (json-encode-hash-table #s(hash-table data (c 3 b 2 a = 1))) + '("{\n \"a\": 1,\n \"b\": 2,\n \"c\": 3\n}" + "{\n \"a\": 1,\n \"c\": 3,\n \"b\": 2\n}" + "{\n \"b\": 2,\n \"a\": 1,\n \"c\": 3\n}" + "{\n \"b\": 2,\n \"c\": 3,\n \"a\": 1\n}" + "{\n \"c\": 3,\n \"a\": 1,\n \"b\": 2\n}" + "{\n \"c\": 3,\n \"b\": 2,\n \"a\": 1\n}"))))) + +(ert-deftest test-json-encode-hash-table-lisp-style () + (let ((json-encoding-object-sort-predicate nil) + (json-encoding-pretty-print t) + (json-encoding-default-indentation " ") + (json-encoding-lisp-style-closings t)) + (should (equal (json-encode-hash-table #s(hash-table)) "{}")) + (should (equal (json-encode-hash-table #s(hash-table data (a 1))) + "{\n \"a\": 1}")) + (should (member (json-encode-hash-table #s(hash-table data (b 2 a 1))) + '("{\n \"a\": 1,\n \"b\": 2}" + "{\n \"b\": 2,\n \"a\": 1}"))) + (should (member (json-encode-hash-table #s(hash-table data (c 3 b 2 a = 1))) + '("{\n \"a\": 1,\n \"b\": 2,\n \"c\": 3}" + "{\n \"a\": 1,\n \"c\": 3,\n \"b\": 2}" + "{\n \"b\": 2,\n \"a\": 1,\n \"c\": 3}" + "{\n \"b\": 2,\n \"c\": 3,\n \"a\": 1}" + "{\n \"c\": 3,\n \"a\": 1,\n \"b\": 2}" + "{\n \"c\": 3,\n \"b\": 2,\n \"a\": 1}"))))) + +(ert-deftest test-json-encode-hash-table-sort () + (let ((json-encoding-object-sort-predicate #'string<) + (json-encoding-pretty-print nil)) + (pcase-dolist (`(,in . ,out) + '((#s(hash-table) . "{}") + (#s(hash-table data (a 1)) . "{\"a\":1}") + (#s(hash-table data (b 2 a 1)) . "{\"a\":1,\"b\":2}") + (#s(hash-table data (c 3 b 2 a 1)) + . "{\"a\":1,\"b\":2,\"c\":3}"))) + (let ((copy (map-pairs in))) + (should (equal (json-encode-hash-table in) out)) + ;; Ensure sorting isn't destructive. + (should (seq-set-equal-p (map-pairs in) copy)))))) + +(ert-deftest test-json-encode-alist () + (let ((json-encoding-object-sort-predicate nil) + (json-encoding-pretty-print nil)) + (should (equal (json-encode-alist ()) "{}")) + (should (equal (json-encode-alist '((a . 1))) "{\"a\":1}")) + (should (equal (json-encode-alist '((b . 2) (a . 1))) "{\"b\":2,\"a\":= 1}")) + (should (equal (json-encode-alist '((c . 3) (b . 2) (a . 1))) + "{\"c\":3,\"b\":2,\"a\":1}")))) + +(ert-deftest test-json-encode-alist-pretty () + (let ((json-encoding-object-sort-predicate nil) + (json-encoding-pretty-print t) + (json-encoding-default-indentation " ") + (json-encoding-lisp-style-closings nil)) + (should (equal (json-encode-alist ()) "{}")) + (should (equal (json-encode-alist '((a . 1))) "{\n \"a\": 1\n}")) + (should (equal (json-encode-alist '((b . 2) (a . 1))) + "{\n \"b\": 2,\n \"a\": 1\n}")) + (should (equal (json-encode-alist '((c . 3) (b . 2) (a . 1))) + "{\n \"c\": 3,\n \"b\": 2,\n \"a\": 1\n}")))) + +(ert-deftest test-json-encode-alist-lisp-style () + (let ((json-encoding-object-sort-predicate nil) + (json-encoding-pretty-print t) + (json-encoding-default-indentation " ") + (json-encoding-lisp-style-closings t)) + (should (equal (json-encode-alist ()) "{}")) + (should (equal (json-encode-alist '((a . 1))) "{\n \"a\": 1}")) + (should (equal (json-encode-alist '((b . 2) (a . 1))) + "{\n \"b\": 2,\n \"a\": 1}")) + (should (equal (json-encode-alist '((c . 3) (b . 2) (a . 1))) + "{\n \"c\": 3,\n \"b\": 2,\n \"a\": 1}")))) + +(ert-deftest test-json-encode-alist-sort () + (let ((json-encoding-object-sort-predicate #'string<) + (json-encoding-pretty-print nil)) + (pcase-dolist (`(,in . ,out) + '((() . "{}") + (((a . 1)) . "{\"a\":1}") + (((b . 2) (a . 1)) . "{\"a\":1,\"b\":2}") + (((c . 3) (b . 2) (a . 1)) + . "{\"a\":1,\"b\":2,\"c\":3}"))) + (let ((copy (copy-alist in))) + (should (equal (json-encode-alist in) out)) + ;; Ensure sorting isn't destructive (bug#40693). + (should (equal in copy)))))) =20 (ert-deftest test-json-encode-plist () - (let ((plist '(:a 1 :b 2)) + (let ((json-encoding-object-sort-predicate nil) (json-encoding-pretty-print nil)) - (should (equal (json-encode plist) "{\"a\":1,\"b\":2}")))) + (should (equal (json-encode-plist ()) "{}")) + (should (equal (json-encode-plist '(:a 1)) "{\"a\":1}")) + (should (equal (json-encode-plist '(:b 2 :a 1)) "{\"b\":2,\"a\":1}")) + (should (equal (json-encode-plist '(:c 3 :b 2 :a 1)) + "{\"c\":3,\"b\":2,\"a\":1}")))) =20 -(ert-deftest test-json-encode-plist-with-sort-predicate () - (let ((plist '(:c 3 :a 1 :b 2)) - (json-encoding-object-sort-predicate 'string<) - (json-encoding-pretty-print nil)) - (should (equal (json-encode plist) "{\"a\":1,\"b\":2,\"c\":3}")))) +(ert-deftest test-json-encode-plist-pretty () + (let ((json-encoding-object-sort-predicate nil) + (json-encoding-pretty-print t) + (json-encoding-default-indentation " ") + (json-encoding-lisp-style-closings nil)) + (should (equal (json-encode-plist ()) "{}")) + (should (equal (json-encode-plist '(:a 1)) "{\n \"a\": 1\n}")) + (should (equal (json-encode-plist '(:b 2 :a 1)) + "{\n \"b\": 2,\n \"a\": 1\n}")) + (should (equal (json-encode-plist '(:c 3 :b 2 :a 1)) + "{\n \"c\": 3,\n \"b\": 2,\n \"a\": 1\n}")))) =20 -(ert-deftest test-json-encode-alist-with-sort-predicate () - (let ((alist '((:c . 3) (:a . 1) (:b . 2))) - (json-encoding-object-sort-predicate 'string<) +(ert-deftest test-json-encode-plist-lisp-style () + (let ((json-encoding-object-sort-predicate nil) + (json-encoding-pretty-print t) + (json-encoding-default-indentation " ") + (json-encoding-lisp-style-closings t)) + (should (equal (json-encode-plist ()) "{}")) + (should (equal (json-encode-plist '(:a 1)) "{\n \"a\": 1}")) + (should (equal (json-encode-plist '(:b 2 :a 1)) + "{\n \"b\": 2,\n \"a\": 1}")) + (should (equal (json-encode-plist '(:c 3 :b 2 :a 1)) + "{\n \"c\": 3,\n \"b\": 2,\n \"a\": 1}")))) + +(ert-deftest test-json-encode-plist-sort () + (let ((json-encoding-object-sort-predicate #'string<) (json-encoding-pretty-print nil)) - (should (equal (json-encode alist) "{\"a\":1,\"b\":2,\"c\":3}")))) + (pcase-dolist (`(,in . ,out) + '((() . "{}") + ((:a 1) . "{\"a\":1}") + ((:b 2 :a 1) . "{\"a\":1,\"b\":2}") + ((:c 3 :b 2 :a 1) . "{\"a\":1,\"b\":2,\"c\":3}"))) + (let ((copy (copy-sequence in))) + (should (equal (json-encode-plist in) out)) + ;; Ensure sorting isn't destructive. + (should (equal in copy)))))) =20 (ert-deftest test-json-encode-list () - (let ((json-encoding-pretty-print nil)) - (should (equal (json-encode-list '(:a 1 :b 2)) - "{\"a\":1,\"b\":2}")) - (should (equal (json-encode-list '((:a . 1) (:b . 2))) - "{\"a\":1,\"b\":2}")) - (should (equal (json-encode-list '(1 2 3 4)) "[1,2,3,4]")))) + (let ((json-encoding-object-sort-predicate nil) + (json-encoding-pretty-print nil)) + (should (equal (json-encode-list ()) "{}")) + (should (equal (json-encode-list '(a)) "[\"a\"]")) + (should (equal (json-encode-list '(:a)) "[\"a\"]")) + (should (equal (json-encode-list '("a")) "[\"a\"]")) + (should (equal (json-encode-list '(a 1)) "[\"a\",1]")) + (should (equal (json-encode-list '("a" 1)) "[\"a\",1]")) + (should (equal (json-encode-list '(:a 1)) "{\"a\":1}")) + (should (equal (json-encode-list '((a . 1))) "{\"a\":1}")) + (should (equal (json-encode-list '((:a . 1))) "{\"a\":1}")) + (should (equal (json-encode-list '(:b 2 :a)) "[\"b\",2,\"a\"]")) + (should (equal (json-encode-list '(4 3 2 1)) "[4,3,2,1]")) + (should (equal (json-encode-list '(b 2 a 1)) "[\"b\",2,\"a\",1]")) + (should (equal (json-encode-list '(:b 2 :a 1)) "{\"b\":2,\"a\":1}")) + (should (equal (json-encode-list '((b . 2) (a . 1))) "{\"b\":2,\"a\":1= }")) + (should (equal (json-encode-list '((:b . 2) (:a . 1))) + "{\"b\":2,\"a\":1}")) + (should (equal (json-encode-list '((a) 1)) "[[\"a\"],1]")) + (should (equal (json-encode-list '((:a) 1)) "[[\"a\"],1]")) + (should (equal (json-encode-list '(("a") 1)) "[[\"a\"],1]")) + (should (equal (json-encode-list '((a 1) 2)) "[[\"a\",1],2]")) + (should (equal (json-encode-list '((:a 1) 2)) "[{\"a\":1},2]")) + (should (equal (json-encode-list '(((a . 1)) 2)) "[{\"a\":1},2]")) + (should (equal (json-encode-list '(:a 1 :b (2))) "{\"a\":1,\"b\":[2]}"= )) + (should (equal (json-encode-list '((a . 1) (b 2))) "{\"a\":1,\"b\":[2]= }")) + (should-error (json-encode-list '(a . 1)) :type 'wrong-type-argument) + (should-error (json-encode-list '((a . 1) 2)) :type 'wrong-type-argume= nt) + (should (equal (should-error (json-encode-list [])) + '(json-error []))) + (should (equal (should-error (json-encode-list [a])) + '(json-error [a]))))) =20 ;;; Arrays =20 (ert-deftest test-json-read-array () (let ((json-array-type 'vector)) + (json-tests--with-temp-buffer "[]" + (should (equal (json-read-array) []))) + (json-tests--with-temp-buffer "[ ]" + (should (equal (json-read-array) []))) + (json-tests--with-temp-buffer "[1]" + (should (equal (json-read-array) [1]))) (json-tests--with-temp-buffer "[1, 2, \"a\", \"b\"]" (should (equal (json-read-array) [1 2 "a" "b"])))) (let ((json-array-type 'list)) + (json-tests--with-temp-buffer "[]" + (should-not (json-read-array))) + (json-tests--with-temp-buffer "[ ]" + (should-not (json-read-array))) + (json-tests--with-temp-buffer "[1]" + (should (equal (json-read-array) '(1)))) (json-tests--with-temp-buffer "[1, 2, \"a\", \"b\"]" (should (equal (json-read-array) '(1 2 "a" "b"))))) (json-tests--with-temp-buffer "[1 2]" - (should-error (json-read-array) :type 'json-error))) + (should (equal (should-error (json-read-array)) + '(json-array-format "," ?2))))) + +(ert-deftest test-json-read-array-function () + (let* ((pre nil) + (post nil) + (keys '(0 1)) + (json-pre-element-read-function + (lambda (key) + (setq pre 'pre) + (should (equal key (pop keys))))) + (json-post-element-read-function + (lambda () (setq post 'post)))) + (json-tests--with-temp-buffer "[1, 0]" + (json-read-array) + (should (eq pre 'pre)) + (should (eq post 'post))))) =20 (ert-deftest test-json-encode-array () - (let ((json-encoding-pretty-print nil)) - (should (equal (json-encode-array [1 2 "a" "b"]) - "[1,2,\"a\",\"b\"]")))) + (let ((json-encoding-object-sort-predicate nil) + (json-encoding-pretty-print nil)) + (should (equal (json-encode-array ()) "[]")) + (should (equal (json-encode-array []) "[]")) + (should (equal (json-encode-array '(1)) "[1]")) + (should (equal (json-encode-array '[1]) "[1]")) + (should (equal (json-encode-array '(2 1)) "[2,1]")) + (should (equal (json-encode-array '[2 1]) "[2,1]")) + (should (equal (json-encode-array '[:b a 2 1]) "[\"b\",\"a\",2,1]")))) + +(ert-deftest test-json-encode-array-pretty () + (let ((json-encoding-object-sort-predicate nil) + (json-encoding-pretty-print t) + (json-encoding-default-indentation " ") + (json-encoding-lisp-style-closings nil)) + (should (equal (json-encode-array ()) "[]")) + (should (equal (json-encode-array []) "[]")) + (should (equal (json-encode-array '(1)) "[\n 1\n]")) + (should (equal (json-encode-array '[1]) "[\n 1\n]")) + (should (equal (json-encode-array '(2 1)) "[\n 2,\n 1\n]")) + (should (equal (json-encode-array '[2 1]) "[\n 2,\n 1\n]")) + (should (equal (json-encode-array '[:b a 2 1]) + "[\n \"b\",\n \"a\",\n 2,\n 1\n]")))) + +(ert-deftest test-json-encode-array-lisp-style () + (let ((json-encoding-object-sort-predicate nil) + (json-encoding-pretty-print t) + (json-encoding-default-indentation " ") + (json-encoding-lisp-style-closings t)) + (should (equal (json-encode-array ()) "[]")) + (should (equal (json-encode-array []) "[]")) + (should (equal (json-encode-array '(1)) "[\n 1]")) + (should (equal (json-encode-array '[1]) "[\n 1]")) + (should (equal (json-encode-array '(2 1)) "[\n 2,\n 1]")) + (should (equal (json-encode-array '[2 1]) "[\n 2,\n 1]")) + (should (equal (json-encode-array '[:b a 2 1]) + "[\n \"b\",\n \"a\",\n 2,\n 1]")))) =20 ;;; Reader =20 (ert-deftest test-json-read () - (json-tests--with-temp-buffer "{ \"a\": 1 }" - ;; We don't care exactly what the return value is (that is tested - ;; in `test-json-read-object'), but it should parse without error. - (should (json-read))) + (pcase-dolist (`(,fn . ,contents) + '((json-read-string "\"\"" "\"a\"") + (json-read-array "[]" "[1]") + (json-read-object "{}" "{\"a\":1}") + (json-read-keyword "null" "false" "true") + (json-read-number + "-0" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"))) + (dolist (content contents) + ;; Check that leading whitespace is skipped. + (dolist (str (list content (concat " " content))) + (cl-letf* ((called nil) + ((symbol-function fn) + (lambda (&rest _) (setq called t)))) + (json-tests--with-temp-buffer str + ;; We don't care exactly what the return value is (that is + ;; tested elsewhere), but it should parse without error. + (should (json-read)) + (should called))))))) + +(ert-deftest test-json-read-invalid () (json-tests--with-temp-buffer "" (should-error (json-read) :type 'json-end-of-file)) - (json-tests--with-temp-buffer "xxx" - (let ((err (should-error (json-read) :type 'json-readtable-error))) - (should (equal (cdr err) '(?x)))))) + (json-tests--with-temp-buffer " " + (should-error (json-read) :type 'json-end-of-file)) + (json-tests--with-temp-buffer "x" + (should (equal (should-error (json-read)) + '(json-readtable-error ?x)))) + (json-tests--with-temp-buffer " x" + (should (equal (should-error (json-read)) + '(json-readtable-error ?x))))) =20 (ert-deftest test-json-read-from-string () - (let ((json-string "{ \"a\": 1 }")) - (json-tests--with-temp-buffer json-string - (should (equal (json-read-from-string json-string) + (dolist (str '("\"\"" "\"a\"" "[]" "[1]" "{}" "{\"a\":1}" + "null" "false" "true" "0" "123")) + (json-tests--with-temp-buffer str + (should (equal (json-read-from-string str) (json-read)))))) =20 -;;; JSON encoder +;;; Encoder =20 (ert-deftest test-json-encode () + (should (equal (json-encode t) "true")) + (let ((json-null 'null)) + (should (equal (json-encode json-null) "null"))) + (let ((json-false 'false)) + (should (equal (json-encode json-false) "false"))) + (should (equal (json-encode "") "\"\"")) (should (equal (json-encode "foo") "\"foo\"")) + (should (equal (json-encode :) "\"\"")) + (should (equal (json-encode :foo) "\"foo\"")) + (should (equal (json-encode '(1)) "[1]")) + (should (equal (json-encode 'foo) "\"foo\"")) + (should (equal (json-encode 0) "0")) + (should (equal (json-encode 123) "123")) + (let ((json-encoding-object-sort-predicate nil) + (json-encoding-pretty-print nil)) + (should (equal (json-encode []) "[]")) + (should (equal (json-encode [1]) "[1]")) + (should (equal (json-encode #s(hash-table)) "{}")) + (should (equal (json-encode #s(hash-table data (a 1))) "{\"a\":1}"))) (with-temp-buffer - (should-error (json-encode (current-buffer)) :type 'json-error))) + (should (equal (should-error (json-encode (current-buffer))) + (list 'json-error (current-buffer)))))) =20 -;;; Pretty-print +;;; Pretty printing & minimizing =20 (defun json-tests-equal-pretty-print (original &optional expected) "Abort current test if pretty-printing ORIGINAL does not yield EXPECTED. @@ -351,46 +931,45 @@ test-json-pretty-print-number (json-tests-equal-pretty-print "0.123")) =20 (ert-deftest test-json-pretty-print-object () - ;; empty (regression test for bug#24252) - (json-tests-equal-pretty-print - "{}" - "{\n}") - ;; one pair + ;; Empty (regression test for bug#24252). + (json-tests-equal-pretty-print "{}") + ;; One pair. (json-tests-equal-pretty-print "{\"key\":1}" "{\n \"key\": 1\n}") - ;; two pairs + ;; Two pairs. (json-tests-equal-pretty-print "{\"key1\":1,\"key2\":2}" "{\n \"key1\": 1,\n \"key2\": 2\n}") - ;; embedded object + ;; Nested object. (json-tests-equal-pretty-print "{\"foo\":{\"key\":1}}" "{\n \"foo\": {\n \"key\": 1\n }\n}") - ;; embedded array + ;; Nested array. (json-tests-equal-pretty-print "{\"key\":[1,2]}" "{\n \"key\": [\n 1,\n 2\n ]\n}")) =20 (ert-deftest test-json-pretty-print-array () - ;; empty + ;; Empty. (json-tests-equal-pretty-print "[]") - ;; one item + ;; One item. (json-tests-equal-pretty-print "[1]" "[\n 1\n]") - ;; two items + ;; Two items. (json-tests-equal-pretty-print "[1,2]" "[\n 1,\n 2\n]") - ;; embedded object + ;; Nested object. (json-tests-equal-pretty-print "[{\"key\":1}]" "[\n {\n \"key\": 1\n }\n]") - ;; embedded array + ;; Nested array. (json-tests-equal-pretty-print "[[1,2]]" "[\n [\n 1,\n 2\n ]\n]")) =20 (provide 'json-tests) + ;;; json-tests.el ends here --=20 2.26.2 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable "Basil L. Contovounesios" writes: > I have a local WIP branch where I am refactoring parts of json.el to > improve performance, and avoiding the proposed copy-sequence is one of > the fixes. Large patch attached (fear not (too much); the bulk of it is new regression tests). CCing Jo=C3=A3o because it also touches jsonrpc.el. The only backward-incompatible part of it should be the stricter number parsing. Until now[1], json.el accepted numbers with a leading plus sign, leading zeros, and no integer component, all of which are forbidden by the JSON spec[2] and rejected by Emacs' native JSON parsing functions. I was initially willing to ignore this according to "be liberal in what you accept and strict in what you output," but given that libraries are already treating json.el and json.c functions as interchangeable, I think json.el should be fixed. Who knows, it may even help to catch some bad JSON generation somewhere, somewhen. [1]: (json-read-number): New arg. Handle explicitly signed numbers. 7712319db8 2008-08-28 20:19:17 +0000 https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=3D7712319db8db973910= 59925b27ae71f304eee7d2 [2]: https://tools.ietf.org/html/rfc8259#section-6 > I've also found a couple of test JSON files to benchmark against. I downloaded the three large (sizes 617KB-2.2MB) JSON files here: https://github.com/miloyip/nativejson-benchmark/tree/master/data and ran the following benchmark: --=-=-= Content-Type: application/emacs-lisp Content-Disposition: inline; filename=json-bench.el Content-Transfer-Encoding: quoted-printable ;;; json-bench.el --- Benchmark json.el refactor -*- lexical-binding: t -*- (require 'json) (eval-when-compile (require 'cl-lib)) (let ((reps 4) json lisp) (dolist (file command-line-args-left) (message "%s" (file-name-nondirectory file)) (message "decode") (dotimes (_ reps) (garbage-collect) (message "%s" (benchmark-run reps (setq lisp (json-read-file file))))) (message "encode") (dotimes (_ reps) (garbage-collect) (message "%s" (benchmark-run reps (setq json (json-encode lisp))))) (cl-assert (equal lisp (json-read-from-string json))))) ;;; json-bench.el ends here --=-=-= Content-Type: text/plain like so: $ emacs -Q -batch -f batch-byte-compile json-bench.el $ for e in /old/emacs /new/emacs; do "$e" -Q -script json-bench.elc *.json; done with the following (manipulated, for easier comparison) output: decode canada.json old (2.147126599 64 0.714606792) (2.184767529 64 0.772983248) (2.190970555 64 0.7805527100000003) (2.1976262359999996 64 0.786285103) new (2.240072109 62 0.701617291) (2.2702309019999998 62 0.751942913) (2.270719533 62 0.753646107) (2.2844341569999997 62 0.7555721750000002) This file is 2MB of numbers, so I'm speculating that the slight slowdown is due to the stricter number regexp. encode canada.json old (5.672111511 172 1.9869896950000001) (5.6662210150000005 172 1.9884779629999993) (5.670608892 172 1.9894344889999998) (5.670605633999999 172 1.9883765339999986) new (2.4715460570000003 96 1.1121157440000005) (2.4745830389999997 96 1.1193736730000001) (2.465779169 96 1.1147967909999998) (2.4715383390000003 96 1.1174477880000007) decode citm_catalog.json old (1.010838497 34 0.3915659290000004) (1.006386333 34 0.390746824999999) (1.06575967 34 0.4085684829999998) (1.0045083860000001 34 0.3905320579999998) new (0.9698266640000001 34 0.39840883500000057) (0.969682733 34 0.3984373899999998) (0.972970641 34 0.4009393059999997) (0.974868517 34 0.40203729300000113) encode citm_catalog.json old (5.063678788 292 3.2036687829999995) (5.056699193 292 3.201438146000001) (5.048888015999999 292 3.1970336089999982) (5.046339092 292 3.197215603) new (4.38071611 268 3.0482562499999997) (4.327264702 268 3.011219348999999) (4.320279397999999 268 3.0082109699999986) (4.322212972 268 3.010901667999999) decode twitter.json old (0.788541053 32 0.34238300700000224) (0.776468868 32 0.33285421699999773) (0.777424967 32 0.3338445579999991) (0.779168795 32 0.3343039160000032) new (0.7064887900000001 32 0.34372805699999986) (0.6965333029999999 32 0.33550817600000116) (0.700879238 32 0.33781746400000046) (0.701126792 32 0.3365076699999996) encode twitter.json old (2.640938486 163 1.6357819669999998) (2.64012542 163 1.6363964359999983) (2.6377853709999997 163 1.6349542369999988) (2.639091697 163 1.635746981000004) new (2.2311199000000004 144 1.5285102250000016) (2.227288643 144 1.5259519570000002) (2.229322183 144 1.5265554599999973) (2.223512976 144 1.5231076530000003) WDYT? Thanks, -- Basil --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Mon May 18 10:28:12 2020 Received: (at 40693) by debbugs.gnu.org; 18 May 2020 14:28:12 +0000 Received: from localhost ([127.0.0.1]:47938 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jagkV-0005zH-SC for submit@debbugs.gnu.org; Mon, 18 May 2020 10:28:12 -0400 Received: from eggs.gnu.org ([209.51.188.92]:34068) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jagkT-0005z5-R4 for 40693@debbugs.gnu.org; Mon, 18 May 2020 10:28:10 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:58194) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jagkO-0000jE-43; Mon, 18 May 2020 10:28:04 -0400 Received: from [176.228.60.248] (port=3989 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1jagkM-0001aP-Mm; Mon, 18 May 2020 10:28:03 -0400 Date: Mon, 18 May 2020 17:27:57 +0300 Message-Id: <83mu659v2q.fsf@gnu.org> From: Eli Zaretskii To: "Basil L. Contovounesios" In-Reply-To: <87ftbyavbq.fsf@tcd.ie> (contovob@tcd.ie) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> <87wo5yqrqo.fsf@tcd.ie> <87ftbyavbq.fsf@tcd.ie> MIME-version: 1.0 Content-type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 40693 Cc: darthandrus@gmail.com, 40693@debbugs.gnu.org, joaotavora@gmail.com, dgutov@yandex.ru 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 (---) > From: "Basil L. Contovounesios" > Cc: Dmitry Gutov , darthandrus@gmail.com, > 40693@debbugs.gnu.org, Joćo Tįvora > > Date: Mon, 18 May 2020 02:24:57 +0100 > > Large patch attached (fear not (too much); the bulk of it is new > regression tests). CCing Joćo because it also touches jsonrpc.el. Thanks, LGTM. From debbugs-submit-bounces@debbugs.gnu.org Mon May 18 18:50:28 2020 Received: (at 40693) by debbugs.gnu.org; 18 May 2020 22:50:28 +0000 Received: from localhost ([127.0.0.1]:48523 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jaoaa-0003PN-2k for submit@debbugs.gnu.org; Mon, 18 May 2020 18:50:28 -0400 Received: from mail-wr1-f54.google.com ([209.85.221.54]:37607) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jaoaZ-0003P2-0S for 40693@debbugs.gnu.org; Mon, 18 May 2020 18:50:27 -0400 Received: by mail-wr1-f54.google.com with SMTP id l17so13703208wrr.4 for <40693@debbugs.gnu.org>; Mon, 18 May 2020 15:50:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=MbkFpvNsyJUPAEuPJSO2G/dC0OeAKC1V2MdctqLyV9g=; b=P6aMJve82dBNDSWywJpyaUGm05UgGrQ4Sd4tbrW5NC2WolYtz2B4lrWEFhx8E0SWC5 rRSFcGlxgUSu9gqF+2IsZIk3R4ICy/CkkMPjvtayVRIbT/ANk3F4eYmZYwsLAk+DLboE j5ly6ZiTTP1/YvswIP36PMOHSTJlQRUU19bU+9EyaduTwm2FyNHimXr4JZQc7CD6c2pk 2HDGH18ahCo/RVArJygFE+0NpGZ/sr6K0zVT1GmTNTO32dImiBWRqQhxgnEyUtAK6z+x S5sm3/DHVX2y6ELOVpBL6PqIt2gucKwaQRUv1vMo629jzdW3MjQ2ltVPzWI1D5YvlKBx j4Tg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:subject:to:cc:references:from:message-id :date:user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=MbkFpvNsyJUPAEuPJSO2G/dC0OeAKC1V2MdctqLyV9g=; b=pROSwBmVdojmzKsFyJiX8fIQUs9zdG3Vv2pgU529OJthNs5RKDcyXvfzMCSkhNLeVY R5jYzoWyWK2CvCAWfIvW/3B4rNVmwDAm/s9OW2OgPXUdVuxqdrrJSlLkag4Z9T0l3eqg XBQjpqKtRXR33b5hMEK5DV2W38YIblGytm9BCJN3SvRx97aamzn6dBjVbNXuoVg7Wi16 wU611HsAxuyHLpeY3atSYjZi4raTLC6L6UqrXEfVPvmlBki/16p3IX4kmzmlkc9LO6mq bUMLc1m8RARv6MmAItDnDcpg85V/tOhFv96U23wSfhJYYqOREoFpZNlbIlVcZ9IQgdDz dfPA== X-Gm-Message-State: AOAM532JhWegHmRkdLeZF4HBuzTmkcFSBF/zdO1Ac1YPwRDY+HeV9jy+ rCFesGsy/uQJOiXYLZ4qf2k= X-Google-Smtp-Source: ABdhPJz7+LFe6X4+CXpxka8geukLR3oQIKM2tPB9rMuo3/7BXp1Z9hFgfKClxN/rq2aFKgmDm4GRqQ== X-Received: by 2002:adf:e388:: with SMTP id e8mr21916649wrm.174.1589842221039; Mon, 18 May 2020 15:50:21 -0700 (PDT) Received: from [192.168.0.3] ([66.205.73.129]) by smtp.googlemail.com with ESMTPSA id s15sm18114136wro.80.2020.05.18.15.50.19 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 18 May 2020 15:50:20 -0700 (PDT) Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist To: "Basil L. Contovounesios" , Eli Zaretskii References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> <87wo5yqrqo.fsf@tcd.ie> <87ftbyavbq.fsf@tcd.ie> From: Dmitry Gutov Message-ID: <3b16257b-ad3d-8bc3-b394-f8cd2eb764d5@yandex.ru> Date: Tue, 19 May 2020 01:50:18 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <87ftbyavbq.fsf@tcd.ie> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit X-Spam-Score: 0.5 (/) X-Debbugs-Envelope-To: 40693 Cc: darthandrus@gmail.com, 40693@debbugs.gnu.org, =?UTF-8?B?Sm/Do28gVMOhdm9yYQ==?= 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: -0.5 (/) On 18.05.2020 04:24, Basil L. Contovounesios wrote: > Large patch attached (fear not (too much); the bulk of it is new > regression tests). CCing JoĆ£o because it also touches jsonrpc.el. LGTM as well. And stricter validation sounds good in this case. From debbugs-submit-bounces@debbugs.gnu.org Mon May 18 19:50:50 2020 Received: (at 40693) by debbugs.gnu.org; 18 May 2020 23:50:50 +0000 Received: from localhost ([127.0.0.1]:48587 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1japWw-0004qM-92 for submit@debbugs.gnu.org; Mon, 18 May 2020 19:50:50 -0400 Received: from mail-wm1-f68.google.com ([209.85.128.68]:33383) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1japWr-0004q4-Su for 40693@debbugs.gnu.org; Mon, 18 May 2020 19:50:45 -0400 Received: by mail-wm1-f68.google.com with SMTP id d207so1110731wmd.0 for <40693@debbugs.gnu.org>; Mon, 18 May 2020 16:50:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=edMwMbCu9ARudHfR7IDV06DtkHFt87eItTXNmvgo8Bc=; b=pgNPQ1bq9PWREF/LslYQLGONkJe3pGibhtIY7w/9i7WP2ar4UBnAabmHH6COAlPLe6 tEMimBeC38CZ0Hmw06jdxOailkFCqi9CT3T+VlokGVra3JpUKnCf8f4BWk9aLHzKeeI/ 9ao30+1i6VcFf5G8p3TBAWKjCewp7uSR8u1yV2mzmh3/kKAghkKzIl+wF32AygMOEajG gq6pUgPyzUjkn0x1aTWXZSf/41JM3zoq/+HRAnObFqHEADWBlj29qLg3yCys1cT/6qD9 Fuv9qrvWOz/cgZtQTYnw5KecBR/NpeqBwvZ8LX4yseiIUMUG1wcDfFhw1fcTjoXNMUUQ xkTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=edMwMbCu9ARudHfR7IDV06DtkHFt87eItTXNmvgo8Bc=; b=Dpzal9n5BwcQZs5rp/LVitkAaEcAyFeUBB82S3kPCoDIq5fkrFP6o/Edx0OfuCfrye yGOAicB0GmZukvOdaaJcieA39+VygcoRFi4n9UN2ofTS5k4rCOjoZoj/UyBUo5hEIVeL JoHoMmnxlBwf2ivqu9VGAI86NHSqc6FxhrbkalzUxewoNXk71Om8oP70/WRNejB6faFH vqtUcDv42KGooa9/zICeWKnuk4sIN4dYVFENrwxPjJgzYhPJeGfI4VWAQRjnFwqB4J2e 7j4wOoBwrkJ9B2Vps8QGS/dzjyo/mZH+EwC3HEEd8t/LtZjeYyEKg0qcNXoUyJlW3D4v bV7A== X-Gm-Message-State: AOAM5309LKdlHzgoUdLM7W+6iATc1lvqzV1o5oYwdBG4/voNXoqcmY1K yKBZ/t65qhIj61Bq73knBwhgW46pQyiU7g== X-Google-Smtp-Source: ABdhPJxz/SyG59AkVYWggEzQD/ww8qnqsZVzUZlWkH+e1J6gA9LmLZSam8nP2w1k46viUxd+7cByCw== X-Received: by 2002:a1c:1f16:: with SMTP id f22mr1922985wmf.46.1589845835489; Mon, 18 May 2020 16:50:35 -0700 (PDT) Received: from krug ([2001:818:d820:9500:824a:171:15a:2213]) by smtp.gmail.com with ESMTPSA id d9sm1566496wmd.10.2020.05.18.16.50.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 May 2020 16:50:34 -0700 (PDT) From: =?utf-8?B?Sm/Do28gVMOhdm9yYQ==?= To: "Basil L. Contovounesios" Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> <87wo5yqrqo.fsf@tcd.ie> <87ftbyavbq.fsf@tcd.ie> Date: Tue, 19 May 2020 00:50:33 +0100 In-Reply-To: <87ftbyavbq.fsf@tcd.ie> (Basil L. Contovounesios's message of "Mon, 18 May 2020 02:24:57 +0100") Message-ID: <87zha43ira.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.91 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 40693 Cc: darthandrus@gmail.com, 40693@debbugs.gnu.org, Eli Zaretskii , Dmitry Gutov 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: -1.0 (-) Hi Basil, "Basil L. Contovounesios" writes: > * lisp/jsonrpc.el (jsonrpc--json-read, jsonrpc--json-encode): Check > whether native JSON functions are fboundp only once, at load time. I welcome this small improvement: in fact I had a TODO there to make something similar. In the TODO i suggested the jsonrpc--json-read could be a macro. You used `defalias` instead and that's fine. However, I don't understand the need for the ugly (require 'json), defvar and declare-function there. Can't we just use sth like `eval-and-compile` at the top of the file?=20=20 > -(defun jsonrpc--json-read () > - "Read JSON object in buffer, move point to end of buffer." > - ;; TODO: I guess we can make these macros if/when jsonrpc.el > - ;; goes into Emacs core. > - (cond ((fboundp 'json-parse-buffer) (json-parse-buffer > - :object-type 'plist > - :null-object nil > - :false-object :json-false)) > - (t (let ((json-object-type 'plist)) > - (json-read))))) > +(defalias 'jsonrpc--json-read > + (if (fboundp 'json-parse-buffer) > + (lambda () > + (json-parse-buffer :object-type 'plist > + :null-object nil > + :false-object :json-false)) > + (require 'json) > + (defvar json-object-type) > + (declare-function json-read "json" ()) > + (lambda () > + (let ((json-object-type 'plist)) > + (json-read)))) > + "Read JSON object in buffer, move point to end of buffer.") Thanks, Jo=C3=A3o From debbugs-submit-bounces@debbugs.gnu.org Thu May 21 17:14:30 2020 Received: (at 40693) by debbugs.gnu.org; 21 May 2020 21:14:30 +0000 Received: from localhost ([127.0.0.1]:57444 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jbsWM-0007QQ-6h for submit@debbugs.gnu.org; Thu, 21 May 2020 17:14:30 -0400 Received: from mail-wm1-f49.google.com ([209.85.128.49]:54388) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jbsWK-0007QD-Ow for 40693@debbugs.gnu.org; Thu, 21 May 2020 17:14:29 -0400 Received: by mail-wm1-f49.google.com with SMTP id h4so6776418wmb.4 for <40693@debbugs.gnu.org>; Thu, 21 May 2020 14:14:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tcd-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=Oromm7gfRpmw6Tb9OK/so9HXWFnrcf87EbCpXKWciuk=; b=Hvwke2W2TcyaWfWWVwlctP+F/OC0mm9+B3xaIhdJdVRtcqUAwvLswt5VTzg5h3eMb6 tHQ4gtF1EYyKgWHWpeioY9WVRIcttZFY83IGPpuro8n/9sYdAbOEXPUNhxkPFYFTgQ9W i299NR25SJvO86HkuD8tsrGvuIaXNQH70heQ7BHhQQp+1SoLv5sIumb2VUS7VNb+mT47 +k4GDJcOCesXNaK+M4NACyfr2tHvP2SRFGt1PdwsBVUZKQsqi32cXmatEmRXkbZyicH1 37WHpeMdRlVZVcYqoCpqBX78XlI1hnDcvOyk2Wb/lu6W4/pxRXsf8re/hA/pOX6dJ5mt lv1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=Oromm7gfRpmw6Tb9OK/so9HXWFnrcf87EbCpXKWciuk=; b=pXd4GpN2jpYdxaFtB1gxZxQhpD3Fskf7kowakyume9kKeeusUCAzmlIvQF78crHqEz TsX/VCYHJzTBOe1PBEKZwrGFxgxniRzJgzBvW1j0CNV3lrf2kvrmNDDfNLpyaAxElAmO fyuNq4ML1s6Wn5/j3/A5DkAbmPI6yDEa9+/1bHOcU3I14Rz5wB/idHZl2hYDp2b5TFk2 jTwY+rGwnFMgyhuRkd64nIAy7AUfQvhMs/Hmnf3xOP0PQeM/43v3CredTnCQjr+aTiQi FMTEbKShZqmGvvOmy14GBHK7Jh1W4EB9j0wgEL1VsHz3tprytPIbipIM3MTzGo9QNjr9 0mOw== X-Gm-Message-State: AOAM532N2oBUuPT1LFFp9wGqNUjhhCXd97fC/LD7qrShqHLZeeL6vemh LxL/tepObpuKEVqkeVtXJAEofw== X-Google-Smtp-Source: ABdhPJwlqWHJ7NnNjkxDskzUeMHWXNksX+4GGrDR0N7RPJB/u+FT93fA7gMDjIlp7YB1ecLj/CJNWQ== X-Received: by 2002:a1c:6506:: with SMTP id z6mr10917977wmb.104.1590095662742; Thu, 21 May 2020 14:14:22 -0700 (PDT) Received: from localhost ([2a02:8084:20e2:c380:1f68:7ff5:120d:64e]) by smtp.gmail.com with ESMTPSA id y5sm2499397wrs.63.2020.05.21.14.14.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 May 2020 14:14:22 -0700 (PDT) From: "Basil L. Contovounesios" To: =?utf-8?B?Sm/Do28gVMOhdm9yYQ==?= Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> <87wo5yqrqo.fsf@tcd.ie> <87ftbyavbq.fsf@tcd.ie> <87zha43ira.fsf@gmail.com> Date: Thu, 21 May 2020 22:14:20 +0100 In-Reply-To: <87zha43ira.fsf@gmail.com> (=?utf-8?Q?=22Jo=C3=A3o_T=C3=A1vor?= =?utf-8?Q?a=22's?= message of "Tue, 19 May 2020 00:50:33 +0100") Message-ID: <87367t9ej7.fsf@tcd.ie> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 40693 Cc: darthandrus@gmail.com, 40693@debbugs.gnu.org, Eli Zaretskii , Dmitry Gutov 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: -1.0 (-) Jo=C3=A3o T=C3=A1vora writes: > "Basil L. Contovounesios" writes: > >> * lisp/jsonrpc.el (jsonrpc--json-read, jsonrpc--json-encode): Check >> whether native JSON functions are fboundp only once, at load time. > > I welcome this small improvement: in fact I had a TODO there to make > something similar. In the TODO i suggested the jsonrpc--json-read could > be a macro. You used `defalias` instead and that's fine. Thanks. Indeed I don't think a macro is necessary here for now. > However, I don't understand the need for the ugly (require 'json), > defvar and declare-function there. Can't we just use sth like > `eval-and-compile` at the top of the file? The declarations are needed because the byte-compiler does not know that loading json.el will e.g. define a dynamically bound variable json-object-type and a nullary function symbol json-read. It therefore not only complains but also generates invalid byte-code. One way to avoid having to write these declarations is e.g.: (defalias 'jsonrpc--json-read (if (fboundp 'json-parse-buffer) (lambda () ...) (eval-and-compile (require 'json)) (lambda () ...)) ...) But I find this more heavy handed and intrusive, since it unconditionally loads json.el during byte-compilation, even when json-parse-buffer is available. If you prefer this approach as a matter of style I'll push the patch with the corresponding changes made. >> -(defun jsonrpc--json-read () >> - "Read JSON object in buffer, move point to end of buffer." >> - ;; TODO: I guess we can make these macros if/when jsonrpc.el >> - ;; goes into Emacs core. >> - (cond ((fboundp 'json-parse-buffer) (json-parse-buffer >> - :object-type 'plist >> - :null-object nil >> - :false-object :json-false)) >> - (t (let ((json-object-type 'plist)) >> - (json-read))))) >> +(defalias 'jsonrpc--json-read >> + (if (fboundp 'json-parse-buffer) >> + (lambda () >> + (json-parse-buffer :object-type 'plist >> + :null-object nil >> + :false-object :json-false)) >> + (require 'json) >> + (defvar json-object-type) >> + (declare-function json-read "json" ()) >> + (lambda () >> + (let ((json-object-type 'plist)) >> + (json-read)))) >> + "Read JSON object in buffer, move point to end of buffer.") Thanks, --=20 Basil From debbugs-submit-bounces@debbugs.gnu.org Thu May 21 18:16:41 2020 Received: (at 40693) by debbugs.gnu.org; 21 May 2020 22:16:41 +0000 Received: from localhost ([127.0.0.1]:57474 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jbtUX-0000R0-4f for submit@debbugs.gnu.org; Thu, 21 May 2020 18:16:41 -0400 Received: from mail-wr1-f65.google.com ([209.85.221.65]:35676) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jbtUV-0000Qm-Mo for 40693@debbugs.gnu.org; Thu, 21 May 2020 18:16:40 -0400 Received: by mail-wr1-f65.google.com with SMTP id x14so2841340wrp.2 for <40693@debbugs.gnu.org>; Thu, 21 May 2020 15:16:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=BZmr8an91y5fvoSUkyfO74dCYw7Wii/dcsn82vcII1k=; b=XcrKfr45JB2+zTvdv8A0hj+J4NoL4tMHc338dbcOQKMoNjJzd1273XmI+iDKg0uAdr LeUoytjtNgyt9x2jVs+ftGvMjfA1sPkOIQNI2EsebkxET0GXRNRhnVIWXdUMKSYSemEt fnA24rvsSzMM10mLd6uX+REbHUkUAoAimV8MLt8w4M82G10UtlZksXD9KwzjN0xUF7Ux dw9lT26g26e9qEbIl0HS2Ma2sm5F9qQ4vLngNOoLrhWnlzYfOutyXyPla5dPIjIw0eoX 8zKsZMdxz2bsK5r9SJtp3BR4V0lVeD9A59uVUp2o8f9iViIePnfKrcsqNoOGCcfT7meu Ovjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=BZmr8an91y5fvoSUkyfO74dCYw7Wii/dcsn82vcII1k=; b=XGw25NtIvjxAqnQvyP26lZquqVPpNL8BKa/tlJesCdzgy6jXjPH55jS1YDwow7D2yE 4eCl8tYS02idnNMp6djqoW9eqSu5VFPOnhSvB0MhJfpln7ZqC2qPDMxtOVKKqtQcAc8Q 7HcQuAVejXmfrkRD6J+MWb65ikmhqT+qgjIh/wO6jCRQrWn53k6f2GfVVe29hOj6BDSY zZRZnBGtpuzcxVbYclAMIsF1VX02jeO2Z5FwAtumFGqyB/BdzBnI/v6EIZ/SmRGQNK4g poZ/dIAu5Hlzbyfqx8hSl0+nQc//VzmQAyzi7YQ3IJMNOfxo+KaKi0koft1SFboYe6QF KDVQ== X-Gm-Message-State: AOAM530yWUPa61ZLV481BFx1uHcRZWGMgCF6KyEGYJtN36UVliMlqaGO 9o6o2t336PKHJ/h77DQNL/tQGtutdEQ= X-Google-Smtp-Source: ABdhPJybnZjR12ef5q6enLfCOJFCV/f29y93nmpd1GqDV04kg1DNlWwUzUtW5BnnNa+Y8v8Pxh9skA== X-Received: by 2002:a5d:4d0f:: with SMTP id z15mr560531wrt.411.1590099393548; Thu, 21 May 2020 15:16:33 -0700 (PDT) Received: from krug ([89.180.155.44]) by smtp.gmail.com with ESMTPSA id m13sm7575900wmi.42.2020.05.21.15.16.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 May 2020 15:16:32 -0700 (PDT) From: =?utf-8?B?Sm/Do28gVMOhdm9yYQ==?= To: "Basil L. Contovounesios" Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> <87wo5yqrqo.fsf@tcd.ie> <87ftbyavbq.fsf@tcd.ie> <87zha43ira.fsf@gmail.com> <87367t9ej7.fsf@tcd.ie> Date: Thu, 21 May 2020 23:16:30 +0100 In-Reply-To: <87367t9ej7.fsf@tcd.ie> (Basil L. Contovounesios's message of "Thu, 21 May 2020 22:14:20 +0100") Message-ID: <87imgp2atd.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.91 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 1.5 (+) X-Spam-Report: Spam detection software, running on the system "debbugs.gnu.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 the administrator of that system for details. Content preview: "Basil L. Contovounesios" writes: > The declarations are needed because the byte-compiler does not know that > loading json.el will e.g. define a dynamically bound variable > json-object-type and a [...] Content analysis details: (1.5 points, 10.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: tcd.ie] 1.5 RCVD_IN_SORBS_WEB RBL: SORBS: sender is an abusable web server [89.180.155.44 listed in dnsbl.sorbs.net] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (joaotavora[at]gmail.com) 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.221.65 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.221.65 listed in wl.mailspike.net] X-Debbugs-Envelope-To: 40693 Cc: darthandrus@gmail.com, 40693@debbugs.gnu.org, Eli Zaretskii , Dmitry Gutov 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: 0.5 (/) "Basil L. Contovounesios" writes: > The declarations are needed because the byte-compiler does not know that > loading json.el will e.g. define a dynamically bound variable > json-object-type and a nullary function symbol json-read. It therefore > not only complains but also generates invalid byte-code. Basil, I understand the need for the declarations, but I was suggesting something different. This, at the top, near all the other requires. (eval-and-compile (unless (fboundp 'json-parse-buffer) (require 'json))) and then do the defalias without the declarations below. (defalias blabla (if (fboundp 'json-parse-buffer) (lambda () json-c-things...) (lambda () json-el-things...))) Am I missing something or doesn't this work like you want? We're checking json.c function thrice instead of twice, but doesn't seem very bad, only a 50% increase :-) > But I find this more heavy handed and intrusive, since it > unconditionally loads json.el during byte-compilation, even when > json-parse-buffer is available. I think the snippet above doesn't have this problem. Anyway, this is a minor nitpick, push whatever you think is better. Jo=C3=A3o From debbugs-submit-bounces@debbugs.gnu.org Fri May 22 10:54:44 2020 Received: (at control) by debbugs.gnu.org; 22 May 2020 14:54:44 +0000 Received: from localhost ([127.0.0.1]:60010 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jc94N-0002CI-QA for submit@debbugs.gnu.org; Fri, 22 May 2020 10:54:44 -0400 Received: from mail-qt1-f193.google.com ([209.85.160.193]:34623) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jc94M-0002C1-B0 for control@debbugs.gnu.org; Fri, 22 May 2020 10:54:42 -0400 Received: by mail-qt1-f193.google.com with SMTP id a23so8500987qto.1 for ; Fri, 22 May 2020 07:54:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tcd-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=wQXLa00oL3CFCiIrAB1UF9R/hwSULi+3PUrwW6UwRr8=; b=SgCvey7tM4J84t8xqmikwWlFXiUaF5ZLWxk5SNvhJv6pDcST0vmLOLqeg7zIKpsXyv ogbqUt9uNJIVHWARTiPzgF04ei4eLZcK3cmjP9fnprF4HX+6FiVCojN6KDJFug076ipQ IOBe2WKQuxfEQZpQvsXsg0tDgJVyUQ06376vl5zCQoj19sx3PwgngRqEqpK9BPaqBIGh las1Aom8CNw42/ikB8C/6XVLnr98xUmKiD7GwQ7NBRcV31OPguu8hDa+Rm73ozVY32Wk RrCncCfBUgsB2eNIjui09jME2sPK/Olwhd7hfZpwUpdjDHyIrI4ieFryDpQ5nGh2irXW v6Ow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=wQXLa00oL3CFCiIrAB1UF9R/hwSULi+3PUrwW6UwRr8=; b=mFdYxCFMZlSdCdhtKiXnorbHXnSG2Aedx9d1BPSRs11fSvWf99uh5n+lahRlekplxg XFoJc9391C7PphFnymtywz1JkRx6zJ/xA5H5Mpc3gaIK3Z1FHQhMKnDai8lMrNL6oaV0 KHDBsgvy+5JljaXVO/uikD6VD/bx5Meu8Ck33J2QXFZSApS0DSW6UIOBvTIZvdrqqAHl 7OAUzhPxZKJylNGnsDwSiWvAwuOi/NTxPlrYivj9ABN1DpOwfQmCbQrRNzbDDFAU3U8o 6yrGpQqy6adAFHujSDQxQIDAEPUxEWZeaTYj7F7W2Wxve4d9WXcVKcHpolAGF+4xejOH 6dzQ== X-Gm-Message-State: AOAM533rwjzbvthbqN4DTSBIqSTpNGzd0OR/OXpY/BV+ZtcuC50Mp25U eUTfA3bu6jIO16wbS4uIvAcyVA== X-Google-Smtp-Source: ABdhPJxMzElPZGbPInFmcOspylA7BwieWbe7JIb00j0oqE+52QyH0/2e0eF6Xfr54RLZGLJrONIOYQ== X-Received: by 2002:aed:37ca:: with SMTP id j68mr16233530qtb.276.1590159276549; Fri, 22 May 2020 07:54:36 -0700 (PDT) Received: from localhost ([2a02:8084:20e2:c380:1f68:7ff5:120d:64e]) by smtp.gmail.com with ESMTPSA id l64sm7115419qkd.15.2020.05.22.07.54.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 May 2020 07:54:35 -0700 (PDT) From: "Basil L. Contovounesios" To: =?utf-8?B?Sm/Do28gVMOhdm9yYQ==?= Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> <87wo5yqrqo.fsf@tcd.ie> <87ftbyavbq.fsf@tcd.ie> <87zha43ira.fsf@gmail.com> <87367t9ej7.fsf@tcd.ie> <87imgp2atd.fsf@gmail.com> Date: Fri, 22 May 2020 15:54:33 +0100 In-Reply-To: <87imgp2atd.fsf@gmail.com> (=?utf-8?Q?=22Jo=C3=A3o_T=C3=A1vor?= =?utf-8?Q?a=22's?= message of "Thu, 21 May 2020 23:16:30 +0100") Message-ID: <87sgfs81g6.fsf@tcd.ie> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: control Cc: darthandrus@gmail.com, Eli Zaretskii , 40693-done@debbugs.gnu.org, Dmitry Gutov 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: -1.0 (-) tags 40693 fixed close 40693 28.1 quit Jo=C3=A3o T=C3=A1vora writes: > "Basil L. Contovounesios" writes: >> The declarations are needed because the byte-compiler does not know that >> loading json.el will e.g. define a dynamically bound variable >> json-object-type and a nullary function symbol json-read. It therefore >> not only complains but also generates invalid byte-code. > > Basil, I understand the need for the declarations, but I was suggesting > something different. This, at the top, near all the other requires. > > (eval-and-compile > (unless (fboundp 'json-parse-buffer) > (require 'json))) > > and then do the defalias without the declarations below. > > (defalias blabla > (if (fboundp 'json-parse-buffer) > (lambda () json-c-things...) > (lambda () json-el-things...))) > > Am I missing something or doesn't this work like you want? There's a problem with the conditional require at byte-compile time. If the version of Emacs doing the byte-compilation has native JSON support, then it will generate invalid byte-code (and complain) for the case where there is no native JSON support. In other words, there will be a bug when an Emacs without native JSON loads a file that was byte-compiled in an Emacs with native JSON. > We're checking json.c function thrice instead of twice, but doesn't > seem very bad, only a 50% increase :-) Indeed, that wouldn't be an issue. >> But I find this more heavy handed and intrusive, since it >> unconditionally loads json.el during byte-compilation, even when >> json-parse-buffer is available. > > I think the snippet above doesn't have this problem. Indeed, but I think it suffers from the worse aforementioned problem. > Anyway, this is a minor nitpick, push whatever you think is better. Thanks. I've therefore gone with the original patch[1], as it exhibits correct behaviour and is the least intrusive, but you should obviously feel free to tweak it as you prefer. [1]: Various json.el improvements 3f082af536 2020-05-22 15:16:13 +0100 https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=3D3f082af536c33ba713= 561e7ad4b691aaad488701 Thanks also to everyone who reviewed the patch. I'm now closing this bug. --=20 Basil From debbugs-submit-bounces@debbugs.gnu.org Fri May 22 16:14:35 2020 Received: (at 40693-done) by debbugs.gnu.org; 22 May 2020 20:14:35 +0000 Received: from localhost ([127.0.0.1]:60491 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jcE3p-0005xE-6c for submit@debbugs.gnu.org; Fri, 22 May 2020 16:14:34 -0400 Received: from mail-wr1-f43.google.com ([209.85.221.43]:33590) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jcE3o-0005wz-9T for 40693-done@debbugs.gnu.org; Fri, 22 May 2020 16:14:28 -0400 Received: by mail-wr1-f43.google.com with SMTP id l11so11397082wru.0 for <40693-done@debbugs.gnu.org>; Fri, 22 May 2020 13:14:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=yrOqxgMAHHhKHj0nrl4zPWDovl1cG/AtAgDTmEQNjZA=; b=WxsUdIn1JOQ7HCve6BKYpSa7sLjauHUwulV1NOQ14pHaOrw1Kqkx15OqxwqTr6k4ff W/NFMrJGzOzOFFduG59VBcrXYSlvEoou07BPZQiQRuNX/0rAD0RHowZGSr1nXOtvUqPh P6kyJ+5OO0tYDau+67end1qq2u1qoO+r1EloNTQbL3W/cZmRbol5h0Lex0xAUxP7DB/b Y4rdtARgV2B6DRBU8zo81iTKV8g8WYeTvhKIulV3Jx+CdoX+vCPUvNWwuv99I7f0gPfV 1Bm0CpZdfhF+jSZ0inPFqbPx4dami33HB8xEXV8UPzOpFuxaGVzCrCIL9e7foydcetu+ BqTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=yrOqxgMAHHhKHj0nrl4zPWDovl1cG/AtAgDTmEQNjZA=; b=oaxOlvM6wvgIZvC8jNCq/4m+yPz+4YEqGykRcfnB/Uy3PztAe6uvyK+GRYUfHCAkpP cp1saAvrvP26yFxhRVTEgxieSlueHOcTsDwPYssDgUBBxIF+7pjks4XE8AlpDLUJ1OgO +9rPULuxp5a5KSWGPbckOv6so4Ynxzz0KYlAK2OOQhnFUmJiiIcU3bla6HxYoVQhQY0k nM/ynASH/MozoH5K7ncrOFNu0NAF/OkFp9LmYhSRg6Pi5cjLCTiiSjujvglJUcJzEbGH HozlO12VKT4QeF0KCDWnWmfS4HgNqi9hMsbzkZEhGe/4jeqFcP2eE4tZ/k8L9Uv/xgrd SkBA== X-Gm-Message-State: AOAM531nodBo8bV9fInoaAJ3nH4HjjWHI7vmZejgALUQB5/9P3a0t7YL 6BL5hElsL+Nrdfw6rayJ8tzDxHYKHHM= X-Google-Smtp-Source: ABdhPJygnUEi6oH978QA18YrOft0odpH12fAvt91Q5tJ9sfmlQl5/zJO8KrzF+4vLgLmYtHpJ0HW3A== X-Received: by 2002:a5d:4dd0:: with SMTP id f16mr3057726wru.117.1590178462043; Fri, 22 May 2020 13:14:22 -0700 (PDT) Received: from krug ([2001:818:d820:9500:824a:171:15a:2213]) by smtp.gmail.com with ESMTPSA id i74sm10343763wri.49.2020.05.22.13.14.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 May 2020 13:14:21 -0700 (PDT) From: =?utf-8?B?Sm/Do28gVMOhdm9yYQ==?= To: "Basil L. Contovounesios" Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> <87wo5yqrqo.fsf@tcd.ie> <87ftbyavbq.fsf@tcd.ie> <87zha43ira.fsf@gmail.com> <87367t9ej7.fsf@tcd.ie> <87imgp2atd.fsf@gmail.com> <87sgfs81g6.fsf@tcd.ie> Date: Fri, 22 May 2020 21:14:20 +0100 In-Reply-To: <87sgfs81g6.fsf@tcd.ie> (Basil L. Contovounesios's message of "Fri, 22 May 2020 15:54:33 +0100") Message-ID: <87eerbybfn.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.91 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 40693-done Cc: darthandrus@gmail.com, Eli Zaretskii , 40693-done@debbugs.gnu.org, Dmitry Gutov 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: -1.0 (-) "Basil L. Contovounesios" writes: >> Am I missing something or doesn't this work like you want? > > There's a problem with the conditional require at byte-compile time. If > the version of Emacs doing the byte-compilation has native JSON support, > then it will generate invalid byte-code (and complain) for the case > where there is no native JSON support. In other words, there will be a > bug when an Emacs without native JSON loads a file that was > byte-compiled in an Emacs with native JSON. This doesn't give any any warning: (defvar foo-42 42) =20=20=20=20=20 (provide 'foo) ;; foo.el ends here and a bar.el (eval-and-compile (defvar bar-have-native-42 t) ;; or nil =20=20=20=20=20 (unless bar-have-native-42=20 (require 'foo))) =20=20=20=20=20 (defalias 'forty-two (if (eval-when-compile bar-have-native-42) (lambda () (message "%s" 42.0)) (lambda () (message "%s" foo-42)))) ;; bar.el ends here And it seems to work in both cases: ~/tmp =E2=9D=AF=E2=9D=AF=E2=9D=AF emacs -Q --batch -L . -f batch-byte-= compile bar.el ~/tmp =E2=9D=AF=E2=9D=AF=E2=9D=AF emacs -Q --batch -L . -l bar.elc -f = forty-two 42.0 # now change that t to nil ~/tmp =E2=9D=AF=E2=9D=AF=E2=9D=AF emacs -Q --batch -L . -f batch-byte-= compile bar.el ~/tmp =E2=9D=AF=E2=9D=AF=E2=9D=AF emacs -Q --batch -L . -l bar.elc -f = forty-two 42 But indeed in the recipe I gave you, I had forgotten the second eval-when-compile. If you take that away, it warns again. No idea how to check if byte-code is "valid" or not: I just check the warnings. Can you tell me? > Thanks. I've therefore gone with the original patch[1], as it exhibits > correct behaviour and is the least intrusive, but you should obviously > feel free to tweak it as you prefer. I think I'll let it be, the reason I'm not a huge fan is the foward declarations of individual functions and variables, but it's not so bad. Jo=C3=A3o From debbugs-submit-bounces@debbugs.gnu.org Sat May 23 12:14:07 2020 Received: (at 40693) by debbugs.gnu.org; 23 May 2020 16:14:07 +0000 Received: from localhost ([127.0.0.1]:35407 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jcWml-0000Pn-42 for submit@debbugs.gnu.org; Sat, 23 May 2020 12:14:07 -0400 Received: from mail-wm1-f46.google.com ([209.85.128.46]:37522) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jcWmj-0000Oz-Q0 for 40693@debbugs.gnu.org; Sat, 23 May 2020 12:14:06 -0400 Received: by mail-wm1-f46.google.com with SMTP id f5so4693123wmh.2 for <40693@debbugs.gnu.org>; Sat, 23 May 2020 09:14:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tcd-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=driYifvTaE7ysAELyuMQYJYNHs++p0NEzH/TeAkmhY0=; b=ytl+NQeR4sGCVBlmyrzxGzrHBC2ilcH3lZKdzqWA6zn2dTNWM4aPaCK2m/hUaJPlxj fJRDXjN7csx/HWu6MYf5U/7ML4BLi9R4IvjsPbYzJ9JMGnLgEiMRdWhL5y3kuy/pIYBD R5pQwwnmWzlP3BkoDhMsjTdbWL5YFNeZ+HiEzusvHNCo7x/8eTBaIaXPdvQY/nF+zCFw weNxUWNVf0l98zqcbskkQYmmr8pTm1DGiR1XkMggwOeNAsjUF5nfk7dYxtzxk/W44Lr/ zZ+mwIT+YOO5ZwQhczGlbg5V9UHXVg2wj2Vux464QCx4+8amXN975qvc8dB5E+mG0QeY YCCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=driYifvTaE7ysAELyuMQYJYNHs++p0NEzH/TeAkmhY0=; b=syleSPcNExFBPTI0TKoEOQpMH/dDg2ZVp62z4203OEreTn5kkh9lYQgnbT57uEdjc3 y0mHbnf8fyFi5ppQZQJdasJTCSNwxbe99JuCY0gmTYNJsWYF7tqZZcdsJbPll+sgAO8a WQWXreKOIZXmh9GlOWDFN105jYhZQZYUDtbnqZBETI/Pk4XizMmS50LSHoGhNdnCUYlg KWhKKC11bwpVWXh9zFKpLfHhKvGlTH1inCm6S1tyfX1TRun92d4hNyiWCd/GUJEA74Ni bmIdv2S6YO7SXtKQjigc60xNFcU1Kaa9yrH0bvf/SVICqCYO/RCCDvj7DWjku6B2pvZ9 qwGw== X-Gm-Message-State: AOAM533PVVjmhiSjDYBdb8X4kH8oBUzbwhO5MIWAhRfroQqs0Sl8ex2v NMAFYwwgheNqKX2hK6uOkmqmtA== X-Google-Smtp-Source: ABdhPJyGQxdMgstn2Ke0fNwnbkSCt14m8L60J57QJqJ7vhWKxudMSyUXlt46/w4CdDvpbLB9HhG2FA== X-Received: by 2002:a1c:1b96:: with SMTP id b144mr17732112wmb.6.1590250439774; Sat, 23 May 2020 09:13:59 -0700 (PDT) Received: from localhost ([2a02:8084:20e2:c380:1f68:7ff5:120d:64e]) by smtp.gmail.com with ESMTPSA id n9sm12136916wrv.43.2020.05.23.09.13.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 23 May 2020 09:13:58 -0700 (PDT) From: "Basil L. Contovounesios" To: =?utf-8?B?Sm/Do28gVMOhdm9yYQ==?= Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> <87wo5yqrqo.fsf@tcd.ie> <87ftbyavbq.fsf@tcd.ie> <87zha43ira.fsf@gmail.com> <87367t9ej7.fsf@tcd.ie> <87imgp2atd.fsf@gmail.com> <87sgfs81g6.fsf@tcd.ie> <87eerbybfn.fsf@gmail.com> Date: Sat, 23 May 2020 17:13:57 +0100 In-Reply-To: <87eerbybfn.fsf@gmail.com> (=?utf-8?Q?=22Jo=C3=A3o_T=C3=A1vor?= =?utf-8?Q?a=22's?= message of "Fri, 22 May 2020 21:14:20 +0100") Message-ID: <87wo52ochm.fsf@tcd.ie> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 40693 Cc: darthandrus@gmail.com, 40693@debbugs.gnu.org, Eli Zaretskii , Dmitry Gutov 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: -1.0 (-) Jo=C3=A3o T=C3=A1vora writes: > "Basil L. Contovounesios" writes: > >>> Am I missing something or doesn't this work like you want? >> >> There's a problem with the conditional require at byte-compile time. If >> the version of Emacs doing the byte-compilation has native JSON support, >> then it will generate invalid byte-code (and complain) for the case >> where there is no native JSON support. In other words, there will be a >> bug when an Emacs without native JSON loads a file that was >> byte-compiled in an Emacs with native JSON. > > This doesn't give any any warning: > > (defvar foo-42 42) >=20=20=20=20=20=20 > (provide 'foo) > ;; foo.el ends here > > and a bar.el > > (eval-and-compile > (defvar bar-have-native-42 t) ;; or nil >=20=20=20=20=20=20 > (unless bar-have-native-42=20 > (require 'foo))) >=20=20=20=20=20=20 > (defalias 'forty-two > (if (eval-when-compile bar-have-native-42) > (lambda () (message "%s" 42.0)) > (lambda () (message "%s" foo-42)))) > ;; bar.el ends here > > And it seems to work in both cases: > > ~/tmp =E2=9D=AF=E2=9D=AF=E2=9D=AF emacs -Q --batch -L . -f batch-byt= e-compile bar.el > ~/tmp =E2=9D=AF=E2=9D=AF=E2=9D=AF emacs -Q --batch -L . -l bar.elc -= f forty-two > 42.0 > # now change that t to nil > ~/tmp =E2=9D=AF=E2=9D=AF=E2=9D=AF emacs -Q --batch -L . -f batch-byt= e-compile bar.el > ~/tmp =E2=9D=AF=E2=9D=AF=E2=9D=AF emacs -Q --batch -L . -l bar.elc -= f forty-two > 42 > > But indeed in the recipe I gave you, I had forgotten the second > eval-when-compile. If you take that away, it warns again. This is not a representative example for the following reasons: 0. bar.el does not use lexical-binding. 1. The second lambda in forty-two does not let-bind foo-42. 2. If you byte-compile bar.el with bar-have-native-42 set to t, and then load bar.elc in an Emacs that has bar-have-native-42 set to nil, then 42.0 gets printed, which is wrong. This is due to the incorrect usage of eval-when-compile: we want the check to happen at runtime as well. Try this instead: ;;; foo.el --- foo -*- lexical-binding: t -*- (eval-and-compile (unless (fboundp 'json-parse-buffer) (require 'json))) (defalias 'foo (if (eval-when-compile (fboundp 'json-parse-buffer)) (lambda () (json-parse-buffer :object-type 'plist :null-object nil :false-object :json-false)) (lambda () (let ((json-object-type 'plist)) (json-read))))) ;;; foo.el ends here > No idea how to check if byte-code is "valid" or not: I just check the > warnings. Can you tell me? 0. emacs -Q -batch -f batch-byte-compile foo.el 1. emacs -Q 2. (fset 'json-parse-buffer nil) C-j 3. M-x load-file RET foo.elc RET 4. (disassemble 'foo) C-j This prints: byte code for foo: args: nil 0 constant plist 1 constant json-read 2 call 0 3 return=20=20=20=20 whereas I'd expect: byte code for foo: args: nil 0 constant plist 1 varbind json-object-type 2 constant json-read 3 call 0 4 unbind 1 5 return=20=20=20=20 >> Thanks. I've therefore gone with the original patch[1], as it exhibits >> correct behaviour and is the least intrusive, but you should obviously >> feel free to tweak it as you prefer. > > I think I'll let it be, the reason I'm not a huge fan is the foward > declarations of individual functions and variables, but it's not so bad. I think the declarations make the intention explicit to both the reader and the byte-compiler in a simple way, without wrestling the eval-*-compile machinery or allowing for subtle bugs like the ones above. Thanks, --=20 Basil From debbugs-submit-bounces@debbugs.gnu.org Sat May 23 15:40:31 2020 Received: (at 40693) by debbugs.gnu.org; 23 May 2020 19:40:31 +0000 Received: from localhost ([127.0.0.1]:35741 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jca0V-0001IV-05 for submit@debbugs.gnu.org; Sat, 23 May 2020 15:40:31 -0400 Received: from mail-wm1-f42.google.com ([209.85.128.42]:52246) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jca0T-0001IJ-Kr for 40693@debbugs.gnu.org; Sat, 23 May 2020 15:40:30 -0400 Received: by mail-wm1-f42.google.com with SMTP id r9so1508058wmh.2 for <40693@debbugs.gnu.org>; Sat, 23 May 2020 12:40:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=7tC6aWKvkSP9QBmB6ELIZofNoFF0HxZd1NUDCmDAoP8=; b=MbokEyLIClx+3VWYme7Q7ZHW48yWOhtUGxpLAYx4U0w4Qq49n+dBBi9W8dvp0ScZOl y2qP/89AdInbKr8a6akFKx6poNa4uwtPWmTH4mt2K/Eu8gR/GGRQ9W9Nb03bx+lt9ucc 8DcjS75JF6yfPIF/YAIvE8U396246MC4OXtKsPk0JzEuJZVedbciNcf3rHgUw0DaCWnY hEgoHpcUgPfiUIx2kC0VgIzuMOIBQHyW19JNf2Okn4YWRoqb76X6paj70tkRZXnRmqQA tPwDPcO7qxQrZt4YnbddTPvgnOuRYGp5WiZxxr/ugjK3BeJTP5vwCPwxvSuWei2XXBvG 1X5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=7tC6aWKvkSP9QBmB6ELIZofNoFF0HxZd1NUDCmDAoP8=; b=m2ZPeSwkFByLoG/TYGPU65SXSqr+kBZV5flY7xRH3WMUpvBsTXv4H6MPOuyEIhvqc2 w9RChab/PAAzzG4OitGUgV/gVFFn572efHbmX1yU+/vGKpNmHU++OMOtg5piJbHtZay5 sADVsOFVKmNjyA0nVhabDT0Zjiv8qKxUipqy0uOYdOIlIse+rUIaKLPnVFLUORaifxS2 KK49HMvzRudfzLJesMS4cNaJETyRuTLFcOBcxR/uhZwBIjcUNy5PAou2cESRwWJGyQ51 pXxN22T9Pm8nKCC4yUe9E8uRRpxh09jZHOFwQplJmkRIhq97Ur/DNdlSVB/6oCBEAEH/ zbSg== X-Gm-Message-State: AOAM532tizEOS97FfbG5NmKVIVWdpFK34+ddBOhsI5vOuRu7ZrNP7kik RNMnPSf3bAN7PP1t/464QTSs2aTG+3U= X-Google-Smtp-Source: ABdhPJxDCXsaEafo+LWa4ub75jMvnEm6jbg5JW7oKJ5FA+JCreH66rV2ZD2DBKIGqtPezzJWE2vvvw== X-Received: by 2002:a05:600c:297:: with SMTP id 23mr19466632wmk.12.1590262823458; Sat, 23 May 2020 12:40:23 -0700 (PDT) Received: from krug ([89.180.159.150]) by smtp.gmail.com with ESMTPSA id z16sm3719584wmf.3.2020.05.23.12.40.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 23 May 2020 12:40:22 -0700 (PDT) From: =?utf-8?B?Sm/Do28gVMOhdm9yYQ==?= To: "Basil L. Contovounesios" Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> <87wo5yqrqo.fsf@tcd.ie> <87ftbyavbq.fsf@tcd.ie> <87zha43ira.fsf@gmail.com> <87367t9ej7.fsf@tcd.ie> <87imgp2atd.fsf@gmail.com> <87sgfs81g6.fsf@tcd.ie> <87eerbybfn.fsf@gmail.com> <87wo52ochm.fsf@tcd.ie> Date: Sat, 23 May 2020 20:40:20 +0100 In-Reply-To: <87wo52ochm.fsf@tcd.ie> (Basil L. Contovounesios's message of "Sat, 23 May 2020 17:13:57 +0100") Message-ID: <87a71ywicb.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.91 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 40693 Cc: darthandrus@gmail.com, 40693@debbugs.gnu.org, Eli Zaretskii , Dmitry Gutov 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: -1.0 (-) "Basil L. Contovounesios" writes: > Jo=C3=A3o T=C3=A1vora writes: >> "Basil L. Contovounesios" writes: > 0. bar.el does not use lexical-binding. > 1. The second lambda in forty-two does not let-bind foo-42. > 2. If you byte-compile bar.el with bar-have-native-42 set to t, and then > load bar.elc in an Emacs that has bar-have-native-42 set to nil, then > 42.0 gets printed, which is wrong. This is due to the incorrect > usage of eval-when-compile: we want the check to happen at runtime as > well. I think you mean load-time. Anyway, this is true if you want 27.1 elc's to be loadable in 26.x. I was labouring under the impression that we don't care about that (and this is why I thought of the macro approach). Do we? The source file is compatible between multiple emacs version, but is the byte-compiled file also compatible? >> No idea how to check if byte-code is "valid" or not: I just check the >> warnings. Can you tell me? >=20 > 0. emacs -Q -batch -f batch-byte-compile foo.el > 1. emacs -Q > 2. (fset 'json-parse-buffer nil) C-j > 3. M-x load-file RET foo.elc RET > 4. (disassemble 'foo) C-j Thanks. > I think the declarations make the intention explicit to both the reader > and the byte-compiler in a simple way, without wrestling the > eval-*-compile machinery or allowing for subtle bugs like the ones > above. The problem, of course, is that you're repeating yourself, a maintenance hazard. Not too big in this case. Jo=C3=A3o From debbugs-submit-bounces@debbugs.gnu.org Sat May 23 18:41:30 2020 Received: (at 40693) by debbugs.gnu.org; 23 May 2020 22:41:30 +0000 Received: from localhost ([127.0.0.1]:35958 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jccpe-0007kg-Bh for submit@debbugs.gnu.org; Sat, 23 May 2020 18:41:30 -0400 Received: from mail-wr1-f45.google.com ([209.85.221.45]:33977) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jccpc-0007kU-Gp for 40693@debbugs.gnu.org; Sat, 23 May 2020 18:41:28 -0400 Received: by mail-wr1-f45.google.com with SMTP id g12so12585075wrw.1 for <40693@debbugs.gnu.org>; Sat, 23 May 2020 15:41:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tcd-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=oFChX1p5fPpBbEP0+X2e6X9sGp1TPv69dIm0w4ZGNtM=; b=Q1VXGLW06OVUQEu+RjX/2RJCrj+j5JJY4fzHYqdOMISEeh+mTn1U/IK0xE9mlf3IH1 RK3CYP5CjqJxJ/+Ggy6c0BniKl8YoNNjOr75J0sbBpH/S+LaWCpzvorUcd+SR1sb7Fld 6g+xpEelb8nmxPgNm6AgVI2sdLttTt8waZn8eIRPzeA2F6z30jVzoU0m7nNL3TVausGa PaBlzM4rHYoibcLYnLW3AtNkdi4P5cU/v8kC8OGtw5dynTxlO1zbq7rv3Na1XgNgkFUQ jvO005iKS8JlUm4NxIkwhybj6LGkDFDwqkPZEssn6wybZR9pygFIdQSbFUe/0rY/7kFK +3XQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=oFChX1p5fPpBbEP0+X2e6X9sGp1TPv69dIm0w4ZGNtM=; b=d8f1hfpfmsdD95dDpOkCvaHkUMqBfnaNspfxdXvX3DG7E68th702nLDp9+zfLejXsT 4AdG0mfnamz1+RwDTEblxNOO+p7IBBl63Uo2asZ1qY3zrYRDNapp5URXy4uF3ogahUqp XnT8lPQr56SM+qlqyzwYoHfs5NSwSgbB3ycOn+/i0c3i+A9hgaFL6kkMQDd5AQK5Ku2X ZqFGuotm66T0+OcFfnqJZ/+q5ZEgXbUmwFl1cD+Exr7YmuaOFoY/1HemP2ZwQ7O1JkD1 tvFEw7qdSQFVkjaJmkE/njsSvWmAopsVhj0UAH5efh4VyQQA7ICrP+uArmIkL5dpeq7h CasQ== X-Gm-Message-State: AOAM533pZ3kdCmodHO2gEegoeJhP74lws6KtbnDzEXcHLzjDD5kpAtV6 2voIhxDPlDnOilfWbuRvsBBDLw== X-Google-Smtp-Source: ABdhPJzyRVWqfLSWzn10j4n9NQwAhYpHIXvrAEUhpB+34SCPZnvspwyzM5pMJzmJGb7dsWoHXlCSsQ== X-Received: by 2002:a05:6000:10cf:: with SMTP id b15mr8530249wrx.214.1590273682547; Sat, 23 May 2020 15:41:22 -0700 (PDT) Received: from localhost ([2a02:8084:20e2:c380:1f68:7ff5:120d:64e]) by smtp.gmail.com with ESMTPSA id z12sm2733576wrg.9.2020.05.23.15.41.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 23 May 2020 15:41:21 -0700 (PDT) From: "Basil L. Contovounesios" To: =?utf-8?B?Sm/Do28gVMOhdm9yYQ==?= Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> <87wo5yqrqo.fsf@tcd.ie> <87ftbyavbq.fsf@tcd.ie> <87zha43ira.fsf@gmail.com> <87367t9ej7.fsf@tcd.ie> <87imgp2atd.fsf@gmail.com> <87sgfs81g6.fsf@tcd.ie> <87eerbybfn.fsf@gmail.com> <87wo52ochm.fsf@tcd.ie> <87a71ywicb.fsf@gmail.com> Date: Sat, 23 May 2020 23:41:20 +0100 In-Reply-To: <87a71ywicb.fsf@gmail.com> (=?utf-8?Q?=22Jo=C3=A3o_T=C3=A1vor?= =?utf-8?Q?a=22's?= message of "Sat, 23 May 2020 20:40:20 +0100") Message-ID: <87eerab7fz.fsf@tcd.ie> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 40693 Cc: darthandrus@gmail.com, 40693@debbugs.gnu.org, Eli Zaretskii , Dmitry Gutov 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: -1.0 (-) Jo=C3=A3o T=C3=A1vora writes: > "Basil L. Contovounesios" writes: > >> Jo=C3=A3o T=C3=A1vora writes: >>> "Basil L. Contovounesios" writes: > >> 0. bar.el does not use lexical-binding. >> 1. The second lambda in forty-two does not let-bind foo-42. >> 2. If you byte-compile bar.el with bar-have-native-42 set to t, and then >> load bar.elc in an Emacs that has bar-have-native-42 set to nil, then >> 42.0 gets printed, which is wrong. This is due to the incorrect >> usage of eval-when-compile: we want the check to happen at runtime as >> well. > > I think you mean load-time. Yes. > Anyway, this is true if you want 27.1 elc's to be loadable in 26.x. It is also true if you want version N .elc files to be loadable in version N. The problems I list are not specific to either JSON or inter-Emacs-version compat. > I was labouring under the impression that we don't care about that > (and this is why I thought of the macro approach). Do we? The source > file is compatible between multiple emacs version, but is the > byte-compiled file also compatible? This isn't (primarily) about 26/27 compat, but about supporting --without-json configurations properly. In the examples I've given so far I was exclusively using Emacs master --with-json, hence the (fset 'json-parse-buffer nil). Native JSON functions are not guaranteed to be available in any version of Emacs to date, just like D-Bus or X. The only benefit of the macro approach is zero overhead - no fboundp checks at load time, and no indirection in calling jsonrpc--json-read. But those should be negligible costs, and macros come with their slew of drawbacks that makes them unnecessary in this simple case. >>> No idea how to check if byte-code is "valid" or not: I just check the >>> warnings. Can you tell me? >>=20 >> 0. emacs -Q -batch -f batch-byte-compile foo.el >> 1. emacs -Q >> 2. (fset 'json-parse-buffer nil) C-j >> 3. M-x load-file RET foo.elc RET >> 4. (disassemble 'foo) C-j > > Thanks. > >> I think the declarations make the intention explicit to both the reader >> and the byte-compiler in a simple way, without wrestling the >> eval-*-compile machinery or allowing for subtle bugs like the ones >> above. > > The problem, of course, is that you're repeating yourself, a maintenance > hazard. Not too big in this case. Agreed. --=20 Basil From debbugs-submit-bounces@debbugs.gnu.org Sat May 23 18:45:21 2020 Received: (at 40693) by debbugs.gnu.org; 23 May 2020 22:45:21 +0000 Received: from localhost ([127.0.0.1]:35966 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jcctN-0007qn-6y for submit@debbugs.gnu.org; Sat, 23 May 2020 18:45:21 -0400 Received: from mail-wm1-f51.google.com ([209.85.128.51]:37969) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jcctL-0007qZ-0O for 40693@debbugs.gnu.org; Sat, 23 May 2020 18:45:19 -0400 Received: by mail-wm1-f51.google.com with SMTP id u12so8639974wmd.3 for <40693@debbugs.gnu.org>; Sat, 23 May 2020 15:45:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=YJdHVtC7Ck90Yy4YODiAlAf1c6m3wd4vcScMOBA40cY=; b=eoCKxPPVhkHnDFImnx59WMgviyyEBAQfWN0HPtpuhMMSBuX9wjQ1Y+l61sfyl/FKje FpHrrjCuu3UP2Uk4y+Q+G2yMTVF4alqTt4Td+MUykXVe++ir9/axYH1xquK0/HST0O8P QaYyn1snt8Wcb+tl2I6S3SAJAgdOf3wVw5EnGVgUEDsdobjoFvhgIWC3AOumgFDvVHVQ ujXQGZTmuu7nRbK5vqDwh/wEosINOlV3no3y0sYyj5UrdhRkb/90FV+3aw+VMZYRNnwO Qmsxzktwe1McBxWWdciih/UrUUJMSqKuFlKIJI1oJnxisiXwXgHHl1+LVZZExpKgCUr2 /Alw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=YJdHVtC7Ck90Yy4YODiAlAf1c6m3wd4vcScMOBA40cY=; b=EFSZBGyCHhRKaxo15aNw/556T7fv6958Hhmp+KQjOjNVXNTTXc3gicHCOEAiZGnMw2 H5MV5xD+EyQIFrMO/MhthAC6VI/gNMnRzjWG03RGBZTNtWedXTrXW69RwwjnxBnvPq00 qBXwLAkZb7T7Zxcxxn/xEPIaz6lOLjiYjmFzl7ILfest8TcRuppmI267ap4BFonxMoxi mScunQyKmk2AuiRxNrBIRGzOns8X2NfziquKeR4qNpKNqBuoCZhu9SLwmxZX65HUxVCa 6CLqSSQ7rGsknAZ9q6WJ5Lhz8GTr2B2OB/KRQkwuRQxqXNruz/b3+mOKxwkBEJM+WtXp OK1A== X-Gm-Message-State: AOAM5337MnI/YoRwclX/fdA5hJGff95flP8H8GRRNuXMTe6+/aCxiJz1 yMj0xFcGGO/Ne/q9K3H5Bo4CkKNnaeM= X-Google-Smtp-Source: ABdhPJzjAZvE0mw/z80Blpmbsluw7O/68TjvlK7FqPQCPsvp8+f7sm9AXEDLbIqlnxax9HyKlmfGxg== X-Received: by 2002:a1c:e003:: with SMTP id x3mr12905034wmg.171.1590273913009; Sat, 23 May 2020 15:45:13 -0700 (PDT) Received: from krug (89-180-159-150.net.novis.pt. [89.180.159.150]) by smtp.gmail.com with ESMTPSA id i15sm9790916wml.47.2020.05.23.15.45.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 23 May 2020 15:45:12 -0700 (PDT) From: =?utf-8?B?Sm/Do28gVMOhdm9yYQ==?= To: "Basil L. Contovounesios" Subject: Re: bug#40693: 28.0.50; json-encode-alist changes alist References: <87a738jotd.fsf@tcd.ie> <87mu6utxd1.fsf@tcd.ie> <83r1w6ziql.fsf@gnu.org> <82572c3f-fb24-0b01-06ec-47067d9219ca@yandex.ru> <83blnazdly.fsf@gnu.org> <87wo5yqrqo.fsf@tcd.ie> <87ftbyavbq.fsf@tcd.ie> <87zha43ira.fsf@gmail.com> <87367t9ej7.fsf@tcd.ie> <87imgp2atd.fsf@gmail.com> <87sgfs81g6.fsf@tcd.ie> <87eerbybfn.fsf@gmail.com> <87wo52ochm.fsf@tcd.ie> <87a71ywicb.fsf@gmail.com> <87eerab7fz.fsf@tcd.ie> Date: Sat, 23 May 2020 23:45:10 +0100 In-Reply-To: <87eerab7fz.fsf@tcd.ie> (Basil L. Contovounesios's message of "Sat, 23 May 2020 23:41:20 +0100") Message-ID: <87ftbquv7t.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.91 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 40693 Cc: darthandrus@gmail.com, 40693@debbugs.gnu.org, Eli Zaretskii , Dmitry Gutov 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: -1.0 (-) "Basil L. Contovounesios" writes: > Yes. > >> Anyway, this is true if you want 27.1 elc's to be loadable in 26.x. > > It is also true if you want version N .elc files to be loadable in > version N. The problems I list are not specific to either JSON or > inter-Emacs-version compat. You're right, I forgot about --without-json/--with-json builds. > The only benefit of the macro approach is zero overhead - no fboundp > checks at load time, and no indirection in calling jsonrpc--json-read. > But those should be negligible costs, and macros come with their slew of > drawbacks that makes them unnecessary in this simple case. Agree. And macros don't solve the intercompatibility problems. All good, thanks for explaining! Jo=C3=A3o From unknown Sun Aug 17 22:09:33 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, 21 Jun 2020 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