Structural Pattern Matching#
PyBryt supports structural pattern matching in order to allow you to create annotations that check
the structure of objects instead of using an ==
check. Structural patterns can be created by
accessing attributes of the singleton
pybryt.structural
and calling them
with attribute-value pairs as arguments. For example, if you’re matching an instance of
mypackage.Foo
with attribute bar
set to 2
; a structural pattern for this could be
created with
pybryt.structural.mypackage.Foo(bar=2)
If there are attributes you want to look for without a specific name, you can pass these as positional arguments:
pybryt.structural.mypackage.Foo(3, bar=2)
To determine whether an object matches the structural pattern, PyBryt imports the package and retrieves the specified class. In the examples above, this would look like
getattr(importlib.import_module("mypackage"), "Foo")
If the provided object is an instance of this class and has the specified attributes, the object
matches. You can determine if an object matches a structural pattern using an ==
comparison.
If no package is specified for the class, the pattern just checks that the name of the class matches the name of the class in the structural pattern, without importing any modules. For example:
df_pattern = pybryt.structural.DataFrame()
df_pattern == pd.DataFrame() # returns True
class DataFrame:
pass
df_pattern == DataFrame() # returns True
Attribute values are matched using the same algorithm as
Value
annotations. If you would like to make use of
the options available to Value
annotations, you can
also pass an annotation as an attribute value:
pybryt.structural.mypackage.Foo(pi=pybryt.Value(np.pi, atol=1e-5))
For checking whether an object contains specific members (determined via the use of Python’s
in
operator), use the contains_
method:
pybryt.structural.mypackage.MyList().contains_(1, 2, 3)
To use structural patterns, pass them as values to Value
annotations. When a value annotation is checking for a structural pattern, it uses the pattern’s
==
check to determine whether any object in the memory footprint matches.
pybryt.Value(pybryt.structural.mypackage.MyList())