Ë €}xiÉfLãóè—dZddlZddlZddlZddlZddlZddlZddlZddlZddl m Z m Z ddl m Z ddlmZmZmZmZdZdZej*dd «Zej*d d «Zeed d d«eddd««eeddd«eddd««eeddd«eddd««eeddd «ed!d"d#««eed$d%d&«ed'd(d)««eed*d+d,«ed-d.d/««eed0d1d2«ed3d4d5««eed6d7d8«ed9d:d;««fZed«ed?d@d?d?¬>«edAdBdAdA¬>«edCdDdEdF¬>«edGd dGdG¬>«fZed=dHdIdJg¬K«edLdMdNdOg¬K«ed@dPdQdRg¬K«edDdSdTgdU¢¬K«edVdWdXgdY¢¬K«edZd[d\d]g¬K«ed^d_d`dag¬K«edbdcdddeg¬K«edfdgdhdig¬K«f Zdj„Zd£dk„Zdl„Zd¤dm„Zd¥dn„Z d¥do„Z!dp„Z"d¦dq„Z#d¥dr„Z$d§ds„Z%dt„Z&du„Z'dv„Z(dw„Z)Gdx„dye*«Z+Gdz„d{e,«Z-Gd|„d}e,«Z.Gd~„de,«Z/Gd€„d�e,«Z0e d¨id‚e1“dƒd„“d…d†“d‡dˆ“d‰dŠ“d‹dŒ“d�dŽ“d�d�“d‘d’“d“d”“d•d–“d—d˜“d™dš“d›dœ“d�dž“dŸd “d¡d¢“Žy)©z/The main module of the `humanfriendly` package.éN)Ú is_stringÚ monotonic)Údefine_aliases)Ú concatenateÚformatÚ pluralizeÚtokenize)Ú CombinedUnitÚ InvalidDateÚ InvalidLengthÚ InvalidSizeÚInvalidTimespanÚSizeUnitÚTimerÚ __version__Úcoerce_booleanÚcoerce_patternÚcoerce_secondsÚdisk_size_unitsÚ format_lengthÚ format_numberÚ format_pathÚ format_sizeÚformat_timespanÚlength_size_unitsÚ parse_dateÚ parse_lengthÚ parse_pathÚ parse_sizeÚparse_timespanÚ round_numberÚ time_unitsz10.0rzdivider, symbol, namer zdecimal, binaryièÚKBÚkilobyteiÚKiBÚkibibytei@BÚMBÚmegabyteiÚMiBÚmebibyteiÊš;ÚGBÚgigabytei@ÚGiBÚgibibytelJ)£ÚTBÚterabytelÚTiBÚtebibytel�Iú5ÚPBÚpetabytel ÚPiBÚpebibytelÈNÎZoÚEBÚexabytelÚEiBÚexbibytel@=7M.cÚZBÚ zettabytelÚZiBÚzebibytelB¶3v^!<ÚYBÚ yottabytel ÚYiBÚyobibyteÚnmg•Ö&è .>)ÚprefixÚdividerÚsingularÚpluralÚmmgü©ñÒMbP?Úcmg{®Gáz„?ÚméÚmetreÚmetresÚkmÚ nanosecondÚ nanosecondsÚns)rErFrGÚ abbreviationsg�íµ ÷ư>Ú microsecondÚ microsecondsÚusÚ millisecondÚ millisecondsÚmsÚsecondÚseconds)ÚsÚsecÚsecsé<ÚminuteÚminutes)rJÚminÚminsiÚhourÚhoursÚhi€QÚdayÚdaysÚdi€: ÚweekÚweeksÚwiâßÚyearÚyearsÚycó¬—t|«r?|j«j«}|dvry|dvryd}tt ||««‚t |«S)a8 Coerce any value to a boolean. :param value: Any Python value. If the value is a string: - The strings '1', 'yes', 'true' and 'on' are coerced to :data:`True`. - The strings '0', 'no', 'false' and 'off' are coerced to :data:`False`. - Other strings raise an exception. Other Python values are coerced using :class:`bool`. :returns: A proper boolean value. :raises: :exc:`exceptions.ValueError` when the value is a string but cannot be coerced with certainty. )Ú1ÚyesÚtrueÚonT)Ú0ÚnoÚfalseÚoffÚFz(Failed to coerce string to boolean! (%r))rÚstripÚlowerÚ ValueErrorrÚbool)ÚvalueÚ normalizedÚmsgs ú;/usr/lib/python3.12/site-packages/humanfriendly/__init__.pyrr[sY€ô�ÔØ—[‘[“]×(Ñ(Ó*ˆ Ø Ð3Ñ 3ØØ Ð:Ñ :Øà<ˆCÜœV C¨Ó/Ó0Ð 0ä�E‹{ÐócóÒ—t|«rtj||«}|Stjd«}t|«}t ||«sd}t t ||««‚|S)a¦ Coerce strings to compiled regular expressions. :param value: A string containing a regular expression pattern or a compiled regular expression. :param flags: The flags used to compile the pattern (an integer). :returns: A compiled regular expression. :raises: :exc:`~exceptions.ValueError` when `value` isn't a string and also isn't a compiled regular expression. rxz;Failed to coerce value to compiled regular expression! (%r))rÚreÚcompileÚtypeÚ isinstancer{r)r}ÚflagsÚ empty_patternÚ pattern_typers r€rrwsb€ô�ÔÜ— ‘ ˜5 %Ó(ˆð €Lô Ÿ ™  2›ˆ ܘMÓ*ˆ ܘ% Ô.ØOˆCÜœV C¨Ó/Ó0Ð 0Ø €Lr�có¼—t|tj«r|j«St|tj «sd}t t||««‚|S)aU Coerce a value to the number of seconds. :param value: An :class:`int`, :class:`float` or :class:`datetime.timedelta` object. :returns: An :class:`int` or :class:`float` value. When `value` is a :class:`datetime.timedelta` object the :meth:`~datetime.timedelta.total_seconds()` method is called. z1Failed to coerce value to number of seconds! (%r))r†ÚdatetimeÚ timedeltaÚ total_secondsÚnumbersÚNumberr{r)r}rs r€rr�sM€ô�%œ×+Ñ+Ô,Ø×"Ñ"Ó$Ð$Ü �eœWŸ^™^Ô ,ØAˆÜœ  UÓ+Ó,Ð,Ø €Lr�cóB—tt«D�]}||jjk\rf|rdt t |«|jjz |¬«}t ||jj|jj«cS||jjk\sŒ�|rŒ t t |«|jjz |¬«}t ||jj|jj«cSt |d«S)aŠ Format a byte count as a human readable file size. :param num_bytes: The size to format in bytes (an integer). :param keep_width: :data:`True` if trailing zeros should not be stripped, :data:`False` if they can be stripped. :param binary: :data:`True` to use binary multiples of bytes (base-2), :data:`False` to use decimal multiples of bytes (base-10). :returns: The corresponding human readable file size (a string). This function knows how to format sizes in bytes, kilobytes, megabytes, gigabytes, terabytes and petabytes. Some examples: >>> from humanfriendly import format_size >>> format_size(0) '0 bytes' >>> format_size(1) '1 byte' >>> format_size(5) '5 bytes' > format_size(1000) '1 KB' > format_size(1024, binary=True) '1 KiB' >>> format_size(1000 ** 3 * 4) '4 GB' ©Ú keep_widthÚbyte) ÚreversedrÚbinaryrEr!ÚfloatrÚsymbolÚdecimal)Ú num_bytesr’r•ÚunitÚnumbers r€rr sÒ€ô8œ×)ˆØ ˜Ÿ ™ ×+Ñ+Ò +±Ü!¤%¨ Ó"2°T·[±[×5HÑ5HÑ"HÐU_Ô`ˆFܘV T§[¡[×%7Ñ%7¸¿¹×9KÑ9KÓLÒ LØ ˜$Ÿ,™,×.Ñ.Ó .²vÜ!¤%¨ Ó"2°T·\±\×5IÑ5IÑ"IÐV`ÔaˆFܘV T§\¡\×%8Ñ%8¸$¿,¹,×:MÑ:MÓNÒ Nð *ô �Y Ó 'Ð'r�cóæ—t|«}|�rÌt|dtj«�r®t |«dk(r!t |d«r|dj «nd}t |«dk(s|jd«rt|d«S|�rM|jd«}tD�]2}||jjj «|jjj «fvr't|d|jjz«cS||jjj «|jjj «fvs7|j|jjdj ««sŒöt|d|r|jjn|jjz«cSd}t!t#|||««‚)aú Parse a human readable data size and return the number of bytes. :param size: The human readable file size to parse (a string). :param binary: :data:`True` to use binary multiples of bytes (base-2) for ambiguous unit symbols and names, :data:`False` to use decimal multiples of bytes (base-10). :returns: The corresponding size in bytes (an integer). :raises: :exc:`InvalidSize` when the input can't be parsed. This function knows how to parse sizes in bytes, kilobytes, megabytes, gigabytes, terabytes and petabytes. Some examples: >>> from humanfriendly import parse_size >>> parse_size('42') 42 >>> parse_size('13b') 13 >>> parse_size('5 bytes') 5 >>> parse_size('1 KB') 1000 >>> parse_size('1 kilobyte') 1000 >>> parse_size('1 KiB') 1024 >>> parse_size('1 KB', binary=True) 1024 >>> parse_size('1.5 GB') 1500000000 >>> parse_size('1.5 GB', binary=True) 1610612736 rérKrxÚbr[z4Failed to parse size! (input %r was tokenized as %r))r r†rŽr�ÚlenrrzÚ startswithÚintÚrstriprr•r—ÚnamerEr˜r r)Úsizer•ÚtokensÚnormalized_unitršrs r€rrÆsŒ€ôD�d‹^€FÚ ”*˜V A™Y¬¯©Õ7ä/2°6«{¸aÒ/?ÄIÈfÐUVÉiÔDX˜& ™)Ÿ/™/Ô+Ð^`ˆô ˆv‹;˜!Ò ˜×9Ñ9¸#Ô>Ü�v˜a‘y“>Ð !â ð.×4Ñ4°SÓ9ˆOß'˜�ð# t§{¡{×'9Ñ'9×'?Ñ'?Ó'AÀ4Ç;Á;×CSÑCS×CYÑCYÓC[Ð&\Ñ\ܘv a™y¨4¯;©;×+>Ñ+>Ñ>Ó?Ò?ð$¨¯ © ×(;Ñ(;×(AÑ(AÓ(CÀTÇ\Á\×EVÑEV×E\ÑE\ÓE^Ð'_Ñ_Ø'×2Ñ2°4·<±<×3FÑ3FÀqÑ3I×3OÑ3OÓ3QÕRܘv a™yÁ6¨D¯K©K×,?Ò,?ÈtÏ|É|×OcÑOcÑdÓeÒeð(ð A€CÜ ”f˜S $¨Ó/Ó 0Ð0r�có´—tt«D];}||dk\sŒ tt|«|dz |¬«}t ||d|d«cSt |d«S)aŸ Format a metre count as a human readable length. :param num_metres: The length to format in metres (float / integer). :param keep_width: :data:`True` if trailing zeros should not be stripped, :data:`False` if they can be stripped. :returns: The corresponding human readable length (a string). This function supports ranges from nanometres to kilometres. Some examples: >>> from humanfriendly import format_length >>> format_length(0) '0 metres' >>> format_length(1) '1 metre' >>> format_length(5) '5 metres' >>> format_length(1000) '1 km' >>> format_length(0.004) '4 mm' rEr‘rFrGrL)r”rr!r–r)Ú num_metresr’ršr›s r€rrsb€ô2Ô*Ö+ˆØ ˜˜i™Ó (Ü!¤%¨ Ó"3°d¸9±oÑ"EÐR\Ô]ˆFܘV T¨*Ñ%5°t¸H±~ÓFÒ Fð,ô �Z Ó )Ð)r�cób—t|«}|r‹t|dtj«rnt |«dk(r|dSt |«dk(rMt |d«r?|dj «}tD]#}|j|d«sŒ|d|dzcSd}tt|||««‚)aä Parse a human readable length and return the number of metres. :param length: The human readable length to parse (a string). :returns: The corresponding length in metres (a float). :raises: :exc:`InvalidLength` when the input can't be parsed. Some examples: >>> from humanfriendly import parse_length >>> parse_length('42') 42 >>> parse_length('1 km') 1000 >>> parse_length('5mm') 0.005 >>> parse_length('15.3cm') 0.153 rrKr�rDrEz6Failed to parse length! (input %r was tokenized as %r)) r r†rŽr�rŸrrzrr r r)Úlengthr¥r¦ršrs r€rr&sª€ô(�fÓ €FÙ ”*˜V A™Y¬¯©Ô7ä ˆv‹;˜!Ò Ø˜!‘9Ð ä ˆv‹;˜!Ò ¤ ¨&°©)Ô 4Ø$ Q™iŸo™oÓ/ˆOç)�Ø"×-Ñ-¨d°8©nÕ=Ø! !™9 t¨I¡Ñ6Ò6ð*ð C€CÜ œ˜s F¨FÓ3Ó 4Ð4r�có¤—tt|««jd«\}}}|jd«}dj t |j d«««}g}|r|j|dd«|dd}|rŒdj t dj |«««}|d|jd«} | r|d| zz }|rd|z}|S)aU Format a number as a string including thousands separators. :param number: The number to format (a number like an :class:`int`, :class:`long` or :class:`float`). :param num_decimals: The number of decimals to render (2 by default). If no decimal places are required to represent the number they will be omitted regardless of this argument. :returns: The formatted number (a string). This function is intended to make it easier to recognize the order of size of the number being formatted. Here's an example: >>> from humanfriendly import format_number >>> print(format_number(6000000)) 6,000,000 > print(format_number(6000000000.42)) 6,000,000,000.42 > print(format_number(6000000000.42, num_decimals=0)) 6,000,000,000 Ú.Ú-rxNéÚ,rt) Ústrr–Ú partitionr Újoinr”ÚlstripÚappendr¢) r›Ú num_decimalsÚ integer_partÚ_Ú decimal_partÚ negative_signÚreversed_digitsÚpartsÚformatted_numberÚdecimals_to_adds r€rrKsÛ€ô0%(¬¨f« Ó$6×$@Ñ$@ÀÓ$EÑ!€L�!�\Ø ×+Ñ+¨CÓ0€MØ—g‘gœh |×':Ñ':¸3Ó'?Ó@ÓA€OØ €EÙ Ø � ‰ �_ R aÐ(Ô)Ø)¨!¨"Ð-ˆò ð—w‘wœx¨¯©°«Ó8Ó9ÐØ" = LÐ1×8Ñ8¸Ó=€OÙØ˜C /Ñ1Ñ1ÐÙØÐ!1Ñ1ÐØ Ðr�có‚—dt|«z}|s.tjdd|«}tjdd|«}|S)aô Round a floating point number to two decimal places in a human friendly format. :param count: The number to format. :param keep_width: :data:`True` if trailing zeros should not be stripped, :data:`False` if they can be stripped. :returns: The formatted number as a string. If no decimal places are required to represent the number, they will be omitted. The main purpose of this function is to be used by functions like :func:`format_length()`, :func:`format_size()` and :func:`format_timespan()`. Here are some examples: >>> from humanfriendly import round_number >>> round_number(1) '1' >>> round_number(math.pi) '3.14' >>> round_number(5.001) '5' z%.2fz0+$rxz\.$)r–rƒÚsub)Úcountr’Útexts r€r!r!ss>€ð0 ”E˜%“LÑ €DÙ Ü�v‰v�e˜R Ó&ˆÜ�v‰v�f˜b $Ó'ˆØ €Kr�c ó—t|«}|dkr|stt|«d«Sg}tjt |««}t tt|rdndd««}|D]s}tjt |d««}||z }||z}||dk7r t|«}n t|«}|dvsŒR|jt||d |d ««Œut|«d k(r|dS|s|d|}t|«S) a½ Format a timespan in seconds as a human readable string. :param num_seconds: Any value accepted by :func:`coerce_seconds()`. :param detailed: If :data:`True` milliseconds are represented separately instead of being represented as fractional seconds (defaults to :data:`False`). :param max_units: The maximum number of units to show in the formatted time span (an integer, defaults to three). :returns: The formatted timespan as a string. :raise: See :func:`coerce_seconds()`. Some examples: >>> from humanfriendly import format_timespan >>> format_timespan(0) '0 seconds' >>> format_timespan(1) '1 second' >>> import math >>> format_timespan(math.pi) '3.14 seconds' >>> hour = 60 * 60 >>> day = hour * 24 >>> week = day * 7 >>> format_timespan(week * 52 + day * 2 + hour * 3) '1 year, 2 days and 3 hours' r^rYrr®NrEéÿÿÿÿ)rrtrFrGrK) rrr!r˜ÚDecimalr°Úlistr”r"r¡r´rŸr)Ú num_secondsÚdetailedÚ max_unitsÚresultÚrelevant_unitsršrErÀs r€rr’s€ô:! Ó-€KØ�Rҡ䜠kÓ2°HÓ=Ð=ðˆÜ—o‘o¤c¨+Ó&6Ó7ˆ Üœh¤z±x±!ÀQÐ2GÐ'HÓIÓJˆÛ"ˆDä—o‘o¤c¨$¨y©/Ó&:Ó;ˆGØ 'Ñ)ˆEØ ˜7Ñ "ˆKà�~ bÑ)Ò)ä˜E› ‘ô% UÓ+�à˜HÒ$Ø— ‘ œi¨¨t°JÑ/?ÀÀhÁÓPÕQð#ô ˆv‹;˜!Ò à˜!‘9Ð áà   Ð+�ä˜vÓ&Ð &r�cóŒ—t|«}|r t|dtj«rƒt |«dk(rt |d«St |«dk(rYt |d«rK|dj«}tD]/}||dk(s||dk(s||dvsŒt |d«|dzcSd}tt|||««‚) aµ Parse a "human friendly" timespan into the number of seconds. :param value: A string like ``5h`` (5 hours), ``10m`` (10 minutes) or ``42s`` (42 seconds). :returns: The number of seconds as a floating point number. :raises: :exc:`InvalidTimespan` when the input can't be parsed. Note that the :func:`parse_timespan()` function is not meant to be the "mirror image" of the :func:`format_timespan()` function. Instead it's meant to allow humans to easily and succinctly specify a timespan with a minimal amount of typing. It's very useful to accept easy to write time spans as e.g. command line arguments to programs. The time units (and abbreviations) supported by this function are: - ms, millisecond, milliseconds - s, sec, secs, second, seconds - m, min, mins, minute, minutes - h, hour, hours - d, day, days - w, week, weeks - y, year, years Some examples: >>> from humanfriendly import parse_timespan >>> parse_timespan('42') 42.0 >>> parse_timespan('42s') 42.0 >>> parse_timespan('1m') 60.0 >>> parse_timespan('1h') 3600.0 >>> parse_timespan('1d') 86400.0 rrKr�rFrGrRrEz8Failed to parse timespan! (input %r was tokenized as %r)) r r†rŽr�rŸr–rrzr"rr)Útimespanr¥r¦ršrs r€r r ÒsÉ€ôN�hÓ €FÙ ”*˜V A™Y¬¯©Ô7ä ˆv‹;˜!Ò Ü˜ ™Ó#Ð #ä ˆv‹;˜!Ò ¤ ¨&°©)Ô 4Ø$ Q™iŸo™oÓ/ˆOß"�Ø# t¨JÑ'7Ò7Ø'¨4°©>Ò9Ø'¨4°Ñ+@Ò@Ü  ¨¡Ó+¨d°9©oÑ=Ò=ð #ð E€CÜ œ&  h°Ó7Ó 8Ð8r�có(— |j«D�cgc]}|j«‘Œ}}t|«dk\rttt t |djd«««ddgz}tt t |djd«««gd¢z}t |dd|ddz«Stt t |jd«««ddgzdd\}}}|||dddfScc}w#t$rd}tt||««‚wxYw) a3 Parse a date/time string into a tuple of integers. :param datestring: The date/time string to parse. :returns: A tuple with the numbers ``(year, month, day, hour, minute, second)`` (all numbers are integers). :raises: :exc:`InvalidDate` when the date cannot be parsed. Supported date/time formats: - ``YYYY-MM-DD`` - ``YYYY-MM-DD HH:MM:SS`` .. note:: If you want to parse date/time strings with a fixed, known format and :func:`parse_date()` isn't useful to you, consider :func:`time.strptime()` or :meth:`datetime.datetime.strptime()`, both of which are included in the Python standard library. Alternatively for more complex tasks consider using the date/time parsing module in the dateutil_ package. Examples: >>> from humanfriendly import parse_date >>> parse_date('2013-06-17') (2013, 6, 17, 0, 0, 0) >>> parse_date('2013-06-17 02:47:42') (2013, 6, 17, 2, 47, 42) Here's how you convert the result to a number (`Unix time`_): >>> from humanfriendly import parse_date >>> from time import mktime >>> mktime(parse_date('2013-06-17 02:47:42') + (-1, -1, -1)) 1371430062.0 And here's how you convert it to a :class:`datetime.datetime` object: >>> from humanfriendly import parse_date >>> from datetime import datetime >>> datetime(*parse_date('2013-06-17 02:47:42')) datetime.datetime(2013, 6, 17, 2, 47, 42) Here's an example that combines :func:`format_timespan()` and :func:`parse_date()` to calculate a human friendly timespan since a given date: >>> from humanfriendly import format_timespan, parse_date >>> from time import mktime, time >>> unix_time = mktime(parse_date('2013-06-17 02:47:42') + (-1, -1, -1)) >>> seconds_since_then = time() - unix_time >>> print(format_timespan(seconds_since_then)) 1 year, 43 weeks and 1 day .. _dateutil: https://dateutil.readthedocs.io/en/latest/parser.html .. _Unix time: http://en.wikipedia.org/wiki/Unix_time r�rr­rKÚ:)rrrr®zJInvalid date! (expected 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS' but got: %r)) ÚsplitryrŸrÅÚmapr¡ÚtupleÚ Exceptionr r) Ú datestringÚtr¥Ú date_partsÚ time_partsrlÚmonthrfrs r€rr s€ðr 3Ø%/×%5Ñ%5Ô%7Ó8Ñ%7 �!—'‘'•)Ð%7ˆÐ8Ü ˆv‹;˜!Ò Üœc¤# v¨a¡y§¡°sÓ';Ó<Ó=ÀÀAÀÑFˆJÜœc¤# v¨a¡y§¡°sÓ';Ó<Ó= ÑIˆJܘ A a˜¨:°a¸¨?Ñ:Ó;Ð ;ä $¤S¬¨j×.>Ñ.>¸sÓ.CÓ%DÓ EÈÈAÈÑ NÐPQÐRSÐTÑ ˆD�%˜Ø˜%  a¨¨AÐ.Ð .ùò9øô ò3ØZˆÜœ&  jÓ1Ó2Ð2ð3ús"‚C0”C+«BC0Â/;C0Ã+C0Ã0!Dcób—tjj|«}tjj d«}|rntjj|«}|j |«r>tjj dtjj||««}|S)aÐ Shorten a pathname to make it more human friendly. :param pathname: An absolute pathname (a string). :returns: The pathname with the user's home directory abbreviated. Given an absolute pathname, this function abbreviates the user's home directory to ``~/`` in order to shorten the pathname without losing information. It is not an error if the pathname is not relative to the current user's home directory. Here's an example of its usage: >>> from os import environ >>> from os.path import join >>> vimrc = join(environ['HOME'], '.vimrc') >>> vimrc '/home/peter/.vimrc' >>> from humanfriendly import format_path >>> format_path(vimrc) '~/.vimrc' ÚHOMEÚ~)ÚosÚpathÚabspathÚenvironÚgetr r²Úrelpath)ÚpathnameÚhomes r€rrRss€ô.�w‰w�‰˜xÓ(€HÜ �:‰:�>‰>˜&Ó !€DÙ Ü�w‰w�‰˜tÓ$ˆØ × Ñ ˜tÔ $Ü—w‘w—|‘| C¬¯©¯©¸À4Ó)HÓIˆHØ €Or�có´—tjjtjjtjj |«««S)a~ Convert a human friendly pathname to an absolute pathname. Expands leading tildes using :func:`os.path.expanduser()` and environment variables using :func:`os.path.expandvars()` and makes the resulting pathname absolute using :func:`os.path.abspath()`. :param pathname: A human friendly pathname (a string). :returns: An absolute pathname (a string). )rÛrÜrÝÚ expanduserÚ expandvars)rás r€rrrs5€ô �7‰7�?‰?œ2Ÿ7™7×-Ñ-¬b¯g©g×.@Ñ.@ÀÓ.JÓKÓ LÐLr�cóR—eZdZdZd d„Zd„Zd d„Zd„Zed„«Z ed„«Z d „Z y) rzD Easy to use timer to keep track of long during operations. Ncó¬—|rd|_d|_d|_d|_y|rd|_d|_||_yd|_d|_t«|_y)a� Remember the time when the :class:`Timer` was created. :param start_time: The start time (a float, defaults to the current time). :param resumable: Create a resumable timer (defaults to :data:`False`). When `start_time` is given :class:`Timer` uses :func:`time.time()` as a clock source, otherwise it uses :func:`humanfriendly.compat.monotonic()`. TçFN)rÚ resumableÚ start_timeÚ total_time)Úselfrêrés r€Ú__init__zTimer.__init__†sR€ñ Ø!ˆDŒNØ!ˆDŒNØ!ˆDŒOØ!ˆD�OÙ Ø"ˆDŒNØ"ˆDŒNØ(ˆD�Oà!ˆDŒNØ"ˆDŒNÜ'›kˆD�Or�cóR—|js td«‚t«|_|S)zµ Start or resume counting elapsed time. :returns: The :class:`Timer` object. :raises: :exc:`~exceptions.ValueError` when the timer isn't resumable. úTimer is not resumable!)rér{rrê©rìs r€Ú __enter__zTimer.__enter__žs%€ð�~Š~ÜÐ6Ó7Ð 7Ü#›+ˆŒØˆ r�có®—|js td«‚|jr2|xjt «|jz z c_d|_yy)z} Stop counting elapsed time. :raises: :exc:`~exceptions.ValueError` when the timer isn't resumable. rïrèN)rér{rêrër)rìÚexc_typeÚ exc_valueÚ tracebacks r€Ú__exit__zTimer.__exit__ªsC€ð �~Š~ÜÐ6Ó7Ð 7Ø �?Š?Ø �OŠOœy›{¨T¯_©_Ñ<Ñ <�OØ!ˆD�Oð r�có\—tjtd||jz ««y)a^ Easy to use rate limiting of repeating actions. :param seconds: The number of seconds to sleep (an integer or floating point number). This method sleeps for the given number of seconds minus the :attr:`elapsed_time`. If the resulting duration is negative :func:`time.sleep()` will still be called, but the argument given to it will be the number 0 (negative numbers cause :func:`time.sleep()` to raise an exception). The use case for this is to initialize a :class:`Timer` inside the body of a :keyword:`for` or :keyword:`while` loop and call :func:`Timer.sleep()` at the end of the loop body to rate limit whatever it is that is being done inside the loop body. For posterity: Although the implementation of :func:`sleep()` only requires a single line of code I've added it to :mod:`humanfriendly` anyway because now that I've thought about how to tackle this once I never want to have to think about it again :-P (unless I find ways to improve this). rN)ÚtimeÚsleepÚmaxÚ elapsed_time)rìrZs r€rùz Timer.sleep¶s"€ô0 � ‰ ”3�q˜' D×$5Ñ$5Ñ5Ó6Õ7r�cóЗd}|jr||jz }|jr<|jr t«nt j«}|||jz z }|S)z; Get the number of seconds counted so far. r)rérërêrrø)rìrûÚ current_times r€rûzTimer.elapsed_timeÐsS€ð ˆ Ø �>Š>Ø ˜DŸO™OÑ +ˆLØ �?Š?Ø*.¯.ª.œ9œ;¼d¿i¹i»kˆLØ ˜L¨4¯?©?Ñ:Ñ :ˆLØÐr�có>—tt|j««S)z6Human readable timespan rounded to seconds (a string).)rÚroundrûrðs r€Úroundedz Timer.roundedÝs€ôœu T×%6Ñ%6Ó7Ó8Ð8r�có,—t|j«S)z;Show the elapsed time since the :class:`Timer` was created.)rrûrðs r€Ú__str__z Timer.__str__âs€ä˜t×0Ñ0Ó1Ð1r�)NF)NNN) Ú__name__Ú __module__Ú __qualname__Ú__doc__rírñrörùÚpropertyrûrr©r�r€rr€sH„ñó*ò0 ó "ò8ð4ñ óð ðñ9óð9ó2r�rcó—eZdZdZy)r a¢ Raised when a string cannot be parsed into a date. For example: >>> from humanfriendly import parse_date >>> parse_date('2013-06-XY') Traceback (most recent call last): File "humanfriendly.py", line 206, in parse_date raise InvalidDate(format(msg, datestring)) humanfriendly.InvalidDate: Invalid date! (expected 'YYYY-MM-DD' or 'YYYY-MM-DD HH:MM:SS' but got: '2013-06-XY') N©rrrrrr�r€r r çó„ò r�r có—eZdZdZy)r a” Raised when a string cannot be parsed into a file size. For example: >>> from humanfriendly import parse_size >>> parse_size('5 Z') Traceback (most recent call last): File "humanfriendly/__init__.py", line 267, in parse_size raise InvalidSize(format(msg, size, tokens)) humanfriendly.InvalidSize: Failed to parse size! (input '5 Z' was tokenized as [5, 'Z']) Nr rr�r€r r ÷r r�r có—eZdZdZy)r aŸ Raised when a string cannot be parsed into a length. For example: >>> from humanfriendly import parse_length >>> parse_length('5 Z') Traceback (most recent call last): File "humanfriendly/__init__.py", line 267, in parse_length raise InvalidLength(format(msg, length, tokens)) humanfriendly.InvalidLength: Failed to parse length! (input '5 Z' was tokenized as [5, 'Z']) Nr rr�r€r r r r�r có—eZdZdZy)raµ Raised when a string cannot be parsed into a timespan. For example: >>> from humanfriendly import parse_timespan >>> parse_timespan('1 age') Traceback (most recent call last): File "humanfriendly/__init__.py", line 419, in parse_timespan raise InvalidTimespan(format(msg, timespan, tokens)) humanfriendly.InvalidTimespan: Failed to parse timespan! (input '1 age' was tokenized as [1, 'age']) Nr rr�r€rrr r�rÚ module_nameÚ format_tablez(humanfriendly.tables.format_pretty_tableÚcompactzhumanfriendly.text.compactrzhumanfriendly.text.concatenateÚdedentzhumanfriendly.text.dedentrzhumanfriendly.text.formatÚ is_empty_linez humanfriendly.text.is_empty_linerzhumanfriendly.text.pluralizer zhumanfriendly.text.tokenizeÚtrim_empty_linesz#humanfriendly.text.trim_empty_linesÚprompt_for_choicez'humanfriendly.prompts.prompt_for_choiceÚAutomaticSpinnerz0humanfriendly.terminal.spinners.AutomaticSpinnerÚSpinnerz'humanfriendly.terminal.spinners.SpinnerÚerase_line_codez&humanfriendly.terminal.ANSI_ERASE_LINEÚhide_cursor_codez'humanfriendly.terminal.ANSI_SHOW_CURSORÚminimum_spinner_intervalz0humanfriendly.terminal.spinners.MINIMUM_INTERVALÚshow_cursor_codez'humanfriendly.terminal.ANSI_HIDE_CURSOR)r)FF)F)r�)Fr®r)2rÚ collectionsr‹r˜rŽrÛÚos.pathrƒrøÚhumanfriendly.compatrrÚhumanfriendly.deprecationrÚhumanfriendly.textrrrr Ú__all__rÚ namedtuplerr rÚdictrr"rrrrrrrrr!rr rrrÚobjectrrÒr r r rrrr�r€Úr%s•ðñ6óÛÛÛÛ ÛÛ Û ÷6Ý4ßGÓGð €ð:€ ð "ˆ;× !Ñ ! *Ð.EÓ F€Ø%ˆ{×%Ñ% nÐ6GÓH€ ñ‘˜' 4¨Ó4±h¸wÈÈzÓ6ZÓ[Ù‘˜' 4¨Ó4±h¸wÈÈzÓ6ZÓ[Ù‘˜' 4¨Ó4±h¸wÈÈzÓ6ZÓ[Ù‘˜' 4¨Ó4±h¸wÈÈzÓ6ZÓ[Ù‘˜' 4¨Ó4±h¸wÈÈzÓ6ZÓ[Ù‘˜' 4¨Ó3±X¸gÀuÈjÓ5YÓZÙ‘˜' 4¨Ó5±xÀÈÐPZÓ7[Ó\Ù‘˜' 4¨Ó5±xÀÈÐPZÓ7[Ó\ð €ñ ¨u¸tÈDÔQÙ ¨u¸tÈDÔQÙ ¨u¸tÈDÔQÙ ¨a¸'È(ÔSÙ ¨t¸dÈ4ÔPð RÐñ˜4¨,¸}Ð]aÐ\bÔcÙ˜4¨-ÀÐ_cÐ^dÔeÙ˜4¨-ÀÐ_cÐ^dÔeÙ˜1 x¸ ÒQeÔfÙ˜2¨¸ÒRfÔgÙ˜7¨V¸GÐTWÐSXÔYÙ˜<°%ÀÐWZÐV[Ô\ÙÐ+°fÀWÐ]`Ð\aÔbÙÐ0¸6È'ÐbeÐafÔgði€ òó8ò,ó&#(óL=1ó@*ò@"5óJ%óPó>='ò@69òrD3òNò@ Môd2ˆFôd2ôN �)ô ô �)ô ô �Iô ô �iô ñ"òÙðñ <ð ñ )ðñ1ðñ 'ðñ 'ðñ5ðñ-ðñ +ð!ñ";ð#ñ(@ð)ñ0Hð1ñ2 6ð3ñ4=ð5ñ6?ð7ñ8Pð9ñ:?ò;r�