-
-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
namedtuple should support fully qualified name for more portable pickling #62141
Comments
[this came up as part of the Enum discussions. Full details in this thread: http://mail.python.org/pipermail/python-dev/2013-May/126076.html] namedtuple currently uses this code to obtain the __module__ for the class it creates dynamically so that pickling works: result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__') This may not work correctly on all Python implementations, for example IronPython. To support some way to pickle on all implementations, namedtuple should support a fully qualified name for the class: Point = namedtuple('mymodule.Point', ['x', 'y']) If the name is a qualified dotted name, it will be split and the first part becomes the __module__. |
That will not work correctly if the module name has a dot in it. |
I agree it should work the same as Enum, and I agree it should be possible to supply the module name. But wouldn't it be cleaner as: Point = namedtuple('Point', 'x y z', module=__name__) rather than: Point = namedtuple(__name__ + '.Point', 'x y z') ? |
Agreed with Eric. We're already modifying PEP-435 to do it that way. |
A question that came up while reviewing the new enum code: "module" or "module_name" for this extra argument? The former is shorter, but the latter is more correct in a way. |
Module, please. The class attribute is also called __module__ after all. On Friday, May 10, 2013, Eli Bendersky wrote:
|
On Fri, May 10, 2013 at 7:02 AM, Guido van Rossum <report@bugs.python.org>wrote:
Makes sense. Thanks. |
Marking this a low priority. I want to see how it pans out for Enums before adding a new parameter to the namedtuple API. Also, I would like to look at the test cases for Enum so I can see how you're writing tests that would fail without this parameter. |
I'd like to propose one slight tweak to the patch. (Also to enum.py.) If no module name was passed and _getframe() fails, can you set the __module__ attribute to something that will cause pickling the object to fail? That would be much better than letting it pickle but then being unable to unpickle it. (TBH I'm not sure how this should be accomplished, and if it can't, forget that I said it. But it would be nice.) |
When pickling a class (or instance of a class) there is already a check
holds. >>> import pickle
>>> class A: pass
...
>>> A.__module__ = 'nonexistent'
>>> pickle.dumps(A())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class 'nonexistent.A'>: import of
module 'nonexistent' failed |
Great, forget I said anything then. LGTM to the patch, feel free to commit (with update to Misc/NEWS please). |
LGTM too. Needs test and docs. |
I would like to make an additional suggestion. Native namedtuple (not a derived class) can be made much simpler to handle The way I implemented it has no need for sys._getframes, and it does The advantage of doing so is that this maximizes the compatibility My implementation re-creates the namedtuple classes on the fly by a This is IMHO the way things should work: Rationale: Limitation: Cheers - Chris |
Just slipped under the radar? |
I was already thinking of the same solution Christian.Tismer proposed before I reached his post. namedtuples seem cleaner if they naturally act as singletons, so (potentially whether or not pickling is involved) declaring a namedtuple with the same name and fields twice returns the same class. Removes the need to deal with module qualified names, and if pickle can be made to support it, the namedtuple class itself could be pickled uniquely in such a way that it could be recreated by someone else who didn't even have a local definition of the namedtuple, the module that defines it, etc. |
Nope, I'll get to it before long. |
Ok, I almost forgot about this because I thought my idea It is still around, and I could put it into an experimental branch Missing pull-request on python.org. |
Pickling qualified names with arbitrary number of dots is supported in 3.4 with protocol 4 and in 3.5 with all protocols (backward compatibly). |
New changeset c8851a0ce7ca by Raymond Hettinger in branch 'default': |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: