You are completely right, if we aren’t documenting it, the majority of people will never discover them and hence no feedback regarding how to improve them.
Python develops the unstable APIs along with the stable ones and they just mention a note for the unstable APIs that “this has no stability guarantees and may change or be removed.”
So, the question is, are there any problems with this approach?
Well, they are having a discussion on how documentation alone isn’t the right approach.
I want to quote a few things from that post because they highlight the issues faced when unstable APIs are documented without any isolation or runtime warnings. It’s a very thorough post that is highly relevant to what we are trying to solve, and I’d highly recommend it to anyone to go through it whenever you have some time.
The author points out that right now, there is no standard, machine-readable way to say an API is “published but not stable yet.” When maintainers want to add a new feature to a stable release, semantic versioning forces them into bad options: either hold the feature back completely, freeze an early design prematurely, or burn a major version bump later for a change that production users didn’t even care about.
He notes that documentation conventions like PEP 411 are a patchwork right now. They act purely as text-based rules, meaning they give no runtime warning, no runtime marker, and no signal that actually reaches the developer who installed the package, only the people who read the docs know about it.
So, he proposes that just like Python has a standard, type-checker-aware way to mark the end of an API’s life through @deprecated decorator (PEP 702), there should be an @experimental decorator for the start of an API’s life when something is published but explicitly unstable.
This will lead to a much cleaner workflow, it gives developers a clear runtime warning in their terminal instead of hiding it in documentation, it lets production teams explicitly block unstable code from going live, and it gives code editors a single standard marker to look for and flag automatically.
He further mentions Python libraries that are trying to solve this on their own. For example, scikit-learn has its own sklearn.exceptions.ExperimentalWarning + sklearn.experimental package, LangChain uses @beta decorator + LangChainBetaWarning. And libraries like NumPy, SciPy, and pandas rely on custom written text notes in their documentation or throw in generic, one-off warnings.
He also points out that several major languages like C#, Rust, Java and many more already ship built-in markers or flags to explicitly isolate unstable code.
Let’s also look at another angle, with the rise of AI assisted coding and agents being able to build entire applications, LLMs that are trained on the entire codebase and documentation know that the API is unstable but it’ll still use the unstable APIs anyway just to get the work done, regardless of the warnings in the documentation. The developer looks at the final outcome, and everything works fine and the code is pushed to production. A few weeks later the API is changed or removed, the application breaks.
And then that person will come on the forum asking for some sort of isolation and runtime warnings just like that developer did on the python forums (although he didn’t raise the issue because of LLMs) and I think this is one of the reasons why isolation is so important and I would even suggest going for package extras (pip install django[experimental]) so that there’s an installation barrier too. This installation barrier will force both the code assistant and the developer to acknowledge that they are in an experimental space.
Following this method, we wouldn’t have to change Django’s policy regarding undocumented features. Instead, by bringing unstable features under experimental space, we can safely document them and provide a direct link to a dedicated forum discussion where all the feedback can be gathered.
Once these features are documented, they are self-marketing for anyone looking at the docs. However, to really drive awareness we shouldn’t limit ourselves to just blogs. We can use every means of communication Django has including newsletter, Discord, the forum, or podcasts, this way we can get a lot of feedback and usage before a feature is promoted.
Python gives us a lot of flexibility, and there are many paths we can take. It all comes down to finding the best way forward for the long-term, even if the implementation isn’t the most direct or natural approach at first. I would love to hear everyone’s thoughts on how we can best structure these while giving new ideas a safe place to grow.
I am open to any suggestions on the specific details to ensure the DEP 2 draft comprehensively covers how all of this will work. Specifically, it would be nice to get the details on what isolation methods should be used, how experimental phases will fit into the release cycle, and since this project comes as an alternative method, what is really needed for a feature to get accepted for this path?
Also, I wanted to know if there are any other reasons to keep features undocumented, or if protecting them from the deprecation policy is the only one?