/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/status.py

  • Committer: John Arbash Meinel
  • Date: 2011-04-20 14:27:19 UTC
  • mto: This revision was merged to the branch mainline in revision 5837.
  • Revision ID: john@arbash-meinel.com-20110420142719-advs1k5vztqzbrgv
Fix bug #767177. Be more agressive with file.close() calls.

Our test suite gets a number of thread leaks and failures because it happens to get async
SFTPFile.close() calls. (if an SFTPFile closes due to __del__ it is done as an async request,
while if you call SFTPFile.close() it is done as a synchronous request.)
We have a couple other cases, probably. Namely SFTPTransport.get() also does an async
prefetch of the content, so if you don't .read() you'll also leak threads that think they
are doing work that you want.

The biggest change here, though, is using a try/finally in a generator, which is not 
python2.4 compatible.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
from bzrlib import (
20
20
    delta as _mod_delta,
 
21
    hooks as _mod_hooks,
21
22
    log,
22
23
    osutils,
23
24
    tsort,
150
151
        old.lock_read()
151
152
        new.lock_read()
152
153
        try:
 
154
            for hook in hooks['pre_status']:
 
155
                hook(StatusHookParams(old, new, to_file, versioned,
 
156
                    show_ids, short, verbose))
 
157
 
153
158
            specific_files, nonexistents \
154
159
                = _filter_nonexistent(specific_files, old, new)
155
160
            want_unversioned = not versioned
210
215
                show_pending_merges(new, to_file, short, verbose=verbose)
211
216
            if nonexistents:
212
217
                raise errors.PathsDoNotExist(nonexistents)
 
218
            for hook in hooks['post_status']:
 
219
                hook(StatusHookParams(old, new, to_file, versioned,
 
220
                    show_ids, short, verbose))
213
221
        finally:
214
222
            old.unlock()
215
223
            new.unlock()
356
364
    # their groups individually.  But for consistency of this
357
365
    # function's API, it's better to sort both than just 'nonexistent'.
358
366
    return sorted(remaining), sorted(nonexistent)
 
367
 
 
368
 
 
369
class StatusHooks(_mod_hooks.Hooks):
 
370
    """A dictionary mapping hook name to a list of callables for status hooks.
 
371
 
 
372
    e.g. ['post_status'] Is the list of items to be called when the
 
373
    status command has finished printing the status.
 
374
    """
 
375
 
 
376
    def __init__(self):
 
377
        """Create the default hooks.
 
378
 
 
379
        These are all empty initially, because by default nothing should get
 
380
        notified.
 
381
        """
 
382
        _mod_hooks.Hooks.__init__(self, "bzrlib.status", "hooks")
 
383
        self.add_hook('post_status',
 
384
            "Called with argument StatusHookParams after Bazaar has "
 
385
            "displayed the status. StatusHookParams has the attributes "
 
386
            "(old_tree, new_tree, to_file, versioned, show_ids, short, "
 
387
            "verbose). The last four arguments correspond to the command "
 
388
            "line options specified by the user for the status command. "
 
389
            "to_file is the output stream for writing.",
 
390
            (2, 3))
 
391
        self.add_hook('pre_status',
 
392
            "Called with argument StatusHookParams before Bazaar "
 
393
            "displays the status. StatusHookParams has the attributes "
 
394
            "(old_tree, new_tree, to_file, versioned, show_ids, short, "
 
395
            "verbose). The last four arguments correspond to the command "
 
396
            "line options specified by the user for the status command. "
 
397
            "to_file is the output stream for writing.",
 
398
            (2, 3))
 
399
 
 
400
 
 
401
class StatusHookParams(object):
 
402
    """Object holding parameters passed to post_status hooks.
 
403
 
 
404
    :ivar old_tree: Start tree (basis tree) for comparison.
 
405
    :ivar new_tree: Working tree.
 
406
    :ivar to_file: If set, write to this file.
 
407
    :ivar versioned: Show only versioned files.
 
408
    :ivar show_ids: Show internal object ids.
 
409
    :ivar short: Use short status indicators.
 
410
    :ivar verbose: Verbose flag.
 
411
    """
 
412
 
 
413
    def __init__(self, old_tree, new_tree, to_file, versioned, show_ids,
 
414
            short, verbose):
 
415
        """Create a group of post_status hook parameters.
 
416
 
 
417
        :param old_tree: Start tree (basis tree) for comparison.
 
418
        :param new_tree: Working tree.
 
419
        :param to_file: If set, write to this file.
 
420
        :param versioned: Show only versioned files.
 
421
        :param show_ids: Show internal object ids.
 
422
        :param short: Use short status indicators.
 
423
        :param verbose: Verbose flag.
 
424
        """
 
425
        self.old_tree = old_tree
 
426
        self.new_tree = new_tree
 
427
        self.to_file = to_file
 
428
        self.versioned = versioned
 
429
        self.show_ids = show_ids
 
430
        self.short = short
 
431
        self.verbose = verbose
 
432
 
 
433
    def __eq__(self, other):
 
434
        return self.__dict__ == other.__dict__
 
435
 
 
436
    def __repr__(self):
 
437
        return "<%s(%s, %s, %s, %s, %s, %s, %s)>" % (self.__class__.__name__,
 
438
            self.old_tree, self.new_tree, self.to_file, self.versioned,
 
439
            self.show_ids, self.short, self.verbose)
 
440
 
 
441
 
 
442
def _show_shelve_summary(params):
 
443
    """post_status hook to display a summary of shelves.
 
444
 
 
445
    :param params: StatusHookParams.
 
446
    """
 
447
    get_shelf_manager = getattr(params.new_tree, 'get_shelf_manager', None)
 
448
    if get_shelf_manager is None:
 
449
        return
 
450
    manager = get_shelf_manager()
 
451
    shelves = manager.active_shelves()
 
452
    if shelves:
 
453
        singular = '%d shelf exists. '
 
454
        plural = '%d shelves exist. '
 
455
        if len(shelves) == 1:
 
456
            fmt = singular
 
457
        else:
 
458
            fmt = plural
 
459
        params.to_file.write(fmt % len(shelves))
 
460
        params.to_file.write('See "bzr shelve --list" for details.\n')
 
461
 
 
462
 
 
463
hooks = StatusHooks()
 
464
 
 
465
 
 
466
hooks.install_named_hook('post_status', _show_shelve_summary,
 
467
    'bzr status')
 
468