Changelog
=========

This document contains information about the changes between the different
versions of PyAMF.

.. contents::

0.8 (2015-12-17)
----------------
- Add support for Django>=1.8
- *Backward incompatible* Wrapped all xml parsing in ``defusedxml`` to protect
  against any XML entity attacks. See
  https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Processing for more
  details. Thanks to Nicolas Grégoire (@Agarri_FR) for the report.

0.7.2 (2015-02-18)
------------------
- Add support for Cython >= 0.15 (should be backward compatible with future
  releases)
- Fix an issue in cpyamf where the class alias would not be cached correctly.

0.7.1 (2015-02-16)
------------------
- Add support for Cython <= 0.22
- Fix a bug in the AppEngine adapters where ``writeNull`` doesn't exist in the
  C extensions

0.7 (2015-02-10)
----------------
- Dropped support for Python 2.5. A Python 3 port is underway.
- Fix a rare string collision bug with AMF3 #36
- Updated to use the latest version of Cython (0.21.2) #34
- Added Travis/coveralls support.
- Add post processing callbacks to finalise the decoded payloads. #45
- Added support for `google.appengine.ext.ndb`. #47
- ``pyamf.Undefined`` now evaluates to ``False`` in a boolean expression
  (:ticket:`827`)
- Fixed an issue in the client where '; charset=utf8' would be appended to the
  ``Content-Type`` response header (:ticket:`822`)
- Add support for :py:class:`collections.OrderedDict` and
  :py:class:`collections.Counter` (:ticket:`816`, :ticket:`815`)
- ``pyamf.codec._Codec.__init__`` now supports duck-typing. (:ticket:`835`)
- Enabled subclassed list/tuple to be overridden by ``pyamf.add_type`` before
  defaulting to writing a sequence. (:ticket:`834`)
- Numerical keys in a ``pyamf.MixedArray`` would cause an exception. Affects
  pure python decoder only. (:ticket:`843`)
- Fixed a segfault (the first ever!) in cpyamf caused by encoding subclassed
  tuples/list/sets. Thanks to wolever for the heavy lifting (:ticket:`830`)
- Add support for weakref'd objects (:ticket:`832`)

0.6.1 (28-02-2011)
------------------
- Switched to Distribute as the future of Python packaging (:ticket:`682`)

0.6 (21-10-2010)
----------------
- Ability to exclude 'stock' attributes with AppEngine Datastore/SQLAlchemy
  (:ticket:`790`)
- Fixed issue with Django models db_column not matching the attr name
  (:ticket:`807`)
- Added generator support (:ticket:`793`, :ticket:`800`)
- Fixed issue with ``amf3.use_proxy_default=True`` and Flex messaging
  (:ticket:`794`)
- Support for AppEngine's ``BlobReferenceProperty`` (:ticket:`787`)
- Improved unit test discovery with unittest2 (:ticket:`780`)
- Ability to define attribute synonyms (:ticket:`779`)
- Provide support for AMF3 remoting packets (BlazeDS acting as a client)
  (:ticket:`737`, :ticket:`766`)
- AMF0 Remoting error tracebacks will be a list rather than a string
  (:ticket:`767`, :ticket:`663`)
- Moved documentation from the Trac wiki to a local Sphinx documentation
  build (:ticket:`752`, :ticket:`672`, :ticket:`670`, :ticket:`662`,
  :ticket:`661`, :ticket:`657`)
- Switch the PyAMF client to use :py:mod:`urllib2`. Provides support for
  proxying and gzipped responses. Thanks to @PaulWinkeler for the heavy
  lifting (:ticket:`751`, :ticket:`622`, :ticket:`590`, :ticket:`566`,
  :ticket:`778`)
- Added support for SQLAlchemy 0.6 (:ticket:`747`, :ticket:`748`)
- Added support for the lxml library (:ticket:`735`)
- Introduced a new adapter for Elixir, a thin wrapper around SQLAlchemy
  (:ticket:`724`)
- Simplified ``type_map`` in ``Encoder`` classes (:ticket:`746`)
- Fixed a small bug when handling empty M2M relationships with unpersisted
  Django objects (:ticket:`741`)
- Updates to support Plasma (:ticket:`736`)
- Fixed a small bug in ``BaseGateway.removeService``, thanks agronholm for the
  patch (:ticket:`729`)
- Pure Python AMF3 Decoding performance improvements (up to x3) (:ticket:`723`)
- Non-ascii characters in the exception message would cause a ``UnicodeError``
  (:ticket:`727`)
- All ORM adapters will no longer set properties as static attributes
  (:ticket:`677`)
- Default to using ``__new__`` for instance creation if available. (:ticket:`700`)
- Ability to ``unregister_type_alias`` (:ticket:`707`)
- ``__amf__.proxy`` actually works (:ticket:`712`)
- Django adapter now uses ``get_all_field_names`` to find model properties
  (:ticket:`625`)
- Added ``ClassAlias.bases`` and deep class tree support for typed classes
  (:ticket:`715`)
- ``use_references`` keyword arg has been removed from ``amf3.Encoder.write*``
  (:ticket:`713`)
- ``ClassAlias.getEncodableAttributes`` now will return a single dict of
  properties (:ticket:`714`)
- PyAMF Client will raise an exception if the remote gateway returns a service
  error (:ticket:`260`)
- Fixed a reference bug with unsaved Django model instances. Thanks to wolver
  for the patch and tests (:ticket:`691`).
- Fixed a small bug in decoding Django relations when declared as static.
  Thanks to wolver for the patch. (:ticket:`693`)
- Removed ``exceptions`` from all ``Context`` and ``pyamf.util.Indexed*``
  classes (:ticket:`660`)
- Empty Django relations are now encoded as ``None``, not ``pyamf.Undefined``
  (:ticket:`659`)
- ``pyamf.ClientType`` removed, as it is not spec compliant (:ticket:`651`)

0.5.1 (2009-09-19)
------------------
- ``pyamf.register_package`` can now accept a list of classes (:ticket:`650`)
- Fixed a regression in ``TwistedGateway`` where services would be called
  twice (:ticket:`648`)
- Fixed a bug with encoding anonymous trait references (:ticket:`644`)
- Moved ``IndexedCollection`` into ``cpyamf`` (:ticket:`424`)
- ``amf3.encode_int`` now encodes signed 29bit ints, not unsigned. Thanks
  to gerard for the report, investigation and patch! (:ticket:`646`)

0.5 (2009-09-07)
----------------
- Added the ability to modify the timezones of dates being de/encoded for
  legacy systems. (:ticket:`612`)
- Fixed a Django reference bug where ``parent.child.parent`` is parent
  would encode 3 objects and not 2. (:ticket:`642`)
- Setting ``None`` on a Django ``DateField`` would blow up the encoder
  (:ticket:`632`)
- ``rootCause`` in ``ErrorFault`` objects are now populated with the
  traceback object. (:ticket:`637`)
- Support for encoding/decoding BlazeDS specific messages (:ticket:`581`)
- Removed tracebacks from exception messages if ``debug=False`` (:ticket:`552`)
- Support for ``google.appengine.ext.db.polymodel.PolyModel`` (:ticket:`633`)
- Support for Django ``File``/``ImageField`` (:ticket:`631`)
- Support for Django model inheritance (:ticket:`626`)
- Rewrote attribute handling code. Added the ability to exclude, set
  read-only and static attributes. See
  http://pyamf.org/architecture/attributecontrol.html for more details
  (:ticket:`601`)
- Exposed the amf request object if ``expose_request=True``.
  Twisted/Django/Google have an ``amf_request`` property on the http request
  object.  WSGI has an entry in the environ dict now - ``pyamf.request``
  (:ticket:`234`)
- Added support for the :py:mod:`array` module (:ticket:`468`)
- Fixed an issue with Django model ``AutoFields`` being set to 0 by the Flex
  client (:ticket:`556`)
- Added support for the :py:mod:`collections` module. (:ticket:`474`)
- Added type checks for class objects. (:ticket:`473`)
- GAE ``FloatProperty`` can now accept int without issue (:ticket:`609`)
- Revamped the lazy imports module to use :py:data:`sys.meta_path` instead.
  Fixes all erroneous import errors (:ticket:`485`).
- Django models will now accept dynamic properties (:ticket:`575`)
- Django PK properties will be set first to allow related properties to apply
  correctly (:ticket:`599`)
- p.r.encode/p.r.decode both have a new ``logger`` kwarg. Supply a
  :py:class:`logging.Logger` instance if you want to see debug output
  (:ticket:`588`)
- ``pyamf.TypedObjectClassAlias`` now forces the class type (:ticket:`537`)
- If a call to ``Decoder.readElement`` results in an ``IOError`` exception,
  the original position of the stream will be restored (:ticket:`573`)
- Replaced hardcoded Python implementation title in p.r.gateway.SERVER_NAME
  (:ticket:`541`)
- Provide a user friendly way to handle :py:class:`datetime.time` objects
  (:ticket:`498`)
- Removed the useless ``pyamf.logging`` module (:ticket:`577`)
- Added a new ``register_package`` helper function to make bulk class
  registration easier. Check the docstring for more info. (:ticket:`576`)
- ``cpyamf.amf3._decode_int`` now propagates exceptions correctly (:ticket:`506`)
- Fixed an incorrect ``OverflowError`` when encoding large integers in AMF3
  (:ticket:`519`)
- Added ``append`` to ``pyamf.util.BufferedByteStream`` (:ticket:`574`)
- Added Epydoc signatures to all ``util.StringIOProxy``, ``util.DataTypeMixIn``
  and ``util.BufferedByteStream`` classes (:ticket:`440`)
- Removed dependancy on ``fpconst``. Platforms with broken platforms are
  detected and handled correctly internally (:ticket:`564`)
- ``amf0.Encoder`` now supports attribute ordering (:ticket:`558`)
- Removed duplicate method ``Context.reset``, in favour of ``Context.clear``
  (:ticket:`527`)
- Rewrote ``cpyamf.util.BufferedByteStream`` to not depend on :py:mod:`cStringIO`.
  Added a C based api for stream functions (:ticket:`513`)
- Unified exceptions for ``BufferedByteStream`` so that only ``IOError``
  is raised. (:ticket:`520`)
- Made raising ``pyamf.ReferenceError`` optional for all Indexed* and
  ``Context`` classes. Refactored AMF3 so that only one ``ClassDefinition``
  is created per class (:ticket:`524`)
- Strict type checking now on ``pyamf.util.BufferedByteStream`` (:ticket:`512`)
- Removed the default loggers from p.r.gateway.*. To re-enable supply a
  ``logger`` instance as a keyword arg to the gateway constructor (:ticket:`525`)
- Removed ``pyamf.util.make_classic_instance`` (as it is not used)
  (:ticket:`521`)
- Removed ``pyamf.util.get_mro``, in favour of :py:func:`inspect.getmro`
  (:ticket:`526`)
- Removed ``pyamf.util.Indexed[Collection|Map].remove`` (:ticket:`518`)

0.4.2 (2009-04-20)
------------------
- Support for decoding the ``source`` property on ``ArrayCollection``
  (:ticket:`488`)
- Fixed an issue in the GAE adapter where dynamic properties would be missing
  on referenced objects. (:ticket:`511`)
- Fixed a critical issue with AMF0 reference counting when encoding remoting
  responses. (:ticket:`510`)
- Strengthened HTTP header handling in the client (:ticket:`492`)
- Support for Django i18n ``ugettext_lazy`` (:ticket:`496`)
- Added support for microseconds for :py:mod:`datetime` objects. Thanks to
  Derek Payton for the patch. (:ticket:`490`)
- Added support for property types on SQLAlchemy mapped classes (:ticket:`491`)
- Added support for property types for Google AppEngine ``db.Model`` and
  ``db.Expando``. (:ticket:`487`)

0.4.1 (2009-02-23)
------------------
- ``amf0.Encoder.use_amf3`` has been extended to cover all object types
  (:ticket:`453`, :ticket:`467`)
- Property types on Django models will now encode as expected. (:ticket:`480`)
- Django ``models.ForeignKey`` properties will be followed only if previously
  accessed outside of PyAMF. ``_[attr]_cache`` is no longer encoded.
  (:ticket:`456`)
- Encoding ``{0:0, '0':1}`` will now raise an ``AttributeError``. (:ticket:`458`)
- Google AppEngine adapter improvements - see ticket for details (:ticket:`479`)
- ``amf0.Encoder`` will encode all elements as AMF3 if ``use_amf3`` option is
  set to ``True`` (:ticket:`453`)
- Unicode handling in ``__repr__`` functions has been improved (:ticket:`455`)
- object attributes and dict keys are now utf8 encoded bytestrings. Python
  \**kwargs doesn't accept unicode key objects. (:ticket:`463`)
- Django ``models.TimeField``, ``models.DateField`` will now be converted to
  the correct type (``datetime.time`` and ``datetime.date`` respectively).
  ``fields.NOT_PROVIDED`` is also checked for by converting to
  ``pyamf.Undefined`` and back again. (:ticket:`457`)

0.4 (2009-01-18)
----------------
- cpyamf now deals with exceptional floats the same way as pure Python -
  especially on Windows (:ticket:`448`)
- Support for SQLAlchemy 0.5.1 (:ticket:`449`)
- ``amf0.Encoder`` now has a ``use_amf3`` flag which determines which XML
  type to return to the client (:ticket:`435`)
- ``BufferedByteStream.truncate(length)`` now actually does something useful
  (:ticket:`444`)
- setup.py now gets the version number from ``pyamf/__init__.py`` source
  (:ticket:`429`)

0.4rc3 (2009-01-14)
-------------------
- Support for SQLAlchemy 0.5.0 (:ticket:`436`)
- pyamf.util.DataTypeMixIn/cpyamf.util.BufferedByteStream can now
  encode/decode 24bit un/signed integers. (:ticket:`422`)
- pyamf.util.StringIOProxy/cpyamf.util.BufferedByteStream both have new
  consume methods that will chop of the tail of the stream (already read
  stream). (:ticket:`423`)
- Now checking for all types of supported xml lib types for encoding, but
  will only use the first implementation for decoding (:ticket:`426`)
- fpconst dependancy is now only required if the platform requires it
  (:ticket:`356`)
- Decoding negative timestamps on certain platforms (namely Windows) are now
  supported (:ticket:`390`)

0.4rc2 (2009-01-05)
-------------------
- Support for SQLAlchemy 0.4.0 (:ticket:`410`)

0.4rc1 (2008-12-31)
-------------------
- Support for encoding/decoding SQLAlchemy ORM objects with a new adapter.
  Lots of people involved in this one, but special thanks to Dave Thompson
  and Michael Van Tellingen for making this happen. (:ticket:`277`)
- All gateways now log exceptions when exceptions are raised during
  en/decoding. (:ticket:`394`)
- Flex messaging now uses correct static attributes for encoding. Determining
  static/dynamic attributes on objects is now easier (:ticket:`357`)
- Added use_proxy option to amf3 which will automagically convert ObjectProxy
  to dict and ArrayCollection to list on decoding, and vice versa on encode.
  Thanks to dthompso for the excellent patch (:ticket:`355`)
- flex.ArrayCollection now subclasses list instead of dict as non-int keys
  are not allowed. IList interface has been implemented. (:ticket:`349`)
- Encoding registered subclass of list that define the 'externalised'
  metadata will be encoded as an object.
- Encoders how have a 'strict' mode. Not generally useful for the time being
  but will help with developments in the future. Type mapped functions now
  require a second 'encoder' attribute. (:ticket:`378`)
- Added adapter to handle the :py:mod:`decimal` module and, if strict is set
  to False, silently converts a Decimal instance to a float (:ticket:`376`)
- ClassAlias can now be subclassed and three new methods have been added:
  applyAttributes, createInstance, getAttributes all which help to provide
  fine control for object/instance manipulation (:ticket:`348`)
- Added support for __slots__ (:ticket:`347`)
- Fixed problem when decoding objects that map to GAE db.Model objects with
  required properties (:ticket:`342`)
- ByteArray now does not throw an error when used in the Remoting framework
  (:ticket:`379`)
- A new adapter that converts sets.ImmutableSet and sets.Set to tuples before
  encoding. (:ticket:`280`)
- A revamped google app engine adapter that checks for the _key attribute in
  an aliased class and first loads the object from the datastore and then
  applies that properties in the object stream. (:ticket:`307`)
- New helper function to make it easier to manually add adapters (:ticket:`350`)
- Ability to disable the c extension with passing --disable-ext to setup.py
  (:ticket:`381`, :ticket:`391`)
- Python C-extension for the pyamf.util.BufferedByteStream class. Originally
  contributed by Gerard Escalante (:ticket:`225`, :ticket:`405`)
- New API to add headers such as cookies in pyamf.remoting.client
  (:ticket:`337`)
- Now clearing the context between remoting requests (:ticket:`309`)
- Fixed issue with AMF3 class definition references (:ticket:`341`)
- More helpful description for register_class args check (:ticket:`334`)
- pyamf.register_class now checks to ensure that __init__ args do not have
  any arguments (:ticket:`322`)
- Added RemoteObject support for AsyncMessage (:ticket:`292`)
- pyamf.remoting.ErrorFault.__repr__ now displays the traceback info (if it
  exists). (:ticket:`331`)
- Both Encoders will now raise pyamf.EncodeError if a function is encoded
  (:ticket:`311`)
- Twisted Gateway would fall over when returning tuples (:ticket:`313`)
- The remoting gateways now send a customizable Server header (:ticket:`317`)
- The remoting client now sends a customizable User-Agent header (:ticket:`306`)
- Added ability to set the HTTP referer in remoting client (:ticket:`316`)
- Fixed issue where the AMF3 encoder assumed objects with a 'tag' attribute
  needed XML encoding. Reported by cy-man (:ticket:`303`)
- Solved issue with repr for AbstractMessage. Reported by datafunk
  (:ticket:`283`)
- Content-type was missing in POST requests from the AMF client. Reported by
  magog (:ticket:`304`)
- Added the disconnect Command operation (:ticket:`325`)
- Fixed issue with the unit tests for Django (:ticket:`281`)
- Removed the NetworkIOMixIn class (:ticket:`232`)

0.3.1 (2008-05-04)
------------------
- Importing module now has tests (:ticket:`266`)
- Django model adapter now imported only when django.db.models is imported
  (:ticket:`261`)
- Google Model/Expando encoding now works out of the box
- Fixed issue with Remote Object destination (:ticket:`270`)
- Added a new gateway for the Google App Engine - see
  pyamf.remoting.gateway.google.WebAppGateway (:ticket:`253`)
- amf0 Encoder now takes amf3 contexts into account (:ticket:`268`)
- amf*.encode helpers can now accept multiple arguments (:ticket:`267`)
- Removed the dependancy of fpconst for Python 2.5 or newer (:ticket:`243`)
- Solved issue with AMFPHP exceptions in AMF client (:ticket:`258`)
- Fixed issue with url parsing in AMF client (:ticket:`256`)
- Client no longer raises httplib.ResponseNotReady when making multiple
  requests using the same RemotingService (:ticket:`254`)

0.3 (2008-04-14)
----------------
- Added compatibility module for Google App Engine (:ticket:`247`)
- Fixed the signed interpretation of compressed integers in AMF3 (:ticket:`241`)
- Classic class decoding would throw an AttributeError (:ticket:`248`)
- Reloading adapter modules caused errors in Django, Pylons and Google App
  Engine. Resolved by removing dependancy on Importing module and
  incorporating into pyamf.util (:ticket:`250`)
- Adapter framework can now be fired when only loading submodules
  (:ticket:`246`)
- Made util.BufferedByteStream endian aware (:ticket:`231`)
- Fixed issue with Twisted threads (:ticket:`233`)

0.2 (2008-03-12)
----------------
- Removed amfinfo console_script (:ticket:`226`)
- Encoders/Decoders now check for __getstate__/__setstate__ respectively
  (:ticket:`209`)
- Gateway import hack has now been removed - permanently (:ticket:`224`)
- Encoding/decoding performance has been increased 2x for AMF0 and up-to
  10x(!) for AMF3 (:ticket:`198`)
- Logging is now possible in all the supported gateways (:ticket:`173`)
- A new preprocessor function that runs after authentication, but before
  invoking the service method (:ticket:`196`)
- authenticator can now be decorated with expose_request (:ticket:`195`)
- Python 2.3 support (:ticket:`33`)
- Python 2.6 support (:ticket:`222`)
- Made PyAMF distributable as zip-based Python Egg (:ticket:`193`)

0.1.1 (2008-02-18)
------------------
- AMF3 encoder reported incorrect byte length header for non-ASCII string
  data. Patch supplied by akaihola. (:ticket:`194`)
- Decoder context not cleared between reading the remoting header and body.
  Reported by gerard (:ticket:`192`)

0.1 (2008-02-11)
----------------
- New error handling api useful for registering custom exception classes
  (:ticket:`185`)
- When a client receives a remoting error, an exception is generated
  (:ticket:`167`)
- expose_request per service control vastly improved (:ticket:`169`)
- Authentication per service control vastly improved (:ticket:`166`)
- uuid is no longer installed when using Python 2.5 or newer (:ticket:`182`)
- The inheritance tree was not consulted when encoding attributes (:ticket:`172`)
- TypedObjects didn't work with old style classes (:ticket:`171`)
- ErrorFault now prints details (:ticket:`168`)
- Added expose_request to TwistedGateway (:ticket:`165`)
- TwistedGateway now expects deferred from service functions (:ticket:`164`)

0.1b (2008-01-13)
-----------------
- IExternalizable now takes its methods from the class and fine grain control
  over attr encoding (:ticket:`110`)
- Added an adapter framework that gets imported when the related module is
  imported. See http://pyamf.org/architecture/adapters.html for more info
- Added 'expose_environ' argument to WSGIGateway to expose the WSGI environ
  as the first arg in the called services.
- Implemented Local Shared Object (LSO) support (:ticket:`11`)
- ByteArray now implements IDataInput and IDataOutput instead of
  StringIOProxy (:ticket:`151`)
- dicts are now used as the default for anonymous objects (:ticket:`131`)
- remoting.client mostly fully supports the predefined headers (defined at
  http://osflash.org/documentation/amf/envelopes/remoting/headers). The only
  one missing is amf_server_debug (:ticket:`39`)
- LazyImporter objects now set the __file__ attribute to None, so that
  querying :py:data:`sys.modules` don't accidentally import the underlying
  module (:ticket:`147`)
- Fixed argument positioning for RemoteObject processing. Thanks akaihola!
  (:ticket:`145`)
- ElementTree requirement is now ignored when using Python >= 2.5
  (:ticket:`144`)
- Added tests for TwistedGateway (:ticket:`132`)
- Workaround for Python 2.4 float shortcomings (:ticket:`78`)
- Service Browser ('DescribeService' header) requests supported. (:ticket:`138`)
- Remoting client now supports authentication. (:ticket:`137`)
- Proper encoding for aliased subclassed builtin types, specifically
  flex.ArrayCollection.
- Added support for easy encoding of Django object queries
  (Foo.objects.all())
- Added 'add_type' allowing finer grain control of how a class is encoded in
  an AMF stream. (:ticket:`130`)
- 'authenticator' keyword added to all gateways (moved from ServiceRequest)
  (:ticket:`129`)
- Added ``expose_request`` argument to DjangoGateway to expose the underlying
  HTTP Request object as the first arg in the called services. (:ticket:`103`)

0.1.0a (2007-12-12)
-------------------
- AMF0 and AMF3 encoders/decoders
- Additional support for IExternalizable, ArrayCollection, ObjectProxy,
  ByteArray, RecordSet and RemoteObject
- Remoting gateways for Twisted, WSGI, and Django
- Authentication/setCredentials support
- zlib compression support for ByteArray
- Remoting client with :py:mod:`httplib`

0.0.1 (2007-10-19)
------------------
- Started project based on previous work done in the RTMPy (http://rtmpy.org)
  project.
