PK!flibaaron/__init__.pyfrom .libaaron import ( reify, cached, w, DotDict, flatten, deepupdate, quietinterrupt, PBytes, mkdummy, unpacktsv, printtsv, ) try: from .libaaron import lxml_little_iter except ImportError: pass PK!,,o00libaaron/aio.pyimport sys from asyncio import * proc = create_subprocess_exec major, minor, *_ = sys.version_info if (major, minor) < (3, 7): def run(coro): loop = get_event_loop() return loop.run_until_complete(coro) def create_task(coro): return get_event_loop().create_task(coro) PK!]p  libaaron/libaaron.pyimport functools import signal import string import sys from collections import abc class reify: """ Use as a class method decorator. It operates almost exactly like the Python ``@property`` decorator, but it puts the result of the method it decorates into the instance dict after the first call, effectively replacing the function it decorates with an instance variable. It is, in Python parlance, a non-data descriptor. Stolen from pyramid. http://docs.pylonsproject.org/projects/pyramid/en/latest/api/decorator.html#pyramid.decorator.reify """ def __init__(self, wrapped): self.wrapped = wrapped functools.update_wrapper(self, wrapped) def __get__(self, inst, objtype=None): if inst is None: return self val = self.wrapped(inst) setattr(inst, self.wrapped.__name__, val) return val def cached(method) -> property: """alternative to reify and property decorators. caches the value when it's generated. It cashes it as instance._name_of_the_property. """ name = "_" + method.__name__ @property def wrapper(self): try: return getattr(self, name) except AttributeError: val = method(self) setattr(self, name, val) return val return wrapper def w(iterable): """yields from an iterable with its context manager.""" with iterable: yield from iterable class DotDict(dict): "dict for people who are too lazy to type brackets and quotation marks" __slots__ = () __getattr__ = dict.__getitem__ __setattr__ = dict.__setitem__ __delattr__ = dict.__delitem__ def __dir__(self): return list(self) def flatten(iterable, map2iter=None): """recursively flatten nested objects""" if map2iter and isinstance(iterable): iterable = map2iter(iterable) for item in iterable: if isinstance(item, str) or not isinstance(item, abc.Iterable): yield item else: yield from flatten(item, map2iter) def deepupdate(mapping: abc.MutableMapping, other: abc.Mapping): """update one dictionary from another recursively. Only individual values will be overwritten--not entire branches of nested dictionaries. """ def inner(other, previouskeys): """previouskeys is a tuple that stores all the names of keys we've recursed into so far so it can they can be looked up recursively on the pimary mapping when a value needs updateing. """ for key, value in other.items(): if isinstance(value, abc.Mapping): inner(value, (*previouskeys, key)) else: node = mapping for previouskey in previouskeys: node = node.setdefault(previouskey, {}) node[key] = value inner(other, ()) def quietinterrupt(msg=None): """add a handler for SIGINT that optionally prints a given message. For stopping scripts without having to see the stacktrace. """ def handler(*args): if msg: print(msg, file=sys.stderr) sys.exit(1) signal.signal(signal.SIGINT, handler) class PBytes(int): """child class of int to facilitate conversion between memory representations in bytes and human readable formats. Mostly for pretty printing, but it can also parse approximate numbers of bytes from a human_readable string. """ __slots__ = () units = "bkmgtpezy" key = {v: i for i, v in enumerate(units)} digits = set(string.digits) digits.update(". ") def __str__(self): n, u = self.human_readable() if u == "B": return str(n) + " bytes" return "%.1f %siB" % self.human_readable() def __repr__(self): return "%s(%r)" % (self.__class__.__name__, int(self)) def human_readable(self, decimal=False): divisor = 1000 if decimal else 1024 number = int(self) for unit in self.units: if number < divisor: break number /= divisor return number, unit.upper() @classmethod def from_str(cls, human_readable_str, decimal=False, bits=False): divisor = 1000 if decimal else 1024 num = [] for c in human_readable_str: if c not in cls.digits: break num.append(c) num = "".join(num) try: num = int(num) except ValueError: num = float(num) if bits: num /= 8 return cls(round(num * divisor ** cls.key[c.lower()])) def unpacktsv(file, sep="\t"): return (line.rstrip().split(sep) for line in file) def printtsv(table, sep="\t", file=sys.stdout): for record in table: print(*record, sep=sep, file=file) def mkdummy(name, **attrs): """Make a placeholder object that uses its own name for its repr""" return type(name, (), dict(__repr__=(lambda self: "<%s>" % name), **attrs))() class reportiter: __slots__ = "iter", "report", "count", "report" def __init__( self, iterable, frequency=100, report=lambda i: print(i, file=sys.stderr) ): self.iter = iter(iterable) self.report = report self.frequency = frequency self.count = 0 def __iter__(self): return self def __next__(self): self.count += 1 if not self.count % self.frequency: self.report(self.count) try: return next(self.iter) except StopIteration: self.report(self.count) raise try: from lxml import etree except ImportError: pass else: def lxml_little_iter(*args, **kwargs): """Use lxml.etree.iterparse to iterate over elements, but clear the tree as we iterate. """ context = etree.iterparse(*args, **kwargs) for event, element in context: yield event, element element.clear() while element.getprevious() is not None: del element.getparent()[0] PK!sEpU++ libaaron-1.1.9.dist-info/LICENSEBSD 2-Clause License Copyright (c) 2018, Aaron Christianson All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. PK!HnHTUlibaaron-1.1.9.dist-info/WHEEL A н#Z;/"d&F[xzw@Zpy3Fv]\fi4WZ^EgM_-]#0(q7PK!Hg !libaaron-1.1.9.dist-info/METADATAWn8}W- ۀ4qM6% lzGMKF"$G=Cʲt$q83gfҋLx1[Z}B-Fn09LU]63QZ_bӵJ\FX~#2>Wz_Ja%ryLRSh U*뫋M!j'٫+orWB;lKY Ux~ES++sQDwb?K2wN4K}Ùޖ֬(K )GK6]w?O}y?_de6_LӅtUah/|m*[p;3։h!YpυΚrki)@$i4f3 +ժY,8tOr\L DΛB5%)GA֪~ 3:90W4L<98od+$Rlg8sSI|IVۚefhx S1_֞+ϫڻ 8] ְAW $B@!^҆+dTŘ `Y4AU!RBlsD^ l.N?,d ]1V$8h}Q@r4bm[`aPf/K?p]0NHӁ5Z* B1QG\xpV?5PHh]._s S`^+ &v!_fO|tI 4XJF|HTdخ cT#xdmӄT&m5h7U:9Sڅ!/#rEB TCcP[1 ;Cbg15Ioq3|èoU*HIeGOauI2Lk f*m6Ǯh TNCyجܘmr~ +X:""UPY֏;}Rrt,T}st\TG}~ݠg7߇>.3('70YD?p>WY驽r$Aϲ $FsBc1 D,E@pt4h mOo 9؆Ggg'GSAnŢ@BZ)`zw$~aL#PxֲcQ 0MtKhct~Wm3 XZ M:J:[R P8e60]RWOP&!Knq!W"M V?Lp mU\Q Yr(`%nOLiQmuCD:՚)P 5:D]Sé(WmՔτVcS`uE{B8vnoCS執͞+w;ܔw!~*ϣσ.[Hô;裎(xPǒc'"\*I;QBk{qI>w x µؿPK!H.Q libaaron-1.1.9.dist-info/RECORDu̻v0нߒ8t *iKND !үDNjQN)%o)Th. ;k'suv_?󔯔*lS^X+Ŏ\Rgox1.5 4w۫Dvku3;Y}@-#HU|Eqf@)͈e^ϹMQFaan-zsiM/. #IAi"M#oZLL1{sQ-MIq`ȻZ