Re: Trouble writing a simple symbol transformer

Michael Haggerty <[email protected]> Sat, 15 Dec 2012 06:41:17 +0100
Newsgroups gmane.comp.version-control.subversion.cvs2svn.user
Message-ID <[email protected]>
On 12/14/2012 03:37 PM, Markus Schöpflin wrote:
> I'm trying to use a custom symbol transformation class as explained in the 
> FAQ. The class looks like this:
> 
> class MySymbolTransform:
>      def __init__(self):
>          self.mapping = {
>              "foo" : "bar" }
>      def transform(self, cvs_file, symbol_name, revision):
>          return self.mapping.get(symbol_name, "CVS_%s" % symbol_name)
> 
> This is then used like this:
> 
> run_options.set_project(
>      ...
>      symbol_transforms=[
>          MySymbolTransform(),
>          ReplaceSubstringsSymbolTransform('\\','/'),
>          NormalizePathsSymbolTransform(),
>          ],
> 
> 
> This seems to work as I'm getting the following output from pass 1:
> 
> Summary of symbol transforms:
> ...
>      "unlabeled-1.1.1.1.12" transformed to "CVS_unlabeled-1.1.1.1.12" in 17 files
>      "unlabeled-1.1.1.1.14" transformed to "CVS_unlabeled-1.1.1.1.14" in 3 files
>      "unlabeled-1.1.1.1.16" transformed to "CVS_unlabeled-1.1.1.1.16" in 17 files
>      "unlabeled-1.1.1.1.18" transformed to "CVS_unlabeled-1.1.1.1.18" in 3 files
>      "unlabeled-1.1.1.1.2" transformed to "CVS_unlabeled-1.1.1.1.2" in 34 files
> ...
> 
> The problem is that after pass 1 I get the following python exception:
> 
> Traceback (most recent call last):
>    File ".../local/git/cvs2svn-trunk/cvs2git", line 70, in <module>
>      git_main(os.path.basename(sys.argv[0]), sys.argv[1:])
>    File ".../git/cvs2svn-trunk/cvs2svn_lib/main.py", line 119, in git_main
>      main(progname, run_options, pass_manager)
>    File ".../git/cvs2svn-trunk/cvs2svn_lib/main.py", line 96, in main
>      pass_manager.run(run_options)
>    File ".../git/cvs2svn-trunk/cvs2svn_lib/pass_manager.py", line 181, in run
>      the_pass.run(run_options, stats_keeper)
>    File ".../git/cvs2svn-trunk/cvs2svn_lib/passes.py", line 123, in run
>      write_projects(artifact_manager.get_temp_file(config.PROJECTS))
>    File ".../git/cvs2svn-trunk/cvs2svn_lib/project.py", line 220, in 
> write_projects
>      cPickle.dump(Ctx()._projects.values(), open(filename, 'wb'), -1)
> cPickle.PicklingError: Can't pickle __builtin__.MySymbolTransform: attribute 
> lookup __builtin__.MySymbolTransform failed
> 
> Can anyone tell me what to do about this, as I have no idea what could be wrong.

Technical explanation: The problem is that the symbol transforms are
pickled in pass1 then unpickled in later passes.  (Pickling is a Python
mechanism for storing objects to a file.)  Class instances can only be
unpickled if the class can be imported at the time of unpickling.  Your
class is not, because it is defined in the options file, which is loaded
using execfile(), not by being imported.

Short answer: define your class in a separate file and import that file
into your options file:

mysymboltransform.py:

>     class MySymbolTransform:
>         def __init__(self):
>             self.mapping = {"foo" : "bar"}
>
>      def transform(self, cvs_file, symbol_name, revision):
>          return self.mapping.get(symbol_name, "CVS_%s" % symbol_name)

cvs2svn.options:

> from mysymboltransform import MySymbolTransform
> [...]
> run_options.set_project(
>      ...
>      symbol_transforms=[
>          MySymbolTransform(),
>          ReplaceSubstringsSymbolTransform('\\','/'),
>          NormalizePathsSymbolTransform(),
>          ],

This is pretty subtle and needs to be added to the FAQ.

Michael

-- 
Michael Haggerty
[email protected]
http://softwareswirl.blogspot.com/

------------------------------------------------------
http://cvs2svn.tigris.org/ds/viewMessage.do?dsForumId=1670&dsMessageId=3035916

To unsubscribe from this discussion, e-mail: [[email protected]].