feat: add `@config.default`
I maintainer di solito rispondono entro 2 giorni
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 35/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Ferma
- Stack tecnologico
- python
- Ambito
- developer-experience
Direzione di ricerca
Inizia tracciando gli entry point esistenti @config.when, @config.when_not e @config.when_not_in usati da dataflow.py, con run.py che mostra il comportamento del driver. Definisci come @config.default interagisce con le configurazioni corrispondenti, la configurazione mancante e i valori predefiniti duplicati, quindi aggiungi test che coprano questi casi e conferma che l'esempio mantenga foo disponibile senza .with_config().
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
This is the result of discussing with a user on backwards compatibility of a dataflow.
Currently, @config offers 4 options:
@config.when(key="foo"): select this implementation when equality isTrue@config.when_not(key="foo"): select this impl. when equality isFalse@config.when_in(key=["foo", "bar"]): selects this impl. whenkey in list[]is True@config.when_not_in(key=["foo", "bar"]): selects this impl. whenkey in list[]is False
This covers a lot of cases, but there's no way to specify a default.
Example 1
Here's a simple illustration of limitations for backwards compatibility.
This is version1
# dataflow.py
def foo() -> int:
return 1
# run.py
import dataflow
from hamilton import driver
dr = driver.Builder().with_modules(dataflow).build()
dr.execute(["foo"])
Example 2
Now I'm adding a version2 and I want to have version1 as my default.
problem
If you use @config.when(version="1") and @config.when(version="2"), this can break downstream drivers because there will be no node foo if .with_config() is not set.
# dataflow.py
from hamilton.function_modifiers import config
@config.when(version="1")
def foo__v1() -> int:
return 1
@config.when(version="2")
def foo__v2() -> int:
return 2
# run.py
import dataflow
from hamilton import driver
# breaks because `.with_config()` didn't set `version="1"` or `version="2"`
dr = driver.Builder().with_modules(dataflow).build()
dr.execute(["foo"])
solution
Best solution is to annotate when_not(version="2") to catch all configurations (including empty ones, i.e., when .with_config() is not present).
# dataflow.py
from hamilton.function_modifiers import config
@config.when_not(version="2")
def foo__v1() -> int:
return 1
@config.when(version="2")
def foo__v2() -> int:
return 2
# run.py
import dataflow
from hamilton import driver
dr = driver.Builder().with_modules(dataflow).build()
dr.execute(["foo"])
Example 3
Now, I'm adding an implementation version3
Problem
If I'm conserving my previous code and adding @config.when(version="3"), it will never be hit. This is because the already existing when_not(version="2") will catch this configuration.
# dataflow.py
from hamilton.function_modifiers import config
@config.when_not(version="2")
def foo__v1() -> int:
return 1
@config.when(version="2")
def foo__v2() -> int:
return 2
@config.when(version="3")
def foo__v3() -> int:
return 3
# run.py
import dataflow
from hamilton import driver
# there will be no errors, but `v1` will be used actually
dr = driver.Builder().with_config({"version": "3"}).with_modules(dataflow).build()
dr.execute(["foo"])
Solution
The user has to modify the decorator for foo__v1() and set it to when_not_in(version=["2", "3"]) to catch all configurations.
The next problem is that whenever an implementation is added, you need to remember to add it to this list otherwise you will silently catch the new version="4".
# dataflow.py
from hamilton.function_modifiers import config
@config.when_not_in(version=["2", "3"])
def foo__v1() -> int:
return 1
@config.when(version="2")
def foo__v2() -> int:
return 2
@config.when(version="3")
def foo__v3() -> int:
return 3
# run.py
import dataflow
from hamilton import driver
dr = driver.Builder().with_modules(dataflow).build()
dr.execute(["foo"])
Consequences
The main issue is backwards compatibility. When refactoring from a single implementation to two implementations, users have to carefully use .when() and .when_not() in conjunction otherwise, they will break Driver that don't have a config. Then, when moving from 2 to 3+, they have to use when_not_in() and manually manage a list. It is also not obvious from the code that the when_not_in() means "default implementation".
Currently, using .when(version="1") and .when(version="2") implicitly creates a pattern of raising an error on invalid configurations (e.g., version=-1) because there would be a missing node foo, which will likely break a key path. If breaking the path didn't raise an error then a correct or incorrect config didn't matter.
This relates to a broader task of defining the space of valid configurations.
Solution
We should have a @config.default to ensure a node foo is always present in the DAG. Its name is also easy to understand. When you're moving from 1 implementation to 2+, you get a clear design decision: do I want a config.when with v1 and v2 or a default and v2?
Using @config.default would mean "select this implementation if no other config is resolved". This condition needs to be the last resolved and you can't have two nodes of the same name with @config.default.
# dataflow.py
from hamilton.function_modifiers import config
@config.default
def foo__v1() -> int:
return 1
@config.when(version="2")
def foo__v2() -> int:
return 2
@config.when(version="3")
def foo__v3() -> int:
return 3
# run.py
import dataflow
from hamilton import driver
# passing no config means `default` was used
dr = driver.Builder().with_modules(dataflow).build()
dr.execute(["foo"])
- Lingua principale
- Jupyter Notebook
- Stelle
- 2.6k
- Fork
- 218
- Merge medio
- 2g 13h
- PR unite (30g)
- 18
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di apache/hamilton
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 2 giorni
-
Engine crashes when client sends nan or inf float to UIForse di nuovo libera @Exudev l’ha presa 231 giorni fa e non c’è nessuna pull request aperta. Apertabug SDK
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
apache/hamilton#1458 · 5 commenti ·
I maintainer di solito rispondono entro 2 giorni
-
More detailed type annotations in graph visualizationsForse di nuovo libera @Nishant-Manocha l’ha presa 366 giorni fa e non c’è nessuna pull request aperta. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
apache/hamilton#1383 · 4 commenti ·
I maintainer di solito rispondono entro 2 giorni
-
Documentation: add explainer for FastAPIForse di nuovo libera @Aditya-Deshwal23 l’ha presa 185 giorni fa e non c’è nessuna pull request aperta. Apertadocumentation
Difficoltà 2/5 1-2 giorni Idoneità per principianti 65/100
apache/hamilton#1304 · 5 commenti ·
I maintainer di solito rispondono entro 2 giorni
-
Link back to github from reference API docsForse già presa @naikvaib l’ha presa 23 giorni fa. Apertadocumentation good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
apache/hamilton#572 · 3 commenti ·
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di apache/hamilton
Issue simili
-
Action Required: Fix Renovate ConfigurationForse già presa @thompson-tomo l’ha presa oggi. Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 78/100
open-telemetry/opentelemetry-collector#16170 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
jbacalso24/mimry#191 ·
I maintainer di solito rispondono entro 1 giorno
-
Installer computes steamid3 as -76561197960265728 when loginusers.vdf uses lowercase "timestamp"Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
scanaislop/aislop#482 ·
I maintainer di solito rispondono entro 1 giorno
-
docs(skills): issue-first should reference an existing Linear ticket instead of filing a duplicateApertadocumentation
Difficoltà 1/5 1-3 ore Idoneità per principianti 74/100
I maintainer di solito rispondono entro 1 giorno