Skip to content

The log

Entry dataclass

Entry(
    seq: int,
    op: Op,
    type_name: str,
    identity: str,
    body: dict[str, Any],
    true_from: date | None,
    true_until: date | None,
    known: datetime,
    written: datetime,
    source: str,
)

1 entry of the log. It has 3 times.

  • When the fact is true.
  • When you got it.
  • When you wrote it.

World.history gives the entries of a fact. World.facts gives facts and not entries.

Attributes:

Name Type Description
seq int

The position of the entry in the log. The first entry is 1.

op Op

What the entry does.

type_name str

The name of the type of the fact, from Fact.type_name.

identity str

The key values of the fact, as JSON text.

body dict[str, Any]

The fields of the fact as a dictionary. It is empty for an end or a retract. It contains same_as for a same entry and old and new for a rename entry.

true_from date | None

The first day on which the fact is true, or None for all time before true_until.

true_until date | None

The day on which the fact stops being true or None if it has no end. This day is not included.

known datetime

The time at which you got the fact.

written datetime

The time at which the entry went into the log.

source str

The text that says where the entry came from.

Example
report = today.one(Task, id="t2")
entry = today.history(report)[0]
entry.op.value, entry.source  # -> ('add', 'me')

seq instance-attribute

seq: int

op instance-attribute

op: Op

type_name instance-attribute

type_name: str

identity instance-attribute

identity: str

body instance-attribute

body: dict[str, Any]

true_from instance-attribute

true_from: date | None

true_until instance-attribute

true_until: date | None

known instance-attribute

known: datetime

written instance-attribute

written: datetime

source instance-attribute

source: str

fact

fact(of: type[T]) -> T

Read the body of an add entry as a fact.

Parameters:

Name Type Description Default
of type[T]

The type of the fact.

required

Returns:

Type Description
T

The fact, checked by the type of.

Raises:

Type Description
ValidationError

The body does not fit the type. This is the case for an end entry or a retract entry or a same entry.

Example
report = today.one(Task, id="t2")
today.history(report)[0].fact(Task) == report  # -> True

__describe__

__describe__() -> Template

Give the t-string that say uses for this entry. It says what the entry did and when you got the fact and where from.

Returns:

Type Description
Template

A t-string. An example is "added on 2 Nov 2026, 09:00 from me,

Template

true from 2 Nov 2026".

Example
from scriptt.world import say

report = today.one(Task, id="t2")
say(t"{today.history(report)[0]}")
# -> 'added on 2 Nov 2026, 09:00 from me, true from 2 Nov 2026'

Origin dataclass

Origin(fact: T, field: str, value: V, entry: Entry)

The value of 1 field of 1 fact and the log entry that wrote that value. World.origin makes it.

Attributes:

Name Type Description
fact T

The fact.

field str

The name of the field.

value V

The value of the field.

entry Entry

The entry of the log that wrote this value.

Example
report = today.one(Task, id="t2")
origin = today.origin(report, lambda t: t.title)
origin.value, origin.entry.source  # -> ('Send the report', 'me')

fact instance-attribute

fact: T

field instance-attribute

field: str

value instance-attribute

value: V

entry instance-attribute

entry: Entry

__describe__

__describe__() -> Template

Give the t-string that say uses for this origin. It has the value and the field and the time you got it and the source.

Returns:

Type Description
Template

A t-string. An example is "Send the report, the title known on 2 Nov

Template

2026, 09:00 from me".

Example
from scriptt.world import say

report = today.one(Task, id="t2")
say(t"{today.origin(report, lambda t: t.title)}")
# -> 'Send the report, the title known on 2 Nov 2026, 09:00 from me'

Op

Bases: Enum

What 1 entry of the log does. Read it from Entry.op.

ADD class-attribute instance-attribute

ADD = 'add'

The fact is true from true_from, until true_until or until the next version.

END class-attribute instance-attribute

END = 'end'

The fact stops being true on a date. Views before that date still see it.

RETRACT class-attribute instance-attribute

RETRACT = 'retract'

The fact was never true. Views that you knew before the retract still see it.

SAME class-attribute instance-attribute

SAME = 'same'

Two facts are 1 thing.

RENAME class-attribute instance-attribute

RENAME = 'rename'

A field of a type has a new name.

Change dataclass

Change(before: T, after: T)

One fact that changed between 2 views. It has how it was and how it is.

Attributes:

Name Type Description
before T

The fact in the earlier view.

after T

The fact in the later view.

before instance-attribute

before: T

after instance-attribute

after: T

fields

fields() -> dict[str, tuple[Any, Any]]

Give the fields that changed.

Returns:

Type Description
dict[str, tuple[Any, Any]]

A dictionary from field name to (before, after). A field that did not

dict[str, tuple[Any, Any]]

change is not in it.

Example
note = today.one(Note, task="t2")
change = (today.suppose(add=[note.but(text="Done")]) - today).changed[0]
change.fields()  # -> {'text': ('Use the new template', 'Done')}

Changes dataclass

Changes(
    added: Facts[T],
    removed: Facts[T],
    changed: Facts[Change[T]],
    kinds: tuple[type[Fact], ...] = (),
)

The difference later - earlier between 2 views. World.__sub__ makes it.

bool(changes) is true if anything differs. Printing it shows one mark for each fact.

  • + for an added fact.
  • - for a removed fact.
  • ~ for a changed fact.

Attributes:

Name Type Description
added Facts[T]

The facts that only the later view has.

removed Facts[T]

The facts that only the earlier view has.

changed Facts[Change[T]]

The facts that are in both views with different fields, as Change objects.

added instance-attribute

added: Facts[T]

removed instance-attribute

removed: Facts[T]

changed instance-attribute

changed: Facts[Change[T]]

kinds class-attribute instance-attribute

kinds: tuple[type[Fact], ...] = ()

of

of(kind: type[U]) -> Changes[U]

Keep only the changes to facts of 1 type.

Parameters:

Name Type Description Default
kind type[U]

The type of fact.

required

Returns:

Type Description
Changes[U]

A new Changes that contains only facts of kind. They are typed as

Changes[U]

kind.

Example
later, earlier = today, todo.on("4 Nov 2026").known("2 Nov 2026 09:00")
(later - earlier).of(Task).added.count()  # -> 1

where

where(
    rule: Callable[[T], object] | None = None,
    /,
    **equal: Any,
) -> Changes[T]

Keep only the changes whose fact agrees. The fact after the change counts for a changed fact.

Parameters:

Name Type Description Default
rule Callable[[T], object] | None

A function that takes a fact and gives a true or false value. The default None means no rule.

None
**equal Any

Fields that must equal a value. An example is source=Source.OWNER. A fact without the field does not agree.

{}

Returns:

Type Description
Changes[T]

A new Changes.

Example
later, earlier = today, todo.on("4 Nov 2026").known("2 Nov 2026 09:00")
(later - earlier).of(Task).where(list="home").added.count()  # -> 1

Conflict dataclass

Conflict(
    identity: tuple, field: str, values: tuple[Any, ...]
)

A field on which the members of 1 thing disagree after World.same.

Attributes:

Name Type Description
identity tuple

The key values of the thing as a tuple.

field str

The name of the field.

values tuple[Any, ...]

The different values that the members give. It has 2 values or more.

identity instance-attribute

identity: tuple

field instance-attribute

field: str

values instance-attribute

values: tuple[Any, ...]

Match

Bases: Enum

The kind of a mapping between 2 terms after SKOS. World.map takes a Match.

Example
from scriptt.world import Match

Match.NARROWER.value  # -> 'narrower'

EXACT class-attribute instance-attribute

EXACT = 'exact'

The 2 terms mean the same.

CLOSE class-attribute instance-attribute

CLOSE = 'close'

The 2 terms mean nearly the same.

BROADER class-attribute instance-attribute

BROADER = 'broader'

The second term is wider than the first.

NARROWER class-attribute instance-attribute

NARROWER = 'narrower'

The second term is narrower than the first.

RELATED class-attribute instance-attribute

RELATED = 'related'

The 2 terms are related in some other way.

Mapping

Bases: Fact

A fact that says that a term in 1 word list maps to a term in another word list. World.map adds one.

Attributes:

Name Type Description
a Key[str]

The term in the first word list. Part of the key.

b Key[str]

The term in the other word list. Part of the key.

match Match

The kind of the mapping.

a instance-attribute

a: Key[str]

b instance-attribute

b: Key[str]

match instance-attribute

match: Match

Under

Bases: Fact

A fact that says that a thing is directly under a parent by 1 kind of link. World.place adds one.

A thing has 1 parent for each kind of link. A later place of the same child and kind replaces the parent.

Attributes:

Name Type Description
child Key[str]

The thing. Part of the key.

rel Key[Rel]

The kind of link. Part of the key.

parent str

The thing directly above it.

child instance-attribute

child: Key[str]

rel instance-attribute

rel: Key[Rel]

parent instance-attribute

parent: str

Rel

Bases: Enum

The kind of link between a thing and the thing above it. World.place takes a Rel.

Example
from scriptt.world import Rel

Rel.IS_A.value  # -> 'is a'

PART_OF class-attribute instance-attribute

PART_OF = 'part of'

The thing is a part of the parent: a task is in a list, a note is under a task.

IS_A class-attribute instance-attribute

IS_A = 'is a'

The thing is a kind of the parent: a senior software engineer is a software engineer.

Problem dataclass

Problem(
    rule: str,
    fact: Fact | None,
    field: str | None,
    value: Any,
    message: str,
)

1 problem that World.problems found. It is a fact that breaks a rule.

Attributes:

Name Type Description
rule str

The rule in words. This is the goal's name or "Task.list points to a TodoList".

fact Fact | None

The fact that breaks it. It is None when the rule is about the whole view (a count goal not met).

field str | None

The field at fault, or None.

value Any

The value at fault, or None.

message str

What is wrong in 1 sentence.

rule instance-attribute

rule: str

fact instance-attribute

fact: Fact | None

field instance-attribute

field: str | None

value instance-attribute

value: Any

message instance-attribute

message: str

__describe__

__describe__() -> Template

Log

The name of the table of every log entry in World.sql. Write {Log} in the query t-string.

The table has these columns.

  • seq
  • op
  • type_name
  • identity
  • body
  • true_from
  • true_until
  • known
  • written
  • source

The body column contains the fact. So body.amount::DOUBLE reads one field.

Example
kind = Task.type_name()
rows = today.sql(t"FROM {Log} SELECT count(*) AS n WHERE type_name = {kind}")
rows[0].n  # -> 7