@@ -947,7 +947,7 @@ call_tzname(PyObject *tzinfo, PyObject *tzinfoarg)
947947 result = PyObject_CallMethod (tzinfo , "tzname" , "O" , tzinfoarg );
948948
949949 if (result != NULL && result != Py_None ) {
950- if (!PyString_Check ( result ) && ! PyUnicode_Check (result )) {
950+ if (!PyUnicode_Check (result )) {
951951 PyErr_Format (PyExc_TypeError , "tzinfo.tzname() must "
952952 "return None or a string, not '%s'" ,
953953 Py_Type (result )-> tp_name );
@@ -1133,7 +1133,7 @@ make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
11331133{
11341134 PyObject * temp ;
11351135 PyObject * tzinfo = get_tzinfo_member (object );
1136- PyObject * Zreplacement = PyString_FromString ("" );
1136+ PyObject * Zreplacement = PyBytes_FromStringAndSize ("" , 0 );
11371137 if (Zreplacement == NULL )
11381138 return NULL ;
11391139 if (tzinfo == Py_None || tzinfo == NULL )
@@ -1159,15 +1159,13 @@ make_Zreplacement(PyObject *object, PyObject *tzinfoarg)
11591159 if (Zreplacement == NULL )
11601160 return NULL ;
11611161 if (PyUnicode_Check (Zreplacement )) {
1162- PyObject * Zreplacement2 =
1163- _PyUnicode_AsDefaultEncodedString (Zreplacement , NULL );
1164- if (Zreplacement2 == NULL )
1162+ PyObject * tmp = PyUnicode_AsUTF8String (Zreplacement );
1163+ if (tmp == NULL )
11651164 return NULL ;
1166- Py_INCREF (Zreplacement2 );
11671165 Py_DECREF (Zreplacement );
1168- Zreplacement = Zreplacement2 ;
1166+ Zreplacement = tmp ;
11691167 }
1170- if (!PyString_Check (Zreplacement )) {
1168+ if (!PyBytes_Check (Zreplacement )) {
11711169 PyErr_SetString (PyExc_TypeError ,
11721170 "tzname.replace() did not return a string" );
11731171 goto Error ;
@@ -1209,11 +1207,13 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
12091207 int ntoappend ; /* # of bytes to append to output buffer */
12101208
12111209 assert (object && format && timetuple );
1212- assert (PyString_Check (format ) || PyUnicode_Check (format ));
1210+ assert (PyUnicode_Check (format ));
1211+ /* Convert the input format to a C string and size */
1212+ pin = PyUnicode_AsString (format );
1213+ if (!pin )
1214+ return NULL ;
1215+ flen = PyUnicode_GetSize (format );
12131216
1214- /* Convert the input format to a C string and size */
1215- if (PyObject_AsCharBuffer (format , & pin , & flen ) < 0 )
1216- return NULL ;
12171217
12181218 /* Give up if the year is before 1900.
12191219 * Python strftime() plays games with the year, and different
@@ -1245,9 +1245,9 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
12451245 * is expensive, don't unless they're actually used.
12461246 */
12471247 totalnew = flen + 1 ; /* realistic if no %z/%Z */
1248- newfmt = PyString_FromStringAndSize (NULL , totalnew );
1248+ newfmt = PyBytes_FromStringAndSize (NULL , totalnew );
12491249 if (newfmt == NULL ) goto Done ;
1250- pnew = PyString_AsString (newfmt );
1250+ pnew = PyBytes_AsString (newfmt );
12511251 usednew = 0 ;
12521252
12531253 while ((ch = * pin ++ ) != '\0' ) {
@@ -1267,7 +1267,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
12671267 /* format utcoffset */
12681268 char buf [100 ];
12691269 PyObject * tzinfo = get_tzinfo_member (object );
1270- zreplacement = PyString_FromString ("" );
1270+ zreplacement = PyBytes_FromStringAndSize ("" , 0 );
12711271 if (zreplacement == NULL ) goto Done ;
12721272 if (tzinfo != Py_None && tzinfo != NULL ) {
12731273 assert (tzinfoarg != NULL );
@@ -1278,13 +1278,16 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
12781278 tzinfoarg ) < 0 )
12791279 goto Done ;
12801280 Py_DECREF (zreplacement );
1281- zreplacement = PyString_FromString (buf );
1282- if (zreplacement == NULL ) goto Done ;
1281+ zreplacement =
1282+ PyBytes_FromStringAndSize (buf ,
1283+ strlen (buf ));
1284+ if (zreplacement == NULL )
1285+ goto Done ;
12831286 }
12841287 }
12851288 assert (zreplacement != NULL );
1286- ptoappend = PyString_AS_STRING (zreplacement );
1287- ntoappend = PyString_GET_SIZE (zreplacement );
1289+ ptoappend = PyBytes_AS_STRING (zreplacement );
1290+ ntoappend = PyBytes_GET_SIZE (zreplacement );
12881291 }
12891292 else if (ch == 'Z' ) {
12901293 /* format tzname */
@@ -1295,9 +1298,9 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
12951298 goto Done ;
12961299 }
12971300 assert (Zreplacement != NULL );
1298- assert (PyString_Check (Zreplacement ));
1299- ptoappend = PyString_AS_STRING (Zreplacement );
1300- ntoappend = PyString_GET_SIZE (Zreplacement );
1301+ assert (PyBytes_Check (Zreplacement ));
1302+ ptoappend = PyBytes_AS_STRING (Zreplacement );
1303+ ntoappend = PyBytes_GET_SIZE (Zreplacement );
13011304 }
13021305 else {
13031306 /* percent followed by neither z nor Z */
@@ -1308,35 +1311,35 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
13081311 /* Append the ntoappend chars starting at ptoappend to
13091312 * the new format.
13101313 */
1311- assert (ptoappend != NULL );
1312- assert (ntoappend >= 0 );
13131314 if (ntoappend == 0 )
13141315 continue ;
1316+ assert (ptoappend != NULL );
1317+ assert (ntoappend > 0 );
13151318 while (usednew + ntoappend > totalnew ) {
13161319 int bigger = totalnew << 1 ;
13171320 if ((bigger >> 1 ) != totalnew ) { /* overflow */
13181321 PyErr_NoMemory ();
13191322 goto Done ;
13201323 }
1321- if (_PyString_Resize ( & newfmt , bigger ) < 0 )
1324+ if (PyBytes_Resize ( newfmt , bigger ) < 0 )
13221325 goto Done ;
13231326 totalnew = bigger ;
1324- pnew = PyString_AsString (newfmt ) + usednew ;
1327+ pnew = PyBytes_AsString (newfmt ) + usednew ;
13251328 }
13261329 memcpy (pnew , ptoappend , ntoappend );
13271330 pnew += ntoappend ;
13281331 usednew += ntoappend ;
13291332 assert (usednew <= totalnew );
13301333 } /* end while() */
13311334
1332- if (_PyString_Resize ( & newfmt , usednew ) < 0 )
1335+ if (PyBytes_Resize ( newfmt , usednew ) < 0 )
13331336 goto Done ;
13341337 {
13351338 PyObject * time = PyImport_ImportModule ("time" );
13361339 if (time == NULL )
13371340 goto Done ;
13381341 result = PyObject_CallMethod (time , "strftime" , "OO" ,
1339- newfmt , timetuple );
1342+ PyUnicode_FromString ( PyBytes_AS_STRING ( newfmt )) , timetuple );
13401343 Py_DECREF (time );
13411344 }
13421345 Done :
@@ -2420,7 +2423,7 @@ date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
24202423 PyObject * tuple ;
24212424 static char * keywords [] = {"format" , NULL };
24222425
2423- if (! PyArg_ParseTupleAndKeywords (args , kw , "S :strftime" , keywords ,
2426+ if (! PyArg_ParseTupleAndKeywords (args , kw , "U :strftime" , keywords ,
24242427 & format ))
24252428 return NULL ;
24262429
@@ -2511,18 +2514,36 @@ date_replace(PyDateTime_Date *self, PyObject *args, PyObject *kw)
25112514 return clone ;
25122515}
25132516
2514- static PyObject * date_getstate (PyDateTime_Date * self , int hashable );
2517+ /*
2518+ Borrowed from stringobject.c, originally it was string_hash()
2519+ */
2520+ static long
2521+ generic_hash (unsigned char * data , int len )
2522+ {
2523+ register unsigned char * p ;
2524+ register long x ;
2525+
2526+ p = (unsigned char * ) data ;
2527+ x = * p << 7 ;
2528+ while (-- len >= 0 )
2529+ x = (1000003 * x ) ^ * p ++ ;
2530+ x ^= len ;
2531+ if (x == -1 )
2532+ x = -2 ;
2533+
2534+ return x ;
2535+ }
2536+
2537+
2538+ static PyObject * date_getstate (PyDateTime_Date * self );
25152539
25162540static long
25172541date_hash (PyDateTime_Date * self )
25182542{
2519- if (self -> hashcode == -1 ) {
2520- PyObject * temp = date_getstate (self , 1 );
2521- if (temp != NULL ) {
2522- self -> hashcode = PyObject_Hash (temp );
2523- Py_DECREF (temp );
2524- }
2525- }
2543+ if (self -> hashcode == -1 )
2544+ self -> hashcode = generic_hash (
2545+ (unsigned char * )self -> data , _PyDateTime_DATE_DATASIZE );
2546+
25262547 return self -> hashcode ;
25272548}
25282549
@@ -2545,22 +2566,18 @@ date_weekday(PyDateTime_Date *self)
25452566
25462567/* __getstate__ isn't exposed */
25472568static PyObject *
2548- date_getstate (PyDateTime_Date * self , int hashable )
2569+ date_getstate (PyDateTime_Date * self )
25492570{
25502571 PyObject * field ;
2551- if (hashable )
2552- field = PyString_FromStringAndSize (
2553- (char * )self -> data , _PyDateTime_DATE_DATASIZE );
2554- else
2555- field = PyBytes_FromStringAndSize (
2556- (char * )self -> data , _PyDateTime_DATE_DATASIZE );
2572+ field = PyBytes_FromStringAndSize (
2573+ (char * )self -> data , _PyDateTime_DATE_DATASIZE );
25572574 return Py_BuildValue ("(N)" , field );
25582575}
25592576
25602577static PyObject *
25612578date_reduce (PyDateTime_Date * self , PyObject * arg )
25622579{
2563- return Py_BuildValue ("(ON)" , Py_Type (self ), date_getstate (self , 0 ));
2580+ return Py_BuildValue ("(ON)" , Py_Type (self ), date_getstate (self ));
25642581}
25652582
25662583static PyMethodDef date_methods [] = {
@@ -3246,9 +3263,11 @@ time_hash(PyDateTime_Time *self)
32463263 return -1 ;
32473264
32483265 /* Reduce this to a hash of another object. */
3249- if (offset == 0 )
3250- temp = PyString_FromStringAndSize ((char * )self -> data ,
3251- _PyDateTime_TIME_DATASIZE );
3266+ if (offset == 0 ) {
3267+ self -> hashcode = generic_hash (
3268+ (unsigned char * )self -> data , _PyDateTime_TIME_DATASIZE );
3269+ return self -> hashcode ;
3270+ }
32523271 else {
32533272 int hour ;
32543273 int minute ;
@@ -3765,12 +3784,12 @@ datetime_strptime(PyObject *cls, PyObject *args)
37653784 PyObject * result = NULL , * obj , * module ;
37663785 const char * string , * format ;
37673786
3768- if (!PyArg_ParseTuple (args , "ss :strptime" , & string , & format ))
3787+ if (!PyArg_ParseTuple (args , "uu :strptime" , & string , & format ))
37693788 return NULL ;
37703789
37713790 if ((module = PyImport_ImportModule ("time" )) == NULL )
37723791 return NULL ;
3773- obj = PyObject_CallMethod (module , "strptime" , "ss " , string , format );
3792+ obj = PyObject_CallMethod (module , "strptime" , "uu " , string , format );
37743793 Py_DECREF (module );
37753794
37763795 if (obj != NULL ) {
@@ -4154,10 +4173,11 @@ datetime_hash(PyDateTime_DateTime *self)
41544173 return -1 ;
41554174
41564175 /* Reduce this to a hash of another object. */
4157- if (n == OFFSET_NAIVE )
4158- temp = PyString_FromStringAndSize (
4159- (char * )self -> data ,
4160- _PyDateTime_DATETIME_DATASIZE );
4176+ if (n == OFFSET_NAIVE ) {
4177+ self -> hashcode = generic_hash (
4178+ (unsigned char * )self -> data , _PyDateTime_DATETIME_DATASIZE );
4179+ return self -> hashcode ;
4180+ }
41614181 else {
41624182 int days ;
41634183 int seconds ;
0 commit comments