77"""
88
99from __future__ import annotations
10- from typing import List , Tuple , Optional , Set , Any , Dict
10+ from typing import List , Tuple , Optional , Any , Dict
1111from dataclasses import dataclass , field
1212from abc import ABC , abstractclassmethod
1313import itertools
@@ -30,19 +30,20 @@ class Snippet(ABC):
3030 documentation. Note that it is not always continuous fragment at text (rst)
3131 level.
3232 """
33- _scopes : List [ Tuple [int ,int ] ] = field (init = False )
33+ _scope : Tuple [int ,int ] = field (init = False )
3434 _refid :Optional [str ] = field (init = False )
3535
3636 def __post_init__ (self ) -> None :
3737 """Post-init processing routine of dataclass"""
3838
3939 # Calcuate scope before deepcopy
40- scopes = []
40+ scope = [float ( 'inf' ), - float ( 'inf' ) ]
4141 for node in self .nodes ():
4242 if not node .line :
4343 continue # Skip node that have None line, I dont know why :'(
44- scopes .append ((line_of_start (node ), line_of_end (node )))
45- self ._scopes = merge_scopes (scopes )
44+ scope [0 ] = min (scope [0 ], line_of_start (node ))
45+ scope [1 ] = max (scope [1 ], line_of_end (node ))
46+ self ._scope = scope
4647
4748 # Find exactly one id attr in nodes
4849 self ._refid = None
@@ -82,25 +83,20 @@ def file(self) -> str:
8283 return self .nodes ()[0 ].source
8384
8485
85- def scopes (self ) -> List [ Tuple [int ,int ] ]:
86+ def scope (self ) -> Tuple [int ,int ]:
8687 """
87- Return the scopes of snippet, which corresponding to the line
88+ Return the scope of snippet, which corresponding to the line
8889 number in the source file.
8990
9091 A scope is a left closed and right open interval of the line number
91- ``[left, right)``. Snippet is not continuous in source file so we return
92- a list of scope.
92+ ``[left, right)``.
9393 """
94- return self ._scopes
94+ return self ._scope
9595
9696
9797 def text (self ) -> List [str ]:
9898 """Return the original reStructuredText text of snippet."""
99- srcfn = self .file ()
100- lines = []
101- for scope in self .scopes ():
102- lines += read_partial_file (srcfn , scope )
103- return lines
99+ return read_partial_file (self .file (), self .scope ())
104100
105101
106102 def refid (self ) -> Optional [str ]:
@@ -197,22 +193,6 @@ def read_partial_file(filename:str, scope:Tuple[int,Optional[int]]) -> List[str]
197193 lines .append (line .strip ('\n ' ))
198194 return lines
199195
200- def merge_scopes (scopes :List [Tuple [int ,int ]]) -> List [Tuple [int ,int ]]:
201- """"Merge the overlap scope, the pass-in scopes must be sorted."""
202- merged = [scopes [0 ]]
203- for tup in scopes :
204- if merged [- 1 ][1 ] >= tup [0 ]:
205- if merged [- 1 ][1 ] >= tup [1 ]:
206- # Completely overlap
207- continue
208- else :
209- # Partial overlap
210- merged [- 1 ] = (merged [- 1 ][0 ], tup [1 ])
211- else :
212- # No overlap
213- merged .append (tup )
214- return merged
215-
216196
217197def line_of_start (node :nodes .Node ) -> int :
218198 assert node .line
0 commit comments