# Built-in Functions

Built-in constants and functions are available in every script without an
import. Each entry lists its signature, return value, errors, and an example.

## Conventions

Signatures follow Python notation. A parameter followed by `?` is optional, `*args` collects any
number of positional arguments, and a bare `=` shows a default value.

Unless a signature shows a keyword parameter, a built-in function accepts positional arguments
only. For example, `enumerate(items, start=1)` fails with `enumerate: unexpected keyword
arguments`; write `enumerate(items, 1)` instead. The functions that take keyword arguments are
`dict`, `fail`, `int`, `max`, `min`, `print`, `round`, `sorted`, and `sum`.

Every failure stops the script and is reported with a traceback. Scripts have no `try` or
`except`; see [Execution Model](/scripting/reference/execution-model#errors-and-tracebacks). The
messages shown below are the first line of the reported error.

## Constants

- **`None`**
  `NoneType`
  . The absence of a value. It is falsy and compares equal only to itself.
- **`True`**
  `bool`
  . The true value.
- **`False`**
  `bool`
  . The false value.

```python
print(None, True, False)  # None True False
print(type(None))         # NoneType
```

## Summary

The definitions below give each function's signature, behavior, and examples.
`sum` and `round` are supplied by Atmos; the other functions come from Starlark.

## abs

- **`abs(x)`**

  Returns the absolute value of an `int` or `float`. It fails when `x` is any other type:
  `got string, want int or float`.

```python
print(abs(-3), abs(-2.5))  # 3 2.5
```

## all

- **`all(iterable)`**

  Returns `True` when every element of `iterable` is truthy, and `True` for an empty
  iterable.

```python
print(all([1, 2, 0]), all([]))  # False True
```

## any

- **`any(iterable)`**

  Returns `True` when at least one element of `iterable` is truthy, and `False` for an
  empty iterable.

```python
print(any([0, "", 3]), any([]))  # True False
```

## bool

- **`bool(x=False)`**

  Returns `True` or `False` according to the truth value of `x`. Zero, empty strings,
  empty collections, `None`, and `False` are falsy. Every other value is truthy.

```python
print(bool(""), bool([0]), bool())  # False True False
```

## bytes

- **`bytes(x)`**

  Returns a `bytes` value. The argument is a string (encoded as UTF-8), another `bytes`
  value, or an iterable of integers in the range 0 to 255. Any other argument fails with
  `bytes: got int, want string, bytes, or iterable of ints`.

```python
print(repr(bytes("hi")))         # b"hi"
print(repr(bytes([104, 105])))   # b"hi"
print(len(bytes("é")))           # 2
```

## chr

- **`chr(i)`**

  Returns the one-character string for the Unicode code point `i`. It fails when `i` is
  negative or greater than `0x10FFFF`.

```python
print(chr(65), chr(0x1F600))  # A 😀
```

## dict

- **`dict(pairs?, **kwargs)`**

  Returns a new dictionary. The optional first argument is a dictionary or an
  iterable of key-value pairs, and keyword arguments add string keys. Later entries replace earlier
  ones. It fails when an element is not a pair or a key is unhashable.

```python
print(dict([("a", 1)], b=2))  # {"a": 1, "b": 2}
print(dict())                 # {}
```

## dir

- **`dir(x)`**

  Returns a sorted list of the attribute and method names of `x`. Values without attributes
  produce an empty list.

```python
print(dir({})[:4])  # ["clear", "get", "items", "keys"]
```

## enumerate

- **`enumerate(iterable, start=0)`**

  Returns a list of `(index, element)` tuples, numbering from `start`.
  Pass `start` as a positional argument.

```python
print(enumerate(["a", "b"], 1))  # [(1, "a"), (2, "b")]
```

## fail

- **`fail(*args, sep=" ")`**

  Stops the script with an error. Atmos reports the message prefixed with
  `fail: `, followed by the traceback. Strings are used as written and other values use their
  `repr()` form, joined with `sep`.

```python
fail("replicas must be positive", 0)
# fail: replicas must be positive 0
```

Because there is no `try` statement, `fail` ends the script. Inside a function run by
[`steps.parallel`](/functions/automation/steps.parallel), the failure belongs to that task and
enters the task's retry policy, as described for [`steps.task`](/functions/automation/steps.task).

## float

- **`float(x=0.0)`**

  Converts a number, bool, or string to a floating-point number. Strings may use
  decimal or exponent notation, or the words `inf`, `infinity`, or `nan` with an optional sign. The
  string must not contain surrounding whitespace. It fails for an empty string, text that is not a
  number (`invalid float literal: x`), a result too large to represent, and other types.

```python
print(float("1.5"), float(3), float("inf"), float())  # 1.5 3.0 +inf 0.0
```

## getattr

- **`getattr(x, name, default?)`**

  Returns the attribute or method `name` of `x`. When the attribute is
  missing it returns `default` if one is given, and fails otherwise:
  `getattr: string has no .zz field or method`.

```python
print(getattr({}, "nope", "fallback"))  # fallback
print(getattr("abc", "upper")())        # ABC
```

## hasattr

- **`hasattr(x, name)`**

  Returns `True` when `x` has an attribute or method called `name`.

```python
print(hasattr([], "append"), hasattr([], "push"))  # True False
```

## hash

- **`hash(x)`**

  Returns an integer hash of a string or bytes value. The result is the same on every run
  and every machine: strings hash like Java's `String.hashCode`, and bytes use the 32-bit FNV
  algorithm. Other types fail with `hash: got int, want string or bytes`. For cryptographic
  digests such as SHA-256, use the [`digest`](/functions/automation/digest.sha256) module.

```python
print(hash("abc"))  # 96354
```

## int

- **`int(x=0, base?)`**

  Converts a value to an integer.
  - **`x`**

    A bool (becomes 0 or 1), a float (truncated toward zero), an integer, or a string. A float
    that is infinite or not a number fails.
  - **`base`**

    Only valid when `x` is a string. A value from 2 to 36, or 0 to pick the base from a `0b`, `0o`,
    or `0x` prefix. Without `base`, the string is read as decimal. Strings may start with a sign
    but must not contain whitespace.
  Unparsable text fails with `int: invalid literal with base 10: abc`. Integers have arbitrary
  precision.

```python
print(int("ff", 16), int("0x1f", 0), int(3.9), int(-3.9), int(True))  # 255 31 3 -3 1
```

## len

- **`len(x)`**

  Returns the number of elements in a string (in bytes), bytes value, list, tuple,
  dictionary, set, or range. Other types fail with `len: value of type int has no len`.

```python
print(len("héllo"), len([1, 2]), len({"a": 1}))  # 6 2 1
```

Strings are measured in UTF-8 bytes, so `len("é")` is 2. Use `len(list(s.codepoints()))` to count
characters.

## list

- **`list(iterable?)`**

  Returns a new list holding the elements of `iterable`, or an empty list without an
  argument. Iterating a dictionary yields its keys.

```python
print(list(range(3)), list({"a": 1}), list())  # [0, 1, 2] ["a"] []
```

## max

- **`max(iterable, key?) or max(a, b, *rest, key?)`**

  Returns the largest element. When `key` is given,
  elements are compared by the value of `key(element)`. The first of several equal maximums wins. An
  empty iterable fails with `max: argument is an empty sequence`; there is no `default` parameter.

```python
print(max(1, 5, 3))                   # 5
print(max(["aa", "b"], key=len))      # aa
```

## min

- **`min(iterable, key?) or min(a, b, *rest, key?)`**

  Returns the smallest element, with the same rules
  as `max`.

```python
print(min([4, 2, 8]), min(3, 1))  # 2 1
```

## ord

- **`ord(s)`**

  Returns the Unicode code point of a one-character string, or the byte value of a
  one-byte `bytes` value. Any other length fails:
  `ord: string encodes 2 Unicode code points, want 1`.

```python
print(ord("A"), ord("é"))  # 65 233
```

## print

- **`print(*args, sep=" ")`**

  Writes its arguments to standard output followed by a newline. Strings are
  printed as written, `bytes` values as raw bytes, and other values in their `repr()` form. See
  [`print`](/functions/automation/print) for where the text goes in each entry point.

```python
print("deploying", ["api", "worker"], 3)  # deploying ["api", "worker"] 3
print("a", "b", sep="-")                  # a-b
```

## range

- **`range(stop), range(start, stop, step=1)`**

  Returns an immutable sequence of integers from `start`
  up to, but not including, `stop`. The `step` may be negative but not zero (`range: step argument must
  not be zero`). A range supports `len`, indexing, slicing, `in`, and iteration, and it is not a list:
  wrap it in `list()` to see its values.

```python
print(list(range(1, 10, 3)))  # [1, 4, 7]
print(list(range(5, 0, -2)))  # [5, 3, 1]
print(len(range(10)))         # 10
```

## repr

- **`repr(x)`**

  Returns the text form of `x` that shows strings with quotes and escapes.

```python
print(repr("a\"b"), repr([1, "x"]), repr(None))  # "a\"b" [1, "x"] None
```

## reversed

- **`reversed(iterable)`**

  Returns a new list with the elements in reverse order.

```python
print(reversed([1, 2, 3]))  # [3, 2, 1]
```

## round

- **`round(number, ndigits=None)`**

  Rounds an integer or float to the
  nearest value at the requested decimal place. On an exact tie, it chooses the
  even result. Negative `ndigits` round to tens, hundreds, and so on.

```python
print(round(2.5), round(3.5))       # 2 4
print(round(3.14159, ndigits=2))    # 3.14
print(round(1250, -2))             # 1200
```

Omitting `ndigits`, or passing `None`, returns an integer. Otherwise the result
keeps the input type: `round(2.5, 0)` is `2.0`, and `round(25, -1)` is `20`.
Integers retain arbitrary precision. Floats use their stored binary value, so
`round(2.675, 2)` is `2.67`.

`number` must be an `int` or `float`; `ndigits` must be an `int` or `None`.
Booleans are not numbers in Starlark. Rounding a non-finite float to an integer
fails. With an integer `ndigits`, non-finite floats are returned unchanged;
a finite result outside the float range fails.

Atmos supplies this function in every script and loaded module.

## set

- **`set(iterable?)`**

  Returns a new set of the distinct elements of `iterable`. Elements must be
  hashable, so a list element fails with `set: unhashable type: list`. A set remembers insertion
  order.

```python
print(set([3, 1, 3, 2]))  # set([3, 1, 2])
```

## sorted

- **`sorted(iterable, key?, reverse=False)`**

  Returns a new list of the elements in ascending order. The
  sort is stable. When `key` is given, elements are ordered by `key(element)`. Elements that cannot
  be compared with each other fail with a message such as `string < int not implemented`. Sorting a
  dictionary sorts its keys.

```python
print(sorted(["bb", "a", "ccc"], key=len))  # ["a", "bb", "ccc"]
print(sorted(["b", "a"], reverse=True))     # ["b", "a"]
```

## str

- **`str(x)`**

  Returns the text form of `x`. A string is returned unchanged, and `bytes` are decoded as
  UTF-8 with invalid sequences replaced by U+FFFD. It takes exactly one argument.

```python
print(str(1), str([1, "a"]), str(None))  # 1 [1, "a"] None
```

## sum

- **`sum(iterable, start=0)`**

  Adds integers and floats in iteration order.
  An empty iterable returns `start`. Integer sums retain arbitrary precision;
  including a float produces a float with the usual floating-point precision.

```python
print(sum([1, 2, 3]))             # 6
print(sum([1, 2, 3], start=10))   # 16
print(sum(range(5)))              # 10
print(sum([]))                    # 0
```

The input can be any iterable of numbers, including a list, tuple, set, or range.
Every item and `start` must be an `int` or `float`. Strings, booleans, and nested
collections produce an error. Use `"".join(parts)` to concatenate strings.

Atmos supplies this function in every script and loaded module. Long sums
respond to script cancellation and task timeouts.

## tuple

- **`tuple(iterable?)`**

  Returns a new tuple of the elements of `iterable`, or the empty tuple without an
  argument.

```python
print(tuple([1, 2]), tuple())  # (1, 2) ()
```

## type

- **`type(x)`**

  Returns the name of the type of `x` as a string.

```python
print(type(1), type(1.5), type("s"), type(None), type([]))  # int float string NoneType list
print(type({}), type(()), type(set()), type(range(1)), type(True))  # dict tuple set range bool
print(type(bytes("a")), type(print))  # bytes builtin_function_or_method
```

## zip

- **`zip(*iterables)`**

  Returns a list of tuples, where tuple `i` holds the `i`-th element of each
  argument. The result stops at the shortest argument, and `zip()` with no arguments returns an empty
  list.

```python
print(zip([1, 2, 3], ["a", "b"]))  # [(1, "a"), (2, "b")]
```

## Names that Atmos adds

Alongside `sum` and `round`, Atmos supplies the following modules and values.
They are available without an import and are documented in the
[automation function reference](/functions/automation).

- **`cli`**
  Module. 
  [`cli.command`](/functions/automation/cli.command)
  , 
  [`cli.arg`](/functions/automation/cli.arg)
  , and 
  [`cli.flag`](/functions/automation/cli.flag)
   declare a standalone app's arguments, flags, and help.
- **`atmos`**
  Module. Run registered Atmos commands: 
  [`atmos.run`](/functions/automation/atmos.run)
  , 
  [`atmos.terraform`](/functions/automation/atmos.terraform)
  , 
  [`atmos.helm`](/functions/automation/atmos.helm)
  , 
  [`atmos.toolchain`](/functions/automation/atmos.toolchain)
  , and the other command wrappers described under 
  [command wrappers](/functions/automation#atmos-command-wrappers)
  .
- **`components`**
  Module. 
  [`components.get`](/functions/automation/components.get)
   resolves a component's configuration. The result's 
  [`exec`](/functions/automation/component.exec)
   method runs a process in the component directory.
- **`exec`**
  Module. 
  [`exec.run`](/functions/automation/exec.run)
   runs an external program from an argument list, and 
  [`exec.which`](/functions/automation/exec.which)
   reports which executable it would start.
- **`steps`**
  Module. 
  [`steps.task`](/functions/automation/steps.task)
   describes a deferred call, and 
  [`steps.parallel`](/functions/automation/steps.parallel)
   runs calls concurrently.
- **`defer`**
  Function. 
  [`defer(fn, *args, **kwargs)`](/functions/automation/defer)
   registers a call to run when the script or task finishes, last in first out, even after 
  `fail()`
   or cancellation.
- **`fs`**
  Module. 
  [`fs.read_file`](/functions/automation/fs.read_file)
   reads a local file as text, and 
  [`fs.resolve`](/functions/automation/fs.resolve)
   turns a path into an absolute one. Every 
  `fs`
   function accepts a leading 
  `~`
   for the home directory.
- **`json`**
  Module. 
  [`json.encode`](/functions/automation/json.encode)
  , 
  [`json.encode_indent`](/functions/automation/json.encode_indent)
  , 
  [`json.decode`](/functions/automation/json.decode)
  , and 
  [`json.indent`](/functions/automation/json.indent)
  .
- **`regex`**
  Module. 
  [`regex.search`](/functions/automation/regex.search)
  , 
  [`regex.findall`](/functions/automation/regex.findall)
  , and 
  [`regex.replace`](/functions/automation/regex.replace)
  .
- **`digest`**
  Module. 
  [`digest.sha256`](/functions/automation/digest.sha256)
  , 
  [`digest.sha512`](/functions/automation/digest.sha512)
  , 
  [`digest.sha1`](/functions/automation/digest.sha1)
  , and 
  [`digest.md5`](/functions/automation/digest.md5)
   return lowercase hex digests of a string or of file contents.
- **`dependencies`**
  Module. 
  [`dependencies.tools`](/functions/automation/dependencies.tools)
   installs and selects tools through the Atmos toolchain.
- **`errors`**
  Module. 
  [`errors.build`](/functions/automation/errors.build)
   creates errors with explanations, hints, examples, context, and exit codes.
- **`ui`**
  Module. 
  [`ui.info`](/functions/automation/ui.info)
  , 
  [`ui.success`](/functions/automation/ui.success)
  , and 
  [`ui.warning`](/functions/automation/ui.warning)
   write status messages to stderr.
- **`log`**
  Module. 
  [`log.trace`](/functions/automation/log.trace)
  , 
  [`log.debug`](/functions/automation/log.debug)
  , 
  [`log.info`](/functions/automation/log.info)
  , 
  [`log.warn`](/functions/automation/log.warn)
  , and 
  [`log.error`](/functions/automation/log.error)
   write to the Atmos log.
- **`ctx`**
  Value. 
  [`ctx`](/functions/automation/ctx)
   describes the invocation: 
  [`ctx.args`](/functions/automation/ctx.args)
  , 
  [`ctx.flags`](/functions/automation/ctx.flags)
  , 
  [`ctx.arguments`](/functions/automation/ctx.arguments)
  , 
  [`ctx.component`](/functions/automation/ctx.component)
  , 
  [`ctx.hook`](/functions/automation/ctx.hook)
  , 
  [`ctx.operation`](/functions/automation/ctx.operation)
  , and 
  [`ctx.script`](/functions/automation/ctx.script)
  .
- **`env`**
  Value. 
  [`env`](/functions/automation/env)
   is a read-only dictionary of the step's declared environment inputs.
- **`output`**
  Global. Assign 
  [`output`](/functions/automation/output)
   at the top level to set the script's result.
- **`load`**
  Statement. 
  [`load`](/functions/automation/load)
   imports names from another 
  `.star`
   file.

The `json` module is the standard Starlark JSON module, so it has exactly four members: `encode`,
`encode_indent`, `decode`, and `indent`. The `ui` module has the three members shown, and `log`
has the five.

The `load` keyword is a statement. It must appear at the top level of a file, outside any function, and it
cannot be passed around as a value. The variable `output` is an ordinary global that the script creates by
assigning it; it is not defined until then, so reading it before an assignment fails with
`undefined: output`.

For where each name's output goes, see
[Execution Model](/scripting/reference/execution-model#output-streams). For the methods of strings,
lists, dictionaries, sets, and bytes, see [Methods](/scripting/reference/methods).
