[pypy-commit] pypy py3.5-time: better fit the visible field concept with extra_fields in _structseq.py

plan_rich pypy.commits at gmail.com
Tue Jan 3 09:46:16 EST 2017


Author: Richard Plangger <planrichi at gmail.com>
Branch: py3.5-time
Changeset: r89334:048cc5e4d429
Date: 2017-01-03 15:31 +0100
http://bitbucket.org/pypy/pypy/changeset/048cc5e4d429/

Log:	better fit the visible field concept with extra_fields in
	_structseq.py

diff --git a/lib_pypy/_structseq.py b/lib_pypy/_structseq.py
--- a/lib_pypy/_structseq.py
+++ b/lib_pypy/_structseq.py
@@ -46,11 +46,14 @@
 
         extra_fields = sorted(fields_by_index.items())
         n_sequence_fields = 0
-        extra_off = 0
         if 'n_sequence_fields' in dict:
             n_sequence_fields = dict['n_sequence_fields']
-            extra_fields = extra_fields[:n_sequence_fields]
-            extra_off = n_fields - n_sequence_fields
+            extra_fields = extra_fields[n_sequence_fields:]
+            seq = n_sequence_fields
+            # pop all fields that are still in sequence!
+            while extra_fields and extra_fields[0][0] == seq:
+                extra_fields.pop(0)
+                seq += 1
         else:
             while extra_fields and extra_fields[0][0] == n_sequence_fields:
                 extra_fields.pop(0)
@@ -59,13 +62,12 @@
         dict['n_sequence_fields'] = n_sequence_fields
         dict['n_unnamed_fields'] = 0     # no fully anonymous fields in PyPy
 
-        extra_fields = [field for index, field in extra_fields[extra_off:]]
+        extra_fields = [field for index, field in extra_fields]
         for i,field in enumerate(extra_fields):
             field.index = None     # no longer relevant
 
         assert '__new__' not in dict
         dict['_extra_fields'] = tuple(extra_fields)
-        dict['_extra_off'] = extra_off
         dict['__new__'] = structseq_new
         dict['__reduce__'] = structseq_reduce
         dict['__setattr__'] = structseq_setattr
@@ -89,7 +91,7 @@
             msg = "at least"
         else:
             msg = "exactly"
-        raise TypeError("expected a sequence with %s %d items. has %d 1" % (
+        raise TypeError("expected a sequence with %s %d items. has %d" % (
             msg, visible_count, length))
     if length > visible_count:
         if length > real_count:
@@ -97,15 +99,14 @@
                 msg = "at most"
             else:
                 msg = "exactly"
-            raise TypeError("expected a sequence with %s %d items. has %d 2" \
+            raise TypeError("expected a sequence with %s %d items. has %d" \
                             % (msg, real_count, length))
         for field, value in zip(cls._extra_fields, sequence[visible_count:]):
             name = field.__name__
             if name in dict:
                 raise TypeError("duplicate value for %r" % (name,))
             dict[name] = value
-        extra_off = cls._extra_off
-        sequence = sequence[:visible_count+extra_off]
+        sequence = sequence[:visible_count]
     result = tuple.__new__(cls, sequence)
     object.__setattr__(result, '__dict__', dict)
     for field in cls._extra_fields:
@@ -124,9 +125,11 @@
 
 def structseq_repr(self):
     fields = {}
+    visible_count = self.n_sequence_fields
     for field in type(self).__dict__.values():
-        if isinstance(field, structseqfield):
+        if isinstance(field, structseqfield) and \
+           field._index <= visible_count:
             fields[field._index] = field
     parts = ["%s=%r" % (fields[index].__name__, value)
-             for index, value in enumerate(self)]
+            for index, value in enumerate(self[:visible_count])]
     return "%s(%s)" % (self._name, ", ".join(parts))
diff --git a/pypy/module/time/interp_time.py b/pypy/module/time/interp_time.py
--- a/pypy/module/time/interp_time.py
+++ b/pypy/module/time/interp_time.py
@@ -597,16 +597,16 @@
     rffi.setintfield(glob_buf, 'c_tm_wday', space.c_int_w(tup_w[6]))
     rffi.setintfield(glob_buf, 'c_tm_yday', tm_yday)
     rffi.setintfield(glob_buf, 'c_tm_isdst', space.c_int_w(tup_w[8]))
-    if HAS_TM_ZONE:
-        #tm_zone = encode_utf8(space, space.unicode_w(tup_w[9]), allow_surrogates=True)
-        #glob_buf.c_tm_zone = rffi.str2charp(tm_zone)
-        # TODO using str2charp allocates an object that is never freed
-        # find a solution for this memory leak
-        glob_buf.c_tm_zone = lltype.nullptr(rffi.CCHARP.TO)
-        rffi.setintfield(glob_buf, 'c_tm_gmtoff', space.c_int_w(tup_w[10]))
-    else:
-        glob_buf.c_tm_zone = lltype.nullptr(rffi.CCHARP.TO)
-        rffi.setintfield(glob_buf, 'c_tm_gmtoff', 0)
+    #
+    glob_buf.c_tm_zone = lltype.nullptr(rffi.CCHARP.TO)
+    rffi.setintfield(glob_buf, 'c_tm_gmtoff', 0)
+    if HAS_TM_ZONE :
+        if len(tup_w) >= 10:
+            # XXX str2charp leaks the object
+            tm_zone = encode_utf8(space, space.unicode_w(tup_w[9]), allow_surrogates=True)
+            glob_buf.c_tm_zone = rffi.str2charp(tm_zone, track_allocation=False)
+        if len(tup_w) >= 11:
+            rffi.setintfield(glob_buf, 'c_tm_gmtoff', space.c_int_w(tup_w[10]))
 
     # tm_wday does not need checking of its upper-bound since taking "%
     #  7" in _gettmarg() automatically restricts the range.


More information about the pypy-commit mailing list