Opened 16 years ago

Closed 15 years ago

Last modified 15 years ago

#124 closed defect (fixed)

"sets" module is deprecated in py2.6

Reported by: Brian Warner Owned by:
Priority: minor Milestone: 0.5.0
Component: unknown Version: 0.3.0
Keywords: Cc:

Description

Running foolscap under python2.6 provokes a deprecation warning, because the old "sets" module (added in py2.3 and obsoleted with the builtin set/frozenset types in py2.4) has finally been deprecated.

To hush the warning in py2.6, we need to stop importing "sets". However, doing that will cause us to stop being compatible with code that was written to be compatible with py2.3 (by using e.g. sets.ImmutableSet? instead of frozenset), even if that code is now only run against py2.4 or py2.5 .

If this py2.3-py2.5 code imports the "sets" module, then we'll need to be able to serialize any Set or ImmutableSet? instances that it creates, so we need to be able to recognize those classes as slicing time. (on the deserialization side, we turn these into set and frozenset, so it doesn't matter at unslicing time).

I suppose the answer is to give up on compatibility with this sort of code, but it makes me feel bad: Foolscap's desire to be less noisy with py2.6 might push someone who wasn't trying to use py2.6 to give up on their py2.3 users.

I'm going to put off fixing this for a little while, maybe a release or two.

Change History (7)

comment:1 Changed 16 years ago by ivank

http://twistedmatrix.com/trac/browser/tags/releases/twisted-8.2.0/twisted/spread/jelly.py

does this:

try:
    # Filter out deprecation warning for Python >= 2.6
    warnings.filterwarnings("ignore", category=DeprecationWarning,
        message="the sets module is deprecated", append=True)
    import sets as _sets
finally:
    warnings.filters.pop()

comment:2 in reply to:  description Changed 16 years ago by sreejith

For slicers/set.py may I suggest the following change; this maintains compatibility if a Set or Immutable set is used, only importing the sets module if the object passed is not a set or frozenset. I think this might be a pretty good temporary solution

--- set.py	2009/05/22 13:09:18	1.1
+++ set.py	2009/05/27 05:45:16	1.2
@@ -1,6 +1,5 @@
 # -*- test-case-name: foolscap.test.test_banana -*-
 
-import sets
 from twisted.internet import defer
 from twisted.python import log
 from foolscap.slicers.list import ListSlicer
@@ -34,8 +33,10 @@
 # code that is compatible with python2.3 might not work with foolscap.
 
 class OldSetSlicer(SetSlicer):
+    import sets
     slices = sets.Set
 class OldImmutableSetSlicer(FrozenSetSlicer):
+    import sets
     slices = sets.ImmutableSet
 
 class _Placeholder:
@@ -166,9 +167,10 @@
     # enough. We need to override checkOpenType to accomplish this.
     opentypes = [("set",), ("immutable-set",)]
     name = "SetConstraint"
-
-    mutable_set_types = (set, sets.Set)
-    immutable_set_types = (frozenset, sets.ImmutableSet)
+    
+    builtin_set_types = (set, frozenset)
+    mutable_set_types = (set,)
+    immutable_set_types = (frozenset,)
     all_set_types = mutable_set_types + immutable_set_types
 
     def __init__(self, constraint, maxLength=None, mutable=None):
@@ -177,13 +179,22 @@
         self.mutable = mutable
 
     def checkObject(self, obj, inbound):
-        if not isinstance(obj, self.all_set_types):
+        mutable_set_types = self.mutable_set_types
+        immutable_set_types = self.immutable_set_types
+        if not isinstance(obj, self.builtin_set_types):
+            import sets
+            mutable_set_types = self.mutable_set_types + (sets.Set,)
+            immutable_set_types = (self.immutable_set_types + 
+                                    (sets.ImmutableSet,))
+        all_set_types = mutable_set_types + immutable_set_types
+
+        if not isinstance(obj, all_set_types):
             raise Violation("not a set")
         if (self.mutable == True and
-            not isinstance(obj, self.mutable_set_types)):
+            not isinstance(obj, mutable_set_types)):
             raise Violation("obj is a set, but not a mutable one")
         if (self.mutable == False and
-            not isinstance(obj, self.immutable_set_types)):
+            not isinstance(obj, immutable_set_types)):
             raise Violation("obj is a set, but not an immutable one")
         if self.maxLength is not None and len(obj) > self.maxLength:
             raise Violation("set is too large")

comment:3 Changed 15 years ago by Brian Warner

hm, thanks for the ideas! I suspect that this wouldn't be enough to avoid importing 'sets', though, because all BaseSlicer-based slicer classes are auto-loaded at import time (via the metaclass in foolscap/slicer.py). The real issue is that application code might send an old-style sets.Set object at any time (as an argument to a callRemote invocation), and foolscap needs to be prepared to identify them (so it can dispatch to the right slicer). This dispatch mechanism uses zope.interface adapters, but that's effectively a big dictionary. If it used, say, string comparison of class/type names instead, this wouldn't be a problem (but we'd have other problems instead).

comment:4 Changed 15 years ago by Brian Warner

Milestone: undecided0.5.0
Resolution: fixed
Status: newclosed

I ended up applying ivank's suggestion, to just suppress the warning. This seemed like the best approach. Fixed in [96d40f2c53b0a02299b3dc0965f6caf335469a6a]/[96d40f2c53b0a02299b3dc0965f6caf335469a6a].

comment:5 Changed 15 years ago by Zooko

A user reported this DeprecationWarning as a bug in Tahoe-LAFS: http://allmydata.org/trac/tahoe/ticket/859

comment:6 Changed 15 years ago by Zooko

If the version of Tahoe-LAFS that ships in Ubuntu 10.04 Lucid Lynx LTS is to have no warnings then either a new version of foolscap needs to be release and uploaded into Karmic or else Tahoe-LAFS needs to suppress this warning itself.

comment:7 Changed 15 years ago by Zooko

Brian has released foolscap v0.5 and the NEWS file says that this ticket was fixed in that release.

Note: See TracTickets for help on using tickets.