mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Added Python 3.8 support. Fixes #5179
1) Upgraded passlib==1.7.1 to passlib==1.7.2 2) Replace unmaintained Flask-Security with maintained Flask-Security-Too package, which is also compatible with python 3.8 3) Other compatibility code changes.
This commit is contained in:
parent
1964e824c8
commit
915b09255c
@ -10,6 +10,7 @@ New features
|
||||
************
|
||||
|
||||
| `Issue #5170 <https://redmine.postgresql.org/issues/5170>`_ - Added Czech language support.
|
||||
| `Issue #5179 <https://redmine.postgresql.org/issues/5179>`_ - Added Python 3.8 support.
|
||||
|
||||
Housekeeping
|
||||
************
|
||||
|
@ -25,7 +25,7 @@ Flask-Principal==0.4.0
|
||||
Flask-SQLAlchemy==2.3.2
|
||||
Flask-WTF==0.14.3
|
||||
Flask-Compress==1.4.0
|
||||
passlib==1.7.1
|
||||
passlib==1.7.2
|
||||
pytz==2018.9
|
||||
simplejson==3.16.0
|
||||
six>=1.12.0
|
||||
@ -37,5 +37,5 @@ psutil==5.5.1
|
||||
psycopg2>=2.8
|
||||
python-dateutil>=2.8.0
|
||||
SQLAlchemy>=1.2.18
|
||||
Flask-Security>=3.0.0
|
||||
Flask-Security-Too>=3.0.0
|
||||
sshtunnel>=0.1.4
|
||||
|
@ -29,7 +29,7 @@ from flask_security.recoverable import reset_password_token_status, \
|
||||
from flask_security.signals import reset_password_instructions_sent
|
||||
from flask_security.utils import config_value, do_flash, get_url, \
|
||||
get_message, slash_url_suffix, login_user, send_mail
|
||||
from flask_security.views import _security, _commit, _render_json, _ctx
|
||||
from flask_security.views import _security, _commit, default_render_json, _ctx
|
||||
from werkzeug.datastructures import MultiDict
|
||||
|
||||
import config
|
||||
@ -952,7 +952,7 @@ if hasattr(config, 'SECURITY_CHANGEABLE') and config.SECURITY_CHANGEABLE:
|
||||
|
||||
if request.json and not has_error:
|
||||
form.user = current_user
|
||||
return _render_json(form)
|
||||
return default_render_json(form)
|
||||
|
||||
return _security.render_template(
|
||||
config_value('CHANGE_PASSWORD_TEMPLATE'),
|
||||
|
@ -569,7 +569,7 @@ class VacuumSettings:
|
||||
|
||||
for row in vacuum_settings_tmp:
|
||||
row_name = row['name']
|
||||
if type is 'toast':
|
||||
if type == 'toast':
|
||||
row_name = 'toast_{0}'.format(row['name'])
|
||||
if row_name in result and result[row_name] is not None:
|
||||
if row['column_type'] == 'number':
|
||||
|
@ -137,7 +137,7 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
|
||||
self.assertIn("from database 'pg_utility_test_db'", str(command))
|
||||
|
||||
# On windows a modified path may be shown so skip this test
|
||||
if os.name is not 'nt':
|
||||
if os.name != 'nt':
|
||||
self.assertIn("test_backup", str(command))
|
||||
|
||||
self.assertIn("pg_dump", str(command))
|
||||
@ -203,7 +203,7 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
|
||||
text
|
||||
|
||||
self.assertIn(self.server['name'], str(command))
|
||||
if os.name is not 'nt':
|
||||
if os.name != 'nt':
|
||||
self.assertIn("test_backup", str(command))
|
||||
|
||||
self.assertIn("pg_restore", str(command))
|
||||
|
@ -46,9 +46,9 @@ class BackupMessageTest(BaseTestGenerator):
|
||||
],
|
||||
cmd="/test_path/pg_dump"
|
||||
),
|
||||
extected_msg="Backing up the server"
|
||||
expected_msg="Backing up the server"
|
||||
" 'test_backup_server (localhost:5444)'",
|
||||
expetced_details_cmd='/test_path/pg_dump --file '
|
||||
expected_details_cmd='/test_path/pg_dump --file '
|
||||
'"backup_file" --host "localhost" '
|
||||
'--port "5444" --username "postgres" '
|
||||
'--no-password --database "postgres"'
|
||||
@ -79,9 +79,9 @@ class BackupMessageTest(BaseTestGenerator):
|
||||
],
|
||||
cmd="/test_path/pg_dump"
|
||||
),
|
||||
extected_msg="Backing up the global objects on the server "
|
||||
expected_msg="Backing up the global objects on the server "
|
||||
"'test_backup_server (localhost:5444)'",
|
||||
expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
|
||||
expected_details_cmd='/test_path/pg_dump --file "backup_file" '
|
||||
'--host "localhost"'
|
||||
' --port "5444" --username "postgres" '
|
||||
'--no-password --database "postgres"'
|
||||
@ -112,10 +112,10 @@ class BackupMessageTest(BaseTestGenerator):
|
||||
],
|
||||
cmd="/test_path/pg_dump"
|
||||
),
|
||||
extected_msg="Backing up an object on the server "
|
||||
expected_msg="Backing up an object on the server "
|
||||
"'test_backup_server (localhost:5444)'"
|
||||
" from database 'postgres'",
|
||||
expetced_details_cmd='/test_path/pg_dump --file "backup_file" '
|
||||
expected_details_cmd='/test_path/pg_dump --file "backup_file" '
|
||||
'--host "localhost" '
|
||||
'--port "5444" --username "postgres" '
|
||||
'--no-password --database "postgres"'
|
||||
@ -139,9 +139,9 @@ class BackupMessageTest(BaseTestGenerator):
|
||||
)
|
||||
|
||||
# Check the expected message returned
|
||||
self.assertEqual(backup_obj.message, self.extected_msg)
|
||||
self.assertEqual(backup_obj.message, self.expected_msg)
|
||||
|
||||
# Check the command
|
||||
obj_details = backup_obj.details(self.class_params['cmd'],
|
||||
self.class_params['args'])
|
||||
self.assertIn(self.expetced_details_cmd, obj_details)
|
||||
self.assertIn(self.expected_details_cmd, obj_details)
|
||||
|
@ -9,7 +9,8 @@
|
||||
|
||||
import sys
|
||||
|
||||
from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
|
||||
from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc, \
|
||||
current_app
|
||||
from pgadmin.tools.backup import BackupMessage, BACKUP
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from pickle import dumps, loads
|
||||
@ -108,22 +109,24 @@ class BatchProcessTest(BaseTestGenerator):
|
||||
|
||||
@patch('pgadmin.tools.backup.BackupMessage.get_server_details')
|
||||
@patch('pgadmin.misc.bgprocess.processes.Popen')
|
||||
@patch('pgadmin.misc.bgprocess.processes.current_app')
|
||||
@patch('pgadmin.misc.bgprocess.processes.db')
|
||||
@patch('pgadmin.tools.backup.current_user')
|
||||
@patch('pgadmin.misc.bgprocess.processes.current_user')
|
||||
def runTest(self, current_user_mock, current_user, db_mock,
|
||||
current_app_mock, popen_mock, get_server_details_mock):
|
||||
popen_mock, get_server_details_mock):
|
||||
with self.app.app_context():
|
||||
current_user.id = 1
|
||||
current_user_mock.id = 1
|
||||
current_app_mock.PGADMIN_RUNTIME = False
|
||||
current_app.PGADMIN_RUNTIME = False
|
||||
|
||||
def db_session_add_mock(j):
|
||||
cmd_obj = loads(j.desc)
|
||||
self.assertTrue(isinstance(cmd_obj, IProcessDesc))
|
||||
self.assertEqual(cmd_obj.backup_type, self.class_params['type'])
|
||||
self.assertEqual(cmd_obj.backup_type,
|
||||
self.class_params['type'])
|
||||
self.assertEqual(cmd_obj.bfile, self.class_params['bfile'])
|
||||
self.assertEqual(cmd_obj.database, self.class_params['database'])
|
||||
self.assertEqual(cmd_obj.database,
|
||||
self.class_params['database'])
|
||||
self.assertEqual(cmd_obj.cmd,
|
||||
' --file "backup_file" '
|
||||
'--host "{0}" '
|
||||
@ -141,8 +144,8 @@ class BatchProcessTest(BaseTestGenerator):
|
||||
db_mock.session.commit = MagicMock(return_value=True)
|
||||
|
||||
get_server_details_mock.return_value = \
|
||||
self.class_params['name'],\
|
||||
self.class_params['host'],\
|
||||
self.class_params['name'], \
|
||||
self.class_params['host'], \
|
||||
self.class_params['port']
|
||||
|
||||
backup_obj = BackupMessage(
|
||||
|
@ -9,7 +9,8 @@
|
||||
|
||||
import sys
|
||||
|
||||
from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
|
||||
from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc, \
|
||||
current_app
|
||||
from pgadmin.tools.maintenance import Message
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from pickle import dumps, loads
|
||||
@ -52,19 +53,19 @@ class BatchProcessTest(BaseTestGenerator):
|
||||
cmd="VACUUM VERBOSE;\n"
|
||||
),
|
||||
expected_msg="Maintenance (Vacuum)",
|
||||
expetced_details_cmd='VACUUM VERBOSE;'
|
||||
expected_details_cmd='VACUUM VERBOSE;'
|
||||
))
|
||||
]
|
||||
|
||||
@patch('pgadmin.misc.bgprocess.processes.Popen')
|
||||
@patch('pgadmin.misc.bgprocess.processes.current_app')
|
||||
@patch('pgadmin.misc.bgprocess.processes.db')
|
||||
@patch('pgadmin.tools.maintenance.Server')
|
||||
@patch('pgadmin.misc.bgprocess.processes.current_user')
|
||||
def runTest(self, current_user_mock, server_mock, db_mock,
|
||||
current_app_mock, popen_mock):
|
||||
popen_mock):
|
||||
with self.app.app_context():
|
||||
current_user_mock.id = 1
|
||||
current_app_mock.PGADMIN_RUNTIME = False
|
||||
current_app.PGADMIN_RUNTIME = False
|
||||
|
||||
class TestMockServer():
|
||||
def __init__(self, name, host, port):
|
||||
|
@ -28,8 +28,8 @@ class MaintenanceMessageTest(BaseTestGenerator):
|
||||
},
|
||||
cmd="VACUUM VERBOSE;\n"
|
||||
),
|
||||
extected_msg="Maintenance (Vacuum)",
|
||||
expetced_details_cmd='VACUUM VERBOSE;'
|
||||
expected_msg="Maintenance (Vacuum)",
|
||||
expected_details_cmd='VACUUM VERBOSE;'
|
||||
|
||||
)),
|
||||
('When maintained the server with FULL VERBOSE options',
|
||||
@ -46,8 +46,8 @@ class MaintenanceMessageTest(BaseTestGenerator):
|
||||
},
|
||||
cmd="VACUUM FULL VERBOSE;\n"
|
||||
),
|
||||
extected_msg="Maintenance (Vacuum)",
|
||||
expetced_details_cmd='VACUUM FULL VERBOSE;'
|
||||
expected_msg="Maintenance (Vacuum)",
|
||||
expected_details_cmd='VACUUM FULL VERBOSE;'
|
||||
|
||||
)),
|
||||
('When maintained the server with ANALYZE',
|
||||
@ -64,8 +64,8 @@ class MaintenanceMessageTest(BaseTestGenerator):
|
||||
},
|
||||
cmd="ANALYZE VERBOSE;\n"
|
||||
),
|
||||
extected_msg="Maintenance (Analyze)",
|
||||
expetced_details_cmd='ANALYZE VERBOSE;'
|
||||
expected_msg="Maintenance (Analyze)",
|
||||
expected_details_cmd='ANALYZE VERBOSE;'
|
||||
|
||||
)),
|
||||
('When maintained the server with REINDEX',
|
||||
@ -82,8 +82,8 @@ class MaintenanceMessageTest(BaseTestGenerator):
|
||||
},
|
||||
cmd="REINDEX;\n"
|
||||
),
|
||||
extected_msg="Maintenance (Reindex)",
|
||||
expetced_details_cmd='REINDEX;'
|
||||
expected_msg="Maintenance (Reindex)",
|
||||
expected_details_cmd='REINDEX;'
|
||||
|
||||
)),
|
||||
('When maintained the server with CLUSTER',
|
||||
@ -100,8 +100,8 @@ class MaintenanceMessageTest(BaseTestGenerator):
|
||||
},
|
||||
cmd="CLUSTER VERBOSE;\n"
|
||||
),
|
||||
extected_msg="Maintenance (Cluster)",
|
||||
expetced_details_cmd='CLUSTER VERBOSE;'
|
||||
expected_msg="Maintenance (Cluster)",
|
||||
expected_details_cmd='CLUSTER VERBOSE;'
|
||||
|
||||
)),
|
||||
]
|
||||
@ -114,8 +114,8 @@ class MaintenanceMessageTest(BaseTestGenerator):
|
||||
)
|
||||
|
||||
# Check the expected message returned
|
||||
self.assertEqual(maintenance_obj.message, self.extected_msg)
|
||||
self.assertEqual(maintenance_obj.message, self.expected_msg)
|
||||
|
||||
# Check the command
|
||||
obj_details = maintenance_obj.details(self.class_params['cmd'], None)
|
||||
self.assertIn(self.expetced_details_cmd, obj_details)
|
||||
self.assertIn(self.expected_details_cmd, obj_details)
|
||||
|
@ -9,7 +9,8 @@
|
||||
|
||||
import sys
|
||||
|
||||
from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc
|
||||
from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc, \
|
||||
current_app
|
||||
from pgadmin.tools.restore import RestoreMessage
|
||||
from pgadmin.utils.route import BaseTestGenerator
|
||||
from pickle import dumps, loads
|
||||
@ -53,15 +54,15 @@ class BatchProcessTest(BaseTestGenerator):
|
||||
|
||||
@patch('pgadmin.tools.restore.RestoreMessage.get_server_details')
|
||||
@patch('pgadmin.misc.bgprocess.processes.Popen')
|
||||
@patch('pgadmin.misc.bgprocess.processes.current_app')
|
||||
@patch('pgadmin.misc.bgprocess.processes.db')
|
||||
@patch('pgadmin.tools.restore.current_user')
|
||||
@patch('pgadmin.misc.bgprocess.processes.current_user')
|
||||
def runTest(self, current_user_mock, current_user, db_mock,
|
||||
current_app_mock, popen_mock, get_server_details_mock):
|
||||
popen_mock, get_server_details_mock):
|
||||
with self.app.app_context():
|
||||
current_user.id = 1
|
||||
current_user_mock.id = 1
|
||||
current_app_mock.PGADMIN_RUNTIME = False
|
||||
current_app.PGADMIN_RUNTIME = False
|
||||
|
||||
def db_session_add_mock(j):
|
||||
cmd_obj = loads(j.desc)
|
||||
@ -81,8 +82,8 @@ class BatchProcessTest(BaseTestGenerator):
|
||||
))
|
||||
|
||||
get_server_details_mock.return_value = \
|
||||
self.class_params['name'],\
|
||||
self.class_params['host'],\
|
||||
self.class_params['name'], \
|
||||
self.class_params['host'], \
|
||||
self.class_params['port']
|
||||
|
||||
db_mock.session.add.side_effect = db_session_add_mock
|
||||
|
@ -45,9 +45,9 @@ class RestoreMessageTest(BaseTestGenerator):
|
||||
],
|
||||
cmd="/test_path/pg_restore"
|
||||
),
|
||||
extected_msg="Restoring backup on the server "
|
||||
expected_msg="Restoring backup on the server "
|
||||
"'test_restore_server (localhost:5444)'",
|
||||
expetced_details_cmd='/test_path/pg_restore --file '
|
||||
expected_details_cmd='/test_path/pg_restore --file '
|
||||
'"restore_file" --host "localhost"'
|
||||
' --port "5444" --username "postgres" '
|
||||
'--no-password --database "postgres"'
|
||||
@ -69,9 +69,9 @@ class RestoreMessageTest(BaseTestGenerator):
|
||||
)
|
||||
|
||||
# Check the expected message returned
|
||||
self.assertEqual(restore_obj.message, self.extected_msg)
|
||||
self.assertEqual(restore_obj.message, self.expected_msg)
|
||||
|
||||
# Check the command
|
||||
obj_details = restore_obj.details(self.class_params['cmd'],
|
||||
self.class_params['args'])
|
||||
self.assertIn(self.expetced_details_cmd, obj_details)
|
||||
self.assertIn(self.expected_details_cmd, obj_details)
|
||||
|
@ -1652,7 +1652,7 @@ Failed to reset the connection to the server due to following error:
|
||||
resp.append(self.__notices.pop(0))
|
||||
|
||||
for notify in self.__notifies:
|
||||
if notify.payload is not None and notify.payload is not '':
|
||||
if notify.payload is not None and notify.payload != '':
|
||||
notify_msg = gettext(
|
||||
"Asynchronous notification \"{0}\" with payload \"{1}\" "
|
||||
"received from server process with PID {2}\n"
|
||||
@ -1725,7 +1725,7 @@ Failed to reset the connection to the server due to following error:
|
||||
# if formatted_msg is false then return from the function
|
||||
if not formatted_msg:
|
||||
notices = self.get_notices()
|
||||
return errmsg if notices is '' else notices + '\n' + errmsg
|
||||
return errmsg if notices == '' else notices + '\n' + errmsg
|
||||
|
||||
# Do not append if error starts with `ERROR:` as most pg related
|
||||
# error starts with `ERROR:`
|
||||
@ -1789,7 +1789,7 @@ Failed to reset the connection to the server due to following error:
|
||||
errmsg += self.decode_to_utf8(exception_obj.diag.context)
|
||||
|
||||
notices = self.get_notices()
|
||||
return errmsg if notices is '' else notices + '\n' + errmsg
|
||||
return errmsg if notices == '' else notices + '\n' + errmsg
|
||||
|
||||
#####
|
||||
# As per issue reported on pgsycopg2 github repository link is shared below
|
||||
|
@ -9,9 +9,13 @@
|
||||
|
||||
"""Utilities for HTML"""
|
||||
|
||||
import cgi
|
||||
from pgadmin.utils import IS_PY2
|
||||
|
||||
if IS_PY2:
|
||||
from cgi import escape as html_escape
|
||||
else:
|
||||
from html import escape as html_escape
|
||||
|
||||
|
||||
def safe_str(x):
|
||||
try:
|
||||
@ -32,4 +36,4 @@ def safe_str(x):
|
||||
x = x.decode('utf-8')
|
||||
except Exception:
|
||||
pass
|
||||
return cgi.escape(x)
|
||||
return html_escape(x, False)
|
||||
|
Loading…
Reference in New Issue
Block a user