Links to personal blogs in docs

I was browsing the datetime docs, and noticed this (from commit d3b6faf9758dce236d45c708a450437cdc3e97cd):

Tip
import datetime as dt instead of import datetime or from datetime import datetime to avoid confusion between the module and the class. See How I Import Python’s datetime Module.

This seems inappropriate to me. What do others think?

8 Likes

Can you say more about why exactly it seems inappropriate? The docs link to many things. What about this link bothers you?

4 Likes

I wouldn’t call it inappropriate, but I would call it superfluous :slight_smile:

The smaller the target of the things we link to the more likely we are to wind up somewhere down the road with a link that’s either dead or hijacked to nefarious purpose, but when the value of the target is high enough it may outweigh that risk. I personally don’t think the link in question provides enough extra value to be worth the link, but it’s also not wrong just because of where it points.

12 Likes

I think the Python docs should be about Python, not about exposing/highlighting any particular person, their thoughts on Python, or how to hire them.

7 Likes

Agreed. I’d make a stronger argument that the article in the link provide no more information than the tip callout and the example above.

FWIW, I found it jarring to see the first-person and mistaken the article title as part of the prose.

1 Like

I filtered approximately 58 links with personal domains from the CPython documentation RST files. Nine links are missing or inaccessible, which is a high error rate.

Code
import requests

links = [
    'https://learning-python.com/about-pp4e.html',
    'https://adamj.eu/tech/2019/09/12/how-i-import-pythons-datetime-module/',
    'https://morepypy.blogspot.com/2015/01/faster-more-memory-efficient-and-more.html',
    'https://greenteapress.com/semaphores/LittleBookOfSemaphores.pdf',
    'https://www.thrysoee.dk/editline/',
    'https://jacobfilipp.com/DrDobbs/articles/DDJ/1988/8807/8807c/8807c.htm',
    'https://old.red-dove.com/python_logging.html',
    'https://www.chiark.greenend.org.uk/~sgtatham/bugs.html',
    'https://www.bytereef.org/mpdecimal/doc/libmpdec/index.html',
    'https://quimby.gnus.org/notes/BABYL',
    'https://www.phyast.pitt.edu/~micheles/',
    'https://www.boddie.org.uk/python/COM.html',
    'https://support.enthought.com/hc/en-us/articles/360038600051-Canopy-GUI-end-of-life-transition-to-the-Enthought-Deployment-Manager-EDM-and-Visual-Studio-Code',
    'http://lists.idyll.org/listinfo/testing-in-python',
    'http://catb.org/~esr/trove/',
    'https://grantjenks.com/docs/sortedcollections/',
    'https://aosabook.org/en/500L/a-web-crawler-with-asyncio-coroutines.html',
    'https://nbviewer.org/url/norvig.com/ipython/Probability.ipynb',
    'https://allendowney.com/research/rand/downey07randfloat.pdf',
    'https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT',
    'https://tauday.com/',
    'https://cr.yp.to/proto/maildir.html',
    'http://xmlrpc.scripting.com/spec.html',
    'https://rhettinger.wordpress.com/2011/01/28/open-your-source-more/',
    'http://www.dabeaz.com/coroutines/index.html',
    'http://www.java2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm',
    'https://www.jcea.es/programacion/pybsddb.htm',
    'https://udrepper.livejournal.com/20407.html',
    'https://codahale.com/a-lesson-in-timing-attacks/',
    'https://nng.nanomsg.org/',
    'https://invisible-island.net/ncurses/ncurses.faq.html',
    'https://timgolden.me.uk/python/win32_how_do_i.html',
    'https://python-notes.curiousefficiency.org/en/latest/python3/text_file_processing.html',
    'http://www.catb.org/~esr/fetchmail/fetchmail-FAQ.html',
    'https://invisible-island.net/ncurses/ncurses-intro.html',
    'https://chaquo.com/chaquopy',
    'https://www.doesjitgobrrr.com/run/2026-04-29',
    'https://tukaani.org/xz/',
    'https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/',
    'https://vincent.bernat.ch/en/blog/2011-ssl-perfect-forward-secrecy',
    'https://www.statisticshowto.com/probability-and-statistics/z-score/',
    'http://www.indowsway.com/floatingpoint.htm',
    'https://jkorpela.fi/unicode/guide.html',
    'http://www.dabeaz.com/generators/',
    'https://jkorpela.fi/http.html',
    'https://www.nongnu.org/nmh/',
    'https://tldp.org/HOWTO/XML-RPC-HOWTO/index.html',
    'https://sourceware.org/libffi/',
    'https://speleotrove.com/decimal/damodel.html#refnumber',
    'https://www.schneier.com/wp-content/uploads/2016/02/skein.pdf',
    'https://speleotrove.com/decimal/decarith.html',
    'https://nbviewer.org/url/norvig.com/ipython/Economics.ipynb',
    'https://nedbatchelder.com/text/unipain.html',
    'https://jvns.ca/blog/2023/01/13/examples-of-floating-point-problems/',
    'https://upfrontsoftware.co.za',
    'https://babel.pocoo.org/',
    'https://williambert.online/2011/07/how-to-unit-testing-in-django-with-mocking-and-patching/',
    'https://reproducible-builds.org/'
]

print('len(links):', len(links))

for link in links:
    try:
        r = requests.get(link, timeout=2)

        if (status := r.status_code) != 200:
            print(status, link)

    except requests.ConnectTimeout:
        print('timeout:', link)

    except Exception:
        print('error:', link)

"""
timeout: https://www.phyast.pitt.edu/~micheles/
404 https://support.enthought.com/hc/en-us/articles/360038600051-Canopy-GUI-end-of-life-transition-to-the-Enthought-Deployment-Manager-EDM-and-Visual-Studio-Code
timeout: http://lists.idyll.org/listinfo/testing-in-python
404 http://xmlrpc.scripting.com/spec.html
404 http://www.java2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm
error: https://codahale.com/a-lesson-in-timing-attacks/
403 https://www.statisticshowto.com/probability-and-statistics/z-score/
timeout: http://www.dabeaz.com/generators/
error: https://www.nongnu.org/nmh/
"""
3 Likes

Links to external resources may be perceived as an endorsement by python. They also can change over time, and may not say what they did when added to the documentation (and may actually be offensive or dangerous). If linked content becomes problematic changes to the docs in active releases will be delayed by release cycles and won’t update any local caches, etc. There may not be a quick fix to dissociate python from whatever that content has become.

I do think there is value in this type of link because including the entire blog post in the docs is also inappropriate…it is too much tangential detail for what should be concise documentation. A link to a python (PSF) controlled site such as the wiki that another thread is discussing the fate of seems more appropriate ( [Feedback requested!] What’s next for the Python and PSF Wiki? - #12 by Mariatta ) since the additional detail can be linked to but control over that content would be retained.

5 Likes

I think such links should be considered cautiously, but really in this case the inclusion of the “tip” itself seems questionable to me. Are we prepared to allow a bunch of similar tips to be sprinkled through the docs?

Any link carries an unavoidable risk of becoming invalid over time. Some links seem pretty unobjectionable, like linking to external resources that define standards or formats that are implemented in the stdlib[1]. In general I would think it’s good to vet links in terms of their presumed stability (e.g., a link to a W3C spec is likely more durable than one to someone’s personal blog) and the effect on readability of including comparable content directly in the docs (e.g., it makes sense to link to some external explanation of HTML rather than bloat the HTMLParser docs with a ground-up explanation).


  1. although ironically some of the places I’d expect to find such links don’t actually have them, like LZMA ↩︎

1 Like

Yes, yes we are. Tips like that can be extremely helpful. I’m not sure that the blog link is adding much (and there’s the mentioned risk of link rot), but the tip itself is definitely worth keeping. See discussions like Renaming datetime.datetime to datetime.DateTime where the problem of “did you import datetime or from datetime import datetime?” is a very real risk; the best solution was to start recommending import datetime as dt which received broad support.

My personal justification for removing the blog link would be link rot (both as a potential everywhere, and an inevitability when the docs are used offline - does anyone still do that?). Its core message is already in the tip, but if there’s anything that is considered missing without the link, I’d be inclined to add it to the tip directly, rather than keep the link.

7 Likes

The link (dated 2019-09-12) is a short technical blog post describing a Python import style where the datetime module is aliased to avoid name conflicts between the module and classes such as datetime, time, and timezone.

The concept itself is long established and widely used in programming for namespace clarity and to prevent naming collisions. As such, the post does not introduce new technical insight or formal guidance beyond standard documentation and common practice. For this reason, citing it in authoritative documentation adds little value and is generally unnecessary for reference purposes, since it is neither a primary source nor a novel contribution.

I also found a personal link that simply documents HTTP headers and links to obsolete HTTP standard pages. MDN Web HTTP Reference Headers is a better alternative.

2 Likes

I added this particular link, and I think it’s appropriate. :slight_smile:

There are many ways to import datetime. The tip suggests using import datetime as dt over the other options to avoid confusion. The examples on the page follow this pattern. But it’s only a tip, you can of course do it however you want in your own code; we’re not (soft) deprecating or warning any of them.

The tip says it’s “to avoid confusion between the module and the class”. Okay, but the link spells this out with examples, and includes another case where there can be confusion with time. I find these helpful, and it explains it clearly for beginners. We could pull these back into the main docs, but the page is already very long (in the top 10 of our longest) and ideally we’d split them up (for usability and SEO and so on).

Yes, links can and do rot. Then we fix them: update, remove, or point to the Internet Archive. We can update the docs and the website will be updated within minutes.

Please will you open an issue so we can fix these? PRs also welcome. And I checked these nine manually, only six are missing or inaccessible.

Offline docs are used (we occasionally get reports about them), plus other formats like EPUB, but by far and away I think it’s safe to say the live website at docs.python.org has the vast majority of use.

12 Likes

If importing it this way is the preferred method, it should be stated as
such in the documentation, not just as a tip. Additionally maybe link to
the blog for a more in-depth explanation.

1 Like

Not all of these are blogs/personal sites, from a quick glance I see e.g., https://chaquo.com/chaquopy/, https://tukaani.org/xz/, https://www.doesjitgobrrr.com/run/2026-04-29, https://sourceware.org/libffi/ or https://reproducible-builds.org/.

You can re-use the existing issue, python/cpython#103484, instead. Also, note that some are existing PRs like, https://www.phyast.pitt.edu/~micheles/ (python/cpython#149092).

1 Like

In general, I would agree that we should minimize the links to external sources for some of the reasons that have been pointed out already in this thread: endorsement, drift in linked resource content.

That said, I look at each external link through the following lens:

Adding a new link

  1. Does this link help the reader to use Python effectively?
  2. Is the content linked something which expands on a new module, provides greater understanding for the end user why the module/class/function is necessary, or adds frequently used patterns?

Reviewing the need for an existing link

  1. Does the link still provide the reader guidance about using Python effectively today?
  2. Would it better to add a short (2-3 sentence) explanation instead of providing a link? Therefore reducing external links.

While hard and fast rules may be easier to apply (i.e. no external links), I believe using good judgement around a specific link makes more sense and has a higher benefit for readers. I trust those working on documentation to collectively make responsible decisions on external links as well as individuals, like Ethan has, to question when something may no longer be necessary.

7 Likes

Do we have a HOWTO or Cookbook style article for datetime? Those can be a decent way to elaborate on tips without risking linkrot and without making the main docs even more overwhelming than they already are.

On the more general question, links to sites published by still active core contributors or active maintainers of other open source projects are generally going to be low risk, but even then there’s a case to be made for linking to Internet Archive snapshots rather than to potentially mutable target pages.

3 Likes

No, just the stdlib reference for this one.

In this case, the author is a Django contributor, on the Django security team, a former Django Steering Council member, meetup organiser, and maintainer of dozens of PyPI packages.

Interesting idea, but in my experience the Internet Archive (as wonderful and important as it is) is slow to use and unfortunately doesn’t serve our readers well when there’s a live copy available.

2 Likes