kraken.core
kraken.core
Address
An address is an immutable parsed representation of a task or project reference, comparable to a filesystem path.
The separator between elements in the address path is a colon (:
). Similarly, a dot (.
) refers to the current
project, and a double dot (..
) refers to the parent project.
The elements of an address can only contain characters matching the :data:Address.Element.VALIDATION_REGEX
.
Asterisks are accepted to permit glob pattern matching on the addressable space, where one asterisk (*
) is
intended to match only within the same hierarchical level (aka. wildcard), wheras a double asterisk (**
) is
used to match any number of levels (aka. recursive wildcard). A trailing question mark on each element is allowed
to permit that address resolution fails at that element.
>>> Address(":a?:b").elements
[Address.Element(value='a', fallible=True), Address.Element(value='b', fallible=False)]
>>> Address("a:..:b").normalize()
Address('b')
Source code in kraken/core/address/_address.py
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 |
|
elements
property
Returns the individual elements of the address. Note that you should also check #is_absolute() to understand whether the elements are to be interpreted relative or absolute.
>>> Address(":").elements
[]
>>> Address(":a:b").elements
[Address.Element(value='a', fallible=False), Address.Element(value='b', fallible=False)]
>>> Address(":a:b").elements == Address("a:b").elements
True
name
property
Returns the value of the last element in the Address. If the address has no elements, which is the case for the root address or an empty address, a #ValueError will be raised.
>>> Address(":a:b").name
'b'
>>> Address("a:b?").name
'b'
>>> Address(":").name
Traceback (most recent call last):
ValueError: Address(':') has no elements, and thus no name
>>> Address("").name
Traceback (most recent call last):
ValueError: Address('') has no elements, and thus no name
parent
property
parent: Address
Returns the parent address.
>>> Address(":a:b").parent
Address(':a')
>>> Address(":a").parent
Address(':')
>>> Address("a").parent
Address('.')
>>> Address(".").parent
Address('..')
>>> Address("..").parent
Address('..:..')
The container status of the address is perserved.
>>> Address(":a:b").parent
Address(':a')
>>> Address(":a:b:").parent
Address(':a:')
Use the set_container()
method to change the container status.
The root and empty address have no parent.
>>> Address(":").parent
Traceback (most recent call last):
ValueError: Root address has no parent
>>> Address("").parent
Traceback (most recent call last):
ValueError: Empty address has no parent
__bool__
Returns False if the address is empty, otherwise True.
>>> bool(Address(":a:b"))
True
>>> bool(Address(""))
False
__getitem__
Returns the nth element in the address.
>>> Address(":a:b")[1]
Address.Element(value='b', fallible=False)
__hash__
Returns a stable hash key of the address.
__init__
__init__(value: str | Sequence[str] | Address) -> None
Create a new Address from a string, sequence of strings or Address.
>>> Address(":a:b")
Address(':a:b')
>>> Address(":a:b".split(":"))
Address(':a:b')
>>> Address(["", "a", "b"])
Address(':a:b')
Address objects are immutable and are not copied by the constructor (this is implemented via the meta class).
>>> a = Address(':a')
>>> a is Address(a)
True
Use Address.create()
to construct a new address object from a list of Address.Element
.
Source code in kraken/core/address/_address.py
__len__
Returns the number of elements in the address.
len(Address(":a:b:c")) 3 len(Address("a:b:c")) 3
__repr__
__str__
Returns the string format of the address. Use the Address
constructor to parse it back into an address.
>>> str(Address(":a:b"))
':a:b'
Source code in kraken/core/address/_address.py
append
append(element: str | Element) -> Address
Return a new address with one element appended.
>>> Address(":").append("a")
Address(':a')
>>> Address(":a:.").append(".")
Address(':a:.:.')
Source code in kraken/core/address/_address.py
concat
Concatenate two addresses. If address is absolute, return address.
>>> Address(":a").concat("b:c")
Address(':a:b:c')
>>> Address(":a").concat(Address(":b"))
Address(':b')
>>> Address(":a").concat(Address("."))
Address(':a:.')
Source code in kraken/core/address/_address.py
create
classmethod
create(
is_absolute: bool,
is_container: bool,
elements: list[Element],
) -> Address
Create a new address object.
:param is_absolute: Whether the address is absolute (starts with :
)
:param elements: The address elements.
>>> Address.create(True, False, [Address.Element("a", fallible=True), Address.Element("b")])
Address(':a?:b')
Source code in kraken/core/address/_address.py
is_absolute
Returns True
if the address is absolute.
>>> Address(":a").is_absolute()
True
>>> Address("a").is_absolute()
False
>>> Address("").is_absolute()
False
Source code in kraken/core/address/_address.py
is_concrete
Returns True
if this is a concrete address. A concrete address is one that is absolute and
has no globbing elements (see #Address.Element.is_globbing()).
>>> Address(":a:b").is_concrete()
True
>>> Address("a:b").is_concrete()
False
>>> Address(":*:b").is_concrete()
False
>>> Address(":a:b?").is_concrete()
False
Source code in kraken/core/address/_address.py
is_container
Returns True
if this is a container address, that is, if it ends with a separator.
>>> Address(":a:b").is_container()
False
>>> Address(":a:b:").is_container()
True
Source code in kraken/core/address/_address.py
is_empty
Returns True
if the address is empty. The empty state is the only invalid state of an address.
>>> Address("").is_empty()
True
>>> Address("a").is_empty()
False
>>> bool(Address(""))
False
>>> bool(Address("a"))
True
>>> Address.EMPTY == Address("")
True
Source code in kraken/core/address/_address.py
is_root
Returns True
if the address is the root address (:
).
>>> Address(":").is_root()
True
>>> Address(":a").is_root()
False
>>> Address("a").is_root()
False
>>> Address("").is_root()
False
Source code in kraken/core/address/_address.py
normalize
normalize(*, keep_container: bool = False) -> Address
Normalize the address, removing any superfluous elements (.
for current, ..
for parent). A normalized
is not a container address. Use #set_container() after #normalize() to make it a container address, or pass
True
to the keep_container argument to keep the container state.
>>> Address("").normalize()
Address('.')
>>> Address("").normalize(keep_container=True)
Address('.')
>>> Address(".").normalize()
Address('.')
>>> Address(".").normalize(keep_container=True)
Address('.')
>>> Address(".:").normalize()
Address('.')
>>> Address(".:").normalize(keep_container=True)
Address('.:')
>>> Address(":a:.:b").normalize()
Address(':a:b')
>>> Address(":a:.:b").normalize(keep_container=True)
Address(':a:b')
>>> Address(":a:..:b").normalize()
Address(':b')
>>> Address("..:.:b").normalize()
Address('..:b')
>>> Address("..:.:b").normalize(keep_container=True)
Address('..:b')
>>> Address("a:b:").normalize()
Address('a:b')
>>> Address("a:b:").normalize(keep_container=True)
Address('a:b:')
>>> Address("a:b:.").normalize(keep_container=True)
Address('a:b')
Source code in kraken/core/address/_address.py
set_container
set_container(is_container: bool) -> Address
Return a copy of this address with the container flag set to the given value. The container flag indicates
whether the string representation of the address is followed by a colon (:
). This status is irrelevant
for the root address, as it is always a container.
>>> Address(":a").set_container(True)
Address(':a:')
>>> Address(":a:").set_container(False)
Address(':a')
Attempting to set the container status to False
for the root address will raise a #ValueError. Attempting
to set any container status to the empty address will also raise a #ValueError.
>>> Address(":").set_container(True)
Address(':')
>>> Address(":").set_container(False)
Traceback (most recent call last):
ValueError: Cannot set container status to False for root address
>>> Address("").set_container(True)
Traceback (most recent call last):
ValueError: Cannot set container status for empty address
Source code in kraken/core/address/_address.py
BackgroundTask
Bases: Task
This base class represents a task that starts some process in the background that keeps running which is then terminated when all direct dependant tasks are completed and no work is left. A common use case for this type of task is to spawn sidecar processes which are relied on by other tasks to be available during their execution.
Source code in kraken/core/system/task.py
start_background_task
abstractmethod
start_background_task(
exit_stack: ExitStack,
) -> TaskStatus | None
Start some task or process in the background. Use the exit_stack to ensure cleanup of your allocated
resources in case of an unexpected error or when the background task is torn down. Returning not-None and
not :attr:TaskStatusType.STARTED
, or causing an exception will immediately close the exit stack.
Source code in kraken/core/system/task.py
Context
Bases: MetadataContainer
, Currentable['Context']
This class is the single instance where all components of a build process come together.
Source code in kraken/core/system/context.py
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 |
|
__init__
__init__(
build_directory: Path,
project_finder: ProjectFinder | None = None,
executor: GraphExecutor | None = None,
observer: GraphExecutorObserver | None = None,
) -> None
:param build_directory: The directory in which all files generated durin the build should be stored.
:param project_finder: This project finder should only search within the directory it was given, not
around or in parent folders. Defaults to :class:CurrentDirectoryProjectFinder
.
:param executor: The executor to use when the graph is executed.
:param observer: The executro observer to use when the graph is executed.
Source code in kraken/core/system/context.py
execute
Execute all default tasks or the tasks specified by targets using the default executor.
If :meth:finalize
was not called already it will be called by this function before the build
graph is created, unless a build graph is passed in the first place.
:param tasks: The list of tasks to execute, or the build graph. If none specified, all default tasks will be executed. :raise BuildError: If any task fails to execute.
Source code in kraken/core/system/context.py
finalize
Call :meth:Task.finalize()
on all tasks. This should be called before a graph is created.
Source code in kraken/core/system/context.py
get_build_graph
Returns the :class:TaskGraph
that contains either all default tasks or the tasks specified with
the targets argument.
:param targets: A list of targets to resolve and to build the graph from. :raise ValueError: If not tasks were selected.
Source code in kraken/core/system/context.py
get_project
Find a project by its address. The address must be absolute.
Source code in kraken/core/system/context.py
iter_projects
Iterates over all projects in the context.
Source code in kraken/core/system/context.py
listen
Registers a listener to the context for the given event type.
Source code in kraken/core/system/context.py
load_project
load_project(
directory: Path,
parent: Project | None = None,
require_buildscript: bool = True,
runner: ScriptRunner | None = None,
script: Path | None = None,
) -> Project
Loads a project from a file or directory.
:param directory: The directory to load the project from.
:param parent: The parent project. If no parent is specified, then the :attr:root_project
must not have been initialized yet and the loaded project will be initialize it.
If the root project is initialized but no parent is specified, an error will be
raised.
:param require_buildscript: If set to True
, a build script must exist in directory.
Otherwise, it will be accepted if no build script exists in the directory.
:param runner: If the :class:ScriptRunner
for this project is already known, it can be passed here.
:param script: If the script to load for the project is already known, it can be passed here. Cannot be
specified without a runner.
Source code in kraken/core/system/context.py
resolve_tasks
resolve_tasks(
addresses: Iterable[Task | str | Address] | None,
relative_to: Project | Address | None = None,
set_selected: bool = False,
) -> list[Task]
This method finds Kraken tasks by their address, relative to a given project. If no project is specified, the address is resolved relative to the root project.
:param addresses: A list of task addresses to resolve. Task addresses may contain glob patterns
(*
and **
as well as ?
at the end of an address element, see the #Address class for
more details).
Any address that consists of only a single non-globbing path element (such as `lint` or `test`)
will be prefixed by a wildcard (such that they are semantically equivalent to `**:lint` and
`**:test`, respectively).
In case the address specifies a container (that is, if it ends with a colon), then this will
resolve the default tasks or this container.
As an example, `:` will get the default tasks of the current project, and `:**:` will get the
default tasks of all sub-projects.
Specifying `None` is a shorthand for resolving `:` and `:**:`, that is, will resolve to the
default tasks of the current project and its sub-projects.
:param relative_to: The Kraken project to resolve the task addresses relative to. If this is not specified, the #root_project is used instead.
:param set_selected: If enabled, addresses that resolve to tasks immediately will be marked as selected
before they are returned. Note that this does not mark tasks as selected when they are picked up by
via the default tasks of a project. For example, when :*
is resolved, the default tasks of all
sub-projects will be returned, but they will not be marked as selected. The tasks of the root project
however, will be marked as selected.
Source code in kraken/core/system/context.py
Graph
Bases: ABC
Interface for task graphs required for execution.
Source code in kraken/core/system/executor/__init__.py
get_successors
abstractmethod
get_task
abstractmethod
is_complete
abstractmethod
ready
abstractmethod
ready() -> list[Task]
Block until new tasks are ready to be executed. Return empty if no tasks are left. If no tasks are left
but :meth:is_complete
returns False
, the build was unsuccessful.
set_status
abstractmethod
set_status(task: Task, status: TaskStatus) -> None
Set the result of a task. Can be called twice for the same task unless the previous call was passing
a status with type :attr:TaskStatusType.STARTED
.
Source code in kraken/core/system/executor/__init__.py
tasks
abstractmethod
tasks(
goals: bool = False,
pending: bool = False,
failed: bool = False,
not_executed: bool = False,
) -> Iterator[Task]
Returns the tasks in the graph in arbitrary order.
:param goals: Return only goal tasks (i.e. leaf nodes). :param pending: Return only pending tasks. :param failed: Return only failed tasks. :param not_executed: Return only not executed tasks (i.e. downstream of failed tasks)
Source code in kraken/core/system/executor/__init__.py
GroupTask
Bases: Task
This task can be used to group tasks under a common name. Ultimately it is just another task that depends on the tasks in the group, forcing them to be executed when this task is targeted. Group tasks are not enabled by default.
Source code in kraken/core/system/task.py
add
Add one or more tasks by name or task object to this group.
This is different from adding a task via :meth:add_relationship
because the task is instead stored in the
:attr:tasks
list which can be used to access the members of the task. Relationships for a group task can
still be used to express relationships between groups or tasks and groups.
Also note that :meth:add_relationship
supports lazy evaluation of task selectors, whereas using this method
to add a task to the group by a selector string requires that the task already exists.
Source code in kraken/core/system/task.py
Project
Bases: KrakenObject
, MetadataContainer
, Currentable['Project']
A project consolidates tasks related to a directory on the filesystem.
Source code in kraken/core/system/project.py
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
|
add_child
add_child(project: Project) -> None
Adds a project as a child project.
Raises:
Type | Description |
---|---|
ValueError
|
If a member with the same name already exists or if the project's parent does not match |
Source code in kraken/core/system/project.py
add_task
add_task(task: Task) -> None
Adds a task to the project.
Raises:
Type | Description |
---|---|
ValueError
|
If a member with the same name already exists or if the task's project does not match |
Source code in kraken/core/system/project.py
build_directory
Returns the recommended build directory for the project; this is a directory inside the context build directory ammended by the project name.
Source code in kraken/core/system/project.py
group
group(
name: str,
*,
description: str | None = None,
default: bool | None = None
) -> GroupTask
Create or get a group of the given name. If a task with the given name already exists, it must refer
to a task of type :class:GroupTask
, otherwise a :class:RuntimeError
is raised.
:param name: The name of the group in the project. :param description: If specified, set the group's description. :param default: Whether the task group is run by default.
Source code in kraken/core/system/project.py
has_subproject
Returns True
if name refers to a subproject that exists in the current project.
Property
Bases: Supplier[T]
A property represents an input or output parameter of an :class:Object
.
Source code in kraken/core/system/property.py
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
|
Deferred
Bases: Exception
This exception is raised when an output property has no value set. It is distinct from the
:class:Supplier.Empty
exception in that it will propagate to the caller in any case.
Source code in kraken/core/system/property.py
__init__
__init__(
owner: PropertyContainer | type[PropertyContainer],
name: str,
item_type: TypeHint | Any,
deferred: bool = False,
help: str | None = None,
) -> None
:param owner: The object that owns the property instance.
:param name: The name of the property.
:param item_type: The original inner type hint of the property (excluding the Property type itself).
:param deferred: Whether the property should be initialized with a :class:DeferredSupplier
.
:param help: A help text for the property.
Source code in kraken/core/system/property.py
default
staticmethod
Assign the result of this function as a default value to a property to declare it's default value.
default_factory
staticmethod
Assign the result of this function as a default value to a property to declare it's default factory.
Source code in kraken/core/system/property.py
finalize
get_of_type
Return the inner value or values of the property as a flat list of t. If the property returns only a a single value of the specified type, the returned list will contain only that value. If the property instead provides a sequence that contains one or more objects of the provided type, only those objects will be returned.
Note that this does not work with generic parametrized types.
Source code in kraken/core/system/property.py
is_set
Returns #True if the property has been set to a value, #False otherwise. This is different from #is_empty(), because it does not require evaluation of the property value. This method reflects whether #set() has been called with any other value than a #VoidSupplier or a #DeferredSupplier.
Source code in kraken/core/system/property.py
output
staticmethod
Assign the result of this function as a default value to a property on the class level of an :class:Object
subclass to mark it as an output property. This is an alternative to using the :class:typing.Annotated
type
hint.
.. code:: Example
from kraken.core.system.property import Object, Property, output
class MyObj(Object):
a: Property[int] = output()
Source code in kraken/core/system/property.py
provides
Returns True
if the property may provide an instance or a sequence of the given type_.
Source code in kraken/core/system/property.py
required
staticmethod
Assign the result of this function as a default value to a property class to declare that it is required. This is the default behaviour of the a property, so this function is only useful to specify a help text or to make it more explicit in the code.
Source code in kraken/core/system/property.py
seterror
value_adapter
staticmethod
Decorator for functions that serve as a value adapter for the given type_.
Source code in kraken/core/system/property.py
Task
Bases: KrakenObject
, PropertyContainer
, ABC
A Kraken Task is a unit of work that can be executed.
Tasks goe through a number of stages during its lifetime:
- Creation and configuration
- Finalization (:meth:
finalize
) -- Mutations to properties of the task are locked after this. - Preparation (:meth:
prepare
) -- The task prepares itself for execution; it may indicate that it does not need to be executed at this state. - Execution (:meth:
execute
) -- The task executes its logic.
Tasks are uniquely identified by their name and the project they belong to, which is also represented
by the tasks's :property:address
. Relationhips to other tasks can be added via the :meth:depends_on
and required_by
methods, or by passing properties of one task into the properties of another.
Source code in kraken/core/system/task.py
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 |
|
project
property
project: Project
A convenient alias for :attr:parent
which is a lot easier to understand when reading the code.
add_tag
Add a tag to this task. The built-in tag "skip" is used to indicate that a task should not be executed.
Source code in kraken/core/system/task.py
depends_on
depends_on(
*tasks: Task | Address | str,
mode: RelationshipMode = "strict",
_inverse: bool = False
) -> None
Declare that this task depends on the specified other tasks. Relationships are lazy, meaning references
to tasks using an address will be evaluated when :meth:get_relationships
is called.
If the mode is set to strict
, the relationship is considered a strong dependency, meaning that the
dependent task must be executed after the dependency. If the mode is set to order-only
, the relationship
indicates only the order in which the tasks must be executed if both were to be executed in the same run.
Source code in kraken/core/system/task.py
execute
abstractmethod
execute() -> TaskStatus | None
Implements the behaviour of the task. The task can assume that all strict dependencies have been executed successfully. Output properties of dependency tasks that are only written by the task's execution are now accessible.
This method should not return :attr:TaskStatusType.PENDING
. If None
is returned, it is assumed that the
task is :attr:TaskStatusType.SUCCEEDED
. If the task fails, it should return :attr:TaskStatusType.FAILED
.
If an exception is raised during this method, the task status is also assumed to be
:attr:TaskStatusType.FAILED
. If the task finished successfully but with warnings, it should return
:attr:TaskStatusType.WARNING
.
Source code in kraken/core/system/task.py
finalize
This method is called by :meth:Context.finalize()
. It gives the task a chance update its
configuration before the build process is executed. The default implementation finalizes all non-output
properties, preventing them to be further mutated.
Source code in kraken/core/system/task.py
get_description
Return the task's description. The default implementation formats the :attr:description
string with the
task's properties. Any Path property will be converted to a relative string to assist the reader.
Source code in kraken/core/system/task.py
get_relationships
Return an iterable that yields all relationships that this task has to other tasks as indicated by information available in the task itself. The method will not return relationships established to this task from other tasks.
The iterable will contain every relationship that is declared via :meth:depends_on
or :meth:required_by
,
as well as relationships that are implied by the task's properties. For example, if a property of this
task is set to the value of a property of another task, a relationship is implied between the tasks.
Source code in kraken/core/system/task.py
get_tags
prepare
prepare() -> TaskStatus | None
Called before a task is executed. This is called from the main process to check for example if the task
is skippable or up to date. The implementation of this method should be quick to determine the task status,
otherwise it should be done in :meth:execute
.
This method should not return :attr:TaskStatusType.SUCCEEDED
or :attr:TaskStatusType.FAILED
. If None
is returned, it is assumed that the task is :attr:TaskStatusType.PENDING
.
Source code in kraken/core/system/task.py
remove_tag
Remove a tag from the task. If the tag does not exist, this is a no-op.
Source code in kraken/core/system/task.py
required_by
Declare that this task is required by the specified other tasks. This is the inverse of :meth:depends_on
,
effectively declaring the same relationship in the opposite direction.
Source code in kraken/core/system/task.py
teardown
teardown() -> TaskStatus | None
This method is called only if the task returns :attr:TaskStatusType.STARTED
from :meth:execute
. It is
called if all direct dependants of the task have been executed (whether successfully or not) or if no further
task execution is queued.
Source code in kraken/core/system/task.py
TaskGraph
Bases: Graph
The task graph represents a Kraken context's tasks as a directed acyclic graph data structure.
Before a task graph is passed to an executor, it is usually trimmed to contain only the tasks that are needed for the successful and complete execution of the desired set of "goal tasks".
Source code in kraken/core/system/graph.py
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 |
|
__init__
Create a new build graph from the given task list.
:param context: The context that the graph belongs to.
:param populate: If enabled, the task graph will be immediately populated with the tasks in the context.
The graph can also be later populated with the :meth:populate
method.
Source code in kraken/core/system/graph.py
execution_order
execution_order(all: bool = False) -> Iterable[Task]
Returns all tasks in the order they need to be executed.
:param all: Return the execution order of all tasks, not just from the target subgraph.
Source code in kraken/core/system/graph.py
get_predecessors
Returns the predecessors of the task in the original full build graph.
Source code in kraken/core/system/graph.py
get_status
get_status(task: Task) -> TaskStatus | None
get_successors
Returns the successors of the task in the original full build graph.
Never returns group tasks.
Source code in kraken/core/system/graph.py
is_complete
Returns True
if, an only if, all tasks in the target subgraph have a non-failure result.
mark_tasks_as_skipped
mark_tasks_as_skipped(
tasks: Sequence[Task | str | Address] = (),
recursive_tasks: Sequence[Task | str | Address] = (),
*,
set_status: bool = False,
reason: str,
origin: str,
reset: bool
) -> None
This method adds the "skip"
tag to all tasks and recursive_tasks. For the dependencies of the
recursive_tasks, the tag will only be added if the task in question is not required by another task
that is not being skipped.
:param set_status: Whether to set #TaskStatusType.SKIPPED for tasks in the graph using #set_status().
:param reason: A reason to attach to the "skip"
tag.
:param origin: An origin to attach to the "skip"
tag.
:param reset: Enable this to remove the "skip"
tags of the same origin are removed from all mentioned
tasks (including transtive dependencies for recursive_tasks) the graph first. Note that this does not
unset any pre-existing task statuses.
Source code in kraken/core/system/graph.py
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 |
|
populate
populate(goals: Iterable[Task] | None = None) -> None
Populate the graph with the tasks from the context. This need only be called if the graph was not initially populated in the constructor.
Inverse relationships
This does not recognize inverse relationships from tasks that are not part of goals or any of their relationships. It is therefore recommended to populate the graph with all tasks in the context and use #trim() to reduce the graph.
Source code in kraken/core/system/graph.py
ready
ready() -> list[Task]
Returns all tasks that are ready to be executed. This can be used to constantly query the graph for new
available tasks as the status of tasks in the graph is updated with :meth:set_status
. An empty list is
returned if no tasks are ready. At this point, if no tasks are currently running, :meth:is_complete
can be
used to check if the entire task graph was executed successfully.
Source code in kraken/core/system/graph.py
reduce
reduce(keep_explicit: bool = False) -> TaskGraph
Return a copy of the task graph that has been transitively reduced.
:param keep_explicit: Keep non-implicit edges in tact.
Source code in kraken/core/system/graph.py
restart
results_from
results_from(other: TaskGraph) -> None
Merge the results from the other graph into this graph. Only takes the results of tasks that are known to the graph. If the same task has a result in both graphs, and one task result is not successful, the not successful result is preferred.
Source code in kraken/core/system/graph.py
resume
Reset the result of all background tasks that are required by any pending tasks. This needs to be called when a build graph is resumed in a secondary execution to ensure that background tasks are active for the tasks that require them.
Source code in kraken/core/system/graph.py
set_status
set_status(
task: Task, status: TaskStatus, *, _force: bool = False
) -> None
Sets the status of a task, marking it as executed.
Source code in kraken/core/system/graph.py
tasks
tasks(
goals: bool = False,
pending: bool = False,
failed: bool = False,
not_executed: bool = False,
) -> Iterator[Task]
Returns the tasks in the graph in arbitrary order.
:param goals: Return only goal tasks (i.e. leaf nodes). :param pending: Return only pending tasks. :param failed: Return only failed tasks. :param not_executed: Return only not executed tasks (i.e. downstream of failed tasks)
Source code in kraken/core/system/graph.py
trim
Returns a copy of the graph that is trimmed to execute only goals and their strict dependencies.
Source code in kraken/core/system/graph.py
TaskSet
Bases: Collection[Task]
Represents a collection of tasks.
Source code in kraken/core/system/task.py
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 |
|
add
add(
tasks: Iterable[Task], *, partition: str | None = None
) -> None
Add the given tasks to the set.
:param tasks: The tasks to add.
:param partition: If specified, this will register the tasks under the given string as a "partition"
within the set. This is used by :meth:Project.resolve_tasks
to store which tasks were resolved
through which task selector string. Later, this can be used to map a task back to the selector it
was resolved from.
Source code in kraken/core/system/task.py
build
staticmethod
build(
context: Context | Project,
selector: (
str
| Address
| Task
| Iterable[str | Address | Task]
),
project: Project | None = None,
) -> TaskSet
For each item in selector, resolve tasks using [Context.resolve_tasks()
]. If a selector is a string,
assign the resolved tasks to a partition by that selector value.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
context |
Context | Project
|
A Kraken context or project to resolve the selector in. If it is a project, string selectors are treated relative to the project. |
required |
selector |
str | Address | Task | Iterable[str | Address | Task]
|
A single selector string or task, or a sequence thereof. Note that selectors of type [ |
required |
Source code in kraken/core/system/task.py
partitions
Return a helper class to access the partitions in the set.
select
Resolve outputs of the given tasks and return them as a dictionary mapping from task to the values. This
should only be called after the given tasks have been executed, otherwise the outputs are likely not set.
Use :meth:resolve_outputs_supplier
to create a :class:Supplier
that delegates to this method when it is
retrieved.
In addition to looking at output properties, this also includes elements contained in :attr:Task.output
.
Source code in kraken/core/system/task.py
TaskStatus
dataclass
Represents a task status with a message.
Source code in kraken/core/system/task.py
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
|
TaskStatusType
Bases: Enum
Represents the possible statuses that a task can return from its execution.
Source code in kraken/core/system/task.py
VoidTask
Bases: Task
This task does nothing and can always be skipped.