From: olegrok@tarantool.org To: tarantool-patches@dev.tarantool.org, imun@tarantool.org, v.shpilevoy@tarantool.org Cc: Oleg Babin <babinoleg@mail.ru> Subject: [Tarantool-patches] [PATCH 2/3] lua: table.deepcopy ignores __pairs metamethod Date: Thu, 13 Feb 2020 23:33:52 +0300 [thread overview] Message-ID: <cb11f4b91e5dbcb88407be4bae493b77edd891c4.1581625524.git.babinoleg@mail.ru> (raw) In-Reply-To: <cover.1581625524.git.babinoleg@mail.ru> From: Oleg Babin <babinoleg@mail.ru> After 1d85144a9b4bbbb026402848efde1ab98bf72633 table.deepcopy changed the behaviour and started iterate through tables considering __pairs metamethod. In some cases it broke backward compatibility. To avoid such problem let's ignore __pairs and iterate through tables as it was before Closes #4770 Follow-up #4560 --- Issue: https://github.com/tarantool/tarantool/issues/4770 Branch: https://github.com/tarantool/tarantool/tree/olegrok/table-fixes src/lua/table.lua | 7 ++++++- test/app-tap/table.test.lua | 26 +++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/lua/table.lua b/src/lua/table.lua index d83217dcb..4fa9c421c 100644 --- a/src/lua/table.lua +++ b/src/lua/table.lua @@ -1,3 +1,8 @@ +-- This pairs implementation doesn't trigger __pairs metamethod +local function internal_pairs(tbl) + return next, tbl, nil +end + local function table_deepcopy_internal(orig, cyclic) cyclic = cyclic or {} local copy = orig @@ -10,7 +15,7 @@ local function table_deepcopy_internal(orig, cyclic) copy = cyclic[orig] else cyclic[orig] = copy - for orig_key, orig_value in pairs(orig) do + for orig_key, orig_value in internal_pairs(orig) do local key = table_deepcopy_internal(orig_key, cyclic) copy[key] = table_deepcopy_internal(orig_value, cyclic) end diff --git a/test/app-tap/table.test.lua b/test/app-tap/table.test.lua index 07894f69e..3faf2ed23 100755 --- a/test/app-tap/table.test.lua +++ b/test/app-tap/table.test.lua @@ -8,7 +8,7 @@ yaml.cfg{ encode_invalid_as_nil = true, } local test = require('tap').test('table') -test:plan(33) +test:plan(35) do -- check basic table.copy (deepcopy) local example_table = { @@ -241,4 +241,28 @@ do -- gh-4340: deepcopy doesn't handle __metatable correctly. ) end +do -- gh-4770: deepcopy uses __pairs for iteration over table. + local original = { a = 1, b = 2 } + + local function custom_pairs(self) + local function step(tbl, k) + local k, v = next(tbl, k) + if v ~= nil then + v = v + 1 + end + return k, v + end + return step, self, nil + end + + setmetatable(original, {__pairs = custom_pairs }) + + -- Don't use is deeply as it could use pairs for check + local copy = table.deepcopy(original) + test:is(original.a, copy.a, + "checking that the first values is correctly copied") + test:is(original.b, copy.b, + "checking that the second values is correctly copied") +end + os.exit(test:check() == true and 0 or 1) -- 2.23.0
next prev parent reply other threads:[~2020-02-13 20:34 UTC|newest] Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-02-13 20:33 [Tarantool-patches] [PATCH 0/3] lua: table fixes olegrok 2020-02-13 20:33 ` [Tarantool-patches] [PATCH 1/3] lua: fix incorrect table.deepcopy __metatable handling olegrok 2020-02-13 22:50 ` Vladislav Shpilevoy 2020-02-20 11:12 ` Igor Munkin 2020-02-13 20:33 ` olegrok [this message] 2020-02-13 22:50 ` [Tarantool-patches] [PATCH 2/3] lua: table.deepcopy ignores __pairs metamethod Vladislav Shpilevoy 2020-02-20 11:00 ` Igor Munkin 2020-02-13 20:33 ` [Tarantool-patches] [PATCH 3/3] tap: is_deeply " olegrok 2020-02-13 22:50 ` Vladislav Shpilevoy 2020-02-20 10:57 ` Igor Munkin 2020-02-13 22:50 ` [Tarantool-patches] [PATCH 0/3] lua: table fixes Vladislav Shpilevoy 2020-02-15 10:05 ` Oleg Babin 2020-02-15 15:35 ` Vladislav Shpilevoy
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=cb11f4b91e5dbcb88407be4bae493b77edd891c4.1581625524.git.babinoleg@mail.ru \ --to=olegrok@tarantool.org \ --cc=babinoleg@mail.ru \ --cc=imun@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH 2/3] lua: table.deepcopy ignores __pairs metamethod' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox