pkgcore.bugzilla.client module

The bugs.gentoo.org client.

class pkgcore.bugzilla.client.Bugzilla(api_key: str | None = None, *, base_url: str = 'https://bugs.gentoo.org', timeout: float = 30.0, retries: int = 3, auth_mode: AuthMode = AuthMode.QUERY, retry_writes: bool = False, user_agent: str | None = None, opener: OpenerDirector | None = None, transport: Transport | None = None)[source]

Bases: object

A Bugzilla instance, defaulting to bugs.gentoo.org.

Without an api key the client is read only, and Bugzilla truncates every email address it returns at the @, so anything matching on addresses needs one.

user_agent names the calling tool; it is prepended to pkgcore’s own token rather than replacing it.

base_url
comments(bug: BugId | int, /) tuple[Comment, ...][source]

Every comment on a bug, oldest first

create(bug: NewBug, /) BugId[source]

File a bug and return its id.

Never retried, since a retry after a timeout files a duplicate.

get(bugs: BugId | int, /) Bug[source]
get(bugs: Iterable[BugId | int], /) dict[BugId, Bug]

Fetch one bug, or a mapping for several.

Raises:

BugzillaNotFound – when a single requested bug doesn’t exist

latest_comment(bug: BugId | int, /, *, creator: str | None = None) Comment | None[source]

The newest comment, optionally restricted to one author.

creator defaults to the authenticated account.

mark_own_comments_obsolete(bug: BugId | int, /) int[source]

Tag the authenticated user’s comments obsolete, returning the count.

Deliberately separate from update(), so a failed update doesn’t leave a bug with every comment obsoleted and no replacement.

Run a search, returning the wire dicts rather than Bug.

Use this for the narrow projections a full Bug doesn’t need; anything left out of fields is simply absent from the results.

resolve_dependencies(bugs: dict[BugId, Bug]) dict[BugId, Bug][source]

Fetch the transitive closure of everything bugs depends on.

Dependencies that can’t be fetched, because they were deleted or are behind a security group, are logged and dropped rather than looping.

search(query: BugQuery = BugQuery(simple=(), charts=(), limit=None, offset=None, order=None), /) dict[BugId, Bug][source]

Run a search, batching and paging as needed

tag_comments(comments: Iterable[CommentId | int], /, tags: ListChange[str]) None[source]

Add or remove tags on comments, one request per comment

update(bugs: BugId | int, /, update: BugUpdate) BugChanges[source]
update(bugs: Iterable[BugId | int], /, update: BugUpdate) tuple[BugChanges, ...]

Apply an update to one or more bugs.

The full id list always goes in the body, because Bugzilla lets the body override the id in the request path rather than the other way around.

whoami() User[source]

The account the api key belongs to, cached for the session