+
   xcc                   s   R t ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIt]P                  ! R4      t]! ^ 4      sRtRt ^ RItR	tRt ^ RItR	t^dt ! R
 R4      t ! R R4      tR	tR R lt]R8X  d
   ]! 4        R# R#   ]3 d     ^ RItR	t LJ  ]3 d      LUi ; ii ; i  ]3 d     L^i ; i)zZA module used by ibus-typing-booster to suggest words by using the
hunspell dictonaries.

)Dict)Tuple)List)Iterable)AnyNzibus-typing-boosterFTc                   sL  a a ] tR t^Ft oRt/ tRV3R lV 3R llltRV3R lR lltV3R lR ltV3R lR	 lt	V3R
 lR lt
V3R lR ltV3R lR ltV3R lR ltV3R lR ltV3R lR ltV3R lR lt]P$                  ! RR7      V3R lR l4       tV3R ltRtVtV ;t# )
Dictionaryz%A class to hold a hunspell dictionaryc                s,   < V ^8  d   QhRS[ RS[RS[ /# )   clsnamereturn)r   strformat__classdict__   "9/usr/share/ibus-typing-booster/engine/hunspell_suggest.py__annotate__Dictionary.__annotate__Q   s"     # #S # ## #    c                s   < W3pW P                   9  d0   \        SV `	  V 4      pW0P                   V&   VP                  VR7       V P                   V,          # )zFCaching instances of this class and reuse previously created instancesr   )
_instancesZsuper__new___initialize)r   r   keyZinstance	__class__s   &&  r   r   ZDictionary.__new__Q   sN    knn$ws+H"*NN3  d +~~c""r   c                s$   < V ^8  d   QhRS[ RR/# )r   r   r	   N)r
   r   r   r   r   r   Z   s     # # #$ #r   c                sX   \         ^8  d   \        P                  RV4       Wn        V P                  P	                  R4      ^ ,          V n        RV n        RV n        . V n        . V n	        ^ V n
        RV n        RV n        RV n        V P                  R8w  d   V P                  4        R# R# )zInitialize a Dictionaryzname=%s_Z UTF-8NZNone)DEBUG_LEVELLOGGERdebugr   splitlanguagedic_pathencodingwords
word_pairsmax_word_lenenchant_dictpyhunspell_objectvoikkoload_dictionary)selfr      &&r   r   ZDictionary._initializeZ   s    ?LLD)			,Q/!
13 !%(,99  " r   c                   < V ^8  d   QhRR/# r   r	   N r   r   r   r   r   k   s     G2 G2 G2r   c           	     s>	   \         ^ 8  d   \        P                  R4       \        P                  ! V P
                  4      w  V n        V n        V n        V P                  '       Edp   V P                  \        P                  9   dY   V P                   Uu. uF<  pV\        P                  ! V\        P                  V P                  ,          R7      3NK>  	  upV n        V P                   F'  p\        V P                  \        V4      4      V n        K)  	  \         ^8  d!   \        P                  RV P                  4       V P
                  P!                  R4      ^ ,          R8X  dW   RV n        RV n        RV n        \(        '       g   \        P+                  R4       R#  \,        P.                  ! R4      V n        R# \6        '       d   \8        P:                  ! 4       pVP=                  V P
                  R	4        VP?                  V P
                  4      V n        \         ^8  dH   V P"                  e8   \        P                  R
V P
                  V P"                  P@                  4       R# R# R# \J        '       dZ   V P                  '       dF   V P                  PM                  RR4      p \N        PP                  ! V P                  V4      V n        R# R# R# R# u upi   \,        P0                  3 d>   p\        P+                  RTP2                  P4                  T4       RT n         Rp?R# Rp?ii ; i  \8        PB                  PD                   dI   p\        PG                  RT P
                  TP2                  P4                  T4       RT n         Rp?R# Rp?i\H         dI   p\        PG                  RT P
                  TP2                  P4                  T4       RT n         Rp?R# Rp?ii ; i  \N        PR                   dI   p\        P                  RT P
                  TP2                  P4                  T4       RT n         Rp?R# Rp?i\H         dI   p\        P                  RT P
                  TP2                  P4                  T4       RT n         Rp?R# Rp?ii ; i)z^Load a hunspell dictionary and instantiate a
enchant.Dict() or a hunspell.Hunspell() object.

zload_dictionary() ...
Zkeepzmax_word_len = %s
r   ZfiNu7   Language is “fi” but “import libvoikko” failed.zInit of voikko failed: %s: %szhunspell,nuspell,aspell,voikkoz%s: %rz)Error initializing enchant for %s: %s: %sz4Unexpected error initializing enchant for %s: %s: %sz.dicz.affz*Error initializing hunspell for %s: %s: %sz5Unexpected error initializing hunspell for %s: %s: %s)*r   r   r   itb_utilZ get_hunspell_dictionary_wordlistr   r    r!   r"   r   ACCENT_LANGUAGESremove_accentsr#   Zmaxr$   lenr   r%   r&   r'   IMPORT_LIBVOIKKO_SUCCESSFULZwarning	libvoikkoZVoikkoZVoikkoExceptionr   __name__IMPORT_ENCHANT_SUCCESSFULenchantZBrokerZset_orderingZrequest_dictZproviderZerrorsZDictNotFoundErrorZ	exceptionZ	ExceptionIMPORT_HUNSPELL_SUCCESSFULreplacehunspellZHunSpellZHunSpellError)r)   xwordZerrorZbrokerZaff_paths   &     r   r(   ZDictionary.load_dictionaryk   s   
 ?LL23  @@K			:::}} 9 99 "ZZ# ( // 9 9$-- HJ K'#
 

$'(9(93t9$E! #Q)4+<+<>yys#A&$.$(!)-&"22NNQS'"+"2"24"8DK
 (( )##DII/OP-(.(;(;DII(FD%"Q4+<+<+H$dii1B1B1K1KM ,I ,+==00@2 )) MM85 * 1>+[ #( "113 'NN#B#(??#;#;UD"&DKK	' ~~77 -$$C		5??#;#;UD )-D%%  -$$N		5??#;#;UD )-D%%	-  -- 2LLD		5??#;#;UD .2D**  2LL%		5??#;#;UD .2D**2st   AK K ;A.L3 *&O. L032L++L03O+=NO+"O+#=O&&O+.R=QRR=RRc                &   < V ^8  d   QhRS[ RS[/# r   r<   r	   r
   boolr   r   r   r   r      s     K Ks Kt Kr   c                s    V P                   '       g   R# V P                   P                  \        P                  ! RV4      4      # )z
Spellcheck a word using enchant

:param word: The word to spellcheck
:return: True if spelling is correct, False if not or unknown
FNFC)r%   Zcheckunicodedata	normalizer)   r<   r*   r   spellcheck_enchantZDictionary.spellcheck_enchant   s9           &&{'<'<UD'IJJr   c                r=   r>   r?   r   r   r   r   r      s     + +# +$ +r   c                s    V P                   '       g   R# V P                   P                  \        P                  ! RV4      P	                  V P
                  R4      4      # )z
Spellcheck a word using pyhunspell

:param word: The word to spellcheck
:return: True if spelling is correct, False if not or unknown
FrA   r9   )r&   spellrB   rC   encoder!   rD   r*   r   spellcheck_pyhunspellZ Dictionary.spellcheck_pyhunspell   sR     %%% %%++!!%.55y*+ 	+r   c                r=   r>   r?   r   r   r   r   r      s     
K 
Kc 
Kd 
Kr   c                s    V P                   '       g   R# \        V P                   P                  \        P                  ! RV4      4      4      # )z
Spellcheck a word using voikko

:param word: The word to spellcheck
:return: True if spelling is correct, False if not or unknown
FrA   )r'   r@   rF   rB   rC   rD   r*   r   spellcheck_voikkoZDictionary.spellcheck_voikko   s7     {{{DKK%%k&;&;E4&HIJJr   c                r=   r>   r?   r   r   r   r   r      s      s t r   c                s    V P                   '       d   V P                  V4      # V P                  '       d   V P                  V4      # V P                  '       d%   \        V P                  P                  V4      4      # R# )aY  
Spellcheck a word using enchant, pyhunspell, or voikko

:param word: The word to spellcheck
:return: True if spelling is correct, False if not or unknown

>>> d = Dictionary('en_US')
>>> d.spellcheck('winter')
True

>>> d.spellcheck('winxer')
False

>>> d = Dictionary('None')
>>> d.spellcheck('winter')
False

>>> d.spellcheck('winxer')
False
F)r%   rE   r&   rH   r'   r@   rF   rD   r*   r   
spellcheckZDictionary.spellcheck   sd    * **400!!!--d33;;;))$/00r   c                s    < V ^8  d   QhRS[ /# r   r	   )r@   r   r   r   r   r      s      4 r   c                sv    V P                   '       g%   V P                  '       g   V P                  '       d   R# R# )aD  
Returns wether this dictionary supports spellchecking or not

:return: True if this dictionary spports spellchecking, False if not

Examples:

>>> d = Dictionary('en_US')
>>> d.has_spellchecking()
True

>>> d = Dictionary('zh_CN')
>>> d.has_spellchecking()
False

>>> d = Dictionary('None')
>>> d.has_spellchecking()
False
TF)r%   r&   r'   r)      &r   has_spellcheckingZDictionary.has_spellchecking   s)    (  6 6 6$+++r   c                6   < V ^8  d   QhRS[ RS[S[ ,          /# r>   r
   r   r   r   r   r   r     s      s tCy r   c                
   V'       d   V P                   '       g   . # V P                   P                  \        P                  ! RV4      4       Uu. uF(  p\        P                  ! \        P
                  V4      NK*  	  up# u upi )z
Return spellchecking suggestions for word using enchant

:param word: The word to return spellchecking suggestions for
:return: List of spellchecking suggestions, possibly empty.
rA   )r%   suggestrB   rC   r/   NORMALIZATION_FORM_INTERNALr)   r<   r;      && r   spellcheck_suggest_enchantZ%Dictionary.spellcheck_suggest_enchant  s{     4,,,I %%k&;&;E4&HI	 J  !!44a9 J	 	    .B c                rO   r>   rP   r   r   r   r   r   %  s      # $s) r   c                s>   V'       d   V P                   '       g   . # V P                   P                  \        P                  ! RV4      P	                  V P
                  R4      4       Uu. uF(  p\        P                  ! \        P                  V4      NK*  	  up# u upi )z
Return spellchecking suggestions for word using pyhunspell

:param word: The word to return spellchecking suggestions for
:return: List of spellchecking suggestions, possibly empty.
rA   r9   )r&   rR   rB   rC   rG   r!   r/   rS   rT   rU   r   spellcheck_suggest_pyhunspellZ(Dictionary.spellcheck_suggest_pyhunspell%  s     4111I ""**%%eT299MM9./	/  !!44a9/	 	 s   ).Bc                rO   r>   rP   r   r   r   r   r   8  s      c d3i r   c                rQ   )z
Return spellchecking suggestions for word using voikko

:param word: The word to return spellchecking suggestions for
:return: List of spellchecking suggestions, possibly empty.
rA   )r'   rR   rB   rC   r/   rS   rT   rU   r   spellcheck_suggest_voikkoZ$Dictionary.spellcheck_suggest_voikko8  sv     4;;;I
 KK 5 5eT BC	 D  !!44a9 D	 	 rW     Zmaxsizec                rO   r>   rP   r   r   r   r   r   V  s        s  tCy  r   c                s    V P                   '       d   V P                  V4      # V P                  '       d   V P                  V4      # V P                  '       d   V P                  V4      # . # )u|  Return spellchecking suggestions for word using enchant,
pyhunspell or voikko

:param word: The word to return spellchecking suggestions for
:return: List of spellchecking suggestions, possibly empty.

Results can be quite different depending on whether enchant or
pyhunspell is used and in case of enchant whether hunspell,
aspell, myspell, or ispell are used. So for the doctests,
better don’t check the complete list of suggestions returned.

Examples:

>>> d = Dictionary('en_US')
>>> 'Camel' in d.spellcheck_suggest('kamel')
True

>>> d.spellcheck_suggest('')
[]

>>> d = Dictionary('None')
>>> d.spellcheck_suggest('kamel')
[]

)r%   rV   r&   rX   r'   rY   rD   r*   r   spellcheck_suggestZDictionary.spellcheck_suggestU  s]    6 22488!!!55d;;;;;11$77	r   c                sR   < V ^8  d   Qh/ S[ S[S[S[3,          S[3,          ;R&   # )r   r   )r    r   r   r
   r   r   r   r   r   F   s$      U38_c)*/ r   )
r    r%   r!   r   r$   r   r&   r'   r#   r"   )Zen_US)r5   
__module____qualname____firstlineno____doc__r   r   r   r(   rE   rH   rI   rJ   rN   rV   rX   rY   	functools	lru_cacher\   Z__annotate_func____static_attributes____classdictcell__Z__classcell__)r   r   s   @@r   r   r   F   s     / .0J# ## #"G2 G2RK K+ +
K 
K : 0 ( & : )  * a  r   r   c                   s   a  ] tR tRt o RtRV 3R lR lltV 3R lR ltV 3R lR ltV 3R	 lR
 ltV 3R lR lt	V 3R lR lt
RV 3R lR llt]P                  ! RR7      V 3R lR l4       tRtV tR# )Hunspelliy  zTA class to suggest completions or corrections
using a list of Hunspell dictionaries
c                4   < V ^8  d   QhRS[ S[,          RR/# r   dictionary_namesr	   N)r   r
   r   r   r   r   Hunspell.__annotate__}  s     ! !# ! !r   c                sv    \        \        \        P                  ! R 4      4      4      s\        ^8  d5   V'       d   \        P                  RV4       M\        P                  R4       / V n	        \        V4      V n        . V n        V P                  4        R#   \
        \        3 d    \        ^ 4      s Li ; i)ZIBUS_TYPING_BOOSTER_DEBUG_LEVELz'Hunspell.__init__(dictionary_names=%s)
z'Hunspell.__init__(dictionary_names=())
N)intr
   osZgetenvr   Z	TypeErrorZ
ValueErrorr   r   _suggest_cachelist_dictionary_names_dictionariesinit_dictionaries)r)   rh   r*   r   __init__ZHunspell.__init__}  s    	!BII?@ACK ?>$& GH@B,01A,B/1  :& 	!a&K	!s   (B B87B8c                r+   r,   r-   r   r   r   r   ri     s     H H4 Hr   c                s^   \         ^8  dI   V P                  '       d"   \        P                  RV P                  4       M\        P                  R4       V P                  P                  4        . V n        V P                   F(  pV P                  P                  \        VR7      4       K*  	  R# )z-Initialize the hunspell dictionaries
        z1Hunspell.init_dictionaries() dictionary_names=%s
z1Hunspell.init_dictionaries() dictionary_names=()
r   N)	r   rn   r   r   rR   Zcache_clearro   appendr   )r)   Zdictionary_name   & r   rp   ZHunspell.init_dictionaries  s     ?%%%H**, HJ  "#55O%%jo&FG  6r   c                s0   < V ^8  d   QhRS[ S[,          /# rK   r   r
   r   r   r   r   ri     s     / /d3i /r   c                s:    \        V P                  R,          4      # )zReturns a copy of the list of dictionary names.

It is important to return a copy, we do not want to change
the private member variable directly.:NNN)rm   rn   rL   rM   r   get_dictionary_namesZHunspell.get_dictionary_names  s    
 D**1-..r   c                rf   rg   rt   r   r   r   r   ri     s     6 6T#Y 64 6r   c                s   WP                   8w  d   \        V4      \        V P                   4      8w  d   Wn         V P                  4        MNWn         . pV F:  pV P                   F'  pVP                  V8X  g   K  VP                  V4       K)  	  K<  	  W n        \        ^8  dL   \        P                  RV4       V P                   F#  p\        P                  RVP                  4       K%  	  R# R# )zSets the list of dictionary names.

If the new list of dictionary names differs from the existing
one, re-initialize the dictionaries.
zset_dictionary_names(%s):
z%s
N)	rn   Zsetrp   ro   r   rr   r   r   r   )r)   rh   Zdictionaries_newr   
dictionary   &&   r   set_dictionary_namesZHunspell.set_dictionary_names  s     555#$D,B,B(CC)9&&&(
 *:&#% ,D&*&8&8
%??d2,33J? '9 - &6"?LL68HI"00
VZ__5 1 r   c                r=   r   input_phraser	   r?   r   r   r   r   ri     s     6 6s 6t 6r   c                s    RV9   d   R# RpRpV P                    F4  pVP                  4       '       g   K  RpW4P                  V4      ,          pK6  	  V'       g   V'       d   R# R# )u  
Checks if a string is likely to be spelled correctly checking
multiple dictionaries

:param input_phrase: A string to spellcheck
:return: True if it is more likely to be spelled correctly,
         False if it is more likely to be spelled incorrectly.
         In detail this means:
         True:
             - If it is a correctly spelled word in at least one of
               the dictionaries supporting spellchecking
             - None of the dictionaries support spellchecking
             - Contains spaces, spellchecking cannot work
         else False.

Examples:

>>> h = Hunspell(['en_US', 'de_DE', 'ja_JP'])
>>> h.spellcheck('Hello')
True

>>> h.spellcheck('Grüße')
True

>>> h.spellcheck('Gruße')
False

>>> h = Hunspell(['en_US', 'ja_JP'])
>>> h.spellcheck('Grüße')
False

>>> h = Hunspell(['ja_JP'])
>>> h.spellcheck('Grüße')
True

>>> h = Hunspell(['en_US', 'None'])
>>> h.spellcheck('Grüße')
False

>>> h = Hunspell(['None'])
>>> h.spellcheck('Grüße')
True
Z TF)ro   rN   rJ   )r)   rz   Z$spellchecking_dictionaries_availablespellcheck_totalrv   rw   r   rJ   ZHunspell.spellcheck  sc    X ,/4, ,,J++--7;4 $9$9,$GG  -  $Hr   c                rO   ry   rP   r   r   r   r   ri     s      # $s) r   c                s    . pVP                  4       '       g   . # V P                   F7  pVP                  V4      '       g   K  VP                  VP                  4       K9  	  V# )u  
Returns a list of dictionaries where input_phrase can be found

:param input_phrase: The word to be spellchecked
:return: A list of dictionary names which accept input phrase
         as a valid word.

Examples:

>>> h = Hunspell(['en_US', 'None', 'it_IT', 'fr_FR'])
>>> h.spellcheck_match_list('arrive')
['en_US', 'fr_FR']
>>> h.spellcheck_match_list('arrivé')
['fr_FR']
>>> h.spellcheck_match_list('ragazzo')
['it_IT']
>>> h.spellcheck_match_list('   ')
[]
)Zstripro   rJ   rr   r   )r)   rz   Z
match_listrv   s   &&  r   spellcheck_match_listZHunspell.spellcheck_match_list  sX    ( 
!!##I,,J$$\22!!*//2 - r   c                sF   < V ^8  d   QhRS[ S[,          RS[S[,          /# )r   r"   r	   )r   r
   r   r   r   r   r   ri     s'     A( A((3- A(c A(r   c                s   V'       g   . # V F  pV'       d   K  . u # 	  . pV P                    FJ  pRpV F  pWTP                  V4      ,          pK  	  V'       g   K/  VP                  VP                  4       KL  	  \	        V4      # )u  
Checks whether there is at least one dictionary where all words
in the input list spellcheck as True.

:param words: A list or tuple of words to spellcheck
:return: - '' if at least one input word is empty
         - name of a dictionary where all
           words in the input list spellcheck as True, if
           there is no such dictionary, return ''.

Examples:

>>> h = Hunspell(['en_US', 'fr_FR'])

All 3 words spellcheck True in the French dictionary:

>>> h.spellcheck_single_dictionary(('Je', 'suis', 'arrivé'))
['fr_FR']

Not a correct French sentence but all 3 words spellcheck True
in the French dictionary:

>>> h.spellcheck_single_dictionary(('Je', 'suis', 'arrive'))
['fr_FR']

All words spellcheck as True in both the English and the French dictionary:

>>> h.spellcheck_single_dictionary(('arrive', 'arrive', 'arrive'))
['en_US', 'fr_FR']

Not all 3 words spellcheck True in the French dictionary and
not all 3 words spellcheck True in the English dictionary either:

>>> h.spellcheck_single_dictionary(('Je', 'suis', 'arrived'))
[]

All 3 words spellcheck True in the English dictionary:

>>> h.spellcheck_single_dictionary(('I', 'have', 'arrived'))
['en_US']

Unfortunately these 3 words spellcheck True in the French dictionary
('have' is a form of the verb 'haver', 'I' is the name of the letter):

>>> h.spellcheck_single_dictionary(('I', 'have', 'arrivé'))
['fr_FR']

If the input contains empty words the result is '':

>>> h.spellcheck_single_dictionary(('I', 'have', ''))
[]
T)ro   rJ   rr   r   sorted)r)   r"   r<   rh   rv   r{   s   &&    r   spellcheck_single_dictionaryZ%Hunspell.spellcheck_single_dictionary  s    j ID4	  ,,J# $9$9$$??   ''
8 - &''r   rZ   r[   c                sL   < V ^8  d   QhRS[ RS[S[S[ S[3,          ,          /# ry   )r
   r   r   rj   r   r   r   r   ri   g  s,     h" h"C h"DsCx,A h"r   c           	     s   \         ^8  d(   \        P                  RRVP                  R4      /4       V'       d   RV9   d   . # \        P
                  ! \        P                  V4      p/ pV P                   EF  pVP                  p/ W$&   VP                  '       g   K(  VP                  '       d8   \        P                  ! V\        P                  VP                  ,          R7      p\        V4      VP                   8:  d   VP                  '       dY   XP#                  4       pVP                   F7  w  rxVP#                  4       P%                  V4      '       g   K,  ^ W$,          V&   K9  	  MUVP#                  4       pVP                   F5  pVP#                  4       P%                  V4      '       g   K*  ^ W$,          V&   K7  	  \        V4      ^8  g   EK]  VP'                  V4      '       d   ^ W$,          V&   \)        W$,          4      R,           U	U
u/ uF7  p	VP+                  V	4       F  p
V
P%                  V	4      '       g   K  V
^ bK!  	  K9  	  pp	p
W$,          P-                  V4       R VP+                  V4       4       p\/        V4       F  w  rWV,          9  g   K  VP                  '       dJ   \        P                  ! V	\        P                  VP                  ,          R7      X8X  d   ^ W$,          V	&   Ko  V^,           ) W$,          V	&   K  	  EK  	  \        P0                  ! VP3                  4       !  p\)        VP5                  4       R R	7      ^ \6         pV# u up
p	i )
u  Return completions or corrections for the input phrase

:param input_phrase: A string to find completions or corrections for

Returns a list of tuples of the form (<word>, <score>)
        <score> can have these values:
            0: This is a completion, i.e. input_phrase matches
               the beginning of <word> (accent insensitive match)
           negative number: This is a spell checking correction

Examples:

(Attention, the return values are in internal
normalization form ('NFD'))

>>> h = Hunspell(['de_DE', 'cs_CZ'])
>>> h.suggest('Geschwindigkeitsubertre')[0]
('Geschwindigkeitsübertretungsverfahren', 0)

>>> h.suggest('Geschwindigkeitsübertretungsverfahren')[0]
('Geschwindigkeitsübertretungsverfahren', 0)

>>> h.suggest('Glühwürmchen')[0]
('Glühwürmchen', 0)

>>> h.suggest('Alpengluhen')[0]
('Alpenglühen', 0)

>>> h.suggest('filosofictejs')[0]
('filosofičtější', 0)

>>> h.suggest('filosofičtější')[0]
('filosofičtější', 0)

>>> h.suggest('filosofičtějš')[0]
('filosofičtější', 0)

>>> h = Hunspell(['it_IT'])
>>> h.suggest('principianti')
[('principianti', 0), ('principiati', -2), ('principiante', -3), ('principiarti', -4), ('principiasti', -5)]

>>> h = Hunspell(['es_ES'])
>>> h.suggest('teneis')
[('tenéis', 0), ('teneos', -2), ('tenes', -3), ('tenis', -4), ('tienes', -5), ('te neis', -6), ('te-neis', -7)]

>>> h.suggest('tenéis')[0]
('tenéis', 0)

>>> h = Hunspell(['en_US'])
>>> ('Camelot', 0) in h.suggest('camel') # Should work with aspell and hunspell
True

>>> h = Hunspell(['fr_FR'])
>>> h.suggest('differemmen')
[('différemment', 0)]

>>> h = Hunspell(['None'])
>>> h.suggest('camel')
[]

>>> h = Hunspell(['None', 'en_US'])
>>> ('Camelot', 0) in h.suggest('camel') # Should work with aspell and hunspell
True

>>> h = Hunspell(['en_US'])
>>> all((x, 0) in h.suggest('tree') for x in ('trees', 'treed'))
True

For benchmarking:

>>> result = [h.suggest(c) for c in 'abcdefghijklmnopqrstuvwxyz']
>>> result = [h.suggest(word) for word in ('infl', 'mess', 'tree', 'temp', 'wood', 'gard', 'came', 'wind', 'wate', 'succ', 'dict', 'load', 'enco', 'spell', 'word', 'auto', 'mode', 'bicy', 'moun', 'batt', 'tabl', 'star', 'moon', 'univ')]
z'Hunspell.suggest() input_phrase=%(ip)s
Zipr   Z/r.   :i    i   Nc              3   sl   "   T F*  p\         P                  ! \        P                  V4      x  K,  	  R # 5i)N)rB   rC   r/   rS   )Z.0r;   rs   r   Z	<genexpr>Z#Hunspell.suggest.<locals>.<genexpr>  s=      ) D  $--$@@!E E Ds   24c                 sJ    V ^,          ) \        V ^ ,          4      V ^ ,          3# )i   )r2   )r;   rM   r   Z<lambda>Z"Hunspell.suggest.<locals>.<lambda>
  s"    A$AaD	!r   )r   )r   r   r   rG   rB   rC   r/   rS   ro   r   r"   r#   r1   r0   r   r2   r$   ZcasefoldZ
startswithrJ   r}   r\   ZupdateZ	enumerateZmerge_dicts_maxZvaluesZitems	MAX_WORDS)r)   rz   Zsuggested_wordsrv   r   Zinput_phrase_no_accentsZqueryr<   ZstrippedZ
suggestionr;   Zsuffixed_suggestionsZextra_suggestionsZindexZsuggested_words_totalZsorted_suggestionss   &&              r   rR   ZHunspell.suggestf  s   Z ?LL:|**7346 sl2I",,00,@ 68,,J??D$&O!(((.6.E.E$%66z7J7JK/M+ |$
(?(??!,,, 7 @ @ B.8.C.CND'002==eDD>? 5d ; /D !- 5 5 7$.$4$4D#}}99%@@>? 5d ; %5 |$)!,,\:: ?@-l;
 +11F*G*L,*LJ!+!>!>z!JA<<
3 1!J *L ) , $)001EF) #55lC	)% .77H-I)%T-BB * 5 5 5 ( 7 7$.)1)B)B(2(;(;*=!> $;	!;
 EF 5j AFKaiL 5j A .Jc -z !) 8 8##%!'#!'')  "!E,s   -MM)ro   rn   rl   N)r-   )r5   r]   r^   r_   r`   rq   rp   ru   rx   rJ   r|   r~   ra   rb   rR   rc   rd   )r   s   @r   re   re   y  sw     ! !&H H / /6 666 6p 8A( A(` )h" *h"r   re   c                s    V ^8  d   QhRR/# r,   r-   )r   s   "r   r   r     s     % %d %r   c                 s   \         P                  ! \        P                  R7      p \         P                  ! R4      pV P                  V4       \        P                  \         P                  4       \        P                  V 4       \        '       d)   ^ RIp^ RIpVP                  4       pVP                  4        ^ RIpVP!                  4       w  rg\        '       dg   XP#                  4        XP%                  V4      pVP'                  4        VP)                  R4       VP+                  R^4       VP+                  R^4       \        P-                  R\.        P0                  P3                  4       4       \        P4                  ! V4       R# )up   
Used for testing and profiling.

“python3 hunspell_suggest.py”

runs some tests and prints profiling data.
)ZstreamzP%(asctime)s %(filename)s line %(lineno)d %(funcName)s %(levelname)s: %(message)sNZ
cumulativer:   r7   z(itb_util.remove_accents() cache info: %s)loggingZStreamHandlersysZstderrZ	FormatterZsetFormatterr   ZsetLevelZDEBUGZ
addHandler	BENCHMARKcProfilepstatsZProfileZenabledoctestZtestmodZdisableZStatsZ
strip_dirsZ
sort_statsZprint_statsZinfor/   r1   Z
cache_infoZexit)	Zlog_handlerZlog_formatterr   r   Zprofiler   ZfailedZ
_attemptedZstatss	            r   mainr     s    ''szz:K%%	M ]+
OOGMM"
k"y""$"??,VyW%&*b))R(
KK:''2246 HHVr   Z__main__)r`   Ztypingr    r   r   r   r   rk   r   rB   ra   r   r/   Z	getLoggerr   rj   r   r6   r8   r7   ZImportErrorr:   r3   r4   r   r   re   r   r   r5   r-   r   r   <module>r      s  *
      	 
    			0	1!f! "  $ $ 	"& 	p pf	V" V"p 	%N zF W 	~ %)"> 	 	~ 		s<   B !B; B8 B((B40B83B44B8;CC