Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the documentation for __future__ #110893

Closed
nedbat opened this issue Oct 15, 2023 · 20 comments
Closed

Improve the documentation for __future__ #110893

nedbat opened this issue Oct 15, 2023 · 20 comments
Labels
3.11 only security fixes 3.12 bugs and security fixes 3.13 bugs and security fixes docs Documentation in the Doc dir easy

Comments

@nedbat
Copy link
Member

nedbat commented Oct 15, 2023

Documentation

(From Discourse: https://discuss.python.org/t/help-understanding-future-module-description/35442/5?u=nedbat)

I was confused by the first line in the docs for __future__

__future__ is a real module, and serves three purposes:

What does it mean by a “real” module? What are modules that aren’t “real”?

Then:

I’d say “real module” is strange all the time, and we don’t need it. "import __future__" serves three purposes is good.

What I would mostly like to change on that page is to document what each import does. The page spends a lot of words explaining the _Feature objects, which no one uses, but doesn’t say what (for example) from __future__ import annotations actually does. It links off to PEPs that are good historical records of decision making, but aren’t good ways to explain what Python does right now.

cc @merwok

Linked PRs

@nedbat nedbat added the docs Documentation in the Doc dir label Oct 15, 2023
@merwok merwok added 3.11 only security fixes easy 3.12 bugs and security fixes 3.13 bugs and security fixes labels Oct 15, 2023
@kshunjan26
Copy link

Can we use something like this as an introduction?

The __future__ module in Python is a special tool used to change the behavior of the Python compiler. It allows you to enable specific language features or modifications that are not the default in the current version of Python but will be in future releases. Importing from __future__ serves three primary purposes:

  • Compatibility: It enables developers to write code that is compatible with both current and future Python versions. By using __future__ imports, you can make sure your code will work as expected in newer Python releases.
  • Runtime Exceptions: If a future statement is used in code running on an older Python version, it will raise runtime exceptions. This ensures that you are aware of potential incompatibilities with older Python releases.
  • Documentation: __future__ also serves as a form of documentation, indicating when incompatible changes were introduced and when they will become mandatory. This information can be useful for developers to understand the evolution of the Python language.

For example, the import statement from __future__ import annotations enables postponed evaluation of type annotations, which is a feature that became standard in Python 3.7 and later versions. By using this import, you can write code that takes advantage of this feature even if you are using an older Python version. It's important to check the Python documentation or relevant PEPs for details on what each import statement does in the current version of Python.

@merwok
Copy link
Member

merwok commented Oct 15, 2023

It’s not the __future__ module that is a special tool, but the __future__ imports

@timhoffm
Copy link
Contributor

timhoffm commented Oct 16, 2023

I suggest a general / user-facing introduction along the lines:

The __future__ module provides language features (new functionality or changed behavior) that are gradually introduced into the language. Features are introduced in a version OptionalRelease, from which on they are available but not active by default. From a MandatoryRelease version on, they are always active.

To activate a feature, import it from the __future__ module (e.g. from __future__ import annotations). The __future__ import must be the first statement in the file (except for a module docstring). It activates the feature for the scope of the file. __future__ imports remain valid after MandatoryRelease but have no effect anymore. This makes it easier to write code that is compatible with multiple versions of Python in the feature transition phase. If your code only supports versions greater or equal to MandatoryRelease, you don't need the __future__ imports of that feature anymore.


After that, you can go into all the technical details and reasoning.

@anujrmohite
Copy link

Hey @nedbat

I noticed you opened issue #110893 about improving the documentation for the future module. As a user of future imports, I agree the current docs could be clearer, especially around what each import actually does. If anyone is not working on it right now then i would love to work on this documentation improvement?

@merwok
Copy link
Member

merwok commented Oct 23, 2023

Yes, you can take this!

@anujrmohite
Copy link

Hey, what about "barry_as_FLUFL" .. future.py file is not currently documented on the official documentation page (https://docs.python.org/3/library/__future__.html#module-__future__)
Should I add it? In making all the changes?

@nedbat
Copy link
Member Author

nedbat commented Oct 25, 2023

Hey, what about "barry_as_FLUFL"

In my opinion, that is a joke, and can remain an undocumented easter egg.

@anujrmohite
Copy link

I suggest a general / user-facing introduction along the lines:

The __future__ module provides language features (new functionality or changed behavior) that are gradually introduced into the language. Features are introduced in a version OptionalRelease, from which on they are available but not active by default. From a MandatoryRelease version on, they are always active.

To activate a feature, import it from the __future__ module (e.g. from __future__ import annotations). The __future__ import must be the first statement in the file (except for a module docstring). It activates the feature for the scope of the file. __future__ imports remain valid after MandatoryRelease but have no effect anymore. This makes it easier to write code that is compatible with multiple versions of Python in the feature transition phase. If your code only supports versions greater or equal to MandatoryRelease, you don't need the __future__ imports of that feature anymore.

After that, you can go into all the technical details and reasoning.

hey,
from the references you provided and doc i have modified along the same line, would you please look into it, please suggest changes or modifications...

The __future__ module provides a way to introduce new language features or changed behavior of existing features gradually. These features are introduced in an OptionalRelease version, where they are available but not active by default. Starting from a MandatoryRelease version, these features become active by default.

To use a specific feature, import it from the __future__ module using the syntax from __future__ import <feature>. It is important to note that the __future__ import statement must be placed as the first statement in the source file, except for a module docstring. This import statement activates the feature for the entire scope of the file.

Once a feature has been imported, the __future__ import remains valid even after the MandatoryRelease version. However, it has no behavioral effect. So this code will be compatible with multiple versions of Python during the transition phase of a feature. If code only supports versions greater than or equal to the MandatoryRelease version, then no longer need to include the __future__ import for that specific feature.

In the __future__.py module, each statement follows this format:
FeatureName = _Feature(OptionalRelease, MandatoryRelease, CompilerFlag)

OptionalRelease and MandatoryRelease are both 5-tuples of the same form as sys.version_info.The format of the 5-tuples is as follows:

This will be added in table
PY_MAJOR_VERSION: The major version number, such as the "2" in "2.1.0a3". It is represented as an integer.
PY_MINOR_VERSION: The minor version number, such as the "1" in "2.1.0a3". It is represented as an integer.
PY_MICRO_VERSION: The micro version number, such as the "0" in "2.1.0a3". It is represented as an integer.
PY_RELEASE_LEVEL: The release level, which can be "alpha", "beta", "candidate", or "final". It is represented as a string.
PY_RELEASE_SERIAL: The release serial number, such as the "3" in "2.1.0a3". It is represented as an integer.

These 5-tuples provide version information about the releases in which a feature was accepted or became part of the language.

Release Information for Features:

The release information for features is captured through OptionalRelease and MandatoryRelease.The OptionalRelease records the first release in which the feature was accepted and MandatoryRelease records when the feature became part of the language. Once a feature is included in a MandatoryRelease, modules no longer need a future statement to use the feature, but they may continue to use such imports if needed.

Instances of the class _Feature provide two methods to retrieve release information:
getOptionalRelease(): This method returns the release information for the OptionalRelease of a specific feature.
getMandatoryRelease(): This method returns the release information for the MandatoryRelease of a specific feature.

The CompilerFlag is a bitfield flag that should be passed in the fourth argument to the built-in function compile() in order to enable the feature in dynamically compiled code. This flag is stored in the compiler_flag attribute on instances of the _Feature class.

@merwok
Copy link
Member

merwok commented Oct 27, 2023

Can someone make a pull request to propose changes? See https://devguide.python.org/ for guidance

I’ll suggest to avoid changing too much text if possible, and improving the general description without going too deep into details (like the line In the __future__ module, each statement follows this format – no need, interested people can go look at the code)

@anujrmohite
Copy link

anujrmohite commented Oct 27, 2023

Can someone make a pull request to propose changes? See https://devguide.python.org/ for guidance

I’ll suggest to avoid changing too much text if possible, and improving the general description without going too deep into details (like the line In the __future__ module, each statement follows this format – no need, interested people can go look at the code)

Yeh Sure, I'll do that...and make required changes...asap

@anujrmohite
Copy link

Hello,
Please review and let me know if any further changes are needed before I open a PR. I'm happy to make any edits that would improve it. :)

The __future__ module provides a way to introduce new language features or changed behavior of existing features gradually. These features are introduced in an OptionalRelease version, where they are available but not active by default. Starting from a MandatoryRelease version, these features become active by default.

To use a specific feature, import it from the __future__ module using the syntax from __future__ import <feature>. It is important to note that the __future__ import statement must be placed as the first statement in the source file, except for a module docstring. This import statement activates the feature for the entire scope of the file.

Once a feature has been imported, the __future__ import remains valid even after the MandatoryRelease version. However, it has no behavioral effect. So this code will be compatible with multiple versions of Python during the transition phase of a feature. If code only supports versions greater than or equal to the MandatoryRelease version, then no longer need to include the __future__ import for that specific feature.

OptionalRelease and MandatoryRelease are both 5-tuples of the same form as sys.version_info.The format of the 5-tuples is as follows:

This will be added in table
PY_MAJOR_VERSION: The major version number, such as the "2" in "2.1.0a3". It is represented as an integer.
PY_MINOR_VERSION: The minor version number, such as the "1" in "2.1.0a3". It is represented as an integer.
PY_MICRO_VERSION: The micro version number, such as the "0" in "2.1.0a3". It is represented as an integer.
PY_RELEASE_LEVEL: The release level, which can be "alpha", "beta", "candidate", or "final". It is represented as a string.
PY_RELEASE_SERIAL: The release serial number, such as the "3" in "2.1.0a3". It is represented as an integer.

These 5-tuples provide version information about the releases in which a feature was accepted or became part of the language.

Release Information for Features:

The release information for features is captured through OptionalRelease and MandatoryRelease.The OptionalRelease records the first release in which the feature was accepted and MandatoryRelease records when the feature became part of the language. Once a feature is included in a MandatoryRelease, modules no longer need a future statement to use the feature, but they may continue to use such imports if needed.

Instances of the class _Feature provide two methods to retrieve release information:
getOptionalRelease(): This method returns the release information for the OptionalRelease of a specific feature.
getMandatoryRelease(): This method returns the release information for the MandatoryRelease of a specific feature.

The CompilerFlag is a bitfield flag that should be passed in the fourth argument to the built-in function compile() in order to enable the feature in dynamically compiled code. This flag is stored in the compiler_flag attribute on instances of the _Feature class.

@merwok
Copy link
Member

merwok commented Oct 27, 2023

Please make a pull request not big posts here

@arneja-arnav
Copy link

Can I work on this?

@merwok
Copy link
Member

merwok commented Nov 15, 2023

Let’s see if Anuj turns the comment here into a pull request first, and if there’s no activity then you can try 🙂
Please mind #110893 (comment)

@anujrmohite
Copy link

Let’s see if Anuj turns the comment here into a pull request first, and if there’s no activity then you can try 🙂 Please mind #110893 (comment)

soon, I'll PR. I've been unwell this month.

@anujrmohite
Copy link

anujrmohite commented Nov 29, 2023

hey @merwok,
I've submitted a PR. #112348 please Could you take a look?
Thanks!

@merwok
Copy link
Member

merwok commented Nov 29, 2023

Seen it, not had the time yet to review.

@vaishnavi192
Copy link
Contributor

so is this issue now solved? or we can still work on it? @merwok

@hugovk
Copy link
Member

hugovk commented Dec 22, 2023

@vaishnavi192 There's still an open PR (#112348), let's be patient and wait for that to be reviewed first.

hauntsaninja added a commit to hauntsaninja/cpython that referenced this issue Jan 27, 2024
nedbat took issue with the phrasing "real module". I'm actually fine
with that phrasing, but I do think the `__future__` page should be clear
about the way in which the `__future__` module is special. (Yes, there
was a footnote linking to the future statements part of the reference,
but there should be upfront discussion).

I'm sympathetic to nedbat's claim that no one really cares about
`__future__._Feature`, so I've moved the interesting table up to the
top.
hauntsaninja added a commit that referenced this issue Jan 29, 2024
nedbat took issue with the phrasing "real module". I'm actually fine
with that phrasing, but I do think the `__future__` page should be clear
about the way in which the `__future__` module is special. (Yes, there
was a footnote linking to the future statements part of the reference,
but there should be upfront discussion).

I'm sympathetic to nedbat's claim that no one really cares about
`__future__._Feature`, so I've moved the interesting table up to the
top.
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Jan 29, 2024
…honGH-114642)

nedbat took issue with the phrasing "real module". I'm actually fine
with that phrasing, but I do think the `__future__` page should be clear
about the way in which the `__future__` module is special. (Yes, there
was a footnote linking to the future statements part of the reference,
but there should be upfront discussion).

I'm sympathetic to nedbat's claim that no one really cares about
`__future__._Feature`, so I've moved the interesting table up to the
top.
(cherry picked from commit 3b86891)

Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com>
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Jan 29, 2024
…honGH-114642)

nedbat took issue with the phrasing "real module". I'm actually fine
with that phrasing, but I do think the `__future__` page should be clear
about the way in which the `__future__` module is special. (Yes, there
was a footnote linking to the future statements part of the reference,
but there should be upfront discussion).

I'm sympathetic to nedbat's claim that no one really cares about
`__future__._Feature`, so I've moved the interesting table up to the
top.
(cherry picked from commit 3b86891)

Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com>
hauntsaninja added a commit that referenced this issue Jan 29, 2024
…-114642) (#114703)

gh-110893: Improve the documentation for __future__ module (GH-114642)

nedbat took issue with the phrasing "real module". I'm actually fine
with that phrasing, but I do think the `__future__` page should be clear
about the way in which the `__future__` module is special. (Yes, there
was a footnote linking to the future statements part of the reference,
but there should be upfront discussion).

I'm sympathetic to nedbat's claim that no one really cares about
`__future__._Feature`, so I've moved the interesting table up to the
top.
(cherry picked from commit 3b86891)

Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com>
hauntsaninja added a commit that referenced this issue Jan 29, 2024
…-114642) (#114702)

gh-110893: Improve the documentation for __future__ module (GH-114642)

nedbat took issue with the phrasing "real module". I'm actually fine
with that phrasing, but I do think the `__future__` page should be clear
about the way in which the `__future__` module is special. (Yes, there
was a footnote linking to the future statements part of the reference,
but there should be upfront discussion).

I'm sympathetic to nedbat's claim that no one really cares about
`__future__._Feature`, so I've moved the interesting table up to the
top.
(cherry picked from commit 3b86891)

Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com>
aisk pushed a commit to aisk/cpython that referenced this issue Feb 11, 2024
…hon#114642)

nedbat took issue with the phrasing "real module". I'm actually fine
with that phrasing, but I do think the `__future__` page should be clear
about the way in which the `__future__` module is special. (Yes, there
was a footnote linking to the future statements part of the reference,
but there should be upfront discussion).

I'm sympathetic to nedbat's claim that no one really cares about
`__future__._Feature`, so I've moved the interesting table up to the
top.
@Harsh-Govil
Copy link

I have done some changes which are definitely helpful related to your problem. Can you please give me the access

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.11 only security fixes 3.12 bugs and security fixes 3.13 bugs and security fixes docs Documentation in the Doc dir easy
Projects
None yet
Development

No branches or pull requests

10 participants