@@ -59,32 +59,40 @@ def __init__(
5959 if hyperscan is None :
6060 raise hyperscan_error
6161
62- if not patterns :
63- raise ValueError (f"{ patterns = !r} cannot be empty." )
64- elif not isinstance (patterns [0 ], RegexPattern ):
62+ if patterns and not isinstance (patterns [0 ], RegexPattern ):
6563 raise TypeError (f"{ patterns [0 ]= !r} must be a RegexPattern." )
6664
6765 use_patterns = enumerate_patterns (
6866 patterns , filter = True , reverse = False ,
6967 )
7068
71- self ._db = self ._make_db ()
69+ debug_exprs = bool (_debug_exprs )
70+ if use_patterns :
71+ db = self ._make_db ()
72+ expr_data = self ._init_db (
73+ db = db ,
74+ debug = debug_exprs ,
75+ patterns = use_patterns ,
76+ sort_ids = _test_sort ,
77+ )
78+ else :
79+ # WARNING: The hyperscan database cannot be initialized with zero
80+ # patterns.
81+ db = None
82+ expr_data = []
83+
84+ self ._db : Optional [hyperscan .Database ] = db
7285 """
7386 *_db* (:class:`hyperscan.Database`) is the Hyperscan database.
7487 """
7588
76- self ._debug_exprs = bool ( _debug_exprs )
89+ self ._debug_exprs = debug_exprs
7790 """
7891 *_debug_exprs* (:class:`bool`) is whether to include additional debugging
7992 information for the expressions.
8093 """
8194
82- self ._expr_data : list [HyperscanExprDat ] = self ._init_db (
83- db = self ._db ,
84- debug = self ._debug_exprs ,
85- patterns = use_patterns ,
86- sort_ids = _test_sort ,
87- )
95+ self ._expr_data : list [HyperscanExprDat ] = expr_data
8896 """
8997 *_expr_data* (:class:`list`) maps expression index (:class:`int`) to
9098 expression data (:class:`:class:`HyperscanExprDat`).
@@ -130,12 +138,15 @@ def _init_db(
130138 Returns a :class:`list` indexed by expression id (:class:`int`) to its data
131139 (:class:`HyperscanExprDat`).
132140 """
141+ # WARNING: Hyperscan raises a `hyperscan.error` exception when compiled with
142+ # zero elements.
143+ assert patterns , patterns
144+
133145 # Prepare patterns.
134146 expr_data : list [HyperscanExprDat ] = []
135147 exprs : list [bytes ] = []
136148 for pattern_index , pattern in patterns :
137- if pattern .include is None :
138- continue
149+ assert pattern .include is not None , (pattern_index , pattern )
139150
140151 # Encode regex.
141152 assert isinstance (pattern , RegexPattern ), pattern
@@ -176,6 +187,7 @@ def _init_db(
176187 elements = len (exprs ),
177188 flags = HS_FLAGS ,
178189 )
190+
179191 return expr_data
180192
181193 @override
@@ -191,8 +203,14 @@ def match_file(self, file: str) -> tuple[Optional[bool], Optional[int]]:
191203 """
192204 # NOTICE: According to benchmarking, a method callback is 20% faster than
193205 # using a closure here.
206+ db = self ._db
207+ if self ._db is None :
208+ # Database was not initialized because there were no patterns. Return no
209+ # match.
210+ return (None , None )
211+
194212 self ._out = (None , - 1 )
195- self . _db .scan (file .encode ('utf8' ), match_event_handler = self .__on_match )
213+ db .scan (file .encode ('utf8' ), match_event_handler = self .__on_match )
196214
197215 out_include , out_index = self ._out
198216 if out_index == - 1 :
0 commit comments