#14823: Unexpected behavior with core.serializers.register_serializer and
unregister_serializer
-----------------------------+----------------------------------------------
 Reporter:  miker...@uw.edu  |       Owner:  nobody    
   Status:  new              |   Milestone:            
Component:  Serialization    |     Version:  SVN       
 Keywords:                   |       Stage:  Unreviewed
Has_patch:  1                |  
-----------------------------+----------------------------------------------
 Almost all the functions in {{{serializers/__init__.py}}} begin with the
 lines
 {{{
 if not _serializers:
     _load_serializers()
 }}}
 but register_serializer and unregister_serializer do not.

 When only using the built-in serializers you didn't have to manually
 register them but if you used an additional serializer you either have to

  1. Include it in settings.SERIALIZATION_MODULES (probably the "right way"
 to do things, but then why make register_serializer public?)
  1. call _load_serializers (non-public API)
  1. manually register both the built-ins and those listed in
 settings.SERIALIZATION_MODULES (duplicating _load_serializers)
  1. call any public function in {{{__init__.py}}} except
 register_serializer or unregister_serializer before registering (strange
 order of operations)

 To reproduce (from a fresh `python manage.py shell`)
 {{{
 from django.core import serializers
 serializers.register_serializer('json2', 'django.core.serializers.json')
 serializers.get_public_serializer_formats() # ['json2']
 serializers.get_serializer('xml') # KeyError: 'xml'
 }}}

 I've attached a patch that adds the same {{{if not _serializers:}}} check
 for register_serializer and unregister_serializer. It keeps with the
 general mentality of the existing code (e.g., not using a separate boolean
 value to check for registration) but introduces an edge case where code
 that attempts to unregister all built-in serializers before registering
 it's own will effectively do nothing. e.g.

 {{{
 from django.core import serializers
 serializers.unregister_serializer('json') # loads json/python/xml (assume
 no yaml), then unregisters json
 serializers.unregister_serializer('xml')
 serializers.unregister_serializer('python') # _serializers is now an empty
 dict
 serializers.register_serializer('foo', 'foo.bar.baz') # re-registers
 json/python/xml, then registers foo.
 }}}
 Under the existing code you'd get a {{{KeyError}}} when attempting to
 unregister json (since it hasn't been loaded yet).

 Alternatively, it could be determined that register_serializer and
 unregister_serializer aren't stable API (they're not documented on the
 Serialization topic page). If that's the case it may make more sense to
 just prefix them with an _ and/or leave a note similar to the thread-safe
 notes.

-- 
Ticket URL: <http://code.djangoproject.com/ticket/14823>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-upda...@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to