diff --git a/frappe/core/doctype/language/language.py b/frappe/core/doctype/language/language.py index 83d68acb36..8c7e01cb62 100644 --- a/frappe/core/doctype/language/language.py +++ b/frappe/core/doctype/language/language.py @@ -14,7 +14,7 @@ def export_languages_json(): languages = frappe.db.get_all('Language', fields=['name', 'language_name']) languages = [{'name': d.language_name, 'code': d.name} for d in languages] - languages.sort(lambda a,b: 1 if a['code'] > b['code'] else -1) + languages.sort(key = lambda a: a['code']) with open(frappe.get_app_path('frappe', 'geo', 'languages.json'), 'w') as f: f.write(frappe.as_json(languages)) diff --git a/frappe/core/page/data_import_tool/data_import_tool.py b/frappe/core/page/data_import_tool/data_import_tool.py index 0bf1e97bb2..8338848561 100644 --- a/frappe/core/page/data_import_tool/data_import_tool.py +++ b/frappe/core/page/data_import_tool/data_import_tool.py @@ -36,7 +36,7 @@ def import_file_by_path(path, ignore_links=False, overwrite=False, submit=False, def export_csv(doctype, path): from frappe.core.page.data_import_tool.exporter import get_template - with open(path, "w") as csvfile: + with open(path, "wb") as csvfile: get_template(doctype=doctype, all_doctypes="Yes", with_data="Yes") csvfile.write(frappe.response.result.encode("utf-8")) diff --git a/frappe/core/page/data_import_tool/exporter.py b/frappe/core/page/data_import_tool/exporter.py index 4f7bf8a067..7920059957 100644 --- a/frappe/core/page/data_import_tool/exporter.py +++ b/frappe/core/page/data_import_tool/exporter.py @@ -81,7 +81,7 @@ def get_template(doctype=None, parent_doctype=None, all_doctypes="No", with_data if field and ((select_columns and f[0] in select_columns[dt]) or not select_columns): tablecolumns.append(field) - tablecolumns.sort(lambda a, b: int(a.idx - b.idx)) + tablecolumns.sort(key = lambda a: int(a.idx)) _column_start_end = frappe._dict(start=0) diff --git a/frappe/custom/doctype/custom_field/custom_field.py b/frappe/custom/doctype/custom_field/custom_field.py index c81ad6cdf4..6eb3eef544 100644 --- a/frappe/custom/doctype/custom_field/custom_field.py +++ b/frappe/custom/doctype/custom_field/custom_field.py @@ -18,8 +18,8 @@ class CustomField(Document): if not self.label: frappe.throw(_("Label is mandatory")) # remove special characters from fieldname - self.fieldname = filter(lambda x: x.isdigit() or x.isalpha() or '_', - cstr(self.label).lower().replace(' ','_')) + self.fieldname = "".join(filter(lambda x: x.isdigit() or x.isalpha() or '_', + cstr(self.label).lower().replace(' ','_'))) # fieldnames should be lowercase self.fieldname = self.fieldname.lower() diff --git a/frappe/desk/doctype/desktop_icon/desktop_icon.py b/frappe/desk/doctype/desktop_icon/desktop_icon.py index 1319ffba49..0787af88f7 100644 --- a/frappe/desk/doctype/desktop_icon/desktop_icon.py +++ b/frappe/desk/doctype/desktop_icon/desktop_icon.py @@ -95,7 +95,7 @@ def get_desktop_icons(user=None): icon.hidden = 1 # sort by idx - user_icons.sort(lambda a, b: 1 if a.idx > b.idx else -1) + user_icons.sort(key = lambda a: a.idx) # translate for d in user_icons: diff --git a/frappe/desk/form/linked_with.py b/frappe/desk/form/linked_with.py index e5192b1edb..39850c4a16 100644 --- a/frappe/desk/form/linked_with.py +++ b/frappe/desk/form/linked_with.py @@ -119,7 +119,7 @@ def _get_linked_doctypes(doctype): if not dt in ret: ret[dt] = {"get_parent": True} - for dt in ret.keys(): + for dt in list(ret.keys()): try: doctype_module = load_doctype_module(dt) except ImportError: diff --git a/frappe/email/queue.py b/frappe/email/queue.py index 0452cba5bc..b0d903e770 100755 --- a/frappe/email/queue.py +++ b/frappe/email/queue.py @@ -478,7 +478,7 @@ def prepare_message(email, recipient, recipients_list): if email.add_unsubscribe_link and email.reference_doctype: # is missing the check for unsubscribe message but will not add as there will be no unsubscribe url unsubscribe_url = get_unsubcribed_url(email.reference_doctype, email.reference_name, recipient, email.unsubscribe_method, email.unsubscribe_params) - message = message.replace("", quopri.encodestring(unsubscribe_url)) + message = message.replace("", quopri.encodestring(unsubscribe_url.encode()).decode()) if email.expose_recipients == "header": pass @@ -494,7 +494,7 @@ def prepare_message(email, recipient, recipients_list): email_sent_message = _("This email was sent to {0} and copied to {1}").format(email_sent_to,email_sent_cc) else: email_sent_message = _("This email was sent to {0}").format(email_sent_to) - message = message.replace("", quopri.encodestring(email_sent_message)) + message = message.replace("", quopri.encodestring(email_sent_message.encode()).decode()) message = message.replace("", recipient) diff --git a/frappe/model/document.py b/frappe/model/document.py index 5b64796c5b..38dc71f73a 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -1004,7 +1004,7 @@ class Document(BaseDocument): def get_signature(self): """Returns signature (hash) for private URL.""" - return hashlib.sha224(get_datetime_str(self.creation)).hexdigest() + return hashlib.sha224(get_datetime_str(self.creation).encode()).hexdigest() def get_liked_by(self): liked_by = getattr(self, "_liked_by", None) diff --git a/frappe/translate.py b/frappe/translate.py index 6ddd7bf3b1..7f47954300 100644 --- a/frappe/translate.py +++ b/frappe/translate.py @@ -555,7 +555,7 @@ def write_csv_file(path, app_messages, lang_dict): :param app_messages: Translatable strings for this app. :param lang_dict: Full translated dict. """ - app_messages.sort(lambda x,y: cmp(x[1], y[1])) + app_messages.sort(key = lambda x: x[1]) from csv import writer with open(path, 'wb') as msgfile: w = writer(msgfile, lineterminator='\n') @@ -684,7 +684,7 @@ def deduplicate_messages(messages): op = operator.itemgetter(1) messages = sorted(messages, key=op) for k, g in itertools.groupby(messages, op): - ret.append(g.next()) + ret.append(next(g)) return ret def get_bench_dir(): diff --git a/frappe/utils/data.py b/frappe/utils/data.py index e2752f6dfe..6ca611be88 100644 --- a/frappe/utils/data.py +++ b/frappe/utils/data.py @@ -734,7 +734,7 @@ def get_filter(doctype, f): from frappe.model import default_fields, optional_fields if isinstance(f, dict): - key, value = f.items()[0] + key, value = next(iter(f.items())) f = make_filter_tuple(doctype, key, value) if not isinstance(f, (list, tuple)): diff --git a/frappe/utils/file_manager.py b/frappe/utils/file_manager.py index de0ebdf12f..822b63e240 100644 --- a/frappe/utils/file_manager.py +++ b/frappe/utils/file_manager.py @@ -301,6 +301,8 @@ def get_file_path(file_name): return file_path def get_content_hash(content): + if isinstance(content, text_type): + content = content.encode() return hashlib.md5(content).hexdigest() def get_file_name(fname, optional_suffix): diff --git a/frappe/utils/password_strength.py b/frappe/utils/password_strength.py index f94893ed53..5591cfbb14 100644 --- a/frappe/utils/password_strength.py +++ b/frappe/utils/password_strength.py @@ -3,14 +3,14 @@ from __future__ import unicode_literals -import zxcvbn +from zxcvbn import zxcvbn import frappe from frappe import _ def test_password_strength(password, user_inputs=None): '''Wrapper around zxcvbn.password_strength''' - result = zxcvbn.password_strength(password, user_inputs) - result['feedback'] = get_feedback(result['score'], result['match_sequence']) + result = zxcvbn(password, user_inputs) + result['feedback'] = get_feedback(result['score'], result['sequence']) return result # NOTE: code modified for frappe translations @@ -37,7 +37,7 @@ def get_feedback (score, sequence): """ Returns the feedback dictionary consisting of ("warning","suggestions") for the given sequences. """ - minimum_password_score = frappe.db.get_single_value("System Settings", "minimum_password_score") + minimum_password_score = int(frappe.db.get_single_value("System Settings", "minimum_password_score")) global default_feedback # Starting feedback diff --git a/frappe/utils/verified_command.py b/frappe/utils/verified_command.py index 08fe7c2ab6..31e2c80804 100644 --- a/frappe/utils/verified_command.py +++ b/frappe/utils/verified_command.py @@ -17,8 +17,8 @@ def get_signed_params(params): if not isinstance(params, string_types): params = urlencode(params) - signature = hmac.new(params) - signature.update(get_secret()) + signature = hmac.new(params.encode()) + signature.update(get_secret().encode()) return params + "&_signature=" + signature.hexdigest() def get_secret(): @@ -36,7 +36,7 @@ def verify_request(): given_signature = hmac.new(params.encode("utf-8")) - given_signature.update(get_secret()) + given_signature.update(get_secret().encode()) valid = signature == given_signature.hexdigest() if not valid: diff --git a/frappe/website/doctype/blog_post/test_blog_post.py b/frappe/website/doctype/blog_post/test_blog_post.py index a6c1668045..d38349ba07 100644 --- a/frappe/website/doctype/blog_post/test_blog_post.py +++ b/frappe/website/doctype/blog_post/test_blog_post.py @@ -17,7 +17,7 @@ class TestBlogPost(unittest.TestCase): self.assertTrue(response.status_code, 200) - html = response.get_data() + html = response.get_data().decode() self.assertTrue('
' in html) def test_generator_not_found(self): diff --git a/frappe/website/utils.py b/frappe/website/utils.py index 7a80d03f85..9388116c6a 100644 --- a/frappe/website/utils.py +++ b/frappe/website/utils.py @@ -19,7 +19,7 @@ def delete_page_cache(path): def find_first_image(html): m = re.finditer("""]*src\s?=\s?['"]([^'"]*)['"]""", html) try: - return m.next().groups()[0] + return next(m).groups()[0] except StopIteration: return None diff --git a/frappe/www/list.py b/frappe/www/list.py index 77975e73d6..073a3171c4 100644 --- a/frappe/www/list.py +++ b/frappe/www/list.py @@ -113,7 +113,7 @@ def prepare_filters(doctype, controller, kwargs): filters[key] = val # filter the filters to include valid fields only - for fieldname, val in filters.items(): + for fieldname, val in list(filters.items()): if not meta.has_field(fieldname): del filters[fieldname] diff --git a/requirements.txt b/requirements.txt index 44a441e34d..b5c564eede 100644 --- a/requirements.txt +++ b/requirements.txt @@ -37,7 +37,7 @@ cryptography pyopenssl ndg-httpsclient pyasn1 -zxcvbn +zxcvbn-python psutil unittest-xml-reporting oauthlib