B _L(@sUddlZddlZddlmZmZddlmZddlmZm Z m Z ddl m Z ddl m Z ddlmZddlmZmZmZddlZddlZddlZdd lmZmZddlZdd lmZddlZddlZddl Z ddl!Z!ddl"Z"ddl#Z#ddl$Z$dd l%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9dd l:m;Z;dd lm?Z?ddl@mAZAmBZBmCZCddlDZDddlEZEddlFmGZGmHZHddlImJZJddlKmLZLmMZMmNZNddlOmPZPmQZQddlRmSZSmTZTddlUmVZVddlWmXZXddlYmZZ[e9rddl\Z\dZ]dZ^dZ_ee?de[dZ`dZae;ebd<ecZdecZeecZfegZhegZiegZjegZkegZlegZmegZne7eMeLfZoe'de(dge-dfZpeqZregZse4eresfZte)eetfZueeDjvd d d!ZweeDjvd"d d#ZxePye`ePjzZ{Gd$d%d%e|Z}Gd&d'd'e~ZGd(d)d)eZGd*d+d+eZe6d,Ze6d-e~d.ZGd/d0d0e+eZGd1d2d2e+eZe7eeeefZeeefZeenZGd3d4d4eZGd5d6d6eZGd7d8d8eZejejejhZGd9ddeZejejhejejejhejejejhejejejejhejejejejejejejhejejejejejejejhejejejejejejejejejhiZe)ee2efebd:<eAGd;d<d<ZeZe2eeed=d>d?Ze,ece/ecd@dAdBZece)ece&fdCdDdEZeDjeDje/ece/ecdFdGdHZeDje7eDjeDjfe4ecdIfe.edJdKdLZeDjedMdNgdOdPeDjdQdRecdSdTeDjdUdVege]dWd dXeDjdYdZeDd[d\eDed d]d^eDjd_d d`daeDjdbdcd dddaeDjded d dfdgeDjdhd didaeDjdjd dkdaeDjdld dmdaeDjdnd dodaeDjdpece_dqd dXeDjdrece^dsd dXeDjdtecdudTeDjdvdwd dxdaeDjdydzd d{daeDje[deDjd|d}eDjd d d d d d~d deDjdeDjd d dd decdd eddeDjeDje/ecege.eeeeeeeeeeecece/ece4ecdIfe/ecddddZeDje4ecdIfeeecece/ecde2ed ddZe3eceeeDjddddZeeeedddddZe2eeeedddddZe2eeeedejeddddZejdfeeeee&edddZececdddZeje7ejdfdddZejdeeeedddZeceeeddddZeceeddddZee4edeeeffdddZe2ee.eVdddZÐd"ece,eeLdddZeLecdddZGddde+eZeAGdddeeZeTjeTjeTjhZe;ebd<e{je{je{je{je{je{je{je{jhZe;ebd<dZe;ebd<deTje<ddhZe;ebd<eTjeTjeTjeTjeTjeTjhZe;ebd<eTjeTjeTjeTjeTjeTjeTjeTjeTjeTjeTjeTjeTjeTjhZe;ebd<eTjeTjhZe;ebd<eeTjhBZe;ebd<e{je{je{je{je{jhZe;ebd<e{je{je{je{je{jhZe;ebd<e{je{je{je{je{je{je{je{je{je{je{je{je{je{je{jhZ e;ebd<ddddddddddddddhZ e;ebd<dڐZ e;ebd<dܐZ e;ebd<dސZ e;ebd<dZe;ebd<dZe;ebd<dZe;ebd<eTjdeTjdeTjdeTjdeTjdeTjdeTjdeTjdeTjdeTjdeTjdeTjdeTjdeTjdiZe;ebd<dZe;ebd<eAGdddZeAGdddZeAGdddZeAGdddeƐeZe{je{je{jhZeTjeTjeTjeTjeTjeTjiZ e!e "Z#e!e $Z%e#e%BZ&e%eTj'ehBZ(eMeecdddZ)e/eoe/eMdddZ*e/eoe.e/eiedddZ+eLeoe/eodddZ,eMeodddZ-d#eMe/eMemdddZ.d$eMe/eMemdd d Z/d d d hZ0dddhZ1eoe-eMdddZ2eAGdddZ3eddecee.e3dddZ4ececdddZ5d%eee(ee-edddZ6eAGd d!d!eZ7eAGd"d#d#Z8Gd$d%d%Z9Gd&d'd'e9e7Z:Gd(d)d)e7Z;Gd*d+d+e7ZGd0d1d1Z?eceed2d3d4Z@e.eMed5d6d7ZAeMe'eogdfd8d9d:ZBeced;d<d=ZCe/eoe/eidd>d?ZDeMedd@dAZEeMeddBdCZFeMeddDdEZGe1e&e'eggefdFdGdHZHeecdIdJdKZIeee.eMddLdMdNZJeoeoddOdPdQZKececd;dRdSZLecdd;dTdUZMd&ee(ee-edVdWdXZNd'eege(ee(eke-edYdZd[ZOeeedd\d]d^ZPdd_e.eMeeMeed`dadbZQepepdcdddeZReRd(ee(ee-edfdgdhZSeRd)ee(ee-edfdidjZTeMeddkdlZUd*eMecedndodpZVeMeddqdrdsZWd+eMeddtdudvZXeMdddwdxZYeMdddydzZZececd{d|d}Z[eLe2ecdd~ddZ\eLddddZ]eLedddZ^eMe-eodddZ_eoedddZ`eoegedddZaeLe/egdddZbeoeoedddZceoedddZdeoedddZeeoe/eodddZfd deLeoeddddZgeoedddZheoedddZieoedddZjeMe2eiedddZkeMedddZleLedddZmeoedddZneoemdddZoeMddddZpeeMedddZqeMeMe.eMedddZreLe2edddZseLe2edddZteege-e2ekdddZueLe2ecdddZveeeJdddZweede/ecdddÄZxe,eee/e0ece0ece/e0ecdeJe-edĜdŐdƄZyee,ecedǜdȐdɄZzeAGdddZ{ece7ej|eGj|eHj|fddːd̄Z}e7ej|eGj|eHj|fe7ej|eGj|eHj|fdd͐d΄Z~d,e7ej|eGj|eHj|fege-ecdϜdАdфZececddҜdӐdԄZececedd՜d֐dׄZe=d d؍ececdٜdڐdۄZe e-ddܜdݐdބZecececececdߜddZe,dddddZejddddZe0ececececdddZece0ecdddZe1ee-e4enefdddZd-eee-e4eneMegfdddZdmdeegecedddZeedIddZd.eege(ekedddZeeMegedddZeeMegedddZe.eMe(eke4eMeMfdddZdmdeepee(eece.eddd Zeed d d Zeeud d dZeetdddZeue,ee4e2ee2efdddZeue,eeddddZddܜddZddܜddZeMedddZecececddd Zed!kr~edS(/N)ABCabstractmethod) defaultdict)ExecutorThreadPoolExecutorProcessPoolExecutor)contextmanager)datetime)Enum) lru_cachepartialwraps)Managerfreeze_support)Path)AnyCallable CollectionDict GeneratorGenericIterableIteratorListOptionalPatternSequenceSetSizedTupleTypeTypeVarUnioncast TYPE_CHECKING)Final) mypyc_attr)user_cache_dir) dataclassfieldreplace)ast3ast27)PathSpec)NodeLeaf type_repr)pygrampytree)drivertoken)Grammar) ParseError)versionXz_/(\.direnv|\.eggs|\.git|\.hg|\.mypy_cache|\.nox|\.tox|\.venv|\.svn|_build|buck-out|build|dist)/z\.pyi?$blackZfurbFURBSTRING_PREFIX_CHARSLineFeatureT)bolderrred)fgr>c@seZdZdZdS)NothingChangedz3Raised when reformatted code is the same as source.N)__name__ __module__ __qualname____doc__rFrF2/tmp/pip-unpacked-wheel-g953wevd/black/__init__.pyrAcsrAc@seZdZdZdS)CannotTransformz-Base class for errors raised by Transformers.N)rBrCrDrErFrFrFrGrHgsrHc@seZdZdZdS) CannotSplitzBA readable split that fits the allotted line length is impossible.N)rBrCrDrErFrFrFrGrIksrIc@seZdZdZdS) InvalidInputz7Raised when input source code fails all parse attempts.N)rBrCrDrErFrFrFrGrJosrJTE)boundc@s*eZdZeddddZedddZdS)OkN)valuereturncCs ||_dS)N)_value)selfrOrFrFrG__init__xsz Ok.__init__)rPcCs|jS)N)rQ)rRrFrFrGok{szOk.ok)rBrCrDrKrSrTrFrFrFrGrNwsrNc@s*eZdZeddddZedddZdS)ErrN)erPcCs ||_dS)N)_e)rRrVrFrFrGrSsz Err.__init__)rPcCs|jS)N)rW)rRrFrFrGr>szErr.err)rBrCrDrLrSr>rFrFrFrGrUsrUc@s>eZdZdZdZdZdZdZedde e e ddd d Z d S) WriteBackrF)color)checkdiffr]rPcCs,|r|s|jS|r|r|jS|r&|jS|jS)N)CHECK COLOR_DIFFDIFFYES)clsr^r_r]rFrFrGfrom_configurations zWriteBack.from_configurationN) rBrCrDNOrcrbr`ra classmethodboolrerFrFrFrGrXs rXc@seZdZdZdZdZdS)ChangedrrYrZN)rBrCrDrfCACHEDrcrFrFrFrGrisric@s6eZdZdZdZdZdZdZdZdZ e dd d Z d S) TargetVersionrZr[r\)rPcCs |tjkS)N)rkPY27)rRrFrFrG is_python2szTargetVersion.is_python2N) rBrCrDrpPY33PY34PY35PY36PY37PY38rhrqrFrFrFrGrksrkc@s4eZdZdZdZdZdZdZdZdZ dZ d Z d Z d S) r<rYrZr[r\rlrmrnro 2N) rBrCrDUNICODE_LITERALS F_STRINGSNUMERIC_UNDERSCORESTRAILING_COMMA_IN_CALLTRAILING_COMMA_IN_DEFASYNC_IDENTIFIERSASYNC_KEYWORDSASSIGNMENT_EXPRESSIONSPOS_ONLY_ARGUMENTSFORCE_OPTIONAL_PARENTHESESrFrFrFrGr<sVERSION_TO_FEATURESc@sbeZdZUeedZeeed<e Z e ed<dZ e ed<dZe ed<dZe ed<ed d d Zd S) Mode)default_factorytarget_versions line_lengthTstring_normalizationFexperimental_string_processingis_pyi)rPcCs^|jr*dddt|jdddD}nd}|t|jtt|jtt|jg}d|S) N,css|]}t|jVqdS)N)strrO).0r7rFrFrG sz%Mode.get_cache_key..cSs|jS)N)rO)vrFrFrGz$Mode.get_cache_key..)key-.)rjoinsortedrrintrr)rR version_strpartsrFrFrG get_cache_keys zMode.get_cache_keyN)rBrCrDr)setrrrk__annotations__DEFAULT_LINE_LENGTHrrrrhrrrrrFrFrFrGrs     r)rfeaturerPcstfdd|DS)Nc3s|]}t|kVqdS)N)r)rr7)rrFrGr sz#supports_feature..)all)rrrF)rrGsupports_feature sr)path_search_startrPcCs$t|}|d}|r t|SdS)z;Find the absolute filepath to a pyproject.toml if it existszpyproject.tomlN)find_project_rootis_filer)rZpath_project_rootZpath_pyproject_tomlrFrFrGfind_pyproject_tomlsr) path_configrPcCs0t|}|didi}dd|DS)zParse a pyproject toml file, pulling out relevant parts for Black If parsing fails, will raise a toml.TomlDecodeError Ztoolr9cSs&i|]\}}||ddddqS)z--r_)r*)rkrrFrFrG sz(parse_pyproject_toml..)tomlloadgetitems)rpyproject_tomlconfigrFrFrGparse_pyproject_tomls r)ctxparamrOrPc Cs|s"t|jdd}|dkr"dSy t|}Wn<tjtfk rj}ztj|d|dWdd}~XYnX|stdSdd| D}|d}|dk rt |t st d d i}|j r||j ||||_ |S) zInject Black configuration from "pyproject.toml" into defaults in `ctx`. Returns the path to a successfully found and read configuration file, None otherwise. srcrFNz"Error reading configuration file: )filenamehintcSs,i|]$\}}t|ttfs"t|n||qSrF) isinstancelistdictr)rrrrFrFrGr;sz'read_pyproject_toml..target_versionztarget-versionz(Config key target-version must be a list)rparamsrrrTomlDecodeErrorOSErrorclickZ FileErrorrrrZBadOptionUsage default_mapupdate)rrrOrrVrrrFrFrGread_pyproject_toml!s. "    r.)cprrPcCsdd|DS)zCompute the target versions from a --target-version flag. This is its own function because mypy couldn't infer the type correctly when it was a lambda, causing mypyc trouble. cSsg|]}t|qSrF)rkupper)rvalrFrFrG Wsz2target_version_option_callback..rF)rrrrFrFrGtarget_version_option_callbackOsrz-hz--help)Zhelp_option_names)Zcontext_settingsz-cz--codez&Format the code passed in as a string.)typehelpz-lz --line-lengthz&How many characters per line to allow.)rdefaultrZ show_defaultz-tz--target-versioncCsg|]}|jqSrF)namelower)rrrFrFrGrgsrz^Python versions that should be supported by Black's output. [default: per-file auto-detection])rcallbackmultiplerz--pyiztFormat all input files like typing stubs regardless of file extension (useful when piping source on standard input).)is_flagrz-Sz--skip-string-normalizationz*Don't normalize string quotes or prefixes.z --experimental-string-processingz}Experimental option that performs more normalization on string literals. Currently disabled because it leads to some crashes.)rhiddenrz--checkzDon't write the files back, just return the status. Return code 0 means nothing would change. Return code 1 means some files would be reformatted. Return code 123 means there was an internal error.z--diffzGDon't write the files back, just output a diff for each file on stdout.z--color/--no-colorz7Show colored diff. Only applies when `--diff` is given.z --fast/--safez@If --fast given, skip temporary sanity checks. [default: --safe]z --includea%A regular expression that matches files and directories that should be included on recursive searches. An empty value means all files are included regardless of the name. Use forward slashes for directories on all platforms (Windows, too). Exclusions are calculated first, inclusions later.z --excludea A regular expression that matches files and directories that should be excluded on recursive searches. An empty value means no paths are excluded. Use forward slashes for directories on all platforms (Windows, too). Exclusions are calculated first, inclusions later.z--force-excludezLike --exclude, but files and directories matching this regex will be excluded even when they are passed explicitly as argumentsz-qz--quietzbDon't emit non-error messages to stderr. Errors are still emitted; silence those with 2>/dev/null.z-vz --verbosezaAlso emit messages to stderr about files that were not changed or were ignored due to --exclude=.r)exists file_okaydir_okayreadable allow_dash)nargsris_eagerz--configF)rrrrr path_typez"Read configuration from FILE path.)rrrr)rcoderrr^r_r]fastpyiskip_string_normalizationrquietverboseincludeexclude force_excluderrrPc Cs$tj|||d}|rt|}nt}t|||| | d}|rV| rVtd|dddd|dk rxtt||d |d t||| | d }t ||| | | |||d }t |d | | |t |dkrt | ||||dnt|||||d| s| st|jrdndtjt|dd||jdS)z"The uncompromising code formatter.)r^r_r])rrrrrzUsing configuration from rFblue)r=r@N)moder)r^r_rr)rrrrrrrreportu?No Python files are present to be formatted. Nothing to do 😴rY)rr write_backrr)sourcesrrrruOh no! 💥 💔 💥uAll done! ✨ 🍰 ✨T)r>)rXrerroutprint format_strexitReport get_sources path_emptylen reformat_onepop reformat_many return_codersechor)rrrrr^r_r]rrrrrrrrrrrrversionsrrrrFrFrGmainZsZ$     rr) rrrrrrrrrPc Csy t|}Wn.tjk r:td||dYnXy t|} Wn.tjk rvtd||dYnXy|rt|nd} Wn.tjk rtd||dYnXt|} t} t|d|||t| } x|D]}t |}| r| t | | || | || q|dkr4| |q|rt|| |}|dkrVqd|}| rp| |}nd}|r|d r||d q| |qtd |qW| S) z)Compute the set of files to be formatted.z.Invalid regular expression for include given: rZz.Invalid regular expression for exclude given: Nz4Invalid regular expression for force_exclude given: u$No Path provided. Nothing to do 😴r/rz.matches the --force-exclude regular expressionzinvalid path: )re_compile_maybe_verbosereerrorr>rrrr get_gitignoreris_dirrgen_python_filesiterdiraddrnormalize_path_maybe_ignoresearchgroup path_ignored)rrrrrrrrZ include_regexZ exclude_regexZforce_exclude_regexrootr gitignoresrnormalized_pathforce_exclude_matchrFrFrGr6s^              r)rmsgrrrrPcCs*t|dkr&|s|s&t||ddS)z; Exit if there is no `src` provided for formatting rN)rrr)rr rrrrFrFrGr~s r)rrrrrrPc Csytj}|s2t|dkr2t|||drtj}ni}|tjkrnt|}| }||krn||t |krntj }|tj k rt ||||drtj}|tjkr|tj k s|tj kr|tjkrt||g||||WnBtk r}z"|jrt||t|Wdd}~XYnXdS)zReformat a single file under `src` without spawning child processes. `fast`, `write_back`, and `mode` options are passed to :func:`format_file_in_place` or :func:`format_stdin_to_stdout`. r)rrrN)rirfrrformat_stdin_to_stdoutrcrXrb read_cacheresolveget_cache_inforjformat_file_in_placer` write_cachedone Exceptionr traceback print_excfailed) rrrrrchangedcacheZres_srcexcrFrFrGrs,  r)rrrrrrPc Cst}t}tjdkr$t|d}yt|d}Wn"tt fk rTt dd}YnXz | t |||||||dWdt ||dk r| XdS)z4Reformat multiple files using a ProcessPoolExecutor.win32=) max_workersrY)rrrrrloopexecutorN)asyncioZget_event_loopos cpu_countsysplatformminr ImportErrorrrrun_until_completeschedule_formattingshutdown)rrrrrrZ worker_countrrFrFrGrs*  r)rrrrrrrrPcsi}tjkrDt}t||\}}xt|D]} || tjq.W|sLdSg} g} dtjkrpt} | fddt|D} | }y$ t j t| t jt|Wntk rYnXx|rtj|tjdIdH\}}x|D]}| |} |r| |q|r>|| t|q|rNtjntj}tjksxtjkr|tjkr| | || |qWqW| rtj| ddIdH| rt|| dS)zRun formatting of `sources` in parallel using the provided `executor`. (Use ProcessPoolExecutors for actual parallelism.) `write_back`, `fast`, and `mode` options are passed to :func:`format_file_in_place`. Ncs*i|]"}|tt|qSrF)rZ ensure_futureZrun_in_executorr)rr)rrlockrrrrFrGrsz'schedule_formatting..)Z return_whenT)rreturn_exceptions) rXrbr  filter_cachedrrrirjrLockkeysZadd_signal_handlersignalSIGINTcancelSIGTERMNotImplementedErrorrwaitZFIRST_COMPLETEDr cancelledappend exceptionrrresultrcrfr`gatherr)rrrrrrrrcachedrr2Zsources_to_cachemanagertaskspendingrrtaskrrF)rrr'rrrrGr%sN          r%)rrrrr'rPc CsP|jdkrt|dd}t|j}t|d}t|\}}} WdQRXyt |||d} Wnt k rtdSX|t j krt|d|| d } | | WdQRXn|t jt jfkrLt} |d |d } |d | d }t|| | |}||jkrt|}|pt6tjtjj|| dd } t| } | || WdQRXdS) zFormat file under `src` path. Return True if changed. If `write_back` is DIFF, write a diff to stdout. If it is YES, write reformatted code to the file. `mode` and `fast` options are passed to :func:`format_file_contents`. z.pyiT)rrbN)rrFw)encodingnewline z +0000)r>r? write_through)suffixr*r utcfromtimestampstatst_mtimeopen decode_bytesreadformat_file_contentsrArXrcwriterbrautcnowr_ color_diff nullcontextio TextIOWrapperr stdoutbufferwrap_stream_for_windowsdetach)rrrrr'thenbuf src_contentsr>r? dst_contentsfnowsrc_namedst_nameZ diff_contentsrFrFrGrs:      r)contentsrPcCs|d}xt|D]t\}}|ds0|dr.)coloramare wrap_streamrSr#)rXrerFrFrGrR[s  rR)r)rrrrPc Cst}ttjj\}}}|}z,yt|||d}dStk rJdSXWdt j tj j||dd}|t j kr|||nb|t jt jfkrt} d|d} d| d} t||| | } |t jkrt| } t|}|| |XdS) zFormat file on stdin. Return True if changed. If `write_back` is YES, write reformatted code back to stdout. If it is DIFF, write a diff to stdout. The `mode` argument is passed to :func:`format_file_contents`. )rrTFN)r>r?rAzSTDIN z +0000zSTDOUT )r rKrGr stdinrQrHrIrArNrOrPrXrcrJrbrar_rLrRrS) rrrrTrr>r?dstrXrYrZr[drFrFrGr ws,        r )rVrrrPcCsH|dkrtt||d}||kr(t|sDt||t|||d|S)zReformat contents a file and return new contents. If `fast` is False, additionally confirm that the reformatted code is valid by calling :func:`assert_equivalent` and :func:`assert_stable` on it. `mode` is passed to :func:`format_str`. r)r)rgrArassert_equivalent assert_stable)rVrrrWrFrFrGrIs   rI)rVrrPc st||j}g}t|}|jr*|jnt|t|td|kpNttj |j |j d}t |j d}t }d}fddtjtjhD} xj||D]\} |t|||| \} }|t|| x$t| || dD]} |t| qWqWd|S) aReformat a string and return new contents. `mode` determines formatting options, such as how many characters per line are allowed. Example: >>> import black >>> print(black.format_str("def f(arg:str='')->None:...", mode=Mode())) def f(arg: str = "") -> None: ... A more complex example: >>> print( ... black.format_str( ... "def f(arg:str='')->None: hey", ... mode=black.Mode( ... target_versions={black.TargetVersion.PY36}, ... line_length=10, ... string_normalization=False, ... is_pyi=False, ... ), ... ), ... ) def f( arg: str = '', ) -> None: hey unicode_literals)remove_u_prefixrnormalize_strings)rrcsh|]}t|r|qSrF)r)rr)rrFrG szformat_str..)rfeaturesr) lib2to3_parselstriprget_future_importsdetect_target_versionsnormalize_fmt_off LineGeneratorrr<rzrrEmptyLineTrackerr;r}r~visitr3rmaybe_empty_linestransform_liner) rVrZsrc_noderWZfuture_importsrbeltZ empty_lineafterZsplit_line_features current_linebeforerdrF)rrGrs2    r)rrPc Cstt|}t|j\}}|s(d|dfSd|dddkr@dnd}|dt||}|||fSQRXdS)zReturn a tuple of (decoded_contents, encoding, newline). `newline` is either CRLF or LF but `decoded_contents` is decoded with universal newlines (i.e. only contains LF). rr]s rNz )rNBytesIOtokenizedetect_encodingreadlineseekrOrH)rZsrcbufr>rbr?ZtiowrFrFrGrGs   rG)rrPcCsn|stjtjtjtjgStdd|Dr6tjtjgSg}t|tjsR| tjt|tj sj| tj|S)Ncss|]}|VqdS)N)rq)rr7rFrFrGrszget_grammars..) r1ZBpython_grammar_no_print_statement_no_exec_statement_async_keywordsZ3python_grammar_no_print_statement_no_exec_statementZ!python_grammar_no_print_statementZpython_grammarrrr<rr3r)rZgrammarsrFrFrG get_grammarss   rrF)src_txtrrPc Cs|dddkr|d7}xtt|D]}t|tj}y||d}PWq&tk r}z^|jd\}}| }y||d} Wnt k rd} YnXt d|d|d | } Wdd}~XYq&Xq&W| dt |t rttj|g}|S) z4Given a string with source, return the lib2to3 Node.rNr]TrYzzCannot parse: :z: )rrr3ZDriverr2rf parse_stringr6context splitlines IndexErrorrJrr/r.syms file_input) rrZgrammardrvr5pelinenocolumnrbZ faulty_linerrFrFrGrx's&  0 rx)noderPcCs t|}|S)z7Given a lib2to3 node, return its string representation.)r)rrrFrFrGlib2to3_unparseBsrc@s8eZdZdZeeedddZeeedddZdS)VisitorzBBasic lib2to3 visitor that yields things of type `T` on `visit()`.)rrPccs`|jdkrtj|j}ntt|j}t|d|d}|rL||EdHn||EdHdS)azMain method to visit `node` and its children. It tries to find a `visit_*()` method for the given `node.type`, like `visit_simple_stmt` for Node objects or `visit_INDENT` for Leaf objects. If no dedicated `visit_*()` method is found, chooses `visit_default()` instead. Then yields objects of type `T` from the selected visitor. Zvisit_N)rr4tok_namerr0getattr visit_default)rRrrZvisitfrFrFrGrKs z Visitor.visitccs.t|tr*x|jD]}||EdHqWdS)zCDefault `visit_*()` implementation. Recurses to children of `node`.N)rr.childrenr)rRrchildrFrFrGrcs  zVisitor.visit_defaultN) rBrCrDrELNrrKrrrFrFrFrGrHsrc@sLeZdZUdZeed<eeedddZ e e e e efdddd ZdS) DebugVisitorr tree_depth)rrPccsdd|j}t|trt|j}t||dd|jd7_x|jD]}||EdHqLW|jd8_t|d|dddn`tj |jt |j}t||d dd |j rtd|j d ddd td|j d dddS) N rZZyellow)r@rYrF)r@r=r)r@nlZgreen)r@r=r)rrr.r0rrrrr4rrrprefixrO)rRrindent_typerrFrFrGrns   zDebugVisitor.visit_defaultN)rrPcCs*t}t|trt|}t||dS)zmPretty-print the lib2to3 AST of a given string of `code`. Convenience method for debugging. N)rrrrxrr)rdrrrFrFrGshows zDebugVisitor.show)rBrCrDrrrrrrKrrgr"rr/r.rrFrFrFrGrjs  r WHITESPACE STATEMENTSTANDALONE_COMMENTandorLOGIC_OPERATORS COMPARATORSMATH_OPERATORSSTARSVARARGS_SPECIALSVARARGS_PARENTSUNPACKING_PARENTSTEST_DESCENDANTS=z+=z-=z*=z@=z/=z%=z&=z|=z^=z<<=z>>=z**=z//= ASSIGNMENTSCOMPREHENSION_PRIORITYCOMMA_PRIORITYTERNARY_PRIORITYLOGIC_PRIORITY STRING_PRIORITY COMPARATOR_PRIORITYrxrornrmrlr\r[rZMATH_PRIORITIESrY DOT_PRIORITYc@sDeZdZUdZdZeed<eedZ e e e e fefed<eedZe eefed<dZeeed<eedZeeed <eedZeeed <eedZeeed <edd d dZedddZd#eeedddZd$eedddZeed ddZeed ddZ eed ddZ!eed dd Z"eedd!d"Z#dS)%BracketTrackerz"Keeps track of brackets on a line.rdepth)r bracket_match delimitersNprevious_for_loop_depths_lambda_argument_depths invisible)leafrPcCs&|jtjkrdS|||||jtkrh|jd8_|j|j|jf}||_ |j sh|j ||j|_ |jdkrt||j}|r|jdk r||jt|j<nt||j}|r||jt|<|jtkr||j|jt|jf<|jd7_|j s|j |||_||||dS)aMark `leaf` with bracket-related metadata. Keep track of delimiters. All leaves receive an int `bracket_depth` field that stores how deep within brackets a given leaf is. 0 means there are no enclosing brackets that started on this line. If a leaf is itself a closing bracket, it receives an `opening_bracket` field that it forms a pair with. This is a one-directional link to avoid reference cycles. If a leaf is a delimiter (a token on which Black can split the line if needed) and it's on depth 0, its `id()` is stored in the tracker's `delimiters` field. NrYr)rr4COMMENT'maybe_decrement_after_for_loop_variable&maybe_decrement_after_lambda_argumentsCLOSING_BRACKETSrrropening_bracketrOrr3 bracket_depthis_split_before_delimiterrridis_split_after_delimiterOPENING_BRACKETSBRACKET maybe_increment_lambda_arguments!maybe_increment_for_loop_variable)rRrrdelimrFrFrGmark s4           zBracketTracker.mark)rPcCs t|jS)zBReturn True if there is an yet unmatched open bracket on the line.)rhr)rRrFrFrGany_open_brackets6sz BracketTracker.any_open_bracketsrF)rrPcstfdd|jDS)zReturn the highest priority of a delimiter found on the line. Values are consistent with what `is_split_*_delimiter()` return. Raises ValueError on no delimiters. c3s|]\}}|kr|VqdS)NrF)rrr)rrFrGr@sz8BracketTracker.max_delimiter_priority..)maxrr)rRrrF)rrGmax_delimiter_priority:sz%BracketTracker.max_delimiter_priority)priorityrPcs2|js dSp|tfdd|jDS)zReturn the number of delimiters with the given `priority`. If no `priority` is passed, defaults to max priority on the line. rc3s|]}|krdVqdS)rYNrF)rr)rrFrGrKsz?BracketTracker.delimiter_count_with_priority..)rrsumvalues)rRrrF)rrGdelimiter_count_with_priorityBs z,BracketTracker.delimiter_count_with_prioritycCs:|jtjkr6|jdkr6|jd7_|j|jdSdS)zIn a for loop, or comprehension, the variables are often unpacks. To avoid splitting on the comma in this situation, increase the depth of tokens between `for` and `in`. forrYTF)rr4NAMErOrrr3)rRrrFrFrGrMs z0BracketTracker.maybe_increment_for_loop_variablecCsL|jrH|jd|jkrH|jtjkrH|jdkrH|jd8_|jdSdS)z>See `maybe_increment_for_loop_variable` above for explanation.rinrYTF)rrrr4rrOr)rRrrFrFrGrZs   z6BracketTracker.maybe_decrement_after_for_loop_variablecCs:|jtjkr6|jdkr6|jd7_|j|jdSdS)zIn a lambda expression, there might be more than one argument. To avoid splitting on the comma in this situation, increase the depth of tokens between `lambda` and `:`. lambdarYTF)rr4rrOrrr3)rRrrFrFrGrhs z/BracketTracker.maybe_increment_lambda_argumentscCsB|jr>|jd|jkr>|jtjkr>|jd8_|jdSdS)z=See `maybe_increment_lambda_arguments` above for explanation.rrYTF)rrrr4COLONr)rRrrFrFrGrus  z5BracketTracker.maybe_decrement_after_lambda_argumentscCs|j|jdtjfS)z7Return the most recent opening square bracket (if any).rY)rrrr4RSQB)rRrFrFrG get_open_lsqbszBracketTracker.get_open_lsqb)rF)r)$rBrCrDrErrrr)rrrrDepthNodeTyper/rLeafIDPriorityrrrrrrrrrhrrrrrrrrrrFrFrFrGrs"  ",    rc@seZdZUdZdZeed<eedZ e e ed<ee dZ eee e fed<eedZeed<dZeed <dZeed <d>e ed d d dZd?e ed d ddZeedddZeedddZeedddZeedddZeedddZeedddZeedddZeedd d!Ze j!feed"d#d$Z"edd%d&Z#edd'd(Z$edd)d*Z%e ed+d,d-Z&e ed.d/d0Z'e e e d1d2d3Z(d dd4d5Z)e ed1d6d7Z*ddd8d9Z+e,dd:d;Z-edd|jr>|jdd=|jrd|sd|j t || |d7_ |j sn|s|j |||rd|_||s|j|dS)agAdd a new `leaf` to the end of the line. Unless `preformatted` is True, the `leaf` will receive a new consistent whitespace prefix and metadata applied by :class:`BracketTracker`. Trailing commas are maybe removed, unpacked for loop variables are demoted from being delimiters. Inline comments are put aside. Nr)complex_subscriptT)rBRACKETSrhrOrgr4ris_class_paren_emptyrr whitespaceis_complex_subscriptrrrmaybe_should_exploderappend_commentr3)rRrrZ has_valuerFrFrGr3s       z Line.appendcCsD|jjdkr2|jrtd|jr2|jtkr2td|j||ddS)zLike :func:`append()` but disallow invalid standalone comment structure. Raises ValueError when any `leaf` is appended after a standalone comment or when a standalone comment is not the first leaf on the line. rz$cannot append to standalone commentsz5cannot append standalone comments to a populated line)rN)rr is_comment ValueErrorrrrr3)rRrrrFrFrG append_safes zLine.append_safe)rPcCst|jdko|jdjtkS)z"Is this line a standalone comment?rYr)rrrr)rRrFrFrGrszLine.is_commentcCst|o|jdjtjkS)zIs this line a decorator?r)rhrrr4AT)rRrFrFrG is_decoratorszLine.is_decoratorcCst|ot|jdS)zIs this an import line?r)rh is_importr)rRrFrFrGrszLine.is_importcCs*t|o(|jdjtjko(|jdjdkS)z Is this line a class definition?rclass)rhrrr4rrO)rRrFrFrGis_classsz Line.is_classcCs&|jo$|jddddtdDkS)zEIs this line a class definition with a body consisting only of "..."?NcSsg|]}ttjdqS)r)r/r4DOT)rrrFrFrGrsz&Line.is_stub_class..r[)rrrange)rRrFrFrG is_stub_classszLine.is_stub_classcCsy|jd}Wntk r"dSXy|jd}Wntk rJd}YnX|jtjkrb|jdkp|jtjko|dk o|jtjko|jdkS)zBIs this a function definition? (Also returns True for async defs.)rFrYNdef)rrrr4rrOASYNC)rR first_leafZ second_leafrFrFrGis_defs   z Line.is_defcCs`t|o^t|jdko^|jo^|jdjtjko^|jdjdko^|jdjtjko^|jdjdkS)zzIs this a class with no base classes but using parentheses? Those are unnecessary and should be removed. r\rZ(r[)) rhrrrrr4LPARrORPAR)rRrFrFrGrszLine.is_class_paren_emptycCs,t|o*|jdjtjko*|jdjdS)z#Is the line a triple quoted string?r)z"""z''')rhrrr4STRINGrOra)rRrFrFrGis_triple_quoted_stringszLine.is_triple_quoted_string) depth_limitrPcCs,x&|jD]}|jtkr|j|krdSqWdS)z)If so, needs to be split before emitting.TF)rrrr)rRrrrFrFrGcontains_standalone_comments s z!Line.contains_standalone_commentscCst}yR|jd}|t||jtjks>|jtjkrV|jsV|jd}|t|Wnt k rldSXd}xJ|j D]<\}}x2|D]*}t |r|st |ds||krdSd}qWq~WdS)NrrFz ignoreT) rrrrrr4COMMArrOrrris_type_comment)rRZ ignored_ids last_leafZ comment_seenZleaf_idrcommentrFrFrG$contains_uncollapsable_type_commentss(      z)Line.contains_uncollapsable_type_commentscCs|js dStdd|jDd}tddt|jDd}||krx@|jddD].}x(|jt|gD]}t|drjdSqjWqRWdS) NFcss|]}|jdkr|jVqdS)rN)r)rrrFrFrGrIsz9Line.contains_unsplittable_type_ignore..rcss|]}|jdkr|jVqdS)rN)r)rrrFrFrGrKsrz ignoreT)rnextreversedrrrr)rR first_line last_linerrrFrFrG!contains_unsplittable_type_ignore8s  z&Line.contains_unsplittable_type_ignorecCstdd|jDS)Ncss|]}t|VqdS)N)is_multiline_string)rrrFrFrGrZsz2Line.contains_multiline_strings..)anyr)rRrFrFrGcontains_multiline_stringsYszLine.contains_multiline_strings)closingrPcCs^|jtkr"|jr"|jdjtjks&dS|jtjtjhkr|j}|jt|g}|jt|jdg|dS)z@Remove the trailing comma and moves the comments attached to it.rN)rrrrr)extend)rRtrailing_commaZtrailing_comma_commentsrFrFrGremove_trailing_commas zLine.remove_trailing_commacCsj|j}|dkrdS|j}t|trL|jtjkr6dS|jtjkrLt ||}|dk oht dd| DS)zAReturn True iff `leaf` is part of a slice with non-trivial exprs.NFcss|]}|jtkVqdS)N)rr)rnrFrFrGrsz,Line.is_complex_subscript..) rr next_siblingrr.rr listmaker subscriptlist child_towardsr# pre_order)rRrZ open_lsqbZsubscript_startrFrFrGrs      zLine.is_complex_subscriptcCst|j|j|jdS)N)rrr)r;rrr)rRrFrFrGclonesz Line.clonecCs|sdSd|j}t|j}t|}|j||j}x|D]}|t|7}q>Wx&tj |j D]}|t|7}qfW|dS)zRender the line.r]z ) riterrrrrOr itertoolschain from_iterablerr)rRrrfirstresrrrFrFrG__str__s   z Line.__str__cCst|jp |jS)z/Return True if the line has leaves or comments.)rhrr)rRrFrFrG__bool__sz Line.__bool__)F)F)/rBrCrDrErrrr)rrrr/rrrrrrrrhrr3rpropertyrrrrr rrrr maxsizerrr!r$rrr*r-rr4rr;r<rFrFrFrGr;sJ    $!%c@seZdZUdZdZeed<dZee ed<dZ e ed<e e dZee ed <e ee e fd d d Ze ee e fd d dZe e ee e fdddZdS)r~a{Provides a stateful method that returns the number of potential extra empty lines needed before and after the currently processed line. Note: this tracker works on lines that haven't been split yet. It assumes the prefix of the first leaf consists of optional newlines. Those newlines are consumed by `maybe_empty_lines()` and included in the computation. FrN previous_linerprevious_after)r previous_defs)rrPcCs:||\}}|jdkrdn||j}||_||_||fS)zReturn the number of extra empty lines before and after the `current_line`. This is for separating `def`, `async def` and `class` with extra empty lines (two on module-level). Nr)_maybe_empty_linesr?r@)rRrrrrFrFrGrs  z"EmptyLineTracker.maybe_empty_linescCsd}|jdkr|jrdnd}|jrJ|jd}|jd}t||}d|_nd}|j}xB|jr|jd|kr|j|jr|rdnd}qV|rdnd}qVW|js|j s|j r| ||S|j r|j j r|j s||j jkr|pddfS|j r|j j r|jr|dfS|dfS)NrYrrZr]rr)rrrrcountr"rArrrr#_maybe_empty_lines_for_class_or_defr?rr)rRrZ max_allowedrrrrFrFrGrBs6        z#EmptyLineTracker._maybe_empty_lines)rrrPcCs|js|j|j|jdkr"dS|jjr.dS|jj|jkrP|jjsL|jjrPdS|jjrr|jj|jkrr|dkrrdS|jr|jj|jkrd}q|js|jjr|j r|jj rd}qd}q|jr|jjsd}qd}nd}|jr|r|d8}|dfS)N)rrrrYrZ) rrAr3rr?rrrrr )rRrrnewlinesrFrFrGrDs6  z4EmptyLineTracker._maybe_empty_lines_for_class_or_def)rBrCrDrErrhrr?rr;r@rr)rrArrrrBrDrFrFrFrGr~s   (r~cseZdZUdZdZeed<dZeed<ee dZ e ed<dZ eed<d.e e e d d d Zee e d fdd Zee e d ddZee e d ddZeeeeee e dddZee e d ddZee e d ddZee e d ddZee e d ddZee e dd d!Zee e dd"d#Zee e dd$d%Zee e d d&d'Zee e dd(d)Z d*d+d,d-Z!Z"S)/r}zGenerates reformatted Line objects. Empty lines are not emitted. Note: destroys the tree it's visiting by mutating prefixes of its leaves in ways that will no longer stringify to valid Python code on the tree. FrTru)rrrtr)rrPccs<|js|jj|7_dS|j}t|j|d|_|VdS)zGenerate a line. If the line is empty, only emit if it makes sense. If the line is too long, split it first and then generate. If any lines were generated, set up a new current_line. N)r)rrr;)rRrZ complete_linerFrFrGrdTs zLineGenerator.line)rrPc#st|tr|jj}xrt|D]f}|r6|j|q |jtj kr^|j|| EdHq | EdH|j|| EdHq Wt ||d|j r|jtj krt||jdt||jtjkrt||jtkr|j|t|EdHdS)zCDefault `visit_*()` implementation. Recurses to children of `node`.N)r)rt)rr/rrrgenerate_commentsr3rr4rrdnormalize_prefixrurnormalize_string_prefixrtnormalize_string_quotesNUMBERnormalize_numeric_literalrsuperr)rRrrr) __class__rFrGrds(         zLineGenerator.visit_defaultccs$|dEdH||EdHdS)z/Increase indentation level, maybe yield a line.rYN)rdr)rRrrFrFrG visit_INDENTszLineGenerator.visit_INDENTccs2|EdH||EdH|dEdHdS)z/Decrease indentation level, maybe yield a line.Nr)rdr)rRrrFrFrG visit_DEDENTszLineGenerator.visit_DEDENT)rkeywordsparensrPccsTt||dxB|jD]8}|jtjkr<|j|kr<|EdH||EdHqWdS)aVisit a statement. This implementation is shared for `if`, `while`, `for`, `try`, `except`, `def`, `with`, `class`, `assert` and assignments. The relevant Python language `keywords` for a given statement will be NAME leaves within it. This methods puts those on a separate line. `parens` holds a set of string leaf values immediately after which invisible parens should be put. ) parens_afterN)normalize_invisible_parensrrr4rrOrdr)rRrrPrQrrFrFrG visit_stmts   zLineGenerator.visit_stmtccs:|jr&t|r&||jdEdHn||EdHdS)zVisit a suite.rZN)r is_stub_suiterrr)rRrrFrFrG visit_suiteszLineGenerator.visit_suiteccs|jo|jjtk}|rh|jr6t|r6||EdHq|dEdH||EdH|dEdHn4|jr~|jr~t|js|EdH||EdHdS)z,Visit a statement without nested statements.NrYr)r(rrr is_stub_bodyrrdrU)rRrZ is_suite_likerFrFrGvisit_simple_stmtszLineGenerator.visit_simple_stmtccsp|EdHt|j}x*|D]"}||EdH|jtjkrPqWt|}x|jD]}||EdHqTWdS)z-Visit `async def`, `async for`, `async with`.N)rdr5rrrr4r r)rRrrrZ internal_stmtrFrFrGvisit_async_stmts    zLineGenerator.visit_async_stmtccs2x,|jD]"}|EdH||EdHqWdS)zVisit decorators.N)rrdr)rRrrrFrFrGvisit_decoratorss zLineGenerator.visit_decorators)rrPccs|EdHdS)zBRemove a semicolon and put the other statement on a separate line.N)rd)rRrrFrFrG visit_SEMIszLineGenerator.visit_SEMIccs"||EdH|EdHdS)zAEnd of file. Process outstanding comments and end with a newline.N)rrd)rRrrFrFrGvisit_ENDMARKERszLineGenerator.visit_ENDMARKERccs.|jjs|EdH||EdHdS)N)rrrrdr)rRrrFrFrGvisit_STANDALONE_COMMENTs z&LineGenerator.visit_STANDALONE_COMMENTccs|j\}}|jtjkrtt|jdkrt|jdjtjkrtttjd}ttj d}| pXd}| |t tj |||g||EdHdS)z_Force parentheses between a unary op and a binary power: -2 ** 8 -> -(2 ** 8) r[rYrrrN)rrrpowerrr4 DOUBLESTARr/rrremove insert_childr.atomr)rRr _operatorZoperandlparrparindexrFrFrG visit_factors     zLineGenerator.visit_factorccst|rd|jkrt|j}t|d}d}d|jj}t|j|||}|r|j|d|dkrnd|}|j|d|dkr|d}|jd|||j|d|_t|||EdHdS) Nz\ r[rz rYrrr) is_docstringrOget_string_prefixrrr fix_docstringrIr)rRrrZlead_lentail_lenr docstringrFrFrG visit_STRINGs   "zLineGenerator.visit_STRINGN)rPcCs&|j}t}t|dhddhd|_t|dddhddhd|_t|ddhdhd|_t|ddhdd hd|_t|d d dd h|d|_t|d h|d|_t|d h|d|_ t|dh|d|_ t|dh|d|_ t||t d|_ t|dhdhd|_t||dhd|_t||dhd|_|j|_|j|_dS)z,You are in a twisty little maze of passages.assertr)rPrQifelseelifwhilerrtryexceptfinallywithr rrPimportdelN)rTrr Zvisit_assert_stmtZ visit_if_stmtZvisit_while_stmtZvisit_for_stmtZvisit_try_stmtZvisit_except_clauseZvisit_with_stmtZ visit_funcdefZvisit_classdefrZvisit_expr_stmtZvisit_return_stmtZvisit_import_fromZvisit_del_stmtrYZvisit_async_funcdefrZZvisit_decorated)rRrØrFrFrG __post_init__ s&zLineGenerator.__post_init__)r)#rBrCrDrErrhrrur)r;rrtrrrdrrr/rNrOr.rrrTrVrXrYrZr[r\r]rgrmrz __classcell__rFrF)rMrGr}Gs*    r})rrrPc CsJd}d}d}|j}|j}|j}|tkr*|S|tjkr8|S|dk sNtd||tjkrr|jtj tj tj hkrr|S|j }|st |} | r| jtkr|S|tjkr| jtjkr|S| jtjkr|s|S|S| jtjkr| jr| jjtjtjtjtjhkr|S| jjtjkr| jSn| jtkr>t| ttBdr|Sn| jtjkrz| jr| jjtj tj hkr|rt|S|Snx| jr| jjtjkr| jtkr|S| jtjkr| jr| jjtjkr| j r| j jtjkr| j jdkr|Sn|jtkr|S|jtjtjhkr4|r,|jtjkrF|Sn|jtjkr^|rF|jtjkrF|Sn|jtjkr|sv|S|tjkr|jtj kr|Sn&|jtjkr|jS|jtjkrF|Sn|jtj kr|sFt |} | r| jtjkrF|SnN|jtj!kr~|tj"ks|tj#kr"|S|sh|tj$krVt |} | rP| jtj%krf|Sn|tj&krz|Sn|jtjkrF|Sn|jtjkr|tjkr|S|st |} | r| jtj"kr|Sn|jtjhtBkrF|Snf|jtj'kr|S|jtj(kr<|r |St |} | r4| jtj)ks4| jtj$krF|Sn |jtj*krv|tj"krZ|S|rF|jtj"krF|Sn|jtj tj hkr|s|jdk std|jjtj kr|S|S|sF|Sn||jtj+kr|rF|tj$krF|SnT|jtj,kr|rF|jtj-krF|Sn*|jtjtj.hkr|st |} | rP| jtkrT|S| j} | dk sht| jtjkr| jtj tj hkr|S| jtjkr| jtjkr|Sn|tjtj%tj/hkrF|Snz|jtj0kr4|tj$kr|r2|jtj$kr2|Sn2|tjkrF|d kr|S|rF|jtj$krF|Sn|jtj krF|S|S) zReturn whitespace prefix if needed for the given `leaf`. `complex_subscript` signals whether the given leaf is part of a subscription which has non-trivial arguments, like arithmetic expressions or function calls. rrz Nz/INTERNAL ERROR: hand-made leaf without parent: )withinrzsubscripts are always parentedrw)1rr(rOALWAYS_NO_SPACEr4rAssertionErrorrrZ subscriptr1Zsliceop prev_siblingpreceding_leafrrEQUALarglistargument parameters varargslist typedargslistrr is_varargrrfactorr RIGHTSHIFT shift_exprrZtnametrailerrrr rJLSQB decorator dotted_namerclassdefrb dictsetmakerr_ star_exprr import_from) rrrfSPACEZ DOUBLESPACEtrrprevZprevpZ prevp_parentrFrFrGr*s0            "     rcCsRxL|rL|j}|rDt|tr|Syt|dStk rBdSX|j}qWdS)z3Return the first leaf that precedes `node`, if any.rN)rrr/rrrr()rr:rFrFrGr s  r)rtokensrPcCsJ|sdS|ddkr|dkS|s$dS|j|dkr6dSt|j|ddS)a;Return if the `node` and its previous siblings match types against the provided list of tokens; the provided `node`has its type matched against the last element in the list. `None` can be used as the first element to declare that the start of the list is anchored at the start of its parent's children.TrNF)rprev_siblings_arer)rrrFrFrGr" s r)ancestor descendantrPcCs"|}x|r|j|kr|j}qW|S)z:Return the child of `ancestor` that contains `descendant`.)r()rrrrFrFrGr22 s r2)rrPcCsd|j}|}xT|r^|j}|dkr P|jdj|kr2P|jtjkr@P|jdk rX|jjtkrXP|}q W|S)zReturn `leaf` or one of its ancestors that is the topmost container of it. By "container" we mean a node where `leaf` is the very first child. Nr)rr(rrrrrr)rZ same_prefix containerr(rFrFrG container_of: s r)rrrPcCs|jtjkrtSdS)zReturn the priority of the `leaf` delimiter, given a line break after it. The delimiter priorities returned here are from those delimiters that would cause a line break after themselves. Higher numbers are higher priority. r)rr4rr)rrrFrFrGrS s rcCs8t|ttBdrdS|jtjkrP|jrP|jjtjtj hkrP|dksL|jt krPt S|jt kr~|jr~|jjtj tjhkr~t|jS|jtkrtS|jtjkr|dk r|jtjkrtS|jtjtjhkrdS|jdkr|jr|jjtjtjhks|jtjkrt|jtr|jjdkrtS|jdkrF|jrF|jjtjtjhkrFtS|jdkrn|jrn|jjtjkrnt S|jdkr~tS|jd kr|jr|jjtj!tj"hkr|dk r|jtjkr|jd kstS|jd kr|jr|jjtj!kr|dk r|jtjkr|jdkstS|jt#kr4|jr4t$SdS) zReturn the priority of the `leaf` delimiter, given a line break before it. The delimiter priorities returned here are from those delimiters that would cause a line break before themselves. Higher numbers are higher priority. )r|rNrasyncro>rorpisrnot)%rrrrr4r r(rrrrrrrrrrrrrrr rOZcomp_forZ old_comp_forrrr/rZcomp_ifZ old_comp_iftestrZcomp_op comparisonrr)rrrFrFrGra sf        $       rz # fmt: offz # fmt:offz# yapf: disablez # fmt: onz# fmt:onz# yapf: enableccs>x8t|j|jtjkdD]}t|j|jd|jdVqWdS)aClean the prefix of the `leaf` and generate comments from it, if any. Comments in lib2to3 are shoved into the whitespace prefix. This happens in `pgen2/driver.py:Driver.parse_tokens()`. This was a brilliant implementation move because it does away with modifying the grammar to include all the possible places in which comments can be placed. The sad consequence for us though is that comments don't "belong" anywhere. This is why this function generates simple parentless Leaf objects for comments. We simply don't know what the correct parent should be. No matter though, we can live without this. We really only need to differentiate between inline and standalone comments. The latter don't share the line with any code. Inline comments are emitted as regular token.COMMENT leaves. Standalone are emitted with a fake STANDALONE_COMMENT token identifier. ) is_endmarkerr])rN) list_commentsrrr4 ENDMARKERr/rOrE)rpcrFrFrGrF srFc@s2eZdZUdZeed<eed<eed<eed<dS) ProtoCommentaDescribes a piece of syntax that is a comment. It's not a :class:`blib2to3.pytree.Leaf` so that: * it can be cached (`Leaf` objects should not be reused more than once as they store their lineno, column, prefix, and parent information); * `newlines` and `consumed` fields are kept separate from the `value`. This simplifies handling of special marker comments like ``# fmt: off/on``. rrOrEconsumedN)rBrCrDrErrrrFrFrFrGr s ri)r>)rrrPc Csg}|rd|kr|Sd}d}d}xt|dD]\}}|t|d7}|}|s\|d7}|dsz|dr0|d7}q0||kr|stj}nt}t |} | t || ||dd}q0W|S)zNReturn a list of :class:`ProtoComment` objects parsed from the given `prefix`.#rr]rY\)rrOrEr) r`r_rryraendswithr4rr make_commentr3r) rrr5rnlinesZ ignored_linesrfrdZ comment_typerrFrFrGr s0    r)contentrPcCsH|}|sdS|ddkr(|dd}|r@|ddkr@d|}d|S)aReturn a consistently formatted comment from the given `content` string. All comments (except for "##", "#!", "#:", '#'", "#%%") should have a single space between the hash sign and the content. If `content` didn't start with a hash sign, one is provided. rrrYNz !:#'%r)rstrip)rrFrFrGr s  r)rdrrwrPc #sh|jr|VdSt|}tttdfdd }|t}|t}|t}|t}|s|j st |j |dsv| r|j r|sjr||g} ng} nv|jrtg} nhtttttdfdd } jr|j r||tt||| g} n||||| g} n|j r tt| g} n| g} xR| D]D} yt|| ||d } Wntk rJwYnX| EdHPqW|VdS) zTransform a `line`, potentially splitting it into many lines. They should fit in the allotted `line_length` but might not be able to. `features` are syntactical features that may be used in the output. N)STrPcs|jjS)zInitialize StringTransformer)rr)r)rrFrGinit_st5 sztransform_line..init_st)rline_str)rdrwrPc3sfxJt|jD]:}tt|j||d}t|djdr|EdHdSqWt|j|dEdHdS)zWraps calls to `right_hand_split`. The calls increasingly `omit` right-hand trailers (bracket pairs with content), meaning the trailers get glued together to split on another bracket pair instead. )omitr)rN)rrw)generate_trailers_to_omitrrright_hand_splitis_line_short_enough)rdrwrrb)rrFrGrhsQ s ztransform_line..rhs)r)rline_to_stringr StringTransformer StringMergerStringParenStripperStringSplitterStringParenWrapperrrrrr!rrrrleft_hand_splitr;rr<rdelimiter_splitstandalone_comment_splitrun_transformerrH) rdrrwrrZ string_mergeZstring_paren_stripZ string_splitZstring_paren_wrapZ transformersr transformr5rF)rrGr& sZ      rc@sreZdZUdZeed<eed<dZeee dddZ eeee e eddd Z eeee ed d d Zd S)ra An implementation of the Transformer protocol that relies on its subclasses overriding the template methods `do_match(...)` and `do_transform(...)`. This Transformer works exclusively on strings (for example, by merging or splitting them). The following sections can be found among the docstrings of each concrete StringTransformer subclass. Requirements: Which requirements must be met of the given Line for this StringTransformer to be applied? Transformations: If the given Line meets all of the above requirements, which string transformations can you expect to be applied to it by this StringTransformer? Collaborations: What contractual agreements does this StringTransformer have with other StringTransfomers? Such collaborations should be eliminated/minimized as much as possible. rru)rdrPcCsdS)z Returns: * Ok(string_idx) such that `line.leaves[string_idx]` is our target string, if a match was able to be made. OR * Err(CannotTransform), if a match was not able to be made. NrF)rRrdrFrFrGdo_match szStringTransformer.do_match)rd string_idxrPcCsdS)a& Yields: * Ok(new_line) where new_line is the new transformed line. OR * Err(CannotTransform) if the transformation failed for some reason. The `do_match(...)` template method should usually be used to reject the form of the given Line, but in some cases it is difficult to know whether or not a Line meets the StringTransformer's requirements until the transformation is already midway. Side Effects: This method should NOT mutate @line directly, but it MAY mutate the Line's underlying Node structure. (WARNING: If the underlying Node structure IS altered, then this method should NOT be allowed to yield an CannotTransform after that point.) NrF)rRrdrrFrFrG do_transform szStringTransformer.do_transform)rd _featuresrPccstdd|jDstd||}t|trN|}td|jjd|| }x>| ||D].}t|tr|}td|| }|VqdWdS)z StringTransformer instances have a call signature that mirrors that of the Transformer type. Raises: CannotTransform(...) if the concrete StringTransformer class is unable to transform @line. css|]}|jtjkVqdS)N)rr4r)rrrFrFrGr sz-StringTransformer.__call__..z"There are no strings in this line.zThe string transformer z; does not recognize this line as one that it can transform.z>StringTransformer failed while attempting to transform string.N) r#rrHrrrUr>rMrBrTr)rRrdr match_resultcant_transformrZ line_resultrFrFrG__call__ s"    zStringTransformer.__call__N)rBrCrDrErrrhrr; TMatchResultrrTResultrrr<rrFrFrFrGr s  rc@s"eZdZUdZeed<eed<dS) CustomSplitaA custom (i.e. manual) string split. A single CustomSplit instance represents a single substring. Examples: Consider the following string: ``` "Hi there friend." " This is a custom" f" string {split}." ``` This string will correspond to the following three CustomSplit instances: ``` CustomSplit(False, 16) CustomSplit(False, 17) CustomSplit(True, 16) ``` has_prefix break_idxN)rBrCrDrErhrrrFrFrFrGr s rc@seZdZUdZeeefZee Z e eee dffe d<eeddddZeee dd d d Zeee dd d ZeedddZdS)CustomSplitMapMixinz This mixin class is used to map merged strings to a sequence of CustomSplits, which will then be used to re-split the strings iff none of the resultant substrings go over the configured max line length. ._CUSTOM_SPLIT_MAPzCustomSplitMapMixin._Key)stringrPcCs t||fS)z Returns: A unique identifier that is used internally to map @string to a group of custom splits. )r)rrFrFrG_get_key szCustomSplitMapMixin._get_keyN)r custom_splitsrPcCs||}t||j|<dS)zCustom Split Map Setter Method Side Effects: Adds a mapping from @string to the custom splits @custom_splits. N)rtupler)rRrrrrFrFrGadd_custom_splits" s z%CustomSplitMapMixin.add_custom_splitscCs$||}|j|}|j|=t|S)aaCustom Split Map Getter Method Returns: * A list of the custom splits that are mapped to @string, if any exist. OR * [], otherwise. Side Effects: Deletes the mapping between @string and its associated custom splits (which are returned to the caller). )rrr)rRrrrrFrFrGpop_custom_splits- s  z%CustomSplitMapMixin.pop_custom_splitscCs||}||jkS)zb Returns: True iff @string is associated with a set of custom splits. )rr)rRrrrFrFrGhas_custom_splitsA s z%CustomSplitMapMixin.has_custom_splits)rBrCrDrErStringIDrZ_Keyrrrrrr staticmethodrrrrrrhrrFrFrFrGr s     rc@seZdZdZeedddZeeee edddZ e eee eddd Z eee edd d Z e eee d dd dZd S)ra`StringTransformer that merges strings together. Requirements: (A) The line contains adjacent strings such that at most one substring has inline comments AND none of those inline comments are pragmas AND the set of all substring prefixes is either of length 1 or equal to {"", "f"} AND none of the substrings are raw strings (i.e. are prefixed with 'r'). OR (B) The line contains a string which uses line continuation backslashes. Transformations: Depending on which of the two requirements above where met, either: (A) The string group associated with the target string is merged. OR (B) All line-continuation backslashes are removed from the target string. Collaborations: StringMerger provides custom split information to StringSplitter. )rdrPcCs~|j}t|}xft|D]Z\}}|jtjkrT||drT||djtjkrTt|S|jtjkrd|jkrt|SqWtdS)NrYz\ z+This line has no strings that need merging.) ris_valid_index_factoryr`rr4rrNrOTErr)rRrdLLis_valid_indexrcrrFrFrGra s   zStringMerger.do_match)rdrrPc cs|}|||}t|tr"|}|||}t|tr@|}t|trt|tr|}|}td}||_||_t|Vn t|VdS)Nz6StringMerger failed to merge any strings in this line.) 7_StringMerger__remove_backslash_line_continuation_charsrrNrT!_StringMerger__merge_string_grouprUr>rH __cause__) rRrdrnew_lineZ rblc_resultZ msg_resultZmsg_cant_transformZrblc_cant_transformrrFrFrGrs s"    zStringMerger.do_transformcCs|j}||}|jtjkr.d|jkr.t|jr>td|dS|}|j |_t ||||j|}|j dd|_t |S)a$ Merge strings that were split across multiple lines using line-continuation backslashes. Returns: Ok(new_line), if @line contains backslash line-continuation characters. OR Err(CannotTransform), otherwise. z\ z String leaf z= does not contain any backslash line continuation characters.r) rrr4rrOhas_triple_quotesrr4rcopy append_leavesr*rN)rdrr string_leafrZnew_string_leafrFrFrGZ*__remove_backslash_line_continuation_chars s      z7StringMerger.__remove_backslash_line_continuation_charscs|j}t|}|||}t|tr(|S||j}d}||jdtttdfdd }g} g} |} d} x6| s|| r|| jt j krt || j} | d7} qlWd} d}d}|} x|| rT|| jt j krT|d7}|| j}t |}d | kr d |kr t d d |}|||}t|}| || |||} || | }| d7} qWtt j | }|jrrt||jt| dd}xh| D]`}||}|dkstd ||t|d }||rt| ndd}| t||qWtt j |j|d}|d k rt|||}xt|D]x\}}||krJ||||krf||krnn,x&|||D]}|j|ddqzWq.t|||gq.W||j| t|S)aI Merges string group (i.e. set of adjacent strings) where the first string in the group is `line.leaves[string_idx]`. Returns: Ok(new_line), if ALL of the validation checks found in __validate_msg(...) pass. OR Err(CannotTransform), otherwise. z#@@@@@ BLACK BREAKPOINT MARKER @@@@@r)r string_prefixrPcsBt|d}|t|dd}td|dd|}|S)aStrip @string (i.e. make it a "naked" string) Pre-conditions: * assert_is_leaf_string(@string) Returns: A string that is identical to @string except that @string_prefix has been stripped, the surrounding QUOTE characters have been removed, and any remaining QUOTE characters have been escaped. z(?:(?.make_nakedrrYrrXz(\{|\})z{1}{1}z=Logic error while filling the custom string breakpoint cache.NT)r)rr_StringMerger__validate_msgrrUr(rOrrr4rrirZsubfrhr3r/rurIrfindr~rr* replace_childr4r`r*rrrN)rRrdrrrvresultZ atom_nodeZ BREAK_MARKrrZprefix_trackerZ next_str_idxrSZNSnum_of_stringsZSSZ next_prefixZNSSrZS_leafZ temp_stringZmark_idxZbreakpoint_idxrrrcr comment_leafrF)rrGZ__merge_string_group sx                   z!StringMerger.__merge_string_groupNcCs(d}t}d}x|j|dD]}|jtjkrR|jtjkrPt||jkrP|d7}Pt|j rdt dS|d7}t |j }d|krt dS| |t||jkr|d7}t |jt|rt dSqW|dkrt d |d S|dkrt d |d St|dkr |d d hkr t d|d StdS)aValidate (M)erge (S)tring (G)roup Transform-time string validation logic for __merge_string_group(...). Returns: * Ok(None), if ALL validation checks (listed below) pass. OR * Err(CannotTransform), if any of the following are true: - The target string is not in a string group (i.e. it has no adjacent strings). - The string group has more than one inline comment. - The string group has an inline comment that appears to be a pragma. - The set of all string prefixes in the string group is of length greater than one and is not equal to {"", "f"}. - The string group consists of raw strings. rNrYz.StringMerger does NOT merge multiline strings.rz(StringMerger does NOT merge raw strings.z0Cannot merge strings which have pragma comments.rZz,Not enough strings to merge (num_of_strings=z).z!Too many inline string comments (rrXzToo many different prefixes ()rrrr4rrrrrrOrrircontains_pragma_commentrrN)rdrZnum_of_inline_string_commentsZset_of_prefixesrrrrFrFrGZ__validate_msgA s8     zStringMerger.__validate_msg)rBrCrDrEr;rrrrrrrrrrrFrFrFrGrJ s!rc@s:eZdZdZeedddZeeee edddZ dS) raStringTransformer that strips surrounding parentheses from strings. Requirements: The line contains a string which is surrounded by parentheses and: - The target string is NOT the only argument to a function call). - If the target string contains a PERCENT, the brackets are not preceeded or followed by an operator with higher precedence than PERCENT. Transformations: The parentheses mentioned in the 'Requirements' section are stripped. Collaborations: StringParenStripper has its own inherent usefulness, but it is also relied on to clean up the parentheses created by StringParenWrapper (in the event that they are no longer needed). )rdrPc Cs|j}t|}xt|D]\}}|jtjkr2q||dr||djtjkst||drdq||dr||djtjks||djt krq|}t }| ||}||drJ||d} tj dd||d|DkrJ| jtj tjtjtjtj tjtjtjtjtjh ks| jrJ| jjtjkrJ| jtjtjhkrJq||r||jtjkrt||s||dr||djtjtjtjtjhkrqt|SqWtdS)NrYrZcSsh|] }|jqSrF)r)rrrFrFrGrv sz/StringParenStripper.do_match..z+This line has no strings wrapped in parens.)rrr`rr4rr is_empty_lparrr StringParserparsePERCENTSTARrSLASH DOUBLESLASHTILDEr_ZAWAITrr(rrPLUSMINUSr is_empty_rparr rNr) rRrdrridxrr string_parserZnext_idxZ before_lparrFrFrGr sX   &  "    zStringParenStripper.do_match)rdrrPc cs|j}t}|||}x0||d||fD]}||r.tdVq.W|}|j|_t|||d|dt t j ||j }||d t|||||t||||d|||dd|| t|VdS)NrYz@Will not strip parentheses which have comments attached to them.)rrrr*rr4rrrr/r4rrOr`rr3rN) rRrdrrrZrpar_idxrrrrFrFrGr s$     & z StringParenStripper.do_transformN) rBrCrDrEr;rrrrrrrFrFrFrGr~ sSrc@s\eZdZdZeeedddZeedddZee e ddd d Z ee e dd d Z dS) BaseStringSplittera Abstract class for StringTransformers which transform a Line's strings by splitting them or placing them on their own lines where necessary to avoid going over the configured line length. Requirements: * The target string value is responsible for the line going over the line length limit. It follows that after all of black's other line split methods have been exhausted, this line (or one of the resulting lines after all line splits are performed) would still be over the line_length limit unless we split this string. AND * The target string is NOT a "pointless" string (i.e. a string that has no parent or siblings). AND * The target string is not followed by an inline comment that appears to be a pragma. AND * The target string is not a multiline (i.e. triple-quote) string. )rdrPcCsdS)a BaseStringSplitter asks its clients to override this method instead of `StringTransformer.do_match(...)`. Follows the same protocol as `StringTransformer.do_match(...)`. Refer to `help(StringTransformer.do_match)` for more information. NrF)rRrdrFrFrGdo_splitter_match s z$BaseStringSplitter.do_splitter_matchcCs>||}t|tr|S|}|||}t|tr:|S|S)N)rrrUrT_BaseStringSplitter__validate)rRrdrrrrFrFrGr# s    zBaseStringSplitter.do_matchN)rdrrPcCs|j}||}|||}t|j|kr0tdS|jrTdd|jjDtjtj gkrftd|jdSt |j||j krt |j t |j|rtdSt |jrtdStdS) aw Checks that @line meets all of the requirements listed in this classes' docstring. Refer to `help(BaseStringSplitter)` for a detailed description of those requirements. Returns: * Ok(None), if ALL of the requirements are met. OR * Err(CannotTransform), if ANY of the requirements are NOT met. zBThe string itself is not what is causing this line to be too long.cSsg|] }|jqSrF)r)rLrFrFrGrD sz1BaseStringSplitter.__validate..z This string (z/) appears to be pointless (i.e. has no parent).ziLine appears to end with an inline pragma comment. Splitting the line could modify the pragma's behavior.z"We cannot split multiline strings.N)r*_BaseStringSplitter__get_max_string_lengthrrOrr(rr4rNEWLINErrrrrN)rRrdrrrmax_string_lengthrFrFrGZ __validate/ s$    zBaseStringSplitter.__validatecCs|j}t|}|jd}||dr|d}||djtjkrb||djdkrb|dkrb|d8}||}|jtjkr~|d7}|jtjkr|d7}|jtj tj tj gkr|d7}x(|d|dD]}|t t |7}qW||dr||d} | jtjkr,| jdkr,t ||dkr,||d} | jtjkrB|d7}||dr||d} | jtjkr| jtj kr|d7}||dr||djtjkr|d7}|t | j7}d} x8|||D]&} | sd} |d7}|t | j7}qW|j|} | S) az Calculates the max string length used when attempting to determine whether or not the target string is responsible for causing the line to go over the line length limit. WARNING: This method is tightly coupled to both StringSplitter and (especially) StringParenWrapper. There is probably a better way to accomplish what is being done here. Returns: max_string_length: such that `line.leaves[string_idx].value > max_string_length` implies that the target string IS responsible for causing this line to exceed the line length limit. r\rYrrZr[NFT)rrrrr4rrOrrrrrrrrr r*r)rRrdrrroffsetZp_idxPrNZNNZ has_commentsrrrFrFrGZ__get_max_string_lengthZ sP     ,   z*BaseStringSplitter.__get_max_string_length) rBrCrDrErr;rrrrrrrrFrFrFrGr s   +rc@szeZdZdZdZdZeedddZee e e eddd Z e e ee d d d Zed dddZe e e dddZd S)ra StringTransformer that splits "atom" strings (i.e. strings which exist on lines by themselves). Requirements: * The line consists ONLY of a single string (with the exception of a '+' symbol which MAY exist at the start of the line), MAYBE a string trailer, and MAYBE a trailing comma. AND * All of the requirements listed in BaseStringSplitter's docstring. Transformations: The string mentioned in the 'Requirements' section is split into as many substrings as necessary to adhere to the configured line length. In the final set of substrings, no substring should be smaller than MIN_SUBSTR_SIZE characters. The string will ONLY be split on spaces (i.e. each new substring should start with a space). If the string is an f-string, it will NOT be split in the middle of an f-expression (e.g. in f"FooBar: {foo() if x else bar()}", {foo() if x else bar()} is an f-expression). If the string that is being split has an associated set of custom split records and those custom splits will NOT result in any line going over the configured line length, those custom splits are used. Otherwise the string is split as late as possible (from left-to-right) while still adhering to the transformation rules listed above. Collaborations: StringSplitter relies on StringMerger to construct the appropriate CustomSplit objects and add them to the custom split map. rmz (?||t|V}t#||d dt|Vn ||j$%|_$t|VdS)NrrXTr)rPcsoS)NrFrF)first_string_linestarts_with_plusrFrGline_needs_plus2sz4StringSplitter.do_transform..line_needs_plus)rrPcs.r*ttjd}td|||dS)a> Side Effects: If @line starts with a plus and this is the first line we are constructing, this function appends a PLUS leaf to @new_line and replaces the old PLUS leaf in the node structure. Otherwise this function does nothing. r^rN)r/r4rrr3)rZ plus_leaf)rr rFrGmaybe_append_plus5s z6StringSplitter.do_transform..maybe_append_plusrYcs:j}|jd8}|rdnd8}|r0dnd8}|S)z Returns: The max allowed length of the string value used for the last line we will construct. r\rYrrZ)rr)r5)ends_with_commardr rRrFrGmax_last_stringFs z4StringSplitter.do_transform..max_last_stringr\zUnable to split z at such high of a line depth: c3s|]}|jkVqdS)N)r)rcsplit) max_break_idxrFrGrfsz.StringSplitter.do_transform..cs"rtdkStkSdS)z Returns: True iff `rest_value` (the remaining string value from the last split), should be split again. rYN)rrF)rr rest_valueuse_custom_breakpointsrFrGmore_splits_should_be_madems z?StringSplitter.do_transform..more_splits_should_be_maderZF)&rrOrinsert_str_child_factoryrirrRE_FEXPRVERBOSErr4rrhr;rrrrrrrrr_StringSplitter__get_break_idx#_StringSplitter__normalize_f_stringrr/r._StringSplitter__maybe_normalize_string_quotesr4r3rNrrrrrr)rRrdrrrinsert_str_childrZdrop_pointless_f_prefixr rZstring_line_resultsrrZmax_bidxZmaybe_break_idxZ next_valueZ next_leafZ next_lineZ rest_leafr Z temp_valuerZnon_string_linerF) rrr r rdr rrrrRr rrGrs                            zStringSplitter.do_transform)rrrPcst}||sttdttttfdfdd dtkttdfdd ttdfd d }|}x ||d r||s|d 8}qW||s|d }x ||d r||s|d 7}qW||r||sdS|S) a This method contains the algorithm that StringSplitter uses to determine which character to split each string at. Args: @string: The substring that we are attempting to split. @max_break_idx: The ideal break index. We will return this value if it meets all the necessary conditions. In the likely event that it doesn't we will try to find the closest index BELOW @max_break_idx that does. If that fails, we will expand our search by also considering all valid indices ABOVE @max_break_idx. Pre-Conditions: * assert_is_leaf_string(@string) * 0 <= @max_break_idx < len(@string) Returns: break_idx, if an index is able to be found that meets all of the conditions listed in the 'Transformations' section of this classes' docstring. OR None, otherwise. N)rPc3sDdkr6gx(tjtjD]}|q WEdHdS)z Yields: All ranges of @string which, if @string were to be split there, would result in the splitting of an f-expression (which is NOT allowed). N)rfinditerrrr3span)match) _fexpr_slicesrRrrFrG fexpr_slicess z4StringSplitter.__get_break_idx..fexpr_slicesrX)rcrPcs<sdSx.D]$\}}||kr,|krnqdSqWdS)z Returns: True iff returning @i would result in the splitting of an f-expression (which is NOT allowed). FTrF)rcstartend)r is_fstringrFrGbreaks_fstring_expressions zAStringSplitter.__get_break_idx..breaks_fstring_expressioncsJ|dk}t|djko6td|jk}|oH|oH| S)z Returns: True iff ALL of the conditions listed in the 'Transformations' section of this classes' docstring would be be met by returning @i. rN)rMIN_SUBSTR_SIZE)rcZis_spaceZ is_big_enough)r#rRrrFrGpasses_all_checks&s z9StringSplitter.__get_break_idx..passes_all_checksrY)rr~rrrIndexrirh)rRrrrr%rrF)rr#rr"rRrrGZ__get_break_idxs$ "   zStringSplitter.__get_break_idxN)rrPcCs|jrt|dS)N)rurI)rRrrFrFrGZ__maybe_normalize_string_quotesGsz.StringSplitter.__maybe_normalize_string_quotes)rrrPcCsrt|d|krjt|j|tjsj|dd}|t|d}tdd|}tdd|}|}||S|SdS)a Pre-Conditions: * assert_is_leaf_string(@string) Returns: * If @string is an f-string that contains no f-expressions, we return a string identical to @string except that the 'f' prefix has been stripped and all double braces (i.e. '{{' or '}}') have been normalized (i.e. turned into '{' or '}'). OR * Otherwise, we return @string. rXrNz\{\{{z\}\}})rrrrrr*rr)rRrr new_prefixtempZ new_stringrFrFrGZ__normalize_f_stringKs   z#StringSplitter.__normalize_f_string)rBrCrDrEr$rr;rrrrrrrrrr/rrrFrFrFrGr s# 'Jarc@seZdZdZeedddZeee e e dddZ eee e e ddd Z eee e e dd d Zeee e e dd d Zeee e e dddZee eeedddZdS)ra> StringTransformer that splits non-"atom" strings (i.e. strings that do not exist on lines by themselves). Requirements: All of the requirements listed in BaseStringSplitter's docstring in addition to the requirements listed below: * The line is a return/yield statement, which returns/yields a string. OR * The line is part of a ternary expression (e.g. `x = y if cond else z`) such that the line starts with `else `, where is some string. OR * The line is an assert statement, which ends with a string. OR * The line is an assignment statement (e.g. `x = ` or `x += `) such that the variable is being assigned the value of some string. OR * The line is a dictionary key assignment where some valid key is being assigned the value of some string. Transformations: The chosen string is wrapped in parentheses and then split at the LPAR. We then have one line which ends with an LPAR and another line that starts with the chosen string. The latter line is then split again at the RPAR. This results in the RPAR (and possibly a trailing comma) being placed on its own line. NOTE: If any leaves exist to the right of the chosen string (except for a trailing comma, which would be placed after the RPAR), those leaves are placed inside the parentheses. In effect, the chosen string is not necessarily being "wrapped" by parentheses. We can, however, count on the LPAR being placed directly before the chosen string. In other words, StringParenWrapper creates "atom" strings. These can then be split again by StringSplitter, if necessary. Collaborations: In the event that a string line split by StringParenWrapper is changed such that it no longer needs to be given its own line, StringParenWrapper relies on StringParenStripper to clean up the parentheses it created. )rdrPcCs|j}d}|p||}|p$||}|p2||}|p@||}|pN||}|dk r|j|j}d|kr|j|jdd}t ||kr| |st dSt |St dS)NrrYr\zWe do not wrap long strings in parentheses when the resultant line would still be over the specified line length and can't be split further by StringSplitter.z2This line does not contain any non-atomic strings.) r _return_match _else_match _assert_match _assign_match _dict_matchrOrrrrrrN)rRrdrr string_valuerrFrFrGrs"   z$StringParenWrapper.do_splitter_match)rrPcCsjt|dtjtjgkrf|djdkrft|}|drFt|drFdnd}||rf||jtj krf|SdS)aK Returns: string_idx such that @LL[string_idx] is equal to our target (i.e. matched) string, if this line matches the return/yield statement requirements listed in the 'Requirements' section of this classes' docstring. OR None, otherwise. r)rPyieldrYrZN) parent_typerZ return_stmt yield_exprrOr is_empty_parrr4r)rrrrFrFrGr+s z StringParenWrapper._return_matchcCstt|dtjkrp|djtjkrp|djdkrpt|}|drPt|drPdnd}||rp||jtj krp|SdS)aG Returns: string_idx such that @LL[string_idx] is equal to our target (i.e. matched) string, if this line matches the ternary expression requirements listed in the 'Requirements' section of this classes' docstring. OR None, otherwise. rrprYrZN) r2rrrr4rrOrr4r)rrrrFrFrGr,szStringParenWrapper._else_matchcCst|dtjkr|djdkrt|}xzt|D]n\}}|jtjkr2t ||dr^|dn|d}||r2||jtj kr2|}t }| ||}||s2|Sq2WdS)aE Returns: string_idx such that @LL[string_idx] is equal to our target (i.e. matched) string, if this line matches the assert statement requirements listed in the 'Requirements' section of this classes' docstring. OR None, otherwise. rrnrYrZN) r2rZ assert_stmtrOrr`rr4rr4rrr)rrrcrrrrrFrFrGr-s    z StringParenWrapper._assert_matchcCst|dtjtjtjgkr|djtjkrt|}xt |D]\}}|jtj tj gkr>t ||drp|dn|d}||r>||jtj kr>|}t}|||}t|dtjkr||r||jtjkr|d7}||s>|Sq>WdS)aI Returns: string_idx such that @LL[string_idx] is equal to our target (i.e. matched) string, if this line matches the assignment statement requirements listed in the 'Requirements' section of this classes' docstring. OR None, otherwise. rrYrZN)r2r expr_stmtrr^rr4rrr`r PLUSEQUALr4rrrr)rrrcrrrrrFrFrGr. s"  z StringParenWrapper._assign_matchcCstjt|dt|djgkrt|}xt|D]\}}|jtjkr2t ||dr^|dn|d}||r2||jtj kr2|}t }| ||}||r||jtj kr|d7}||s2|Sq2WdS)aX Returns: string_idx such that @LL[string_idx] is equal to our target (i.e. matched) string, if this line matches the dictionary key assignment statement requirements listed in the 'Requirements' section of this classes' docstring. OR None, otherwise. rrYrZN)rrr2r(rr`rr4rr4rrrr)rrrcrrrrrFrFrGr/;s    zStringParenWrapper._dict_match)rdrrPccsJ|j}t|}t||}t|d}d}||jtjkr>d}||g}|rZ||||} |d|} d} | r| djtj krd} || d| t | || t tj d} | rt ||d| n|| | | x.|D]&} x || D]}| j|ddqWqWt| V||j}t|jdd|jd}t tj|}||||d}||dr||dd}|r| | r|r|djtjkstd| }t |||t|V|}| j|_t tjd }|dk rt ||n|||||rr4r7rr ParserStaterrrSrr/rrrhr;rFrFrFrGrs.      $r)err_msgrPcCst|}t|S)zW(T)ransform Err Convenience function used when working with the TResult type. )rHrU)r@rrFrFrGrOsr) comment_listrPcCs"x|D]}|jdrdSqWdS)z Returns: True iff one of the comments in @comment_list is a pragma used by one of the more common static analysis tools for python (e.g. mypy, flake8, pylint). )z# type:z# noqaz # pylint:TF)rOra)rArrFrFrGrXs  r)rrPcs(|j|tddfdd }|S)a Factory for a convenience function that is used to orphan @string_leaf and then insert multiple new leaves into the same part of the node structure that @string_leaf had originally occupied. Examples: Let `string_leaf = Leaf(token.STRING, '"foo"')` and `N = string_leaf.parent`. Assume the node `N` has the following original structure: Node( expr_stmt, [ Leaf(NAME, 'x'), Leaf(EQUAL, '='), Leaf(STRING, '"foo"'), ] ) We then run the code snippet shown below. ``` insert_str_child = insert_str_child_factory(string_leaf) lpar = Leaf(token.LPAR, '(') insert_str_child(lpar) bar = Leaf(token.STRING, '"bar"') insert_str_child(bar) rpar = Leaf(token.RPAR, ')') insert_str_child(rpar) ``` After which point, it follows that `string_leaf.parent is None` and the node `N` now has the following structure: Node( expr_stmt, [ Leaf(NAME, 'x'), Leaf(EQUAL, '='), Leaf(LPAR, '('), Leaf(STRING, '"bar"'), Leaf(RPAR, ')'), ] ) N)rrPcs0dk s tdk st|d7dS)NrY)r~ra)r)string_child_idx string_parentrFrGrs   z2insert_str_child_factory..insert_str_child)r(r`r)rrrF)rBrCrGrfs. r)rrPcCs|t}|dddkS)zS Returns: True iff @string starts with three quotation characters. Nr[>"""''')ryr:)rZ raw_stringrFrFrGrs rcCs|dks|jdkrdS|jjS)z| Returns: @node.parent.type, if @node is not None and has a parent. OR None, otherwise. N)r(r)rrFrFrGr2sr2cCst|pt|S)N)rr)rrFrFrGr4sr4cCs|jtjko|jdkS)Nr)rr4rrO)rrFrFrGrsrcCs|jtjko|jdkS)Nr)rr4rrO)rrFrFrGrsr)seqrPcsttdfdd }|S)a Examples: ``` my_list = [1, 2, 3] is_valid_index = is_valid_index_factory(my_list) assert is_valid_index(0) assert is_valid_index(2) assert not is_valid_index(3) assert not is_valid_index(-1) ``` )rrPcsd|kotkSS)zx Returns: True iff @idx is positive AND seq[@idx] does NOT raise an IndexError. r)r)r)rFrFrGrsz.is_valid_index_factory..is_valid_index)rrh)rFrrF)rFrGrsr)rdrPcCst|dS)zmReturns the string representation of @line. WARNING: This is known to be computationally expensive. r])rrg)rdrFrFrGrsr)rold_linerrPcCsVxP|D]H}t|j|j}t||||x ||D]}|j|ddq8WqWdS)a Append leaves (taken from @old_line) to @new_line, making sure to fix the underlying Node structure where appropriate. All of the leaves in @leaves are duplicated. The duplicates are then appended to @new_line and used to replace their originals in the underlying Node structure. Any comments attached to the old leaves are reattached to the new leaves. Pre-conditions: set(@leaves) is a subset of set(@old_line.leaves). T)rN)r/rrOrr3r*)rrGrZold_leafZnew_leafrrFrFrGrs   r) old_child new_childrPcCs.|j}|sdS|}|dk r*|||dS)z Side Effects: * If @old_child.parent is set, replace @old_child with @new_child in @old_child's underlying Node structure. OR * Otherwise, this function does nothing. N)r(r`ra)rHrIr(Z child_idxrFrFrGrs rcCs>t|d}d}x(||tkr8|||7}|d7}qW|S)z Pre-conditions: * assert_is_leaf_string(@string) Returns: @string's prefix (e.g. '', 'r', 'f', or 'rf'). rrrY)rr:r)rrZ prefix_idxrFrFrGris ricCs|d}|d}d||gkr,t||}n t||}d|krRt|dksbnt|d|ddks|t|dt|d |ttstt|d |d ttd d S) aH Checks the pre-condition that @string has the format that you would expect of `leaf.value` where `leaf` is some Leaf such that `leaf.type == token.STRING`. A more precise description of the pre-conditions that are checked are listed below. Pre-conditions: * @string starts with either ', ", ', or " where `set()` is some subset of `set(STRING_PREFIX_CHARS)`. * @string ends with a quote character (' or "). Raises: AssertionError(...) if the pre-conditions listed above are not satisfied. "'rrrYz0 is missing a starting quote character (' or ").)rKrJz/ is missing an ending quote character (' or ").Nz is NOT a subset of r)rrr"rr~rissubsetr:)rZ dquote_idxZ squote_idxZ quote_idxrFrFrGr"s         r)rdrrPc csg}g}g}|}d}xZ|jD]P}||krH|jtkrH|j|krH|rD|n|}||||kr|jtkr|}|}qW|s|tdt|||}t|||dd} t|||} t|| | x|| | fD]} | r| VqWdS)a/Split line into many lines, starting with the first matching bracket pair. Note: this usually looks weird, only use this for function definitions. Prefer RHS otherwise. This is why this function is not symmetrical with :func:`right_hand_split` which also handles optional parentheses. NzNo brackets foundT)is_body) rrrrr3rrIbracket_split_build_line bracket_split_succeeded_or_raise) rdr tail_leaves body_leaves head_leavescurrent_leavesZmatching_bracketrheadbodytailr5rFrFrGrEs0         r)rdrrwrrPccsg}g}g}|}d}d} xdt|jD]V} ||krD| |krD|r@|n|}|| ||kr$| jtkr$t| |kr$| j}| } |}q$W|r| r|std|||t |||} t |||dd} t |||} t | | | t j |kr|jt jkr|js| jt jkr| js|js| dst| ||drt| h|}yt||||dEdHdStk rt| st| |dstd n| s| rtd YnXt|t| x | | | fD]}|r|VqWdS) aXSplit line into many lines, starting with the last matching bracket pair. If the split was by optional parentheses, attempt splitting without them, too. `omit` is a collection of closing bracket IDs that shouldn't be considered for this split. Note: running this function modifies `bracket_depth` on the leaves of `line`. NzNo brackets foundT)rMr)omit_on_explode)rwr)rz|dkr&tdn|dkr>td|ddS)aRaise :exc:`CannotSplit` if the last left- or right-hand split failed. Do nothing otherwise. A left- or right-hand split is based on a pair of brackets. Content before (and including) the opening bracket is left on one line, content inside the brackets is put on a separate line, and finally content starting with and following the closing bracket is put on a separate line. Those are called `head`, `body`, and `tail`, respectively. If the split produced the same line (all content in `head`) or ended up with an empty `body` and the `tail` is just the closing bracket, then it's considered failed. rz)Splitting brackets produced the same liner[z,Splitting brackets on an empty body to save z characters is not worth itN)rrrgrI)rTrUrVrkrFrFrGrOs rO)rM)roriginalrrMrPc Cst|jd}|rd|_|jd7_|rt|ddd|joZ|jdkoZtdd|D }|jsf|rxZtt |dd d D]B}||j t krq|||j t j krtt j d }||d|Pq|Wx<|D]4}|j|dd x ||D]} |j| dd qWqW|rt||rd|_|S) zReturn a new line with given `leaves` and respective comments from `original`. If `is_body` is True, the result line is one-indented inside brackets and as such has its first leaf's prefix normalized and a trailing comma added when expected. )rTrYr)rrcss|]}|jtjkVqdS)N)rr4r)rrrFrFrGrsz+bracket_split_build_line..rr)r)r;rrrGrrOr#rr rrrr4rr/insertr3r*should_split_body_exploder) rr]rrMr5Z no_commasrc new_commar comment_afterrFrFrGrNs0     rN) split_funcrPcs,tdtttttdfdd }|S)zNormalize prefix of the first leaf in every line returned by `split_func`. This is a decorator over relevant split functions. rF)rdrwrPc3s0x*||D]}t|jddd|Vq WdS)NrT)r)rGr)rdrw)rbrFrG split_wrapper sz0dont_increase_indentation..split_wrapper)rF)r r;rr<r)rbrcrF)rbrGdont_increase_indentations"rd)rdrwrPc #syjd}Wntk r*tdYnXj}y|jt|hd}Wntk rdtdYnX|tkr||dkrtdt j j dt j }d}ttt d fd d }xΈjD]}||Ed Hx |D]} || Ed HqWt||j}|j|krVt|tjhd r0|o,tj|k}n&t|tjtjhd rV|oTtj|k}|jt|} | |krVt j j dqWr|r|tkrڈjdjtj krڈjdjt!krttj d} "| Vd S)zSplit according to delimiters of the highest priority. If the appropriate Features are given, the split will add trailing commas also in function signatures and calls that contain `*` and `**`. rz Line empty)rzNo delimiters foundrYz7Splitting a single attribute from its owner looks wrong)rrT)rrPc3sLyj|ddWn4tk rFVtjjd|YnXdS)zEAppend `leaf` to current line or to new line if appending impossible.T)r)rrN)rrr;rrr3)r)rrdrFrGappend_to_line/s z'delimiter_split..append_to_lineN)r|r)#rrrIrrrrrrr;rrr r>r/rr*r"rrrrr<r~rrr}rrrrr4rrr3) rdrwrbtZdelimiter_priorityZ lowest_depthZtrailing_comma_safererraZ leaf_priorityr`rF)rrdrGrsL      rc#sdstdtjjdtttdfdd }x>jD]4}||EdHx |D]}||EdHqbWqDWrVdS)z4Split standalone comments from the rest of the line.rz*Line does not have any standalone comments)rr)rrPc3sLyj|ddWn4tk rFVtjjd|YnXdS)zEAppend `leaf` to current line or to new line if appending impossible.T)r)rrN)rrr;rrr3)r)rrdrFrGrefs z0standalone_comment_split..append_to_lineN) rrIr;rrr/rrr*)rdrwrerrarF)rrdrGr\s  rcCsP|j}|j}|j}t|tjkoL|dkr6|r6|jtjkpL|dkoL|oL|jtjkS)z9Return True if the given leaf starts an import statement.rwfrom) r(rrOrhr4rr import_namer)rrrrrFrFrGr{s rr)rrBrPcCs(|j}|j}|tjthko&|d|S)zdReturn True if the given leaf is a special comment. Only returns true for type comments for now.z# type:)rrOr4rrra)rrBrrrFrFrGrsr)rrrPcCsV|sL|jd}d|dkrL|dd}t|dkr>|d8}d||_dSd|_dS) zLeave existing extra newlines if not `inside_brackets`. Remove everything else. Note: don't use backslashes for formatting or you'll lose your voting rights. rrrrr]rYNr)rr_rCr)rrZsplZnl_countrFrFrGrGs    rG)rrtrPcCstdtd|jtj}|dk s2td|j|d}|dddd d d }|rh|d d }||d |_dS)zMake all string prefixes lowercase. If remove_u_prefix is given, also removes any u prefix from the string. Note: Mutates its argument. z^([z]*)(.*)$Nzfailed to match string rYFrXBbUurrZ)rrr:rODOTALLr~rr*)rrtrZ orig_prefixr)rFrFrGrHs  rHcCs|jt}|dddkr dS|dddkr:d}d}n|ddkrPd}d}nd}d}|j|}|dkrpdS|jd|}td |}td |}td |}|j|t|t| } d |kr|| rdS| } nZt |d || } | | kr | } ||| ||_t |d || } t |d || } d|krt d| tj } x | D]} dt | krhdSqhW|dkr| dddkr| ddd} | d} | d}|| krdS|| kr|dkrdS||| ||_dS)zPrefer double quotes but only if it doesn't cause more escaping. Adds or removes backslashes as appropriate. Doesn't parse and fix strings nested in f-strings (yet). Note: Mutates its argument. Nr[z"""z'''rrJrKrz(([^\\]|^)(\\\\)*)z([^\\]|^)\\((?:\\\\)*)rz\1\2z\1\\rXz (?:[^{]|^)\{ # start of the string or a non-{ followed by a single { ([^{].*?) # contents of the brackets except if begins with {{ \}(?:[^}]|$) # A } followed by end of the string or a non-} rz\")rOryr:rrcompilercasefoldr sub_twicefindallrrrC)rrOZ orig_quoteZ new_quoteZfirst_quote_posrZunescaped_new_quoteZescaped_new_quoteZescaped_orig_quoterUZnew_bodymatchesmZorig_escape_countZnew_escape_countrFrFrGrIs\           rIcCs|j}|drn|drL|dd|dd}}||}nd|kr|d\}}d}|dr|dd}d}n|d r|dd}t|}|d||}nD|d r|dd }|d }|d krd }t||}nt|}||_dS)zNormalizes numeric (float, int, and complex) literals. All letters used in the representation are normalized to lowercase (except in Python 2 long literals). )Z0o0b0xNrZrVrrrYr^)jlrrxr)rOrrarr_format_float_or_int_stringr)rtextrrsignnumberrBrFrFrGrKs0         rK)rzrPcCs0d|kr |S|d\}}|p dd|p*dS)z"Formats a float string like "1.0".rr)r_)rzrrrFrFrGry#sry)rrRrPcCsx$t|jddD]}|jtkrdSqWd}xRtt|jD]>\}}t|trh|j t j krht ||d|dkrt|tr|j t j krd}|rft|rq<|j t jkrt||drt||ddnt|rt||ddn|j t jkrB|j tjkr d |_d |jd _n4|j tjkr>||ttjd |ttjd Pn$t|trXt|sft||ddt|toz|j|k}q.rz(INTERNAL ERROR: fmt: on/off handling (1)z(INTERNAL ERROR: fmt: on/off handling (2))rT)rrrrOr~rrrrrgenerate_ignored_nodesr(rrrr`r~rar/rE) rrZprevious_consumedrrZ ignored_nodesr9r(rZ hidden_valueZ first_idxZignoredrfrFrFrGrksD      rccsrt|}xd|dk rl|jtjkrlt|r*dSt||jr^x2|jD]}t||jrRdS|Vq>Wq |V|j}q WdS)zvStarting from the container of `leaf`, generate all leaves until `# fmt: on`. Stops at the end of the block. N) rrr4r is_fmt_oncontains_fmt_on_at_columnrrr/)rrrrFrFrGrs    r)rrPcCs>d}x4t|jddD]"}|jtkr(d}q|jtkrd}qW|S)zDetermine whether formatting is switched on within a container. Determined by whether the last `# fmt:` comment is `on` or `off`. F)rT)rrrOFMT_ONr~)rZfmt_onrrFrFrGrs  r)rrrPcCsJxD|jD]:}t|tr"t||ks6t|tr|j|krt|rdSqWdS)zDDetermine if children at a given column have formatting switched on.TF)rrr.first_leaf_columnr/rr)rrrrFrFrGrs     rcCs$x|jD]}t|tr|jSqWdS)z5Returns the column of the first leaf child of a node.N)rrr/r)rrrFrFrGrs   r)rr(rPcCs|jtjks|jtjkot|jdkrdS|j\}}}|jtjkr6|jtjks:dS|S)zqReturns `wrapped` if `node` is of the shape ( wrapped ). Parenthesis can be optional. Returns None otherwiser[N)rrrr4rr)rrdwrappedrerFrFrGunwrap_singleton_parenthesiss  r)r})r(rr}rPcCshttj|rdnd}ttj|r"dnd}|j}d|_|p>d}ttj|||g}||_| ||dS)zWrap `child` in parentheses. This replaces `child` with an atom holding the parentheses and the old child. That requires moving the prefix. If `visible` is False, the leaves will be valueless (and thus invisible). rrrrN) r/r4rrrr`r.rrbra)r(rr}rdrerrfrIrFrFrGr(s rcCsv|jtjkrLt|}|dks(|jtjkr,dSt|jdkoJ|jdjtjkS|jt kott|jdkot|jdjtjkS)zMReturn True if `node` holds a tuple with one element, with or without parens.NFrZrY) rrrbr testlist_gexprrr4rIMPLICIT_TUPLE)rZgexprFrFrGr:s   rcCst|}|dk o|jtjkS)z7Return True iff `node` is of the shape ( test := test )N)rrrZnamedexpr_test)rinnerrFrFrGrJsrcCs||jtjkrdS|jtjkr*|jdkr*dS|jtjkr:dSt|jdkrLdS|j\}}}|jtj krx|jtj krxt |SdS)zAReturn True if `node` holds a `yield` or `yield from` expression.Tr1Fr[) rrr3r4rrOrbrrrrr)rrdexprrerFrFrGrPs   r)rr|rPcCs@|jtks|jsdS|j}|jtjkr6|js0dS|j}|j|kS)aFReturn True if `leaf` is a star or double star in a vararg or kwarg. If `within` includes VARARGS_PARENTS, this applies to function signatures. If `within` includes UNPACKING_PARENTS, it applies to right hand-side extended iterable unpacking (PEP 3132) and additional unpacking generalizations (PEP 448). F)rrr(rr)rr|rrFrFrGres rcCst|jod|jkS)zKReturn True if `leaf` is a multiline string that actually spans many lines.r])rrO)rrFrFrGr"|sr"cCsVt|jdksD|jdjtjksD|jdjtjksD|jdjtjkrHdSt|jdS)z2Return True if `node` is a suite with a stub body.r\rrYr[FrZ)rrrr4rINDENTDEDENTrW)rrFrFrGrUs rUcCsdt|tr|jtjkrdSt|jdkr,dS|jd}|jtjkobt|jdkobtdd|jDS)zCReturn True if `node` is a simple statement containing an ellipsis.FrZrr[css|]}|ttjdkVqdS)rN)r/r4r )rrrFrFrGrszis_stub_body..) rr.rr simple_stmtrrrbr)rrrFrFrGrWs  rWcCs|jtjkrdS|jd}|jd}|jtjkr<|jtjks@dSt}xH|jddD]6}t|t rp| |qVx| D]}| |qzWqVWy| St k rdSXdS)zReturn maximum delimiter priority inside `node`. This is specific to atoms with contents contained in a pair of parentheses. If `node` isn't an atom or there are no enclosing parentheses, returns 0. rrrYN)rrrbrr4rrrrr/rrrr)rr9rrfrrrFrFrGrs      rcCs*|jtjkrd|_n|jtjkr&d|_dS)zMake sure parentheses are visible. They could be invisible as part of some statements (see :func:`normalize_invisible_parens` and :func:`visit_import_from`). rrN)rr4rrOr)rrFrFrGr[s  r[)rdrrPc Cs|jr|jdksdSt}d}y:|jd}|jtjkrHd}|t||j j |d}Wnt t fk rpdSX|t ko|p|jjtjtjhkS)zFShould `line` be immediately split with `delimiter_split()` after RHS?z[{(FrT)r)r(rOrrrr4rrrrrrrrrrbr)rdrrr,r max_priorityrFrFrGr_s  r_)openingr%rrPcCs|jtjkr|jtjkrdS|jd}x&t|D]\}}||kr0Pq0Wtdd}|d7}xd||dD]T}||krvP|j}||krh|jtjkrh|d7}|jrh|jjt j t j hkrh|d7}PqhW|dkS)zNReturn True if content between `opening` and `closing` looks like a one-tuple.FrYz#Opening paren not found in `leaves`rNrZ) rr4rrrr` LookupErrorrr(rrr)rr%rrZ_opening_indexrZcommasrrFrFrGr's*   r'cCsft}xX|D]J}|jtjkrH|jdd}|dkrF|tjq|jtj krld|jkrj|tj q|jtj kr|j r|j jt jt jhkr|tjq|jtjkr|tjq|jt jt jhkr|jr|jdjtjkr|jt jkrtj}ntj}x\|jD]R}|jtkr"|||jt jkrx&|jD]}|jtkr8||q8WqWqW|S)a&Return a set of (relatively) new Python features used in this file. Currently looking for: - f-strings; - underscores in numeric literals; - trailing commas after * or ** in function signatures and calls; - positional only arguments in function signatures and lambdas; NrZ>F"RFFRfrf"rff'F'rr)rr3rr4rrOrr<r{rJr|rr(rrrrZ COLONEQUALrrrr~r}rr)rrwr.Z value_headrchZargchrFrFrGget_features_useds8           rcst|fddtDS)z5Detect the version to target based on the nodes used.csh|]}t|kr|qSrF)r)rr7)rwrFrGrv5sz)detect_target_versions..)rrk)rrF)rwrGr{2s r{)rdrrPc cst}|js|Vd|j}d}d}t}xxt|ddD]f\}}} || 7}||krXP| t|jt|jk} |jtks~| rP|r||krd}nZ|jt kr|dkr|j |dnd} |jr| r| jt j krt |j||j sP|t|q:|jt kr:|dkr|j |dnd} | r6| jtkr6|t|q:|rb|t|||||V|jr| r| jt j krt |j||j sP|jr:|j}|}q:WdS)aGenerate sets of closing bracket IDs that should be omitted in a RHS. Brackets can be omitted if the entire trailer up to and including a preceding closing bracket fits in one line. Yielded sets are cumulative (contain results of previous yields, too). First set is empty, unless the line should explode, in which case bracket pairs until the one that needs to explode are omitted. r\NT)rrrY)rrrenumerate_with_lengthrrOrrrrrr4rr'rrrrrclear) rdrrlengthrr\Zinner_bracketsrfr leaf_lengthZhas_inline_commentrrFrFrGr:sX      rcst}ttttddfdfdd x|jD]}|jtjkrBP|jd}t |t rt |jdkr|jt j kr|jdjt jkrq0Pq0|jtjkr|jd}t |t r|jdkrP|t|jd dO}q0Pq0W|S) z/Return a set of __future__ imports in the file.N)rrPc3sx|D]}t|tr*|jtjkr|jVq|jtjkrp|jd}t|tsRt d|jtjksft d|jVq|jtj kr|jEdHqt dqWdS)NrzInvalid syntax parsing imports) rr/rr4rrOrZimport_as_namerr~Zimport_as_names)rr orig_name)get_imports_from_childrenrFrGrs        z5get_future_imports..get_imports_from_childrenrrZrY __future__r[)rrrrrrrrrrr/rr4rrrrO)rZimportsrZ first_child module_namerF)rrGrzs&"       rz)rrPc Cs<|d}g}|r0|}|}WdQRXtd|S)z9 Return a PathSpec matching gitignore content if present.z .gitignoreNZ gitwildmatch)rrF readlinesr-Z from_lines)rrrbZgfrFrFrGrs  r)pathrrrPc Csy||}Wnftk rJ}z||d|dSd}~XYn4tk r||rv||d|dSYnX|S)zrNormalize `path`. May return `None` if `path` was ignored. `report` is where "path ignored" output goes. zcannot be read because Nz'is a symbolic link that points outside )r  relative_toas_posixrrr is_symlink)rrrrrVrFrFrGrsr)pathsrrrrrrrPc cs|std|x|D]}t|||}|dkr8q||rP||dqd|}|rh|d7}|rv||nd} | r| dr||dq|r||nd} | r| dr||dq|rt| ||||||EdHq| r|r||nd} | r|VqWdS) a Generate all files under `path` whose paths are not excluded by the `exclude_regex` or `force_exclude` regexes, but are included by the `include` regex. Symbolic links pointing outside of the `root` directory are ignored. `report` is where output about exclusions goes. z/INTERNAL ERROR: `root` must be absolute but is Nz#matches the .gitignore file contentrrz(matches the --exclude regular expressionz.matches the --force-exclude regular expressionT) is_absoluter~rZ match_filerrrrrrr) rrrrrrrrrZ exclude_matchrZ include_matchrFrFrGrs@      r)srcsrPcCs|stdSdd|D}dd|D}ttjdd|Dddd }xD|f|jD]4}|d rn|S|d r~|S|d rZ|SqZW|S) a)Return a directory containing .git, .hg, or pyproject.toml. That directory will be a common parent of all files and directories passed in `srcs`. If no directory in the tree contains a marker that would specify it's the project root, the root of the file system is returned. rcSsg|]}tt|qSrF)rcwdr )rrrFrFrGr$sz%find_project_root..cSs(g|] }t|j|r|gngqSrF)rparentsr)rrrFrFrGr)scss|]}t|VqdS)N)r)rrrFrFrGr-sz$find_project_root..cSs|jS)N)r)rrFrFrGr.rz#find_project_root..)rz.gitz.hgzpyproject.toml) rr rr intersectionrrrr)rZ path_srcsZ src_parentsZ common_base directoryrFrFrGrs      rc@seZdZUdZdZeed<dZeed<dZeed<dZ eed<dZ e ed<dZ e ed <dZ e ed <eed d d dZeed dddZeed dddZee dddZedddZd S)rzDProvides a reformatting counter. Can be rendered with `str(report)`.Fr^r_rrr change_count same_count failure_countN)rrrPcCs|tjkrL|js|jrdnd}|js*|jsr)rRrrrFrFrGrZsz Report.failed)rrrPcCs |jrt|d|dddS)Nz ignored: F)r=)rr)rRrrrFrFrGr_szReport.path_ignored)rPcCs|jr dS|jr|jrdSdS)aReturn the exit code that the app should use. This considers the current state of changed files and failures: - if there were any failures, return 123; - if any files were changed and --check is being used, return 1; - otherwise return 0. {rYr)rrr^)rRrFrFrGrcs  zReport.return_codecCs|js |jrd}d}d}n d}d}d}g}|jrh|jdkr>dnd }|tj|jd |d |d d |jr|jdkr|dnd }||jd |d ||jr|jdkrdnd }|tj|jd |d |ddd|dS)zcRender a color report of the current state. Use `click.unstyle` to remove colors. zwould be reformattedzwould be left unchangedzwould fail to reformatrzleft unchangedzfailed to reformatrYrrz filerT)r=r?)r@z, r) r^r_rr3rstylerrr)rRrZ unchangedrrrrFrFrGr;vs( ""zReport.__str__)rBrCrDrEr^rhrr_rrrrrrrrirrrrr=rr;rFrFrFrGr>s        c Csd}tjdkrXx~ttjdddD]0}ytj||d|fdStk rPw"Yq"Xq"Wn6x4dD],}ytj|||dStk rw^Yq^Xq^Wt|S) Nz )r[rorYr\rr[)feature_version)rnrm)r  version_infor astr SyntaxErrorr+r,)rr minor_versionrrFrFrG parse_asts   rcCstt|tjtjtjtjtjfr,tj|jdSt|tjtjtjfrPtj|j dSt|tj tj frptj|j dS|S)z,Map ast nodes deprecated in 3.8 to Constant.)rO) rrStrr+r,BytesConstantrNumr. NameConstantrO)rrFrFrG_fixup_ast_constantssr)rrrPc cst|}d||jjdVxt|jD]}tjtjf}tj dkrV|t jf7}t ||rbPyt ||}Wnt k rw.YnXd|d|dVt |trFx|D]}|dkrt |t jtjtjfrt |t jtjtjfrxN|jD]}t||dEdHqWqt |t jtjtjfrt||dEdHqWq.t |t jtjtjfrtt||dEdHq.t |t jr|d krt |trtd d |}n|}d|d|d |jjVq.Wd|d |jjVdS)z=Simple visitor generating strings to compare ASTs by content.z r)r[rorYrtargetsrZNrOz *\n[ \t]*r]z, # z) # /)rrMrBr_fieldsr+Z TypeIgnorer,r rrrrAttributeErrorrZDeleterZelts_stringify_astASTrrrrrg)rrr)Ztype_ignore_classesrOitem normalizedrFrFrGrs>          $r)rrorPc Csy t|}Wn0tk r<}ztd|Wdd}~XYnXy t|}WnPtk r}z2tdt|j|}td|d|dWdd}~XYnXdt|}dt|}||krtt ||dd}td |ddS) z:Raise AssertionError if `src` and `dst` aren't equivalent.zScannot use --safe with this file; failed to parse source file. AST error message: Nrz-INTERNAL ERROR: Black produced invalid code: ze. Please report a bug on https://github.com/psf/black/issues. This invalid output might be helpful: r]rrozINTERNAL ERROR: Black produced code that is not equivalent to the source. Please report a bug on https://github.com/psf/black/issues. This diff might be helpful: ) rrr~ dump_to_filerr format_tb __traceback__rr_)rroZsrc_astrZdst_astlogZ src_ast_strZ dst_ast_strrFrFrGrqs&   rq)rrorrPcCsLt||d}||krHtt|t||ddt||dd}td|ddS)zDRaise AssertionError if `dst` reformats differently the second time.)rsourcez first passz second passzINTERNAL ERROR: Black produced different code on the second pass of the formatter. Please report a bug on https://github.com/psf/black/issues. This diff might be helpful: N)rrrr_r~)rrorZnewdstrrFrFrGrrs   rr)Z patchable)outputrPc GsXtjdddddd8}x0|D](}|||r|ddkr|dqWWd QRX|jS) z;Dump `output` to a temporary file. Return path to the file.r=Zblk_z.logFutf8)rrrBdeleter>rr]N)tempfileNamedTemporaryFilerJr)rrXrbrFrFrGr!s  r)rPccs dVdS)zWReturn an empty context manager. To be used like `nullcontext` in Python 3.7. NrFrFrFrFrGrM.srM)arka_nameb_namerPc CsFddl}dd|D}dd|D}d|j||||ddS) z9Return a unified diff string between strings `a` and `b`.rNcSsg|] }|dqS)r]rF)rrdrFrFrGr;szdiff..cSsg|] }|dqS)r]rF)rrdrFrFrGr<srrl)ZfromfileZtofiler.)difflibrrZ unified_diff)rrkrrrZa_linesZb_linesrFrFrGr_7s r_zasyncio.Task[Any])r9rPcCs"tdx|D] }|qWdS)zFasyncio signal handler that cancels all `tasks` and reports to stderr.zAborted!N)r>r.)r9r;rFrFrGr.Bs r.)rrPc Cszntjdddkrtj}ntjj}dd||D}|s>dSx|D] }|qDW|tj||ddWdt d}| tj | XdS) zFCancel all pending tasks on `loop`, wait for them, and close the loop.NrZ)r[rncSsg|]}|s|qSrF)r)rr;rFrFrGrQszshutdown..T)rr(zconcurrent.futures) r rr all_tasksZTaskr.r$r6logging getLoggersetLevelCRITICALclose)rrZ to_cancelr;Z cf_loggerrFrFrGr&Is    r&)regex replacementr]rPcCs|||||S)zReplace `regex` with `replacement` twice on `original`. This is used by string normalization to perform replaces on overlapping matches. )r)rrr]rFrFrGrqcsrq)rrPcCsd|krd|}t|}|S)zdCompile a regular expression string in `regex`. If it contains newlines, use verbose mode. r]z(?x))rro)rZcompiledrFrFrGrls r)sequencerPccs4t|d}x"t|D]}||fV|d8}qWdS)z;Like `reversed(enumerate(sequence))` if that were possible.rYN)rr)rrfelementrFrFrGenumerate_reversedws  r)rdrrPccsttttgttttff|r&tnt}xf||j D]X\}}t |j t |j }d|j krbdSx | |D]}|t |j 7}qnW|||fVq8WdS)z|Return an enumeration of leaves with their length. Stops prematurely on multiline strings and standalone comments. r]N)r#rrr/rrr&rr`rrrrOr*)rdroprfrrrrFrFrGrs r)r)rdrrrPcCs*|s t|}t||ko(d|ko(| S)zReturn True if `line` is no longer than `line_length`. Uses the provided `line_str` rendering, if any, otherwise computes a new one. r])rrr)rdrrrFrFrGrs  rcCs|j}t|dkrdS|djtjkr|djtjkrd}d}|d}x|dddD]}|jtkr||jtkrrdS|d7}nL|jtjkr|d7}n6|jtjkr|jtjks|jtksdSn|jtkrdS|dkrV|dkrVdSqVWdS) zReturn False if the line cannot be split *for sure*. This is not an exhaustive search but a cheap heuristic that we can use to avoid some unfortunate formattings (mostly around wrapping unsplittable code in unnecessary parentheses). rZFrrYrrNT) rrrr4rr rrr)rdrZ call_count dot_countrrrFrFrGrZs,         rZ)rdrrWrPc Cs^|j}|jsdS|}||dkr*dS|tkr6dSt|jdksLtd|jd}|jd}|jt kr|jt krt |||drdS|jd}|jd }|j ryt |j|d \}}Wntk rdSX|jtjks|jtjks|jtjkrZ|jrZ|jjtjkrZ|jt krdSt|r,dS|j rF|jtjkrFdSt|||d rZdSdS) aDoes `line` have a shape safe to reformat without optional parens around it? Returns True for only a subset of potentially nice looking formattings but the point is to not return false positives that end up producing lines that are too long. TrYFrZzStranded delimiterr)r9rrr)r)rr)rrrrrrrr~rrr_can_omit_opening_parenrlast_two_exceptrr4rr&rr(rrr"r_can_omit_closing_paren) rdrrWrfrr9secondZ penultimaterrFrFrGrYsF       rY)rdr9rrPcCsd}d|j}d}xht|D]F\}}}|jtkr>|j|kr>d}|r||7}||krTP|jtkrd}qWt|j|dkr|dSdS)z See `can_omit_invisible_parens`.Fr\rTrY)rrrrrrrr)rdr9r remainderr_indexrrrFrFrGrs  r)rdrrrPcCs\d|j}d}xHt|D]<\}}}||7}||jkrF|s@||krTdSq|jtkrd}qWdS)z See `can_omit_invisible_parens`.r\FT)rrrrr)rdrrrZseen_other_bracketsrrrrFrFrGr.s    r)rrrPcCs\d}d}xNt|D]:}|r(||krd}q|r4||fSt||krH|j}q|}qWtddS)zKReturn (penultimate, last) leaves skipping brackets in `omit` and contents.Nz!Last two leaves were also skipped)rrrr)rr stop_afterrrrFrFrGr?s r)rdrrrwrrPc s|s t|}g}x@|||D]2}t|d|kr:td|t||dqW|jdkr|jjrt dd|jjDs| s|d s|d st |djdr|S|}t|||jt|tjhB}t||||d } tfd d| Dr| }|S) Nr]z-Line transformer returned an unchanged result)rrwrcss|] }|jVqdS)N)rO)rZbracketrFrFrGrhsz"run_transformer..r)r)rc3s|]}t|jdVqdS))rN)rr)rln)rrFrGrws)rrrgrHr+rrBrrr#r$rr!rrr4rrrr<rrr) rdrrrwrr5Ztransformed_lineZ line_copyZ features_fopZsecond_opinionrF)rrGrTs0   r)rrPcCstd|dS)Nzcache.z.pickle) CACHE_DIRr)rrFrFrGget_cache_file}src CsXt|}|siS|d0}yt|}Wntjtfk rHiSXWdQRX|S)zRead the cache if it exists and is well formed. If it is not well formed, the call to write_cache later should resolve the issue. r<N)rrrFpicklerUnpicklingErrorr)r cache_fileZfobjrrFrFrGr s r )rrPcCs|}|j|jfS)zKReturn the information used to check if a file is already formatted or not.)rDrEst_size)rrDrFrFrGr sr )rrrPcCsTtt}}x<|D]4}|}||t|kr>||q||qW||fS)zSplit an iterable of paths in `sources` into two sets. The first contains paths of files that modified on disk or are not in the cache. The other contains paths to non-modified files. )rr rr r)rrtodorrrFrFrGr)s  r))rrrrPc Cst|}ybtjddd|dd|D}tjt|jdd}tj||ddWd QRXt |j |Wnt k r~YnXd S) zUpdate the cache file.T)rexist_okcSsi|]}t||qSrF)r r )rrrFrFrGrszwrite_cache..F)dirrr\)protocolN) rrmkdirrrrr(rdumprr*rr)rrrrZ new_cacherXrFrFrGrsrcCs\yddlm}ddlm}Wntk r0dSXx$||fD]}t|dr.)rrrModuleNotFoundErrorhasattrr)rrmodulerFrFrG patch_clicks   rcCstttdS)N)rrrrFrFrFrG patched_mainsr cCsJt|s dSt|jdtjtjtjgr*dSt|jtjtj tjgrFdSdS)NFT) r"rr(r4rrrrrr)rrFrFrGrhsrh)rlrrPc Cs|sdS|}tj}x6|ddD]&}|}|r(t|t|t|}q(W|dg}|tjkrt|d}xRt|ddD]>\}}||d } | s||kr| || q| dqWd |S)NrrYrrZr]) expandtabsrr r>ryr"rrgr`rr3r) rlrrbrrdstrippedZtrimmedZ last_line_idxrcZ stripped_linerFrFrGrjs"    rj__main__)rF)N)N)rF)rF)rFrF)rF)rF)r)F)r)F)rF(rrabcrr collectionsrconcurrent.futuresrrr contextlibrr enumr functoolsr r r rNr6rmultiprocessingrrrpathlibrrrrr,r rrrtypingrrrrrrrrrrrrrrrr r!r"r#r$Ztyping_extensionsr%Zmypy_extensionsr&appdirsr'Z dataclassesr(r)r*rrZ typed_astr+r,Zpathspecr-Zblib2to3.pytreer.r/r0Zblib2to3r1r2Zblib2to3.pgen2r3r4Zblib2to3.pgen2.grammarr5Zblib2to3.pgen2.parser6Z_black_versionr7 __version__rlrZDEFAULT_EXCLUDESZDEFAULT_INCLUDESrr:rrZ FileContentEncodingZNewLinerrrr?rrrr&rZ Transformerfloat TimestampZFileSize CacheInfoCacherrr>Z initializeZpython_symbolsr UserWarningrArrHrIrrJrKrLrNrUZResultrrrXrirkrurvrwZ PY36_VERSIONSr<rprrrrzrsrtr}r{r|r~rrrrrZFileModerhrrrContext ParameterrOptionrcommandroptionZChoiceZversion_optionrZ pass_contextrrrrrZAbstractEventLoopr%rfrrLrOrRr rIrbytesrGrrxrrrrrrrZif_stmtZ while_stmtZfor_stmtZtry_stmtZ except_clauseZ with_stmtZfuncdefrrrrrLESSGREATEREQEQUALNOTEQUAL LESSEQUAL GREATEREQUALrVBAR CIRCUMFLEXAMPER LEFTSHIFTrrrrrrrrrr_rrrrrrrrrbrr0rrrrZlambdefZor_testZand_testZnot_testrrrZxor_exprZand_exprrZ arith_exprZtermr^rrrrrrrrrrrr;r~r}ZtestlistZexprlistrrrrrLBRACEr&rrr+rrrrrr}rrrr2rrrr~rrFrrrrrrrrrrrrrrrrrr2r4rrrrrrrirrrrOrNrdrrrrrGrHrIrKryrSr|rrrrrrrrrrrrrrr"rUrWrr[r_r'rr{rrzrrrrrrrrrrqrrrrMr_r.r&rqrrrrrZrYrrrrrr r r)rrr rhrjrBrFrFrFrGs&     X                  -   6= ?  "$C,#?'"  #   Mu [*g ""` "$m _;6D%\ "=  &$#*'S"),FL$ 86 $ $   1$L2   5&V,*9     ( $('J*".