Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c510c6b

Browse files
authored
Simplify PyInit_timezone. (GH-9467)
Reduce the knotty preprocessor conditional logic, dedent unnecessarily nested code, and handle errors properly. The first edition of this change (afde1c1) failed (bpo-34715) because FreeBSD doesn't define the timezone globals. That's why we're now checking for HAVE_DECL_TZNAME.
1 parent a4ae828 commit c510c6b

2 files changed

Lines changed: 52 additions & 50 deletions

File tree

Modules/timemodule.c

Lines changed: 48 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,7 +1522,7 @@ PyDoc_STRVAR(get_clock_info_doc,
15221522
\n\
15231523
Get information of the specified clock.");
15241524

1525-
#if !defined(HAVE_TZNAME) || defined(__GLIBC__) || defined(__CYGWIN__)
1525+
#ifndef HAVE_DECL_TZNAME
15261526
static void
15271527
get_zone(char *zone, int n, struct tm *p)
15281528
{
@@ -1543,7 +1543,7 @@ get_gmtoff(time_t t, struct tm *p)
15431543
return timegm(p) - t;
15441544
#endif
15451545
}
1546-
#endif /* !defined(HAVE_TZNAME) || defined(__GLIBC__) || defined(__CYGWIN__) */
1546+
#endif // !HAVE_DECL_TZNAME
15471547

15481548
static void
15491549
PyInit_timezone(PyObject *m) {
@@ -1563,7 +1563,7 @@ PyInit_timezone(PyObject *m) {
15631563
15641564
And I'm lazy and hate C so nyer.
15651565
*/
1566-
#if defined(HAVE_TZNAME) && !defined(__GLIBC__) && !defined(__CYGWIN__)
1566+
#ifdef HAVE_DECL_TZNAME
15671567
PyObject *otz0, *otz1;
15681568
tzset();
15691569
PyModule_AddIntConstant(m, "timezone", timezone);
@@ -1574,54 +1574,52 @@ PyInit_timezone(PyObject *m) {
15741574
#endif
15751575
PyModule_AddIntConstant(m, "daylight", daylight);
15761576
otz0 = PyUnicode_DecodeLocale(tzname[0], "surrogateescape");
1577-
otz1 = PyUnicode_DecodeLocale(tzname[1], "surrogateescape");
1578-
PyModule_AddObject(m, "tzname", Py_BuildValue("(NN)", otz0, otz1));
1579-
#else /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/
1580-
{
1581-
#define YEAR ((time_t)((365 * 24 + 6) * 3600))
1582-
time_t t;
1583-
struct tm p;
1584-
long janzone, julyzone;
1585-
char janname[10], julyname[10];
1586-
t = (time((time_t *)0) / YEAR) * YEAR;
1587-
_PyTime_localtime(t, &p);
1588-
get_zone(janname, 9, &p);
1589-
janzone = -get_gmtoff(t, &p);
1590-
janname[9] = '\0';
1591-
t += YEAR/2;
1592-
_PyTime_localtime(t, &p);
1593-
get_zone(julyname, 9, &p);
1594-
julyzone = -get_gmtoff(t, &p);
1595-
julyname[9] = '\0';
1596-
1597-
if( janzone < julyzone ) {
1598-
/* DST is reversed in the southern hemisphere */
1599-
PyModule_AddIntConstant(m, "timezone", julyzone);
1600-
PyModule_AddIntConstant(m, "altzone", janzone);
1601-
PyModule_AddIntConstant(m, "daylight",
1602-
janzone != julyzone);
1603-
PyModule_AddObject(m, "tzname",
1604-
Py_BuildValue("(zz)",
1605-
julyname, janname));
1606-
} else {
1607-
PyModule_AddIntConstant(m, "timezone", janzone);
1608-
PyModule_AddIntConstant(m, "altzone", julyzone);
1609-
PyModule_AddIntConstant(m, "daylight",
1610-
janzone != julyzone);
1611-
PyModule_AddObject(m, "tzname",
1612-
Py_BuildValue("(zz)",
1613-
janname, julyname));
1614-
}
1577+
if (otz0 == NULL) {
1578+
return;
16151579
}
1616-
#ifdef __CYGWIN__
1617-
tzset();
1618-
PyModule_AddIntConstant(m, "timezone", _timezone);
1619-
PyModule_AddIntConstant(m, "altzone", _timezone-3600);
1620-
PyModule_AddIntConstant(m, "daylight", _daylight);
1621-
PyModule_AddObject(m, "tzname",
1622-
Py_BuildValue("(zz)", _tzname[0], _tzname[1]));
1623-
#endif /* __CYGWIN__ */
1624-
#endif /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/
1580+
otz1 = PyUnicode_DecodeLocale(tzname[1], "surrogateescape");
1581+
if (otz1 == NULL) {
1582+
Py_DECREF(otz0);
1583+
return;
1584+
}
1585+
PyObject *tzname_obj = Py_BuildValue("(NN)", otz0, otz1);
1586+
if (tzname_obj == NULL)
1587+
return;
1588+
PyModule_AddObject(m, "tzname", tzname_obj);
1589+
#else // !HAVE_DECL_TZNAME
1590+
static const time_t YEAR = (365 * 24 + 6) * 3600;
1591+
time_t t;
1592+
struct tm p;
1593+
long janzone, julyzone;
1594+
char janname[10], julyname[10];
1595+
t = (time((time_t *)0) / YEAR) * YEAR;
1596+
_PyTime_localtime(t, &p);
1597+
get_zone(janname, 9, &p);
1598+
janzone = -get_gmtoff(t, &p);
1599+
janname[9] = '\0';
1600+
t += YEAR/2;
1601+
_PyTime_localtime(t, &p);
1602+
get_zone(julyname, 9, &p);
1603+
julyzone = -get_gmtoff(t, &p);
1604+
julyname[9] = '\0';
1605+
1606+
PyObject *tzname_obj;
1607+
if (janzone < julyzone) {
1608+
/* DST is reversed in the southern hemisphere */
1609+
PyModule_AddIntConstant(m, "timezone", julyzone);
1610+
PyModule_AddIntConstant(m, "altzone", janzone);
1611+
PyModule_AddIntConstant(m, "daylight", janzone != julyzone);
1612+
tzname_obj = Py_BuildValue("(zz)", julyname, janname);
1613+
} else {
1614+
PyModule_AddIntConstant(m, "timezone", janzone);
1615+
PyModule_AddIntConstant(m, "altzone", julyzone);
1616+
PyModule_AddIntConstant(m, "daylight", janzone != julyzone);
1617+
tzname_obj = Py_BuildValue("(zz)", janname, julyname);
1618+
}
1619+
if (tzname_obj == NULL)
1620+
return;
1621+
PyModule_AddObject(m, "tzname", tzname_obj);
1622+
#endif // !HAVE_DECL_TZNAME
16251623
}
16261624

16271625

PC/pyconfig.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,10 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */
396396
/* Define to 1 if you have the <direct.h> header file. */
397397
#define HAVE_DIRECT_H 1
398398

399+
/* Define to 1 if you have the declaration of `tzname', and to 0 if you don't.
400+
*/
401+
#define HAVE_DECL_TZNAME 1
402+
399403
/* Define if you have dirent.h. */
400404
/* #define DIRENT 1 */
401405

0 commit comments

Comments
 (0)