completer.py 133 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850
  1. """Completion for IPython.
  2. This module started as fork of the rlcompleter module in the Python standard
  3. library. The original enhancements made to rlcompleter have been sent
  4. upstream and were accepted as of Python 2.3,
  5. This module now support a wide variety of completion mechanism both available
  6. for normal classic Python code, as well as completer for IPython specific
  7. Syntax like magics.
  8. Latex and Unicode completion
  9. ============================
  10. IPython and compatible frontends not only can complete your code, but can help
  11. you to input a wide range of characters. In particular we allow you to insert
  12. a unicode character using the tab completion mechanism.
  13. Forward latex/unicode completion
  14. --------------------------------
  15. Forward completion allows you to easily type a unicode character using its latex
  16. name, or unicode long description. To do so type a backslash follow by the
  17. relevant name and press tab:
  18. Using latex completion:
  19. .. code::
  20. \\alpha<tab>
  21. α
  22. or using unicode completion:
  23. .. code::
  24. \\GREEK SMALL LETTER ALPHA<tab>
  25. α
  26. Only valid Python identifiers will complete. Combining characters (like arrow or
  27. dots) are also available, unlike latex they need to be put after the their
  28. counterpart that is to say, ``F\\\\vec<tab>`` is correct, not ``\\\\vec<tab>F``.
  29. Some browsers are known to display combining characters incorrectly.
  30. Backward latex completion
  31. -------------------------
  32. It is sometime challenging to know how to type a character, if you are using
  33. IPython, or any compatible frontend you can prepend backslash to the character
  34. and press :kbd:`Tab` to expand it to its latex form.
  35. .. code::
  36. \\α<tab>
  37. \\alpha
  38. Both forward and backward completions can be deactivated by setting the
  39. :std:configtrait:`Completer.backslash_combining_completions` option to
  40. ``False``.
  41. Experimental
  42. ============
  43. Starting with IPython 6.0, this module can make use of the Jedi library to
  44. generate completions both using static analysis of the code, and dynamically
  45. inspecting multiple namespaces. Jedi is an autocompletion and static analysis
  46. for Python. The APIs attached to this new mechanism is unstable and will
  47. raise unless use in an :any:`provisionalcompleter` context manager.
  48. You will find that the following are experimental:
  49. - :any:`provisionalcompleter`
  50. - :any:`IPCompleter.completions`
  51. - :any:`Completion`
  52. - :any:`rectify_completions`
  53. .. note::
  54. better name for :any:`rectify_completions` ?
  55. We welcome any feedback on these new API, and we also encourage you to try this
  56. module in debug mode (start IPython with ``--Completer.debug=True``) in order
  57. to have extra logging information if :mod:`jedi` is crashing, or if current
  58. IPython completer pending deprecations are returning results not yet handled
  59. by :mod:`jedi`
  60. Using Jedi for tab completion allow snippets like the following to work without
  61. having to execute any code:
  62. >>> myvar = ['hello', 42]
  63. ... myvar[1].bi<tab>
  64. Tab completion will be able to infer that ``myvar[1]`` is a real number without
  65. executing almost any code unlike the deprecated :any:`IPCompleter.greedy`
  66. option.
  67. Be sure to update :mod:`jedi` to the latest stable version or to try the
  68. current development version to get better completions.
  69. Matchers
  70. ========
  71. All completions routines are implemented using unified *Matchers* API.
  72. The matchers API is provisional and subject to change without notice.
  73. The built-in matchers include:
  74. - :any:`IPCompleter.dict_key_matcher`: dictionary key completions,
  75. - :any:`IPCompleter.magic_matcher`: completions for magics,
  76. - :any:`IPCompleter.unicode_name_matcher`,
  77. :any:`IPCompleter.fwd_unicode_matcher`
  78. and :any:`IPCompleter.latex_name_matcher`: see `Forward latex/unicode completion`_,
  79. - :any:`back_unicode_name_matcher` and :any:`back_latex_name_matcher`: see `Backward latex completion`_,
  80. - :any:`IPCompleter.file_matcher`: paths to files and directories,
  81. - :any:`IPCompleter.python_func_kw_matcher` - function keywords,
  82. - :any:`IPCompleter.python_matches` - globals and attributes (v1 API),
  83. - ``IPCompleter.jedi_matcher`` - static analysis with Jedi,
  84. - :any:`IPCompleter.custom_completer_matcher` - pluggable completer with a default
  85. implementation in :any:`InteractiveShell` which uses IPython hooks system
  86. (`complete_command`) with string dispatch (including regular expressions).
  87. Differently to other matchers, ``custom_completer_matcher`` will not suppress
  88. Jedi results to match behaviour in earlier IPython versions.
  89. Custom matchers can be added by appending to ``IPCompleter.custom_matchers`` list.
  90. Matcher API
  91. -----------
  92. Simplifying some details, the ``Matcher`` interface can described as
  93. .. code-block::
  94. MatcherAPIv1 = Callable[[str], list[str]]
  95. MatcherAPIv2 = Callable[[CompletionContext], SimpleMatcherResult]
  96. Matcher = MatcherAPIv1 | MatcherAPIv2
  97. The ``MatcherAPIv1`` reflects the matcher API as available prior to IPython 8.6.0
  98. and remains supported as a simplest way for generating completions. This is also
  99. currently the only API supported by the IPython hooks system `complete_command`.
  100. To distinguish between matcher versions ``matcher_api_version`` attribute is used.
  101. More precisely, the API allows to omit ``matcher_api_version`` for v1 Matchers,
  102. and requires a literal ``2`` for v2 Matchers.
  103. Once the API stabilises future versions may relax the requirement for specifying
  104. ``matcher_api_version`` by switching to :func:`functools.singledispatch`, therefore
  105. please do not rely on the presence of ``matcher_api_version`` for any purposes.
  106. Suppression of competing matchers
  107. ---------------------------------
  108. By default results from all matchers are combined, in the order determined by
  109. their priority. Matchers can request to suppress results from subsequent
  110. matchers by setting ``suppress`` to ``True`` in the ``MatcherResult``.
  111. When multiple matchers simultaneously request suppression, the results from of
  112. the matcher with higher priority will be returned.
  113. Sometimes it is desirable to suppress most but not all other matchers;
  114. this can be achieved by adding a set of identifiers of matchers which
  115. should not be suppressed to ``MatcherResult`` under ``do_not_suppress`` key.
  116. The suppression behaviour can is user-configurable via
  117. :std:configtrait:`IPCompleter.suppress_competing_matchers`.
  118. """
  119. # Copyright (c) IPython Development Team.
  120. # Distributed under the terms of the Modified BSD License.
  121. #
  122. # Some of this code originated from rlcompleter in the Python standard library
  123. # Copyright (C) 2001 Python Software Foundation, www.python.org
  124. from __future__ import annotations
  125. import builtins as builtin_mod
  126. import enum
  127. import glob
  128. import inspect
  129. import itertools
  130. import keyword
  131. import ast
  132. import os
  133. import re
  134. import string
  135. import sys
  136. import tokenize
  137. import time
  138. import unicodedata
  139. import uuid
  140. import warnings
  141. from ast import literal_eval
  142. from collections import defaultdict
  143. from contextlib import contextmanager
  144. from dataclasses import dataclass
  145. from functools import cached_property, partial
  146. from types import SimpleNamespace
  147. from typing import (
  148. Union,
  149. Any,
  150. Optional,
  151. TYPE_CHECKING,
  152. TypeVar,
  153. Literal,
  154. )
  155. from collections.abc import Iterable, Iterator, Sequence, Sized
  156. from IPython.core.guarded_eval import (
  157. guarded_eval,
  158. EvaluationContext,
  159. _validate_policy_overrides,
  160. )
  161. from IPython.core.error import TryNext, UsageError
  162. from IPython.core.inputtransformer2 import ESC_MAGIC
  163. from IPython.core.latex_symbols import latex_symbols, reverse_latex_symbol
  164. from IPython.testing.skipdoctest import skip_doctest
  165. from IPython.utils import generics
  166. from IPython.utils.PyColorize import theme_table
  167. from IPython.utils.decorators import sphinx_options
  168. from IPython.utils.dir2 import dir2, get_real_method
  169. from IPython.utils.path import ensure_dir_exists
  170. from IPython.utils.process import arg_split
  171. from traitlets import (
  172. Bool,
  173. Enum,
  174. Int,
  175. List as ListTrait,
  176. Unicode,
  177. Dict as DictTrait,
  178. DottedObjectName,
  179. Union as UnionTrait,
  180. observe,
  181. )
  182. from traitlets.config.configurable import Configurable
  183. from traitlets.utils.importstring import import_item
  184. import __main__
  185. from typing import cast
  186. from typing import TypedDict, NotRequired, Protocol, TypeAlias, TypeGuard
  187. # skip module docstests
  188. __skip_doctest__ = True
  189. try:
  190. import jedi
  191. jedi.settings.case_insensitive_completion = False
  192. import jedi.api.helpers
  193. import jedi.api.classes
  194. JEDI_INSTALLED = True
  195. except ImportError:
  196. JEDI_INSTALLED = False
  197. # -----------------------------------------------------------------------------
  198. # Globals
  199. #-----------------------------------------------------------------------------
  200. # ranges where we have most of the valid unicode names. We could be more finer
  201. # grained but is it worth it for performance While unicode have character in the
  202. # range 0, 0x110000, we seem to have name for about 10% of those. (131808 as I
  203. # write this). With below range we cover them all, with a density of ~67%
  204. # biggest next gap we consider only adds up about 1% density and there are 600
  205. # gaps that would need hard coding.
  206. _UNICODE_RANGES = [(32, 0x3347A), (0xE0001, 0xE01F0)]
  207. # Public API
  208. __all__ = ["Completer", "IPCompleter"]
  209. if sys.platform == 'win32':
  210. PROTECTABLES = ' '
  211. else:
  212. PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
  213. # Protect against returning an enormous number of completions which the frontend
  214. # may have trouble processing.
  215. MATCHES_LIMIT = 500
  216. # Completion type reported when no type can be inferred.
  217. _UNKNOWN_TYPE = "<unknown>"
  218. # sentinel value to signal lack of a match
  219. not_found = object()
  220. class ProvisionalCompleterWarning(FutureWarning):
  221. """
  222. Exception raise by an experimental feature in this module.
  223. Wrap code in :any:`provisionalcompleter` context manager if you
  224. are certain you want to use an unstable feature.
  225. """
  226. pass
  227. warnings.filterwarnings('error', category=ProvisionalCompleterWarning)
  228. @skip_doctest
  229. @contextmanager
  230. def provisionalcompleter(action='ignore'):
  231. """
  232. This context manager has to be used in any place where unstable completer
  233. behavior and API may be called.
  234. >>> with provisionalcompleter():
  235. ... completer.do_experimental_things() # works
  236. >>> completer.do_experimental_things() # raises.
  237. .. note::
  238. Unstable
  239. By using this context manager you agree that the API in use may change
  240. without warning, and that you won't complain if they do so.
  241. You also understand that, if the API is not to your liking, you should report
  242. a bug to explain your use case upstream.
  243. We'll be happy to get your feedback, feature requests, and improvements on
  244. any of the unstable APIs!
  245. """
  246. with warnings.catch_warnings():
  247. warnings.filterwarnings(action, category=ProvisionalCompleterWarning)
  248. yield
  249. def has_open_quotes(s: str) -> Union[str, bool]:
  250. """Return whether a string has open quotes.
  251. This simply counts whether the number of quote characters of either type in
  252. the string is odd.
  253. Returns
  254. -------
  255. If there is an open quote, the quote character is returned. Else, return
  256. False.
  257. """
  258. # We check " first, then ', so complex cases with nested quotes will get
  259. # the " to take precedence.
  260. if s.count('"') % 2:
  261. return '"'
  262. elif s.count("'") % 2:
  263. return "'"
  264. else:
  265. return False
  266. def protect_filename(s: str, protectables: str = PROTECTABLES) -> str:
  267. """Escape a string to protect certain characters."""
  268. if set(s) & set(protectables):
  269. if sys.platform == "win32":
  270. return '"' + s + '"'
  271. else:
  272. return "".join(("\\" + c if c in protectables else c) for c in s)
  273. else:
  274. return s
  275. def expand_user(path: str) -> tuple[str, bool, str]:
  276. """Expand ``~``-style usernames in strings.
  277. This is similar to :func:`os.path.expanduser`, but it computes and returns
  278. extra information that will be useful if the input was being used in
  279. computing completions, and you wish to return the completions with the
  280. original '~' instead of its expanded value.
  281. Parameters
  282. ----------
  283. path : str
  284. String to be expanded. If no ~ is present, the output is the same as the
  285. input.
  286. Returns
  287. -------
  288. newpath : str
  289. Result of ~ expansion in the input path.
  290. tilde_expand : bool
  291. Whether any expansion was performed or not.
  292. tilde_val : str
  293. The value that ~ was replaced with.
  294. """
  295. # Default values
  296. tilde_expand = False
  297. tilde_val = ''
  298. newpath = path
  299. if path.startswith('~'):
  300. tilde_expand = True
  301. rest = len(path)-1
  302. newpath = os.path.expanduser(path)
  303. if rest:
  304. tilde_val = newpath[:-rest]
  305. else:
  306. tilde_val = newpath
  307. return newpath, tilde_expand, tilde_val
  308. def compress_user(path:str, tilde_expand:bool, tilde_val:str) -> str:
  309. """Does the opposite of expand_user, with its outputs.
  310. """
  311. if tilde_expand:
  312. return path.replace(tilde_val, '~')
  313. else:
  314. return path
  315. def completions_sorting_key(word):
  316. """key for sorting completions
  317. This does several things:
  318. - Demote any completions starting with underscores to the end
  319. - Insert any %magic and %%cellmagic completions in the alphabetical order
  320. by their name
  321. """
  322. prio1, prio2 = 0, 0
  323. if word.startswith('__'):
  324. prio1 = 2
  325. elif word.startswith('_'):
  326. prio1 = 1
  327. if word.endswith('='):
  328. prio1 = -1
  329. if word.startswith('%%'):
  330. # If there's another % in there, this is something else, so leave it alone
  331. if "%" not in word[2:]:
  332. word = word[2:]
  333. prio2 = 2
  334. elif word.startswith('%'):
  335. if "%" not in word[1:]:
  336. word = word[1:]
  337. prio2 = 1
  338. return prio1, word, prio2
  339. class _FakeJediCompletion:
  340. """
  341. This is a workaround to communicate to the UI that Jedi has crashed and to
  342. report a bug. Will be used only id :any:`IPCompleter.debug` is set to true.
  343. Added in IPython 6.0 so should likely be removed for 7.0
  344. """
  345. def __init__(self, name):
  346. self.name = name
  347. self.complete = name
  348. self.type = 'crashed'
  349. self.name_with_symbols = name
  350. self.signature = ""
  351. self._origin = "fake"
  352. self.text = "crashed"
  353. def __repr__(self):
  354. return '<Fake completion object jedi has crashed>'
  355. _JediCompletionLike = Union["jedi.api.Completion", _FakeJediCompletion]
  356. class Completion:
  357. """
  358. Completion object used and returned by IPython completers.
  359. .. warning::
  360. Unstable
  361. This function is unstable, API may change without warning.
  362. It will also raise unless use in proper context manager.
  363. This act as a middle ground :any:`Completion` object between the
  364. :class:`jedi.api.classes.Completion` object and the Prompt Toolkit completion
  365. object. While Jedi need a lot of information about evaluator and how the
  366. code should be ran/inspected, PromptToolkit (and other frontend) mostly
  367. need user facing information.
  368. - Which range should be replaced replaced by what.
  369. - Some metadata (like completion type), or meta information to displayed to
  370. the use user.
  371. For debugging purpose we can also store the origin of the completion (``jedi``,
  372. ``IPython.python_matches``, ``IPython.magics_matches``...).
  373. """
  374. __slots__ = ['start', 'end', 'text', 'type', 'signature', '_origin']
  375. def __init__(
  376. self,
  377. start: int,
  378. end: int,
  379. text: str,
  380. *,
  381. type: Optional[str] = None,
  382. _origin="",
  383. signature="",
  384. ) -> None:
  385. warnings.warn(
  386. "``Completion`` is a provisional API (as of IPython 6.0). "
  387. "It may change without warnings. "
  388. "Use in corresponding context manager.",
  389. category=ProvisionalCompleterWarning,
  390. stacklevel=2,
  391. )
  392. self.start = start
  393. self.end = end
  394. self.text = text
  395. self.type = type
  396. self.signature = signature
  397. self._origin = _origin
  398. def __repr__(self):
  399. return '<Completion start=%s end=%s text=%r type=%r, signature=%r,>' % \
  400. (self.start, self.end, self.text, self.type or '?', self.signature or '?')
  401. def __eq__(self, other) -> bool:
  402. """
  403. Equality and hash do not hash the type (as some completer may not be
  404. able to infer the type), but are use to (partially) de-duplicate
  405. completion.
  406. Completely de-duplicating completion is a bit tricker that just
  407. comparing as it depends on surrounding text, which Completions are not
  408. aware of.
  409. """
  410. return self.start == other.start and \
  411. self.end == other.end and \
  412. self.text == other.text
  413. def __hash__(self):
  414. return hash((self.start, self.end, self.text))
  415. class SimpleCompletion:
  416. """Completion item to be included in the dictionary returned by new-style Matcher (API v2).
  417. .. warning::
  418. Provisional
  419. This class is used to describe the currently supported attributes of
  420. simple completion items, and any additional implementation details
  421. should not be relied on. Additional attributes may be included in
  422. future versions, and meaning of text disambiguated from the current
  423. dual meaning of "text to insert" and "text to used as a label".
  424. """
  425. __slots__ = ["text", "type"]
  426. def __init__(self, text: str, *, type: Optional[str] = None):
  427. self.text = text
  428. self.type = type
  429. def __repr__(self):
  430. return f"<SimpleCompletion text={self.text!r} type={self.type!r}>"
  431. class _MatcherResultBase(TypedDict):
  432. """Definition of dictionary to be returned by new-style Matcher (API v2)."""
  433. #: Suffix of the provided ``CompletionContext.token``, if not given defaults to full token.
  434. matched_fragment: NotRequired[str]
  435. #: Whether to suppress results from all other matchers (True), some
  436. #: matchers (set of identifiers) or none (False); default is False.
  437. suppress: NotRequired[Union[bool, set[str]]]
  438. #: Identifiers of matchers which should NOT be suppressed when this matcher
  439. #: requests to suppress all other matchers; defaults to an empty set.
  440. do_not_suppress: NotRequired[set[str]]
  441. #: Are completions already ordered and should be left as-is? default is False.
  442. ordered: NotRequired[bool]
  443. @sphinx_options(show_inherited_members=True, exclude_inherited_from=["dict"])
  444. class SimpleMatcherResult(_MatcherResultBase, TypedDict):
  445. """Result of new-style completion matcher."""
  446. # note: TypedDict is added again to the inheritance chain
  447. # in order to get __orig_bases__ for documentation
  448. #: List of candidate completions
  449. completions: Sequence[SimpleCompletion] | Iterator[SimpleCompletion]
  450. class _JediMatcherResult(_MatcherResultBase):
  451. """Matching result returned by Jedi (will be processed differently)"""
  452. #: list of candidate completions
  453. completions: Iterator[_JediCompletionLike]
  454. AnyMatcherCompletion = Union[_JediCompletionLike, SimpleCompletion]
  455. AnyCompletion = TypeVar("AnyCompletion", AnyMatcherCompletion, Completion)
  456. @dataclass
  457. class CompletionContext:
  458. """Completion context provided as an argument to matchers in the Matcher API v2."""
  459. # rationale: many legacy matchers relied on completer state (`self.text_until_cursor`)
  460. # which was not explicitly visible as an argument of the matcher, making any refactor
  461. # prone to errors; by explicitly passing `cursor_position` we can decouple the matchers
  462. # from the completer, and make substituting them in sub-classes easier.
  463. #: Relevant fragment of code directly preceding the cursor.
  464. #: The extraction of token is implemented via splitter heuristic
  465. #: (following readline behaviour for legacy reasons), which is user configurable
  466. #: (by switching the greedy mode).
  467. token: str
  468. #: The full available content of the editor or buffer
  469. full_text: str
  470. #: Cursor position in the line (the same for ``full_text`` and ``text``).
  471. cursor_position: int
  472. #: Cursor line in ``full_text``.
  473. cursor_line: int
  474. #: The maximum number of completions that will be used downstream.
  475. #: Matchers can use this information to abort early.
  476. #: The built-in Jedi matcher is currently excepted from this limit.
  477. # If not given, return all possible completions.
  478. limit: Optional[int]
  479. @cached_property
  480. def text_until_cursor(self) -> str:
  481. return self.line_with_cursor[: self.cursor_position]
  482. @cached_property
  483. def line_with_cursor(self) -> str:
  484. return self.full_text.split("\n")[self.cursor_line]
  485. #: Matcher results for API v2.
  486. MatcherResult = Union[SimpleMatcherResult, _JediMatcherResult]
  487. class _MatcherAPIv1Base(Protocol):
  488. def __call__(self, text: str) -> list[str]:
  489. """Call signature."""
  490. ...
  491. #: Used to construct the default matcher identifier
  492. __qualname__: str
  493. class _MatcherAPIv1Total(_MatcherAPIv1Base, Protocol):
  494. #: API version
  495. matcher_api_version: Optional[Literal[1]]
  496. def __call__(self, text: str) -> list[str]:
  497. """Call signature."""
  498. ...
  499. #: Protocol describing Matcher API v1.
  500. MatcherAPIv1: TypeAlias = Union[_MatcherAPIv1Base, _MatcherAPIv1Total]
  501. class MatcherAPIv2(Protocol):
  502. """Protocol describing Matcher API v2."""
  503. #: API version
  504. matcher_api_version: Literal[2] = 2
  505. def __call__(self, context: CompletionContext) -> MatcherResult:
  506. """Call signature."""
  507. ...
  508. #: Used to construct the default matcher identifier
  509. __qualname__: str
  510. Matcher: TypeAlias = Union[MatcherAPIv1, MatcherAPIv2]
  511. def _is_matcher_v1(matcher: Matcher) -> TypeGuard[MatcherAPIv1]:
  512. api_version = _get_matcher_api_version(matcher)
  513. return api_version == 1
  514. def _is_matcher_v2(matcher: Matcher) -> TypeGuard[MatcherAPIv2]:
  515. api_version = _get_matcher_api_version(matcher)
  516. return api_version == 2
  517. def _is_sizable(value: Any) -> TypeGuard[Sized]:
  518. """Determines whether objects is sizable"""
  519. return hasattr(value, "__len__")
  520. def _is_iterator(value: Any) -> TypeGuard[Iterator]:
  521. """Determines whether objects is sizable"""
  522. return hasattr(value, "__next__")
  523. def has_any_completions(result: MatcherResult) -> bool:
  524. """Check if any result includes any completions."""
  525. completions = result["completions"]
  526. if _is_sizable(completions):
  527. return len(completions) != 0
  528. if _is_iterator(completions):
  529. try:
  530. old_iterator = completions
  531. first = next(old_iterator)
  532. result["completions"] = cast(
  533. Iterator[SimpleCompletion],
  534. itertools.chain([first], old_iterator),
  535. )
  536. return True
  537. except StopIteration:
  538. return False
  539. raise ValueError(
  540. "Completions returned by matcher need to be an Iterator or a Sizable"
  541. )
  542. def completion_matcher(
  543. *,
  544. priority: Optional[float] = None,
  545. identifier: Optional[str] = None,
  546. api_version: int = 1,
  547. ) -> Callable[[Matcher], Matcher]:
  548. """Adds attributes describing the matcher.
  549. Parameters
  550. ----------
  551. priority : Optional[float]
  552. The priority of the matcher, determines the order of execution of matchers.
  553. Higher priority means that the matcher will be executed first. Defaults to 0.
  554. identifier : Optional[str]
  555. identifier of the matcher allowing users to modify the behaviour via traitlets,
  556. and also used to for debugging (will be passed as ``origin`` with the completions).
  557. Defaults to matcher function's ``__qualname__`` (for example,
  558. ``IPCompleter.file_matcher`` for the built-in matched defined
  559. as a ``file_matcher`` method of the ``IPCompleter`` class).
  560. api_version: Optional[int]
  561. version of the Matcher API used by this matcher.
  562. Currently supported values are 1 and 2.
  563. Defaults to 1.
  564. """
  565. def wrapper(func: Matcher):
  566. func.matcher_priority = priority or 0 # type: ignore
  567. func.matcher_identifier = identifier or func.__qualname__ # type: ignore
  568. func.matcher_api_version = api_version # type: ignore
  569. if TYPE_CHECKING:
  570. if api_version == 1:
  571. func = cast(MatcherAPIv1, func)
  572. elif api_version == 2:
  573. func = cast(MatcherAPIv2, func)
  574. return func
  575. return wrapper
  576. def _get_matcher_priority(matcher: Matcher):
  577. return getattr(matcher, "matcher_priority", 0)
  578. def _get_matcher_id(matcher: Matcher):
  579. return getattr(matcher, "matcher_identifier", matcher.__qualname__)
  580. def _get_matcher_api_version(matcher):
  581. return getattr(matcher, "matcher_api_version", 1)
  582. context_matcher = partial(completion_matcher, api_version=2)
  583. _IC = Iterable[Completion]
  584. def _deduplicate_completions(text: str, completions: _IC)-> _IC:
  585. """
  586. Deduplicate a set of completions.
  587. .. warning::
  588. Unstable
  589. This function is unstable, API may change without warning.
  590. Parameters
  591. ----------
  592. text : str
  593. text that should be completed.
  594. completions : Iterator[Completion]
  595. iterator over the completions to deduplicate
  596. Yields
  597. ------
  598. `Completions` objects
  599. Completions coming from multiple sources, may be different but end up having
  600. the same effect when applied to ``text``. If this is the case, this will
  601. consider completions as equal and only emit the first encountered.
  602. Not folded in `completions()` yet for debugging purpose, and to detect when
  603. the IPython completer does return things that Jedi does not, but should be
  604. at some point.
  605. """
  606. completions = list(completions)
  607. if not completions:
  608. return
  609. new_start = min(c.start for c in completions)
  610. new_end = max(c.end for c in completions)
  611. seen = set()
  612. for c in completions:
  613. new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
  614. if new_text not in seen:
  615. yield c
  616. seen.add(new_text)
  617. def rectify_completions(text: str, completions: _IC, *, _debug: bool = False) -> _IC:
  618. """
  619. Rectify a set of completions to all have the same ``start`` and ``end``
  620. .. warning::
  621. Unstable
  622. This function is unstable, API may change without warning.
  623. It will also raise unless use in proper context manager.
  624. Parameters
  625. ----------
  626. text : str
  627. text that should be completed.
  628. completions : Iterator[Completion]
  629. iterator over the completions to rectify
  630. _debug : bool
  631. Log failed completion
  632. Notes
  633. -----
  634. :class:`jedi.api.classes.Completion` s returned by Jedi may not have the same start and end, though
  635. the Jupyter Protocol requires them to behave like so. This will readjust
  636. the completion to have the same ``start`` and ``end`` by padding both
  637. extremities with surrounding text.
  638. During stabilisation should support a ``_debug`` option to log which
  639. completion are return by the IPython completer and not found in Jedi in
  640. order to make upstream bug report.
  641. """
  642. warnings.warn("`rectify_completions` is a provisional API (as of IPython 6.0). "
  643. "It may change without warnings. "
  644. "Use in corresponding context manager.",
  645. category=ProvisionalCompleterWarning, stacklevel=2)
  646. completions = list(completions)
  647. if not completions:
  648. return
  649. starts = (c.start for c in completions)
  650. ends = (c.end for c in completions)
  651. new_start = min(starts)
  652. new_end = max(ends)
  653. seen_jedi = set()
  654. seen_python_matches = set()
  655. for c in completions:
  656. new_text = text[new_start:c.start] + c.text + text[c.end:new_end]
  657. if c._origin == 'jedi':
  658. seen_jedi.add(new_text)
  659. elif c._origin == "IPCompleter.python_matcher":
  660. seen_python_matches.add(new_text)
  661. yield Completion(new_start, new_end, new_text, type=c.type, _origin=c._origin, signature=c.signature)
  662. diff = seen_python_matches.difference(seen_jedi)
  663. if diff and _debug:
  664. print('IPython.python matches have extras:', diff)
  665. if sys.platform == 'win32':
  666. DELIMS = ' \t\n`!@#$^&*()=+[{]}|;\'",<>?'
  667. else:
  668. DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
  669. GREEDY_DELIMS = ' =\r\n'
  670. class CompletionSplitter:
  671. """An object to split an input line in a manner similar to readline.
  672. By having our own implementation, we can expose readline-like completion in
  673. a uniform manner to all frontends. This object only needs to be given the
  674. line of text to be split and the cursor position on said line, and it
  675. returns the 'word' to be completed on at the cursor after splitting the
  676. entire line.
  677. What characters are used as splitting delimiters can be controlled by
  678. setting the ``delims`` attribute (this is a property that internally
  679. automatically builds the necessary regular expression)"""
  680. # Private interface
  681. # A string of delimiter characters. The default value makes sense for
  682. # IPython's most typical usage patterns.
  683. _delims = DELIMS
  684. # The expression (a normal string) to be compiled into a regular expression
  685. # for actual splitting. We store it as an attribute mostly for ease of
  686. # debugging, since this type of code can be so tricky to debug.
  687. _delim_expr = None
  688. # The regular expression that does the actual splitting
  689. _delim_re = None
  690. def __init__(self, delims=None):
  691. delims = CompletionSplitter._delims if delims is None else delims
  692. self.delims = delims
  693. @property
  694. def delims(self):
  695. """Return the string of delimiter characters."""
  696. return self._delims
  697. @delims.setter
  698. def delims(self, delims):
  699. """Set the delimiters for line splitting."""
  700. expr = '[' + ''.join('\\'+ c for c in delims) + ']'
  701. self._delim_re = re.compile(expr)
  702. self._delims = delims
  703. self._delim_expr = expr
  704. def split_line(self, line, cursor_pos=None):
  705. """Split a line of text with a cursor at the given position.
  706. """
  707. cut_line = line if cursor_pos is None else line[:cursor_pos]
  708. return self._delim_re.split(cut_line)[-1]
  709. class Completer(Configurable):
  710. greedy = Bool(
  711. False,
  712. help="""Activate greedy completion.
  713. .. deprecated:: 8.8
  714. Use :std:configtrait:`Completer.evaluation` and :std:configtrait:`Completer.auto_close_dict_keys` instead.
  715. When enabled in IPython 8.8 or newer, changes configuration as follows:
  716. - ``Completer.evaluation = 'unsafe'``
  717. - ``Completer.auto_close_dict_keys = True``
  718. """,
  719. ).tag(config=True)
  720. evaluation = Enum(
  721. ("forbidden", "minimal", "limited", "unsafe", "dangerous"),
  722. default_value="limited",
  723. help="""Policy for code evaluation under completion.
  724. Successive options allow to enable more eager evaluation for better
  725. completion suggestions, including for nested dictionaries, nested lists,
  726. or even results of function calls.
  727. Setting ``unsafe`` or higher can lead to evaluation of arbitrary user
  728. code on :kbd:`Tab` with potentially unwanted or dangerous side effects.
  729. Allowed values are:
  730. - ``forbidden``: no evaluation of code is permitted,
  731. - ``minimal``: evaluation of literals and access to built-in namespace;
  732. no item/attribute evaluation, no access to locals/globals,
  733. no evaluation of any operations or comparisons.
  734. - ``limited``: access to all namespaces, evaluation of hard-coded methods
  735. (for example: :py:meth:`dict.keys`, :py:meth:`object.__getattr__`,
  736. :py:meth:`object.__getitem__`) on allow-listed objects (for example:
  737. :py:class:`dict`, :py:class:`list`, :py:class:`tuple`, ``pandas.Series``),
  738. - ``unsafe``: evaluation of all methods and function calls but not of
  739. syntax with side-effects like `del x`,
  740. - ``dangerous``: completely arbitrary evaluation; does not support auto-import.
  741. To override specific elements of the policy, you can use ``policy_overrides`` trait.
  742. """,
  743. ).tag(config=True)
  744. use_jedi = Bool(default_value=JEDI_INSTALLED,
  745. help="Experimental: Use Jedi to generate autocompletions. "
  746. "Default to True if jedi is installed.").tag(config=True)
  747. jedi_compute_type_timeout = Int(default_value=400,
  748. help="""Experimental: restrict time (in milliseconds) during which Jedi can compute types.
  749. Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt
  750. performance by preventing jedi to build its cache.
  751. """).tag(config=True)
  752. debug = Bool(default_value=False,
  753. help='Enable debug for the Completer. Mostly print extra '
  754. 'information for experimental jedi integration.')\
  755. .tag(config=True)
  756. backslash_combining_completions = Bool(True,
  757. help="Enable unicode completions, e.g. \\alpha<tab> . "
  758. "Includes completion of latex commands, unicode names, and expanding "
  759. "unicode characters back to latex commands.").tag(config=True)
  760. auto_close_dict_keys = Bool(
  761. False,
  762. help="""
  763. Enable auto-closing dictionary keys.
  764. When enabled string keys will be suffixed with a final quote
  765. (matching the opening quote), tuple keys will also receive a
  766. separating comma if needed, and keys which are final will
  767. receive a closing bracket (``]``).
  768. """,
  769. ).tag(config=True)
  770. policy_overrides = DictTrait(
  771. default_value={},
  772. key_trait=Unicode(),
  773. help="""Overrides for policy evaluation.
  774. For example, to enable auto-import on completion specify:
  775. .. code-block::
  776. ipython --Completer.policy_overrides='{"allow_auto_import": True}' --Completer.use_jedi=False
  777. """,
  778. ).tag(config=True)
  779. @observe("evaluation")
  780. def _evaluation_changed(self, _change):
  781. _validate_policy_overrides(
  782. policy_name=self.evaluation, policy_overrides=self.policy_overrides
  783. )
  784. @observe("policy_overrides")
  785. def _policy_overrides_changed(self, _change):
  786. _validate_policy_overrides(
  787. policy_name=self.evaluation, policy_overrides=self.policy_overrides
  788. )
  789. auto_import_method = DottedObjectName(
  790. default_value="importlib.import_module",
  791. allow_none=True,
  792. help="""\
  793. Provisional:
  794. This is a provisional API in IPython 9.3, it may change without warnings.
  795. A fully qualified path to an auto-import method for use by completer.
  796. The function should take a single string and return `ModuleType` and
  797. can raise `ImportError` exception if module is not found.
  798. The default auto-import implementation does not populate the user namespace with the imported module.
  799. """,
  800. ).tag(config=True)
  801. def __init__(self, namespace=None, global_namespace=None, **kwargs):
  802. """Create a new completer for the command line.
  803. Completer(namespace=ns, global_namespace=ns2) -> completer instance.
  804. If unspecified, the default namespace where completions are performed
  805. is __main__ (technically, __main__.__dict__). Namespaces should be
  806. given as dictionaries.
  807. An optional second namespace can be given. This allows the completer
  808. to handle cases where both the local and global scopes need to be
  809. distinguished.
  810. """
  811. # Don't bind to namespace quite yet, but flag whether the user wants a
  812. # specific namespace or to use __main__.__dict__. This will allow us
  813. # to bind to __main__.__dict__ at completion time, not now.
  814. if namespace is None:
  815. self.use_main_ns = True
  816. else:
  817. self.use_main_ns = False
  818. self.namespace = namespace
  819. # The global namespace, if given, can be bound directly
  820. if global_namespace is None:
  821. self.global_namespace = {}
  822. else:
  823. self.global_namespace = global_namespace
  824. self.custom_matchers = []
  825. super(Completer, self).__init__(**kwargs)
  826. def complete(self, text, state):
  827. """Return the next possible completion for 'text'.
  828. This is called successively with state == 0, 1, 2, ... until it
  829. returns None. The completion should begin with 'text'.
  830. """
  831. if self.use_main_ns:
  832. self.namespace = __main__.__dict__
  833. if state == 0:
  834. if "." in text:
  835. self.matches = self.attr_matches(text)
  836. else:
  837. self.matches = self.global_matches(text)
  838. try:
  839. return self.matches[state]
  840. except IndexError:
  841. return None
  842. def global_matches(self, text: str, context: Optional[CompletionContext] = None):
  843. """Compute matches when text is a simple name.
  844. Return a list of all keywords, built-in functions and names currently
  845. defined in self.namespace or self.global_namespace that match.
  846. """
  847. matches = []
  848. match_append = matches.append
  849. n = len(text)
  850. search_lists = [
  851. keyword.kwlist,
  852. builtin_mod.__dict__.keys(),
  853. list(self.namespace.keys()),
  854. list(self.global_namespace.keys()),
  855. ]
  856. if context and context.full_text.count("\n") > 1:
  857. # try to evaluate on full buffer
  858. previous_lines = "\n".join(
  859. context.full_text.split("\n")[: context.cursor_line]
  860. )
  861. if previous_lines:
  862. all_code_lines_before_cursor = (
  863. self._extract_code(previous_lines) + "\n" + text
  864. )
  865. context = EvaluationContext(
  866. globals=self.global_namespace,
  867. locals=self.namespace,
  868. evaluation=self.evaluation,
  869. auto_import=self._auto_import,
  870. policy_overrides=self.policy_overrides,
  871. )
  872. try:
  873. obj = guarded_eval(
  874. all_code_lines_before_cursor,
  875. context,
  876. )
  877. except Exception as e:
  878. if self.debug:
  879. warnings.warn(f"Evaluation exception {e}")
  880. search_lists.append(list(context.transient_locals.keys()))
  881. for lst in search_lists:
  882. for word in lst:
  883. if word[:n] == text and word != "__builtins__":
  884. match_append(word)
  885. snake_case_re = re.compile(r"[^_]+(_[^_]+)+?\Z")
  886. for lst in [list(self.namespace.keys()), list(self.global_namespace.keys())]:
  887. shortened = {
  888. "_".join([sub[0] for sub in word.split("_")]): word
  889. for word in lst
  890. if snake_case_re.match(word)
  891. }
  892. for word in shortened.keys():
  893. if word[:n] == text and word != "__builtins__":
  894. match_append(shortened[word])
  895. return matches
  896. def attr_matches(self, text):
  897. """Compute matches when text contains a dot.
  898. Assuming the text is of the form NAME.NAME....[NAME], and is
  899. evaluatable in self.namespace or self.global_namespace, it will be
  900. evaluated and its attributes (as revealed by dir()) are used as
  901. possible completions. (For class instances, class members are
  902. also considered.)
  903. WARNING: this can still invoke arbitrary C code, if an object
  904. with a __getattr__ hook is evaluated.
  905. """
  906. return self._attr_matches(text)[0]
  907. # we simple attribute matching with normal identifiers.
  908. _ATTR_MATCH_RE = re.compile(r"(.+)\.(\w*)$")
  909. def _strip_code_before_operator(self, code: str) -> str:
  910. o_parens = {"(", "[", "{"}
  911. c_parens = {")", "]", "}"}
  912. # Dry-run tokenize to catch errors
  913. try:
  914. _ = list(tokenize.generate_tokens(iter(code.splitlines()).__next__))
  915. except tokenize.TokenError:
  916. # Try trimming the expression and retrying
  917. trimmed_code = self._trim_expr(code)
  918. try:
  919. _ = list(
  920. tokenize.generate_tokens(iter(trimmed_code.splitlines()).__next__)
  921. )
  922. code = trimmed_code
  923. except tokenize.TokenError:
  924. return code
  925. tokens = _parse_tokens(code)
  926. encountered_operator = False
  927. after_operator = []
  928. nesting_level = 0
  929. for t in tokens:
  930. if t.type == tokenize.OP:
  931. if t.string in o_parens:
  932. nesting_level += 1
  933. elif t.string in c_parens:
  934. nesting_level -= 1
  935. elif t.string != "." and nesting_level == 0:
  936. encountered_operator = True
  937. after_operator = []
  938. continue
  939. if encountered_operator:
  940. after_operator.append(t.string)
  941. if encountered_operator:
  942. return "".join(after_operator)
  943. else:
  944. return code
  945. def _extract_code(self, line: str):
  946. """No-op in Completer, but can be used in subclasses to customise behaviour"""
  947. return line
  948. def _attr_matches(
  949. self,
  950. text: str,
  951. include_prefix: bool = True,
  952. context: Optional[CompletionContext] = None,
  953. ) -> tuple[Sequence[str], str]:
  954. m2 = self._ATTR_MATCH_RE.match(text)
  955. if not m2:
  956. return [], ""
  957. expr, attr = m2.group(1, 2)
  958. try:
  959. expr = self._strip_code_before_operator(expr)
  960. except tokenize.TokenError:
  961. pass
  962. obj = self._evaluate_expr(expr)
  963. if obj is not_found:
  964. if context:
  965. # try to evaluate on full buffer
  966. previous_lines = "\n".join(
  967. context.full_text.split("\n")[: context.cursor_line]
  968. )
  969. if previous_lines:
  970. all_code_lines_before_cursor = (
  971. self._extract_code(previous_lines) + "\n" + expr
  972. )
  973. obj = self._evaluate_expr(all_code_lines_before_cursor)
  974. if obj is not_found:
  975. return [], ""
  976. if self.limit_to__all__ and hasattr(obj, '__all__'):
  977. words = get__all__entries(obj)
  978. else:
  979. words = dir2(obj)
  980. try:
  981. words = generics.complete_object(obj, words)
  982. except TryNext:
  983. pass
  984. except AssertionError:
  985. raise
  986. except Exception:
  987. # Silence errors from completion function
  988. pass
  989. # Build match list to return
  990. n = len(attr)
  991. # Note: ideally we would just return words here and the prefix
  992. # reconciliator would know that we intend to append to rather than
  993. # replace the input text; this requires refactoring to return range
  994. # which ought to be replaced (as does jedi).
  995. if include_prefix:
  996. tokens = _parse_tokens(expr)
  997. rev_tokens = reversed(tokens)
  998. skip_over = {tokenize.ENDMARKER, tokenize.NEWLINE}
  999. name_turn = True
  1000. parts = []
  1001. for token in rev_tokens:
  1002. if token.type in skip_over:
  1003. continue
  1004. if token.type == tokenize.NAME and name_turn:
  1005. parts.append(token.string)
  1006. name_turn = False
  1007. elif (
  1008. token.type == tokenize.OP and token.string == "." and not name_turn
  1009. ):
  1010. parts.append(token.string)
  1011. name_turn = True
  1012. else:
  1013. # short-circuit if not empty nor name token
  1014. break
  1015. prefix_after_space = "".join(reversed(parts))
  1016. else:
  1017. prefix_after_space = ""
  1018. return (
  1019. ["%s.%s" % (prefix_after_space, w) for w in words if w[:n] == attr],
  1020. "." + attr,
  1021. )
  1022. def _trim_expr(self, code: str) -> str:
  1023. """
  1024. Trim the code until it is a valid expression and not a tuple;
  1025. return the trimmed expression for guarded_eval.
  1026. """
  1027. while code:
  1028. code = code[1:]
  1029. try:
  1030. res = ast.parse(code)
  1031. except SyntaxError:
  1032. continue
  1033. assert res is not None
  1034. if len(res.body) != 1:
  1035. continue
  1036. if not isinstance(res.body[0], ast.Expr):
  1037. continue
  1038. expr = res.body[0].value
  1039. if isinstance(expr, ast.Tuple) and not code[-1] == ")":
  1040. # we skip implicit tuple, like when trimming `fun(a,b`<completion>
  1041. # as `a,b` would be a tuple, and we actually expect to get only `b`
  1042. continue
  1043. return code
  1044. return ""
  1045. def _evaluate_expr(self, expr):
  1046. obj = not_found
  1047. done = False
  1048. while not done and expr:
  1049. try:
  1050. obj = guarded_eval(
  1051. expr,
  1052. EvaluationContext(
  1053. globals=self.global_namespace,
  1054. locals=self.namespace,
  1055. evaluation=self.evaluation,
  1056. auto_import=self._auto_import,
  1057. policy_overrides=self.policy_overrides,
  1058. ),
  1059. )
  1060. done = True
  1061. except (SyntaxError, TypeError) as e:
  1062. if self.debug:
  1063. warnings.warn(f"Trimming because of {e}")
  1064. # TypeError can show up with something like `+ d`
  1065. # where `d` is a dictionary.
  1066. # trim the expression to remove any invalid prefix
  1067. # e.g. user starts `(d[`, so we get `expr = '(d'`,
  1068. # where parenthesis is not closed.
  1069. # TODO: make this faster by reusing parts of the computation?
  1070. expr = self._trim_expr(expr)
  1071. except Exception as e:
  1072. if self.debug:
  1073. warnings.warn(f"Evaluation exception {e}")
  1074. done = True
  1075. if self.debug:
  1076. warnings.warn(f"Resolved to {obj}")
  1077. return obj
  1078. @property
  1079. def _auto_import(self):
  1080. if self.auto_import_method is None:
  1081. return None
  1082. if not hasattr(self, "_auto_import_func"):
  1083. self._auto_import_func = import_item(self.auto_import_method)
  1084. return self._auto_import_func
  1085. def get__all__entries(obj):
  1086. """returns the strings in the __all__ attribute"""
  1087. try:
  1088. words = getattr(obj, '__all__')
  1089. except Exception:
  1090. return []
  1091. return [w for w in words if isinstance(w, str)]
  1092. class _DictKeyState(enum.Flag):
  1093. """Represent state of the key match in context of other possible matches.
  1094. - given `d1 = {'a': 1}` completion on `d1['<tab>` will yield `{'a': END_OF_ITEM}` as there is no tuple.
  1095. - given `d2 = {('a', 'b'): 1}`: `d2['a', '<tab>` will yield `{'b': END_OF_TUPLE}` as there is no tuple members to add beyond `'b'`.
  1096. - given `d3 = {('a', 'b'): 1}`: `d3['<tab>` will yield `{'a': IN_TUPLE}` as `'a'` can be added.
  1097. - given `d4 = {'a': 1, ('a', 'b'): 2}`: `d4['<tab>` will yield `{'a': END_OF_ITEM & END_OF_TUPLE}`
  1098. """
  1099. BASELINE = 0
  1100. END_OF_ITEM = enum.auto()
  1101. END_OF_TUPLE = enum.auto()
  1102. IN_TUPLE = enum.auto()
  1103. def _parse_tokens(c):
  1104. """Parse tokens even if there is an error."""
  1105. tokens = []
  1106. token_generator = tokenize.generate_tokens(iter(c.splitlines()).__next__)
  1107. while True:
  1108. try:
  1109. tokens.append(next(token_generator))
  1110. except tokenize.TokenError:
  1111. return tokens
  1112. except StopIteration:
  1113. return tokens
  1114. def _match_number_in_dict_key_prefix(prefix: str) -> Union[str, None]:
  1115. """Match any valid Python numeric literal in a prefix of dictionary keys.
  1116. References:
  1117. - https://docs.python.org/3/reference/lexical_analysis.html#numeric-literals
  1118. - https://docs.python.org/3/library/tokenize.html
  1119. """
  1120. if prefix[-1].isspace():
  1121. # if user typed a space we do not have anything to complete
  1122. # even if there was a valid number token before
  1123. return None
  1124. tokens = _parse_tokens(prefix)
  1125. rev_tokens = reversed(tokens)
  1126. skip_over = {tokenize.ENDMARKER, tokenize.NEWLINE}
  1127. number = None
  1128. for token in rev_tokens:
  1129. if token.type in skip_over:
  1130. continue
  1131. if number is None:
  1132. if token.type == tokenize.NUMBER:
  1133. number = token.string
  1134. continue
  1135. else:
  1136. # we did not match a number
  1137. return None
  1138. if token.type == tokenize.OP:
  1139. if token.string == ",":
  1140. break
  1141. if token.string in {"+", "-"}:
  1142. number = token.string + number
  1143. else:
  1144. return None
  1145. return number
  1146. _INT_FORMATS = {
  1147. "0b": bin,
  1148. "0o": oct,
  1149. "0x": hex,
  1150. }
  1151. def match_dict_keys(
  1152. keys: list[Union[str, bytes, tuple[Union[str, bytes], ...]]],
  1153. prefix: str,
  1154. delims: str,
  1155. extra_prefix: Optional[tuple[Union[str, bytes], ...]] = None,
  1156. ) -> tuple[str, int, dict[str, _DictKeyState]]:
  1157. """Used by dict_key_matches, matching the prefix to a list of keys
  1158. Parameters
  1159. ----------
  1160. keys
  1161. list of keys in dictionary currently being completed.
  1162. prefix
  1163. Part of the text already typed by the user. E.g. `mydict[b'fo`
  1164. delims
  1165. String of delimiters to consider when finding the current key.
  1166. extra_prefix : optional
  1167. Part of the text already typed in multi-key index cases. E.g. for
  1168. `mydict['foo', "bar", 'b`, this would be `('foo', 'bar')`.
  1169. Returns
  1170. -------
  1171. A tuple of three elements: ``quote``, ``token_start``, ``matched``, with
  1172. ``quote`` being the quote that need to be used to close current string.
  1173. ``token_start`` the position where the replacement should start occurring,
  1174. ``matches`` a dictionary of replacement/completion keys on keys and values
  1175. indicating whether the state.
  1176. """
  1177. prefix_tuple = extra_prefix if extra_prefix else ()
  1178. prefix_tuple_size = sum(
  1179. [
  1180. # for pandas, do not count slices as taking space
  1181. not isinstance(k, slice)
  1182. for k in prefix_tuple
  1183. ]
  1184. )
  1185. text_serializable_types = (str, bytes, int, float, slice)
  1186. def filter_prefix_tuple(key):
  1187. # Reject too short keys
  1188. if len(key) <= prefix_tuple_size:
  1189. return False
  1190. # Reject keys which cannot be serialised to text
  1191. for k in key:
  1192. if not isinstance(k, text_serializable_types):
  1193. return False
  1194. # Reject keys that do not match the prefix
  1195. for k, pt in zip(key, prefix_tuple):
  1196. if k != pt and not isinstance(pt, slice):
  1197. return False
  1198. # All checks passed!
  1199. return True
  1200. filtered_key_is_final: dict[
  1201. Union[str, bytes, int, float], _DictKeyState
  1202. ] = defaultdict(lambda: _DictKeyState.BASELINE)
  1203. for k in keys:
  1204. # If at least one of the matches is not final, mark as undetermined.
  1205. # This can happen with `d = {111: 'b', (111, 222): 'a'}` where
  1206. # `111` appears final on first match but is not final on the second.
  1207. if isinstance(k, tuple):
  1208. if filter_prefix_tuple(k):
  1209. key_fragment = k[prefix_tuple_size]
  1210. filtered_key_is_final[key_fragment] |= (
  1211. _DictKeyState.END_OF_TUPLE
  1212. if len(k) == prefix_tuple_size + 1
  1213. else _DictKeyState.IN_TUPLE
  1214. )
  1215. elif prefix_tuple_size > 0:
  1216. # we are completing a tuple but this key is not a tuple,
  1217. # so we should ignore it
  1218. pass
  1219. else:
  1220. if isinstance(k, text_serializable_types):
  1221. filtered_key_is_final[k] |= _DictKeyState.END_OF_ITEM
  1222. filtered_keys = filtered_key_is_final.keys()
  1223. if not prefix:
  1224. return "", 0, {repr(k): v for k, v in filtered_key_is_final.items()}
  1225. quote_match = re.search("(?:\"|')", prefix)
  1226. is_user_prefix_numeric = False
  1227. if quote_match:
  1228. quote = quote_match.group()
  1229. valid_prefix = prefix + quote
  1230. try:
  1231. prefix_str = literal_eval(valid_prefix)
  1232. except Exception:
  1233. return "", 0, {}
  1234. else:
  1235. # If it does not look like a string, let's assume
  1236. # we are dealing with a number or variable.
  1237. number_match = _match_number_in_dict_key_prefix(prefix)
  1238. # We do not want the key matcher to suggest variable names so we yield:
  1239. if number_match is None:
  1240. # The alternative would be to assume that user forgort the quote
  1241. # and if the substring matches, suggest adding it at the start.
  1242. return "", 0, {}
  1243. prefix_str = number_match
  1244. is_user_prefix_numeric = True
  1245. quote = ""
  1246. pattern = '[^' + ''.join('\\' + c for c in delims) + ']*$'
  1247. token_match = re.search(pattern, prefix, re.UNICODE)
  1248. assert token_match is not None # silence mypy
  1249. token_start = token_match.start()
  1250. token_prefix = token_match.group()
  1251. matched: dict[str, _DictKeyState] = {}
  1252. str_key: Union[str, bytes]
  1253. for key in filtered_keys:
  1254. if isinstance(key, (int, float)):
  1255. # User typed a number but this key is not a number.
  1256. if not is_user_prefix_numeric:
  1257. continue
  1258. str_key = str(key)
  1259. if isinstance(key, int):
  1260. int_base = prefix_str[:2].lower()
  1261. # if user typed integer using binary/oct/hex notation:
  1262. if int_base in _INT_FORMATS:
  1263. int_format = _INT_FORMATS[int_base]
  1264. str_key = int_format(key)
  1265. else:
  1266. # User typed a string but this key is a number.
  1267. if is_user_prefix_numeric:
  1268. continue
  1269. str_key = key
  1270. try:
  1271. if not str_key.startswith(prefix_str):
  1272. continue
  1273. except (AttributeError, TypeError, UnicodeError):
  1274. # Python 3+ TypeError on b'a'.startswith('a') or vice-versa
  1275. continue
  1276. # reformat remainder of key to begin with prefix
  1277. rem = str_key[len(prefix_str) :]
  1278. # force repr wrapped in '
  1279. rem_repr = repr(rem + '"') if isinstance(rem, str) else repr(rem + b'"')
  1280. rem_repr = rem_repr[1 + rem_repr.index("'"):-2]
  1281. if quote == '"':
  1282. # The entered prefix is quoted with ",
  1283. # but the match is quoted with '.
  1284. # A contained " hence needs escaping for comparison:
  1285. rem_repr = rem_repr.replace('"', '\\"')
  1286. # then reinsert prefix from start of token
  1287. match = "%s%s" % (token_prefix, rem_repr)
  1288. matched[match] = filtered_key_is_final[key]
  1289. return quote, token_start, matched
  1290. def cursor_to_position(text:str, line:int, column:int)->int:
  1291. """
  1292. Convert the (line,column) position of the cursor in text to an offset in a
  1293. string.
  1294. Parameters
  1295. ----------
  1296. text : str
  1297. The text in which to calculate the cursor offset
  1298. line : int
  1299. Line of the cursor; 0-indexed
  1300. column : int
  1301. Column of the cursor 0-indexed
  1302. Returns
  1303. -------
  1304. Position of the cursor in ``text``, 0-indexed.
  1305. See Also
  1306. --------
  1307. position_to_cursor : reciprocal of this function
  1308. """
  1309. lines = text.split('\n')
  1310. assert line <= len(lines), '{} <= {}'.format(str(line), str(len(lines)))
  1311. return sum(len(line) + 1 for line in lines[:line]) + column
  1312. def position_to_cursor(text: str, offset: int) -> tuple[int, int]:
  1313. """
  1314. Convert the position of the cursor in text (0 indexed) to a line
  1315. number(0-indexed) and a column number (0-indexed) pair
  1316. Position should be a valid position in ``text``.
  1317. Parameters
  1318. ----------
  1319. text : str
  1320. The text in which to calculate the cursor offset
  1321. offset : int
  1322. Position of the cursor in ``text``, 0-indexed.
  1323. Returns
  1324. -------
  1325. (line, column) : (int, int)
  1326. Line of the cursor; 0-indexed, column of the cursor 0-indexed
  1327. See Also
  1328. --------
  1329. cursor_to_position : reciprocal of this function
  1330. """
  1331. assert 0 <= offset <= len(text) , "0 <= %s <= %s" % (offset , len(text))
  1332. before = text[:offset]
  1333. blines = before.split('\n') # ! splitnes trim trailing \n
  1334. line = before.count('\n')
  1335. col = len(blines[-1])
  1336. return line, col
  1337. def _safe_isinstance(obj, module, class_name, *attrs):
  1338. """Checks if obj is an instance of module.class_name if loaded
  1339. """
  1340. if module in sys.modules:
  1341. m = sys.modules[module]
  1342. for attr in [class_name, *attrs]:
  1343. m = getattr(m, attr)
  1344. return isinstance(obj, m)
  1345. @context_matcher()
  1346. def back_unicode_name_matcher(context: CompletionContext):
  1347. """Match Unicode characters back to Unicode name
  1348. Same as :any:`back_unicode_name_matches`, but adopted to new Matcher API.
  1349. """
  1350. fragment, matches = back_unicode_name_matches(context.text_until_cursor)
  1351. return _convert_matcher_v1_result_to_v2(
  1352. matches, type="unicode", fragment=fragment, suppress_if_matches=True
  1353. )
  1354. def back_unicode_name_matches(text: str) -> tuple[str, Sequence[str]]:
  1355. """Match Unicode characters back to Unicode name
  1356. This does ``☃`` -> ``\\snowman``
  1357. Note that snowman is not a valid python3 combining character but will be expanded.
  1358. Though it will not recombine back to the snowman character by the completion machinery.
  1359. This will not either back-complete standard sequences like \\n, \\b ...
  1360. .. deprecated:: 8.6
  1361. You can use :meth:`back_unicode_name_matcher` instead.
  1362. Returns
  1363. =======
  1364. Return a tuple with two elements:
  1365. - The Unicode character that was matched (preceded with a backslash), or
  1366. empty string,
  1367. - a sequence (of 1), name for the match Unicode character, preceded by
  1368. backslash, or empty if no match.
  1369. """
  1370. if len(text)<2:
  1371. return '', ()
  1372. maybe_slash = text[-2]
  1373. if maybe_slash != '\\':
  1374. return '', ()
  1375. char = text[-1]
  1376. # no expand on quote for completion in strings.
  1377. # nor backcomplete standard ascii keys
  1378. if char in string.ascii_letters or char in ('"',"'"):
  1379. return '', ()
  1380. try :
  1381. unic = unicodedata.name(char)
  1382. return '\\'+char,('\\'+unic,)
  1383. except KeyError:
  1384. pass
  1385. return '', ()
  1386. @context_matcher()
  1387. def back_latex_name_matcher(context: CompletionContext) -> SimpleMatcherResult:
  1388. """Match latex characters back to unicode name
  1389. This does ``\\ℵ`` -> ``\\aleph``
  1390. """
  1391. text = context.text_until_cursor
  1392. no_match = {
  1393. "completions": [],
  1394. "suppress": False,
  1395. }
  1396. if len(text)<2:
  1397. return no_match
  1398. maybe_slash = text[-2]
  1399. if maybe_slash != '\\':
  1400. return no_match
  1401. char = text[-1]
  1402. # no expand on quote for completion in strings.
  1403. # nor backcomplete standard ascii keys
  1404. if char in string.ascii_letters or char in ('"',"'"):
  1405. return no_match
  1406. try :
  1407. latex = reverse_latex_symbol[char]
  1408. # '\\' replace the \ as well
  1409. return {
  1410. "completions": [SimpleCompletion(text=latex, type="latex")],
  1411. "suppress": True,
  1412. "matched_fragment": "\\" + char,
  1413. }
  1414. except KeyError:
  1415. pass
  1416. return no_match
  1417. def _formatparamchildren(parameter) -> str:
  1418. """
  1419. Get parameter name and value from Jedi Private API
  1420. Jedi does not expose a simple way to get `param=value` from its API.
  1421. Parameters
  1422. ----------
  1423. parameter
  1424. Jedi's function `Param`
  1425. Returns
  1426. -------
  1427. A string like 'a', 'b=1', '*args', '**kwargs'
  1428. """
  1429. description = parameter.description
  1430. if not description.startswith('param '):
  1431. raise ValueError('Jedi function parameter description have change format.'
  1432. 'Expected "param ...", found %r".' % description)
  1433. return description[6:]
  1434. def _make_signature(completion)-> str:
  1435. """
  1436. Make the signature from a jedi completion
  1437. Parameters
  1438. ----------
  1439. completion : jedi.Completion
  1440. object does not complete a function type
  1441. Returns
  1442. -------
  1443. a string consisting of the function signature, with the parenthesis but
  1444. without the function name. example:
  1445. `(a, *args, b=1, **kwargs)`
  1446. """
  1447. # it looks like this might work on jedi 0.17
  1448. if hasattr(completion, 'get_signatures'):
  1449. signatures = completion.get_signatures()
  1450. if not signatures:
  1451. return '(?)'
  1452. c0 = completion.get_signatures()[0]
  1453. return '('+c0.to_string().split('(', maxsplit=1)[1]
  1454. return '(%s)'% ', '.join([f for f in (_formatparamchildren(p) for signature in completion.get_signatures()
  1455. for p in signature.defined_names()) if f])
  1456. _CompleteResult = dict[str, MatcherResult]
  1457. DICT_MATCHER_REGEX = re.compile(
  1458. r"""(?x)
  1459. ( # match dict-referring - or any get item object - expression
  1460. .+
  1461. )
  1462. \[ # open bracket
  1463. \s* # and optional whitespace
  1464. # Capture any number of serializable objects (e.g. "a", "b", 'c')
  1465. # and slices
  1466. ((?:(?:
  1467. (?: # closed string
  1468. [uUbB]? # string prefix (r not handled)
  1469. (?:
  1470. '(?:[^']|(?<!\\)\\')*'
  1471. |
  1472. "(?:[^"]|(?<!\\)\\")*"
  1473. )
  1474. )
  1475. |
  1476. # capture integers and slices
  1477. (?:[-+]?\d+)?(?::(?:[-+]?\d+)?){0,2}
  1478. |
  1479. # integer in bin/hex/oct notation
  1480. 0[bBxXoO]_?(?:\w|\d)+
  1481. )
  1482. \s*,\s*
  1483. )*)
  1484. ((?:
  1485. (?: # unclosed string
  1486. [uUbB]? # string prefix (r not handled)
  1487. (?:
  1488. '(?:[^']|(?<!\\)\\')*
  1489. |
  1490. "(?:[^"]|(?<!\\)\\")*
  1491. )
  1492. )
  1493. |
  1494. # unfinished integer
  1495. (?:[-+]?\d+)
  1496. |
  1497. # integer in bin/hex/oct notation
  1498. 0[bBxXoO]_?(?:\w|\d)+
  1499. )
  1500. )?
  1501. $
  1502. """
  1503. )
  1504. def _convert_matcher_v1_result_to_v2_no_no(
  1505. matches: Sequence[str],
  1506. type: str,
  1507. ) -> SimpleMatcherResult:
  1508. """same as _convert_matcher_v1_result_to_v2 but fragment=None, and suppress_if_matches is False by construction"""
  1509. return SimpleMatcherResult(
  1510. completions=[SimpleCompletion(text=match, type=type) for match in matches],
  1511. suppress=False,
  1512. )
  1513. def _convert_matcher_v1_result_to_v2(
  1514. matches: Sequence[str],
  1515. type: str,
  1516. fragment: Optional[str] = None,
  1517. suppress_if_matches: bool = False,
  1518. ) -> SimpleMatcherResult:
  1519. """Utility to help with transition"""
  1520. result = {
  1521. "completions": [SimpleCompletion(text=match, type=type) for match in matches],
  1522. "suppress": (True if matches else False) if suppress_if_matches else False,
  1523. }
  1524. if fragment is not None:
  1525. result["matched_fragment"] = fragment
  1526. return cast(SimpleMatcherResult, result)
  1527. class IPCompleter(Completer):
  1528. """Extension of the completer class with IPython-specific features"""
  1529. @observe('greedy')
  1530. def _greedy_changed(self, change):
  1531. """update the splitter and readline delims when greedy is changed"""
  1532. if change["new"]:
  1533. self.evaluation = "unsafe"
  1534. self.auto_close_dict_keys = True
  1535. self.splitter.delims = GREEDY_DELIMS
  1536. else:
  1537. self.evaluation = "limited"
  1538. self.auto_close_dict_keys = False
  1539. self.splitter.delims = DELIMS
  1540. dict_keys_only = Bool(
  1541. False,
  1542. help="""
  1543. Whether to show dict key matches only.
  1544. (disables all matchers except for `IPCompleter.dict_key_matcher`).
  1545. """,
  1546. )
  1547. suppress_competing_matchers = UnionTrait(
  1548. [Bool(allow_none=True), DictTrait(Bool(None, allow_none=True))],
  1549. default_value=None,
  1550. help="""
  1551. Whether to suppress completions from other *Matchers*.
  1552. When set to ``None`` (default) the matchers will attempt to auto-detect
  1553. whether suppression of other matchers is desirable. For example, at
  1554. the beginning of a line followed by `%` we expect a magic completion
  1555. to be the only applicable option, and after ``my_dict['`` we usually
  1556. expect a completion with an existing dictionary key.
  1557. If you want to disable this heuristic and see completions from all matchers,
  1558. set ``IPCompleter.suppress_competing_matchers = False``.
  1559. To disable the heuristic for specific matchers provide a dictionary mapping:
  1560. ``IPCompleter.suppress_competing_matchers = {'IPCompleter.dict_key_matcher': False}``.
  1561. Set ``IPCompleter.suppress_competing_matchers = True`` to limit
  1562. completions to the set of matchers with the highest priority;
  1563. this is equivalent to ``IPCompleter.merge_completions`` and
  1564. can be beneficial for performance, but will sometimes omit relevant
  1565. candidates from matchers further down the priority list.
  1566. """,
  1567. ).tag(config=True)
  1568. merge_completions = Bool(
  1569. True,
  1570. help="""Whether to merge completion results into a single list
  1571. If False, only the completion results from the first non-empty
  1572. completer will be returned.
  1573. As of version 8.6.0, setting the value to ``False`` is an alias for:
  1574. ``IPCompleter.suppress_competing_matchers = True.``.
  1575. """,
  1576. ).tag(config=True)
  1577. disable_matchers = ListTrait(
  1578. Unicode(),
  1579. help="""List of matchers to disable.
  1580. The list should contain matcher identifiers (see :any:`completion_matcher`).
  1581. """,
  1582. ).tag(config=True)
  1583. omit__names = Enum(
  1584. (0, 1, 2),
  1585. default_value=2,
  1586. help="""Instruct the completer to omit private method names
  1587. Specifically, when completing on ``object.<tab>``.
  1588. When 2 [default]: all names that start with '_' will be excluded.
  1589. When 1: all 'magic' names (``__foo__``) will be excluded.
  1590. When 0: nothing will be excluded.
  1591. """
  1592. ).tag(config=True)
  1593. limit_to__all__ = Bool(False,
  1594. help="""
  1595. DEPRECATED as of version 5.0.
  1596. Instruct the completer to use __all__ for the completion
  1597. Specifically, when completing on ``object.<tab>``.
  1598. When True: only those names in obj.__all__ will be included.
  1599. When False [default]: the __all__ attribute is ignored
  1600. """,
  1601. ).tag(config=True)
  1602. profile_completions = Bool(
  1603. default_value=False,
  1604. help="If True, emit profiling data for completion subsystem using cProfile."
  1605. ).tag(config=True)
  1606. profiler_output_dir = Unicode(
  1607. default_value=".completion_profiles",
  1608. help="Template for path at which to output profile data for completions."
  1609. ).tag(config=True)
  1610. @observe('limit_to__all__')
  1611. def _limit_to_all_changed(self, change):
  1612. warnings.warn('`IPython.core.IPCompleter.limit_to__all__` configuration '
  1613. 'value has been deprecated since IPython 5.0, will be made to have '
  1614. 'no effects and then removed in future version of IPython.',
  1615. UserWarning)
  1616. def __init__(
  1617. self, shell=None, namespace=None, global_namespace=None, config=None, **kwargs
  1618. ):
  1619. """IPCompleter() -> completer
  1620. Return a completer object.
  1621. Parameters
  1622. ----------
  1623. shell
  1624. a pointer to the ipython shell itself. This is needed
  1625. because this completer knows about magic functions, and those can
  1626. only be accessed via the ipython instance.
  1627. namespace : dict, optional
  1628. an optional dict where completions are performed.
  1629. global_namespace : dict, optional
  1630. secondary optional dict for completions, to
  1631. handle cases (such as IPython embedded inside functions) where
  1632. both Python scopes are visible.
  1633. config : Config
  1634. traitlet's config object
  1635. **kwargs
  1636. passed to super class unmodified.
  1637. """
  1638. self.magic_escape = ESC_MAGIC
  1639. self.splitter = CompletionSplitter()
  1640. # _greedy_changed() depends on splitter and readline being defined:
  1641. super().__init__(
  1642. namespace=namespace,
  1643. global_namespace=global_namespace,
  1644. config=config,
  1645. **kwargs,
  1646. )
  1647. # List where completion matches will be stored
  1648. self.matches = []
  1649. self.shell = shell
  1650. # Regexp to split filenames with spaces in them
  1651. self.space_name_re = re.compile(r'([^\\] )')
  1652. # Hold a local ref. to glob.glob for speed
  1653. self.glob = glob.glob
  1654. # Determine if we are running on 'dumb' terminals, like (X)Emacs
  1655. # buffers, to avoid completion problems.
  1656. term = os.environ.get('TERM','xterm')
  1657. self.dumb_terminal = term in ['dumb','emacs']
  1658. # Special handling of backslashes needed in win32 platforms
  1659. if sys.platform == "win32":
  1660. self.clean_glob = self._clean_glob_win32
  1661. else:
  1662. self.clean_glob = self._clean_glob
  1663. #regexp to parse docstring for function signature
  1664. self.docstring_sig_re = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
  1665. self.docstring_kwd_re = re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
  1666. #use this if positional argument name is also needed
  1667. #= re.compile(r'[\s|\[]*(\w+)(?:\s*=?\s*.*)')
  1668. self.magic_arg_matchers = [
  1669. self.magic_config_matcher,
  1670. self.magic_color_matcher,
  1671. ]
  1672. # This is set externally by InteractiveShell
  1673. self.custom_completers = None
  1674. # This is a list of names of unicode characters that can be completed
  1675. # into their corresponding unicode value. The list is large, so we
  1676. # lazily initialize it on first use. Consuming code should access this
  1677. # attribute through the `@unicode_names` property.
  1678. self._unicode_names = None
  1679. self._backslash_combining_matchers = [
  1680. self.latex_name_matcher,
  1681. self.unicode_name_matcher,
  1682. back_latex_name_matcher,
  1683. back_unicode_name_matcher,
  1684. self.fwd_unicode_matcher,
  1685. ]
  1686. if not self.backslash_combining_completions:
  1687. for matcher in self._backslash_combining_matchers:
  1688. self.disable_matchers.append(_get_matcher_id(matcher))
  1689. if not self.merge_completions:
  1690. self.suppress_competing_matchers = True
  1691. @property
  1692. def matchers(self) -> list[Matcher]:
  1693. """All active matcher routines for completion"""
  1694. if self.dict_keys_only:
  1695. return [self.dict_key_matcher]
  1696. if self.use_jedi:
  1697. return [
  1698. *self.custom_matchers,
  1699. *self._backslash_combining_matchers,
  1700. *self.magic_arg_matchers,
  1701. self.custom_completer_matcher,
  1702. self.magic_matcher,
  1703. self._jedi_matcher,
  1704. self.dict_key_matcher,
  1705. self.file_matcher,
  1706. ]
  1707. else:
  1708. return [
  1709. *self.custom_matchers,
  1710. *self._backslash_combining_matchers,
  1711. *self.magic_arg_matchers,
  1712. self.custom_completer_matcher,
  1713. self.dict_key_matcher,
  1714. self.magic_matcher,
  1715. self.python_matcher,
  1716. self.file_matcher,
  1717. self.python_func_kw_matcher,
  1718. ]
  1719. def all_completions(self, text: str) -> list[str]:
  1720. """
  1721. Wrapper around the completion methods for the benefit of emacs.
  1722. """
  1723. prefix = text.rpartition('.')[0]
  1724. with provisionalcompleter():
  1725. return ['.'.join([prefix, c.text]) if prefix and self.use_jedi else c.text
  1726. for c in self.completions(text, len(text))]
  1727. return self.complete(text)[1]
  1728. def _clean_glob(self, text:str):
  1729. return self.glob("%s*" % text)
  1730. def _clean_glob_win32(self, text:str):
  1731. return [f.replace("\\","/")
  1732. for f in self.glob("%s*" % text)]
  1733. @context_matcher()
  1734. def file_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
  1735. """Match filenames, expanding ~USER type strings.
  1736. Most of the seemingly convoluted logic in this completer is an
  1737. attempt to handle filenames with spaces in them. And yet it's not
  1738. quite perfect, because Python's readline doesn't expose all of the
  1739. GNU readline details needed for this to be done correctly.
  1740. For a filename with a space in it, the printed completions will be
  1741. only the parts after what's already been typed (instead of the
  1742. full completions, as is normally done). I don't think with the
  1743. current (as of Python 2.3) Python readline it's possible to do
  1744. better.
  1745. """
  1746. # TODO: add a heuristic for suppressing (e.g. if it has OS-specific delimiter,
  1747. # starts with `/home/`, `C:\`, etc)
  1748. text = context.token
  1749. code_until_cursor = self._extract_code(context.text_until_cursor)
  1750. completion_type = self._determine_completion_context(code_until_cursor)
  1751. in_cli_context = self._is_completing_in_cli_context(code_until_cursor)
  1752. if (
  1753. completion_type == self._CompletionContextType.ATTRIBUTE
  1754. and not in_cli_context
  1755. ):
  1756. return {
  1757. "completions": [],
  1758. "suppress": False,
  1759. }
  1760. # chars that require escaping with backslash - i.e. chars
  1761. # that readline treats incorrectly as delimiters, but we
  1762. # don't want to treat as delimiters in filename matching
  1763. # when escaped with backslash
  1764. if text.startswith('!'):
  1765. text = text[1:]
  1766. text_prefix = u'!'
  1767. else:
  1768. text_prefix = u''
  1769. text_until_cursor = self.text_until_cursor
  1770. # track strings with open quotes
  1771. open_quotes = has_open_quotes(text_until_cursor)
  1772. if '(' in text_until_cursor or '[' in text_until_cursor:
  1773. lsplit = text
  1774. else:
  1775. try:
  1776. # arg_split ~ shlex.split, but with unicode bugs fixed by us
  1777. lsplit = arg_split(text_until_cursor)[-1]
  1778. except ValueError:
  1779. # typically an unmatched ", or backslash without escaped char.
  1780. if open_quotes:
  1781. lsplit = text_until_cursor.split(open_quotes)[-1]
  1782. else:
  1783. return {
  1784. "completions": [],
  1785. "suppress": False,
  1786. }
  1787. except IndexError:
  1788. # tab pressed on empty line
  1789. lsplit = ""
  1790. if not open_quotes and lsplit != protect_filename(lsplit):
  1791. # if protectables are found, do matching on the whole escaped name
  1792. has_protectables = True
  1793. text0,text = text,lsplit
  1794. else:
  1795. has_protectables = False
  1796. text = os.path.expanduser(text)
  1797. if text == "":
  1798. return {
  1799. "completions": [
  1800. SimpleCompletion(
  1801. text=text_prefix + protect_filename(f), type="path"
  1802. )
  1803. for f in self.glob("*")
  1804. ],
  1805. "suppress": False,
  1806. }
  1807. # Compute the matches from the filesystem
  1808. if sys.platform == 'win32':
  1809. m0 = self.clean_glob(text)
  1810. else:
  1811. m0 = self.clean_glob(text.replace('\\', ''))
  1812. if has_protectables:
  1813. # If we had protectables, we need to revert our changes to the
  1814. # beginning of filename so that we don't double-write the part
  1815. # of the filename we have so far
  1816. len_lsplit = len(lsplit)
  1817. matches = [text_prefix + text0 +
  1818. protect_filename(f[len_lsplit:]) for f in m0]
  1819. else:
  1820. if open_quotes:
  1821. # if we have a string with an open quote, we don't need to
  1822. # protect the names beyond the quote (and we _shouldn't_, as
  1823. # it would cause bugs when the filesystem call is made).
  1824. matches = m0 if sys.platform == "win32" else\
  1825. [protect_filename(f, open_quotes) for f in m0]
  1826. else:
  1827. matches = [text_prefix +
  1828. protect_filename(f) for f in m0]
  1829. # Mark directories in input list by appending '/' to their names.
  1830. return {
  1831. "completions": [
  1832. SimpleCompletion(text=x + "/" if os.path.isdir(x) else x, type="path")
  1833. for x in matches
  1834. ],
  1835. "suppress": False,
  1836. }
  1837. def _extract_code(self, line: str) -> str:
  1838. """Extract code from magics if any."""
  1839. if not line:
  1840. return line
  1841. maybe_magic, *rest = line.split(maxsplit=1)
  1842. if not rest:
  1843. return line
  1844. args = rest[0]
  1845. known_magics = self.shell.magics_manager.lsmagic()
  1846. line_magics = known_magics["line"]
  1847. magic_name = maybe_magic.lstrip(self.magic_escape)
  1848. if magic_name not in line_magics:
  1849. return line
  1850. if not maybe_magic.startswith(self.magic_escape):
  1851. all_variables = [*self.namespace.keys(), *self.global_namespace.keys()]
  1852. if magic_name in all_variables:
  1853. # short circuit if we see a line starting with say `time`
  1854. # but time is defined as a variable (in addition to being
  1855. # a magic). In these cases users need to use explicit `%time`.
  1856. return line
  1857. magic_method = line_magics[magic_name]
  1858. try:
  1859. if magic_name == "timeit":
  1860. opts, stmt = magic_method.__self__.parse_options(
  1861. args,
  1862. "n:r:tcp:qov:",
  1863. posix=False,
  1864. strict=False,
  1865. preserve_non_opts=True,
  1866. )
  1867. return stmt
  1868. elif magic_name == "prun":
  1869. opts, stmt = magic_method.__self__.parse_options(
  1870. args, "D:l:rs:T:q", list_all=True, posix=False
  1871. )
  1872. return stmt
  1873. elif hasattr(magic_method, "parser") and getattr(
  1874. magic_method, "has_arguments", False
  1875. ):
  1876. # e.g. %debug, %time
  1877. args, extra = magic_method.parser.parse_argstring(args, partial=True)
  1878. return " ".join(extra)
  1879. except UsageError:
  1880. return line
  1881. return line
  1882. @context_matcher()
  1883. def magic_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
  1884. """Match magics."""
  1885. # Get all shell magics now rather than statically, so magics loaded at
  1886. # runtime show up too.
  1887. text = context.token
  1888. lsm = self.shell.magics_manager.lsmagic()
  1889. line_magics = lsm['line']
  1890. cell_magics = lsm['cell']
  1891. pre = self.magic_escape
  1892. pre2 = pre + pre
  1893. explicit_magic = text.startswith(pre)
  1894. # Completion logic:
  1895. # - user gives %%: only do cell magics
  1896. # - user gives %: do both line and cell magics
  1897. # - no prefix: do both
  1898. # In other words, line magics are skipped if the user gives %% explicitly
  1899. #
  1900. # We also exclude magics that match any currently visible names:
  1901. # https://github.com/ipython/ipython/issues/4877, unless the user has
  1902. # typed a %:
  1903. # https://github.com/ipython/ipython/issues/10754
  1904. bare_text = text.lstrip(pre)
  1905. global_matches = self.global_matches(bare_text)
  1906. if not explicit_magic:
  1907. def matches(magic):
  1908. """
  1909. Filter magics, in particular remove magics that match
  1910. a name present in global namespace.
  1911. """
  1912. return ( magic.startswith(bare_text) and
  1913. magic not in global_matches )
  1914. else:
  1915. def matches(magic):
  1916. return magic.startswith(bare_text)
  1917. completions = [pre2 + m for m in cell_magics if matches(m)]
  1918. if not text.startswith(pre2):
  1919. completions += [pre + m for m in line_magics if matches(m)]
  1920. is_magic_prefix = len(text) > 0 and text[0] == "%"
  1921. return {
  1922. "completions": [
  1923. SimpleCompletion(text=comp, type="magic") for comp in completions
  1924. ],
  1925. "suppress": is_magic_prefix and len(completions) > 0,
  1926. }
  1927. @context_matcher()
  1928. def magic_config_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
  1929. """Match class names and attributes for %config magic."""
  1930. # NOTE: uses `line_buffer` equivalent for compatibility
  1931. matches = self.magic_config_matches(context.line_with_cursor)
  1932. return _convert_matcher_v1_result_to_v2_no_no(matches, type="param")
  1933. def magic_config_matches(self, text: str) -> list[str]:
  1934. """Match class names and attributes for %config magic.
  1935. .. deprecated:: 8.6
  1936. You can use :meth:`magic_config_matcher` instead.
  1937. """
  1938. texts = text.strip().split()
  1939. if len(texts) > 0 and (texts[0] == 'config' or texts[0] == '%config'):
  1940. # get all configuration classes
  1941. classes = sorted(set([ c for c in self.shell.configurables
  1942. if c.__class__.class_traits(config=True)
  1943. ]), key=lambda x: x.__class__.__name__)
  1944. classnames = [ c.__class__.__name__ for c in classes ]
  1945. # return all classnames if config or %config is given
  1946. if len(texts) == 1:
  1947. return classnames
  1948. # match classname
  1949. classname_texts = texts[1].split('.')
  1950. classname = classname_texts[0]
  1951. classname_matches = [ c for c in classnames
  1952. if c.startswith(classname) ]
  1953. # return matched classes or the matched class with attributes
  1954. if texts[1].find('.') < 0:
  1955. return classname_matches
  1956. elif len(classname_matches) == 1 and \
  1957. classname_matches[0] == classname:
  1958. cls = classes[classnames.index(classname)].__class__
  1959. help = cls.class_get_help()
  1960. # strip leading '--' from cl-args:
  1961. help = re.sub(re.compile(r'^--', re.MULTILINE), '', help)
  1962. return [ attr.split('=')[0]
  1963. for attr in help.strip().splitlines()
  1964. if attr.startswith(texts[1]) ]
  1965. return []
  1966. @context_matcher()
  1967. def magic_color_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
  1968. """Match color schemes for %colors magic."""
  1969. text = context.line_with_cursor
  1970. texts = text.split()
  1971. if text.endswith(' '):
  1972. # .split() strips off the trailing whitespace. Add '' back
  1973. # so that: '%colors ' -> ['%colors', '']
  1974. texts.append('')
  1975. if len(texts) == 2 and (texts[0] == 'colors' or texts[0] == '%colors'):
  1976. prefix = texts[1]
  1977. return SimpleMatcherResult(
  1978. completions=[
  1979. SimpleCompletion(color, type="param")
  1980. for color in theme_table.keys()
  1981. if color.startswith(prefix)
  1982. ],
  1983. suppress=False,
  1984. )
  1985. return SimpleMatcherResult(
  1986. completions=[],
  1987. suppress=False,
  1988. )
  1989. @context_matcher(identifier="IPCompleter.jedi_matcher")
  1990. def _jedi_matcher(self, context: CompletionContext) -> _JediMatcherResult:
  1991. matches = self._jedi_matches(
  1992. cursor_column=context.cursor_position,
  1993. cursor_line=context.cursor_line,
  1994. text=context.full_text,
  1995. )
  1996. return {
  1997. "completions": matches,
  1998. # static analysis should not suppress other matcher
  1999. # NOTE: file_matcher is automatically suppressed on attribute completions
  2000. "suppress": False,
  2001. }
  2002. def _jedi_matches(
  2003. self, cursor_column: int, cursor_line: int, text: str
  2004. ) -> Iterator[_JediCompletionLike]:
  2005. """
  2006. Return a list of :any:`jedi.api.Completion`\\s object from a ``text`` and
  2007. cursor position.
  2008. Parameters
  2009. ----------
  2010. cursor_column : int
  2011. column position of the cursor in ``text``, 0-indexed.
  2012. cursor_line : int
  2013. line position of the cursor in ``text``, 0-indexed
  2014. text : str
  2015. text to complete
  2016. Notes
  2017. -----
  2018. If ``IPCompleter.debug`` is ``True`` may return a :any:`_FakeJediCompletion`
  2019. object containing a string with the Jedi debug information attached.
  2020. .. deprecated:: 8.6
  2021. You can use :meth:`_jedi_matcher` instead.
  2022. """
  2023. namespaces = [self.namespace]
  2024. if self.global_namespace is not None:
  2025. namespaces.append(self.global_namespace)
  2026. completion_filter = lambda x:x
  2027. offset = cursor_to_position(text, cursor_line, cursor_column)
  2028. # filter output if we are completing for object members
  2029. if offset:
  2030. pre = text[offset-1]
  2031. if pre == '.':
  2032. if self.omit__names == 2:
  2033. completion_filter = lambda c:not c.name.startswith('_')
  2034. elif self.omit__names == 1:
  2035. completion_filter = lambda c:not (c.name.startswith('__') and c.name.endswith('__'))
  2036. elif self.omit__names == 0:
  2037. completion_filter = lambda x:x
  2038. else:
  2039. raise ValueError("Don't understand self.omit__names == {}".format(self.omit__names))
  2040. interpreter = jedi.Interpreter(text[:offset], namespaces)
  2041. try_jedi = True
  2042. try:
  2043. # find the first token in the current tree -- if it is a ' or " then we are in a string
  2044. completing_string = False
  2045. try:
  2046. first_child = next(c for c in interpreter._get_module().tree_node.children if hasattr(c, 'value'))
  2047. except StopIteration:
  2048. pass
  2049. else:
  2050. # note the value may be ', ", or it may also be ''' or """, or
  2051. # in some cases, """what/you/typed..., but all of these are
  2052. # strings.
  2053. completing_string = len(first_child.value) > 0 and first_child.value[0] in {"'", '"'}
  2054. # if we are in a string jedi is likely not the right candidate for
  2055. # now. Skip it.
  2056. try_jedi = not completing_string
  2057. except Exception as e:
  2058. # many of things can go wrong, we are using private API just don't crash.
  2059. if self.debug:
  2060. print("Error detecting if completing a non-finished string :", e, '|')
  2061. if not try_jedi:
  2062. return iter([])
  2063. try:
  2064. return filter(completion_filter, interpreter.complete(column=cursor_column, line=cursor_line + 1))
  2065. except Exception as e:
  2066. if self.debug:
  2067. return iter(
  2068. [
  2069. _FakeJediCompletion(
  2070. 'Oops Jedi has crashed, please report a bug with the following:\n"""\n%s\ns"""'
  2071. % (e)
  2072. )
  2073. ]
  2074. )
  2075. else:
  2076. return iter([])
  2077. class _CompletionContextType(enum.Enum):
  2078. ATTRIBUTE = "attribute" # For attribute completion
  2079. GLOBAL = "global" # For global completion
  2080. def _determine_completion_context(self, line):
  2081. """
  2082. Determine whether the cursor is in an attribute or global completion context.
  2083. """
  2084. # Cursor in string/comment → GLOBAL.
  2085. is_string, is_in_expression = self._is_in_string_or_comment(line)
  2086. if is_string and not is_in_expression:
  2087. return self._CompletionContextType.GLOBAL
  2088. # If we're in a template string expression, handle specially
  2089. if is_string and is_in_expression:
  2090. # Extract the expression part - look for the last { that isn't closed
  2091. expr_start = line.rfind("{")
  2092. if expr_start >= 0:
  2093. # We're looking at the expression inside a template string
  2094. expr = line[expr_start + 1 :]
  2095. # Recursively determine the context of the expression
  2096. return self._determine_completion_context(expr)
  2097. # Handle plain number literals - should be global context
  2098. # Ex: 3. -42.14 but not 3.1.
  2099. if re.search(r"(?<!\w)(?<!\d\.)([-+]?\d+\.(\d+)?)(?!\w)$", line):
  2100. return self._CompletionContextType.GLOBAL
  2101. # Handle all other attribute matches np.ran, d[0].k, (a,b).count, obj._private
  2102. chain_match = re.search(r".*(.+(?<!\s)\.(?:[a-zA-Z_]\w*)?)$", line)
  2103. if chain_match:
  2104. return self._CompletionContextType.ATTRIBUTE
  2105. return self._CompletionContextType.GLOBAL
  2106. def _is_completing_in_cli_context(self, text: str) -> bool:
  2107. """
  2108. Determine if we are completing in a CLI alias, line magic, or bang expression context.
  2109. """
  2110. stripped = text.lstrip()
  2111. if stripped.startswith("!") or stripped.startswith("%"):
  2112. return True
  2113. # Check for CLI aliases
  2114. try:
  2115. tokens = stripped.split(None, 1)
  2116. if not tokens:
  2117. return False
  2118. first_token = tokens[0]
  2119. # Must have arguments after the command for this to apply
  2120. if len(tokens) < 2:
  2121. return False
  2122. # Check if first token is a known alias
  2123. if not any(
  2124. alias[0] == first_token for alias in self.shell.alias_manager.aliases
  2125. ):
  2126. return False
  2127. try:
  2128. if first_token in self.shell.user_ns:
  2129. # There's a variable defined, so the alias is overshadowed
  2130. return False
  2131. except (AttributeError, KeyError):
  2132. pass
  2133. return True
  2134. except Exception:
  2135. return False
  2136. def _is_in_string_or_comment(self, text):
  2137. """
  2138. Determine if the cursor is inside a string or comment.
  2139. Returns (is_string, is_in_expression) tuple:
  2140. - is_string: True if in any kind of string
  2141. - is_in_expression: True if inside an f-string/t-string expression
  2142. """
  2143. in_single_quote = False
  2144. in_double_quote = False
  2145. in_triple_single = False
  2146. in_triple_double = False
  2147. in_template_string = False # Covers both f-strings and t-strings
  2148. in_expression = False # For expressions in f/t-strings
  2149. expression_depth = 0 # Track nested braces in expressions
  2150. i = 0
  2151. while i < len(text):
  2152. # Check for f-string or t-string start
  2153. if (
  2154. i + 1 < len(text)
  2155. and text[i] in ("f", "t")
  2156. and (text[i + 1] == '"' or text[i + 1] == "'")
  2157. and not (
  2158. in_single_quote
  2159. or in_double_quote
  2160. or in_triple_single
  2161. or in_triple_double
  2162. )
  2163. ):
  2164. in_template_string = True
  2165. i += 1 # Skip the 'f' or 't'
  2166. # Handle triple quotes
  2167. if i + 2 < len(text):
  2168. if (
  2169. text[i : i + 3] == '"""'
  2170. and not in_single_quote
  2171. and not in_triple_single
  2172. ):
  2173. in_triple_double = not in_triple_double
  2174. if not in_triple_double:
  2175. in_template_string = False
  2176. i += 3
  2177. continue
  2178. if (
  2179. text[i : i + 3] == "'''"
  2180. and not in_double_quote
  2181. and not in_triple_double
  2182. ):
  2183. in_triple_single = not in_triple_single
  2184. if not in_triple_single:
  2185. in_template_string = False
  2186. i += 3
  2187. continue
  2188. # Handle escapes
  2189. if text[i] == "\\" and i + 1 < len(text):
  2190. i += 2
  2191. continue
  2192. # Handle nested braces within f-strings
  2193. if in_template_string:
  2194. # Special handling for consecutive opening braces
  2195. if i + 1 < len(text) and text[i : i + 2] == "{{":
  2196. i += 2
  2197. continue
  2198. # Detect start of an expression
  2199. if text[i] == "{":
  2200. # Only increment depth and mark as expression if not already in an expression
  2201. # or if we're at a top-level nested brace
  2202. if not in_expression or (in_expression and expression_depth == 0):
  2203. in_expression = True
  2204. expression_depth += 1
  2205. i += 1
  2206. continue
  2207. # Detect end of an expression
  2208. if text[i] == "}":
  2209. expression_depth -= 1
  2210. if expression_depth <= 0:
  2211. in_expression = False
  2212. expression_depth = 0
  2213. i += 1
  2214. continue
  2215. in_triple_quote = in_triple_single or in_triple_double
  2216. # Handle quotes - also reset template string when closing quotes are encountered
  2217. if text[i] == '"' and not in_single_quote and not in_triple_quote:
  2218. in_double_quote = not in_double_quote
  2219. if not in_double_quote and not in_triple_quote:
  2220. in_template_string = False
  2221. elif text[i] == "'" and not in_double_quote and not in_triple_quote:
  2222. in_single_quote = not in_single_quote
  2223. if not in_single_quote and not in_triple_quote:
  2224. in_template_string = False
  2225. # Check for comment
  2226. if text[i] == "#" and not (
  2227. in_single_quote or in_double_quote or in_triple_quote
  2228. ):
  2229. return True, False
  2230. i += 1
  2231. is_string = (
  2232. in_single_quote or in_double_quote or in_triple_single or in_triple_double
  2233. )
  2234. # Return tuple (is_string, is_in_expression)
  2235. return (
  2236. is_string or (in_template_string and not in_expression),
  2237. in_expression and expression_depth > 0,
  2238. )
  2239. @context_matcher()
  2240. def python_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
  2241. """Match attributes or global python names"""
  2242. text = context.text_until_cursor
  2243. text = self._extract_code(text)
  2244. in_cli_context = self._is_completing_in_cli_context(text)
  2245. if in_cli_context:
  2246. completion_type = self._CompletionContextType.GLOBAL
  2247. else:
  2248. completion_type = self._determine_completion_context(text)
  2249. if completion_type == self._CompletionContextType.ATTRIBUTE:
  2250. try:
  2251. matches, fragment = self._attr_matches(
  2252. text, include_prefix=False, context=context
  2253. )
  2254. if text.endswith(".") and self.omit__names:
  2255. if self.omit__names == 1:
  2256. # true if txt is _not_ a __ name, false otherwise:
  2257. no__name = lambda txt: re.match(r".*\.__.*?__", txt) is None
  2258. else:
  2259. # true if txt is _not_ a _ name, false otherwise:
  2260. no__name = (
  2261. lambda txt: re.match(r"\._.*?", txt[txt.rindex(".") :])
  2262. is None
  2263. )
  2264. matches = filter(no__name, matches)
  2265. matches = _convert_matcher_v1_result_to_v2(
  2266. matches, type="attribute", fragment=fragment
  2267. )
  2268. return matches
  2269. except NameError:
  2270. # catches <undefined attributes>.<tab>
  2271. return SimpleMatcherResult(completions=[], suppress=False)
  2272. else:
  2273. try:
  2274. matches = self.global_matches(context.token, context=context)
  2275. except TypeError:
  2276. matches = self.global_matches(context.token)
  2277. # TODO: maybe distinguish between functions, modules and just "variables"
  2278. return SimpleMatcherResult(
  2279. completions=[
  2280. SimpleCompletion(text=match, type="variable") for match in matches
  2281. ],
  2282. suppress=False,
  2283. )
  2284. @completion_matcher(api_version=1)
  2285. def python_matches(self, text: str) -> Iterable[str]:
  2286. """Match attributes or global python names.
  2287. .. deprecated:: 8.27
  2288. You can use :meth:`python_matcher` instead."""
  2289. if "." in text:
  2290. try:
  2291. matches = self.attr_matches(text)
  2292. if text.endswith('.') and self.omit__names:
  2293. if self.omit__names == 1:
  2294. # true if txt is _not_ a __ name, false otherwise:
  2295. no__name = (lambda txt:
  2296. re.match(r'.*\.__.*?__',txt) is None)
  2297. else:
  2298. # true if txt is _not_ a _ name, false otherwise:
  2299. no__name = (lambda txt:
  2300. re.match(r'\._.*?',txt[txt.rindex('.'):]) is None)
  2301. matches = filter(no__name, matches)
  2302. except NameError:
  2303. # catches <undefined attributes>.<tab>
  2304. matches = []
  2305. else:
  2306. matches = self.global_matches(text)
  2307. return matches
  2308. def _default_arguments_from_docstring(self, doc):
  2309. """Parse the first line of docstring for call signature.
  2310. Docstring should be of the form 'min(iterable[, key=func])\n'.
  2311. It can also parse cython docstring of the form
  2312. 'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
  2313. """
  2314. if doc is None:
  2315. return []
  2316. #care only the firstline
  2317. line = doc.lstrip().splitlines()[0]
  2318. #p = re.compile(r'^[\w|\s.]+\(([^)]*)\).*')
  2319. #'min(iterable[, key=func])\n' -> 'iterable[, key=func]'
  2320. sig = self.docstring_sig_re.search(line)
  2321. if sig is None:
  2322. return []
  2323. # iterable[, key=func]' -> ['iterable[' ,' key=func]']
  2324. sig = sig.groups()[0].split(',')
  2325. ret = []
  2326. for s in sig:
  2327. #re.compile(r'[\s|\[]*(\w+)(?:\s*=\s*.*)')
  2328. ret += self.docstring_kwd_re.findall(s)
  2329. return ret
  2330. def _default_arguments(self, obj):
  2331. """Return the list of default arguments of obj if it is callable,
  2332. or empty list otherwise."""
  2333. call_obj = obj
  2334. ret = []
  2335. if inspect.isbuiltin(obj):
  2336. pass
  2337. elif not (inspect.isfunction(obj) or inspect.ismethod(obj)):
  2338. if inspect.isclass(obj):
  2339. #for cython embedsignature=True the constructor docstring
  2340. #belongs to the object itself not __init__
  2341. ret += self._default_arguments_from_docstring(
  2342. getattr(obj, '__doc__', ''))
  2343. # for classes, check for __init__,__new__
  2344. call_obj = (getattr(obj, '__init__', None) or
  2345. getattr(obj, '__new__', None))
  2346. # for all others, check if they are __call__able
  2347. elif hasattr(obj, '__call__'):
  2348. call_obj = obj.__call__
  2349. ret += self._default_arguments_from_docstring(
  2350. getattr(call_obj, '__doc__', ''))
  2351. _keeps = (inspect.Parameter.KEYWORD_ONLY,
  2352. inspect.Parameter.POSITIONAL_OR_KEYWORD)
  2353. try:
  2354. sig = inspect.signature(obj)
  2355. ret.extend(k for k, v in sig.parameters.items() if
  2356. v.kind in _keeps)
  2357. except ValueError:
  2358. pass
  2359. return list(set(ret))
  2360. @context_matcher()
  2361. def python_func_kw_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
  2362. """Match named parameters (kwargs) of the last open function."""
  2363. matches = self.python_func_kw_matches(context.token)
  2364. return _convert_matcher_v1_result_to_v2_no_no(matches, type="param")
  2365. def python_func_kw_matches(self, text):
  2366. """Match named parameters (kwargs) of the last open function.
  2367. .. deprecated:: 8.6
  2368. You can use :meth:`python_func_kw_matcher` instead.
  2369. """
  2370. if "." in text: # a parameter cannot be dotted
  2371. return []
  2372. try: regexp = self.__funcParamsRegex
  2373. except AttributeError:
  2374. regexp = self.__funcParamsRegex = re.compile(r'''
  2375. '.*?(?<!\\)' | # single quoted strings or
  2376. ".*?(?<!\\)" | # double quoted strings or
  2377. \w+ | # identifier
  2378. \S # other characters
  2379. ''', re.VERBOSE | re.DOTALL)
  2380. # 1. find the nearest identifier that comes before an unclosed
  2381. # parenthesis before the cursor
  2382. # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
  2383. tokens = regexp.findall(self.text_until_cursor)
  2384. iterTokens = reversed(tokens)
  2385. openPar = 0
  2386. for token in iterTokens:
  2387. if token == ')':
  2388. openPar -= 1
  2389. elif token == '(':
  2390. openPar += 1
  2391. if openPar > 0:
  2392. # found the last unclosed parenthesis
  2393. break
  2394. else:
  2395. return []
  2396. # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
  2397. ids = []
  2398. isId = re.compile(r'\w+$').match
  2399. while True:
  2400. try:
  2401. ids.append(next(iterTokens))
  2402. if not isId(ids[-1]):
  2403. ids.pop()
  2404. break
  2405. if not next(iterTokens) == '.':
  2406. break
  2407. except StopIteration:
  2408. break
  2409. # Find all named arguments already assigned to, as to avoid suggesting
  2410. # them again
  2411. usedNamedArgs = set()
  2412. par_level = -1
  2413. for token, next_token in zip(tokens, tokens[1:]):
  2414. if token == '(':
  2415. par_level += 1
  2416. elif token == ')':
  2417. par_level -= 1
  2418. if par_level != 0:
  2419. continue
  2420. if next_token != '=':
  2421. continue
  2422. usedNamedArgs.add(token)
  2423. argMatches = []
  2424. try:
  2425. callableObj = '.'.join(ids[::-1])
  2426. namedArgs = self._default_arguments(eval(callableObj,
  2427. self.namespace))
  2428. # Remove used named arguments from the list, no need to show twice
  2429. for namedArg in set(namedArgs) - usedNamedArgs:
  2430. if namedArg.startswith(text):
  2431. argMatches.append("%s=" %namedArg)
  2432. except:
  2433. pass
  2434. return argMatches
  2435. @staticmethod
  2436. def _get_keys(obj: Any) -> list[Any]:
  2437. # Objects can define their own completions by defining an
  2438. # _ipy_key_completions_() method.
  2439. method = get_real_method(obj, '_ipython_key_completions_')
  2440. if method is not None:
  2441. return method()
  2442. # Special case some common in-memory dict-like types
  2443. if isinstance(obj, dict) or _safe_isinstance(obj, "pandas", "DataFrame"):
  2444. try:
  2445. return list(obj.keys())
  2446. except Exception:
  2447. return []
  2448. elif _safe_isinstance(obj, "pandas", "core", "indexing", "_LocIndexer"):
  2449. try:
  2450. return list(obj.obj.keys())
  2451. except Exception:
  2452. return []
  2453. elif _safe_isinstance(obj, 'numpy', 'ndarray') or\
  2454. _safe_isinstance(obj, 'numpy', 'void'):
  2455. return obj.dtype.names or []
  2456. return []
  2457. @context_matcher()
  2458. def dict_key_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
  2459. """Match string keys in a dictionary, after e.g. ``foo[``."""
  2460. matches = self.dict_key_matches(context.token)
  2461. return _convert_matcher_v1_result_to_v2(
  2462. matches, type="dict key", suppress_if_matches=True
  2463. )
  2464. def dict_key_matches(self, text: str) -> list[str]:
  2465. """Match string keys in a dictionary, after e.g. ``foo[``.
  2466. .. deprecated:: 8.6
  2467. You can use :meth:`dict_key_matcher` instead.
  2468. """
  2469. # Short-circuit on closed dictionary (regular expression would
  2470. # not match anyway, but would take quite a while).
  2471. if self.text_until_cursor.strip().endswith("]"):
  2472. return []
  2473. match = DICT_MATCHER_REGEX.search(self.text_until_cursor)
  2474. if match is None:
  2475. return []
  2476. expr, prior_tuple_keys, key_prefix = match.groups()
  2477. obj = self._evaluate_expr(expr)
  2478. if obj is not_found:
  2479. return []
  2480. keys = self._get_keys(obj)
  2481. if not keys:
  2482. return keys
  2483. tuple_prefix = guarded_eval(
  2484. prior_tuple_keys,
  2485. EvaluationContext(
  2486. globals=self.global_namespace,
  2487. locals=self.namespace,
  2488. evaluation=self.evaluation, # type: ignore
  2489. in_subscript=True,
  2490. auto_import=self._auto_import,
  2491. policy_overrides=self.policy_overrides,
  2492. ),
  2493. )
  2494. closing_quote, token_offset, matches = match_dict_keys(
  2495. keys, key_prefix, self.splitter.delims, extra_prefix=tuple_prefix
  2496. )
  2497. if not matches:
  2498. return []
  2499. # get the cursor position of
  2500. # - the text being completed
  2501. # - the start of the key text
  2502. # - the start of the completion
  2503. text_start = len(self.text_until_cursor) - len(text)
  2504. if key_prefix:
  2505. key_start = match.start(3)
  2506. completion_start = key_start + token_offset
  2507. else:
  2508. key_start = completion_start = match.end()
  2509. # grab the leading prefix, to make sure all completions start with `text`
  2510. if text_start > key_start:
  2511. leading = ''
  2512. else:
  2513. leading = text[text_start:completion_start]
  2514. # append closing quote and bracket as appropriate
  2515. # this is *not* appropriate if the opening quote or bracket is outside
  2516. # the text given to this method, e.g. `d["""a\nt
  2517. can_close_quote = False
  2518. can_close_bracket = False
  2519. continuation = self.line_buffer[len(self.text_until_cursor) :].strip()
  2520. if continuation.startswith(closing_quote):
  2521. # do not close if already closed, e.g. `d['a<tab>'`
  2522. continuation = continuation[len(closing_quote) :]
  2523. else:
  2524. can_close_quote = True
  2525. continuation = continuation.strip()
  2526. # e.g. `pandas.DataFrame` has different tuple indexer behaviour,
  2527. # handling it is out of scope, so let's avoid appending suffixes.
  2528. has_known_tuple_handling = isinstance(obj, dict)
  2529. can_close_bracket = (
  2530. not continuation.startswith("]") and self.auto_close_dict_keys
  2531. )
  2532. can_close_tuple_item = (
  2533. not continuation.startswith(",")
  2534. and has_known_tuple_handling
  2535. and self.auto_close_dict_keys
  2536. )
  2537. can_close_quote = can_close_quote and self.auto_close_dict_keys
  2538. # fast path if closing quote should be appended but not suffix is allowed
  2539. if not can_close_quote and not can_close_bracket and closing_quote:
  2540. return [leading + k for k in matches]
  2541. results = []
  2542. end_of_tuple_or_item = _DictKeyState.END_OF_TUPLE | _DictKeyState.END_OF_ITEM
  2543. for k, state_flag in matches.items():
  2544. result = leading + k
  2545. if can_close_quote and closing_quote:
  2546. result += closing_quote
  2547. if state_flag == end_of_tuple_or_item:
  2548. # We do not know which suffix to add,
  2549. # e.g. both tuple item and string
  2550. # match this item.
  2551. pass
  2552. if state_flag in end_of_tuple_or_item and can_close_bracket:
  2553. result += "]"
  2554. if state_flag == _DictKeyState.IN_TUPLE and can_close_tuple_item:
  2555. result += ", "
  2556. results.append(result)
  2557. return results
  2558. @context_matcher()
  2559. def unicode_name_matcher(self, context: CompletionContext) -> SimpleMatcherResult:
  2560. """Match Latex-like syntax for unicode characters base
  2561. on the name of the character.
  2562. This does ``\\GREEK SMALL LETTER ETA`` -> ``η``
  2563. Works only on valid python 3 identifier, or on combining characters that
  2564. will combine to form a valid identifier.
  2565. """
  2566. text = context.text_until_cursor
  2567. slashpos = text.rfind('\\')
  2568. if slashpos > -1:
  2569. s = text[slashpos+1:]
  2570. try :
  2571. unic = unicodedata.lookup(s)
  2572. # allow combining chars
  2573. if ('a'+unic).isidentifier():
  2574. return {
  2575. "completions": [SimpleCompletion(text=unic, type="unicode")],
  2576. "suppress": True,
  2577. "matched_fragment": "\\" + s,
  2578. }
  2579. except KeyError:
  2580. pass
  2581. return {
  2582. "completions": [],
  2583. "suppress": False,
  2584. }
  2585. @context_matcher()
  2586. def latex_name_matcher(self, context: CompletionContext):
  2587. """Match Latex syntax for unicode characters.
  2588. This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``α``
  2589. """
  2590. fragment, matches = self.latex_matches(context.text_until_cursor)
  2591. return _convert_matcher_v1_result_to_v2(
  2592. matches, type="latex", fragment=fragment, suppress_if_matches=True
  2593. )
  2594. def latex_matches(self, text: str) -> tuple[str, Sequence[str]]:
  2595. """Match Latex syntax for unicode characters.
  2596. This does both ``\\alp`` -> ``\\alpha`` and ``\\alpha`` -> ``α``
  2597. .. deprecated:: 8.6
  2598. You can use :meth:`latex_name_matcher` instead.
  2599. """
  2600. slashpos = text.rfind('\\')
  2601. if slashpos > -1:
  2602. s = text[slashpos:]
  2603. if s in latex_symbols:
  2604. # Try to complete a full latex symbol to unicode
  2605. # \\alpha -> α
  2606. return s, [latex_symbols[s]]
  2607. else:
  2608. # If a user has partially typed a latex symbol, give them
  2609. # a full list of options \al -> [\aleph, \alpha]
  2610. matches = [k for k in latex_symbols if k.startswith(s)]
  2611. if matches:
  2612. return s, matches
  2613. return '', ()
  2614. @context_matcher()
  2615. def custom_completer_matcher(self, context):
  2616. """Dispatch custom completer.
  2617. If a match is found, suppresses all other matchers except for Jedi.
  2618. """
  2619. matches = self.dispatch_custom_completer(context.token) or []
  2620. result = _convert_matcher_v1_result_to_v2(
  2621. matches, type=_UNKNOWN_TYPE, suppress_if_matches=True
  2622. )
  2623. result["ordered"] = True
  2624. result["do_not_suppress"] = {_get_matcher_id(self._jedi_matcher)}
  2625. return result
  2626. def dispatch_custom_completer(self, text):
  2627. """
  2628. .. deprecated:: 8.6
  2629. You can use :meth:`custom_completer_matcher` instead.
  2630. """
  2631. if not self.custom_completers:
  2632. return
  2633. line = self.line_buffer
  2634. if not line.strip():
  2635. return None
  2636. # Create a little structure to pass all the relevant information about
  2637. # the current completion to any custom completer.
  2638. event = SimpleNamespace()
  2639. event.line = line
  2640. event.symbol = text
  2641. cmd = line.split(None,1)[0]
  2642. event.command = cmd
  2643. event.text_until_cursor = self.text_until_cursor
  2644. # for foo etc, try also to find completer for %foo
  2645. if not cmd.startswith(self.magic_escape):
  2646. try_magic = self.custom_completers.s_matches(
  2647. self.magic_escape + cmd)
  2648. else:
  2649. try_magic = []
  2650. for c in itertools.chain(self.custom_completers.s_matches(cmd),
  2651. try_magic,
  2652. self.custom_completers.flat_matches(self.text_until_cursor)):
  2653. try:
  2654. res = c(event)
  2655. if res:
  2656. # first, try case sensitive match
  2657. withcase = [r for r in res if r.startswith(text)]
  2658. if withcase:
  2659. return withcase
  2660. # if none, then case insensitive ones are ok too
  2661. text_low = text.lower()
  2662. return [r for r in res if r.lower().startswith(text_low)]
  2663. except TryNext:
  2664. pass
  2665. except KeyboardInterrupt:
  2666. """
  2667. If custom completer take too long,
  2668. let keyboard interrupt abort and return nothing.
  2669. """
  2670. break
  2671. return None
  2672. def completions(self, text: str, offset: int)->Iterator[Completion]:
  2673. """
  2674. Returns an iterator over the possible completions
  2675. .. warning::
  2676. Unstable
  2677. This function is unstable, API may change without warning.
  2678. It will also raise unless use in proper context manager.
  2679. Parameters
  2680. ----------
  2681. text : str
  2682. Full text of the current input, multi line string.
  2683. offset : int
  2684. Integer representing the position of the cursor in ``text``. Offset
  2685. is 0-based indexed.
  2686. Yields
  2687. ------
  2688. Completion
  2689. Notes
  2690. -----
  2691. The cursor on a text can either be seen as being "in between"
  2692. characters or "On" a character depending on the interface visible to
  2693. the user. For consistency the cursor being on "in between" characters X
  2694. and Y is equivalent to the cursor being "on" character Y, that is to say
  2695. the character the cursor is on is considered as being after the cursor.
  2696. Combining characters may span more that one position in the
  2697. text.
  2698. .. note::
  2699. If ``IPCompleter.debug`` is :py:data:`True` will yield a ``--jedi/ipython--``
  2700. fake Completion token to distinguish completion returned by Jedi
  2701. and usual IPython completion.
  2702. .. note::
  2703. Completions are not completely deduplicated yet. If identical
  2704. completions are coming from different sources this function does not
  2705. ensure that each completion object will only be present once.
  2706. """
  2707. warnings.warn("_complete is a provisional API (as of IPython 6.0). "
  2708. "It may change without warnings. "
  2709. "Use in corresponding context manager.",
  2710. category=ProvisionalCompleterWarning, stacklevel=2)
  2711. seen = set()
  2712. profiler:Optional[cProfile.Profile]
  2713. try:
  2714. if self.profile_completions:
  2715. import cProfile
  2716. profiler = cProfile.Profile()
  2717. profiler.enable()
  2718. else:
  2719. profiler = None
  2720. for c in self._completions(text, offset, _timeout=self.jedi_compute_type_timeout/1000):
  2721. if c and (c in seen):
  2722. continue
  2723. yield c
  2724. seen.add(c)
  2725. except KeyboardInterrupt:
  2726. """if completions take too long and users send keyboard interrupt,
  2727. do not crash and return ASAP. """
  2728. pass
  2729. finally:
  2730. if profiler is not None:
  2731. profiler.disable()
  2732. ensure_dir_exists(self.profiler_output_dir)
  2733. output_path = os.path.join(self.profiler_output_dir, str(uuid.uuid4()))
  2734. print("Writing profiler output to", output_path)
  2735. profiler.dump_stats(output_path)
  2736. def _completions(self, full_text: str, offset: int, *, _timeout) -> Iterator[Completion]:
  2737. """
  2738. Core completion module.Same signature as :any:`completions`, with the
  2739. extra `timeout` parameter (in seconds).
  2740. Computing jedi's completion ``.type`` can be quite expensive (it is a
  2741. lazy property) and can require some warm-up, more warm up than just
  2742. computing the ``name`` of a completion. The warm-up can be :
  2743. - Long warm-up the first time a module is encountered after
  2744. install/update: actually build parse/inference tree.
  2745. - first time the module is encountered in a session: load tree from
  2746. disk.
  2747. We don't want to block completions for tens of seconds so we give the
  2748. completer a "budget" of ``_timeout`` seconds per invocation to compute
  2749. completions types, the completions that have not yet been computed will
  2750. be marked as "unknown" an will have a chance to be computed next round
  2751. are things get cached.
  2752. Keep in mind that Jedi is not the only thing treating the completion so
  2753. keep the timeout short-ish as if we take more than 0.3 second we still
  2754. have lots of processing to do.
  2755. """
  2756. deadline = time.monotonic() + _timeout
  2757. before = full_text[:offset]
  2758. cursor_line, cursor_column = position_to_cursor(full_text, offset)
  2759. jedi_matcher_id = _get_matcher_id(self._jedi_matcher)
  2760. def is_non_jedi_result(
  2761. result: MatcherResult, identifier: str
  2762. ) -> TypeGuard[SimpleMatcherResult]:
  2763. return identifier != jedi_matcher_id
  2764. results = self._complete(
  2765. full_text=full_text, cursor_line=cursor_line, cursor_pos=cursor_column
  2766. )
  2767. non_jedi_results: dict[str, SimpleMatcherResult] = {
  2768. identifier: result
  2769. for identifier, result in results.items()
  2770. if is_non_jedi_result(result, identifier)
  2771. }
  2772. jedi_matches = (
  2773. cast(_JediMatcherResult, results[jedi_matcher_id])["completions"]
  2774. if jedi_matcher_id in results
  2775. else ()
  2776. )
  2777. iter_jm = iter(jedi_matches)
  2778. if _timeout:
  2779. for jm in iter_jm:
  2780. try:
  2781. type_ = jm.type
  2782. except Exception:
  2783. if self.debug:
  2784. print("Error in Jedi getting type of ", jm)
  2785. type_ = None
  2786. delta = len(jm.name_with_symbols) - len(jm.complete)
  2787. if type_ == 'function':
  2788. signature = _make_signature(jm)
  2789. else:
  2790. signature = ''
  2791. yield Completion(start=offset - delta,
  2792. end=offset,
  2793. text=jm.name_with_symbols,
  2794. type=type_,
  2795. signature=signature,
  2796. _origin='jedi')
  2797. if time.monotonic() > deadline:
  2798. break
  2799. for jm in iter_jm:
  2800. delta = len(jm.name_with_symbols) - len(jm.complete)
  2801. yield Completion(
  2802. start=offset - delta,
  2803. end=offset,
  2804. text=jm.name_with_symbols,
  2805. type=_UNKNOWN_TYPE, # don't compute type for speed
  2806. _origin="jedi",
  2807. signature="",
  2808. )
  2809. # TODO:
  2810. # Suppress this, right now just for debug.
  2811. if jedi_matches and non_jedi_results and self.debug:
  2812. some_start_offset = before.rfind(
  2813. next(iter(non_jedi_results.values()))["matched_fragment"]
  2814. )
  2815. yield Completion(
  2816. start=some_start_offset,
  2817. end=offset,
  2818. text="--jedi/ipython--",
  2819. _origin="debug",
  2820. type="none",
  2821. signature="",
  2822. )
  2823. ordered: list[Completion] = []
  2824. sortable: list[Completion] = []
  2825. for origin, result in non_jedi_results.items():
  2826. matched_text = result["matched_fragment"]
  2827. start_offset = before.rfind(matched_text)
  2828. is_ordered = result.get("ordered", False)
  2829. container = ordered if is_ordered else sortable
  2830. # I'm unsure if this is always true, so let's assert and see if it
  2831. # crash
  2832. assert before.endswith(matched_text)
  2833. for simple_completion in result["completions"]:
  2834. completion = Completion(
  2835. start=start_offset,
  2836. end=offset,
  2837. text=simple_completion.text,
  2838. _origin=origin,
  2839. signature="",
  2840. type=simple_completion.type or _UNKNOWN_TYPE,
  2841. )
  2842. container.append(completion)
  2843. yield from list(self._deduplicate(ordered + self._sort(sortable)))[
  2844. :MATCHES_LIMIT
  2845. ]
  2846. def complete(
  2847. self, text=None, line_buffer=None, cursor_pos=None
  2848. ) -> tuple[str, Sequence[str]]:
  2849. """Find completions for the given text and line context.
  2850. Note that both the text and the line_buffer are optional, but at least
  2851. one of them must be given.
  2852. Parameters
  2853. ----------
  2854. text : string, optional
  2855. Text to perform the completion on. If not given, the line buffer
  2856. is split using the instance's CompletionSplitter object.
  2857. line_buffer : string, optional
  2858. If not given, the completer attempts to obtain the current line
  2859. buffer via readline. This keyword allows clients which are
  2860. requesting for text completions in non-readline contexts to inform
  2861. the completer of the entire text.
  2862. cursor_pos : int, optional
  2863. Index of the cursor in the full line buffer. Should be provided by
  2864. remote frontends where kernel has no access to frontend state.
  2865. Returns
  2866. -------
  2867. Tuple of two items:
  2868. text : str
  2869. Text that was actually used in the completion.
  2870. matches : list
  2871. A list of completion matches.
  2872. Notes
  2873. -----
  2874. This API is likely to be deprecated and replaced by
  2875. :any:`IPCompleter.completions` in the future.
  2876. """
  2877. warnings.warn('`Completer.complete` is pending deprecation since '
  2878. 'IPython 6.0 and will be replaced by `Completer.completions`.',
  2879. PendingDeprecationWarning)
  2880. # potential todo, FOLD the 3rd throw away argument of _complete
  2881. # into the first 2 one.
  2882. # TODO: Q: does the above refer to jedi completions (i.e. 0-indexed?)
  2883. # TODO: should we deprecate now, or does it stay?
  2884. results = self._complete(
  2885. line_buffer=line_buffer, cursor_pos=cursor_pos, text=text, cursor_line=0
  2886. )
  2887. jedi_matcher_id = _get_matcher_id(self._jedi_matcher)
  2888. return self._arrange_and_extract(
  2889. results,
  2890. # TODO: can we confirm that excluding Jedi here was a deliberate choice in previous version?
  2891. skip_matchers={jedi_matcher_id},
  2892. # this API does not support different start/end positions (fragments of token).
  2893. abort_if_offset_changes=True,
  2894. )
  2895. def _arrange_and_extract(
  2896. self,
  2897. results: dict[str, MatcherResult],
  2898. skip_matchers: set[str],
  2899. abort_if_offset_changes: bool,
  2900. ):
  2901. sortable: list[AnyMatcherCompletion] = []
  2902. ordered: list[AnyMatcherCompletion] = []
  2903. most_recent_fragment = None
  2904. for identifier, result in results.items():
  2905. if identifier in skip_matchers:
  2906. continue
  2907. if not result["completions"]:
  2908. continue
  2909. if not most_recent_fragment:
  2910. most_recent_fragment = result["matched_fragment"]
  2911. if (
  2912. abort_if_offset_changes
  2913. and result["matched_fragment"] != most_recent_fragment
  2914. ):
  2915. break
  2916. if result.get("ordered", False):
  2917. ordered.extend(result["completions"])
  2918. else:
  2919. sortable.extend(result["completions"])
  2920. if not most_recent_fragment:
  2921. most_recent_fragment = "" # to satisfy typechecker (and just in case)
  2922. return most_recent_fragment, [
  2923. m.text for m in self._deduplicate(ordered + self._sort(sortable))
  2924. ]
  2925. def _complete(self, *, cursor_line, cursor_pos, line_buffer=None, text=None,
  2926. full_text=None) -> _CompleteResult:
  2927. """
  2928. Like complete but can also returns raw jedi completions as well as the
  2929. origin of the completion text. This could (and should) be made much
  2930. cleaner but that will be simpler once we drop the old (and stateful)
  2931. :any:`complete` API.
  2932. With current provisional API, cursor_pos act both (depending on the
  2933. caller) as the offset in the ``text`` or ``line_buffer``, or as the
  2934. ``column`` when passing multiline strings this could/should be renamed
  2935. but would add extra noise.
  2936. Parameters
  2937. ----------
  2938. cursor_line
  2939. Index of the line the cursor is on. 0 indexed.
  2940. cursor_pos
  2941. Position of the cursor in the current line/line_buffer/text. 0
  2942. indexed.
  2943. line_buffer : optional, str
  2944. The current line the cursor is in, this is mostly due to legacy
  2945. reason that readline could only give a us the single current line.
  2946. Prefer `full_text`.
  2947. text : str
  2948. The current "token" the cursor is in, mostly also for historical
  2949. reasons. as the completer would trigger only after the current line
  2950. was parsed.
  2951. full_text : str
  2952. Full text of the current cell.
  2953. Returns
  2954. -------
  2955. An ordered dictionary where keys are identifiers of completion
  2956. matchers and values are ``MatcherResult``s.
  2957. """
  2958. # if the cursor position isn't given, the only sane assumption we can
  2959. # make is that it's at the end of the line (the common case)
  2960. if cursor_pos is None:
  2961. cursor_pos = len(line_buffer) if text is None else len(text)
  2962. if self.use_main_ns:
  2963. self.namespace = __main__.__dict__
  2964. # if text is either None or an empty string, rely on the line buffer
  2965. if (not line_buffer) and full_text:
  2966. line_buffer = full_text.split('\n')[cursor_line]
  2967. if not text: # issue #11508: check line_buffer before calling split_line
  2968. text = (
  2969. self.splitter.split_line(line_buffer, cursor_pos) if line_buffer else ""
  2970. )
  2971. # If no line buffer is given, assume the input text is all there was
  2972. if line_buffer is None:
  2973. line_buffer = text
  2974. # deprecated - do not use `line_buffer` in new code.
  2975. self.line_buffer = line_buffer
  2976. self.text_until_cursor = self.line_buffer[:cursor_pos]
  2977. if not full_text:
  2978. full_text = line_buffer
  2979. context = CompletionContext(
  2980. full_text=full_text,
  2981. cursor_position=cursor_pos,
  2982. cursor_line=cursor_line,
  2983. token=self._extract_code(text),
  2984. limit=MATCHES_LIMIT,
  2985. )
  2986. # Start with a clean slate of completions
  2987. results: dict[str, MatcherResult] = {}
  2988. jedi_matcher_id = _get_matcher_id(self._jedi_matcher)
  2989. suppressed_matchers: set[str] = set()
  2990. matchers = {
  2991. _get_matcher_id(matcher): matcher
  2992. for matcher in sorted(
  2993. self.matchers, key=_get_matcher_priority, reverse=True
  2994. )
  2995. }
  2996. for matcher_id, matcher in matchers.items():
  2997. matcher_id = _get_matcher_id(matcher)
  2998. if matcher_id in self.disable_matchers:
  2999. continue
  3000. if matcher_id in results:
  3001. warnings.warn(f"Duplicate matcher ID: {matcher_id}.")
  3002. if matcher_id in suppressed_matchers:
  3003. continue
  3004. result: MatcherResult
  3005. try:
  3006. if _is_matcher_v1(matcher):
  3007. result = _convert_matcher_v1_result_to_v2_no_no(
  3008. matcher(text), type=_UNKNOWN_TYPE
  3009. )
  3010. elif _is_matcher_v2(matcher):
  3011. result = matcher(context)
  3012. else:
  3013. api_version = _get_matcher_api_version(matcher)
  3014. raise ValueError(f"Unsupported API version {api_version}")
  3015. except BaseException:
  3016. # Show the ugly traceback if the matcher causes an
  3017. # exception, but do NOT crash the kernel!
  3018. sys.excepthook(*sys.exc_info())
  3019. continue
  3020. # set default value for matched fragment if suffix was not selected.
  3021. result["matched_fragment"] = result.get("matched_fragment", context.token)
  3022. if not suppressed_matchers:
  3023. suppression_recommended: Union[bool, set[str]] = result.get(
  3024. "suppress", False
  3025. )
  3026. suppression_config = (
  3027. self.suppress_competing_matchers.get(matcher_id, None)
  3028. if isinstance(self.suppress_competing_matchers, dict)
  3029. else self.suppress_competing_matchers
  3030. )
  3031. should_suppress = (
  3032. (suppression_config is True)
  3033. or (suppression_recommended and (suppression_config is not False))
  3034. ) and has_any_completions(result)
  3035. if should_suppress:
  3036. suppression_exceptions: set[str] = result.get(
  3037. "do_not_suppress", set()
  3038. )
  3039. if isinstance(suppression_recommended, Iterable):
  3040. to_suppress = set(suppression_recommended)
  3041. else:
  3042. to_suppress = set(matchers)
  3043. suppressed_matchers = to_suppress - suppression_exceptions
  3044. new_results = {}
  3045. for previous_matcher_id, previous_result in results.items():
  3046. if previous_matcher_id not in suppressed_matchers:
  3047. new_results[previous_matcher_id] = previous_result
  3048. results = new_results
  3049. results[matcher_id] = result
  3050. _, matches = self._arrange_and_extract(
  3051. results,
  3052. # TODO Jedi completions non included in legacy stateful API; was this deliberate or omission?
  3053. # if it was omission, we can remove the filtering step, otherwise remove this comment.
  3054. skip_matchers={jedi_matcher_id},
  3055. abort_if_offset_changes=False,
  3056. )
  3057. # populate legacy stateful API
  3058. self.matches = matches
  3059. return results
  3060. @staticmethod
  3061. def _deduplicate(
  3062. matches: Sequence[AnyCompletion],
  3063. ) -> Iterable[AnyCompletion]:
  3064. filtered_matches: dict[str, AnyCompletion] = {}
  3065. for match in matches:
  3066. text = match.text
  3067. if (
  3068. text not in filtered_matches
  3069. or filtered_matches[text].type == _UNKNOWN_TYPE
  3070. ):
  3071. filtered_matches[text] = match
  3072. return filtered_matches.values()
  3073. @staticmethod
  3074. def _sort(matches: Sequence[AnyCompletion]):
  3075. return sorted(matches, key=lambda x: completions_sorting_key(x.text))
  3076. @context_matcher()
  3077. def fwd_unicode_matcher(self, context: CompletionContext):
  3078. """Same as :any:`fwd_unicode_match`, but adopted to new Matcher API."""
  3079. # TODO: use `context.limit` to terminate early once we matched the maximum
  3080. # number that will be used downstream; can be added as an optional to
  3081. # `fwd_unicode_match(text: str, limit: int = None)` or we could re-implement here.
  3082. fragment, matches = self.fwd_unicode_match(context.text_until_cursor)
  3083. return _convert_matcher_v1_result_to_v2(
  3084. matches, type="unicode", fragment=fragment, suppress_if_matches=True
  3085. )
  3086. def fwd_unicode_match(self, text: str) -> tuple[str, Sequence[str]]:
  3087. """
  3088. Forward match a string starting with a backslash with a list of
  3089. potential Unicode completions.
  3090. Will compute list of Unicode character names on first call and cache it.
  3091. .. deprecated:: 8.6
  3092. You can use :meth:`fwd_unicode_matcher` instead.
  3093. Returns
  3094. -------
  3095. At tuple with:
  3096. - matched text (empty if no matches)
  3097. - list of potential completions, empty tuple otherwise)
  3098. """
  3099. # TODO: self.unicode_names is here a list we traverse each time with ~100k elements.
  3100. # We could do a faster match using a Trie.
  3101. # Using pygtrie the following seem to work:
  3102. # s = PrefixSet()
  3103. # for c in range(0,0x10FFFF + 1):
  3104. # try:
  3105. # s.add(unicodedata.name(chr(c)))
  3106. # except ValueError:
  3107. # pass
  3108. # [''.join(k) for k in s.iter(prefix)]
  3109. # But need to be timed and adds an extra dependency.
  3110. slashpos = text.rfind('\\')
  3111. # if text starts with slash
  3112. if slashpos > -1:
  3113. # PERF: It's important that we don't access self._unicode_names
  3114. # until we're inside this if-block. _unicode_names is lazily
  3115. # initialized, and it takes a user-noticeable amount of time to
  3116. # initialize it, so we don't want to initialize it unless we're
  3117. # actually going to use it.
  3118. s = text[slashpos + 1 :]
  3119. sup = s.upper()
  3120. candidates = [x for x in self.unicode_names if x.startswith(sup)]
  3121. if candidates:
  3122. return s, candidates
  3123. candidates = [x for x in self.unicode_names if sup in x]
  3124. if candidates:
  3125. return s, candidates
  3126. splitsup = sup.split(" ")
  3127. candidates = [
  3128. x for x in self.unicode_names if all(u in x for u in splitsup)
  3129. ]
  3130. if candidates:
  3131. return s, candidates
  3132. return "", ()
  3133. # if text does not start with slash
  3134. else:
  3135. return '', ()
  3136. @property
  3137. def unicode_names(self) -> list[str]:
  3138. """List of names of unicode code points that can be completed.
  3139. The list is lazily initialized on first access.
  3140. """
  3141. if self._unicode_names is None:
  3142. names = []
  3143. for c in range(0,0x10FFFF + 1):
  3144. try:
  3145. names.append(unicodedata.name(chr(c)))
  3146. except ValueError:
  3147. pass
  3148. self._unicode_names = _unicode_name_compute(_UNICODE_RANGES)
  3149. return self._unicode_names
  3150. def _unicode_name_compute(ranges: list[tuple[int, int]]) -> list[str]:
  3151. names = []
  3152. for start,stop in ranges:
  3153. for c in range(start, stop) :
  3154. try:
  3155. names.append(unicodedata.name(chr(c)))
  3156. except ValueError:
  3157. pass
  3158. return names