Skip to content

Commit 53bad90

Browse files
authored
Settle 404 pages (#17811)
* Don't pre-compute the canonical URL Turns out content within Jinja blocks will get executed even if they are later replaced with another block. Additionally, if template rendering fails for a exception view, it falls back to a plain status response. Instead, use a request method to try and compute the canonical URL only if one was not provided, and gracefully handle the case where the canonical URL can't be constructed by not including a block at all. * Use request.canonical_url to simplify * Update translations * Add tests
1 parent e9e4c24 commit 53bad90

File tree

6 files changed

+92
-56
lines changed

6 files changed

+92
-56
lines changed

tests/unit/test_filters.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,3 +314,25 @@ def test_remove_invalid_xml_unicode(inp, expected):
314314
Test that invalid XML unicode characters are removed.
315315
"""
316316
assert filters.remove_invalid_xml_unicode(inp) == expected
317+
318+
319+
def test_canonical_url():
320+
request = pretend.stub(
321+
matched_route=pretend.stub(name="foo"),
322+
route_url=pretend.call_recorder(lambda a: "bar"),
323+
)
324+
assert filters._canonical_url(request) == "bar"
325+
assert request.route_url.calls == [pretend.call("foo")]
326+
327+
328+
def test_canonical_url_no_matched_route():
329+
request = pretend.stub(matched_route=None)
330+
assert filters._canonical_url(request) is None
331+
332+
333+
def test_canonical_url_missing_kwargs():
334+
request = pretend.stub(
335+
matched_route=pretend.stub(name="foo"),
336+
route_url=pretend.raiser(KeyError),
337+
)
338+
assert filters._canonical_url(request) is None

warehouse/filters.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,5 +203,14 @@ def remove_invalid_xml_unicode(value: str | None) -> str | None:
203203
return "".join(c for c in value if ord(c) >= 32) if value else value
204204

205205

206+
def _canonical_url(request, **kwargs):
207+
if request.matched_route:
208+
try:
209+
return request.route_url(request.matched_route.name, **kwargs)
210+
except KeyError:
211+
pass
212+
213+
206214
def includeme(config):
207215
config.add_request_method(_camo_url, name="camo_url")
216+
config.add_request_method(_canonical_url, name="canonical_url")

warehouse/locale/messages.pot

Lines changed: 52 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -948,14 +948,14 @@ msgstr ""
948948
#: warehouse/templates/404.html:34 warehouse/templates/500.html:28
949949
#: warehouse/templates/500.html:29
950950
#: warehouse/templates/accounts/two-factor.html:55
951-
#: warehouse/templates/base.html:280 warehouse/templates/base.html:281
952-
#: warehouse/templates/base.html:282 warehouse/templates/base.html:283
953-
#: warehouse/templates/base.html:293 warehouse/templates/base.html:294
954-
#: warehouse/templates/base.html:307 warehouse/templates/base.html:308
955-
#: warehouse/templates/base.html:310 warehouse/templates/base.html:319
956-
#: warehouse/templates/base.html:321 warehouse/templates/base.html:322
957-
#: warehouse/templates/base.html:323 warehouse/templates/base.html:333
958-
#: warehouse/templates/base.html:346
951+
#: warehouse/templates/base.html:285 warehouse/templates/base.html:286
952+
#: warehouse/templates/base.html:287 warehouse/templates/base.html:288
953+
#: warehouse/templates/base.html:298 warehouse/templates/base.html:299
954+
#: warehouse/templates/base.html:312 warehouse/templates/base.html:313
955+
#: warehouse/templates/base.html:315 warehouse/templates/base.html:324
956+
#: warehouse/templates/base.html:326 warehouse/templates/base.html:327
957+
#: warehouse/templates/base.html:328 warehouse/templates/base.html:338
958+
#: warehouse/templates/base.html:351
959959
#: warehouse/templates/includes/accounts/profile-callout.html:18
960960
#: warehouse/templates/includes/file-details.html:101
961961
#: warehouse/templates/index.html:100 warehouse/templates/index.html:104
@@ -1111,7 +1111,7 @@ msgid "Main navigation"
11111111
msgstr ""
11121112

11131113
#: warehouse/templates/base.html:41 warehouse/templates/base.html:55
1114-
#: warehouse/templates/base.html:277
1114+
#: warehouse/templates/base.html:282
11151115
#: warehouse/templates/includes/current-user-indicator.html:63
11161116
#: warehouse/templates/pages/help.html:119
11171117
#: warehouse/templates/pages/sitemap.html:27
@@ -1183,16 +1183,16 @@ msgstr ""
11831183
msgid "RSS: 40 newest packages"
11841184
msgstr ""
11851185

1186-
#: warehouse/templates/base.html:162
1186+
#: warehouse/templates/base.html:167
11871187
msgid "Skip to main content"
11881188
msgstr ""
11891189

1190-
#: warehouse/templates/base.html:165
1190+
#: warehouse/templates/base.html:170
11911191
msgid "Switch to mobile version"
11921192
msgstr ""
11931193

1194-
#: warehouse/templates/base.html:174 warehouse/templates/base.html:183
1195-
#: warehouse/templates/base.html:193
1194+
#: warehouse/templates/base.html:179 warehouse/templates/base.html:188
1195+
#: warehouse/templates/base.html:198
11961196
#: warehouse/templates/includes/flash-messages.html:30
11971197
#: warehouse/templates/includes/session-notifications.html:20
11981198
#: warehouse/templates/manage/account.html:843
@@ -1210,174 +1210,174 @@ msgstr ""
12101210
msgid "Warning"
12111211
msgstr ""
12121212

1213-
#: warehouse/templates/base.html:176
1213+
#: warehouse/templates/base.html:181
12141214
msgid "You are using an unsupported browser, upgrade to a newer version."
12151215
msgstr ""
12161216

1217-
#: warehouse/templates/base.html:185
1217+
#: warehouse/templates/base.html:190
12181218
msgid ""
12191219
"You are using TestPyPI – a separate instance of the Python Package Index "
12201220
"that allows you to try distribution tools and processes without affecting"
12211221
" the real index."
12221222
msgstr ""
12231223

1224-
#: warehouse/templates/base.html:195
1224+
#: warehouse/templates/base.html:200
12251225
msgid ""
12261226
"Some features may not work without JavaScript. Please try enabling it if "
12271227
"you encounter problems."
12281228
msgstr ""
12291229

1230-
#: warehouse/templates/base.html:233 warehouse/templates/base.html:254
1230+
#: warehouse/templates/base.html:238 warehouse/templates/base.html:259
12311231
#: warehouse/templates/error-base-with-search.html:20
12321232
#: warehouse/templates/index.html:43
12331233
msgid "Search PyPI"
12341234
msgstr ""
12351235

1236-
#: warehouse/templates/base.html:234 warehouse/templates/base.html:255
1236+
#: warehouse/templates/base.html:239 warehouse/templates/base.html:260
12371237
#: warehouse/templates/error-base-with-search.html:21
12381238
#: warehouse/templates/index.html:46
12391239
msgid "Search projects"
12401240
msgstr ""
12411241

1242-
#: warehouse/templates/base.html:238 warehouse/templates/base.html:259
1242+
#: warehouse/templates/base.html:243 warehouse/templates/base.html:264
12431243
#: warehouse/templates/error-base-with-search.html:24
12441244
#: warehouse/templates/index.html:50
12451245
msgid "Search"
12461246
msgstr ""
12471247

1248-
#: warehouse/templates/base.html:278
1248+
#: warehouse/templates/base.html:283
12491249
msgid "Help navigation"
12501250
msgstr ""
12511251

1252-
#: warehouse/templates/base.html:280
1252+
#: warehouse/templates/base.html:285
12531253
msgid "Installing packages"
12541254
msgstr ""
12551255

1256-
#: warehouse/templates/base.html:281
1256+
#: warehouse/templates/base.html:286
12571257
msgid "Uploading packages"
12581258
msgstr ""
12591259

1260-
#: warehouse/templates/base.html:282
1260+
#: warehouse/templates/base.html:287
12611261
msgid "User guide"
12621262
msgstr ""
12631263

1264-
#: warehouse/templates/base.html:283
1264+
#: warehouse/templates/base.html:288
12651265
msgid "Project name retention"
12661266
msgstr ""
12671267

1268-
#: warehouse/templates/base.html:284
1268+
#: warehouse/templates/base.html:289
12691269
msgid "FAQs"
12701270
msgstr ""
12711271

1272-
#: warehouse/templates/base.html:290 warehouse/templates/pages/sitemap.html:37
1272+
#: warehouse/templates/base.html:295 warehouse/templates/pages/sitemap.html:37
12731273
msgid "About PyPI"
12741274
msgstr ""
12751275

1276-
#: warehouse/templates/base.html:291
1276+
#: warehouse/templates/base.html:296
12771277
msgid "About PyPI navigation"
12781278
msgstr ""
12791279

1280-
#: warehouse/templates/base.html:293
1280+
#: warehouse/templates/base.html:298
12811281
msgid "PyPI Blog"
12821282
msgstr ""
12831283

1284-
#: warehouse/templates/base.html:294
1284+
#: warehouse/templates/base.html:299
12851285
msgid "Infrastructure dashboard"
12861286
msgstr ""
12871287

1288-
#: warehouse/templates/base.html:295 warehouse/templates/pages/sitemap.html:40
1288+
#: warehouse/templates/base.html:300 warehouse/templates/pages/sitemap.html:40
12891289
#: warehouse/templates/pages/stats.html:16
12901290
msgid "Statistics"
12911291
msgstr ""
12921292

1293-
#: warehouse/templates/base.html:296
1293+
#: warehouse/templates/base.html:301
12941294
msgid "Logos & trademarks"
12951295
msgstr ""
12961296

1297-
#: warehouse/templates/base.html:297
1297+
#: warehouse/templates/base.html:302
12981298
msgid "Our sponsors"
12991299
msgstr ""
13001300

1301-
#: warehouse/templates/base.html:303
1301+
#: warehouse/templates/base.html:308
13021302
msgid "Contributing to PyPI"
13031303
msgstr ""
13041304

1305-
#: warehouse/templates/base.html:304
1305+
#: warehouse/templates/base.html:309
13061306
msgid "How to contribute navigation"
13071307
msgstr ""
13081308

1309-
#: warehouse/templates/base.html:306
1309+
#: warehouse/templates/base.html:311
13101310
msgid "Bugs and feedback"
13111311
msgstr ""
13121312

1313-
#: warehouse/templates/base.html:307
1313+
#: warehouse/templates/base.html:312
13141314
msgid "Contribute on GitHub"
13151315
msgstr ""
13161316

1317-
#: warehouse/templates/base.html:308
1317+
#: warehouse/templates/base.html:313
13181318
msgid "Translate PyPI"
13191319
msgstr ""
13201320

1321-
#: warehouse/templates/base.html:309
1321+
#: warehouse/templates/base.html:314
13221322
msgid "Sponsor PyPI"
13231323
msgstr ""
13241324

1325-
#: warehouse/templates/base.html:310
1325+
#: warehouse/templates/base.html:315
13261326
msgid "Development credits"
13271327
msgstr ""
13281328

1329-
#: warehouse/templates/base.html:316 warehouse/templates/pages/sitemap.html:23
1329+
#: warehouse/templates/base.html:321 warehouse/templates/pages/sitemap.html:23
13301330
msgid "Using PyPI"
13311331
msgstr ""
13321332

1333-
#: warehouse/templates/base.html:317
1333+
#: warehouse/templates/base.html:322
13341334
msgid "Using PyPI navigation"
13351335
msgstr ""
13361336

1337-
#: warehouse/templates/base.html:319
1337+
#: warehouse/templates/base.html:324
13381338
#: warehouse/templates/manage/organization/activate_subscription.html:33
13391339
msgid "Terms of Service"
13401340
msgstr ""
13411341

1342-
#: warehouse/templates/base.html:320
1342+
#: warehouse/templates/base.html:325
13431343
msgid "Report security issue"
13441344
msgstr ""
13451345

1346-
#: warehouse/templates/base.html:321
1346+
#: warehouse/templates/base.html:326
13471347
msgid "Code of conduct"
13481348
msgstr ""
13491349

1350-
#: warehouse/templates/base.html:322
1350+
#: warehouse/templates/base.html:327
13511351
msgid "Privacy Notice"
13521352
msgstr ""
13531353

1354-
#: warehouse/templates/base.html:323
1354+
#: warehouse/templates/base.html:328
13551355
msgid "Acceptable Use Policy"
13561356
msgstr ""
13571357

1358-
#: warehouse/templates/base.html:333
1358+
#: warehouse/templates/base.html:338
13591359
msgid "Status:"
13601360
msgstr ""
13611361

1362-
#: warehouse/templates/base.html:334
1362+
#: warehouse/templates/base.html:339
13631363
msgid "all systems operational"
13641364
msgstr ""
13651365

1366-
#: warehouse/templates/base.html:338
1366+
#: warehouse/templates/base.html:343
13671367
msgid ""
13681368
"Developed and maintained by the Python community, for the Python "
13691369
"community."
13701370
msgstr ""
13711371

1372-
#: warehouse/templates/base.html:340
1372+
#: warehouse/templates/base.html:345
13731373
msgid "Donate today!"
13741374
msgstr ""
13751375

1376-
#: warehouse/templates/base.html:347 warehouse/templates/pages/sitemap.html:16
1376+
#: warehouse/templates/base.html:352 warehouse/templates/pages/sitemap.html:16
13771377
msgid "Site map"
13781378
msgstr ""
13791379

1380-
#: warehouse/templates/base.html:353
1380+
#: warehouse/templates/base.html:358
13811381
msgid "Switch to desktop version"
13821382
msgstr ""
13831383

warehouse/templates/accounts/profile.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
{% endif %}
2222
{% endblock %}
2323

24-
{% block canonical_url %}{{ request.route_url('accounts.profile', username=user.username) }}{% endblock %}
24+
{% block canonical_url %}{{ request.canonical_url(username=user.username) }}{% endblock %}
2525

2626
{% block content %}
2727
<div class="horizontal-section horizontal-section--medium">

warehouse/templates/base.html

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,15 @@
107107
<link rel="alternate" type="application/rss+xml" title="{% trans %}RSS: 40 newest packages{% endtrans %}" href="{{ request.route_path('rss.packages') }}">
108108
{% block additional_rss %}{% endblock %}
109109
{# Allow overriding the canonical URL if we have explicitly set it.
110-
# Otherwise, use the URL to the current matched route as the canonical URL,
110+
# Otherwise, try to use the URL to the current matched route as the canonical URL,
111111
# which strips anchor tags and query parameters.
112+
# If that fails, don't include a canonical URL
112113
#}
113-
<link rel="canonical" href="{% block canonical_url %}{{ request.route_url(request.matched_route.name) }}{% endblock %}">
114+
{% if self.canonical_url() %}
115+
<link rel="canonical" href="{% block canonical_url %}{% endblock %}">
116+
{% elif request.canonical_url() %}
117+
<link rel="canonical" href="{{ request.canonical_url() }}">
118+
{% endif %}
114119

115120
<meta property="og:url" content="{% if request.matched_route %}{{ request.current_route_url() }}{% else %}{{ request.url }}{% endif %}">
116121
<meta property="og:site_name" content="PyPI">

warehouse/templates/organizations/profile.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
{% block title %}{% trans orgname=organization.display_name %}Profile of {{ orgname }}{% endtrans %}{% endblock %}
1717

18-
{% block canonical_url %}{{ request.route_url('organizations.profile', organization=organization.normalized_name) }}{% endblock %}
18+
{% block canonical_url %}{{ request.canonical_url(organization=organization.normalized_name) }}{% endblock %}
1919

2020
{% block content %}
2121
<div class="horizontal-section horizontal-section--medium">

0 commit comments

Comments
 (0)