nokyotsu
(Juan Antonio Navarro)
April 19, 2023, 10:27am
1
The calendar
module already defines constants e.g. MONDAY
(0), TUESDAY
(1), etc. for the days of the week .
Since these are likely to be commonly needed too, would it make sense for the calendar module to also export constants for all of JANUARY
(1), FEBRUARY
(2), …, DECEMBER
(12)?
This would allow one to write from calendar import APRIL
and then e.g. use APRIL
instead of 4
when building a datetime.date
object.
Related: datetime - Python module defining constants for month numbers? - Stack Overflow
Rosuav
(Chris Angelico)
April 19, 2023, 10:30am
2
It does seem a little odd, but the days of week are in all caps, where the months aren’t.
>>> calendar.February
2
>>> calendar.FRIDAY
4
nokyotsu
(Juan Antonio Navarro)
April 19, 2023, 10:45am
3
Note January
and February
are defined but:
not exported in __all__
,
all other months are missing.
In addition to the discrepancy on case.
Rosuav
(Chris Angelico)
April 19, 2023, 10:51am
4
Oh. I didn’t even notice that. Curious. It looks like those particular constants should probably be considered internal, then.
TBH these should probably be an enum, not just loose integers in the module. I don’t use the calendar module enough to have a strong opinion, but if you look at things like re.VERBOSE
there’s good precedent for using an enum for this.
3 Likes
MrFuppes
(Florian Obersteiner)
April 19, 2023, 11:28am
5
a bit of context; some other languages do define such constants in their standard libraries:
go
Java 8
Rust
- chrono crate is not exactly standard lib but pretty close afaik
…so for a language like Python it wouldn’t hurt in my eyes to have such a convenience
MrFuppes
(Florian Obersteiner)
April 19, 2023, 11:37am
6
+1 for using (int) enums
turns out the weekdays are derived from a range
1 Like
Rosuav
(Chris Angelico)
April 19, 2023, 11:49am
7
Yeah, deriving from a range is a pretty reasonable way to do a naive enumeration. But since we have the actual enum module now, it’s better to use that IMO.
nokyotsu
(Juan Antonio Navarro)
April 19, 2023, 12:54pm
8
Indeed, using a global_enum
as in re.VERBOSE
sounds like a great idea to me.
tjreedy
(Terry Jan Reedy)
April 19, 2023, 8:39pm
9
@smontanaro You seem to know calendar
as well as any current dev. Any opinion on this idea? Would using an enum also for the days break anything?
stoneleaf
(Ethan Furman)
April 19, 2023, 8:57pm
10
Not Skip, but If we use an IntEnum
nothing should break. Hopefully calendar
has good tests!
Rosuav
(Chris Angelico)
April 19, 2023, 9:13pm
12
It shouldn’t. The aforementioned regex flags were changed in that exact sort of way:
rosuav@sikorsky:~$ python3.5 -c 'import re; print(type(re.VERBOSE))'
<class 'int'>
rosuav@sikorsky:~$ python3.6 -c 'import re; print(type(re.VERBOSE))'
<enum 'RegexFlag'>
rosuav@sikorsky:~$ python3.11 -c 'import re; print(type(re.VERBOSE))'
<flag 'RegexFlag'>
where RegexFlag is an IntFlag (because they’re bitwise - for the days and months, IntEnum would be the choice).
Since calendar.January
and calendar.February
are intended for internal use, should they be deprecated in favour of the new enums?
hugovk
(Hugo van Kemenade)
April 19, 2023, 9:56pm
13
Searching the top 5k packages , they only show up in jsonargparse
:
$ python3 ~/github/misc/cpython/search_pypi_top.py -q . "from calendar import .*(January|February)"
./jsonargparse-4.20.1.tar.gz: jsonargparse-4.20.1/jsonargparse_tests/test_signatures.py: from calendar import Calendar, January # type: ignore
Time: 0:00:16.076726
Found 1 matching lines in 1 projects
$ python3 ~/github/misc/cpython/search_pypi_top.py -q . "calendar\.(January|February)"
./jsonargparse-4.20.1.tar.gz: jsonargparse-4.20.1/jsonargparse_tests/test_signatures.py: self.assertRaises(ArgumentError, lambda: parser.parse_args(['--cal={"class_path":"calendar.January"}']))
./jsonargparse-4.20.1.tar.gz: jsonargparse-4.20.1/jsonargparse_tests/test_signatures.py: self.assertRaises(ArgumentError, lambda: parser.parse_args(['--cal.help=calendar.January']))
Time: 0:00:15.878868
Found 2 matching lines in 1 projects
hugovk
(Hugo van Kemenade)
April 19, 2023, 10:11pm
14
And only 12 and 22 files found via GitHub’s beta code search.
stoneleaf
(Ethan Furman)
April 19, 2023, 11:42pm
15
I can see them being IntFlag
– makes it easy to represent a task that happens on M/W/F.
hugovk
(Hugo van Kemenade)
April 25, 2023, 6:58am
16
gh-103636: add enums for days and months in calendar module by Agent-Hellboy · Pull Request #103642 · python/cpython · GitHub has added the month and day enums (JANUARY
- DECEMBER
, MONDAY - SUNDAY
), and removed the two January
and February
constants.
What’s the advice for projects using the now-removed constants? Something like this?
try:
# Python 3.12+
from calendar import JANUARY
except ImportError:
# Python <= 3.11
from calendar import January as JANUARY
I’m pretty sure PEP-387 says that we cannot remove January
and February
without a deprecation period. I’d strongly consider adding back those two constants.
nokyotsu
(Juan Antonio Navarro)
April 25, 2023, 9:22am
18
This was discussed in the pull request . As I understand, the old constants were never part of the public API and, as such, it was decided no deprecation warning was required.
I’m not so sure about that. Hugo’s example is perfectly valid in 3.11. Now it is not valid. I suggest asking the SC.
1 Like
stoneleaf
(Ethan Furman)
April 25, 2023, 2:25pm
20
Is this a hypothetical, or do you know of projects actually doing this?
Only January
and February
were defined (not March - December), and they were not part of the public API (so PEP 387 does not apply).
We could add a module-level __getattr__
to continue to provide January
and February
and issue a warning to anybody who is using it…