Validation#
The phylozoo.utils.validation module contains the utilities used to validate PhyloZoo objects and to disable validation for performance-critical code.
All functions and classes on this page can be imported from the validation module:
from phylozoo.utils.validation import no_validation, validation_aware
What is validation?#
PhyloZoo performs validation on objects to ensure they satisfy required structural and attribute rules. For example, these checks cover connectivity, the absence of forbidden cycles, correct node degrees (such as having exactly one root and leaves with in-degree 1), and valid edge attributes (for example, ensuring hybrid-edge γ values lie in [0, 1] and sum to 1.0 at hybrid nodes).
By default, validation runs automatically at the end of object construction so that invalid objects are rejected as soon as they are created. For some classes, validation is expensive, and it can therefore be disabled; for performance, or when building objects in stages.
If a check fails, a domain‑specific exception is raised (such as PhyloZooNetworkStructureError or PhyloZooNetworkDegreeError).
See Exceptions for the full exception hierarchy.
This page explains which classes use the validation system, how to enable or disable it, and how to make your own classes validation‑aware.
Which classes are validation-aware?#
The following classes are validation-aware and run a validation method that is recognized by the validation system:
DirectedPhyNetwork— directed phylogenetic networksMixedPhyNetwork— mixed directed/undirected networks (base for semi-directed)SemiDirectedPhyNetwork— semi-directed phylogenetic networksDirectedGenerator— directed level-k generatorsSemiDirectedGenerator— semi-directed level-k generators
For the exact checks each class performs, see their documentation in the API reference.
Note that some other classes also validate input but they are are not validation-aware. This design choice was made for classes where validation is inexpensive.
Disabling validation#
Use the no_validation() context manager to
temporarily disable validation. Inside the block, calls to validate() (and
any other methods you configured) are skipped for the matching classes and
methods, so construction no longer runs those checks.
Disable all validation (default methods for all validation-aware classes)
from phylozoo import DirectedPhyNetwork
from phylozoo.utils.validation import no_validation
with no_validation():
net = DirectedPhyNetwork(edges=[(1, 2), (2, 3)]) # validate() not run
Disable only for specific classes
Use the classes argument with class names or fnmatch patterns. Only
those classes skip validation; others still run it.
from phylozoo.core.network.dnetwork.generator.base import DirectedGenerator
from phylozoo.utils.validation import no_validation
with no_validation(classes=["DirectedGenerator"]):
gen = DirectedGenerator(...) # validate() suppressed
net = DirectedPhyNetwork(...) # validate() still runs
with no_validation(classes=["*Generator"]): # any class whose name ends with "Generator"
gen = DirectedGenerator(...) # validate() suppressed
Disable only specific methods
Use the methods argument with method names or fnmatch patterns. The
class’s default list (see below) is ignored when you pass methods.
from phylozoo.utils.validation import no_validation
with no_validation(methods=["validate"]):
net = DirectedPhyNetwork(...) # only validate() is suppressed
with no_validation(methods=["validate", "_validate_*"]):
net = DirectedPhyNetwork(...) # validate() and all _validate_* helpers suppressed
Combine class and method filters
with no_validation(classes=["*Generator"], methods=["validate"]):
gen = DirectedGenerator(...) # validate() suppressed only for generator classes
Note
Nested blocks stack: inner no_validation settings apply in addition to
outer ones. After exiting the context, validation runs normally again.
Warning
Only turn off validation when you are sure the objects you build are valid. Invalid objects can cause confusing errors in later code.
Example: Batch creation of networks#
When building many networks with a particular structures, which are known or tested to be valid, it can be beneficial to disable validation for performance. After constructing the networks, you can still validate them individually if needed.
from phylozoo import DirectedPhyNetwork
from phylozoo.utils.validation import no_validation
from phylozoo.utils.exceptions import PhyloZooNetworkError
with no_validation():
networks = [
DirectedPhyNetwork(edges=[(i, i + 1)])
for i in range(100)
]
for net in networks:
try:
net.validate()
except PhyloZooNetworkError as e:
print(f"Invalid network: {net}, error: {e}")
Using the decorator for your own classes#
To make a class participate in this system, decorate it with
validation_aware(). You choose which methods
can be suppressed and which are suppressed by default when
no_validation() is used with no
methods argument.
Parameters
allowed — Method names or
fnmatchpatterns that may be suppressed (e.g.["validate", "_validate_*"]). Only these methods are wrapped.default — Subset of
allowedthat is suppressed whenno_validation()is used withoutmethods. Must match at least oneallowedpattern orPhyloZooValueErroris raised.
Example
from phylozoo.utils.validation import validation_aware, no_validation
@validation_aware(allowed=["validate", "_validate_*"], default=["validate"])
class MyNetwork:
def __init__(self):
self.validate() # runs unless inside no_validation()
def validate(self):
self._validate_structure()
def _validate_structure(self):
# your checks; raise PhyloZoo*Error on failure
pass
# Normal use: validation runs
obj = MyNetwork()
# Suppress only validate (default for this class)
with no_validation():
obj2 = MyNetwork() # validate() and _validate_* not run
# Suppress only a specific method for all classes
with no_validation(methods=["_validate_structure"]):
obj.validate() # validate() runs, _validate_structure() is skipped
See Also#
Exceptions — Exception and warning classes raised during validation.
Directed Network Class — DirectedPhyNetwork construction and validation.
Semi-Directed Network Class — SemiDirectedPhyNetwork and MixedPhyNetwork construction and validation.
Directed Generator — DirectedGenerator construction and validation.
Semi-Directed Generator — SemiDirectedGenerator construction and validation.