{ "info": { "author": "Ken Kundert", "author_email": "shlib@nurdletech.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "Natural Language :: English", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Utilities" ], "description": "ShLib - Shell Library\n=====================\n\n.. image:: https://img.shields.io/travis/KenKundert/shlib/master.svg\n :target: https://travis-ci.org/KenKundert/shlib\n\n.. image:: https://img.shields.io/coveralls/KenKundert/shlib.svg\n :target: https://coveralls.io/r/KenKundert/shlib\n\n.. image:: https://img.shields.io/pypi/v/shlib.svg\n :target: https://pypi.python.org/pypi/shlib\n\n.. image:: https://img.shields.io/pypi/pyversions/shlib.svg\n :target: https://pypi.python.org/pypi/shlib/\n\n:Author: Ken Kundert\n:Version: 1.1.0\n:Released: 2019-03-21\n\nA light-weight package with few dependencies that allows users to do \nshell-script like things relatively easily in Python. Is a natural complement to \nthe pathlib library. Pathlib does pretty much what you would like to do with \na single path; shlib does similar things with many paths at once. For example, \nwith pathlib you can remove (unlink) a single file, but with shlib you can \nremove many files at once. Furthermore, most of the features of pathlib are \nimplemented as pathlib methods, so you must convert your strings to paths before \nyou can use them. ShLib is equally comfortable with strings as with paths.\n\nWriting programs that substantially interact with the file system can be \nsurprisingly painful in Python because the code that is used to do so is spread \nover many packages and those packages are not very compatible with each other \nnor do they follow the conventions of the corresponding shell commands.\n\nThis package, shlib, attempts to address those issues by providing one package \nthat combines the commonly used utilities for interacting with the filesystem \nthat follows the conventions used by the corresponding shell commands. \n\nIt consists of replacements for some very common Unix utilities that interact \nwith the filesystem, such as cp, mv, rm, ln, mkdir, and cd. These tend to be \nless fussy than their command line counter parts. For example, rm deletes both \nfiles and directories without distinction and will not complain if the file or \ndirectory does not exist. Similarly mkdir will create any child directories \nneeded and will not complain if the directory already exists.\n\nFinally, it provides several ways to run external programs.\n\nEach feature is designed to allow you to express your desires simply and \nefficiently without worrying too much about exceptions.\n\nMost of the functions in this package take paths to files or directories. Those \npaths may be specified either as strings or pathlib paths. Many of the functions \naccept multiple paths, and those can be specified either as an array or as \nindividual arguments. Several of the functions return either a path or \na collection of paths. These paths are returned as pathlib paths.\n\n\nInstallation\n------------\n\nUse 'pip3 install shlib' to install. Requires Python2.7 or Python3.3 or better.\n\n\nSystem Utility Functions\n------------------------\n\nCopy (cp)\n~~~~~~~~~\n\nCopy files or directories::\n\n cp(src, ..., dest)\n\nor::\n\n cp([src, ...], dest)\n\nCopy all source items, whether they be files or directories to dest. If there is \nmore than one src item, then dest must be a directory and the copies will be \nplaced in that directory. The src arguments may be strings, pathlib paths, or \ncollections of strings and paths. The dest must be a string or path.\n\nExample:\n\n.. code-block:: python\n\n >>> from shlib import *\n >>> testdir = 'testdir'\n >>> rm(testdir)\n >>> mkdir(testdir)\n >>> files = cartesian_product(testdir, ['f1', 'f2'])\n >>> touch(files)\n >>> dirs = cartesian_product(testdir, ['d1', 'd2'])\n >>> mkdir(dirs)\n >>> print(sorted(str(e) for e in ls(testdir)))\n ['testdir/d1', 'testdir/d2', 'testdir/f1', 'testdir/f2']\n\n >>> cp('testdir/f1', 'testdir/f4')\n >>> print(sorted(str(f) for f in lsf(testdir)))\n ['testdir/f1', 'testdir/f2', 'testdir/f4']\n\n >>> dest1 = to_path(testdir, 'dest1')\n >>> mkdir(dest1)\n >>> cp(files, dest1)\n >>> print(sorted(str(f) for f in lsf(dest1)))\n ['testdir/dest1/f1', 'testdir/dest1/f2']\n\n >>> cp(dirs, dest1)\n >>> print(sorted(str(d) for d in lsd(dest1)))\n ['testdir/dest1/d1', 'testdir/dest1/d2']\n\n >>> f1, f2 = tuple(files)\n >>> dest2 = to_path(testdir, 'dest2')\n >>> mkdir(dest2)\n >>> cp(f1, f2, dest2)\n >>> print(sorted(str(f) for f in lsf(dest2)))\n ['testdir/dest2/f1', 'testdir/dest2/f2']\n\n >>> dest3 = to_path(testdir, 'dest3')\n >>> mkdir(dest3)\n >>> cp([f1, f2], dest3)\n >>> print(sorted(str(f) for f in lsf(dest3)))\n ['testdir/dest3/f1', 'testdir/dest3/f2']\n\n\nMove (mv)\n~~~~~~~~~\n\nMove files or directories::\n\n mv(src, ..., dest)\n\nMove all source items, whether they be files or directories to dest. If there is \nmore than one src item, then dest must be a directory and everything will be \nplaced in that directory. The src arguments may be strings or lists of strings. \nThe dest must be a string.\n\n.. code-block:: python\n\n >>> from shlib import *\n >>> testdir = 'testdir'\n >>> rm(testdir)\n >>> mkdir(testdir)\n >>> files = cartesian_product(testdir, ['f1', 'f2'])\n >>> touch(files)\n >>> dirs = cartesian_product(testdir, ['d1', 'd2'])\n >>> mkdir(dirs)\n >>> print(sorted(str(e) for e in ls(testdir)))\n ['testdir/d1', 'testdir/d2', 'testdir/f1', 'testdir/f2']\n\n >>> dest = to_path(testdir, 'dest')\n >>> mkdir(dest)\n >>> mv(files, dest) # move a list of files\n >>> print(sorted(str(f) for f in lsf(dest)))\n ['testdir/dest/f1', 'testdir/dest/f2']\n\n >>> mv(dirs, dest) # move a list of directories\n >>> print(sorted(str(d) for d in lsd(dest)))\n ['testdir/dest/d1', 'testdir/dest/d2']\n\n\nRemove (rm)\n~~~~~~~~~~~\n\nRemove files or directories::\n\n rm(path, ...)\n\nDelete all files and directories given as arguments. Does not complain if any of \nthe items do not exist. Each argument must be either a string or a list of \nstrings.\n\n.. code-block:: python\n\n >>> print(sorted(str(e) for e in ls(testdir)))\n ['testdir/dest']\n\n >>> print(sorted(str(e) for e in ls(dest)))\n ['testdir/dest/d1', 'testdir/dest/d2', 'testdir/dest/f1', 'testdir/dest/f2']\n\n >>> rm(lsf(dest))\n >>> print(sorted(str(e) for e in ls(dest)))\n ['testdir/dest/d1', 'testdir/dest/d2']\n\n >>> rm(dest)\n >>> print(sorted(str(e) for e in ls(testdir)))\n []\n\n >>> rm(testdir)\n\nLink (ln)\n~~~~~~~~~~~\n\nCreate a symbolic link::\n\n ln(src, link)\n\nCreates a symbolic link *link* that points to *src*. Each argument must be \neither a string.\n\n\nMake File (touch)\n~~~~~~~~~~~~~~~~~\n\nCreate a new empty file or update the timestamp on an existing file::\n\n touch(path, ...)\n\nEach argument must be either a string or a list of strings.\n\n\nMake Directory (mkdir)\n~~~~~~~~~~~~~~~~~~~~~~\n\nCreate an empty directory::\n\n mkdir(path, ...)\n\nFor each argument it creates a directory and any needed parent directories. \nReturns without complaint if the directory already exists. Each argument must be \neither a string or a list of strings.\n\n\nChange Directory (cd)\n~~~~~~~~~~~~~~~~~~~~~\n\nChange to an existing directory::\n\n cd(path)\n\nMakes path the current working directory.\n\nMay also be used in a with block::\n\n with cd(path):\n cwd()\n\nThe working directory returns to its original value upon leaving the with block.\n\n\nList Directory (ls, lsd, lsf)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nList a directory::\n\n ls(path, ... [])\n lsd(path, ... [])\n lsf(path, ... [])\n\nThe first form returns a list of all items found in a directory. The second \nreturns only the directories, and the third returns only the files.\n\nOne or more paths may be specified using unnamed arguments. The paths may be \nstrings or pathlib paths, or collections of those. If no paths are not given, \nthe current working directory is assumed.\n\nThe remaining arguments must be specified as keyword arguments.\n\n::\n\n select=\n\nIf *select* is specified, an item is returned only if it matches the given \npattern. Using '\\*\\*' in *select* enables a recursive walk through a directory \nand all its subdirectories. Using '\\*\\*' alone returns only directories whereas \n'\\*\\*/\\*' returns files and directories.\n\n::\n\n reject=\n\nIf *reject* is specified, an item is not returned if it matches the given \npattern.\n\n::\n\n only={'file','dir'}\n\n\nIf *only* is specified, it may be either 'file' or 'dir', in which case only \nitems of the corresponding type are returned.\n\n::\n\n hidden=\n\nThe value of hidden is a boolean that indicates whether items that begin with \n'.' are included in the output. If hidden is not specified, hidden items are not \nincluded unless *select* begins with '.'.\n\nExamples::\n\n pyfiles = lsf(select='*.py')\n subdirs = lsd()\n tmp_mutt = lsf('/tmp/', select='mutt-*')\n\n\nFile Permissions\n~~~~~~~~~~~~~~~~\n\nChange the file permissiongs of a file, or files, or directory, or directories::\n\n chmod(mode, path)\n\nwhere *mode* is a three digit octal number.\n\nYou may read the permissions of a file or directory using::\n\n mode = getmod(path)\n\n\nPaths\n-----\n\nto_path\n~~~~~~~\n\nCreate a path from a collection of path segments::\n\n p = to_path(seg, ...)\n\nThe segments are combined to form a path. Expands a leading ~. Returns a pathlib \npath. It is generally not necessary to apply to_path() to paths being given to \nthe shlib functions, but using it gives you access to all of the various pathlib \nmethods for the path.\n\n.. code-block:: python\n\n >>> path = to_path('A', 'b', '3')\n >>> str(path)\n 'A/b/3'\n\n\nCartesian Product\n~~~~~~~~~~~~~~~~~\n\nCreate a list of paths by combining from path segments in all combinations::\n\n cartesian_product(seg, ...)\n\nLike with to_path(), the components are combined to form a path, but in this \ncase each component may be a list. The results is the various components are \ncombined in a Cartesian product to form a list. For example:\n\n.. code-block:: python\n\n >>> paths = cartesian_product(['A', 'B'], ['a', 'b'], ['1', '2'])\n >>> for p in paths:\n ... print(p)\n A/a/1\n A/a/2\n A/b/1\n A/b/2\n B/a/1\n B/a/2\n B/b/1\n B/b/2\n\n\nBrace Expand\n~~~~~~~~~~~~\n\nCreate a list of paths using Bash-like brace expansion::\n\n brace_expand(pattern)\n\n.. code-block:: python\n\n >>> paths = brace_expand('python{2.{5..7},3.{2..6}}')\n\n >>> for p in sorted(str(p) for p in paths):\n ... print(p)\n python2.5\n python2.6\n python2.7\n python3.2\n python3.3\n python3.4\n python3.5\n python3.6\n\n\nExecuting Programs\n------------------\n\nThe following classes and functions are used to execute external programs from \nwithin Python.\n\nCommand (Cmd)\n~~~~~~~~~~~~~\n\nA class that runs an external program::\n\n Cmd(cmd[, modes][, env][, encoding][, log][, option_args])\n\n*cmd* may be a list or a string.\n*mode* is a string that specifies various options. The options are specified \nusing a single letter, with upper case enabling the option and lower case \ndisabling it:\n\n | S, s: Use, or do not use, shell\n | O, o: Capture, or do not capture, stdout\n | E, e: Capture, or do not capture, stderr\n | M, m: Merge, or do not merge, stderr into stdout (M overrides E, e)\n | W, s: Wait, or do not wait, for command to terminate before proceeding\n\nIf a letter corresponding to a particular option is not specified, the default \nis used for that option. In addition, one of the following may be given, and it \nmust be given last\n\n | ``*``: accept any output status code\n | N: accept any output status code equal to or less than N\n | M,N,...: accept status codes M, N, ...\n\nIf you do not specify the status code behavior, only 0 is accepted as normal \ntermination, all other codes will be treated as errors. An exception is raised \nif exit status is not acceptable. By default an *OSError* is raised, however if \nthe *use_inform* preference is true, then *inform.Error* is used. In this case \nthe error includes attributes that can be used to access the *stdout*, *stderr*, \n*status*, *cmd*, and *msg*.\n\n*env* is a dictionary of environment variable and their values.\n\n*encoding* is used on the input and output streams when converting them to and\nfrom strings.\n\n*log* specifies whether details about the command should be sent to log file.\nMay be True, False, or None. If None, then behavior is set by *log_cmd*\npreference. Use of *log* requires that *Inform* package be installed.\n\n*option_args* is used when rendering command to logfile, it indicates how many\narguments each option takes. This only occurs when *use_inform* preference is \ntrue and *Inform* package is installed.\n\nFor example, to run diff you might use::\n\n >>> import sys, textwrap\n >>> ref = textwrap.dedent('''\n ... line1\n ... line2\n ... line3\n ... ''').strip()\n >>> test = textwrap.dedent('''\n ... line1\n ... line2\n ... ''').strip()\n\n >>> ref_bytes_written = to_path('./REF').write_text(ref)\n >>> test_bytes_written = to_path('./TEST').write_text(test)\n\n >>> cat = Cmd(['cat', 'TEST'], 'sOeW')\n >>> cat.run()\n 0\n\n >>> print(cat.stdout)\n line1\n line2\n\n >>> diff = Cmd('diff TEST REF', 'sOEW1')\n >>> status = diff.run()\n >>> status\n 1\n\nUse of *O* in the modes allows access to stdout, which is needed to access the \ndifferences. Specifying *E* also allows access to stderr, which in this case is \nhelpful in case something goes wrong because it allows the error handler to \naccess the error message generated by diff. Specifying *W* indicates that run() \nshould block until diff completes. This is also necessary for you to be able to \ncapture either stdout or stderr. Specifying 1 indicates that either 0 or 1 are \nvalid output status codes; any other code output by diff would be treated as an \nerror.\n\nIf you do not indicate that stdout or stderr should be captured, those streams \nremain connected to your TTY. You can specify a string to the run() method, \nwhich is fed to the program through stdin. If you don't specify anything the \nstdin stream for the program also remains connected to the TTY.\n\nIf you indicate that run() should return immediately without out waiting for the \nprogram to exit, then you can use the wait() and kill() methods to manage the \nexecution. For example::\n\n diff = Cmd(['gvim', '-d', lfile, rfile], 'w')\n diff.run()\n try:\n status = diff.wait()\n except KeyboardInterrupt:\n diff.kill()\n\nCasting the object to a string returns the command itself::\n\n >>> print(str(cat))\n cat TEST\n\nIf you call run(), then you should either specify 'W' as the wait mode, or you \nshould call the wait() method. If you do not, then any string you specified as \nstdin is not applied. If your intention is to kick off a process and not wait \nfor it to finish, you should use start() instead. It also allows you to specify \na string to pass to stdin, however you cannot access stdout, stderr, or the exit \nstatus. If you specify the 'O' or 'E' modes when using start(), those outputs \nare simply discarded. This is a useful way of discarding uninteresting \ndiagnostics from the program you are calling.\n\n*Cmd* also provides the *render* method, which converts the command to a string. \nIt takes the same optional arguments as does *render_command*.\n\n\nRun\n~~~\n\n*Run* subclasses *Cmd*. It basically constructs the process and then immediately \ncalls the run() method. It takes the same arguments as Cmd, but an additional \nargument that allows you to specify stdin for the process::\n\n Run(cmd[, modes][, stdin][, env][, encoding])\n\nRun expect you to wait for the process to end, either by specify the 'W' mode, \nor by calling wait(). For example::\n\n >>> echo = Run('cat > helloworld', 'SoeW', 'hello world')\n >>> echo.status\n 0\n\n >>> cat = Run(['cat', 'helloworld'], 'sOew')\n >>> cat.wait()\n 0\n\n >>> print(cat.stdout)\n hello world\n\n\nStart\n~~~~~\n\nStart also subclasses Cmd. It is similar to Run in that it immediately executes \nthe command, but it differs in that it does not expect you to wait for the \ncommand to terminate. You may specify stdin to the command if you wish, but \nsince you are not waiting for the command to terminate you cannot access stdout, \nstderr or the exit status. Effectively, Start() kicks off the process and then \nignores it. You may pass wait or accept in the mode string, but they are \nignored. If you select either stdout or stderr to be captured, then are wired to \n/dev/null, meaning that the selected output is swallowed and discarded.\n\n::\n\n >>> cat = Start('cat helloworld', 'sOe')\n\n\nwhich\n~~~~~\n\nGiven a name, a path, and a collection of read, write, or execute flags, this \nfunction returns the locations along the path where a file or directory can be \nfound with matching flags::\n\n which(name, path=None, flags=os.X_OK)\n\nBy default the path is specified by the PATH environment variable and the flags \ncheck whether you have execute permission.\n\n\nrender_command\n~~~~~~~~~~~~~~\n\nRender a command to a string::\n\n render_command(cmd[, option_args][, width])\n\nConverts the command to a string. The formatting is such that you should be \nable to feed the result directly to a shell and have command execute properly.\n\n*cmd* is the command to render. It may be a string or a list of strings.\n\n*option_args* is a dictionary. The keys are options accepted by the command and \nthe value is the number of arguments for that option. If an option is not \nfound, it is assumed to have 0 arguments.\n\n*width* specifies how long the string must be before it is broken into multiple \nlines. If length of resulting line would be width or less, return as a\nsingle line, otherwise place each argument and option on separate line.\n\nIf the command is rendered as multiple lines, each argument and option is placed \non a separate line, while keeping argument to options on the same line as the \noption. Placing each option and argument on its own line allows complicated \ncommands with long arguments to be displayed cleanly.\n\nFor example::\n\n >>> args = {'--dux': 2, '-d': 2, '--tux': 1}\n >>> print(render_command('bux --dux a b -d c d --tux e f g h', args))\n bux --dux a b -d c d --tux e f g h\n\n >>> print(render_command('bux --dux a b -d c d --tux e f g h', args, width=0))\n bux \\\n --dux a b \\\n -d c d \\\n --tux e \\\n f \\\n g \\\n h\n\n\nset_prefs\n~~~~~~~~~\n\nUsed to set preferences that affect the *Cmd* class. The preferences are given \nas keyword arguments.\n\n*use_inform* indicates that the *Inform* exception *Error* should be raised if \nthe exit status from a command is not acceptable. If this not given or is False, \nan OSError is raised instead. Use of this preference requires that *Inform* be \navailable. If *use_inform* is True, then inform.Error() is used by *Cmd* and \nits subclasses (*Run* and *Start*).\n\n*log_cmd* specifies that the command and its exit status should be written to \nthe *Inform* log file. Use of this preference requires that *Inform* be \navailable.\n\n\nError Reporting with Inform\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe *Cmd* class and its subclasses (*Run* and *Start*) raise an `Inform \n`_ Error if the *use_inform* preference was \nspecified. This allows for rich error reporting. In particular, the command, \nexit status, stdout and stderr are all returned with the exception and are \navailable to insert into an error message. For example::\n\n >> from shlib import Run, set_prefs\n >> from inform import Error\n\n >> set_prefs(use_inform=True)\n\n >> try:\n .. c = Run('sort words', 'sOEW0')\n .. except Error as e:\n .. e.report(template=(\n .. '\"{cmd}\" exits with status {status}.\\n {stderr}',\n .. '\"{cmd}\" exits with status {status}.',\n .. ))\n error: \"sort words\" exits with status 2.\n sort: cannot read: words: No such file or directory.\n\nIf command returns a non-zero exit status, an exception is raised and one of two \nerror messages are printed. The first is printed if *stderr* is not empty, and \nthe second is printed if it is.", "description_content_type": "", "docs_url": null, "download_url": "https://github.com/kenkundert/shlib/tarball/master", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://nurdletech.com/linux-utilities/shlib", "keywords": "shlib,shell,utilities", "license": "GPLv3+", "maintainer": "", "maintainer_email": "", "name": "shlib", "package_url": "https://pypi.org/project/shlib/", "platform": "", "project_url": "https://pypi.org/project/shlib/", "project_urls": { "Download": "https://github.com/kenkundert/shlib/tarball/master", "Homepage": "https://nurdletech.com/linux-utilities/shlib" }, "release_url": "https://pypi.org/project/shlib/1.1.0/", "requires_dist": null, "requires_python": "", "summary": "shell library", "version": "1.1.0" }, "last_serial": 4971134, "releases": { "0.0.0": [ { "comment_text": "", "digests": { "md5": "98526ffdcc88fe4a5ca715184bab0184", "sha256": "049b2e5055ea4ea4152976443b55c351701897d5baea8e9100fb2fe302e9b142" }, "downloads": -1, "filename": "shlib-0.0.0.tar.gz", "has_sig": false, "md5_digest": "98526ffdcc88fe4a5ca715184bab0184", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6615, "upload_time": "2016-01-14T05:41:09", "url": "https://files.pythonhosted.org/packages/f1/b3/db519b11f1906131982da947de1fa6e549b2ef5290aa4f905906aaed21b8/shlib-0.0.0.tar.gz" } ], "0.0.1": [ { "comment_text": "", "digests": { "md5": "e832ec651507424b6a8ddffa35616682", "sha256": "ab463ce2e9d92eaf1965d51063305de8530fd6ccdf7fa1b33c60911f8c158279" }, "downloads": -1, "filename": "shlib-0.0.1.tar.gz", "has_sig": false, "md5_digest": "e832ec651507424b6a8ddffa35616682", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6612, "upload_time": "2016-01-14T05:45:08", "url": "https://files.pythonhosted.org/packages/6e/c6/8a7a12562220f738d8410533bf60d706b9b940f2fad183c9229d7d8b1bf2/shlib-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "bd14ad062369d93da446b9bc3b33ccca", "sha256": "4e6989f6003d5c869568e33ed9928d70876a8b460e9b8e53d9c4ff3c0f0d95e7" }, "downloads": -1, "filename": "shlib-0.0.2.tar.gz", "has_sig": false, "md5_digest": "bd14ad062369d93da446b9bc3b33ccca", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11083, "upload_time": "2016-01-14T06:22:41", "url": "https://files.pythonhosted.org/packages/f3/b8/a4cb879707c5a5e2d6a923865b60c229befd857ac2016005aff420848b6e/shlib-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "8634bda5250851ab301507a03f795cfc", "sha256": "c6a6061e81ba17d767da5aa87a0248315d11af3a8d730ec362c685ceb177bf0e" }, "downloads": -1, "filename": "shlib-0.0.3.tar.gz", "has_sig": false, "md5_digest": "8634bda5250851ab301507a03f795cfc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11529, "upload_time": "2016-01-14T22:10:54", "url": "https://files.pythonhosted.org/packages/ba/5a/9181ca012b5ffe0b9938050fad59038e15a05292e47bbe28463ea5240d1c/shlib-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "ca8bea871421d624fc18b3b516c811ce", "sha256": "7d50989f697af286068acd720d18cec0810ada846862171923bc8abd2973a747" }, "downloads": -1, "filename": "shlib-0.0.4.tar.gz", "has_sig": false, "md5_digest": "ca8bea871421d624fc18b3b516c811ce", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11839, "upload_time": "2016-01-15T01:38:41", "url": "https://files.pythonhosted.org/packages/b1/a6/352708e5201ca532ec2c7ae4328461451507d96384763b38e2d8e80cf8fa/shlib-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "f51a57c61274205f1249b5db00b76fb5", "sha256": "a6197566d3e4c283565c379d833d228db6ad20cd01fef9cb8f4e4bdb1e12734e" }, "downloads": -1, "filename": "shlib-0.0.5.tar.gz", "has_sig": false, "md5_digest": "f51a57c61274205f1249b5db00b76fb5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11883, "upload_time": "2016-01-15T06:39:54", "url": "https://files.pythonhosted.org/packages/05/ae/eb73a71fbe498e7c2901ca25b5afd1b4dde4a0412d8f05fa8cdd4b311c8b/shlib-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "1b6000bb91040509a5f9c4b725542e07", "sha256": "5c9b318f668728450f266368387446885bde574f0bd3bc05d98f0b626cd7c51b" }, "downloads": -1, "filename": "shlib-0.0.6.tar.gz", "has_sig": false, "md5_digest": "1b6000bb91040509a5f9c4b725542e07", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11880, "upload_time": "2016-01-18T02:52:52", "url": "https://files.pythonhosted.org/packages/03/5c/5848eae7b2baa444a60493420c2ca880cce315f315b9b03322fa237dde69/shlib-0.0.6.tar.gz" } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "d5d077338c954d1e4514d60788aa558c", "sha256": "fc1a5182da76e0819da2cea135b8764c80413f837f5a57172300a76dba7dd714" }, "downloads": -1, "filename": "shlib-0.0.7.tar.gz", "has_sig": false, "md5_digest": "d5d077338c954d1e4514d60788aa558c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11885, "upload_time": "2016-01-20T00:06:21", "url": "https://files.pythonhosted.org/packages/db/1a/7ae5873ab89e52d10cd3befd096401062760a40c4e0a4d95a52df54d3f52/shlib-0.0.7.tar.gz" } ], "0.1.0": [ { "comment_text": "", "digests": { "md5": "e375033d276a488ee3225af981b85ed8", "sha256": "38a77cbc38fafbc295f0f3dc67be2ff7db86f544f08765659f2ee94b8a03584e" }, "downloads": -1, "filename": "shlib-0.1.0.tar.gz", "has_sig": false, "md5_digest": "e375033d276a488ee3225af981b85ed8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12696, "upload_time": "2016-02-04T00:24:34", "url": "https://files.pythonhosted.org/packages/6a/06/6c04d946a402e5e0807874dfdb1696e3790d3d0e52694ab80cb21b3967c7/shlib-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "3447e92c9cbfbcb8f0f66d5f378abcf9", "sha256": "dd499928b6f644acfa0ce7118078e37e0a62b84782155398a2721f800b20fc96" }, "downloads": -1, "filename": "shlib-0.1.1.tar.gz", "has_sig": false, "md5_digest": "3447e92c9cbfbcb8f0f66d5f378abcf9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12963, "upload_time": "2016-05-30T17:34:20", "url": "https://files.pythonhosted.org/packages/d7/8e/b2fc01bb4e3a96dd77b010a862c39408ec201514e3d733dcf3fcc843b2eb/shlib-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "bdeeac4cf88821aa90d2f4220cbeda14", "sha256": "2c36783357876e47ea6486328683c09c23b1c5cf125b56acd1561fbf2264c191" }, "downloads": -1, "filename": "shlib-0.1.2.tar.gz", "has_sig": false, "md5_digest": "bdeeac4cf88821aa90d2f4220cbeda14", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12949, "upload_time": "2016-05-30T17:43:23", "url": "https://files.pythonhosted.org/packages/fd/1c/941ce704ebe800b6587b0e996f7dc53e16ecfd220122c75cac6985162368/shlib-0.1.2.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "58803f8d4f0da469db311e68b4cfc34e", "sha256": "03464d99f8d03e140a30b9dd59e1c122790d0d1eb81cbb05fce865dc5ce0cbc6" }, "downloads": -1, "filename": "shlib-0.2.0.tar.gz", "has_sig": false, "md5_digest": "58803f8d4f0da469db311e68b4cfc34e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15242, "upload_time": "2016-09-27T06:46:31", "url": "https://files.pythonhosted.org/packages/ec/3f/8f71b209c22da6c88a3a2a73289b4717f8289a693be15543c6b775039fee/shlib-0.2.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "8641351a2bd14006df582e18c5313f70", "sha256": "2e06f3ab080b858a9b3746a425c238f9431a775482ebf6b7934d3e4e6281f25f" }, "downloads": -1, "filename": "shlib-0.3.1.tar.gz", "has_sig": false, "md5_digest": "8641351a2bd14006df582e18c5313f70", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15801, "upload_time": "2016-11-01T23:14:28", "url": "https://files.pythonhosted.org/packages/d3/3b/2adaba9e9c7d8bf510a6c32595d21f34174b05d7520f27024fbd041a7397/shlib-0.3.1.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "8e2fd066b0082be446bc7e21861e1924", "sha256": "4098a32c6fd60821a22f1476a9906e32d4d6cc9118055a022f9d11109490146d" }, "downloads": -1, "filename": "shlib-0.4.0.tar.gz", "has_sig": false, "md5_digest": "8e2fd066b0082be446bc7e21861e1924", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15695, "upload_time": "2016-12-30T03:20:49", "url": "https://files.pythonhosted.org/packages/09/3f/8984125f656b9e023239ba12002b0a1fdcdb5fb3c5dfd707d83435ecd312/shlib-0.4.0.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "84421f2504d84609e7840ea8744d59b7", "sha256": "8c29a36f79ed9bb9dcbcd44ec44b51d0ea1ef68771707f4be2a734d43ae4d824" }, "downloads": -1, "filename": "shlib-0.5.0.tar.gz", "has_sig": false, "md5_digest": "84421f2504d84609e7840ea8744d59b7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15727, "upload_time": "2017-01-04T21:35:06", "url": "https://files.pythonhosted.org/packages/3b/39/e31ae29d97e975fe90097dc75d4c4490bddc11e763f397dcb2910c832f8a/shlib-0.5.0.tar.gz" } ], "0.6.0": [ { "comment_text": "", "digests": { "md5": "eda72912048e99833452c32712289c38", "sha256": "869b7526ecc73e4722b14130ae4593ed47e76b365f728050cfc76747137b5160" }, "downloads": -1, "filename": "shlib-0.6.0.tar.gz", "has_sig": false, "md5_digest": "eda72912048e99833452c32712289c38", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15735, "upload_time": "2017-01-05T07:32:01", "url": "https://files.pythonhosted.org/packages/7a/78/9f0ba9d8161e04e75bd28d36c6b25a92b85a4e299c39f7cb42fe77ebc0fd/shlib-0.6.0.tar.gz" } ], "0.7.0": [ { "comment_text": "", "digests": { "md5": "70c38646a406ce70546c23b54bc20e98", "sha256": "a26eb6113d2b95f57ebdad84268509c58b4881a810352a2213ef12647a536833" }, "downloads": -1, "filename": "shlib-0.7.0.tar.gz", "has_sig": true, "md5_digest": "70c38646a406ce70546c23b54bc20e98", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16147, "upload_time": "2017-10-06T22:01:14", "url": "https://files.pythonhosted.org/packages/1e/f0/aaf5bcfd9694f79dcc7579747a5bf11ff383a036557f6e0a25d3132b3cb6/shlib-0.7.0.tar.gz" } ], "0.8.0": [ { "comment_text": "", "digests": { "md5": "3e5d4f9f4c05820afe74d935020f223e", "sha256": "160c9925e298b62c895a4a1088b3528c514831fb645815116c1d57c2222a7a55" }, "downloads": -1, "filename": "shlib-0.8.0.tar.gz", "has_sig": true, "md5_digest": "3e5d4f9f4c05820afe74d935020f223e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19909, "upload_time": "2018-08-25T06:06:15", "url": "https://files.pythonhosted.org/packages/35/57/d7b18a65e0d32583e9a78e9dd01c2dfd1e3df920add7372dec98f30b8bbb/shlib-0.8.0.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "df89c1e1e40bf22986360edfa99864e4", "sha256": "f1ecdcf6f1976e9972355bbaab5e134e7a71b78ba124facb1ae99b18394fa9c3" }, "downloads": -1, "filename": "shlib-1.0.0.tar.gz", "has_sig": false, "md5_digest": "df89c1e1e40bf22986360edfa99864e4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18725, "upload_time": "2019-01-14T06:25:36", "url": "https://files.pythonhosted.org/packages/52/f0/685f16e8fd1f5cf8887dd4765560ffb3205f2f7081c90602e4b681fb9e17/shlib-1.0.0.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "875d11327805a6c81f5b575c60e9c994", "sha256": "f9798b0a3e37407171f06efca7c213269f034eee2c94dd9933a819730a6d528b" }, "downloads": -1, "filename": "shlib-1.1.0.tar.gz", "has_sig": false, "md5_digest": "875d11327805a6c81f5b575c60e9c994", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24823, "upload_time": "2019-03-22T04:04:04", "url": "https://files.pythonhosted.org/packages/ca/43/301703a7c92be90faae6260d0a633e150f88c0fcdf4850e5099249238ea0/shlib-1.1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "875d11327805a6c81f5b575c60e9c994", "sha256": "f9798b0a3e37407171f06efca7c213269f034eee2c94dd9933a819730a6d528b" }, "downloads": -1, "filename": "shlib-1.1.0.tar.gz", "has_sig": false, "md5_digest": "875d11327805a6c81f5b575c60e9c994", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24823, "upload_time": "2019-03-22T04:04:04", "url": "https://files.pythonhosted.org/packages/ca/43/301703a7c92be90faae6260d0a633e150f88c0fcdf4850e5099249238ea0/shlib-1.1.0.tar.gz" } ] }