Esta página é uma visão geral do Starlark, anteriormente conhecido como Skylark, a linguagem usada no Bazel. Para uma lista completa de funções e tipos, consulte a referência da API Bazel.
Para mais informações sobre a linguagem, consulte o repositório do Starlark no GitHub.
Para ver a especificação oficial da sintaxe e do comportamento do Starlark, consulte a especificação de idioma do Starlark.
Sintaxe
A sintaxe de Starlark é inspirada em Python3. Esta é uma sintaxe válida no Starlark:
def fizz_buzz(n):
"""Print Fizz Buzz numbers from 1 to n."""
for i in range(1, n + 1):
s = ""
if i % 3 == 0:
s += "Fizz"
if i % 5 == 0:
s += "Buzz"
print(s if s else i)
fizz_buzz(20)
A semântica do Starlark pode ser diferente do Python, mas as diferenças comportamentais são raras, exceto nos casos em que o Starlark gera um erro. Os seguintes tipos Python são compatíveis:
Mutabilidade
Starlark favorece a imutabilidade. Duas estruturas de dados mutáveis estão disponíveis: listas e dicts. Alterações em estruturas de dados mutáveis, como anexar um valor a uma lista ou excluir uma entrada em um dicionário, são válidas apenas para objetos criados no contexto atual. Depois que um contexto termina, os valores se tornam imutáveis.
Isso ocorre porque as versões do Bazel usam a execução paralela. Durante uma criação, cada arquivo .bzl
e cada arquivo BUILD
recebem o próprio contexto de execução. Cada regra também é analisada em seu próprio contexto.
Veja um exemplo com o arquivo foo.bzl
:
# `foo.bzl`
var = [] # declare a list
def fct(): # declare a function
var.append(5) # append a value to the list
fct() # execute the fct function
O Bazel cria var
quando foo.bzl
é carregado. Portanto, var
faz parte do contexto de foo.bzl
. Quando fct()
é executado, isso é feito no contexto do foo.bzl
. Após a conclusão da avaliação de foo.bzl
, o ambiente contém uma entrada imutável, var
, com o valor [5]
.
Quando outro bar.bzl
carrega símbolos de foo.bzl
, os valores carregados permanecem imutáveis. Por esse motivo, o seguinte código em bar.bzl
é ilegal:
# `bar.bzl`
load(":foo.bzl", "var", "fct") # loads `var`, and `fct` from `./foo.bzl`
var.append(6) # runtime error, the list stored in var is frozen
fct() # runtime error, fct() attempts to modify a frozen list
As variáveis globais definidas nos arquivos bzl
não podem ser alteradas fora do arquivo bzl
que as definiu. Assim como o exemplo acima usando arquivos bzl
, os valores retornados por regras são imutáveis.
Diferenças entre arquivos BUILD e .bzl
BUILD
arquivos registram destinos fazendo chamadas para regras. Os arquivos .bzl
fornecem
definições para constantes, regras, macros e funções.
Funções nativas e regras nativas são símbolos globais em arquivos BUILD
. Os arquivos bzl
precisam ser carregados usando o módulo native
.
Há duas restrições sintáticas em arquivos BUILD
: 1) declarar funções é ilegal e 2) os argumentos *args
e **kwargs
não são permitidos.
Diferenças com o Python
As variáveis globais são imutáveis.
Instruções
for
não são permitidas no nível superior. Use-as nas funções. Em arquivosBUILD
, é possível usar abrangências de lista.Instruções
if
não são permitidas no nível superior. No entanto, as expressõesif
podem ser usadas:first = data[0] if len(data) > 0 else None
.Ordem determinística para iterar por dicionários.
Recursão não permitida.
O tipo int está limitado a números inteiros assinados de 32 bits. Os estouros geram um erro.
Modificar uma coleção durante a iteração é um erro.
Exceto para testes de igualdade, os operadores de comparação
<
,<=
,>=
,>
etc. não são definidos nos tipos de valor. Em resumo:5 < 'foo'
gerará um erro e5 == "5"
retornará falso.Nas tuplas, a vírgula à direita é válida somente quando a tupla está entre os parênteses, quando você escreve
(1,)
em vez de1,
.Os literais do dicionário não podem ter chaves duplicadas. Por exemplo, este é um erro:
{"a": 4, "b": 7, "a": 1}
.As strings são representadas por aspas duplas (como quando você chama repr).
As strings não são iteráveis.
Os seguintes recursos do Python não são compatíveis:
- concatenação de strings implícita (use um operador
+
explícito); - Comparações encadeadas (como
1 < x < 5
). class
(consulte a funçãostruct
).import
(consulte a instruçãoload
).while
,yield
.- float e set types.
- geradores e expressões do gerador.
is
(use==
).try
,raise
,except
,finally
(consultefail
para ver erros fatais).global
,nonlocal
.- funções mais integradas, a maioria dos métodos.