Skip to content

bpo-38155: Adding __all__ to datetime module #16203

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

Merged
merged 3 commits into from
Sep 19, 2019
Merged

Conversation

ta1hia
Copy link
Contributor

@ta1hia ta1hia commented Sep 16, 2019

@@ -62,6 +62,19 @@ def test_constants(self):
self.assertEqual(datetime.MINYEAR, 1)
self.assertEqual(datetime.MAXYEAR, 9999)

def test_all(self):
"""Test that __all__ only points to valid attributes."""
Copy link
Member

@ammaraskar ammaraskar Sep 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I think there's a simpler way to test this, just do:

from datetime import *

This will throw an AttributeError if you have an invalid attribute defined there.

Example (test.py):

__all__ = ['a']
b = 1
>>> from test import *
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'test' has no attribute 'a'

cc @pganssle

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ammaraskar from x import * is only valid at the top level of a file, so this cannot be executed in a test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pganssle Ah, is this already the most viable way to test the validity of the attributes then?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it's the best one I could think of. There may be better tests for __all__, but given that this module already does some funky and apparently fragile stuff with the import mechanism, I think it's probably best not to try to get too fancy - particularly since it's not that important of a test.

@aeros aeros added the type-feature A feature request or enhancement label Sep 16, 2019
Copy link
Contributor

@aeros aeros left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @tahia-khan.

I have some suggestions regarding the news entry, but overall +1 on the PR. This seems to be well aligned with what @pganssle was asking for in the issue comments.

@@ -0,0 +1 @@
Add __all__ to the datetime module, including unit tests.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made a couple of minor formatting adjustments and removed the part about the tests. News entries typically don't contain information about the tests, as they aren't part of the public API.

Suggested change
Add __all__ to the datetime module, including unit tests.
Add ``__all__`` to :mod:`datetime`.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tahia-khan You may also want to (optionally) add your name to the news - "Patch by Tahia Khan." (or whatever you prefer to be credited as).

Lib/datetime.py Outdated
@@ -4,6 +4,8 @@
time zone and DST data sources.
"""

__all__ = ("date", "datetime", "time", "timedelta", "timezone", "tzinfo", "MINYEAR", "MAXYEAR")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure it follows to limit all lines to a maximum of 79 characters.
PEP8: https://www.python.org/dev/peps/pep-0008/#maximum-line-length

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case this isn't clear, this can easily be fixed by changing it to:

Suggested change
__all__ = ("date", "datetime", "time", "timedelta", "timezone", "tzinfo", "MINYEAR", "MAXYEAR")
__all__ = ("date", "datetime", "time", "timedelta", "timezone", "tzinfo",
"MINYEAR", "MAXYEAR")

@@ -19,7 +19,7 @@
from operator import lt, le, gt, ge, eq, ne, truediv, floordiv, mod

from test import support
from test.support import is_resource_enabled, ALWAYS_EQ, LARGEST, SMALLEST
from test.support import import_fresh_module, is_resource_enabled, ALWAYS_EQ, LARGEST, SMALLEST
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section is also going over the 79 char limit. Please adjust it accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this I'll go with parenthesis notation from the PEP328 rather than backslashes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you won't need to change this line at all once you have dropped test_c_all.

Copy link
Member

@pganssle pganssle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR @tahia-khan, and thanks for the reviews @aeros167 and @ammaraskar! With the formatting changes and dropping test_c_all, I think this looks pretty good.

I was mildly taken aback that you've defined __all__ as a tuple rather than a list, which is traditional, but I don't see any reason why it shouldn't be a list, and in fact __all__ being immutable makes more sense than mutable, so I'm not sure why it's not more common.

for attr in datetime_module.__all__:
self.assertIn(attr, all_attrs)

def test_c_all(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think this is the right place for this test - datetimetester.py is executed twice - once with the C module and once with the Python module. This may also mess with the state of sys.modules, see this comment.

I think just drop the test_c_all test and just leave the other test.

@@ -0,0 +1 @@
Add __all__ to the datetime module, including unit tests.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tahia-khan You may also want to (optionally) add your name to the news - "Patch by Tahia Khan." (or whatever you prefer to be credited as).

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@ta1hia
Copy link
Contributor Author

ta1hia commented Sep 17, 2019

Thanks everybody for the detailed change suggestions. I'll wait a bit for the final reviewer and submit all changes in one commit.

I was mildly taken aback that you've defined __all__ as a tuple rather than a list, which is traditional, but I don't see any reason why it shouldn't be a list, and in fact __all__ being immutable makes more sense than mutable, so I'm not sure why it's not more common.

@pganssle Ah - I didn't actually realize lists were the usual choice. I was peeking around other files that had an __all__ defined and it seemed like both lists and tuples were being used, so I went with the immutable choice :)

@pganssle
Copy link
Member

Ah - I didn't actually realize lists were the usual choice. I was peeking around other files that had an __all__ defined and it seemed like both lists and tuples were being used, so I went with the immutable choice :)

Yes, I agree that you made the sensible choice here. I tried looking it up and I could see no one arguing that you shouldn't use a tuple, and some people arguing that you shouldn't use a list, so I say we keep it as tuple.

@pganssle pganssle requested review from pganssle and removed request for abalkin September 17, 2019 13:26
@ta1hia
Copy link
Contributor Author

ta1hia commented Sep 18, 2019

I have made the requested changes; please review again

@bedevere-bot
Copy link

Thanks for making the requested changes!

@pganssle: please review the changes made to this pull request.

Copy link
Member

@pganssle pganssle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks everyone, this looks good, so I've rebased it and I'm going to merge now.

The alignment in the latest version also looked a little off for whatever reason, I aligned the second line in the __all__ to the parenthesis as part of the rebase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-feature A feature request or enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants