libbe.comment

Define Comment for representing bug comments.

class libbe.comment.Comment(bug=None, uuid=None, from_storage=False, in_reply_to=None, body=None, content_type=None)

Comments are a notes that attach to Bugs in threaded trees. In mailing-list terms, a comment is analogous to a single part of an email.

>>> c = Comment()
>>> c.uuid != None
True
>>> c.uuid = "some-UUID"
>>> print c.content_type
text/plain

Methods

add_reply(reply[, allow_time_inversion])
append L.append(object) – append object to end
branch_len() Return the largest number of nodes from root to leaf (inclusive).
clear_cached_setting([setting]) If setting=None, clear all cached settings
comment_from_uuid(uuid[, match_alt_id]) Use a uuid to look up a comment.
count(...)
extend L.extend(iterable) – extend list by appending elements from the iterable
from_xml(xml_string[, preserve_uuids, verbose]) Note: If alt-id is not given, translates any <uuid> fields to
has_descendant(descendant[, depth_first, ...]) Check if a node is contained in a tree.
index((value, [start, ...) Raises ValueError if the value is not present.
insert L.insert(index, object) – insert object before index
load_settings([settings_mapfile])
merge(other[, accept_changes, ...]) Merge info from other into this comment.
new_reply([body, content_type])
>>> comm = Comment(bug=None, body="Some insightful remarks")
pop(...) Raises IndexError if list is empty or index is out of range.
remove()
reverse L.reverse() – reverse IN PLACE
safe_in_reply_to() Return self.in_reply_to, except...
save() Save any loaded contents to storage.
save_settings()
sibling_uuids()
sort(*args, **kwargs) Sort the tree recursively.
string([indent])
>>> comm = Comment(bug=None, body="Some\ninsightful\nremarks\n")
string_thread([string_method_name, indent, ...]) Return a string displaying a thread of comments.
thread([flatten]) Generate a (depth, node) tuple for every node in the tree.
traverse(*args, **kwargs) Avoid working with the possible dummy root comment
xml([indent])
>>> comm = Comment(bug=None, body="Some\ninsightful\nremarks\n")
xml_thread([indent])
add_reply(reply, allow_time_inversion=False)
alt_id

Alternate ID for linking imported comments. Internally comments are linked (via In-reply-to) to the parent’s UUID. However, these UUIDs are generated internally, so Alt-id is provided as a user-controlled linking target.

This property defaults to None.

author

The author of the comment

This property defaults to None.

body

The meat of the comment

comment_from_uuid(uuid, match_alt_id=True)

Use a uuid to look up a comment.

>>> a = Comment(bug=None, uuid="a")
>>> b = a.new_reply()
>>> b.uuid = "b"
>>> c = b.new_reply()
>>> c.uuid = "c"
>>> d = a.new_reply()
>>> d.uuid = "d"
>>> d.alt_id = "d-alt"
>>> comm = a.comment_from_uuid("d")
>>> id(comm) == id(d)
True
>>> comm = a.comment_from_uuid("d-alt")
>>> id(comm) == id(d)
True
>>> comm = a.comment_from_uuid(None, match_alt_id=False)
Traceback (most recent call last):
  ...
KeyError: None
content_type

Mime type for comment body

This property defaults to text/plain.

date

An RFC 2822 timestamp for comment creation

This property defaults to None.

extra_strings

Space for an array of extra strings. Useful for storing state for functionality implemented purely in becommands/<some_function>.py.

This property defaults to [].

This property is checked with <function _extra_strings_check_fn at 0x95900d4>.

from_xml(xml_string, preserve_uuids=False, verbose=True)

Note: If alt-id is not given, translates any <uuid> fields to <alt-id> fields. >>> commA = Comment(bug=None, body=”Someninsightfulnremarksn”) >>> commA.uuid = “0123” >>> commA.date = “Thu, 01 Jan 1970 00:00:00 +0000” >>> commA.author = u’François’ >>> commA.extra_strings += [‘TAG: very helpful’] >>> xml = commA.xml() >>> commB = Comment() >>> commB.from_xml(xml, verbose=True) >>> commB.explicit_attrs [‘author’, ‘date’, ‘content_type’, ‘body’, ‘alt_id’] >>> commB.xml() == xml False >>> commB.uuid = commB.alt_id >>> commB.alt_id = None >>> commB.xml() == xml True >>> commC = Comment() >>> commC.from_xml(xml, preserve_uuids=True) >>> commC.uuid == commA.uuid True

in_reply_to

UUID for parent comment or bug

This property defaults to None.

load_settings(settings_mapfile=None)
merge(other, accept_changes=True, accept_extra_strings=True, change_exception=False)

Merge info from other into this comment. Overrides any attributes in self that are listed in other.explicit_attrs.

>>> commA = Comment(bug=None, body='Some insightful remarks')
>>> commA.uuid = '0123'
>>> commA.date = 'Thu, 01 Jan 1970 00:00:00 +0000'
>>> commA.author = 'Frank'
>>> commA.extra_strings += ['TAG: very helpful']
>>> commA.extra_strings += ['TAG: favorite']
>>> commB = Comment(bug=None, body='More insightful remarks')
>>> commB.uuid = '3210'
>>> commB.date = 'Fri, 02 Jan 1970 00:00:00 +0000'
>>> commB.author = 'John'
>>> commB.explicit_attrs = ['author', 'body']
>>> commB.extra_strings += ['TAG: very helpful']
>>> commB.extra_strings += ['TAG: useful']
>>> commA.merge(commB, accept_changes=False,
...             accept_extra_strings=False, change_exception=False)
>>> commA.merge(commB, accept_changes=False,
...             accept_extra_strings=False, change_exception=True)
Traceback (most recent call last):
  ...
ValueError: Merge would change author "Frank"->"John" for comment 0123
>>> commA.merge(commB, accept_changes=True,
...             accept_extra_strings=False, change_exception=True)
Traceback (most recent call last):
  ...
ValueError: Merge would add extra string "TAG: useful" to comment 0123
>>> print commA.author
John
>>> print commA.extra_strings
['TAG: favorite', 'TAG: very helpful']
>>> commA.merge(commB, accept_changes=True,
...             accept_extra_strings=True, change_exception=True)
>>> print commA.extra_strings
['TAG: favorite', 'TAG: useful', 'TAG: very helpful']
>>> print commA.xml()
<comment>
  <uuid>0123</uuid>
  <short-name>//012</short-name>
  <author>John</author>
  <date>Thu, 01 Jan 1970 00:00:00 +0000</date>
  <content-type>text/plain</content-type>
  <body>More insightful remarks</body>
  <extra-string>TAG: favorite</extra-string>
  <extra-string>TAG: useful</extra-string>
  <extra-string>TAG: very helpful</extra-string>
</comment>
new_reply(body=None, content_type=None)
>>> comm = Comment(bug=None, body="Some insightful remarks")
>>> repA = comm.new_reply("Critique original comment")
>>> repB = repA.new_reply("Begin flamewar :p")
>>> repB.in_reply_to == repA.uuid
True
remove()
required_saved_properties = ['Content-type']
safe_in_reply_to()

Return self.in_reply_to, except...

  • if no comment matches that id, in which case return None.
  • if that id matches another comments .alt_id, in which case return the matching comments .uuid.
save()

Save any loaded contents to storage.

However, if self.storage.is_writeable() == True, then any changes are automatically written to storage as soon as they happen, so calling this method will just waste time (unless something else has been messing with your stored files).

save_settings()
settings_properties = ['Alt-id', 'Author', 'In-reply-to', 'Content-type', 'Date', 'extra_strings']
sibling_uuids()
string(indent=0)
>>> comm = Comment(bug=None, body="Some\ninsightful\nremarks\n")
>>> comm.uuid = 'abcdef'
>>> comm.date = "Thu, 01 Jan 1970 00:00:00 +0000"
>>> print comm.string(indent=2)
  --------- Comment ---------
  Name: //abc
  From: 
  Date: Thu, 01 Jan 1970 00:00:00 +0000

  Some
  insightful
  remarks
string_thread(string_method_name='string', indent=0, flatten=True)

Return a string displaying a thread of comments. bug_shortname is only used if auto_name_map == True.

string_method_name (defaults to “string”) is the name of the Comment method used to generate the output string for each Comment in the thread. The method must take the arguments indent and shortname.

>>> a = Comment(bug=None, uuid="a", body="Insightful remarks")
>>> a.time = utility.str_to_time("Thu, 20 Nov 2008 01:00:00 +0000")
>>> b = a.new_reply("Critique original comment")
>>> b.uuid = "b"
>>> b.time = utility.str_to_time("Thu, 20 Nov 2008 02:00:00 +0000")
>>> c = b.new_reply("Begin flamewar :p")
>>> c.uuid = "c"
>>> c.time = utility.str_to_time("Thu, 20 Nov 2008 03:00:00 +0000")
>>> d = a.new_reply("Useful examples")
>>> d.uuid = "d"
>>> d.time = utility.str_to_time("Thu, 20 Nov 2008 04:00:00 +0000")
>>> a.sort(key=lambda comm : comm.time)
>>> print a.string_thread(flatten=True)
--------- Comment ---------
Name: //a
From: 
Date: Thu, 20 Nov 2008 01:00:00 +0000

Insightful remarks
  --------- Comment ---------
  Name: //b
  From: 
  Date: Thu, 20 Nov 2008 02:00:00 +0000

  Critique original comment
  --------- Comment ---------
  Name: //c
  From: 
  Date: Thu, 20 Nov 2008 03:00:00 +0000

  Begin flamewar :p
--------- Comment ---------
Name: //d
From: 
Date: Thu, 20 Nov 2008 04:00:00 +0000

Useful examples
>>> print a.string_thread()
--------- Comment ---------
Name: //a
From: 
Date: Thu, 20 Nov 2008 01:00:00 +0000

Insightful remarks
  --------- Comment ---------
  Name: //b
  From: 
  Date: Thu, 20 Nov 2008 02:00:00 +0000

  Critique original comment
  --------- Comment ---------
  Name: //c
  From: 
  Date: Thu, 20 Nov 2008 03:00:00 +0000

  Begin flamewar :p
--------- Comment ---------
Name: //d
From: 
Date: Thu, 20 Nov 2008 04:00:00 +0000

Useful examples
time

An integer version of .date

traverse(*args, **kwargs)

Avoid working with the possible dummy root comment

xml(indent=0)
>>> comm = Comment(bug=None, body="Some\ninsightful\nremarks\n")
>>> comm.uuid = "0123"
>>> comm.date = "Thu, 01 Jan 1970 00:00:00 +0000"
>>> print comm.xml(indent=2)
  <comment>
    <uuid>0123</uuid>
    <short-name>//012</short-name>
    <author></author>
    <date>Thu, 01 Jan 1970 00:00:00 +0000</date>
    <content-type>text/plain</content-type>
    <body>Some
insightful
remarks</body>
  </comment>
>>> comm.content_type = 'image/png'
>>> print comm.xml()
<comment>
  <uuid>0123</uuid>
  <short-name>//012</short-name>
  <author></author>
  <date>Thu, 01 Jan 1970 00:00:00 +0000</date>
  <content-type>image/png</content-type>
  <body>U29tZQppbnNpZ2h0ZnVsCnJlbWFya3MK
</body>
</comment>
xml_thread(indent=0)
class libbe.comment.CommentCompoundComparator(cmp_list=(<function <lambda> at 0x95911ec>, <function <lambda> at 0x95910d4>, <function <lambda> at 0x9591144>, <function <lambda> at 0x959117c>, <function <lambda> at 0x959110c>, <function <lambda> at 0x959109c>, <function <lambda> at 0x95911b4>))
exception libbe.comment.MissingReference(comment)
libbe.comment.cmp_attr(comment_1, comment_2, attr, invert=False)

Compare a general attribute between two comments using the conventional comparison rule for that attribute type. If invert == True, sort against that convention.

>>> attr="author"
>>> commentA = Comment()
>>> commentB = Comment()
>>> commentA.author = "John Doe"
>>> commentB.author = "Jane Doe"
>>> cmp_attr(commentA, commentB, attr) > 0
True
>>> cmp_attr(commentA, commentB, attr, invert=True) < 0
True
>>> commentB.author = "John Doe"
>>> cmp_attr(commentA, commentB, attr) == 0
True
libbe.comment.cmp_author(comment_1, comment_2)
libbe.comment.cmp_body(comment_1, comment_2)
libbe.comment.cmp_content_type(comment_1, comment_2)
libbe.comment.cmp_extra_strings(comment_1, comment_2)
libbe.comment.cmp_in_reply_to(comment_1, comment_2)
libbe.comment.cmp_time(comment_1, comment_2)
libbe.comment.cmp_uuid(comment_1, comment_2)
libbe.comment.load_comments(bug, load_full=False)

Set load_full=True when you want to load the comment completely from disk now, rather than waiting and lazy loading as required.

libbe.comment.save_comments(bug)

Previous topic

libbe.command.util

This Page