Remove obsolete python code (<3.6). (#571)

This commit is contained in:
Rémy HUBSCHER 2020-04-24 12:32:52 +02:00 committed by GitHub
parent abf1eea842
commit 7587e292fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 51 additions and 72 deletions

View file

@ -1,7 +1,6 @@
sudo: false sudo: false
language: python language: python
python: python:
- "3.5"
- "3.6" - "3.6"
- "3.7" - "3.7"
- "3.8" - "3.8"

View file

@ -21,7 +21,7 @@ encouraged to do so.
Requirements Requirements
============ ============
* **Python**: 3.5, 3.6, 3.7. * **Python**: 3.6, 3.7, 3.8.
* **Backends**: MySQL, PostgreSQL, SQLite, Memory. * **Backends**: MySQL, PostgreSQL, SQLite, Memory.
Contributing Contributing

View file

@ -1,7 +1,3 @@
# coding: utf8
import os
import sys
templates_path = ["_templates"] templates_path = ["_templates"]
source_suffix = ".rst" source_suffix = ".rst"
master_doc = "index" master_doc = "index"

View file

@ -1,4 +1,3 @@
# coding: utf8
from functools import wraps from functools import wraps
from flask import current_app, request from flask import current_app, request

View file

@ -1,4 +1,3 @@
# coding: utf8
from flask import Blueprint from flask import Blueprint
from flask_cors import CORS from flask_cors import CORS
from flask_restful import Api from flask_restful import Api

View file

@ -51,7 +51,7 @@ class GenerateConfig(Command):
def run(self, config_file): def run(self, config_file):
env = create_jinja_env("conf-templates", strict_rendering=True) env = create_jinja_env("conf-templates", strict_rendering=True)
template = env.get_template("%s.j2" % config_file) template = env.get_template(f"{config_file}.j2")
bin_path = os.path.dirname(sys.executable) bin_path = os.path.dirname(sys.executable)
pkg_path = os.path.abspath(os.path.dirname(__file__)) pkg_path = os.path.abspath(os.path.dirname(__file__))

View file

@ -323,7 +323,7 @@ class Project(db.Model):
return self.name return self.name
def __repr__(self): def __repr__(self):
return "<Project %s>" % self.name return f"<Project {self.name}>"
class Person(db.Model): class Person(db.Model):
@ -381,7 +381,7 @@ class Person(db.Model):
return self.name return self.name
def __repr__(self): def __repr__(self):
return "<Person %s for project %s>" % (self.name, self.project.name) return f"<Person {self.name} for project {self.project.name}>"
# We need to manually define a join table for m2m relations # We need to manually define a join table for m2m relations
@ -460,13 +460,12 @@ class Bill(db.Model):
return 0 return 0
def __str__(self): def __str__(self):
return "%s for %s" % (self.amount, self.what) return f"{self.amount} for {self.what}"
def __repr__(self): def __repr__(self):
return "<Bill of %s from %s for %s>" % ( return (
self.amount, f"<Bill of {self.amount} from {self.payer} for "
self.payer, f"{', '.join([o.name for o in self.owers])}>"
", ".join([o.name for o in self.owers]),
) )

View file

@ -1,4 +1,3 @@
# coding: utf8
import base64 import base64
from collections import defaultdict from collections import defaultdict
import datetime import datetime
@ -59,7 +58,7 @@ class BaseTestCase(TestCase):
"name": name, "name": name,
"id": name, "id": name,
"password": name, "password": name,
"contact_email": "%s@notmyidea.org" % name, "contact_email": f"{name}@notmyidea.org",
}, },
) )
@ -68,7 +67,7 @@ class BaseTestCase(TestCase):
id=name, id=name,
name=str(name), name=str(name),
password=generate_password_hash(name), password=generate_password_hash(name),
contact_email="%s@notmyidea.org" % name, contact_email=f"{name}@notmyidea.org",
) )
models.db.session.add(project) models.db.session.add(project)
models.db.session.commit() models.db.session.commit()
@ -83,7 +82,7 @@ class IhatemoneyTestCase(BaseTestCase):
return self.assertEqual( return self.assertEqual(
expected, expected,
resp.status_code, resp.status_code,
"%s expected %s, got %s" % (url, expected, resp.status_code), f"{url} expected {expected}, got {resp.status_code}",
) )
@ -410,7 +409,7 @@ class BudgetTestCase(IhatemoneyTestCase):
) )
# remove fred # remove fred
self.client.post("/raclette/members/%s/delete" % fred_id) self.client.post(f"/raclette/members/{fred_id}/delete")
# he is still in the database, but is deactivated # he is still in the database, but is deactivated
self.assertEqual(len(models.Project.query.get("raclette").members), 2) self.assertEqual(len(models.Project.query.get("raclette").members), 2)
@ -420,7 +419,7 @@ class BudgetTestCase(IhatemoneyTestCase):
# a bill or displaying the balance # a bill or displaying the balance
result = self.client.get("/raclette/") result = self.client.get("/raclette/")
self.assertNotIn( self.assertNotIn(
("/raclette/members/%s/delete" % fred_id), result.data.decode("utf-8") (f"/raclette/members/{fred_id}/delete"), result.data.decode("utf-8")
) )
result = self.client.get("/raclette/add") result = self.client.get("/raclette/add")
@ -619,7 +618,7 @@ class BudgetTestCase(IhatemoneyTestCase):
# edit the bill # edit the bill
self.client.post( self.client.post(
"/raclette/edit/%s" % bill.id, f"/raclette/edit/{bill.id}",
data={ data={
"date": "2011-08-10", "date": "2011-08-10",
"what": "fromage à raclette", "what": "fromage à raclette",
@ -633,7 +632,7 @@ class BudgetTestCase(IhatemoneyTestCase):
self.assertEqual(bill.amount, 10, "bill edition") self.assertEqual(bill.amount, 10, "bill edition")
# delete the bill # delete the bill
self.client.get("/raclette/delete/%s" % bill.id) self.client.get(f"/raclette/delete/{bill.id}")
self.assertEqual(0, len(models.Bill.query.all()), "bill deletion") self.assertEqual(0, len(models.Bill.query.all()), "bill deletion")
# test balance # test balance
@ -1079,7 +1078,7 @@ class BudgetTestCase(IhatemoneyTestCase):
self.assertNotEqual( self.assertNotEqual(
0.0, 0.0,
rounded_amount, rounded_amount,
msg="%f is equal to zero after rounding" % t["amount"], msg=f"{t['amount']} is equal to zero after rounding",
) )
def test_export(self): def test_export(self):
@ -1417,7 +1416,7 @@ class APITestCase(IhatemoneyTestCase):
def api_create(self, name, id=None, password=None, contact=None): def api_create(self, name, id=None, password=None, contact=None):
id = id or name id = id or name
password = password or name password = password or name
contact = contact or "%s@notmyidea.org" % name contact = contact or f"{name}@notmyidea.org"
return self.client.post( return self.client.post(
"/api/projects", "/api/projects",
@ -1431,7 +1430,7 @@ class APITestCase(IhatemoneyTestCase):
def api_add_member(self, project, name, weight=1): def api_add_member(self, project, name, weight=1):
self.client.post( self.client.post(
"/api/projects/%s/members" % project, f"/api/projects/{project}/members",
data={"name": name, "weight": weight}, data={"name": name, "weight": weight},
headers=self.get_auth(project), headers=self.get_auth(project),
) )
@ -1439,11 +1438,11 @@ class APITestCase(IhatemoneyTestCase):
def get_auth(self, username, password=None): def get_auth(self, username, password=None):
password = password or username password = password or username
base64string = ( base64string = (
base64.encodebytes(("%s:%s" % (username, password)).encode("utf-8")) base64.encodebytes(f"{username}:{password}".encode("utf-8"))
.decode("utf-8") .decode("utf-8")
.replace("\n", "") .replace("\n", "")
) )
return {"Authorization": "Basic %s" % base64string} return {"Authorization": f"Basic {base64string}"}
def test_cors_requests(self): def test_cors_requests(self):
# Create a project and test that CORS headers are present if requested. # Create a project and test that CORS headers are present if requested.
@ -1599,7 +1598,7 @@ class APITestCase(IhatemoneyTestCase):
# Access with token # Access with token
resp = self.client.get( resp = self.client.get(
"/api/projects/raclette/token", "/api/projects/raclette/token",
headers={"Authorization": "Basic %s" % decoded_resp["token"]}, headers={"Authorization": f"Basic {decoded_resp['token']}"},
) )
self.assertEqual(200, resp.status_code) self.assertEqual(200, resp.status_code)
@ -2124,10 +2123,10 @@ class APITestCase(IhatemoneyTestCase):
resp = self.client.get("/raclette/history", follow_redirects=True) resp = self.client.get("/raclette/history", follow_redirects=True)
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
self.assertIn( self.assertIn(
"Person %s added" % em_surround("alexis"), resp.data.decode("utf-8") f"Person {em_surround('alexis')} added", resp.data.decode("utf-8")
) )
self.assertIn( self.assertIn(
"Project %s added" % em_surround("raclette"), resp.data.decode("utf-8"), f"Project {em_surround('raclette')} added", resp.data.decode("utf-8"),
) )
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 2) self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 2)
self.assertNotIn("127.0.0.1", resp.data.decode("utf-8")) self.assertNotIn("127.0.0.1", resp.data.decode("utf-8"))
@ -2263,7 +2262,7 @@ class HistoryTestCase(IhatemoneyTestCase):
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
self.assertIn( self.assertIn(
"Project %s added" % em_surround("demo"), resp.data.decode("utf-8"), f"Project {em_surround('demo')} added", resp.data.decode("utf-8"),
) )
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 1) self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 1)
self.assertNotIn("127.0.0.1", resp.data.decode("utf-8")) self.assertNotIn("127.0.0.1", resp.data.decode("utf-8"))
@ -2319,7 +2318,7 @@ class HistoryTestCase(IhatemoneyTestCase):
self.assertNotIn("127.0.0.1", resp.data.decode("utf-8")) self.assertNotIn("127.0.0.1", resp.data.decode("utf-8"))
self.assertNotIn("<td> -- </td>", resp.data.decode("utf-8")) self.assertNotIn("<td> -- </td>", resp.data.decode("utf-8"))
self.assertNotIn( self.assertNotIn(
"Project %s added" % em_surround("demo"), resp.data.decode("utf-8") f"Project {em_surround('demo')} added", resp.data.decode("utf-8")
) )
def test_project_edit(self): def test_project_edit(self):
@ -2335,18 +2334,16 @@ class HistoryTestCase(IhatemoneyTestCase):
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
self.assertIn(f"Project {em_surround('demo')} added", resp.data.decode("utf-8"))
self.assertIn( self.assertIn(
"Project %s added" % em_surround("demo"), resp.data.decode("utf-8") f"Project contact email changed to {em_surround('demo2@notmyidea.org')}",
)
self.assertIn(
"Project contact email changed to %s" % em_surround("demo2@notmyidea.org"),
resp.data.decode("utf-8"), resp.data.decode("utf-8"),
) )
self.assertIn( self.assertIn(
"Project private code changed", resp.data.decode("utf-8"), "Project private code changed", resp.data.decode("utf-8"),
) )
self.assertIn( self.assertIn(
"Project renamed to %s" % em_surround("demo2"), resp.data.decode("utf-8"), f"Project renamed to {em_surround('demo2')}", resp.data.decode("utf-8"),
) )
self.assertLess( self.assertLess(
resp.data.decode("utf-8").index("Project renamed "), resp.data.decode("utf-8").index("Project renamed "),
@ -2462,7 +2459,7 @@ class HistoryTestCase(IhatemoneyTestCase):
# edit the bill # edit the bill
resp = self.client.post( resp = self.client.post(
"/demo/edit/%i" % bill_id, f"/demo/edit/{bill_id}",
data={ data={
"date": "2011-08-10", "date": "2011-08-10",
"what": "fromage à raclette", "what": "fromage à raclette",
@ -2474,12 +2471,12 @@ class HistoryTestCase(IhatemoneyTestCase):
) )
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
# delete the bill # delete the bill
resp = self.client.get("/demo/delete/%i" % bill_id, follow_redirects=True) resp = self.client.get(f"/demo/delete/{bill_id}", follow_redirects=True)
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
# delete user using POST method # delete user using POST method
resp = self.client.post( resp = self.client.post(
"/demo/members/%i/delete" % user_id, follow_redirects=True f"/demo/members/{user_id}/delete", follow_redirects=True
) )
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
@ -2581,7 +2578,7 @@ class HistoryTestCase(IhatemoneyTestCase):
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
self.assertIn( self.assertIn(
"Person %s added" % em_surround("alexis"), resp.data.decode("utf-8") f"Person {em_surround('alexis')} added", resp.data.decode("utf-8")
) )
# create a bill # create a bill
@ -2601,7 +2598,7 @@ class HistoryTestCase(IhatemoneyTestCase):
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
self.assertIn( self.assertIn(
"Bill %s added" % em_surround("25.0 for fromage à raclette"), f"Bill {em_surround('25.0 for fromage à raclette')} added",
resp.data.decode("utf-8"), resp.data.decode("utf-8"),
) )
@ -2622,7 +2619,7 @@ class HistoryTestCase(IhatemoneyTestCase):
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
self.assertIn( self.assertIn(
"Bill %s added" % em_surround("25.0 for fromage à raclette"), f"Bill {em_surround('25.0 for fromage à raclette')} added",
resp.data.decode("utf-8"), resp.data.decode("utf-8"),
) )
self.assertRegex( self.assertRegex(
@ -2641,7 +2638,7 @@ class HistoryTestCase(IhatemoneyTestCase):
) )
self.assertLess( self.assertLess(
resp.data.decode("utf-8").index( resp.data.decode("utf-8").index(
"Bill %s renamed to" % em_surround("25.0 for fromage à raclette") f"Bill {em_surround('25.0 for fromage à raclette')} renamed to"
), ),
resp.data.decode("utf-8").index("Amount changed"), resp.data.decode("utf-8").index("Amount changed"),
) )
@ -2653,7 +2650,7 @@ class HistoryTestCase(IhatemoneyTestCase):
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
self.assertIn( self.assertIn(
"Bill %s removed" % em_surround("10.0 for new thing"), f"Bill {em_surround('10.0 for new thing')} removed",
resp.data.decode("utf-8"), resp.data.decode("utf-8"),
) )
@ -2682,9 +2679,7 @@ class HistoryTestCase(IhatemoneyTestCase):
resp.data.decode("utf-8"), resp.data.decode("utf-8"),
) )
self.assertLess( self.assertLess(
resp.data.decode("utf-8").index( resp.data.decode("utf-8").index(f"Person {em_surround('alexis')} renamed"),
"Person %s renamed" % em_surround("alexis")
),
resp.data.decode("utf-8").index("Weight changed"), resp.data.decode("utf-8").index("Weight changed"),
) )
@ -2695,7 +2690,7 @@ class HistoryTestCase(IhatemoneyTestCase):
resp = self.client.get("/demo/history") resp = self.client.get("/demo/history")
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
self.assertIn( self.assertIn(
"Person %s removed" % em_surround("new name"), resp.data.decode("utf-8") f"Person {em_surround('new name')} removed", resp.data.decode("utf-8")
) )
def test_double_bill_double_person_edit_second(self): def test_double_bill_double_person_edit_second(self):
@ -2748,8 +2743,7 @@ class HistoryTestCase(IhatemoneyTestCase):
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
self.assertRegex( self.assertRegex(
resp.data.decode("utf-8"), resp.data.decode("utf-8"),
r"Bill %s:\s* Amount changed\s* from %s\s* to %s" r"Bill {}:\s* Amount changed\s* from {}\s* to {}".format(
% (
em_surround("25.0 for Bill 1", regex_escape=True), em_surround("25.0 for Bill 1", regex_escape=True),
em_surround("25.0", regex_escape=True), em_surround("25.0", regex_escape=True),
em_surround("88.0", regex_escape=True), em_surround("88.0", regex_escape=True),
@ -2758,8 +2752,7 @@ class HistoryTestCase(IhatemoneyTestCase):
self.assertNotRegex( self.assertNotRegex(
resp.data.decode("utf-8"), resp.data.decode("utf-8"),
r"Removed\s* %s\s* and\s* %s\s* from\s* owers list" r"Removed\s* {}\s* and\s* {}\s* from\s* owers list".format(
% (
em_surround("User 1", regex_escape=True), em_surround("User 1", regex_escape=True),
em_surround("User 2", regex_escape=True), em_surround("User 2", regex_escape=True),
), ),
@ -2795,11 +2788,10 @@ class HistoryTestCase(IhatemoneyTestCase):
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 5) self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 5)
self.assertNotIn("127.0.0.1", resp.data.decode("utf-8")) self.assertNotIn("127.0.0.1", resp.data.decode("utf-8"))
self.assertIn( self.assertIn(
"Bill %s added" % em_surround("25.0 for Bill 1"), resp.data.decode("utf-8") f"Bill {em_surround('25.0 for Bill 1')} added", resp.data.decode("utf-8")
) )
self.assertIn( self.assertIn(
"Bill %s removed" % em_surround("25.0 for Bill 1"), f"Bill {em_surround('25.0 for Bill 1')} removed", resp.data.decode("utf-8"),
resp.data.decode("utf-8"),
) )
# Add a new bill # Add a new bill
@ -2819,20 +2811,19 @@ class HistoryTestCase(IhatemoneyTestCase):
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 6) self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 6)
self.assertNotIn("127.0.0.1", resp.data.decode("utf-8")) self.assertNotIn("127.0.0.1", resp.data.decode("utf-8"))
self.assertIn( self.assertIn(
"Bill %s added" % em_surround("25.0 for Bill 1"), resp.data.decode("utf-8") f"Bill {em_surround('25.0 for Bill 1')} added", resp.data.decode("utf-8")
) )
self.assertEqual( self.assertEqual(
resp.data.decode("utf-8").count( resp.data.decode("utf-8").count(
"Bill %s added" % em_surround("25.0 for Bill 1") f"Bill {em_surround('25.0 for Bill 1')} added"
), ),
1, 1,
) )
self.assertIn( self.assertIn(
"Bill %s added" % em_surround("20.0 for Bill 2"), resp.data.decode("utf-8") f"Bill {em_surround('20.0 for Bill 2')} added", resp.data.decode("utf-8")
) )
self.assertIn( self.assertIn(
"Bill %s removed" % em_surround("25.0 for Bill 1"), f"Bill {em_surround('25.0 for Bill 1')} removed", resp.data.decode("utf-8"),
resp.data.decode("utf-8"),
) )
def test_double_bill_double_person_edit_second_no_web(self): def test_double_bill_double_person_edit_second_no_web(self):

View file

@ -301,9 +301,7 @@ def create_project():
project=g.project.name, project=g.project.name,
) )
message_body = render_template( message_body = render_template(f"reminder_mail.{get_locale().language}.j2")
"reminder_mail.%s.j2" % get_locale().language
)
msg = Message( msg = Message(
message_title, body=message_body, recipients=[project.contact_email] message_title, body=message_body, recipients=[project.contact_email]
@ -337,7 +335,7 @@ def remind_password():
# get the project # get the project
project = Project.query.get(form.id.data) project = Project.query.get(form.id.data)
# send a link to reset the password # send a link to reset the password
password_reminder = "password_reminder.%s.j2" % get_locale().language password_reminder = f"password_reminder.{get_locale().language}.j2"
current_app.mail.send( current_app.mail.send(
Message( Message(
"password recovery", "password recovery",
@ -520,7 +518,7 @@ def export_project(file, format):
return send_file( return send_file(
file2export, file2export,
attachment_filename="%s-%s.%s" % (g.project.id, file, format), attachment_filename=f"{g.project.id}-{file}.{format}",
as_attachment=True, as_attachment=True,
) )
@ -570,7 +568,7 @@ def invite():
# send the email # send the email
message_body = render_template( message_body = render_template(
"invitation_mail.%s.j2" % get_locale().language f"invitation_mail.{get_locale().language}.j2"
) )
message_title = _( message_title = _(

View file

@ -11,7 +11,6 @@ license = Custom BSD Beerware
classifiers = classifiers =
Programming Language :: Python Programming Language :: Python
Programming Language :: Python :: 3 Programming Language :: Python :: 3
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.8

View file

@ -1,5 +1,5 @@
[tox] [tox]
envlist = py38,py37,py36,py35,docs,flake8,black envlist = py38,py37,py36,docs,flake8,black
skip_missing_interpreters = True skip_missing_interpreters = True
[testenv] [testenv]
@ -39,7 +39,6 @@ extend-ignore =
[travis] [travis]
python = python =
3.5: py35
3.6: py36 3.6: py36
3.7: py37 3.7: py37
3.8: py38, docs, black, flake8 3.8: py38, docs, black, flake8