build(deps): bump uv from 0.10.9 to 0.11.6 (#256)
Bumps uv from 0.10.9 to 0.11.6.
Release notes
Sourced from uv's releases.
0.11.6
Release Notes
Released on 2026-04-09.
This release resolves a low severity security advisory in which wheels with malformed RECORD entries could delete arbitrary files on uninstall. See GHSA-pjjw-68hj-v9mw for details.
Bug fixes
- Do not remove files outside the venv on uninstall (#18942)
- Validate and heal wheel
RECORDduring installation (#18943)- Avoid
uv cache cleanerrors due to Win32 path normalization (#18856)Install uv 0.11.6
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/uv/releases/download/0.11.6/uv-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/uv/releases/download/0.11.6/uv-installer.ps1 | iex"Download uv 0.11.6
... (truncated)
Changelog
Sourced from uv's changelog.
0.11.6
Released on 2026-04-09.
This release resolves a low severity security advisory in which wheels with malformed RECORD entries could delete arbitrary files on uninstall. See GHSA-pjjw-68hj-v9mw for details.
Bug fixes
- Do not remove files outside the venv on uninstall (#18942)
- Validate and heal wheel
RECORDduring installation (#18943)- Avoid
uv cache cleanerrors due to Win32 path normalization (#18856)0.11.5
Released on 2026-04-08.
Python
- Add CPython 3.13.13, 3.14.4, and 3.15.0a8 (#18908)
Enhancements
- Fix
build_system.requireserror message (#18911)- Remove trailing path separators in path normalization (#18915)
- Improve error messages for unsupported or invalid TLS certificates (#18924)
Preview features
- Add
exclude-newerto[[tool.uv.index]](#18839)uv audit: add context/warnings for ignored vulnerabilities (#18905)Bug fixes
- Normalize persisted fork markers before lock equality checks (#18612)
- Clear junction properly when uninstalling Python versions on Windows (#18815)
- Report error cleanly instead of panicking on TLS certificate error (#18904)
Documentation
- Remove the legacy
PIP_COMPATIBILITY.mdredirect file (#18928)- Fix
uv init example-bare --bareexamples (#18822, #18925)0.11.4
Released on 2026-04-07.
Enhancements
... (truncated)
Commits
6595080Bump version to 0.11.6 (#18948)7983c7aValidate and heal RECORD during installation (#18943)b38439bAvoiduv cache cleanerrors due to Win32 path normalization (#18856)a0e461aDo not remove files outside the venv on uninstall (#18942)95eaa68Bump version to 0.11.5 (#18930)f6d67d5Improve certificate loading error messages (#18924)39b83c3Addexclude-newerto[[tool.uv.index]](#18839)7924ba5uv audit: add context/warnings for ignored vulnerabilities (#18905)a352ce0Remove the legacy PIP_COMPATIBILITY.md redirect file (#18928)33b6338Normalize persisted fork markers before lock equality checks (#18612)- Additional commits viewable in compare view
Dependabot will resolve any conflicts with this PR as long as you don’t alter it yourself. You can also trigger a rebase manually by commenting
@dependabot rebase.
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
@dependabot rebasewill rebase this PR@dependabot recreatewill recreate this PR, overwriting any edits that have been made to it@dependabot show <dependency name> ignore conditionswill show all of the ignore conditions of the specified dependency@dependabot ignore this major versionwill close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this minor versionwill close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)@dependabot ignore this dependencywill close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the Security Alerts page.Signed-off-by: dependabot[bot] support@github.com Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9
京公网安备 11010802032778号
VCF/BCF transformation using python expressions
vembrane allows to transform VCF/BCF files by specifying flexible Python expressions over
INFOorFORMATfield,CHROM,POS,ID,REF,ALT,QUAL,FILTER, and the annotation fieldANN/CSQ. Supported transformations include filtering, tagging, annotation, sorting, and conversion to tabular (CSV/TSV), structured formats (JSON/JSONL/YAML), and FHIR. vembrane relies on pysam or cyvcf2 for reading/writing VCF/BCF files.See https://vembrane.github.io for a high-level overview. For a comparison with similar tools have a look at the vembrane benchmarks.
Installation
vembrane is available in bioconda and can either be installed into an existing conda environment with
mamba install -c conda-forge -c bioconda vembraneor into a new named environmentmamba create -n environment_name -c conda-forge -c bioconda vembrane. Alternatively, if you are familiar with git and uv, clone this repository and runuv sync. See docs/develop.md for further details.Subcommands
vembrane provides several subcommands for different tasks:
filter: Filters VCF/BCF files based on flexible Python expressions. See the detailed documentation below.tag: A non-destructive version offilter. Instead of removing records, it adds a user-defined tag to theFILTERfield of records that match an expression. For more details, seedocs/tag.md.table: Creates tabular (TSV/CSV or parquet) files from VCF/BCF data. The columns can be defined with flexible Python expressions. For more details, seedocs/table.md.annotate: Annotates VCF/BCF files with data from an external table-like file (e.g., TSV, CSV), based on genomic coordinates. For more details, seedocs/annotate.md.sort: Sorts VCF/BCF files. The sort order can be defined via flexible Python expressions and thus be based on any field and annotation that occurs in the VCF/BCF (e.g. impact or clinical significance). The primary use case is variant prioritization. For more details, seedocs/sort.md.structured: Converts VCF records into structured formats like JSON, JSONL, or YAML using a flexible YTE template. For more details, seedocs/structured.md.fhir: Converts VCF records into FHIR observations. For more details, seedocs/fhir.md.vembrane filterFull documentation is also available in
docs/filter.md.Usage
vembrane takes two positional arguments: The filter expression and the input file; the latter may be omitted to read from
stdininstead, making it easy to use vembrane in pipe chains.Filter expression
The filter expression can be any valid python expression that evaluates to a value of type
bool. If you want to use truthy values, you need to wrap the expression inbool(), or aggregate multiple values viaany()orall().However, functions and symbols available have been restricted to the following:
all,anyabs,len,max,min,round,sumenumerate,filter,iter,map,next,range,reversed,sorted,zipdict,list,set,tuplebool,chr,float,int,ord,strmathstatisticsrewithout_na(values: Iterable[T]) -> Iterable[T](keep only values that are notNA)replace_na(values: Iterable[T], replacement: T) -> Iterable[T](replace values that areNAwith some other fixed value)count_hom,count_het,count_any_ref,count_any_var,count_hom_ref,count_hom_varis_hom,is_het,is_hom_ref,is_hom_varhas_ref,has_varAvailable fields
The following VCF fields can be accessed in the filter expression:
INFODict[str, Any¹]INFO field -> ValueINFO["DP"] > 0ANN²Dict[str, Any³]ANN field -> Value²ANN["SYMBOL"] == "CDH2"²CHROMstrCHROM == "chr2"POSint24 < POS < 42ENDintINFO["END"]24 < END < 42IDstrID == "rs11725853"REFstrREF == "A"ALTstrALT == "C"QUALfloatQUAL >= 60FILTERList[str]"PASS" in FILTERFORMATDict[str, Dict[str, Any¹]]Format -> (Sample -> Value)FORMAT["DP"][SAMPLES[0]] > 0SAMPLESList[str][Sample]"Tumor" in SAMPLESINDEXintINDEX < 10¹ depends on type specified in VCF header
² if your VCF defines annotations under a key other than
ANN(e.g. VEP’sCSQ) you have to specify this via the--annotation-keyflag (e.g.--annotation-key CSQ). You can (and should, for portability) still useANNin your expressions then (although the given annotation key works as well, e.g.CSQ["SYMBOL"]).³ for the usual snpeff and vep annotations, custom types have been specified; any unknown ANN field will simply be of type
str. If something lacks a custom parser/type, please consider filing an issue in the issue tracker.⁴ vembrane does not handle multi-allelic records itself. Instead, such files should be preprocessed by either of the following tools (preferably even before annotation):
bcftools norm -m-any […]gatk LeftAlignAndTrimVariants […] --split-multi-allelicsvcfmulti2oneallele […]Examples
Only keep annotations and variants where gene equals “CDH2” and its impact is “HIGH”:
Only keep variants with quality at least 30:
Only keep annotations and variants where feature (transcript) is ENST00000307301:
Only keep annotations and variants where protein position is less than 10:
Only keep variants where the ID matches the regex pattern
^rs[0-9]+:Only keep variants where mapping quality is exactly 60:
Only keep annotations and variants where CLIN_SIG contains “pathogenic”, “likely_pathogenic” or “drug_response”:
Using set operations, the same may also be expressed as:
Filter on sample specific values:
SAMPLES:SAMPLES:Filter on genotypes for specific samples (named “kid”, “mom”, “dad”):
Explicitly access the
GTfield for the first sample in the file:Custom
ANNtypesvembraneparses entries in the annotation field (ANNor whatever you specify under--annotation-key) as outlined in docs/ann_types.md.Missing values in annotations
If a certain annotation field lacks a value, it will be replaced with the special value of
NA. Comparing with this value will always result inFalse, e.g.ANN["MOTIF_POS"] > 0will always evaluate toFalseif there was no value in the “MOTIF_POS” field of ANN (otherwise the comparison will be carried out with the usual semantics).For fields with custom types, such as
ANN["Protein_position"]which is of typePosRangewith attributesstart,endandlength, trying to accessANN["Protein_position"].startwill result inNAif there was no value for"Protein_position"in the annotation of the respective record, i.e. the access will returnNAinstead of raising anAttributeError. In general, any attribute access onNAwill result inNA(and issue a warning to stderr).Since you may want to use the regex module to search for matches,
NAalso acts as an emptystr, such thatre.search("nothing", NA)returns nothing instead of raising an exception.Explicitly handling missing/optional values in INFO or FORMAT fields can be done by checking for NA, e.g.:
INFO["DP"] is NA.Handling missing/optional values in fields other than INFO or FORMAT can be done by checking for None, e.g
ID is not None.Sometimes, multi-valued fields may contain missing values; in this case, the
without_nafunction can be convenient, for example:mean(without_na(FORMAT['DP'][s] for s in SAMPLES)) > 2.3. It is also possible to replaceNAwith some constant value with thereplace_nafunction:mean(replace_na((FORMAT['DP'][s] for s in SAMPLES), 0.0)) > 2.3Auxiliary files
vembranesupports additional files, such as lists of genes or ids with the--aux NAME=path/to/fileoption. The file should contain one item per line and is parsed as a set. For examplevembrane filter --aux genes=genes.txt "ANN['SYMBOL'] in AUX['genes']" variants.vcfwill keep only records where the annotated symbol is in the set specified ingenes.txt.Custom context
In addition to the default context for expressions given to vembrane, consisting of variables containing the VCF/BCF record information, helper functions and useful Python builtins (like
any()), it is possible to define additional custom context via the flags--context STATEMENT: providing a Python statement,--context-file PATH: providing a Python script to evaluate (considering the parent directory of the script as search path for eventual additional imports).In both cases, the provided input is evaluated with Python. Any global variables (or functions) become available in the Python expressions that you provide to vembrane for filtering or the other subcommands. Note that the code you provide as context is not sandboxed and should be trusted. Carefully review any code you get from the internet or AI.
An example use case is the import of additional Python modules. For example, you could use this to randomly subsample 10% of the VCF/BCF records given in a file
input.vcf:Ontologies
vembranesupports ontologies in OBO format. The ontology is loaded into memory and can be accessed in the filter expression via theSOsymbol. This enables filtering based on relationships between ontology terms. For example,vembrane filter --ontology so.obo 'ANN["Consequence"].any_is_a("intron_variant")'will keep only records where at least one of the consequences is an intron variant or a subtype thereof. If no ontology is provided, the built-in ontology from sequenceontology.org (date: 2024-06-06) is loaded automatically if theSOsymbol is accessed.There are three relevant classes/types:
Term: Represents a term in the ontology. It inherits fromstrand can be used as such.Consequences: Represents a list of terms. It inherits fromlistand can be used as such.SO: Represents the ontology itself. It is a singleton and can be used to access the ontology.The following functions are available for ontologies, where
termis a singleTermandtermsis aConsequencesobject:SO.get_id(term: Term) -> str: Convert from term name (e.g.stop_gained) to accession (e.g.SO:0001587).SO.get_term(id_: str) -> Term: Convert from accession (e.g.SO:0001587) to term name (e.g.stop_gained).terms.most_specific_terms() -> Consequences: Narrow down the list of terms to the most specific ones, e.g.frameshift_variant&frameshift_truncation&intron_variant&splice_site_variant&splice_donor_5th_base_variantwill lead toframeshift_truncation&splice_donor_5th_base_variant.term.ancestors() -> Consequences: Get all ancestral levels of a term, all the way to the ontology’s root node.term.descendants() -> Consequences: Get all descendant levels of a term, all the way to the ontology’s respective leave nodes.term.parents() -> Consequences: Get immediate parents of a term.term.children() -> Consequences: Get immediate children of a term.term.is_a(parent: Term) -> bool: Check if there is a path fromtermtoparent, i.e. whethertermis theparenttype or a subtype of it.terms.any_is_a(parent: Term) -> bool: Check if any of the terms is a subtype ofparent.term.is_ancestor(other: Term) -> bool: Check iftermis an ancestor ofother.term.is_descendant(other: Term) -> bool: Check iftermis a descendant ofother. (Same asis_a)term.path_length(target: Term) -> int | None: Get the shortest path length fromtermtotargetor vice versa. ReturnsNoneif no path exists.Citation
Check the “Cite this repository” entry in the sidebar for citation options.
Also, please read should-I-cite-this-software for background.
Authors