Skip to content

Commit 8fefd5a

Browse files
committed
add ob_randomflag state in floatobject
add ob_randomflag state in unicodeobject allow state to transfer and maintain check whether such flag is on in len() add tests
1 parent f282e9d commit 8fefd5a

9 files changed

Lines changed: 54 additions & 88 deletions

File tree

Include/cpython/floatobject.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@
55
typedef struct {
66
PyObject_HEAD
77
double ob_fval;
8+
unsigned char ob_randomflag;
89
} PyFloatObject;
910

11+
#define NOT_FROM_RANDOM 0
12+
#define FROM_RANDOM 1
13+
1014
// Macro version of PyFloat_AsDouble() trading safety for speed.
1115
// It doesn't check if op is a double object.
1216
#define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval)
1317

18+
PyAPI_FUNC(PyObject *) _PyFloat_FromDoubleWithFlags(double x, unsigned char flags);
1419

1520
PyAPI_FUNC(int) PyFloat_Pack2(double x, char *p, int le);
1621
PyAPI_FUNC(int) PyFloat_Pack4(double x, char *p, int le);

Include/cpython/unicodeobject.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ typedef struct {
135135
unsigned int ascii:1;
136136
/* Padding to ensure that PyUnicode_DATA() is always aligned to
137137
4 bytes (see issue #19537 on m68k). */
138-
unsigned int :25;
138+
unsigned int ob_randomflag:1;
139+
unsigned int :24;
139140
} state;
140141
} PyASCIIObject;
141142

@@ -500,6 +501,11 @@ PyAPI_FUNC(PyObject*) _PyUnicode_FromASCII(
500501
const char *buffer,
501502
Py_ssize_t size);
502503

504+
PyAPI_FUNC(PyObject*) _PyUnicode_FromASCII_withRandomFlag(
505+
const char *buffer,
506+
Py_ssize_t size,
507+
unsigned char flag);
508+
503509
/* Compute the maximum character of the substring unicode[start:end].
504510
Return 127 for an empty string. */
505511
PyAPI_FUNC(Py_UCS4) _PyUnicode_FindMaxChar (

Lib/test/test_py2xwarn.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ def test_random(self):
4242
expected = "String repr of random.random() is longer in 3.x, change code accordingly"
4343
import random
4444
with check_py2x_warnings(("", Py2xWarning)) as w:
45-
self.assertWarning(str(random.random()), w, expected)
45+
self.assertWarning(len(str(random.random())), w, expected)
46+
w.reset()
47+
self.assertNoWarning(len(str(0.123456)), w)
4648

4749
def test_truncate0(self):
4850
expected = "Calling truncate(0) on text stream without seek(0)" + \

Modules/_randommodule.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@
7272

7373
#include "Python.h"
7474
#include "pycore_moduleobject.h" // _PyModule_GetState()
75-
#include "pg_float.h"
7675
#ifdef HAVE_PROCESS_H
7776
# include <process.h> // getpid()
7877
#endif
@@ -180,7 +179,7 @@ _random_Random_random_impl(RandomObject *self)
180179
uint32_t a=genrand_uint32(self)>>5, b=genrand_uint32(self)>>6;
181180
double x = (a * 67108864.0 + b) * (1.0 / 9007199254740992.0);
182181
if (Py_Py2xWarningFlag){
183-
return PgFloat_FromDouble(x,1);
182+
return _PyFloat_FromDoubleWithFlags(x,FROM_RANDOM);
184183
}
185184
else{
186185
return PyFloat_FromDouble(x);

Modules/pg_float.c

Lines changed: 0 additions & 68 deletions
This file was deleted.

Modules/pg_float.h

Lines changed: 0 additions & 12 deletions
This file was deleted.

Objects/floatobject.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,20 @@ PyFloat_FromDouble(double fval)
153153
}
154154
_PyObject_Init((PyObject*)op, &PyFloat_Type);
155155
op->ob_fval = fval;
156+
op->ob_randomflag = NOT_FROM_RANDOM;
156157
return (PyObject *) op;
157158
}
158159

160+
PyObject *
161+
_PyFloat_FromDoubleWithFlags(double x, unsigned char flag)
162+
{
163+
PyObject *o = PyFloat_FromDouble(x);
164+
if (o == NULL)
165+
return NULL;
166+
((PyFloatObject *)o)->ob_randomflag = flag;
167+
return o;
168+
}
169+
159170
static PyObject *
160171
float_from_string_inner(const char *s, Py_ssize_t len, void *obj)
161172
{
@@ -376,14 +387,18 @@ float_repr(PyFloatObject *v)
376387
{
377388
PyObject *result;
378389
char *buf;
379-
380390
buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
381391
'r', 0,
382392
Py_DTSF_ADD_DOT_0,
383393
NULL);
384394
if (!buf)
385395
return PyErr_NoMemory();
386-
result = _PyUnicode_FromASCII(buf, strlen(buf));
396+
if (Py_Py2xWarningFlag){
397+
result = _PyUnicode_FromASCII_withRandomFlag(buf, strlen(buf), v->ob_randomflag);
398+
}
399+
else{
400+
result = _PyUnicode_FromASCII(buf, strlen(buf));
401+
}
387402
PyMem_Free(buf);
388403
return result;
389404
}

Objects/unicodeobject.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,7 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar)
11891189
_PyUnicode_STATE(unicode).kind = kind;
11901190
_PyUnicode_STATE(unicode).compact = 1;
11911191
_PyUnicode_STATE(unicode).ascii = is_ascii;
1192+
_PyUnicode_STATE(unicode).ob_randomflag = NOT_FROM_RANDOM;
11921193
if (is_ascii) {
11931194
((char*)data)[size] = 0;
11941195
}
@@ -1935,6 +1936,16 @@ _PyUnicode_FromASCII(const char *buffer, Py_ssize_t size)
19351936
return unicode;
19361937
}
19371938

1939+
PyObject*
1940+
_PyUnicode_FromASCII_withRandomFlag(const char *buffer, Py_ssize_t size, unsigned char flag)
1941+
{
1942+
PyObject *o = _PyUnicode_FromASCII(buffer, size);
1943+
if (o == NULL)
1944+
return NULL;
1945+
((PyASCIIObject *)o)->state.ob_randomflag = flag;
1946+
return o;
1947+
}
1948+
19381949
static Py_UCS4
19391950
kind_maxchar_limit(int kind)
19401951
{
@@ -11605,7 +11616,15 @@ unicode_join(PyObject *self, PyObject *iterable)
1160511616

1160611617
static Py_ssize_t
1160711618
unicode_length(PyObject *self)
11608-
{
11619+
{
11620+
if(Py_Py2xWarningFlag && PyUnicode_Check(self)){
11621+
if (((PyASCIIObject *)self)->state.ob_randomflag == 1) {
11622+
PyErr_WarnEx(
11623+
PyExc_Py2xWarning,
11624+
"String repr of random.random() is longer in 3.x, change code accordingly",
11625+
1);
11626+
}
11627+
}
1160911628
return PyUnicode_GET_LENGTH(self);
1161011629
}
1161111630

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,7 @@ def detect_simple_extensions(self):
940940
self.addext(Extension('_datetime', ['_datetimemodule.c']))
941941
self.addext(Extension('_zoneinfo', ['_zoneinfo.c']))
942942
# random number generator implemented in C
943-
self.addext(Extension("_random", ["_randommodule.c", "pg_float.c"]))
943+
self.addext(Extension("_random", ["_randommodule.c"]))
944944
self.addext(Extension("_bisect", ["_bisectmodule.c"]))
945945
self.addext(Extension("_heapq", ["_heapqmodule.c"]))
946946
# C-optimized pickle replacement

0 commit comments

Comments
 (0)