Edgewall Software

Opened 10 years ago

Closed 10 years ago

#11505 closed defect (fixed)

Exception TypeError: "'NoneType' object is not callable" in <function <lambda> at 0xb98f9b0> ignored — at Version 6

Reported by: Ryan J Ollos Owned by: Jun Omae
Priority: normal Milestone: 1.0.2
Component: general Version:
Severity: normal Keywords:
Cc: Branch:
Release Notes:

Avoid a TypeError on Python interpreter's termination while running setup.py test -s ....

API Changes:
Internal Changes:

Description

This issue was first mentioned in comment:1:ticket:11249, with a good hint about the problem in comment:2:ticket:11249. Running the tests with python setup.py test yields more info about the exception (as opposed to running python -m trac.test, which yields on the output in comment:1:ticket:11249):

$ python setup.py test -m tracopt.versioncontrol.git.tests
running test
running egg_info
unrecognized .svn/entries format; skipping .
writing requirements to Trac.egg-info/requires.txt
writing Trac.egg-info/PKG-INFO
writing top-level names to Trac.egg-info/top_level.txt
writing dependency_links to Trac.egg-info/dependency_links.txt
writing entry points to Trac.egg-info/entry_points.txt
unrecognized .svn/entries format in /home/user/Workspace/t11500/teo-rjollos.git
reading manifest file 'Trac.egg-info/SOURCES.txt'
writing manifest file 'Trac.egg-info/SOURCES.txt'
running build_ext
test_git_version (tracopt.versioncontrol.git.tests.PyGIT.GitTestCase) ... ok
test_is_sha (tracopt.versioncontrol.git.tests.PyGIT.GitTestCase) ... ok
test_parse (tracopt.versioncontrol.git.tests.PyGIT.TestParseCommit) ... ok
test_control_files_detection (tracopt.versioncontrol.git.tests.PyGIT.NormalTestCase) ... ok
test_get_branches_with_cr_in_commitlog (tracopt.versioncontrol.git.tests.PyGIT.NormalTestCase) ... ok
test_node_get_history_with_empty_commit (tracopt.versioncontrol.git.tests.PyGIT.NormalTestCase) ... ok
test_rev_is_anchestor_of (tracopt.versioncontrol.git.tests.PyGIT.NormalTestCase) ... ok
test_sync_after_removing_branch (tracopt.versioncontrol.git.tests.PyGIT.NormalTestCase) ... ok
test_turn_off_persistent_cache (tracopt.versioncontrol.git.tests.PyGIT.NormalTestCase) ... ok
test_get_historian (tracopt.versioncontrol.git.tests.PyGIT.UnicodeNameTestCase) ... ok
test_ls_tree (tracopt.versioncontrol.git.tests.PyGIT.UnicodeNameTestCase) ... ok
test_unicode_branches (tracopt.versioncontrol.git.tests.PyGIT.UnicodeNameTestCase) ... ok
test_unicode_filename (tracopt.versioncontrol.git.tests.PyGIT.UnicodeNameTestCase) ... ok
test_unicode_tags (tracopt.versioncontrol.git.tests.PyGIT.UnicodeNameTestCase) ... ok
test_unicode_verifyrev (tracopt.versioncontrol.git.tests.PyGIT.UnicodeNameTestCase) ... ok
test_bare (tracopt.versioncontrol.git.tests.git_fs.SanityCheckingTestCase) ... ok
test_no_head_file (tracopt.versioncontrol.git.tests.git_fs.SanityCheckingTestCase) ... ok
test_no_objects_dir (tracopt.versioncontrol.git.tests.git_fs.SanityCheckingTestCase) ... ok
test_no_refs_dir (tracopt.versioncontrol.git.tests.git_fs.SanityCheckingTestCase) ... ok
test_non_bare (tracopt.versioncontrol.git.tests.git_fs.SanityCheckingTestCase) ... ok
test_non_persistent (tracopt.versioncontrol.git.tests.git_fs.PersistentCacheTestCase) ... ok
test_persistent (tracopt.versioncontrol.git.tests.git_fs.PersistentCacheTestCase) ... ok
test_with_cache (tracopt.versioncontrol.git.tests.git_fs.HistoryTimeRangeTestCase) ... ok
test_without_cache (tracopt.versioncontrol.git.tests.git_fs.HistoryTimeRangeTestCase) ... ok

----------------------------------------------------------------------
Ran 24 tests in 1.566s

OK
Exception TypeError: TypeError("'NoneType' object is not callable",) in <bound method Storage.__del__ of <tracopt.versioncontrol.git.PyGIT.Storage object at 0x4474b50>> ignored
Exception TypeError: TypeError("'NoneType' object is not callable",) in <bound method Storage.__del__ of <tracopt.versioncontrol.git.PyGIT.Storage object at 0x4471f90>> ignored

The exception is avoided with the following change:

  • tracopt/versioncontrol/git/PyGIT.py

    diff --git a/tracopt/versioncontrol/git/PyGIT.py b/tracopt/versioncontrol/git/Py
    index 14e2886..c8285a6 100644
    a b class Storage(object):  
    411411        with self.__cat_file_pipe_lock:
    412412            if self.__cat_file_pipe is not None:
    413413                self.__cat_file_pipe.stdin.close()
    414                 terminate(self.__cat_file_pipe)
     414                # terminate(self.__cat_file_pipe)
    415415                self.__cat_file_pipe.wait()
    416416
    417417    #

Side note: the tests can't actually be run using python setup.py test -m tracopt.versioncontrol.git.tests without other changes, but this will be addressed in the next ticket.

However, this change does not fix the issue as I would have expected:

  • tracopt/versioncontrol/git/PyGIT.py

    diff --git a/tracopt/versioncontrol/git/PyGIT.py b/tracopt/versioncontrol/git/Py
    index 14e2886..ad03f5d 100644
    a b class Storage(object):  
    411411        with self.__cat_file_pipe_lock:
    412412            if self.__cat_file_pipe is not None:
    413413                self.__cat_file_pipe.stdin.close()
    414                 terminate(self.__cat_file_pipe)
    415                 self.__cat_file_pipe.wait()
     414                if self.__cat_file_pipe is not None:
     415                    terminate(self.__cat_file_pipe)
     416                    self.__cat_file_pipe.wait()
    416417
    417418    #
    418419    # cache handling

Change History (6)

comment:1 by Jun Omae, 10 years ago

That issue occurs under the following conditions.

  1. PyGIT.Storage instance is cached in;
    • RepositoryManager._cache: GitRepository instance is contained and GitRepository.git instance variable is a Storage instance.
    • PyGIT.StorageFactory.__dict_nonweak or __dict: [git] persistent_cache = enabled
  2. Storage.__del__ is called on Python interpreter's termination. The terminate function in global scope of tracopt.versioncontrol.git.PyGIT is set to None.

Proposed changes can be found in jomae.git@t11505.

  • Add StorageFactory._clean() which clears __dict_nonweak and __dict variables.
  • Call RepositoryManager.reload_repositories() and StorageFactory._clean() in tearDown() of tracopt.versioncontrol.git.tests test cases to clear the cached Storage instances.

Also, the issue isn't reproduced with tracd server. When tracd is terminated by CTRL-C and SIGTERM, the Storage.__del__ is not called. I have not yet confirmed it with mod_wsgi, fcgid, etc.

comment:2 by Jun Omae, 10 years ago

tracopt.versioncontrol.svn.tests has the same issue.

$ ~/venv/py25/bin/python setup.py test -s tracopt.versioncontrol.svn.tests.suite
...
OK
Exception exceptions.TypeError: "'NoneType' object is not callable" in <function <lambda> at 0xa708d14> ignored

in reply to:  2 comment:3 by Ryan J Ollos, 10 years ago

Replying to jomae:

tracopt.versioncontrol.svn.tests has the same issue.

Good catch, thanks. I see that issue as well when running the svn tests.

in reply to:  2 ; comment:4 by Jun Omae, 10 years ago

tracopt.versioncontrol.svn.tests has the same issue.

$ ~/venv/py25/bin/python setup.py test -s tracopt.versioncontrol.svn.tests.suite
...
OK
Exception exceptions.TypeError: "'NoneType' object is not callable" in <function <lambda> at 0xa708d14> ignored

I suppose that svn.core.Pool's __del__ method probably leads the same issue, see http://svn.apache.org/viewvc/subversion/tags/1.6.23/subversion/bindings/swig/core.i?view=markup#l844.

In [863fe327/jomae.git], call RepositoryManager.reload_repositories() to avoid it.

in reply to:  4 comment:5 by Jun Omae, 10 years ago

Owner: set to Jun Omae
Status: newassigned

In [863fe327/jomae.git], call RepositoryManager.reload_repositories() to avoid it.

I've committed the above patch in [12715] and merged to trunk in [12716].

I'll revise and commit the patch for tracopt.versioncontrol.git.tests later.

comment:6 by Jun Omae, 10 years ago

Release Notes: modified (diff)
Resolution: fixed
Status: assignedclosed

Committed in [12774] and merged to trunk in [12775].

Note: See TracTickets for help on using tickets.