Skip to content

Commit fec440f

Browse files
authored
Fix repr and add tests (#1296)
1 parent 3ecd038 commit fec440f

File tree

3 files changed

+73
-4
lines changed

3 files changed

+73
-4
lines changed

CHANGES.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
Version 3.1.2
2+
-------------
3+
4+
- Fix issue with calling ``repr()`` on ``SQLAlchemy`` instance with no default engine. :issue:`1295`
5+
6+
17
Version 3.1.1
28
-------------
39

src/flask_sqlalchemy/extension.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,12 +281,14 @@ def __repr__(self) -> str:
281281
if not has_app_context():
282282
return f"<{type(self).__name__}>"
283283

284-
message = f"{type(self).__name__} {self.engine.url}"
284+
num_default_engines = 1 if self.engines.get(None) else 0
285+
engine_str = self.engine.url if num_default_engines else "(No default engine)"
285286

286-
if len(self.engines) > 1:
287-
message = f"{message} +{len(self.engines) - 1}"
287+
num_other_engines = len(self.engines) - num_default_engines
288+
if num_other_engines >= 1:
289+
engine_str = f"{engine_str} +{num_other_engines} engines"
288290

289-
return f"<{message}>"
291+
return f"<{type(self).__name__} {engine_str}>"
290292

291293
def init_app(self, app: Flask) -> None:
292294
"""Initialize a Flask application for use with this extension instance. This

tests/test_extension_repr.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from __future__ import annotations
2+
3+
from flask import Flask
4+
5+
from flask_sqlalchemy import SQLAlchemy
6+
7+
8+
def test_repr_no_context() -> None:
9+
db = SQLAlchemy()
10+
app = Flask(__name__)
11+
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite://"
12+
13+
db.init_app(app)
14+
assert repr(db) == "<SQLAlchemy>"
15+
16+
17+
def test_repr_default() -> None:
18+
db = SQLAlchemy()
19+
app = Flask(__name__)
20+
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite://"
21+
22+
db.init_app(app)
23+
with app.app_context():
24+
assert repr(db) == "<SQLAlchemy sqlite://>"
25+
26+
27+
def test_repr_default_plustwo() -> None:
28+
db = SQLAlchemy()
29+
app = Flask(__name__)
30+
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite://"
31+
app.config["SQLALCHEMY_BINDS"] = {
32+
"a": "sqlite:///:memory:",
33+
"b": "sqlite:///test.db",
34+
}
35+
36+
db.init_app(app)
37+
with app.app_context():
38+
assert repr(db) == "<SQLAlchemy sqlite:// +2 engines>"
39+
40+
41+
def test_repr_nodefault() -> None:
42+
db = SQLAlchemy()
43+
app = Flask(__name__)
44+
app.config["SQLALCHEMY_BINDS"] = {"x": "sqlite:///:memory:"}
45+
46+
db.init_app(app)
47+
with app.app_context():
48+
assert repr(db) == "<SQLAlchemy (No default engine) +1 engines>"
49+
50+
51+
def test_repr_nodefault_plustwo() -> None:
52+
db = SQLAlchemy()
53+
app = Flask(__name__)
54+
app.config["SQLALCHEMY_BINDS"] = {
55+
"a": "sqlite:///:memory:",
56+
"b": "sqlite:///test.db",
57+
}
58+
59+
db.init_app(app)
60+
with app.app_context():
61+
assert repr(db) == "<SQLAlchemy (No default engine) +2 engines>"

0 commit comments

Comments
 (0)