Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [PATCH v3 0/5] Support Python 3 in tests and PEPify source code
@ 2020-12-23 12:36 sergeyb
  2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 1/5] test: convert print to function and make quotes use consistent sergeyb
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: sergeyb @ 2020-12-23 12:36 UTC (permalink / raw)
  To: tarantool-patches, v.shpilevoy, lvasiliev; +Cc: Sergey Bronnikov

From: Sergey Bronnikov <estetus@gmail.com>

Changes v3:
- added patch with migration iteritems() to items()
- revert changes that updates .result files
- rework patch with bytes strings

Changes v2:
- make using quotes with strings consistent
- remove dead code
- remove empty prints
- added make target for running flake8
- added flake8 config
- added job to run flake8 on Gitlab CI

Changes v1:
- convert print statements to functions
- use "format()" instead of "%" everywhere

Gitlab CI: https://gitlab.com/tarantool/tarantool/-/pipelines/233768577
Branch: https://github.com/tarantool/tarantool/tree/ligurio/gh-5538-support-python3
Issue: https://github.com/tarantool/tarantool/issues/5538

Sergey Bronnikov (5):
  test: convert print to function and make quotes use consistent
  test: make dict.items() compatible with Python 3.x
  test: make strings compatible with Python 3
  test: get rid of iteritems()
  test: remove dead code in Python tests end extra newlines

 test/app-tap/httpd.py                    |  44 ++---
 test/box-py/args.test.py                 |  12 +-
 test/box-py/bad_trigger.test.py          |  16 +-
 test/box-py/bootstrap.test.py            |  16 +-
 test/box-py/call.test.py                 |  80 ++++----
 test/box-py/iproto.test.py               | 239 ++++++++++++-----------
 test/box-py/print.test.py                |  25 +--
 test/box-py/snapshot.test.py             |  19 +-
 test/long_run-py/finalizers.test.py      |  10 +-
 test/replication-py/cluster.test.py      | 217 ++++++++++----------
 test/replication-py/conflict.test.py     |  55 +++---
 test/replication-py/init_storage.test.py |  58 +++---
 test/replication-py/multi.test.py        |  78 ++++----
 test/replication-py/swap.test.py         |  55 +++---
 test/xlog-py/big_lsn.test.py             |   4 +-
 test/xlog-py/dup_key.test.py             |  23 ++-
 test/xlog-py/empty.test.py               |   4 +-
 test/xlog-py/lsn_gap.test.py             |  11 +-
 test/xlog-py/misc.test.py                |  26 +--
 test/xlog-py/missing.test.py             |  10 +-
 20 files changed, 518 insertions(+), 484 deletions(-)

-- 
2.25.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Tarantool-patches] [PATCH v3 1/5] test: convert print to function and make quotes use consistent
  2020-12-23 12:36 [Tarantool-patches] [PATCH v3 0/5] Support Python 3 in tests and PEPify source code sergeyb
@ 2020-12-23 12:36 ` sergeyb
  2020-12-23 15:39   ` Vladislav Shpilevoy
  2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 2/5] test: make dict.items() compatible with Python 3.x sergeyb
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: sergeyb @ 2020-12-23 12:36 UTC (permalink / raw)
  To: tarantool-patches, v.shpilevoy, lvasiliev

From: Sergey Bronnikov <sergeyb@tarantool.org>

- convert print statement to function. In a Python 3 'print' becomes a
function, see [1]. Patch makes 'print' in a regression tests compatible with
Python 3.
- according to PEP8, mixing using double quotes and quotes in a project looks
inconsistent. Patch makes using quotes with strings consistent.
- use "format()" instead of "%" everywhere

1. https://docs.python.org/3/whatsnew/3.0.html#print-is-a-function

Part of #5538
---
 test/app-tap/httpd.py                    |  42 ++---
 test/box-py/args.test.py                 |  12 +-
 test/box-py/bad_trigger.test.py          |  16 +-
 test/box-py/bootstrap.test.py            |  16 +-
 test/box-py/call.test.py                 |  80 +++++----
 test/box-py/iproto.test.py               | 206 ++++++++++-----------
 test/box-py/print.test.py                |  25 +--
 test/box-py/snapshot.test.py             |  19 +-
 test/long_run-py/finalizers.test.py      |  10 +-
 test/replication-py/cluster.test.py      | 217 ++++++++++++-----------
 test/replication-py/conflict.test.py     |  54 +++---
 test/replication-py/init_storage.test.py |  52 +++---
 test/replication-py/multi.test.py        |  78 ++++----
 test/replication-py/swap.test.py         |  46 ++---
 test/xlog-py/big_lsn.test.py             |   4 +-
 test/xlog-py/dup_key.test.py             |  16 +-
 test/xlog-py/empty.test.py               |   4 +-
 test/xlog-py/lsn_gap.test.py             |  10 +-
 test/xlog-py/misc.test.py                |  26 +--
 test/xlog-py/missing.test.py             |  10 +-
 20 files changed, 490 insertions(+), 453 deletions(-)

diff --git a/test/app-tap/httpd.py b/test/app-tap/httpd.py
index b4662bc1f..b57ef1e39 100755
--- a/test/app-tap/httpd.py
+++ b/test/app-tap/httpd.py
@@ -6,35 +6,35 @@ from gevent import spawn, sleep, socket
 
 def absent():
     code = "500 Server Error"
-    headers = [('Content-Type', 'application/json')]
+    headers = [("Content-Type", "application/json")]
     body = ["No such method"]
     return code, body, headers
 
 def hello():
     code = "200 OK"
     body = ["hello world"]
-    headers = [('Content-Type', 'application/json')]
+    headers = [("Content-Type", "application/json")]
     return code, body, headers
 
 def hello1():
     code = "200 OK"
     body = [b"abc"]
-    headers = [('Content-Type', 'application/json')]
+    headers = [("Content-Type", "application/json")]
     return code, body, headers
 
 def headers():
     code = "200 OK"
     body = [b"cookies"]
-    headers = [('Content-Type', 'application/json'),
-               ('Content-Type', 'application/yaml'),
-               ('Set-Cookie', 'likes=cheese; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly'),
-               ('Set-Cookie', 'bad@name=no;'),
-               ('Set-Cookie', 'badcookie'),
-               ('Set-Cookie', 'good_name=yes;'),
-               ('Set-Cookie', 'age = 17; NOSuchOption; EmptyOption=Value;Secure'),
-               ('my_header', 'value1'),
-               ('my_header', 'value2'),
-               ('very_very_very_long_headers_name1', 'true'),
+    headers = [("Content-Type", "application/json"),
+               ("Content-Type", "application/yaml"),
+               ("Set-Cookie", "likes=cheese; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly"),
+               ("Set-Cookie", "bad@name=no;"),
+               ("Set-Cookie", "badcookie"),
+               ("Set-Cookie", "good_name=yes;"),
+               ("Set-Cookie", "age = 17; NOSuchOption; EmptyOption=Value;Secure"),
+               ("my_header", "value1"),
+               ("my_header", "value2"),
+               ("very_very_very_long_headers_name1", "true"),
                ]
     return code, body, headers
 
@@ -42,13 +42,13 @@ def long_query():
     sleep(0.005)
     code = "200 OK"
     body = [b"abc"]
-    headers = [('Content-Type', 'application/json')]
+    headers = [("Content-Type", "application/json")]
     return code, body, headers
 
 def redirect():
     code = "302 Found"
     body = ["redirecting"]
-    headers = [('Location', '/')]
+    headers = [("Location", "/")]
     return code, body, headers
 
 paths = {
@@ -63,7 +63,7 @@ paths = {
 def read_handle(env, response):
     code = "404 Not Found"
     headers = []
-    body = ['Not Found']
+    body = ["Not Found"]
     if env["PATH_INFO"] in paths:
         code, body, headers = paths[env["PATH_INFO"]]()
     for key,value in env.iteritems():
@@ -74,7 +74,7 @@ def read_handle(env, response):
 
 def post_handle(env, response):
     code = "200 OK"
-    body = [env['wsgi.input'].read()]
+    body = [env["wsgi.input"].read()]
     headers = []
     for key,value in env.iteritems():
         if "HTTP_" in key:
@@ -83,7 +83,7 @@ def post_handle(env, response):
     return body
 
 def other_handle(env, response, method, code):
-    headers = [('Content-Type', 'text/plain'), ("method", method)]
+    headers = [("Content-Type", "text/plain"), ("method", method)]
     body = [method]
     for key,value in env.iteritems():
         if "HTTP_" in key:
@@ -119,15 +119,15 @@ def heartbeat():
         sys.exit(1)
 
 def usage():
-    sys.stderr.write("Usage: %s { --inet HOST:PORT | --unix PATH }\n" %
-                     sys.argv[0])
+    message = "Usage: {} {{ --inet HOST:PORT | --unix PATH }}\n".format(sys.argv[0])
+    sys.stderr.write(message)
     sys.exit(1)
 
 if len(sys.argv) != 3:
     usage()
 
 if sys.argv[1] == "--inet":
-    host, port = sys.argv[2].split(':')
+    host, port = sys.argv[2].split(":")
     sock_family = socket.AF_INET
     sock_addr = (host, int(port))
 elif sys.argv[1] == "--unix":
diff --git a/test/box-py/args.test.py b/test/box-py/args.test.py
index c0fac9038..89d64a08c 100644
--- a/test/box-py/args.test.py
+++ b/test/box-py/args.test.py
@@ -5,7 +5,7 @@ import re
 # Disabled on OpenBSD due to fail #XXXX.
 import platform
 
-if platform.system() == 'OpenBSD':
+if platform.system() == "OpenBSD":
     self.skip = 1
 
 # mask BFD warnings: https://bugs.launchpad.net/tarantool/+bug/1018356
@@ -13,9 +13,9 @@ sys.stdout.push_filter("unable to read unknown load command 0x2\d+", "")
 server.test_option("--help")
 server.test_option("-h")
 # Replace with the same value for case when builddir inside source dir
-sys.stdout.push_filter(re.escape(os.getenv("BUILDDIR")+'/src/tarantool'), "tarantool")
+sys.stdout.push_filter(re.escape(os.getenv("BUILDDIR")+"/src/tarantool"), "tarantool")
 sys.stdout.push_filter(re.escape(os.getenv("BUILDDIR")), "${SOURCEDIR}")
-sys.stdout.push_filter(re.escape(os.getenv("SOURCEDIR")+'/src/tarantool'), "tarantool")
+sys.stdout.push_filter(re.escape(os.getenv("SOURCEDIR")+"/src/tarantool"), "tarantool")
 sys.stdout.push_filter(re.escape(os.getenv("SOURCEDIR")), "${SOURCEDIR}")
 sys.stdout.push_filter("invalid option.*", "invalid option")
 sys.stdout.push_filter("unrecognized option.*", "unrecognized option")
@@ -44,11 +44,11 @@ server.test_option(script + " --help 1 2 3")
 server.test_option("-V " + script + " 1 2 3")
 
 # gh-3966: os.exit() hangs if called by a command from the argument list.
-server.test_option("-e \"print(1) os.exit() print(2)\"")
-server.test_option("-e \"print(1)\" -e \"os.exit()\" -e \"print(1)\" -e \"os.exit()\" -e \"print(1)\"")
+server.test_option("-e 'print(1) os.exit() print(2)'")
+server.test_option("-e 'print(1)' -e 'os.exit()' -e 'print(1)' -e 'os.exit()' -e 'print(1)'")
 
 server.test_option("-e \"print('Hello')\" " + script + " 1 2 3")
-server.test_option("-e \"a = 10\" " + \
+server.test_option("-e 'a = 10' " + \
                    "-e print(a) " + \
                    script + \
                    " 1 2 3 --help")
diff --git a/test/box-py/bad_trigger.test.py b/test/box-py/bad_trigger.test.py
index 7d200b921..9dd6e17c9 100644
--- a/test/box-py/bad_trigger.test.py
+++ b/test/box-py/bad_trigger.test.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 from lib.box_connection import BoxConnection
 from lib.tarantool_connection import TarantoolConnection
 from tarantool import NetworkError
@@ -6,11 +8,11 @@ from tarantool.const import IPROTO_GREETING_SIZE, IPROTO_CODE, IPROTO_ERROR, \
 import socket
 import msgpack
 
-print """
+print("""
  #
  # if on_connect() trigger raises an exception, the connection is dropped
  #
- """
+ """)
 
 # silence possible error of strict mode
 server.admin("nosuchfunction = nil")
@@ -24,12 +26,12 @@ conn.connect()
 s = conn.socket
 
 # Read greeting
-print 'greeting: ', len(s.recv(IPROTO_GREETING_SIZE)) == IPROTO_GREETING_SIZE
+print("greeting:  {}".format(len(s.recv(IPROTO_GREETING_SIZE)) == IPROTO_GREETING_SIZE))
 
 # Read error packet
 IPROTO_FIXHEADER_SIZE = 5
 fixheader = s.recv(IPROTO_FIXHEADER_SIZE)
-print 'fixheader: ', len(fixheader) == IPROTO_FIXHEADER_SIZE
+print("fixheader:  {}".format(len(fixheader) == IPROTO_FIXHEADER_SIZE))
 unpacker.feed(fixheader)
 packet_len = unpacker.unpack()
 packet = s.recv(packet_len)
@@ -38,9 +40,9 @@ unpacker.feed(packet)
 # Parse packet
 header = unpacker.unpack()
 body = unpacker.unpack()
-print 'error code', (header[IPROTO_CODE] & (REQUEST_TYPE_ERROR - 1))
-print 'error message: ', body[IPROTO_ERROR]
-print 'eof:', len(s.recv(1024)) == 0
+print("error code {}".format((header[IPROTO_CODE] & (REQUEST_TYPE_ERROR - 1))))
+print("error message:  {}".format(body[IPROTO_ERROR]))
+print("eof: {}".format(len(s.recv(1024)) == 0))
 s.close()
 
 server.admin("box.session.on_connect(nil, f1)")
diff --git a/test/box-py/bootstrap.test.py b/test/box-py/bootstrap.test.py
index 63c13e8a4..33a93d24e 100644
--- a/test/box-py/bootstrap.test.py
+++ b/test/box-py/bootstrap.test.py
@@ -1,11 +1,11 @@
-server.admin('box.internal.bootstrap()')
-server.admin('box.space._schema:select{}')
-server.admin('box.space._cluster:select{}')
-server.admin('box.space._space:select{}')
-server.admin('box.space._index:select{}')
-server.admin('box.space._user:select{}')
-server.admin('for _, v in box.space._func:pairs{} do r = {} table.insert(r, v:update({{"=", 18, ""}, {"=", 19, ""}})) return r end')
-server.admin('box.space._priv:select{}')
+server.admin("box.internal.bootstrap()")
+server.admin("box.space._schema:select{}")
+server.admin("box.space._cluster:select{}")
+server.admin("box.space._space:select{}")
+server.admin("box.space._index:select{}")
+server.admin("box.space._user:select{}")
+server.admin("for _, v in box.space._func:pairs{} do r = {} table.insert(r, v:update({{\"=\", 18, \"\"}, {\"=\", 19, \"\"}})) return r end")
+server.admin("box.space._priv:select{}")
 
 # Cleanup
 server.stop()
diff --git a/test/box-py/call.test.py b/test/box-py/call.test.py
index 974ba0cac..ed25cc319 100644
--- a/test/box-py/call.test.py
+++ b/test/box-py/call.test.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import os
 import sys
 
@@ -6,9 +8,9 @@ def call(name, *args):
 
 admin("box.schema.user.create('test', { password = 'test' })")
 admin("box.schema.user.grant('test', 'execute,read,write', 'universe')")
-iproto.authenticate('test', 'test')
+iproto.authenticate("test", "test")
 # workaround for gh-770 centos 6 float representation
-admin('exp_notation = 1e123')
+admin("exp_notation = 1e123")
 admin("function f1() return 'testing', 1, false, -1, 1.123, math.abs(exp_notation - 1e123) < 0.1, nil end")
 admin("f1()")
 call("f1")
@@ -19,13 +21,13 @@ call("f1")
 
 # A test case for https://github.com/tarantool/tarantool/issues/44
 # IPROTO required!
-call("box.error", 33333, 'Hey!')
+call("box.error", 33333, "Hey!")
 
-print """
+print("""
 # A test case for Bug#103491
 # server CALL processing bug with name path longer than two
 # https://bugs.launchpad.net/tarantool/+bug/1034912
-"""
+""")
 admin("f = function() return 'OK' end")
 admin("test = {}")
 admin("test.f = f")
@@ -35,11 +37,11 @@ call("f")
 call("test.f")
 call("test.test.f")
 
-print """
+print("""
 # Test for Bug #955226
 # Lua Numbers are passed back wrongly as strings
 #
-"""
+""")
 admin("function foo() return 1, 2, '1', '2' end")
 call("foo")
 
@@ -48,8 +50,8 @@ call("foo")
 #
 admin("function f1(...) return {...} end")
 admin("function f2(...) return f1({...}) end")
-call("f1", 'test_', 'test_')
-call("f2", 'test_', 'test_')
+call("f1", "test_", "test_")
+call("f2", "test_", "test_")
 call("f1")
 call("f2")
 #
@@ -72,8 +74,8 @@ call("f3")
 admin("function f3() return { { test={1,2,3} }, { test2={1,2,3} } } end")
 call("f3")
 
-call("f1", 'jason')
-call("f1", 'jason', 1, 'test', 2, 'stewart')
+call("f1", "jason")
+call("f1", "jason", 1, "test", 2, "stewart")
 
 admin("space = box.schema.space.create('tweedledum')")
 admin("index = space:create_index('primary', { type = 'hash' })")
@@ -81,30 +83,30 @@ admin("index = space:create_index('primary', { type = 'hash' })")
 admin("function myreplace(...) return space:replace{...} end")
 admin("function myinsert(...) return space:insert{...} end")
 
-call("myinsert", 1, 'test box delete')
+call("myinsert", 1, "test box delete")
 call("space:delete", 1)
-call("myinsert", 1, 'test box delete')
+call("myinsert", 1, "test box delete")
 call("space:delete", 1)
 call("space:delete", 1)
-call("myinsert", 2, 'test box delete')
+call("myinsert", 2, "test box delete")
 call("space:delete", 1)
 call("space:delete", 2)
 call("space:delete", 2)
 admin("space:delete{2}")
 
-call("myinsert", 2, 'test box delete')
+call("myinsert", 2, "test box delete")
 call("space:get", 2)
 admin("space:delete{2}")
 call("space:get", 2)
-call("myinsert", 2, 'test box.select()')
+call("myinsert", 2, "test box.select()")
 call("space:get", 2)
 call("space:select", 2)
 admin("space:get{2}")
 admin("space:select{2}")
 admin("space:get{1}")
 admin("space:select{1}")
-call("myreplace", 2, 'hello', 'world')
-call("myreplace", 2, 'goodbye', 'universe')
+call("myreplace", 2, "hello", "world")
+call("myreplace", 2, "goodbye", "universe")
 call("space:get", 2)
 call("space:select", 2)
 admin("space:get{2}")
@@ -114,9 +116,9 @@ call("space:get", 2)
 call("space:select", 2)
 call("space:delete", 2)
 call("space:delete", 2)
-call("myinsert", 3, 'old', 2)
+call("myinsert", 3, "old", 2)
 # test that insert produces a duplicate key error
-call("myinsert", 3, 'old', 2)
+call("myinsert", 3, "old", 2)
 admin("space:update({3}, {{'=', 1, 4}, {'=', 2, 'new'}})")
 admin("space:insert(space:get{3}:update{{'=', 1, 4}, {'=', 2, 'new'}}) space:delete{3}")
 call("space:get", 4)
@@ -136,19 +138,19 @@ admin("index = space:create_index('primary', { type = 'tree' })")
 
 
 def lua_eval(name, *args):
-    print 'eval (%s)(%s)' % (name, ','.join([ str(arg) for arg in args]))
-    print '---'
-    print iproto.py_con.eval(name, args)
+    print("eval ({})({})".format(name, ",".join([ str(arg) for arg in args])))
+    print("---")
+    print(iproto.py_con.eval(name, args))
 
 def lua_call(name, *args):
-    print 'call %s(%s)' % (name, ','.join([ str(arg) for arg in args]))
-    print '---'
-    print iproto.py_con.call(name, args)
+    print("call {}({})".format(name, ",".join([ str(arg) for arg in args])))
+    print("---")
+    print(iproto.py_con.call(name, args))
 
 def test(expr, *args):
-    lua_eval('return ' + expr, *args)
-    admin('function f(...) return ' + expr + ' end')
-    lua_call('f', *args)
+    lua_eval("return " + expr, *args)
+    admin("function f(...) return " + expr + " end")
+    lua_call("f", *args)
 
 # Return values
 test("1")
@@ -172,18 +174,18 @@ test("{t}")
 test("{t, t, t}")
 test("error('exception')")
 test("box.error(0)")
-test('...')
-test('...', 1, 2, 3)
-test('...',  None, None, None)
-test('...', { 'k1': 'v1', 'k2': 'v2'})
+test("...")
+test("...", 1, 2, 3)
+test("...",  None, None, None)
+test("...", { "k1": "v1", "k2": "v2"})
 # Transactions
-test('space:auto_increment({"transaction"})')
-test('space:select{}')
-test('box.begin(), space:auto_increment({"failed"}), box.rollback()')
-test('space:select{}')
-test('require("fiber").sleep(0)')
+test("space:auto_increment({\"transaction\"})")
+test("space:select{}")
+test("box.begin(), space:auto_increment({\"failed\"}), box.rollback()")
+test("space:select{}")
+test("require(\"fiber\").sleep(0)")
 # Other
-lua_eval('!invalid expression')
+lua_eval("!invalid expression")
 
 admin("space:drop()")
 admin("box.schema.user.drop('test')")
diff --git a/test/box-py/iproto.test.py b/test/box-py/iproto.test.py
index cdd1a71c5..6ed49051b 100644
--- a/test/box-py/iproto.test.py
+++ b/test/box-py/iproto.test.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import os
 import sys
 import struct
@@ -11,32 +13,32 @@ from lib.tarantool_connection import TarantoolConnection
 
 admin("box.schema.user.grant('guest', 'read,write,execute', 'universe')")
 
-print """
+print("""
 #
 # iproto packages test
 #
-"""
+""")
 
 # opeing new connection to tarantool/box
 conn = TarantoolConnection(server.iproto.host, server.iproto.port)
 conn.connect()
 s = conn.socket
 
-print """
+print("""
 # Test bug #899343 (server assertion failure on incorrect packet)
-"""
-print "# send the package with invalid length"
-invalid_request = struct.pack('<LLL', 1, 4294967290, 1)
-print s.send(invalid_request)
-print "# check that is server alive"
-print iproto.py_con.ping() > 0
+""")
+print("# send the package with invalid length")
+invalid_request = struct.pack("<LLL", 1, 4294967290, 1)
+print(s.send(invalid_request))
+print("# check that is server alive")
+print(iproto.py_con.ping() > 0)
 
 # closing connection
 s.close()
 
 key_names = {}
 for (k,v) in globals().items():
-    if type(k) == str and k.startswith('IPROTO_') and type(v) == int:
+    if type(k) == str and k.startswith("IPROTO_") and type(v) == int:
         key_names[v] = k
 
 def repr_dict(todump):
@@ -48,9 +50,9 @@ def repr_dict(todump):
 
 def test(header, body):
     # Connect and authenticate
-    c = Connection('localhost', server.iproto.port)
+    c = Connection("localhost", server.iproto.port)
     c.connect()
-    print 'query', repr_dict(header), repr_dict(body)
+    print("query", repr_dict(header), repr_dict(body))
     header = msgpack.dumps(header)
     body = msgpack.dumps(body)
     query = msgpack.dumps(len(header) + len(body)) + header + body
@@ -59,36 +61,36 @@ def test(header, body):
     try:
         s.send(query)
     except OSError as e:
-        print '   => ', 'Failed to send request'
+        print("   => ", "Failed to send request")
     c.close()
-    print iproto.py_con.ping() > 0
+    print(iproto.py_con.ping() > 0)
 
-print """
+print("""
 #  Test gh-206 "Segfault if sending IPROTO package without `KEY` field"
-"""
+""")
 
-print "IPROTO_SELECT"
+print("IPROTO_SELECT")
 test({ IPROTO_CODE : REQUEST_TYPE_SELECT }, { IPROTO_SPACE_ID: 280 })
-print "\n"
+print("\n")
 
-print "IPROTO_DELETE"
+print("IPROTO_DELETE")
 test({ IPROTO_CODE : REQUEST_TYPE_DELETE }, { IPROTO_SPACE_ID: 280 })
-print "\n"
+print("\n")
 
-print "IPROTO_UPDATE"
+print("IPROTO_UPDATE")
 test({ IPROTO_CODE : REQUEST_TYPE_UPDATE }, { IPROTO_SPACE_ID: 280 })
 test({ IPROTO_CODE : REQUEST_TYPE_UPDATE },
      { IPROTO_SPACE_ID: 280, IPROTO_KEY: (1, )})
-print "\n"
+print("\n")
 
-print "IPROTO_REPLACE"
+print("IPROTO_REPLACE")
 test({ IPROTO_CODE : REQUEST_TYPE_REPLACE }, { IPROTO_SPACE_ID: 280 })
-print "\n"
+print("\n")
 
-print "IPROTO_CALL"
+print("IPROTO_CALL")
 test({ IPROTO_CODE : REQUEST_TYPE_CALL }, {})
-test({ IPROTO_CODE : REQUEST_TYPE_CALL }, { IPROTO_KEY: ('procname', )})
-print "\n"
+test({ IPROTO_CODE : REQUEST_TYPE_CALL }, { IPROTO_KEY: ("procname", )})
+print("\n")
 
 # gh-434 Tarantool crashes on multiple iproto requests with WAL enabled
 admin("box.cfg.wal_mode")
@@ -96,7 +98,7 @@ admin("space = box.schema.space.create('test', { id = 567 })")
 admin("index = space:create_index('primary', { type = 'hash' })")
 admin("box.schema.user.grant('guest', 'read,write,execute', 'space', 'test')")
 
-c = Connection('localhost', server.iproto.port)
+c = Connection("localhost", server.iproto.port)
 c.connect()
 request1 = RequestInsert(c, 567, [1, "baobab"])
 request2 = RequestInsert(c, 567, [2, "obbaba"])
@@ -104,11 +106,11 @@ s = c._socket
 try:
     s.send(bytes(request1) + bytes(request2))
 except OSError as e:
-    print '   => ', 'Failed to send request'
+    print("   => ", "Failed to send request")
 response1 = Response(c, c._read_response())
 response2 = Response(c, c._read_response())
-print response1.__str__()
-print response2.__str__()
+print(response1.__str__())
+print(response2.__str__())
 
 request1 = RequestInsert(c, 567, [3, "occama"])
 request2 = RequestSelect(c, 567, 0, [1], 0, 1, 0)
@@ -116,11 +118,11 @@ s = c._socket
 try:
     s.send(bytes(request1) + bytes(request2))
 except OSError as e:
-    print '   => ', 'Failed to send request'
+    print("   => ", "Failed to send request")
 response1 = Response(c, c._read_response())
 response2 = Response(c, c._read_response())
-print response1.__str__()
-print response2.__str__()
+print(response1.__str__())
+print(response2.__str__())
 
 request1 = RequestSelect(c, 567, 0, [2], 0, 1, 0)
 request2 = RequestInsert(c, 567, [4, "ockham"])
@@ -128,11 +130,11 @@ s = c._socket
 try:
     s.send(bytes(request1) + bytes(request2))
 except OSError as e:
-    print '   => ', 'Failed to send request'
+    print("   => ", "Failed to send request")
 response1 = Response(c, c._read_response())
 response2 = Response(c, c._read_response())
-print response1.__str__()
-print response2.__str__()
+print(response1.__str__())
+print(response2.__str__())
 
 request1 = RequestSelect(c, 567, 0, [1], 0, 1, 0)
 request2 = RequestSelect(c, 567, 0, [2], 0, 1, 0)
@@ -140,11 +142,11 @@ s = c._socket
 try:
     s.send(bytes(request1) + bytes(request2))
 except OSError as e:
-    print '   => ', 'Failed to send request'
+    print("   => ", "Failed to send request")
 response1 = Response(c, c._read_response())
 response2 = Response(c, c._read_response())
-print response1.__str__()
-print response2.__str__()
+print(response1.__str__())
+print(response2.__str__())
 
 c.close()
 
@@ -176,7 +178,7 @@ class RawSelect(Request):
         self._body = request_body
 
 c = iproto.py_con
-space = c.space('test')
+space = c.space("test")
 space_id = space.space_no
 
 TESTS = [
@@ -192,34 +194,34 @@ TESTS = [
 for test in TESTS:
     it = iter(test)
     size = next(it)
-    print 'STR', size
-    print '--'
+    print("STR", size)
+    print("--")
     for fmt in it:
-        print '0x' + fmt.encode('hex'), '=>',
-        field = '*' * size
+        print("0x" + fmt.encode("hex"), "=>", end=" ")
+        field = "*" * size
         c._send_request(RawInsert(c, space_id, "\x91" + fmt + field))
         tuple = space.select(field)[0]
-        print len(tuple[0])== size and 'ok' or 'fail',
+        print(len(tuple[0])== size and "ok" or "fail", end=" ")
         it2 = iter(test)
         next(it2)
         for fmt2 in it2:
             tuple = c._send_request(RawSelect(c, space_id,
                 "\x91" + fmt2 + field))[0]
-            print len(tuple[0]) == size and 'ok' or 'fail',
+            print(len(tuple[0]) == size and "ok" or "fail", end=" ")
         tuple = space.delete(field)[0]
-        print len(tuple[0]) == size and 'ok' or 'fail',
-        print
-    print
+        print(len(tuple[0]) == size and "ok" or "fail", end="")
+        print()
+    print()
 
 
-print 'Test of schema_id in iproto.'
-c = Connection('localhost', server.iproto.port)
+print("Test of schema_id in iproto.")
+c = Connection("localhost", server.iproto.port)
 c.connect()
 s = c._socket
 
 def receive_response():
-    resp_len = ''
-    resp_headerbody = ''
+    resp_len = ""
+    resp_headerbody = ""
     resp_header = {}
     resp_body = {}
     try:
@@ -235,10 +237,10 @@ def receive_response():
         resp_header = unpacker.unpack()
         resp_body = unpacker.unpack()
     except OSError as e:
-        print '   => ', 'Failed to recv response'
+        print("   => ", "Failed to recv response")
     res = {}
-    res['header'] = resp_header
-    res['body'] = resp_body
+    res["header"] = resp_header
+    res["body"] = resp_body
     return res
 
 def test_request(req_header, req_body):
@@ -249,7 +251,7 @@ def test_request(req_header, req_body):
     try:
         s.send(query)
     except OSError as e:
-        print '   => ', 'Failed to send request'
+        print("   => ", "Failed to send request")
     return receive_response()
 
 header = { IPROTO_CODE : REQUEST_TYPE_SELECT}
@@ -260,62 +262,62 @@ body = { IPROTO_SPACE_ID: space_id,
     IPROTO_OFFSET: 0,
     IPROTO_LIMIT: 1 }
 resp = test_request(header, body)
-print 'Normal connect done w/o errors:', resp['header'][0] == 0
-print 'Got schema_id:', resp['header'][5] > 0
-schema_id = resp['header'][5]
+print("Normal connect done w/o errors:", resp["header"][0] == 0)
+print("Got schema_id:", resp["header"][5] > 0)
+schema_id = resp["header"][5]
 
 header = { IPROTO_CODE : REQUEST_TYPE_SELECT, 5 : 0 }
 resp = test_request(header, body)
-print 'Zero-schema_id connect done w/o errors:', resp['header'][0] == 0
-print 'Same schema_id:', resp['header'][5] == schema_id
+print("Zero-schema_id connect done w/o errors:", resp["header"][0] == 0)
+print("Same schema_id:", resp["header"][5] == schema_id)
 
 header = { IPROTO_CODE : REQUEST_TYPE_SELECT, 5 : schema_id }
 resp = test_request(header, body)
-print 'Normal connect done w/o errors:', resp['header'][0] == 0
-print 'Same schema_id:', resp['header'][5] == schema_id
+print("Normal connect done w/o errors:", resp["header"][0] == 0)
+print("Same schema_id:", resp["header"][5] == schema_id)
 
 header = { IPROTO_CODE : REQUEST_TYPE_SELECT, 5 : schema_id + 1 }
 resp = test_request(header, body)
-print 'Wrong schema_id leads to error:', resp['header'][0] != 0
-print 'Same schema_id:', resp['header'][5] == schema_id
+print("Wrong schema_id leads to error:", resp["header"][0] != 0)
+print("Same schema_id:", resp["header"][5] == schema_id)
 
 admin("space2 = box.schema.create_space('test2')")
 
 header = { IPROTO_CODE : REQUEST_TYPE_SELECT, 5 : schema_id }
 resp = test_request(header, body)
-print 'Schema changed -> error:', resp['header'][0] != 0
-print 'Got another schema_id:', resp['header'][5] != schema_id
+print("Schema changed -> error:", resp["header"][0] != 0)
+print("Got another schema_id:", resp["header"][5] != schema_id)
 
 #
 # gh-2334 Lost SYNC in JOIN response.
 #
-uuid = '0d5bd431-7f3e-4695-a5c2-82de0a9cbc95'
+uuid = "0d5bd431-7f3e-4695-a5c2-82de0a9cbc95"
 header = { IPROTO_CODE: REQUEST_TYPE_JOIN, IPROTO_SYNC: 2334 }
 body = { IPROTO_SERVER_UUID: uuid }
 resp = test_request(header, body)
-if resp['header'][IPROTO_SYNC] == 2334:
+if resp["header"][IPROTO_SYNC] == 2334:
     i = 1
     while i < 3:
         resp = receive_response()
-        if resp['header'][IPROTO_SYNC] != 2334:
-            print 'Bad sync on response with number ', i
+        if resp["header"][IPROTO_SYNC] != 2334:
+            print("Bad sync on response with number ", i)
             break
-        if resp['header'][IPROTO_CODE] == REQUEST_TYPE_OK:
+        if resp["header"][IPROTO_CODE] == REQUEST_TYPE_OK:
             i += 1
     else:
-        print 'Sync ok'
+        print("Sync ok")
 else:
-    print 'Bad first sync'
+    print("Bad first sync")
 
 #
 # Try incorrect JOIN. SYNC must be also returned.
 #
-body[IPROTO_SERVER_UUID] = 'unknown'
+body[IPROTO_SERVER_UUID] = "unknown"
 resp = test_request(header, body)
-if resp['header'][IPROTO_SYNC] == 2334:
-    print('Sync on error is ok')
+if resp["header"][IPROTO_SYNC] == 2334:
+    print("Sync on error is ok")
 else:
-    print('Sync on error is not ok')
+    print("Sync on error is not ok")
 
 c.close()
 
@@ -332,8 +334,8 @@ admin("space:insert({1})")
 admin("space:insert({2, 'Music'})")
 admin("space:insert({3, 'Length', 93})")
 
-iproto.py_con.space('gh1280').select([])
-iproto.py_con.space('gh1280').select(list())
+iproto.py_con.space("gh1280").select([])
+iproto.py_con.space("gh1280").select(list())
 
 
 admin("space:drop()")
@@ -344,26 +346,26 @@ admin("box.schema.user.revoke('guest', 'read,write,execute', 'universe')")
 # gh-272 if the packet was incorrect, respond with an error code
 # gh-1654 do not close connnection on invalid request
 #
-print """
+print("""
 # Test bugs gh-272, gh-1654 if the packet was incorrect, respond with
 # an error code and do not close connection
-"""
+""")
 
-c = Connection('localhost', server.iproto.port)
+c = Connection("localhost", server.iproto.port)
 c.connect()
 s = c._socket
 header = { "hello": "world"}
 body = { "bug": 272 }
 resp = test_request(header, body)
-print 'sync=%d, %s' % (resp['header'][IPROTO_SYNC], resp['body'].get(IPROTO_ERROR))
+print("sync={}, {}".format(resp["header"][IPROTO_SYNC], resp["body"].get(IPROTO_ERROR)))
 header = { IPROTO_CODE : REQUEST_TYPE_SELECT }
 header[IPROTO_SYNC] = 1234
 resp = test_request(header, body)
-print 'sync=%d, %s' % (resp['header'][IPROTO_SYNC], resp['body'].get(IPROTO_ERROR))
+print("sync={}, {}".format(resp["header"][IPROTO_SYNC], resp["body"].get(IPROTO_ERROR)))
 header[IPROTO_SYNC] = 5678
 body = { IPROTO_SPACE_ID: 304, IPROTO_KEY: [], IPROTO_LIMIT: 1 }
 resp = test_request(header, body)
-print 'sync=%d, %s' % (resp['header'][IPROTO_SYNC], resp['body'].get(IPROTO_ERROR))
+print("sync={}, {}".format(resp["header"][IPROTO_SYNC], resp["body"].get(IPROTO_ERROR)))
 c.close()
 
 
@@ -371,7 +373,7 @@ admin("space = box.schema.space.create('test_index_base', { id = 568 })")
 admin("index = space:create_index('primary', { type = 'hash' })")
 admin("box.schema.user.grant('guest', 'read,write,execute', 'space', 'test_index_base')")
 
-c = Connection('localhost', server.iproto.port)
+c = Connection("localhost", server.iproto.port)
 c.connect()
 s = c._socket
 
@@ -379,32 +381,32 @@ request = RequestInsert(c, 568, [1, 0, 0, 0])
 try:
     s.send(bytes(request))
 except OSError as e:
-    print '   => ', 'Failed to send request'
+    print("   => ", "Failed to send request")
 response = Response(c, c._read_response())
-print response.__str__()
+print(response.__str__())
 
-request = RequestUpdate(c, 568, 0, [1], [['+', 2, 1], ['-', 3, 1]])
+request = RequestUpdate(c, 568, 0, [1], [["+", 2, 1], ["-", 3, 1]])
 try:
     s.send(bytes(request))
 except OSError as e:
-    print '   => ', 'Failed to send request'
+    print("   => ", "Failed to send request")
 response = Response(c, c._read_response())
-print response.__str__()
+print(response.__str__())
 
-request = RequestUpsert(c, 568, 0, [1, 0, 0, 0], [['+', 2, 1], ['-', 3, 1]])
+request = RequestUpsert(c, 568, 0, [1, 0, 0, 0], [["+", 2, 1], ["-", 3, 1]])
 try:
     s.send(bytes(request))
 except OSError as e:
-    print '   => ', 'Failed to send request'
+    print("   => ", "Failed to send request")
 response = Response(c, c._read_response())
 
 request = RequestSelect(c, 568, 0, [1], 0, 1, 0)
 try:
     s.send(bytes(request))
 except OSError as e:
-    print '   => ', 'Failed to send request'
+    print("   => ", "Failed to send request")
 response = Response(c, c._read_response())
-print response.__str__()
+print(response.__str__())
 
 c.close()
 
@@ -414,15 +416,15 @@ c.close()
 admin("function kek() return 'kek' end")
 admin("box.schema.user.grant('guest', 'read,write,execute', 'universe')")
 
-c = Connection('localhost', server.iproto.port)
+c = Connection("localhost", server.iproto.port)
 c.connect()
 s = c._socket
 
 header = { IPROTO_CODE: REQUEST_TYPE_CALL, IPROTO_SYNC: 100 }
-body = { IPROTO_FUNCTION_NAME: 'kek' }
+body = { IPROTO_FUNCTION_NAME: "kek" }
 resp = test_request(header, body)
-print "Sync: ", resp['header'][IPROTO_SYNC]
-print "Retcode: ", resp['body'][IPROTO_DATA]
+print("Sync: ", resp["header"][IPROTO_SYNC])
+print("Retcode: ", resp["body"][IPROTO_DATA])
 
 c.close()
 
diff --git a/test/box-py/print.test.py b/test/box-py/print.test.py
index 5083bdf42..97739f85c 100644
--- a/test/box-py/print.test.py
+++ b/test/box-py/print.test.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import tarantool
 
 import sys
@@ -6,7 +8,7 @@ import re
 
 log = server.get_log()
 
-admin('print("Hello, world")')
+admin("print(\"Hello, world\")")
 admin("io = require('io')")
 
 admin("""local f = require('fiber').create(
@@ -18,17 +20,18 @@ admin("""local f = require('fiber').create(
 admin("require('fiber').sleep(0.01)")
 
 print("Check log line (Hello):")
-print('---')
-if log.seek_once('Hello') >= 0:
-    print('- "logfile contains "Hello""')
+print("---")
+if log.seek_once("Hello") >= 0:
+    print("- \"logfile contains \"Hello\"\"")
 else:
-    print('- "logfile does not contain "Hello""')
-print('...')
+    print("- 'logfile does not contain 'Hello''")
+print("...")
 
 print("Check log line (Ehllo):")
-print('---')
-if log.seek_once('Ehllo') >= 0:
-    print('- "logfile contains "Ehllo""')
+print("---")
+if log.seek_once("Ehllo") >= 0:
+    print("- \"logfile contains \"Ehllo\"\"")
 else:
-    print('- "logfile does not contain "Ehllo""')
-print('...')
+    print("- \"logfile does not contain \"Ehllo\"\"")
+
+print("...")
diff --git a/test/box-py/snapshot.test.py b/test/box-py/snapshot.test.py
index 2bfb8f621..e34126ed2 100644
--- a/test/box-py/snapshot.test.py
+++ b/test/box-py/snapshot.test.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import os
 import sys
 import yaml
@@ -9,13 +11,14 @@ sys.stdout.push_filter(server.vardir, "<dir>")
 admin("space = box.schema.space.create('tweedledum')")
 admin("index = space:create_index('primary', { type = 'hash' })")
 
-print """#
+print("""#
 # A test case for: http://bugs.launchpad.net/bugs/686411
 # Check that 'box.snapshot()' does not overwrite a snapshot
 # file that already exists. Verify also that any other
 # error that happens when saving snapshot is propagated
 # to the caller.
-"""
+""")
+
 admin("space:insert{1, 'first tuple'}")
 admin("box.snapshot()")
 #
@@ -38,14 +41,14 @@ os.rmdir(snapshot)
 admin("space:delete{1}")
 admin("space:delete{2}")
 
-print """#
+print("""#
 # A test case for http://bugs.launchpad.net/bugs/727174
 # "tarantool_box crashes when saving snapshot on SIGUSR1"
-#"""
+#""")
 
-print """
+print("""
 # Increment the lsn number, to make sure there is no such snapshot yet
-#"""
+#""")
 
 admin("space:insert{1, 'Test tuple'}")
 
@@ -65,9 +68,9 @@ while not os.access(snapshot, os.F_OK) and iteration < MAX_ITERATIONS:
   iteration = iteration + 1
 
 if iteration == 0 or iteration >= MAX_ITERATIONS:
-  print "Snapshot is missing."
+  print("Snapshot is missing.")
 else:
-  print "Snapshot exists."
+  print("Snapshot exists.")
 
 admin("space:drop()")
 
diff --git a/test/long_run-py/finalizers.test.py b/test/long_run-py/finalizers.test.py
index 96118e607..faddc7de1 100644
--- a/test/long_run-py/finalizers.test.py
+++ b/test/long_run-py/finalizers.test.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import os
 import sys
 import re
@@ -5,12 +7,12 @@ import yaml
 from lib.tarantool_server import TarantoolServer
 
 server = TarantoolServer(server.ini)
-server.script = 'long_run-py/lua/finalizers.lua'
-server.vardir = os.path.join(server.vardir, 'finalizers')
+server.script = "long_run-py/lua/finalizers.lua"
+server.vardir = os.path.join(server.vardir, "finalizers")
 server.crash_expected = True
 try:
     server.deploy()
 except:
-    print "Expected error:", sys.exc_info()[0]
+    print("Expected error:", sys.exc_info()[0])
 else:
-    print "Error! exception did not occur"
+    print("Error! exception did not occur")
diff --git a/test/replication-py/cluster.test.py b/test/replication-py/cluster.test.py
index 088ca9c34..a796046c4 100644
--- a/test/replication-py/cluster.test.py
+++ b/test/replication-py/cluster.test.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import os
 import sys
 import re
@@ -7,19 +9,19 @@ import glob
 from lib.tarantool_server import TarantoolServer
 
 ## Get cluster uuid
-cluster_uuid = ''
+cluster_uuid = ""
 try:
     cluster_uuid = yaml.safe_load(server.admin("box.space._schema:get('cluster')",
         silent = True))[0][1]
-    uuid.UUID('{' + cluster_uuid + '}')
-    print 'ok - cluster uuid'
+    uuid.UUID("{" + cluster_uuid + "}")
+    print("ok - cluster uuid")
 except Exception as e:
-    print 'not ok - invalid cluster uuid', e
+    print("not ok - invalid cluster uuid", e)
 
 server.iproto.reconnect() # re-connect with new permissions
-print '-------------------------------------------------------------'
-print ' gh-696: Check global READ permissions for replication'
-print '-------------------------------------------------------------'
+print("-------------------------------------------------------------")
+print(" gh-696: Check global READ permissions for replication")
+print("-------------------------------------------------------------")
 
 
 # Generate replica cluster UUID
@@ -27,56 +29,59 @@ replica_uuid = str(uuid.uuid4())
 
 ## Universal read permission is required to perform JOIN/SUBSCRIBE
 rows = list(server.iproto.py_con.join(replica_uuid))
-print len(rows) == 1 and rows[0].return_message.find('Read access') >= 0 and \
-    'ok' or 'not ok', '-', 'join without read permissions on universe'
+status = len(rows) == 1 and rows[0].return_message.find("Read access") >= 0 and \
+    "ok" or "not ok"
+print("{} - join without read permissions on universe".format(status))
 rows = list(server.iproto.py_con.subscribe(cluster_uuid, replica_uuid))
-print len(rows) == 1 and rows[0].return_message.find('Read access') >= 0 and \
-    'ok' or 'not ok', '-', 'subscribe without read permissions on universe'
+status = len(rows) == 1 and rows[0].return_message.find("Read access") >= 0 and \
+    "ok" or "not ok"
+print("{} - subscribe without read permissions on universe".format(status))
 ## Write permission to space `_cluster` is required to perform JOIN
 server.admin("box.schema.user.grant('guest', 'read', 'universe')")
 server.iproto.reconnect() # re-connect with new permissions
 rows = list(server.iproto.py_con.join(replica_uuid))
-print len(rows) == 1 and rows[0].return_message.find('Write access') >= 0 and \
-    'ok' or 'not ok', '-', 'join without write permissions to _cluster'
+status = len(rows) == 1 and rows[0].return_message.find("Write access") >= 0 and \
+    "ok" or "not ok"
+print("{} - join without write permissions to _cluster".format(status))
 
 def check_join(msg):
     ok = True
     for resp in server.iproto.py_con.join(replica_uuid):
         if resp._return_code != 0:
-            print 'not ok', '-', msg, resp.return_message
+            print("not ok - {} {}".format(msg, resp.return_message))
             ok = False
 
     server.iproto.reconnect() # the only way to stop JOIN
     if not ok:
         return
-    tuples = server.iproto.py_con.space('_cluster').select(replica_uuid, index = 1)
+    tuples = server.iproto.py_con.space("_cluster").select(replica_uuid, index = 1)
     if len(tuples) == 0:
-        print 'not ok', '-', msg, 'missing entry in _cluster'
+        print("not ok - {} missing entry in _cluster".format(msg))
         return
     server_id = tuples[0][0]
-    print 'ok', '-', msg
+    print("ok - {}".format(msg))
     return server_id
 
 ## JOIN with permissions
 server.admin("box.schema.user.grant('guest', 'write', 'space', '_cluster')")
 server.iproto.reconnect() # re-connect with new permissions
-server_id = check_join('join with granted permissions')
-server.iproto.py_con.space('_cluster').delete(server_id)
+server_id = check_join("join with granted permissions")
+server.iproto.py_con.space("_cluster").delete(server_id)
 
 # JOIN with granted role
 server.admin("box.schema.user.revoke('guest', 'read', 'universe')")
 server.admin("box.schema.user.revoke('guest', 'write', 'space', '_cluster')")
 server.admin("box.schema.user.grant('guest', 'replication')")
 server.iproto.reconnect() # re-connect with new permissions
-server_id = check_join('join with granted role')
-server.iproto.py_con.space('_cluster').delete(server_id)
+server_id = check_join("join with granted role")
+server.iproto.py_con.space("_cluster").delete(server_id)
 
-print '-------------------------------------------------------------'
-print 'gh-434: Assertion if replace _cluster tuple for local server'
-print '-------------------------------------------------------------'
+print("-------------------------------------------------------------")
+print("gh-434: Assertion if replace _cluster tuple for local server")
+print("-------------------------------------------------------------")
 
-master_uuid = server.get_param('uuid')
-sys.stdout.push_filter(master_uuid, '<master uuid>')
+master_uuid = server.get_param("uuid")
+sys.stdout.push_filter(master_uuid, "<master uuid>")
 
 # Invalid UUID
 server.admin("box.space._cluster:replace{1, require('uuid').NULL:str()}")
@@ -87,19 +92,19 @@ server.admin("box.space._cluster:replace{1, require('uuid').str()}")
 # Update of tail is OK
 server.admin("box.space._cluster:update(1, {{'=', 3, 'test'}})")
 
-print '-------------------------------------------------------------'
-print 'gh-1140: Assertion if replace _cluster tuple for remote server'
-print '-------------------------------------------------------------'
+print("-------------------------------------------------------------")
+print("gh-1140: Assertion if replace _cluster tuple for remote server")
+print("-------------------------------------------------------------")
 
 # Test that insert is OK
-new_uuid = '0d5bd431-7f3e-4695-a5c2-82de0a9cbc95'
+new_uuid = "0d5bd431-7f3e-4695-a5c2-82de0a9cbc95"
 server.admin("box.space._cluster:insert{{5, '{0}'}}".format(new_uuid))
 server.admin("box.info.vclock[5] == nil")
 
 # Replace with the same UUID is OK
 server.admin("box.space._cluster:replace{{5, '{0}'}}".format(new_uuid))
 # Replace with a new UUID is not OK
-new_uuid = 'a48a19a3-26c0-4f8c-a5b5-77377bab389b'
+new_uuid = "a48a19a3-26c0-4f8c-a5b5-77377bab389b"
 server.admin("box.space._cluster:replace{{5, '{0}'}}".format(new_uuid))
 # Update of tail is OK
 server.admin("box.space._cluster:update(5, {{'=', 3, 'test'}})")
@@ -112,83 +117,83 @@ server.admin("box.info.vclock[5] == nil")
 server.stop()
 server.deploy()
 
-print '-------------------------------------------------------------'
-print 'Start a new replica and check box.info on the start'
-print '-------------------------------------------------------------'
+print("-------------------------------------------------------------")
+print("Start a new replica and check box.info on the start")
+print("-------------------------------------------------------------")
 # master server
 master = server
-master_id = master.get_param('id')
+master_id = master.get_param("id")
 
 master.admin("box.schema.user.grant('guest', 'replication')")
 
 replica = TarantoolServer(server.ini)
-replica.script = 'replication-py/replica.lua'
+replica.script = "replication-py/replica.lua"
 replica.vardir = server.vardir
 replica.rpl_master = master
 replica.deploy()
-replica_id = replica.get_param('id')
-replica_uuid = replica.get_param('uuid')
-sys.stdout.push_filter(replica_uuid, '<replica uuid>')
-
-replica.admin('box.info.id == %d' % replica_id)
-replica.admin('not box.info.ro')
-replica.admin('box.info.lsn == 0')
-replica.admin('box.info.vclock[%d] == nil' % replica_id)
-
-print '-------------------------------------------------------------'
-print 'Modify data to bump LSN and check box.info'
-print '-------------------------------------------------------------'
-replica.admin('box.space._schema:insert{"test", 48}')
-replica.admin('box.info.lsn == 1')
-replica.admin('box.info.vclock[%d] == 1' % replica_id)
-
-print '-------------------------------------------------------------'
-print 'Connect master to replica'
-print '-------------------------------------------------------------'
-replication_source = yaml.safe_load(replica.admin('box.cfg.listen', silent = True))[0]
-sys.stdout.push_filter(replication_source, '<replication_source>')
-master.admin("box.cfg{ replication_source = '%s' }" % replication_source)
+replica_id = replica.get_param("id")
+replica_uuid = replica.get_param("uuid")
+sys.stdout.push_filter(replica_uuid, "<replica uuid>")
+
+replica.admin("box.info.id == {}".format(replica_id))
+replica.admin("not box.info.ro")
+replica.admin("box.info.lsn == 0")
+replica.admin("box.info.vclock[{}] == nil".format(replica_id))
+
+print("-------------------------------------------------------------")
+print("Modify data to bump LSN and check box.info")
+print("-------------------------------------------------------------")
+replica.admin("box.space._schema:insert{\"test\", 48}")
+replica.admin("box.info.lsn == 1")
+replica.admin("box.info.vclock[{}] == 1".format(replica_id))
+
+print("-------------------------------------------------------------")
+print("Connect master to replica")
+print("-------------------------------------------------------------")
+replication_source = yaml.safe_load(replica.admin("box.cfg.listen", silent = True))[0]
+sys.stdout.push_filter(replication_source, "<replication_source>")
+master.admin("box.cfg{{ replication_source = '{}' }}".format(replication_source))
 master.wait_lsn(replica_id, replica.get_lsn(replica_id))
 
-print '-------------------------------------------------------------'
-print 'Disconnect replica from master'
-print '-------------------------------------------------------------'
-replica.admin('box.cfg { replication_source = "" }')
+print("-------------------------------------------------------------")
+print("Disconnect replica from master")
+print("-------------------------------------------------------------")
+replica.admin("box.cfg { replication_source = \"\" }")
 
-print '-------------------------------------------------------------'
-print 'Unregister replica'
-print '-------------------------------------------------------------'
+print("-------------------------------------------------------------")
+print("Unregister replica")
+print("-------------------------------------------------------------")
 
-master.admin('box.space._cluster:delete{%d} ~= nil' % replica_id)
+master.admin("box.space._cluster:delete{{{}}} ~= nil".format(replica_id))
 
 # gh-1219: LSN must not be removed from vclock on unregister
-master.admin('box.info.vclock[%d] == 1' % replica_id)
+master.admin("box.info.vclock[{}] == 1".format(replica_id))
 
-print '-------------------------------------------------------------'
-print 'Modify data to bump LSN on replica'
-print '-------------------------------------------------------------'
-replica.admin('box.space._schema:insert{"tost", 49}')
-replica.admin('box.info.lsn == 2')
-replica.admin('box.info.vclock[%d] == 2' % replica_id)
+print("-------------------------------------------------------------")
+print("Modify data to bump LSN on replica")
+print("-------------------------------------------------------------")
+replica.admin("box.space._schema:insert{\"tost\", 49}")
+replica.admin("box.info.lsn == 2")
+replica.admin("box.info.vclock[{}] == 2".format(replica_id))
 
-print '-------------------------------------------------------------'
-print 'Master must not crash then receives orphan rows from replica'
-print '-------------------------------------------------------------'
+print("-------------------------------------------------------------")
+print("Master must not crash then receives orphan rows from replica")
+print("-------------------------------------------------------------")
 
-replication_source = yaml.safe_load(replica.admin('box.cfg.listen', silent = True))[0]
-sys.stdout.push_filter(replication_source, '<replication>')
-master.admin("box.cfg{ replication = '%s' }" % replication_source)
+replication_source = yaml.safe_load(replica.admin("box.cfg.listen", silent = True))[0]
+sys.stdout.push_filter(replication_source, "<replication>")
+master.admin("box.cfg{{ replication = '{}' }}".format(replication_source))
 
 master.wait_lsn(replica_id, replica.get_lsn(replica_id))
-master.admin('box.info.vclock[%d] == 2' % replica_id)
+master.admin("box.info.vclock[{}] == 2".format(replica_id))
 
 master.admin("box.cfg{ replication = '' }")
 replica.stop()
 replica.cleanup()
 
-print '-------------------------------------------------------------'
-print 'Start a new replica and check that server_id, LSN is re-used'
-print '-------------------------------------------------------------'
+print("-------------------------------------------------------------")
+print("Start a new replica and check that server_id, LSN is re-used")
+print("-------------------------------------------------------------")
 
 #
 # gh-1219: Proper removal of servers with non-zero LSN from _cluster
@@ -196,36 +201,36 @@ print '-------------------------------------------------------------'
 # Snapshot is required. Otherwise a relay will skip records made by previous
 # replica with the re-used id.
 master.admin("box.snapshot()")
-master.admin('box.info.vclock[%d] == 2' % replica_id)
+master.admin("box.info.vclock[{}] == 2".format(replica_id))
 
 replica = TarantoolServer(server.ini)
-replica.script = 'replication-py/replica.lua'
+replica.script = "replication-py/replica.lua"
 replica.vardir = server.vardir
 replica.rpl_master = master
 replica.deploy()
 replica.wait_lsn(master_id, master.get_lsn(master_id))
 # Check that replica_id was re-used
-replica.admin('box.info.id == %d' % replica_id)
-replica.admin('not box.info.ro')
+replica.admin("box.info.id == {}".format(replica_id))
+replica.admin("not box.info.ro")
 # All records were succesfully recovered.
 # Replica should have the same vclock as master.
-master.admin('box.info.vclock[%d] == 2' % replica_id)
-replica.admin('box.info.vclock[%d] == 2' % replica_id)
+master.admin("box.info.vclock[{}] == 2".format(replica_id))
+replica.admin("box.info.vclock[{}] == 2".format(replica_id))
 
 replica.stop()
 replica.cleanup()
-master.admin('box.space._cluster:delete{%d} ~= nil' % replica_id)
+master.admin("box.space._cluster:delete{{{}}} ~= nil".format(replica_id))
 
-print '-------------------------------------------------------------'
-print 'JOIN replica to read-only master'
-print '-------------------------------------------------------------'
+print("-------------------------------------------------------------")
+print("JOIN replica to read-only master")
+print("-------------------------------------------------------------")
 
 # master server
 master = server
-master.admin('box.cfg { read_only = true }')
+master.admin("box.cfg { read_only = true }")
 #gh-1230 Assertion vclock_has on attempt to JOIN read-only master
 failed = TarantoolServer(server.ini)
-failed.script = 'replication-py/failed.lua'
+failed.script = "replication-py/failed.lua"
 failed.vardir = server.vardir
 failed.rpl_master = master
 failed.name = "failed"
@@ -235,16 +240,16 @@ try:
 except Exception as e:
     line = "ER_READONLY"
     if failed.logfile_pos.seek_once(line) >= 0:
-        print "'%s' exists in server log" % line
+        print("'{}' exists in server log".format(line))
 
-master.admin('box.cfg { read_only = false }')
+master.admin("box.cfg { read_only = false }")
 
-print '-------------------------------------------------------------'
-print 'JOIN replica with different replica set UUID'
-print '-------------------------------------------------------------'
+print("-------------------------------------------------------------")
+print("JOIN replica with different replica set UUID")
+print("-------------------------------------------------------------")
 
 failed = TarantoolServer(server.ini)
-failed.script = 'replication-py/uuid_mismatch.lua'
+failed.script = "replication-py/uuid_mismatch.lua"
 failed.vardir = server.vardir
 failed.rpl_master = master
 failed.name = "uuid_mismatch"
@@ -254,15 +259,15 @@ try:
 except Exception as e:
     line = "ER_REPLICASET_UUID_MISMATCH"
     if failed.logfile_pos.seek_once(line) >= 0:
-        print "'%s' exists in server log" % line
+        print("'{}' exists in server log".format(line))
 
 failed.cleanup()
 
-print '-------------------------------------------------------------'
-print 'Cleanup'
-print '-------------------------------------------------------------'
+print("-------------------------------------------------------------")
+print("Cleanup")
+print("-------------------------------------------------------------")
 
 # Cleanup
 sys.stdout.pop_filter()
 master.admin("box.schema.user.revoke('guest', 'replication')")
-master.admin('box.space._cluster:delete{2} ~= nil')
+master.admin("box.space._cluster:delete{2} ~= nil")
diff --git a/test/replication-py/conflict.test.py b/test/replication-py/conflict.test.py
index 1dcd66765..5e19d0c40 100644
--- a/test/replication-py/conflict.test.py
+++ b/test/replication-py/conflict.test.py
@@ -1,35 +1,37 @@
+from __future__ import print_function
+
 from lib.tarantool_server import TarantoolServer
 from time import sleep
 import yaml
 
-def check_replication(nodes, select_args=''):
+def check_replication(nodes, select_args=""):
     for node in nodes:
-        node.admin('box.space.test:select{%s}' % select_args)
+        node.admin("box.space.test:select{{{}}}".format(select_args))
 
 master = server
 master.admin("box.schema.user.grant('guest', 'replication')")
 
 replica = TarantoolServer(server.ini)
-replica.script = 'replication-py/replica.lua'
+replica.script = "replication-py/replica.lua"
 replica.vardir = server.vardir
 replica.rpl_master = master
 replica.deploy()
 
 def parallel_run(cmd1, cmd2, compare):
-    print 'parallel send: %s' % cmd1
-    print 'parallel send: %s' % cmd2
-    master.admin.socket.sendall('%s\n' % cmd1)
-    replica.admin.socket.sendall('%s\n' % cmd2)
+    print("parallel send: {}".format(cmd1))
+    print("parallel send: {}".format(cmd2))
+    master.admin.socket.sendall("{}\n".format(cmd1))
+    replica.admin.socket.sendall("{}\n".format(cmd2))
 
     master.admin.socket.recv(2048)
     replica.admin.socket.recv(2048)
 
     # wait for status changing in tarantool
     master_status = yaml.safe_load(master.admin(
-        'box.info().replication[2].upstream.status', silent=True
+        "box.info().replication[2].upstream.status", silent=True
     ))[0]
     replica_status = yaml.safe_load(replica.admin(
-        'box.info().replication[1].upstream.status', silent=True
+        "box.info().replication[1].upstream.status", silent=True
     ))[0]
 
     # wait for status
@@ -37,11 +39,11 @@ def parallel_run(cmd1, cmd2, compare):
     while True:
         sleep(0.01)
         if any(results):
-            print 'replication state is correct'
+            print("replication state is correct")
             break
 
 def prepare_cluster():
-    print 'reset master-master replication'
+    print("reset master-master replication")
     master.stop()
     master.cleanup()
     master.start()
@@ -51,13 +53,13 @@ def prepare_cluster():
     replica.cleanup()
     replica.start()
 
-    master.admin("box.cfg{replication='%s'}" % replica.iproto.uri, silent=True)
-    r1_id = replica.get_param('id')
-    r2_id = master.get_param('id')
+    master.admin("box.cfg{{replication='{}'}}".format(replica.iproto.uri), silent=True)
+    r1_id = replica.get_param("id")
+    r2_id = master.get_param("id")
 
     master.admin("space = box.schema.space.create('test')", silent=True)
     master.admin("index = space:create_index('primary', { type = 'tree'})", silent=True)
-    master.admin('for k = 1, 9 do space:insert{k, k*k} end', silent=True)
+    master.admin("for k = 1, 9 do space:insert{k, k*k} end", silent=True)
 
     # wait lsn
     replica.wait_lsn(r2_id, master.get_lsn(r2_id))
@@ -69,20 +71,20 @@ parallel_run(
     "box.space.test:update(1, {{'#', 2, 1}})",
     "box.space.test:update(1, {{'#', 2, 1}})",
     [
-        lambda x,y: x == 'stopped' or y == 'stopped',
-        lambda x,y: x == 'follow' and y == 'follow',
+        lambda x,y: x == "stopped" or y == "stopped",
+        lambda x,y: x == "follow" and y == "follow",
     ]
 )
-check_replication([master, replica], '1')
+check_replication([master, replica], "1")
 
 # test2: insert different values with single id
 prepare_cluster()
 parallel_run(
-    'box.space.test:insert{20, 1}',
-    'box.space.test:insert{20, 2}',
+    "box.space.test:insert{20, 1}",
+    "box.space.test:insert{20, 2}",
     [
-        lambda x,y: x == 'stopped' or y == 'stopped',
-        lambda x,y: x == 'follow' and y == 'follow',
+        lambda x,y: x == "stopped" or y == "stopped",
+        lambda x,y: x == "follow" and y == "follow",
     ]
 )
 
@@ -91,7 +93,7 @@ prepare_cluster()
 parallel_run(
     "box.space.test:update(2, {{'=', 2, 1}})",
     "box.space.test:update(2, {{'=', 2, 2}})",
-    [lambda x,y: x == 'follow' and y == 'follow',]
+    [lambda x,y: x == "follow" and y == "follow",]
 )
 
 # test4: CRDT increment with update
@@ -99,16 +101,16 @@ prepare_cluster()
 parallel_run(
     "box.space.test:update(1, {{'+', 2, 1}})",
     "box.space.test:update(1, {{'+', 2, 2}})",
-    [lambda x,y: x == 'follow' and y == 'follow',]
+    [lambda x,y: x == "follow" and y == "follow",]
 )
-check_replication([master, replica], '1')
+check_replication([master, replica], "1")
 
 # test5: delete not existing key
 prepare_cluster()
 parallel_run(
     "box.space.test:delete(999)",
     "box.space.test:delete(999)",
-    [lambda x,y: x == 'follow' and y == 'follow',]
+    [lambda x,y: x == "follow" and y == "follow",]
 )
 check_replication([master, replica])
 
diff --git a/test/replication-py/init_storage.test.py b/test/replication-py/init_storage.test.py
index f8641bf65..43ebc8afb 100644
--- a/test/replication-py/init_storage.test.py
+++ b/test/replication-py/init_storage.test.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import os
 import glob
 from lib.tarantool_server import TarantoolStartError
@@ -5,65 +7,65 @@ from lib.tarantool_server import TarantoolServer
 
 # master server
 master = server
-master_id = master.get_param('id')
+master_id = master.get_param("id")
 master.admin("box.schema.user.grant('guest', 'replication')")
 
-print '-------------------------------------------------------------'
-print 'gh-484: JOIN doesn\'t save data to snapshot with TREE index'
-print '-------------------------------------------------------------'
+print("-------------------------------------------------------------")
+print("gh-484: JOIN doesn't save data to snapshot with TREE index")
+print("-------------------------------------------------------------")
 
 master.admin("space = box.schema.space.create('test', {id =  42})")
 master.admin("index = space:create_index('primary', { type = 'tree'})")
 
-master.admin('for k = 1, 9 do space:insert{k, k*k} end')
+master.admin("for k = 1, 9 do space:insert{k, k*k} end")
 
 replica = TarantoolServer(server.ini)
-replica.script = 'replication-py/replica.lua'
+replica.script = "replication-py/replica.lua"
 replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
 replica.rpl_master = master
 replica.deploy()
-replica.admin('box.space.test:select()')
+replica.admin("box.space.test:select()")
 
 replica.restart()
-replica.admin('box.space.test:select()')
+replica.admin("box.space.test:select()")
 replica.stop()
 replica.cleanup()
 
-print '-------------------------------------------------------------'
-print 'replica test 2 (must be ok)'
-print '-------------------------------------------------------------'
+print("-------------------------------------------------------------")
+print("replica test 2 (must be ok)")
+print("-------------------------------------------------------------")
 
 master.restart()
-master.admin('for k = 10, 19 do box.space[42]:insert{k, k*k*k} end')
+master.admin("for k = 10, 19 do box.space[42]:insert{k, k*k*k} end")
 master.admin("for k = 20, 29 do box.space[42]:upsert({k}, {}) end")
 lsn = master.get_lsn(master_id)
 
 replica = TarantoolServer(server.ini)
-replica.script = 'replication-py/replica.lua'
+replica.script = "replication-py/replica.lua"
 replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
 replica.rpl_master = master
 replica.deploy()
 
-replica.admin('space = box.space.test');
+replica.admin("space = box.space.test");
 replica.wait_lsn(master_id, lsn)
 for i in range(1, 20):
-    replica.admin('space:get{%d}' % i)
+    replica.admin("space:get{{{}}}".format(i))
 
 replica.stop()
 replica.cleanup()
 
-print '-------------------------------------------------------------'
-print 'reconnect on JOIN/SUBSCRIBE'
-print '-------------------------------------------------------------'
+print("-------------------------------------------------------------")
+print("reconnect on JOIN/SUBSCRIBE")
+print("-------------------------------------------------------------")
 
 server.stop()
 replica = TarantoolServer(server.ini)
-replica.script = 'replication-py/replica.lua'
+replica.script = "replication-py/replica.lua"
 replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
 replica.rpl_master = master
 replica.deploy(wait=False)
 
-print 'waiting reconnect on JOIN...'
+print("waiting reconnect on JOIN...")
 server.start()
 try:
     # Replica may fail to start due connection issues may occur, check
@@ -73,14 +75,14 @@ try:
     replica.crash_expected = True
     replica.wait_until_started()
 except TarantoolStartError:
-    print 'not ok - server failed to start'
+    print("not ok - server failed to start")
 else:
-    print 'ok'
+    print("ok")
 
 replica.stop()
 server.stop()
 
-print 'waiting reconnect on SUBSCRIBE...'
+print("waiting reconnect on SUBSCRIBE...")
 replica.start(wait=False)
 server.start()
 try:
@@ -91,9 +93,9 @@ try:
     replica.crash_expected = True
     replica.wait_until_started()
 except TarantoolStartError:
-    print 'not ok - server failed to start'
+    print("not ok - server failed to start")
 else:
-    print 'ok'
+    print("ok")
 
 replica.stop()
 replica.cleanup()
diff --git a/test/replication-py/multi.test.py b/test/replication-py/multi.test.py
index 233802458..a346fd560 100644
--- a/test/replication-py/multi.test.py
+++ b/test/replication-py/multi.test.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import sys
 import os
 from lib.tarantool_server import TarantoolServer
@@ -14,17 +16,17 @@ master.admin("fiber = require('fiber')")
 master.admin("box.schema.user.grant('guest', 'replication')")
 master.admin("box.schema.user.grant('guest', 'execute', 'universe')")
 
-print '----------------------------------------------------------------------'
-print 'Bootstrap replicas'
-print '----------------------------------------------------------------------'
+print("----------------------------------------------------------------------")
+print("Bootstrap replicas")
+print("----------------------------------------------------------------------")
 
 # Start replicas
-master.id = master.get_param('id')
+master.id = master.get_param("id")
 cluster = [ master ]
 for i in range(REPLICA_N - 1):
     server = TarantoolServer(server.ini)
-    server.script = 'replication-py/replica.lua'
-    server.vardir = os.path.join(server.vardir, 'replica', str(master.id + i))
+    server.script = "replication-py/replica.lua"
+    server.vardir = os.path.join(server.vardir, "replica", str(master.id + i))
     server.rpl_master = master
     server.deploy()
     # Wait replica to fully bootstrap.
@@ -34,14 +36,14 @@ for i in range(REPLICA_N - 1):
 # Make a list of servers
 sources = []
 for server in cluster:
-    sources.append(yaml.safe_load(server.admin('box.cfg.listen', silent = True))[0])
-    server.id = server.get_param('id')
+    sources.append(yaml.safe_load(server.admin("box.cfg.listen", silent = True))[0])
+    server.id = server.get_param("id")
 
-print 'done'
+print("done")
 
-print '----------------------------------------------------------------------'
-print 'Make a full mesh'
-print '----------------------------------------------------------------------'
+print("----------------------------------------------------------------------")
+print("Make a full mesh")
+print("----------------------------------------------------------------------")
 
 # Connect each server to each other to make full mesh
 for server in cluster:
@@ -54,55 +56,55 @@ for server in cluster:
             while #box.info.vclock[...] ~= nil do
                 fiber.sleep(0.01)
             end;""", server2.id)
-        print 'server', server.id, "connected"
+        print("server {} connected".format(server.id))
 
-print 'done'
+print("done")
 
-print '----------------------------------------------------------------------'
-print 'Test inserts'
-print '----------------------------------------------------------------------'
+print("----------------------------------------------------------------------")
+print("Test inserts")
+print("----------------------------------------------------------------------")
 
-print 'Create a test space'
+print("Create a test space")
 master.admin("_ = box.schema.space.create('test')")
 master.admin("_ = box.space.test:create_index('primary')")
 master_lsn = master.get_lsn(master.id)
 # Wait changes to propagate to replicas
 for server in cluster:
     server.wait_lsn(master.id, master_lsn)
-    print 'server', server.id, 'is ok'
-print
+    print("server {} is ok".format(server.id))
+print("")
 
-print 'Insert records'
+print("Insert records")
 for i in range(ROW_N):
     server = cluster[i % REPLICA_N]
-    server.admin("box.space.test:insert{%d, %s}" % (i, server.id), silent = True)
-print 'inserted %d records' % ROW_N
-print
+    server.admin("box.space.test:insert{{{}, {}}}".format(i, server.id), silent = True)
+print("inserted {} records".format(ROW_N))
+print("")
 
-print 'Synchronize'
+print("Synchronize")
 for server1 in cluster:
     for server2 in cluster:
         server1.wait_lsn(server2.id, server2.get_lsn(server2.id))
-    print 'server', server1.id, 'done'
-print 'done'
-print
+    print("server {} done".format(server1.id))
+print("done")
+print("")
 
-print 'Check data'
+print("Check data")
 for server in cluster:
     cnt = yaml.safe_load(server.admin("box.space.test:len()", silent = True))[0]
-    print 'server', server.id, 'is', cnt == ROW_N and 'ok' or 'not ok'
-print 'Done'
-print
+    print("server {} is {}".format(server.id, cnt == ROW_N and "ok" or "not ok"))
+print("Done")
+print("")
 
-print
-print '----------------------------------------------------------------------'
-print 'Cleanup'
-print '----------------------------------------------------------------------'
+print("")
+print("----------------------------------------------------------------------")
+print("Cleanup")
+print("----------------------------------------------------------------------")
 
 for server in cluster:
     server.stop()
-    print 'server', server.id, 'done'
-print
+    print("server {} done".format(server.id))
+print("")
 
 master.cleanup()
 master.deploy()
diff --git a/test/replication-py/swap.test.py b/test/replication-py/swap.test.py
index 98eeeea6d..b162ae241 100644
--- a/test/replication-py/swap.test.py
+++ b/test/replication-py/swap.test.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import os
 import tarantool
 from lib.tarantool_server import TarantoolServer
@@ -7,26 +9,26 @@ import yaml
 REPEAT = 20
 ID_BEGIN = 0
 ID_STEP = 5
-LOGIN = 'test'
-PASSWORD = 'pass123456'
+LOGIN = "test"
+PASSWORD = "pass123456"
 
-engines = ['memtx', 'vinyl']
+engines = ["memtx", "vinyl"]
 
 def insert_tuples(_server, begin, end, msg = "tuple"):
     for engine in engines:
         for i in range(begin, end):
-            print 'box.space.%s:insert{%d, "%s %d"}' % (engine, i, msg, i)
-            print '-'
+            print('box.space.{}:insert{{{}, "{} {}"}}'.format(engine, i, msg, i))
+            print("-")
             space = _server.iproto.py_con.space(engine)
-            print space.insert((i, '%s %d' % (msg, i)))
+            print(space.insert((i, "{} {}".format(msg, i))))
 
 def select_tuples(_server, begin, end):
     for engine in engines:
         for i in range(begin, end):
-            print 'box.space.%s:select{%d}' % (engine, i)
-            print '-'
+            print("box.space.{}:select{{{}}}".format(engine, i))
+            print("-")
             space = _server.iproto.py_con.space(engine)
-            print space.select(i)
+            print(space.select(i))
 
 # master server
 master = server
@@ -34,11 +36,11 @@ master = server
 master.stop()
 master.cleanup()
 master.deploy()
-master.admin("box.schema.user.create('%s', { password = '%s'})" % (LOGIN, PASSWORD))
-master.admin("box.schema.user.grant('%s', 'read,write,execute', 'universe')" % LOGIN)
+master.admin("box.schema.user.create('{}', {{ password = '{}'}})".format(LOGIN, PASSWORD))
+master.admin("box.schema.user.grant('{}', 'read,write,execute', 'universe')".format(LOGIN))
 master.iproto.py_con.authenticate(LOGIN, PASSWORD)
-master.uri = '%s:%s@%s' % (LOGIN, PASSWORD, master.iproto.uri)
-os.putenv('MASTER', master.uri)
+master.uri = "{}:{}@{}".format(LOGIN, PASSWORD, master.iproto.uri)
+os.putenv("MASTER", master.uri)
 
 # replica server
 replica = TarantoolServer()
@@ -46,12 +48,12 @@ replica.script = "replication-py/replica.lua"
 replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
 replica.deploy()
 replica.admin("while box.info.id == 0 do require('fiber').sleep(0.01) end")
-replica.uri = '%s:%s@%s' % (LOGIN, PASSWORD, replica.iproto.uri)
+replica.uri = "{}:{}@{}".format(LOGIN, PASSWORD, replica.iproto.uri)
 replica.admin("while box.space['_priv']:len() < 1 do require('fiber').sleep(0.01) end")
 replica.iproto.py_con.authenticate(LOGIN, PASSWORD)
 
 for engine in engines:
-    master.admin("s = box.schema.space.create('%s', { engine = '%s'})" % (engine, engine))
+    master.admin("s = box.schema.space.create('{}', {{ engine = '{}'}})".format(engine, engine))
     master.admin("index = s:create_index('primary', {type = 'tree'})")
 
 ### gh-343: replica.cc must not add login and password to proc title
@@ -61,12 +63,12 @@ for engine in engines:
 #if not m or m.group(1) != host_port:
 #    print 'invalid box.info.status', status, 'expected host:port', host_port
 
-master_id = master.get_param('id')
-replica_id = replica.get_param('id')
+master_id = master.get_param("id")
+replica_id = replica.get_param("id")
 
 id = ID_BEGIN
 for i in range(REPEAT):
-    print "test %d iteration" % i
+    print("test {} iteration".format(i))
 
     # insert to master
     insert_tuples(master, id, id + ID_STEP)
@@ -82,7 +84,7 @@ for i in range(REPEAT):
     select_tuples(replica, id, id + ID_STEP)
     id += ID_STEP
 
-    print "swap servers"
+    print("swap servers")
     # reconfigure replica to master
     replica.rpl_master = None
     print("switch replica to master")
@@ -90,7 +92,7 @@ for i in range(REPEAT):
     # reconfigure master to replica
     master.rpl_master = replica
     print("switch master to replica")
-    master.admin("box.cfg{replication='%s'}" % replica.uri, silent=True)
+    master.admin("box.cfg{{replication='{}'}}".format(replica.uri), silent=True)
 
     # insert to replica
     insert_tuples(replica, id, id + ID_STEP)
@@ -106,7 +108,7 @@ for i in range(REPEAT):
     select_tuples(master, id, id + ID_STEP)
     id += ID_STEP
 
-    print "rollback servers configuration"
+    print("rollback servers configuration")
     # reconfigure replica to master
     master.rpl_master = None
     print("switch master to master")
@@ -114,7 +116,7 @@ for i in range(REPEAT):
     # reconfigure master to replica
     replica.rpl_master = master
     print("switch replica to replica")
-    replica.admin("box.cfg{replication='%s'}" % master.uri, silent=True)
+    replica.admin("box.cfg{{replication='{}'}}".format(master.uri), silent=True)
 
 
 # Cleanup.
diff --git a/test/xlog-py/big_lsn.test.py b/test/xlog-py/big_lsn.test.py
index c6a31d971..edc1e5620 100644
--- a/test/xlog-py/big_lsn.test.py
+++ b/test/xlog-py/big_lsn.test.py
@@ -19,8 +19,8 @@ old_wal = os.path.join(wal_dir, "%020d.xlog" % old_lsn)
 new_wal = os.path.join(wal_dir, "%020d.xlog" % new_lsn)
 with open(old_wal, "r+") as f:
     s = f.read()
-    s = s.replace("VClock: {1: %d}" % old_lsn,
-                  "VClock: {1: %d}" % new_lsn)
+    s = s.replace("VClock: {{1: {}}}".format(old_lsn),
+                  "VClock: {{1: {}}}".format(new_lsn))
     f.seek(0)
     f.write(s)
 os.rename(old_wal, new_wal)
diff --git a/test/xlog-py/dup_key.test.py b/test/xlog-py/dup_key.test.py
index 7609c9555..caf2478a9 100644
--- a/test/xlog-py/dup_key.test.py
+++ b/test/xlog-py/dup_key.test.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import os
 import yaml
 
@@ -26,7 +28,7 @@ server.stop()
 
 # Save wal#1
 if os.access(wal, os.F_OK):
-    print ".xlog exists"
+    print(".xlog exists")
     os.rename(wal, wal_old)
 
 # Write wal#2
@@ -37,16 +39,16 @@ server.stop()
 
 # Restore wal#1
 if not os.access(wal, os.F_OK):
-    print ".xlog does not exist"
+    print(".xlog does not exist")
     os.rename(wal_old, wal)
 
 server.start()
-line = 'Duplicate key'
-print "check log line for '%s'" % line
-print
+line = "Duplicate key"
+print("check log line for '{}'".format(line))
+print("")
 if server.logfile_pos.seek_once(line) >= 0:
-    print "'%s' exists in server log" % line
-print
+    print("'{}' exists in server log".format(line))
+print("")
 
 server.admin("box.space.test:get{1}")
 server.admin("box.space.test:get{2}")
diff --git a/test/xlog-py/empty.test.py b/test/xlog-py/empty.test.py
index d6f89e0fb..8b19bc3d7 100644
--- a/test/xlog-py/empty.test.py
+++ b/test/xlog-py/empty.test.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import os
 import yaml
 from os.path import abspath
@@ -20,7 +22,7 @@ f.close()
 server.start()
 server.stop()
 if os.access(filename, os.F_OK):
-    print ".xlog exists"
+    print(".xlog exists")
 # the server has started but is crippled since it
 # can't override an existing file
 server.start()
diff --git a/test/xlog-py/lsn_gap.test.py b/test/xlog-py/lsn_gap.test.py
index 7a503ff07..8da6166a2 100644
--- a/test/xlog-py/lsn_gap.test.py
+++ b/test/xlog-py/lsn_gap.test.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import os
 import yaml
 #
@@ -28,11 +30,11 @@ os.unlink(wal)
 
 server.start()
 line="ignoring a gap in LSN"
-print "check log line for '%s'" % line
-print
+print("check log line for '{}'".format(line))
+print("")
 if server.logfile_pos.seek_once(line) >= 0:
-    print "'%s' exists in server log" % line
-print
+    print("'{}' exists in server log".format(line))
+print("")
 
 # missing tuple from removed xlog
 server.admin("box.space.test:select{}")
diff --git a/test/xlog-py/misc.test.py b/test/xlog-py/misc.test.py
index e39ae1495..3330a8e57 100644
--- a/test/xlog-py/misc.test.py
+++ b/test/xlog-py/misc.test.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import os
 import yaml
 
@@ -11,9 +13,9 @@ server.stop()
 
 data_path = os.path.join(server.vardir, server.name)
 
-print """
+print("""
 # xlog file must exist after inserts.
-"""
+""")
 filename = str(lsn).zfill(20) + ".xlog"
 wal = os.path.join(data_path, filename)
 
@@ -21,16 +23,16 @@ server.start()
 
 server.admin("space = box.schema.space.create('tweedledum')")
 if os.access(wal, os.F_OK):
-  print ".xlog exists"
+  print(".xlog exists")
 
 server.admin("index = space:create_index('primary', { type = 'hash' })")
 
 server.stop()
 lsn += 2
 
-print """
+print("""
 # a new xlog must be opened after regular termination.
-"""
+""")
 filename = str(lsn).zfill(20) + ".xlog"
 server.start()
 
@@ -39,17 +41,17 @@ wal = os.path.join(data_path, filename)
 server.admin("box.space.tweedledum:insert{3, 'third tuple'}")
 
 if os.access(wal, os.F_OK):
-  print "a new .xlog exists"
+  print("a new .xlog exists")
 
 server.stop()
 
 if os.access(wal, os.F_OK):
-  print ".xlog stays around after sutdown"
+  print(".xlog stays around after shutdown")
 lsn += 1
 
-print """
+print("""
 # An xlog file with one record during recovery.
-"""
+""")
 
 server.start()
 filename = str(lsn).zfill(20) + ".xlog"
@@ -63,7 +65,7 @@ if pid > 0:
 server.stop()
 
 if os.access(wal, os.F_OK):
-    print ".xlog exists after kill -9"
+    print(".xlog exists after kill -9")
     # Remove last byte from xlog
     f = open(wal, "a")
     size = f.tell()
@@ -73,7 +75,7 @@ if os.access(wal, os.F_OK):
 server.start()
 
 if os.access(wal, os.F_OK):
-  print "corrupt .xlog exists after start"
+  print("corrupt .xlog exists after start")
 server.stop()
 lsn += 1
 
@@ -98,4 +100,4 @@ for f in os.listdir(data_path):
 server.start()
 lsn = int(yaml.safe_load(admin("box.info.lsn", silent=True))[0])
 if lsn == orig_lsn:
-    print ".snap.inprogress is ignored"
+    print(".snap.inprogress is ignored")
diff --git a/test/xlog-py/missing.test.py b/test/xlog-py/missing.test.py
index df35dc6d7..2fff0df6c 100644
--- a/test/xlog-py/missing.test.py
+++ b/test/xlog-py/missing.test.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
 import yaml
 import os 
 #
@@ -34,11 +36,11 @@ os.unlink(wal)
 # this may lead to infinite recursion at start
 server.start()
 line="ignoring a gap in LSN"
-print "check log line for '%s'" % line
-print
+print("check log line for '{}'".format(line))
+print("")
 if server.logfile_pos.seek_once(line) >= 0:
-    print "'%s' exists in server log" % line
-print
+    print("'{}' exists in server log".format(line))
+print("")
 
 # missing tuples from removed xlog
 server.admin("box.space.test:select{}")
-- 
2.25.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Tarantool-patches] [PATCH v3 2/5] test: make dict.items() compatible with Python 3.x
  2020-12-23 12:36 [Tarantool-patches] [PATCH v3 0/5] Support Python 3 in tests and PEPify source code sergeyb
  2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 1/5] test: convert print to function and make quotes use consistent sergeyb
@ 2020-12-23 12:36 ` sergeyb
  2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 3/5] test: make strings compatible with Python 3 sergeyb
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: sergeyb @ 2020-12-23 12:36 UTC (permalink / raw)
  To: tarantool-patches, v.shpilevoy, lvasiliev

From: Sergey Bronnikov <sergeyb@tarantool.org>

In Python 2.x calling items() makes a copy of the keys that you can
iterate over while modifying the dict. This doesn't work in Python 3.x
because items() returns an iterator instead of a list and Python 3 raise
an exception "dictionary changed size during iteration". To workaround
it one can use list to force a copy of the keys to be made.

Part of #5538
---
 test/box-py/iproto.test.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/box-py/iproto.test.py b/test/box-py/iproto.test.py
index 6ed49051b..6723e03f5 100644
--- a/test/box-py/iproto.test.py
+++ b/test/box-py/iproto.test.py
@@ -37,7 +37,7 @@ print(iproto.py_con.ping() > 0)
 s.close()
 
 key_names = {}
-for (k,v) in globals().items():
+for (k,v) in list(globals().items()):
     if type(k) == str and k.startswith("IPROTO_") and type(v) == int:
         key_names[v] = k
 
-- 
2.25.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Tarantool-patches] [PATCH v3 3/5] test: make strings compatible with Python 3
  2020-12-23 12:36 [Tarantool-patches] [PATCH v3 0/5] Support Python 3 in tests and PEPify source code sergeyb
  2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 1/5] test: convert print to function and make quotes use consistent sergeyb
  2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 2/5] test: make dict.items() compatible with Python 3.x sergeyb
@ 2020-12-23 12:36 ` sergeyb
  2020-12-23 15:40   ` Vladislav Shpilevoy
  2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 4/5] test: get rid of iteritems() sergeyb
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: sergeyb @ 2020-12-23 12:36 UTC (permalink / raw)
  To: tarantool-patches, v.shpilevoy, lvasiliev

From: Sergey Bronnikov <sergeyb@tarantool.org>

The largest change in Python 3 is the handling of strings.
In Python 2, the str type was used for two different
kinds of values - text and bytes, whereas in Python 3,
these are separate and incompatible types.
Patch converts strings to byte strings where it is required
to make tests compatible with Python 3.

Part of #5538
---
 test/box-py/bad_trigger.test.py      |  2 +-
 test/box-py/iproto.test.py           | 41 +++++++++++++++++-----------
 test/replication-py/conflict.test.py |  5 ++--
 3 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/test/box-py/bad_trigger.test.py b/test/box-py/bad_trigger.test.py
index 9dd6e17c9..03b7efcda 100644
--- a/test/box-py/bad_trigger.test.py
+++ b/test/box-py/bad_trigger.test.py
@@ -41,7 +41,7 @@ unpacker.feed(packet)
 header = unpacker.unpack()
 body = unpacker.unpack()
 print("error code {}".format((header[IPROTO_CODE] & (REQUEST_TYPE_ERROR - 1))))
-print("error message:  {}".format(body[IPROTO_ERROR]))
+print("error message:  {}".format(body[IPROTO_ERROR].decode("utf-8")))
 print("eof: {}".format(len(s.recv(1024)) == 0))
 s.close()
 
diff --git a/test/box-py/iproto.test.py b/test/box-py/iproto.test.py
index 6723e03f5..c518b0d73 100644
--- a/test/box-py/iproto.test.py
+++ b/test/box-py/iproto.test.py
@@ -163,7 +163,7 @@ class RawInsert(Request):
 
     def __init__(self, conn, space_no, blob):
         super(RawInsert, self).__init__(conn)
-        request_body = "\x82" + msgpack.dumps(IPROTO_SPACE_ID) + \
+        request_body = b'\x82' + msgpack.dumps(IPROTO_SPACE_ID) + \
             msgpack.dumps(space_id) + msgpack.dumps(IPROTO_TUPLE) + blob
         self._body = request_body
 
@@ -172,7 +172,7 @@ class RawSelect(Request):
 
     def __init__(self, conn, space_no, blob):
         super(RawSelect, self).__init__(conn)
-        request_body = "\x83" + msgpack.dumps(IPROTO_SPACE_ID) + \
+        request_body = b'\x83' + msgpack.dumps(IPROTO_SPACE_ID) + \
             msgpack.dumps(space_id) + msgpack.dumps(IPROTO_KEY) + blob + \
             msgpack.dumps(IPROTO_LIMIT) + msgpack.dumps(100);
         self._body = request_body
@@ -182,13 +182,13 @@ space = c.space("test")
 space_id = space.space_no
 
 TESTS = [
-    (1,     "\xa1", "\xd9\x01", "\xda\x00\x01", "\xdb\x00\x00\x00\x01"),
-    (31,    "\xbf", "\xd9\x1f", "\xda\x00\x1f", "\xdb\x00\x00\x00\x1f"),
-    (32,    "\xd9\x20", "\xda\x00\x20", "\xdb\x00\x00\x00\x20"),
-    (255,   "\xd9\xff", "\xda\x00\xff", "\xdb\x00\x00\x00\xff"),
-    (256,   "\xda\x01\x00", "\xdb\x00\x00\x01\x00"),
-    (65535, "\xda\xff\xff", "\xdb\x00\x00\xff\xff"),
-    (65536, "\xdb\x00\x01\x00\x00"),
+    (1,     b'\xa1', b'\xd9\x01', b'\xda\x00\x01', b'\xdb\x00\x00\x00\x01'),
+    (31,    b'\xbf', b'\xd9\x1f', b'\xda\x00\x1f', b'\xdb\x00\x00\x00\x1f'),
+    (32,    b'\xd9\x20', b'\xda\x00\x20', b'\xdb\x00\x00\x00\x20'),
+    (255,   b'\xd9\xff', b'\xda\x00\xff', b'\xdb\x00\x00\x00\xff'),
+    (256,   b'\xda\x01\x00', b'\xdb\x00\x00\x01\x00'),
+    (65535, b'\xda\xff\xff', b'\xdb\x00\x00\xff\xff'),
+    (65536, b'\xdb\x00\x01\x00\x00'),
 ]
 
 for test in TESTS:
@@ -197,16 +197,19 @@ for test in TESTS:
     print("STR", size)
     print("--")
     for fmt in it:
-        print("0x" + fmt.encode("hex"), "=>", end=" ")
+        if sys.version[0] == '2':
+            print("0x" + fmt.encode("hex"), "=>", end=" ")
+        else:
+            print("0x" + fmt.hex(), "=>", end=" ")
         field = "*" * size
-        c._send_request(RawInsert(c, space_id, "\x91" + fmt + field))
+        c._send_request(RawInsert(c, space_id, b'\x91' + fmt + field.encode("utf-8")))
         tuple = space.select(field)[0]
         print(len(tuple[0])== size and "ok" or "fail", end=" ")
         it2 = iter(test)
         next(it2)
         for fmt2 in it2:
             tuple = c._send_request(RawSelect(c, space_id,
-                "\x91" + fmt2 + field))[0]
+                b'\x91' + fmt2 + field.encode("utf-8")))[0]
             print(len(tuple[0]) == size and "ok" or "fail", end=" ")
         tuple = space.delete(field)[0]
         print(len(tuple[0]) == size and "ok" or "fail", end="")
@@ -357,15 +360,18 @@ s = c._socket
 header = { "hello": "world"}
 body = { "bug": 272 }
 resp = test_request(header, body)
-print("sync={}, {}".format(resp["header"][IPROTO_SYNC], resp["body"].get(IPROTO_ERROR)))
+print("sync={}, {}".format(resp["header"][IPROTO_SYNC],
+        resp["body"].get(IPROTO_ERROR).decode("utf-8")))
 header = { IPROTO_CODE : REQUEST_TYPE_SELECT }
 header[IPROTO_SYNC] = 1234
 resp = test_request(header, body)
-print("sync={}, {}".format(resp["header"][IPROTO_SYNC], resp["body"].get(IPROTO_ERROR)))
+print("sync={}, {}".format(resp["header"][IPROTO_SYNC],
+        resp["body"].get(IPROTO_ERROR).decode("utf-8")))
 header[IPROTO_SYNC] = 5678
 body = { IPROTO_SPACE_ID: 304, IPROTO_KEY: [], IPROTO_LIMIT: 1 }
 resp = test_request(header, body)
-print("sync={}, {}".format(resp["header"][IPROTO_SYNC], resp["body"].get(IPROTO_ERROR)))
+print("sync={}, {}".format(resp["header"][IPROTO_SYNC],
+        resp["body"].get(IPROTO_ERROR).decode("utf-8")))
 c.close()
 
 
@@ -424,7 +430,10 @@ header = { IPROTO_CODE: REQUEST_TYPE_CALL, IPROTO_SYNC: 100 }
 body = { IPROTO_FUNCTION_NAME: "kek" }
 resp = test_request(header, body)
 print("Sync: ", resp["header"][IPROTO_SYNC])
-print("Retcode: ", resp["body"][IPROTO_DATA])
+body = resp["body"][IPROTO_DATA]
+if sys.version[0] == '3':
+    body = [body[0].decode("utf-8")]
+print("Retcode: ", body)
 
 c.close()
 
diff --git a/test/replication-py/conflict.test.py b/test/replication-py/conflict.test.py
index 5e19d0c40..925ae046b 100644
--- a/test/replication-py/conflict.test.py
+++ b/test/replication-py/conflict.test.py
@@ -20,9 +20,8 @@ replica.deploy()
 def parallel_run(cmd1, cmd2, compare):
     print("parallel send: {}".format(cmd1))
     print("parallel send: {}".format(cmd2))
-    master.admin.socket.sendall("{}\n".format(cmd1))
-    replica.admin.socket.sendall("{}\n".format(cmd2))
-
+    master.admin.socket.sendall(cmd1.encode("utf-8") + b'\n')
+    replica.admin.socket.sendall(cmd2.encode("utf-8") + b'\n')
     master.admin.socket.recv(2048)
     replica.admin.socket.recv(2048)
 
-- 
2.25.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Tarantool-patches] [PATCH v3 4/5] test: get rid of iteritems()
  2020-12-23 12:36 [Tarantool-patches] [PATCH v3 0/5] Support Python 3 in tests and PEPify source code sergeyb
                   ` (2 preceding siblings ...)
  2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 3/5] test: make strings compatible with Python 3 sergeyb
@ 2020-12-23 12:36 ` sergeyb
  2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 5/5] test: remove dead code in Python tests end extra newlines sergeyb
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: sergeyb @ 2020-12-23 12:36 UTC (permalink / raw)
  To: tarantool-patches, v.shpilevoy, lvasiliev; +Cc: Sergey Bronnikov

From: Sergey Bronnikov <estetus@gmail.com>

For Python 3, PEP 3106 changed the design of the dict builtin and the
mapping API in general to replace the separate list based and iterator
based APIs in Python 2 with a merged, memory efficient set and multiset
view based API. This new style of dict iteration was also added to the
Python 2.7 dict type as a new set of iteration methods. PEP-0469 [1]
recommends to replace d.iteritems() to iter(d.items()) to make code
compatible with Python 3.

1. https://www.python.org/dev/peps/pep-0469/

Part of #5538
---
 test/app-tap/httpd.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/app-tap/httpd.py b/test/app-tap/httpd.py
index b57ef1e39..a2dee1b83 100755
--- a/test/app-tap/httpd.py
+++ b/test/app-tap/httpd.py
@@ -66,7 +66,7 @@ def read_handle(env, response):
     body = ["Not Found"]
     if env["PATH_INFO"] in paths:
         code, body, headers = paths[env["PATH_INFO"]]()
-    for key,value in env.iteritems():
+    for key,value in iter(env.items()):
         if "HTTP_" in key:
             headers.append((key[5:].lower(), value))
     response(code, headers)
-- 
2.25.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Tarantool-patches] [PATCH v3 5/5] test: remove dead code in Python tests end extra newlines
  2020-12-23 12:36 [Tarantool-patches] [PATCH v3 0/5] Support Python 3 in tests and PEPify source code sergeyb
                   ` (3 preceding siblings ...)
  2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 4/5] test: get rid of iteritems() sergeyb
@ 2020-12-23 12:36 ` sergeyb
  2020-12-23 23:42 ` [Tarantool-patches] [PATCH v3 0/5] Support Python 3 in tests and PEPify source code Leonid Vasiliev
  2020-12-24 16:05 ` Vladislav Shpilevoy
  6 siblings, 0 replies; 12+ messages in thread
From: sergeyb @ 2020-12-23 12:36 UTC (permalink / raw)
  To: tarantool-patches, v.shpilevoy, lvasiliev

From: Sergey Bronnikov <sergeyb@tarantool.org>

Closes #5538
---
 test/replication-py/init_storage.test.py | 6 +++---
 test/replication-py/swap.test.py         | 9 +--------
 test/xlog-py/dup_key.test.py             | 7 ++-----
 test/xlog-py/lsn_gap.test.py             | 1 -
 4 files changed, 6 insertions(+), 17 deletions(-)

diff --git a/test/replication-py/init_storage.test.py b/test/replication-py/init_storage.test.py
index 43ebc8afb..a6e2d6563 100644
--- a/test/replication-py/init_storage.test.py
+++ b/test/replication-py/init_storage.test.py
@@ -21,7 +21,7 @@ master.admin("for k = 1, 9 do space:insert{k, k*k} end")
 
 replica = TarantoolServer(server.ini)
 replica.script = "replication-py/replica.lua"
-replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
+replica.vardir = server.vardir
 replica.rpl_master = master
 replica.deploy()
 replica.admin("box.space.test:select()")
@@ -42,7 +42,7 @@ lsn = master.get_lsn(master_id)
 
 replica = TarantoolServer(server.ini)
 replica.script = "replication-py/replica.lua"
-replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
+replica.vardir = server.vardir
 replica.rpl_master = master
 replica.deploy()
 
@@ -61,7 +61,7 @@ print("-------------------------------------------------------------")
 server.stop()
 replica = TarantoolServer(server.ini)
 replica.script = "replication-py/replica.lua"
-replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
+replica.vardir = server.vardir
 replica.rpl_master = master
 replica.deploy(wait=False)
 
diff --git a/test/replication-py/swap.test.py b/test/replication-py/swap.test.py
index b162ae241..ce1682641 100644
--- a/test/replication-py/swap.test.py
+++ b/test/replication-py/swap.test.py
@@ -45,7 +45,7 @@ os.putenv("MASTER", master.uri)
 # replica server
 replica = TarantoolServer()
 replica.script = "replication-py/replica.lua"
-replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
+replica.vardir = server.vardir
 replica.deploy()
 replica.admin("while box.info.id == 0 do require('fiber').sleep(0.01) end")
 replica.uri = "{}:{}@{}".format(LOGIN, PASSWORD, replica.iproto.uri)
@@ -56,13 +56,6 @@ for engine in engines:
     master.admin("s = box.schema.space.create('{}', {{ engine = '{}'}})".format(engine, engine))
     master.admin("index = s:create_index('primary', {type = 'tree'})")
 
-### gh-343: replica.cc must not add login and password to proc title
-#status = replica.get_param("status")
-#host_port = "%s:%s" % master.iproto.uri
-#m = re.search(r'replica/(.*)/.*', status)
-#if not m or m.group(1) != host_port:
-#    print 'invalid box.info.status', status, 'expected host:port', host_port
-
 master_id = master.get_param("id")
 replica_id = replica.get_param("id")
 
diff --git a/test/xlog-py/dup_key.test.py b/test/xlog-py/dup_key.test.py
index caf2478a9..5ca4f147d 100644
--- a/test/xlog-py/dup_key.test.py
+++ b/test/xlog-py/dup_key.test.py
@@ -3,10 +3,8 @@ from __future__ import print_function
 import os
 import yaml
 
-#print """
-#A test case for https://bugs.launchpad.net/tarantool/+bug/1052018
-#panic_on_wal_error doesn't work for duplicate key errors
-#"""
+# A test case for https://bugs.launchpad.net/tarantool/+bug/1052018
+# panic_on_wal_error doesn't work for duplicate key errors
 
 server.stop()
 server.deploy()
@@ -53,4 +51,3 @@ print("")
 server.admin("box.space.test:get{1}")
 server.admin("box.space.test:get{2}")
 server.admin("box.space.test:len()")
-
diff --git a/test/xlog-py/lsn_gap.test.py b/test/xlog-py/lsn_gap.test.py
index 8da6166a2..b80b97146 100644
--- a/test/xlog-py/lsn_gap.test.py
+++ b/test/xlog-py/lsn_gap.test.py
@@ -38,4 +38,3 @@ print("")
 
 # missing tuple from removed xlog
 server.admin("box.space.test:select{}")
-
-- 
2.25.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Tarantool-patches] [PATCH v3 1/5] test: convert print to function and make quotes use consistent
  2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 1/5] test: convert print to function and make quotes use consistent sergeyb
@ 2020-12-23 15:39   ` Vladislav Shpilevoy
  2020-12-24 10:50     ` Sergey Bronnikov
  0 siblings, 1 reply; 12+ messages in thread
From: Vladislav Shpilevoy @ 2020-12-23 15:39 UTC (permalink / raw)
  To: sergeyb, tarantool-patches, lvasiliev

Hi! Thanks for the patch!

> diff --git a/test/replication-py/swap.test.py b/test/replication-py/swap.test.py
> index 98eeeea6d..b162ae241 100644
> --- a/test/replication-py/swap.test.py
> +++ b/test/replication-py/swap.test.py
> @@ -7,26 +9,26 @@ import yaml
>  REPEAT = 20
>  ID_BEGIN = 0
>  ID_STEP = 5
> -LOGIN = 'test'
> -PASSWORD = 'pass123456'
> +LOGIN = "test"
> +PASSWORD = "pass123456"
>  
> -engines = ['memtx', 'vinyl']
> +engines = ["memtx", "vinyl"]
>  
>  def insert_tuples(_server, begin, end, msg = "tuple"):
>      for engine in engines:
>          for i in range(begin, end):
> -            print 'box.space.%s:insert{%d, "%s %d"}' % (engine, i, msg, i)
> -            print '-'
> +            print('box.space.{}:insert{{{}, "{} {}"}}'.format(engine, i, msg, i))

Oh, noooo! There is still ' instead of " !!!

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Tarantool-patches] [PATCH v3 3/5] test: make strings compatible with Python 3
  2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 3/5] test: make strings compatible with Python 3 sergeyb
@ 2020-12-23 15:40   ` Vladislav Shpilevoy
  2020-12-24 11:03     ` Sergey Bronnikov
  0 siblings, 1 reply; 12+ messages in thread
From: Vladislav Shpilevoy @ 2020-12-23 15:40 UTC (permalink / raw)
  To: sergeyb, tarantool-patches, lvasiliev

Thanks for the patch!

See 3 comments below.

> diff --git a/test/box-py/iproto.test.py b/test/box-py/iproto.test.py
> index 6723e03f5..c518b0d73 100644
> --- a/test/box-py/iproto.test.py
> +++ b/test/box-py/iproto.test.py
> @@ -197,16 +197,19 @@ for test in TESTS:
>      print("STR", size)
>      print("--")
>      for fmt in it:
> -        print("0x" + fmt.encode("hex"), "=>", end=" ")
> +        if sys.version[0] == '2':

1. '2' -> "2". It is a normal string, not byte string. Correct?

> +            print("0x" + fmt.encode("hex"), "=>", end=" ")
> +        else:
> +            print("0x" + fmt.hex(), "=>", end=" ")
>          field = "*" * size
> -        c._send_request(RawInsert(c, space_id, "\x91" + fmt + field))
> +        c._send_request(RawInsert(c, space_id, b'\x91' + fmt + field.encode("utf-8")))
>          tuple = space.select(field)[0]
>          print(len(tuple[0])== size and "ok" or "fail", end=" ")
>          it2 = iter(test)
>          next(it2)
>          for fmt2 in it2:
>              tuple = c._send_request(RawSelect(c, space_id,
> -                "\x91" + fmt2 + field))[0]
> +                b'\x91' + fmt2 + field.encode("utf-8")))[0]
>              print(len(tuple[0]) == size and "ok" or "fail", end=" ")
>          tuple = space.delete(field)[0]
>          print(len(tuple[0]) == size and "ok" or "fail", end="")
> @@ -357,15 +360,18 @@ s = c._socket
>  header = { "hello": "world"}
>  body = { "bug": 272 }
>  resp = test_request(header, body)
> -print("sync={}, {}".format(resp["header"][IPROTO_SYNC], resp["body"].get(IPROTO_ERROR)))
> +print("sync={}, {}".format(resp["header"][IPROTO_SYNC],
> +        resp["body"].get(IPROTO_ERROR).decode("utf-8")))

2. It seems this file used 4 char indentation. Lets conform.

>  header = { IPROTO_CODE : REQUEST_TYPE_SELECT }
>  header[IPROTO_SYNC] = 1234
>  resp = test_request(header, body)
> -print("sync={}, {}".format(resp["header"][IPROTO_SYNC], resp["body"].get(IPROTO_ERROR)))
> +print("sync={}, {}".format(resp["header"][IPROTO_SYNC],
> +        resp["body"].get(IPROTO_ERROR).decode("utf-8")))
>  header[IPROTO_SYNC] = 5678
>  body = { IPROTO_SPACE_ID: 304, IPROTO_KEY: [], IPROTO_LIMIT: 1 }
>  resp = test_request(header, body)
> -print("sync={}, {}".format(resp["header"][IPROTO_SYNC], resp["body"].get(IPROTO_ERROR)))
> +print("sync={}, {}".format(resp["header"][IPROTO_SYNC],
> +        resp["body"].get(IPROTO_ERROR).decode("utf-8")))
>  c.close()
>  
>  
> @@ -424,7 +430,10 @@ header = { IPROTO_CODE: REQUEST_TYPE_CALL, IPROTO_SYNC: 100 }
>  body = { IPROTO_FUNCTION_NAME: "kek" }
>  resp = test_request(header, body)
>  print("Sync: ", resp["header"][IPROTO_SYNC])
> -print("Retcode: ", resp["body"][IPROTO_DATA])
> +body = resp["body"][IPROTO_DATA]
> +if sys.version[0] == '3':

3. '3' -> "3".

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Tarantool-patches] [PATCH v3 0/5] Support Python 3 in tests and PEPify source code
  2020-12-23 12:36 [Tarantool-patches] [PATCH v3 0/5] Support Python 3 in tests and PEPify source code sergeyb
                   ` (4 preceding siblings ...)
  2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 5/5] test: remove dead code in Python tests end extra newlines sergeyb
@ 2020-12-23 23:42 ` Leonid Vasiliev
  2020-12-24 16:05 ` Vladislav Shpilevoy
  6 siblings, 0 replies; 12+ messages in thread
From: Leonid Vasiliev @ 2020-12-23 23:42 UTC (permalink / raw)
  To: sergeyb, tarantool-patches, v.shpilevoy; +Cc: Sergey Bronnikov

Hi! Thank you for the patchset.
LGTM.

On 23.12.2020 15:36, sergeyb@tarantool.org wrote:
> From: Sergey Bronnikov <estetus@gmail.com>
> 
> Changes v3:
> - added patch with migration iteritems() to items()
> - revert changes that updates .result files
> - rework patch with bytes strings
> 
> Changes v2:
> - make using quotes with strings consistent
> - remove dead code
> - remove empty prints
> - added make target for running flake8
> - added flake8 config
> - added job to run flake8 on Gitlab CI
> 
> Changes v1:
> - convert print statements to functions
> - use "format()" instead of "%" everywhere
> 
> Gitlab CI: https://gitlab.com/tarantool/tarantool/-/pipelines/233768577
> Branch: https://github.com/tarantool/tarantool/tree/ligurio/gh-5538-support-python3
> Issue: https://github.com/tarantool/tarantool/issues/5538
> 
> Sergey Bronnikov (5):
>    test: convert print to function and make quotes use consistent
>    test: make dict.items() compatible with Python 3.x
>    test: make strings compatible with Python 3
>    test: get rid of iteritems()
>    test: remove dead code in Python tests end extra newlines
> 
>   test/app-tap/httpd.py                    |  44 ++---
>   test/box-py/args.test.py                 |  12 +-
>   test/box-py/bad_trigger.test.py          |  16 +-
>   test/box-py/bootstrap.test.py            |  16 +-
>   test/box-py/call.test.py                 |  80 ++++----
>   test/box-py/iproto.test.py               | 239 ++++++++++++-----------
>   test/box-py/print.test.py                |  25 +--
>   test/box-py/snapshot.test.py             |  19 +-
>   test/long_run-py/finalizers.test.py      |  10 +-
>   test/replication-py/cluster.test.py      | 217 ++++++++++----------
>   test/replication-py/conflict.test.py     |  55 +++---
>   test/replication-py/init_storage.test.py |  58 +++---
>   test/replication-py/multi.test.py        |  78 ++++----
>   test/replication-py/swap.test.py         |  55 +++---
>   test/xlog-py/big_lsn.test.py             |   4 +-
>   test/xlog-py/dup_key.test.py             |  23 ++-
>   test/xlog-py/empty.test.py               |   4 +-
>   test/xlog-py/lsn_gap.test.py             |  11 +-
>   test/xlog-py/misc.test.py                |  26 +--
>   test/xlog-py/missing.test.py             |  10 +-
>   20 files changed, 518 insertions(+), 484 deletions(-)
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Tarantool-patches] [PATCH v3 1/5] test: convert print to function and make quotes use consistent
  2020-12-23 15:39   ` Vladislav Shpilevoy
@ 2020-12-24 10:50     ` Sergey Bronnikov
  0 siblings, 0 replies; 12+ messages in thread
From: Sergey Bronnikov @ 2020-12-24 10:50 UTC (permalink / raw)
  To: Vladislav Shpilevoy, tarantool-patches, lvasiliev

Thanks for review!

On 23.12.2020 18:39, Vladislav Shpilevoy wrote:
> Hi! Thanks for the patch!
>
>> diff --git a/test/replication-py/swap.test.py b/test/replication-py/swap.test.py
>> index 98eeeea6d..b162ae241 100644
>> --- a/test/replication-py/swap.test.py
>> +++ b/test/replication-py/swap.test.py
>> @@ -7,26 +9,26 @@ import yaml
>>   REPEAT = 20
>>   ID_BEGIN = 0
>>   ID_STEP = 5
>> -LOGIN = 'test'
>> -PASSWORD = 'pass123456'
>> +LOGIN = "test"
>> +PASSWORD = "pass123456"
>>   
>> -engines = ['memtx', 'vinyl']
>> +engines = ["memtx", "vinyl"]
>>   
>>   def insert_tuples(_server, begin, end, msg = "tuple"):
>>       for engine in engines:
>>           for i in range(begin, end):
>> -            print 'box.space.%s:insert{%d, "%s %d"}' % (engine, i, msg, i)
>> -            print '-'
>> +            print('box.space.{}:insert{{{}, "{} {}"}}'.format(engine, i, msg, i))
> Oh, noooo! There is still ' instead of " !!!

Fixed and force-pushed.

--- a/test/replication-py/swap.test.py
+++ b/test/replication-py/swap.test.py
@@ -17,7 +17,7 @@ engines = ["memtx", "vinyl"]
  def insert_tuples(_server, begin, end, msg = "tuple"):
      for engine in engines:
          for i in range(begin, end):
-            print('box.space.{}:insert{{{}, "{} {}"}}'.format(engine, 
i, msg, i))
+            print("box.space.{}:insert{{{}, \"{} {}\"}}".format(engine, 
i, msg, i))
              print("-")
              space = _server.iproto.py_con.space(engine)
              print(space.insert((i, "{} {}".format(msg, i))))

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Tarantool-patches] [PATCH v3 3/5] test: make strings compatible with Python 3
  2020-12-23 15:40   ` Vladislav Shpilevoy
@ 2020-12-24 11:03     ` Sergey Bronnikov
  0 siblings, 0 replies; 12+ messages in thread
From: Sergey Bronnikov @ 2020-12-24 11:03 UTC (permalink / raw)
  To: Vladislav Shpilevoy, tarantool-patches, lvasiliev

Thanks for review!

On 23.12.2020 18:40, Vladislav Shpilevoy wrote:
> Thanks for the patch!
>
> See 3 comments below.
>
>> diff --git a/test/box-py/iproto.test.py b/test/box-py/iproto.test.py
>> index 6723e03f5..c518b0d73 100644
>> --- a/test/box-py/iproto.test.py
>> +++ b/test/box-py/iproto.test.py
>> @@ -197,16 +197,19 @@ for test in TESTS:
>>       print("STR", size)
>>       print("--")
>>       for fmt in it:
>> -        print("0x" + fmt.encode("hex"), "=>", end=" ")
>> +        if sys.version[0] == '2':
> 1. '2' -> "2". It is a normal string, not byte string. Correct?

Yep.

--- a/test/box-py/iproto.test.py
+++ b/test/box-py/iproto.test.py
@@ -197,7 +197,7 @@ for test in TESTS:
      print("STR", size)
      print("--")
      for fmt in it:
-        if sys.version[0] == '2':
+        if sys.version[0] == "2":
              print("0x" + fmt.encode("hex"), "=>", end=" ")
          else:
              print("0x" + fmt.hex(), "=>", end=" ")

>> +            print("0x" + fmt.encode("hex"), "=>", end=" ")
>> +        else:
>> +            print("0x" + fmt.hex(), "=>", end=" ")
>>           field = "*" * size
>> -        c._send_request(RawInsert(c, space_id, "\x91" + fmt + field))
>> +        c._send_request(RawInsert(c, space_id, b'\x91' + fmt + field.encode("utf-8")))
>>           tuple = space.select(field)[0]
>>           print(len(tuple[0])== size and "ok" or "fail", end=" ")
>>           it2 = iter(test)
>>           next(it2)
>>           for fmt2 in it2:
>>               tuple = c._send_request(RawSelect(c, space_id,
>> -                "\x91" + fmt2 + field))[0]
>> +                b'\x91' + fmt2 + field.encode("utf-8")))[0]
>>               print(len(tuple[0]) == size and "ok" or "fail", end=" ")
>>           tuple = space.delete(field)[0]
>>           print(len(tuple[0]) == size and "ok" or "fail", end="")
>> @@ -357,15 +360,18 @@ s = c._socket
>>   header = { "hello": "world"}
>>   body = { "bug": 272 }
>>   resp = test_request(header, body)
>> -print("sync={}, {}".format(resp["header"][IPROTO_SYNC], resp["body"].get(IPROTO_ERROR)))
>> +print("sync={}, {}".format(resp["header"][IPROTO_SYNC],
>> +        resp["body"].get(IPROTO_ERROR).decode("utf-8")))
> 2. It seems this file used 4 char indentation. Lets conform.
it seems same indentation used in lines above and below, so I kept it as is.
>>   header = { IPROTO_CODE : REQUEST_TYPE_SELECT }
>>   header[IPROTO_SYNC] = 1234
>>   resp = test_request(header, body)
>> -print("sync={}, {}".format(resp["header"][IPROTO_SYNC], resp["body"].get(IPROTO_ERROR)))
>> +print("sync={}, {}".format(resp["header"][IPROTO_SYNC],
>> +        resp["body"].get(IPROTO_ERROR).decode("utf-8")))
>>   header[IPROTO_SYNC] = 5678
>>   body = { IPROTO_SPACE_ID: 304, IPROTO_KEY: [], IPROTO_LIMIT: 1 }
>>   resp = test_request(header, body)
>> -print("sync={}, {}".format(resp["header"][IPROTO_SYNC], resp["body"].get(IPROTO_ERROR)))
>> +print("sync={}, {}".format(resp["header"][IPROTO_SYNC],
>> +        resp["body"].get(IPROTO_ERROR).decode("utf-8")))
>>   c.close()
>>   
>>   
>> @@ -424,7 +430,10 @@ header = { IPROTO_CODE: REQUEST_TYPE_CALL, IPROTO_SYNC: 100 }
>>   body = { IPROTO_FUNCTION_NAME: "kek" }
>>   resp = test_request(header, body)
>>   print("Sync: ", resp["header"][IPROTO_SYNC])
>> -print("Retcode: ", resp["body"][IPROTO_DATA])
>> +body = resp["body"][IPROTO_DATA]
>> +if sys.version[0] == '3':
> 3. '3' -> "3".
@@ -431,7 +431,7 @@ body = { IPROTO_FUNCTION_NAME: "kek" }
  resp = test_request(header, body)
  print("Sync: ", resp["header"][IPROTO_SYNC])
  body = resp["body"][IPROTO_DATA]
-if sys.version[0] == '3':
+if sys.version[0] == "3":
      body = [body[0].decode("utf-8")]
  print("Retcode: ", body)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Tarantool-patches] [PATCH v3 0/5] Support Python 3 in tests and PEPify source code
  2020-12-23 12:36 [Tarantool-patches] [PATCH v3 0/5] Support Python 3 in tests and PEPify source code sergeyb
                   ` (5 preceding siblings ...)
  2020-12-23 23:42 ` [Tarantool-patches] [PATCH v3 0/5] Support Python 3 in tests and PEPify source code Leonid Vasiliev
@ 2020-12-24 16:05 ` Vladislav Shpilevoy
  6 siblings, 0 replies; 12+ messages in thread
From: Vladislav Shpilevoy @ 2020-12-24 16:05 UTC (permalink / raw)
  To: sergeyb, tarantool-patches, lvasiliev; +Cc: Sergey Bronnikov

Hi! Thanks for the patchset!

LGTM.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2020-12-24 16:05 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-23 12:36 [Tarantool-patches] [PATCH v3 0/5] Support Python 3 in tests and PEPify source code sergeyb
2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 1/5] test: convert print to function and make quotes use consistent sergeyb
2020-12-23 15:39   ` Vladislav Shpilevoy
2020-12-24 10:50     ` Sergey Bronnikov
2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 2/5] test: make dict.items() compatible with Python 3.x sergeyb
2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 3/5] test: make strings compatible with Python 3 sergeyb
2020-12-23 15:40   ` Vladislav Shpilevoy
2020-12-24 11:03     ` Sergey Bronnikov
2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 4/5] test: get rid of iteritems() sergeyb
2020-12-23 12:36 ` [Tarantool-patches] [PATCH v3 5/5] test: remove dead code in Python tests end extra newlines sergeyb
2020-12-23 23:42 ` [Tarantool-patches] [PATCH v3 0/5] Support Python 3 in tests and PEPify source code Leonid Vasiliev
2020-12-24 16:05 ` Vladislav Shpilevoy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox