Edgewall Software

Version 23 (modified by Remy Blank, 14 years ago) ( diff )

Added a section about removal of Authorizer and co.

TracDev/ApiChanges/0.12

Summary

  1. Prerequisites
    1. Modified Dependencies
    2. New Dependencies
      1. Babel (optional)
  2. Modifications made to the 0.12 API
    1. Modified Interfaces
      1. IWikiMacroProvider (0.12)​ (0.11)​
      2. IWikiPageManipulator (0.12)​ (0.11)​
    2. Other Changes to the 0.12 API
      1. prevnext_nav support for i18n (0.12)​ (0.11)​
      2. Href with an empty base (0.12)​ (0.11)​
      3. tracd and HTTP/1.1
      4. Authz permission checking
      5. Repository constructor (0.12)​ (0.11)​
      6. Node constructor (0.12)​ (0.11)​
      7. Changeset constructor (0.12)​ (0.11)​
      8. CachedRepository constructor (0.12)​ (0.11)​
  3. New in the 0.12 API
    1. New Classes
      1. trac.cache.CacheProxy (0.12)​
      2. trac.util.text.empty (0.12)​
    2. New Interfaces
      1. trac.versioncontrol.api.IRepositoryChangeListener (0.12)​
      2. trac.versioncontrol.api.IRepositoryProvider (0.12)​
      3. trac.ticket.api.IMilestoneChangeListener (0.12)​

Prerequisites

Python 2.3 support has been dropped. Python versions 2.4, 2.5, 2.6 and 2.7 are supported.

Modified Dependencies

The bundled version of jQuery is now 1.3.2 instead of 1.2.6 in Trac 0.11. Among other things, this means that previously deprecated selector syntax is now no longer supported. See jQuery 1.3 API changes for details.

New Dependencies

Babel (optional)

The internationalization support (i18) for Trac is depending on Babel.

It's perfectly fine to go on using Trac without it, but then of course the interface will remain in English.

Modifications made to the 0.12 API

Modified Interfaces

IWikiMacroProvider (0.12) (0.11)

Added an optional argument args to IWikiMacroProvider.expand_macro() to contain the shebang-line arguments when using wiki processor syntax. For example, with the following content:

{{{
#!MyMacro test=123 other="This is a text"
This is the content.
}}}

The macro MyMacro will have its expand_macro() called with args={'test': '123', 'other': 'This is a text'}.

See also #8204.

IWikiPageManipulator (0.12) (0.11)

This interface has not actually been changed, but the implementation has been fixed so that it actually does what it promises, that is, validate a wiki page after it's been populated from user input. Previously, page.text would contain the old text, and the new text would typically be retrieved with req.args.get('text') as a workaround.

The page now has the new text in page.text, and the old text in page.old_text.

See also #7731.

Other Changes to the 0.12 API

prevnext_nav support for i18n (0.12) (0.11)

The prevnext_nav function used for adding contextual navigation links was not i18n friendly. In order to make the need for adaptation obvious, the arity of the function has changed and the label for the previous and next links have to be spelled out in full.

Href with an empty base (0.12) (0.11)

The Href class has been changed to ensure that it always generates valid URLs, even with an empty base. In 0.11, the following uses all return an empty string:

# 0.11
>>> href = Href('')             # Also applies to Href('/')
>>> href()
''
>>> href('/')
''

In 0.12, the same expressions return a valid relative URL:

# 0.12
>>> href = Href('')
>>> href()
'/'
>>> href('/')
'/'

This change will break plugins that use the following idiom to concatenate the base URL with a path starting with a slash:

# 0.12
>>> href = Href('')
>>> path = '/path/to/page'
>>> href() + path               # Broken
'//path/to/page'

For this specific use case, a new syntax has been added to avoid doubled slashes:

# 0.12 and 0.11.6
>>> href = Href('')
>>> path = '/path/to/page'
>>> href + path                 # New syntax
'/path/to/page'

The new syntax has been backported to 0.11-stable in 0.11.6 to facilitate compatibility of plugins with both 0.11.6 and 0.12. If compatibility with older releases of the 0.11.x branch is required, the following code can be used:

# 0.12 and 0.11.x
>>> href = Href('')
>>> path = '/path/to/page'
>>> href().rstrip('/') + path   # Compatibility
'/path/to/page'

See also #8159.

tracd and HTTP/1.1

Since 0.11.5, tracd could be used with the --http11 flag, which would select the use of the HTTP/1.1 protocol and most notably activate Keep-Alive connections. This is now the default behavior in 0.12.

This has some important consequences for plugins which send content directly to the client. They should take care of setting the Content-Length header properly, otherwise the browser will simply "hang".

This means that any:

    req.write(content)

must be preceded by a:

    req.send_header('Content-Length', len(content))

Don't forget to do that for any data directly sent back to the client, including responses for XHRs (e.g. r8300). This requires some discipline in the coding, but the benefit is a huge performance boost for tracd, so it's well worth the price.

In order to make errors more immediately visible, the Request.write method is more strict in 0.12: it only accepts str data parameter, and will also raise an exception if the Content-Length header was not set prior to the call.

See #8020 and #8675 for details.

Authz permission checking

Permission checking using an authz-type file has been moved from an Authorizer instance used by SubversionRepository to a fine-grained permission policy AuthzSourcePolicy defined in svn_authz.py. This allows using authz files not only for Subversion repositories, but also for other repository types.

Consequently, the Authorizer, PermissionDenied and RealSubversionAuthorizer classes as well as the SubversionAuthorizer function have been removed.

See #7116 for details.

Repository constructor (0.12) (0.11)

Due to the authz changes above, the authz argument has been removed from the Repository constructor.

Conversely, a new argument params has been added to the Repository constructor. params is a dictionary containing various parameters for the repository, and is stored as a .params attribute in Repository. The value for the key "name" is the repository name (available as .reponame) as displayed in the source browser. The value for the key "id" (available as .id) is the surrogate key identifying the repository in the database.

Both changes need to be taken into account by derived classes (typically in plugins implementing version control backends), which must propagate the arguments up to Repository.__init__()

See #7116 for details on the authz argument, and #8731 for the params argument.

Node constructor (0.12) (0.11)

The Repository instance to which a node belongs is now passed as an additional repos argument to the Node constructor, and stored in the .repos attribute. This argument must be forwarded by Node subclasses (typically in plugins implementing version control backends).

See #7116 for details.

Changeset constructor (0.12) (0.11)

The Repository instance to which a changeset belongs is now passed as an additional repos argument to the Changeset constructor, and stored in the .repos attribute. This argument must be forwarded by Changeset subclasses (typically in plugins implementing version control backends).

See #7116 for details.

CachedRepository constructor (0.12) (0.11)

In 0.11, the first argument to the CachedRepository constructor was a callable that would return a DB instance when called. In 0.12, the first argument has been changed to an Environment instance. Subclasses of CachedRepository must therefore be changed accordingly, and components implementing IRepositoryConnector and returning a CachedRepository or a subclass must pass self.env instead of a getdb callable.

Moreover, the authz argument has been removed as well, as described above.

New in the 0.12 API

New Classes

trac.cache.CacheProxy (0.12)

There's a new cache subsystem in trac.cache allowing Component instances to cache any data in a safe way. Whenever the cache entry is invalidated, the cached value will be automatically refreshed at the next retrieval, even if the invalidation occurs in a different process. This makes the config.touch() trick obsolete.

New decorators:

See TracDev/CacheManager for details.

trac.util.text.empty (0.12)

Special marker object used to represent a NULL value from the database as an empty string, yet be able to distinguish it from '' when really necessary.

New Interfaces

trac.versioncontrol.api.IRepositoryChangeListener (0.12)

Components implementing the IRepositoryChangeListener interface are notified when new changesets are added to a repository, and when metadata for changesets is modified. Both events are generated by trac-admin $ENV changeset commands, and therefore require that hooks in the repositories call these commands on commit and revision property changes, as described in TracRepositoryAdmin.

See #7723 for details.

trac.versioncontrol.api.IRepositoryProvider (0.12)

Components implementing IRepositoryProvider provide information about repositories managed by a Trac instance. There are currently two components implementing this interface: the first one extracts repository information from the [repositories] section of trac.ini, the second from the database.

Plugins can implement additional providers, for example to automatically include all repositories located below a given directory (similar to the SVNParentPath directive of mod_dav_svn).

trac.ticket.api.IMilestoneChangeListener (0.12)

Components implementing the IMilestoneChangeListener interface are notified upon creation, modification and deletion of milestones. The milestone model object is passed to each handler. Moreover, on modification an additional dictionary is passed, containing the attributes that were modified and their previous values.

See #6543 for details.

Note: See TracWiki for help on using the wiki.