{ "info": { "author": "", "author_email": "", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3" ], "description": "TSTL: the Template Scripting Testing Language\n===========================================\n\nTSTL is a domain-specific language (DSL) and set of tools to support automated generation of tests for software. This\nimplementation targets Python. You define (in Python) a set of\ncomponents used to build up a test, and any properties you want to\nhold for the tested system, and TSTL generates tests for your system.\nTSTL supports test replay, test reduction, and code coverage analysis,\nand includes push-button support for some sophisticated\ntest-generation methods. In other words, TSTL is a _property-based\ntesting_ tool.\n\nWhat is property based testing? Property-based testing is testing that relies\nnot on developers specifying results for specific inputs or call sequences, but on more\ngeneral specification of behavior, combined with automatic generation of many\ntests to make sure that the general specification holds. For more on\nproperty-based testing see:\n\n- https://fsharpforfunandprofit.com/posts/property-based-testing/\n\n- https://hypothesis.works/articles/what-is-property-based-testing/\n\n- https://github.com/trailofbits/deepstate (a tool mixing symbolic\n analysis and fuzzing with property-based testing, for C and C++,\n with design somewhat informed by TSTL)\n\nTSTL has been used to find and fix real faults in real code, including ESRI's ArcPy (http://desktop.arcgis.com/en/arcmap/latest/analyze/arcpy/what-is-arcpy-.htm), sortedcontainers (https://github.com/grantjenks/sorted_containers),\ngmpy2 (https://github.com/aleaxit/gmpy), sympy (http://www.sympy.org/en/index.html), pyfakefs (https://github.com/jmcgeheeiv/pyfakefs),\nPython itself (https://bugs.python.org/issue27870), the Solidity compiler (https://github.com/ethereum/solidity), a Solidity static analysis tool, and even OS X.\n\nInstallation\n------------\n\nYou can grab a recent tstl most easily using pip. `pip install tstl` should work fine. If you want something even more recent you can do:\n\n git clone https://github.com/agroce/tstl.git\n cd tstl\n python setup.py install\n\nFor code coverage, you will also need to install Ned Batchelder's `coverage.py` tool; `pip install coverage` is all that is needed.\n\nTSTL in a Nutshell\n------------------\n\nTo get an idea of how TSTL operates, let's try a toy example. We will use TSTL to solve a simple \"puzzle\" to see if it is possible to generate the integer value 510 using only a few lines of Python code, using only a small set of operations (add 4, subtract 3, multiply by 3, and produce a power of two) starting from 0.\n\n1. Create a file called `nutshell.tstl` with the following content:\n\n```\n@import math\n\n# A line beginning with an @ is just python code.\n\npool: 5\n\n# A pool is a set of values we'll produce and use in testing.\n# We need some integers, and we'll let TSTL produce up to 5 of them.\n# The name is a variable name, basically, but often will be like a\n# type name, showing how the value is used.\n\n := 0\n += 4\n -= 3\n *= 3\n{OverflowError} := int(math.pow(2,))\n\n# These are actions, basically single lines of Python code.\n# The big changes from normal Python are:\n# 1. := is like Python assignment with =, but also tells TSTL this\n# assignment _initializes_ a value.\n# 2. is a placeholder meaning _any_ int value in the pool.\n# 3. {OverflowError} means that we want to ignore if this line of\n# Python produces an uncaught OverflowError exception.\n\n# A test in TSTL is a sequence of actions. So, given the above, one\n# test would be:\n#\n# int3 = 0\n# int4 = 0\n# int3 *= 3\n# int4 += 4\n# int3 = 0\n# int2 = int(math.pow(2,int4))\n# int2 -= 3\n\n# As you can see, the actions can appear in any order, but every\n# pool variable is first initialized by some := assignment.\n# Similarly, TSTL may use pool variables in an arbitrary order;\n# thus we never see int0 or int1 used, here, by chance.\n\n# The size of the int pool determines how many different ints can\n# appear in such a test. You can think of it as TSTL's \"working\n# memory.\" If you have a pool size of 1, and an action like\n# foo(,) you'll always call foo with the same value for both\n# parameters -- like foo(int0,int0). You should always have a pool\n# size at least as large as the number of times you use a pool in a\n# single action. More is often better, to give TSTL more ability to\n# bring back in earlier computed values.\n\nproperty: != 510\n\n# property: expresses an invariant of what we are testing. If the\n# boolean expression evaluates to False, the test has failed.\n```\n\nAs in normal Python, `#` indicates a comment. Comment lines are below\nthe TSTL code being described.\n\n2. Type `tstl nutshell.tstl`.\n3. Type `tstl_rt --normalize --output nutshell.test`.\n\nThis should, in a few seconds, find a way to violate the property\n(produce the value 510), find a maximally-simple version of that\n\"failing test\", and produce a file `nutshell.test` that contains the\ntest. If we had omitted the `{OverflowError}` TSTL would either have\nfound a way to produce 510, or (less likely) would have found a way to\nproduce an overflow in the `pow` call: either would be considered a failure.\n\n4. Type `tstl_replay nutshell.test --verbose`.\n\nThis will replay the test you just created.\n\n5. Comment out (using `#` as usual in Python code) the line ` -= 3`. Now try running `tstl_rt`.\n\nThe core idea of TSTL is to define a set of possible steps in a test,\nplus properties describing what can be considered a test failure, and\nlet TSTL find out if there exists a sequence of actions that will\nproduce a test failure. The actions may be function or method calls,\nor steps that assemble input data (for example, building up a string\nto pass to a parser), or, really, anything you can do with Python.\n\nUsing TSTL\n------------\n\nTSTL installs a few standard tools: the TSTL compiler itself, `tstl`; a random test generator\n`tstl_rt`; a tool for producing standalone tests, `tstl_standalone`;\na tool for replaying TSTL test files, `tstl_replay`; a tool for\ndelta-debugging and normalization of TSTL tests, `tstl_reduce`; and a tool for running a set of tests as a regression, `tstl_regress`.\n\nYou can do most of what you'll need with just the commands `tstl`, `tstl_rt`, `tstl_replay`, and `tstl_reduce`.\n\n* `tstl ` compiles a `.tstl` file into an `sut.py` interface for testing\n* `tstl_rt` runs random testing on the `sut.py` in the current directory, and dumps any discovered faults into `.test` files\n* `tstl_replay ` runs a saved TSTL test, and tells you if it passes or fails; with `--verbose` it provides a fairly detailed trace of the test execution\n* `tstl_reduce ` takes `` runs reduction and normalization on it to produce a shorter, easier to understand test, and saves the output as ``.\n\nAll of these tools offer a large number of configuration options; `--help` will produce a list of supported options for all TSTL tools.\n\n\nExtended Example\n-----\n\nThe easiest way to understand TSTL may be to examine\nexamples/AVL/avlnew.tstl (https://github.com/agroce/tstl/blob/master/examples/AVL/avlnew.tstl), which is a simple example file in the latest\nlanguage format.\n\n`avlnew.tstl` creates a pretty full-featured tester for an AVL tree class. You can\nwrite something very quick and fairly effective with just a few lines\nof code, however:\n\n @import avl\n pool: 3\n\tpool: 2\n\n\tproperty: .check_balanced()\n\n\t := <[1..20]>\n := avl.AVLTree()\n\n\t.insert()\n\t.delete()\n\t.find()\n .display()\t\n\nThis says that there are two kinds of \"things\" involved in our\nAVL tree implementation testing: `int` and `avl`. We define, in\nPython, how to create these things, and what we can do with\nthese things, and then TSTL produces sequences of actions, that is\n_tests_, that match our definition. TSTL also checks that all AVL trees, at all times, are\nproperly balanced. If we wanted, as in `avlnew.tstl`, we could also\nmake sure that our AVL tree \"acts like\" a set --- when we insert\nsomething, we can find that thing, and when we delete something, we\ncan no longer find it.\n\nNote that we start with \"raw Python\" to import the avl module, the SUT. While TSTL\nsupports using from, aliases, and wildcards in imports, you should always\nimport the module(s) under test with a simple import. This allows TSTL to identify\nthe code to be tested and automatically provide coverage, static analysis-aided\ntesting methods, and proper module management. Utility code in the standard library,\non the other hand, can be imported any way you wish.\n\nIf we test this (or `avlnew.tstl`) for 30 seconds, something like this will appear:\n\n`~/tstl/examples/AVL$ tstl_rt --timeout 30`\n\n\n Random testing using config=Config(swarmSwitch=None, verbose=False, fastQuickAnalysis=False, failedLogging=None, maxtests=-1, greedyStutter=False, exploit=None, seed=None, generalize=False, localize=False, uncaught=False, speed='FAST', internal=False, normalize=False, highLowSwarm=None, replayable=False, essentials=False, quickTests=False, coverfile='coverage.out', uniqueValuesAnalysis=False, swarm=False, ignoreprops=False, total=False, swarmLength=None, noreassign=False, profile=False, full=False, multiple=False, relax=False, swarmP=0.5, stutter=None, running=False, compareFails=False, nocover=False, swarmProbs=None, gendepth=None, quickAnalysis=False, exploitCeiling=0.1, logging=None, html=None, keep=False, depth=100, throughput=False, timeout=30, output=None, markov=None, startExploit=0)\n 12 [2:0]\n -- < 2 [1:0]\n ---- < 1 [0:0] L\n ---- > 5 [0:0] L\n -- > 13 [1:-1]\n ---- > 14 [0:0] L\n set([1, 2, 5, 12, 13, 14])\n ...\n 11 [2:0]\n -- < 5 [1:0]\n ---- < 1 [0:0] L\n ---- > 9 [0:0] L\n -- > 14 [1:-1]\n ---- > 18 [0:0] L\n set([1, 5, 9, 11, 14, 18])\n STOPPING TEST DUE TO TIMEOUT, TERMINATED AT LENGTH 17\n STOPPING TESTING DUE TO TIMEOUT\n 80.8306709265 PERCENT COVERED\n 30.0417540073 TOTAL RUNTIME\n 236 EXECUTED\n 23517 TOTAL TEST OPERATIONS\n 10.3524413109 TIME SPENT EXECUTING TEST OPERATIONS\n 0.751145362854 TIME SPENT EVALUATING GUARDS AND CHOOSING ACTIONS\n 18.4323685169 TIME SPENT CHECKING PROPERTIES\n 28.7848098278 TOTAL TIME SPENT RUNNING SUT\n 0.179262161255 TIME SPENT RESTARTING\n 0.0 TIME SPENT REDUCING TEST CASES\n 224 BRANCHES COVERED\n 166 STATEMENTS COVERED\n\nFor many (but not all!) programs, a more powerful alternative to\nsimple random testing is to use swarm testing, which restricts the\nactions in each individual test (e.g., insert but no delete, or find\nbut no inorder traversals) (see\nhttp://agroce.github.io/issta12.pdf).\n\n ~/tstl/examples/AVL$ tstl_rt --timeout 30 --swarm\n Random testing using config=Config(swarmSwitch=None, verbose=False, fastQuickAnalysis=False, failedLogging=None, maxtests=-1, greedyStutter=False, exploit=None, seed=None, generalize=False, localize=False, uncaught=False, speed='FAST', internal=False, normalize=False, highLowSwarm=None, replayable=False, essentials=False, quickTests=False, coverfile='coverage.out', uniqueValuesAnalysis=False, swarm=True, ignoreprops=False, total=False, swarmLength=None, noreassign=False, profile=False, full=False, multiple=False, relax=False, swarmP=0.5, stutter=None, running=False, compareFails=False, nocover=False, swarmProbs=None, gendepth=None, quickAnalysis=False, exploitCeiling=0.1, logging=None, html=None, keep=False, depth=100, throughput=False, timeout=30, output=None, markov=None, startExploit=0)\n 11 [2:0]\n -- < 7 [1:0]\n ...\n STOPPING TEST DUE TO TIMEOUT, TERMINATED AT LENGTH 94\n 224 BRANCHES COVERED\n 166 STATEMENTS COVERED\n\nHere, the method is not very important; simple random testing does a\ndecent job covering the AVL tree code in just 60 seconds. If we\nintroduce a bug by removing the `self.rebalance()` call on line 205 of\navl.py, either method will quickly report a failing test case,\nautomatically reduced. By default, the random tester will run the test\nin a verbose mode to show in more detail what happens during the execution\nthat causes a failure.\n\n\t~/tstl/examples/AVL$ tstl_rt --timeout 30\n\tRandom testing using config=Config(swarmSwitch=None, verbose=False, fastQuickAnalysis=False, failedLogging=None, maxtests=-1, greedyStutter=False, exploit=None, seed=None, generalize=False, localize=False, uncaught=False, speed='FAST', uniqueValuesAnalysis=False, normalize=False, silentFail=False, noAlphaConvert=False, replayable=False, essentials=False, quickTests=False, coverfile='coverage.out', swarm=False, internal=False, total=False, progress=False, swarmLength=None, noreassign=False, profile=False, full=False, multiple=False, timedProgress=30, relax=False, swarmP=0.5, stutter=None, highLowSwarm=None, readQuick=False, verboseActions=False, running=False, ignoreProps=False, compareFails=False, nocover=False, swarmProbs=None, gendepth=None, quickAnalysis=False, exploitCeiling=0.1, computeFeatureStats=False, logging=None, html=None, keep=False, noExceptionMatch=False, depth=100, showActions=False, throughput=False, timeout=30, output='failure.26816.test', markov=None, startExploit=0)\n\t 11 [2:0]\n\t-- < 8 [1:0]\n\t---- < 4 [0:0] L\n\t---- > 9 [0:0] L\n\t-- > 18 [1:1]\n\t---- < 15 [0:0] L\n\tset([4, 8, 9, 11, 15, 18])\n\tPROPERLY VIOLATION\n\tERROR: (, AssertionError(), )\n\tTRACEBACK:\n\t File \"/Users/alex/tstl/examples/AVL/sut.py\", line 7960, in check\n\t assert self.p_avl[0].check_balanced()\n\tOriginal test has 98 steps\n\tREDUCING...\n\tFailed to reduce, increasing granularity to 4\n\tReduced test length to 73\n\tFailed to reduce, increasing granularity to 4\n\tReduced test length to 55\n\tFailed to reduce, increasing granularity to 4\n\tReduced test length to 41\n\tFailed to reduce, increasing granularity to 4\n\tReduced test length to 31\n\tFailed to reduce, increasing granularity to 4\n\tReduced test length to 24\n\tFailed to reduce, increasing granularity to 4\n\tFailed to reduce, increasing granularity to 8\n\tReduced test length to 20\n\tFailed to reduce, increasing granularity to 4\n\tFailed to reduce, increasing granularity to 8\n\tReduced test length to 17\n\tFailed to reduce, increasing granularity to 4\n\tFailed to reduce, increasing granularity to 8\n\tReduced test length to 14\n\tFailed to reduce, increasing granularity to 4\n\tFailed to reduce, increasing granularity to 8\n\tReduced test length to 13\n\tFailed to reduce, increasing granularity to 4\n\tFailed to reduce, increasing granularity to 8\n\tReduced test length to 11\n\tFailed to reduce, increasing granularity to 4\n\tFailed to reduce, increasing granularity to 8\n\tFailed to reduce, increasing granularity to 11\n\tReduced test has 11 steps\n\tREDUCED IN 1.02356314659 SECONDS\n\tAlpha converting test...\n\tint0 = 1 # STEP 0\n\tavl0 = avl.AVLTree() # STEP 1\n\tavl0.insert(int0) # STEP 2\n\tint0 = 6 # STEP 3\n\tavl0.insert(int0) # STEP 4\n\tint0 = 8 # STEP 5\n\tavl0.insert(int0) # STEP 6\n\tint1 = 20 # STEP 7\n\tavl0.insert(int1) # STEP 8\n\tint1 = 1 # STEP 9\n\tavl0.delete(int1) # STEP 10\n\n\tSAVING TEST AS failure.26816.test\n\tFINAL VERSION OF TEST, WITH LOGGED REPLAY:\n\tint0 = 1 # STEP 0\n\tACTION: int0 = 1 \n\tint0 = None : \n\t=> int0 = 1 : \n\t==================================================\n\tavl0 = avl.AVLTree() # STEP 1\n\tACTION: avl0 = avl.AVLTree() \n\tavl0 = None : \n\tavl_REF0 = None : \n\t=> avl0 = : \n\tREFERENCE ACTION: avl_REF0 = set()\n\t=> avl_REF0 = set([]) : \n\t==================================================\n\tavl0.insert(int0) # STEP 2\n\tACTION: avl0.insert(int0) \n\tint0 = 1 : \n\tavl0 = : \n\tavl_REF0 = set([]) : \n\tREFERENCE ACTION: avl_REF0.add(int0)\n\t=> avl_REF0 = set([1]) : \n\t==================================================\n\tint0 = 6 # STEP 3\n\tACTION: int0 = 6 \n\tint0 = 1 : \n\t=> int0 = 6 : \n\t==================================================\n\tavl0.insert(int0) # STEP 4\n\tACTION: avl0.insert(int0) \n\tint0 = 6 : \n\tavl0 = : \n\tavl_REF0 = set([1]) : \n\tREFERENCE ACTION: avl_REF0.add(int0)\n\t=> avl_REF0 = set([1, 6]) : \n\t==================================================\n\tint0 = 8 # STEP 5\n\tACTION: int0 = 8 \n\tint0 = 6 : \n\t=> int0 = 8 : \n\t==================================================\n\tavl0.insert(int0) # STEP 6\n\tACTION: avl0.insert(int0) \n\tint0 = 8 : \n\tavl0 = : \n\tavl_REF0 = set([1, 6]) : \n\tREFERENCE ACTION: avl_REF0.add(int0)\n\t=> avl_REF0 = set([8, 1, 6]) : \n\t==================================================\n\tint1 = 20 # STEP 7\n\tACTION: int1 = 20 \n\tint1 = None : \n\t=> int1 = 20 : \n\t==================================================\n\tavl0.insert(int1) # STEP 8\n\tACTION: avl0.insert(int1) \n\tint1 = 20 : \n\tavl0 = : \n\tavl_REF0 = set([8, 1, 6]) : \n\tREFERENCE ACTION: avl_REF0.add(int1)\n\t=> avl_REF0 = set([8, 1, 20, 6]) : \n\t==================================================\n\tint1 = 1 # STEP 9\n\tACTION: int1 = 1 \n\tint1 = 20 : \n\t=> int1 = 1 : \n\t==================================================\n\tavl0.delete(int1) # STEP 10\n\tACTION: avl0.delete(int1) \n\tint1 = 1 : \n\tavl0 = : \n\tavl_REF0 = set([8, 1, 20, 6]) : \n\tREFERENCE ACTION: avl_REF0.discard(int1)\n\t=> avl_REF0 = set([8, 20, 6]) : \n\t==================================================\n\tERROR: (, AssertionError(), )\n\tTRACEBACK:\n\t File \"/Users/alex/tstl/examples/AVL/sut.py\", line 7960, in check\n\t assert self.p_avl[0].check_balanced()\n\tSTOPPING TESTING DUE TO FAILED TEST\n\t79.552715655 PERCENT COVERED\n\t2.22598695755 TOTAL RUNTIME\n\t15 EXECUTED\n\t1498 TOTAL TEST OPERATIONS\n\t0.408244371414 TIME SPENT EXECUTING TEST OPERATIONS\n\t0.0258889198303 TIME SPENT EVALUATING GUARDS AND CHOOSING ACTIONS\n\t0.706946611404 TIME SPENT CHECKING PROPERTIES\n\t1.11519098282 TOTAL TIME SPENT RUNNING SUT\n\t0.00753235816956 TIME SPENT RESTARTING\n\t1.03021097183 TIME SPENT REDUCING TEST CASES\n\t220 BRANCHES COVERED\n\t164 STATEMENTS COVERED\n\n\nUsing `--output`, the failing test can be saved to a named file, and with the `standalone.py`\nutility, converted into a completely standalone test case that does\nnot require TSTL itself. Without `--output` the test is still saved, but the name is based on the process ID of `tstl_rt`. In either case, you can easily re-run a saved test, even without converting to a standalone test, using `tstl_replay `, and reduce it using `tstl_reduce`. The `--verbose` flag is useful for replay, since it will show you exactly what happens during a test.\n\n ~/tstl/examples/AVL$ tstl_rt --timeout 30 --output failure.test\n Random testing using config=Config(swarmSwitch=None, verbose=False, fastQuickAnalysis=False, failedLogging=None, maxtests=-1, greedyStutter=False, exploit=None, seed=None, generalize=False, localize=False, uncaught=False, speed='FAST', internal=False, normalize=False, highLowSwarm=None, replayable=False, essentials=False, quickTests=False, coverfile='coverage.out', uniqueValuesAnalysis=False, swarm=False, ignoreprops=False, total=False, swarmLength=None, noreassign=False, profile=False, full=False, multiple=False, relax=False, swarmP=0.5, stutter=None, running=False, compareFails=False, nocover=False, swarmProbs=None, gendepth=None, quickAnalysis=False, exploitCeiling=0.1, logging=None, html=None, keep=False, depth=100, throughput=False, timeout=30, output=None, markov=None, startExploit=0)\n ...\n ~/tstl/examples/AVL$ tstl_reduce failure.test failure_norm.test\n REDUCING...\n ...\n NORMALIZING...\n ...\n ~/tstl/examples/AVL$ tstl_replay failure_norm.test --verbose\n ...\n ~/tstl/examples/AVL$ tstl_standalone failure_norm.test failure.py\n ~/tstl/examples/AVL$ python failure.py\n Traceback (most recent call last):\n File \"failure.py\", line 98, in \n check()\n File \"failure.py\", line 45, in check\n assert avl2.check_balanced()\n AssertionError\n\nThe final useful hint for getting started is that sometimes you may want to test something\n(for example, a library implemented in C) where failing tests crash the Python interpreter. This is possible,\nbut requires some effort. First, run `tstl_rt` with the `--replayable` option. This causes the generator to\nkeep a file, `currtest.test`, in the directory you are running testing in: this file holds the current test. If the random tester crashes, this will include the action that caused the crash. In a few rare cases, the behavior of past tests is also relevant to a crash (reloading the module does not really reset state of the system -- e.g., interacting with hardware). For these cases, use `--total` and look at the file `fulltest.test`, which contains ALL actions ever performed by the random tester.\n\nThe `currtest.test` and `fulltest.test` files work just like normal TSTL files, and can be replayed with the replay utility or turned into standalone files. However, for test reduction and normalization to work correctly, they must be reduced by passing the `--sandbox` argument to `tstl_reduce`.\n\nWhat about tests that fail by entering an infinite loop? The same technique as is used for crashes works. However, you need to run `tstl_rt` with a time limit (using ulimit if you are on UNIX-like systems, for example). The `tstl_reduce` utility provides a `--timeout` argument to handle such tests, but this only works on systems supporting ulimit, for now. In very rare cases, you might have a test execution lock up because, for example, the failure causes a read from standard input. If you hit this, contact me.\n\nFinally, how do you integrate TSTL testing with more conventional approaches, e.g., pytest? The file `test_tstl_regressions.py` in the examples directory shows one way. If you add all your TSTL tests of interest to a `tstl_tests` directory under the directory where `sut.py` lives, you can make pytest run all your TSTL tests. Perhaps more interestingly, this file also wraps a simple caller that forces 60 seconds of random testing to be executed by pytest, as a sanity check. You can tweak the configuration of the random testing easily -- often, adding \"--swarm\" is a good idea.\n\nTSTL and Mutation Testing\n-----\nUsing the\n[universalmutator](https://github.com/agroce/universalmutator) tool,\nyou can easily investigate the power of your TSTL test harnesses to find\nbugs. For example, if we wanted to see how effective 10 seconds of\nrandom testing using our AVL harness is, we could do this:\n\n```\n~/tstl/examples/AVL$ pip install universalmutator\n~/tstl/examples/AVL$ tstl avlnew.tstl\nGenerating harness core using config=Config(tstl='avlnew.tstl', stats=False, checkFailureDeterminism=False, pylib=False, defaultReplay=False, forceRefExceptionMatch=False, enumerateEnabled=False, forceStrongRefExceptionMatch=False, classname='sut', version=False, noCover=False, debug=False, output='sut.py', noReload=False, ignoreAngles=False, coverReload=False, coverInit=False)\n~/tstl/examples/AVL$ mkdir mutants\n~/tstl/examples/AVL$ mutate avl.py --mutantDir mutants\n*** UNIVERSALMUTATOR ***\nMUTATING WITH RULES: universal.rules, python.rules\n1497 MUTANTS GENERATED BY RULES\n...\n768 VALID MUTANTS\n591 INVALID MUTANTS\n138 REDUNDANT MUTANTS\n~/tstl/examples/AVL$ analyze_mutants avl.py \"tstl_rt --timeout 10\" --mutantDir mutants\nANALYZING avl.py\nCOMMAND: ** ['tstl_rt --timeout 10'] **\n#1: [0.0s 0.0% DONE]\n mutants/avl.mutant.89.py NOT KILLED\n RUNNING SCORE: 0.0\n#2: [10.43s 0.13% DONE]\n mutants/avl.mutant.507.py KILLED IN 0.689107179642\n RUNNING SCORE: 0.5\n#3: [11.12s 0.26% DONE]\n mutants/avl.mutant.312.py KILLED IN 2.01887583733\n RUNNING SCORE: 0.666666666667\n#4: [13.14s 0.39% DONE]\n mutants/avl.mutant.165.py NOT KILLED\n RUNNING SCORE: 0.5\n...\n```\n\nThis reports the score for mutants that our testing doesn't even\ncover, which may be of little interest if we only target part of an\nAPI. And, frankly, there are easier ways to see which code isn't covered\nthan using mutation testing! So we may want to limit our analysis to\ncode actually covered by the AVL harness, using a generously large\ntimeout:\n\n```\n~/tstl/examples/AVL$ tstl_rt --timeout 120 --internal >& avlnew.lines\n~/tstl/examples/AVL$ check_covered avl.py avlnew.lines coveredmutants.txt --tstl --mutantDir mutants\n~/tstl/examples/AVL$ analyze_mutants avl.py \"tstl_rt --timeout 10\" --mutantDir mutants --fromFile coveredmutants.txt\nANALYZING avl.py\nCOMMAND: ** ['tstl_rt --timeout 10'] **\n#1: [0.0s 0.0% DONE]\n mutants/avl.mutant.17.py KILLED IN 0.574796915054\n RUNNING SCORE: 1.0\n#2: [0.58s 0.14% DONE]\n mutants/avl.mutant.186.py KILLED IN 0.581020116806\n RUNNING SCORE: 1.0\n#3: [1.16s 0.28% DONE]\n mutants/avl.mutant.692.py NOT KILLED\n RUNNING SCORE: 0.666666666667\n...\n```\n\nHints for Better Testing\n-----\n\nSometimes just doing `tstl_rt` or even `tstl_rt --swarm` isn't enough. There are other options for improving testing. A particularly powerful one in many cases is using the size of functions in terms of lines-of-code to guide testing. To do this, you first let TSTL determine the sizes:\n\n`tstl_rt --generateLOC sut.loc --timeout 120`\n\nThen you use that generated file to guide testing:\n\n`tstl_rt --biasLOC sut.loc`\n\nIt's also a good idea, for faster testing (since the power of random\ntesting is partly in generating huge numbers of tests every minute),\nto turn off code coverage collection with `--noCover`. This isn't so\ngreat if you are looking to see if your tests cover your code well,\nbut for pedal-to-the-metal bug-hunting, it is often the way to go.\n\nThere are other things that can improve testing. The `--profileProbs`\noption gathers information on how often each action in the TSTL\nharness has been taken during testing, and linearly biases random action\nchoice towards actions that have been taken fewer times. This slows\ndown test generation substantially in most cases, but for many\nprograms (especially complex ones) it also dramatically improves code\ncoverage and fault detection, by exploring hard-to-hit actions, and\nspending less time generating input data vs. running the SUT. In\nthese cases the loss in test throughput produced by attempts to take\nlikely-disabled actions is much more than compensated\nfor by an improvement in test quality. Because both rely on setting\naction probabilities, `--profileProbs` and `--biasLOC` are\nunfortunately not compatible.\n\nFor some programs, the structure of the harness file slows down test\ngeneration, and the `--useDependencies` option can improve test throughput by\na factor of 2-10x. However, for most programs this option slows down\ntest generation by roughly a factor of two.\n\nBecause the utility of these options varies so widely, it is best to\nsimply try them out. For `--profileProbs` you should see a large\nincrease in code coverage if it is effective for your testing problem\n(probably accompanied by a large drop in the number of tests generated),\nand for `--useDependencies` you should see a large increase in the\nnumber of tests/test operations performed.\n\nYou can also try a \"genetic algorithms\" approach guided by coverage, that exploits \"high coverage\" tests:\n\n`tstl_rt --exploit 0.8 --Pmutate 0.5`\n\nAdding `--reducePool` sometimes also improves the performance of this method.\n\nYou can tune the exploit and mutate parameters to see if they improve\nresults. You can even combine lines-of-code bias or profile-based\nprobabilities with the `exploit` approach and/or swarm testing. Unfortunately, using `--exploit` does mean you can't get away with `--noCover` to avoid the overhead of computing code coverage.\n\nWe're working on a way to get TSTL to perform experiments\nautomatically and advise you of the best configuration for testing a\ngiven harness.\n\nTo get a set of very fast \"regression tests\" you can run `tstl_rt` for\na long time in a good configuration with the `--quickTests` option,\nand generate a set of very short tests with high code coverage.\n\nFault Localization\n-----\n\nTSTL supports automated fault localization. If you have a harness that finds\na bug, you might get some insight into the nature of that bug by\nrunning something like:\n\n`tstl-rt --localize --multiple`\n\nThis will run TSTL for an hour, generate a number of failing\ntest cases (if your bug can be found relatively easily in an hour),\nand then report on the 20 most-likely-faulty statements and branches\nin the code under test. Some of this code may be involved in things\nlike printing assertion values, or error handling for the fault, but\nthere's a good chance you'll find the buggy code in the localization\nresults, in our experience. In fact, a five minute run will suffice\nfor good localization, often, if five minutes is sufficient to find\nyour bug a few times. Note that results are much worse if you have more than one bug!\n\nA Swarm-Based Workflow\n-----------\nOne way to use swarm testing effectively is to apply _directed swarm\ntesting_, an approach where data on how swarm interacts with code\ncoverage is used to boost coverage of rarely covered statements and\nbranches.\n\nTo do this, run your initial testing using `tstl_rt` (for an hour or more) with the options:\n\n- `--swarm`\n- `--saveSwarmCoverage `\n- `--fullCoverage `\n\nThis will test your program, and produce two files of interest.\n`` will contain a simple text file with branches and\nstatements covered, ranked by the number of times they were covered.\nThis is basically a simplified version of the kind of output you may\nbe familiar with from `gcov` or other tools. You can look at this\nfile, and identify interesting looking, but rarely-covered, code.\n\nThen, take the identifier (the full string, including parenthesis) of\nthe interesting code and use the `tstl_directedswarm` tool like this:\n\n`tstl_directedswarm \"\" `\n\n(`` is the file you produced in the original run of swarm\ntesting.) This will try to figure out which actions help (\"trigger\")\nand hinder (\"suppress\") coverage of\nthe target code, and produce a file (`probFile`) with probabilities for use in more\nfocused swarm testing. If the tool doesn't identify any triggers or\nsuppressors, try running again with the `--confidence` option and a\nnumber less than 0.95; the lower the confidence required, the more\nlikely you are to find triggers and suppressors, but the less likely\nthey are to be meaningful -- you can try slowly lowering until you get\nsome results. Then run testing again, like this:\n\n`tstl_rt --swarm --swarmProbs `\n\nYou should usually be able to cover the rarely-covered code well this\nway. Since covering rarely covered code often\nuncovers interesting new never-seen-before code, you may want to\nrepeat this process once you've explored the rarely-covered code from\nyour intial run. You can, of course, store swarm\ncoverage and full coverage stats for the focused runs of TSTL, and\nkeep exploring.\n\nA more systematic way to go about directed swarm testing is to try:\n\n`tstl_analyzeswarm --cutoff 0.5`\n\nto generate triggers and suppressors for ALL coverage targets hit\nduring a run, grouped into equivalence classes (targets with the same\nset of triggers and suppressors) and ranked by the least-hit target in\neach equivalence class. The output will be stored in files beginning\nwith ``: a set of files named `.N.probs` that can\nused with `--swarmProbs`, and a single `.class` file, with all the targets,\ntriggers, suppressors, and minimum frequencies for classes, plus\npointers to the related probability files. Just iterating through the generated\nprobability files for the classes for the rarest targets is a good way\nto go about directed swarm testing. The `0.5` above can be any\ncutoff, above which targets hit by at least that fraction of tests are\nconsidered well-tested and ignored. Setting this as low as `0.01` can\nwork well, for initial runs producing a large number of tests.\n\n\nTSTL and the American Fuzzy Lop (AFL) Fuzzer\n---------\n\nYou can even use AFL (http://lcamtuf.coredump.cx/afl/) to generate\nTSTL tests. You need to install AFL itself and the `python-afl` pip\npackage (or grab the code from github at https://github.com/jwilk/python-afl). Then you can fuzz using AFL in any directory with a compiled\nTSTL harness:\n\n`tstl_afl_fuzz --output --input `\n\nThis will use some (usually good) default settings to first have TSTL\ngenerate some good starting tests for AFL to build on, then run AFL\nfor a day on the SUT. A day may not be enough, so the same\n`--timeout` parameter is supported as by the TSTL random tester. You\ncan also use swarm testing by adding `--swarm`. There are other, less\nfrequently used, options as well. Failing tests generated by AFL will\nbe stored as `aflfail..test` in the current directory. One piece\nof advice: `` should probably be a ramdisk, unless you\nwant to really hammer your SSD (don't even think about doing this on\nan actual hard drive).\n\nYou should also try the `--persist` option to `tstl_afl_fuzz`, which\nwill often improve fuzzing speed by a large margin, and\ndramatically improve AFL results (since throughput is so critical); however, \nthis is somewhat less well-tested than the non-persistent mode. With\nmore testing, this will likely become the default setting, so you may\nwant to jump ahead of the curve, and only run non-persistent if\npersistent mode seems to cause problems.\n\nThis is a powerful testing option, as it lets you use AFL's great\nheuristics to fuzz things that are at best highly inconvenient with\njust AFL. You can set up complex TSTL properties, mix grammar\ngeneration and API-call sequences, and do differential testing\nTSTL-style, but use AFL's tuned input generation methods. The main\ndrawback is that AFL really expects much faster executables than TSTL\nis giving it, so you probably need to run for days to improve on what\nTSTL can do in an hour, unless your SUT is unusual. But it is\ncertainly an attractive option for week-long heavy-duty testing when\n`tstl_rt` isn't finding any problems.\n\nNote that if you don't use `tstl_afl_fuzz` but directly call\n`py-afl-fuzz` you probably (except on Mac OS, where memory limiting\ndoesn't work anyway) need a large `-m` for TSTL to work.\n\n Under the hood, the`tstl_afl`command takes a file of bytes and interprets every N bytes (N\ndepends on how many actions your harness has) as the\nindex of a TSTL action (modulo the number of actions), using `sut.py`\nas usual. When `tstl_afl` detects a failure\nit also produces a conventional TSTL test file under the name\n`aflfail..test`. You can even use `--swarm` to interpret the first 4 bytes\nas a seed to control swarm testing, thus allowing AFL to use swarm testing; this has the drawback that the\nfile will be interpreted incorrectly by other TSTL tools, unless you\npass them the `--aflswarm` option. Most TSTL tools take an\n`--afl` option that indicates tests to be read in are in AFL format,\nand `--aflswarm` to indicate they are swarm tests.\n\n`tstl_afl` is also useful for turning a single\nAFL byte file into a normal TSTL test file, using the `--alwaysSave` option, which dumps a TSTL test file in the current directory, created from the byte-based input.\n\nThere are also tools for converting large numbers of files to and from AFL format.\n`tstl_toafl` simply takes existing TSTL test files and\nconverts them to AFL byte inputs, and `tstl_fromafl` does the expected\nopposite (and takes an argument indicating the files are in swarm format). `tstl_aflcorpus` randomly generates inputs that trigger novel SUT\ncoverage to get AFL started, but it is usually easier to just generate quick tests with\n`tstl_rt --quickTests` and convert those with `tstl_toafl`.\n`tstl_aflcorpus` does allow using the AFL swarm format, however; just\nrun it with `--swarm`. Because of the way the swarm format works, it\nis unfortunately currently not possible to extract a swarm format test\nfrom a standard TSTL test.\n\nTSTL's \"SmallCheck\"\n------------------\n\n`tstl_smallcheck` is a special-purpose test generator that uses a\ndepth-first-search to exhaustively generate tests up to a provided\ndepth limit. The tool outputs \ncoverage-increasing tests, and stops if it encounters a failure. This will seldom finish if the depth is more than 3 to\n10 (at the most) steps, unless it hits a failure. If you run out of\npatience, you can interrupt the process with CTRL-C and the tool will\nsave the discovered tests.\n\nOne way to get deeper \"exhaustive\" testing\nis to use the `--recursive` option to explore from coverage increasing\ntests, repeatedly up to a limited number of times, using the same\ndepth as the original run (and a small initial depth).\n\nIf you want to collect all failing tests, not just stop at the first one,\nyou'll need to use the `--multiple` option. Because of their small size and\nthe presumed desire for exhaustive exploration (you used this tool,\nafter all), this tool provides neither reduction nor normalization of\ncovering tests or failures, to\navoid any risk of slippage.\n\nIn addition to `--recursive`, you can use `--visited` or `--visitedList` to avoid re-visiting\nalready explored states during the DFS; however, this requires some\ncare. If the tool fails, or the tests don't seem valid/correct, you may want to recompile your harness with\n`--defaultReplay`, because state-based backtracking doesn't work. In\nmany cases, due to the high cost of state comparison in this setting,\nkeeping track of visited states may not even be very helpful.\n\nRandom testing using `tstl_rt` is probably almost always more\neffective than this approach, but `tstl_smallcheck` can provide\nguarantees that `tstl_rt` cannot, such as that no test with fewer than\nfour steps can\ncause any failures. Starting a smallcheck from existing quick tests using the `--fromTests` option is one way to add extra confidence in your testing.\n\nTSTL and Hypothesis\n------------------------\n\nSome of you may be asking: \"How does TSTL differ from the Hypothesis\nhttps://hypothesis.readthedocs.io/en/latest/ testing tool?\" There are a few\nanswers. First, TSTL is probably much less polished than Hypothesis,\nright now! More importantly, however, Hypothesis and TSTL both\ngenerate tests, but they are primarily intended to generate different\nkinds of tests. Hypothesis is in what we consider the QuickCheck\nfamily: if you have a function `f` that takes as input a list, a\nstring, or something more complex, Hypothesis is very likely what you\nwant to use. If you have a set of functions, `f`, `g`, and `h`, and\nthey don't just return things, but modify invisible system state (but\nalso return things that may be inputs to other functions), you may\nwant TSTL. You can do state-based sequence-of-method-calls testing\nwith Hypothesis, but it may be easier with TSTL, and it's what TSTL is\nbuilt for. So, if you're testing a sorting implementation, Hypothesis\nis almost certainly much better. If you're testing something like a\nfile system, you might want to look into TSTL. If you're testing a\nparser that takes a string as input, both tools might be useful,\ndepending on your situation. One additional difference for the typical user is that TSTL has considerable built-in support for performing differential/reference testing, where your SUT is compared to a reference implementation, possibly with some code to handle expected differences (see the `pyfakefs` example for a good look at how powerful this can be). Finally, TSTL is built as a practical testing tool, but the design is strongly influenced by the decision to make it useful as a platform for experimenting with novel software testing algorithms.\n\nThe similarity is that both TSTL and Hypothesis don't look like\ntraditional unit testing. They instead let you define the idea of a\nvalid input (either some data values, or in TSTL a sequence of method\ncalls and assignments that more resembles a traditional\ndo-some-stuff-and-then-check-it unit test) and assert general\nproperties about the behavior of a system under valid input.\n\nTips for Handling Numerous Bugs\n---------------\n\nIf you test real software with a good harness, you may well find many\nissues. There are a few ways to deal with this. First, using\n`--normalize` when doing `--multiple` runs with `tstl_rt` can help.\nIn some cases (file systems) normalization (or even reduction) goes\ntoo far. In testing at NASA, we found that \"last operation\" was a\ngood heuristic for different bugs. Using `--keepLast` in testing (or when\nusing `tstl_reduce`) forces reduction and normalization to leave the\nlast step alone. Normalization can still move it around, or\nchange the pool it uses, but is much more careful about changing the\nactual action performed. There is also a tool `tstl_triage` that\ntakes a _glob expression for a set of tests_, runs them all, and reports ones with\ndifferent (heuristic) failure signatures. In particular, it gives you\nthe shortest test for each signature. Remember that triage requires a\nglob expression (in quotes) not a list of files. This is so it can\nhandle even sets of tests that go beyond the shell expansion limit.\nWe assume that you won't need to handle that many tests in regression,\nbut for triage, who knows? Another tool, `tstl_fpf` takes similar\narguments to `tstl_triage` but instead of clustering tests into groups\nthat are likely the same bug, it ranks all tests, such that very\ndifferent tests are high in the ranking, using the\n\"furthest-point-first\" (FPF) method proposed by\nChen et. al in PLDI 2013.\n\nFurther Details\n----------------\n\nFor more details on TSTL, the best starting point is a comprehensive\njournal paper in STTT:\nhttp://agroce.github.io/sttt17.pdf.\nThere are also NASA Formal Methods (NFM) and International Symposium\non Software Testing and Analysis (ISSTA) 2015 papers at\nhttp://agroce.github.io/nfm15.pdf and\nhttp://agroce.github.io/issta15.pdf, with some implementation\ndetails or concepts that are not present in the more up-to-date and\ncomplete paper. In particular, the NFM paper, \"A Little* Language for\nTesting\" has a deprecated syntax and other issues, but is the most\nconcise explanation of the core TSTL idea: a DSL embedding a full\nprogramming language,\ndesigned to make testing (and building testing tools) easy.\n\nThere is a more recent paper describing test normalization, a feature\nunique to TSTL, in more detail, http://agroce.github.io/issta17.pdf, as well as a\ntool paper describing how to use TSTL's test manipulation commands \n(http://agroce.github.io/issta17tool.pdf).\n\nThe NFM and ISSTA papers use an early version of TSTL syntax, which marks\npools and TSTL constructs with % signs. \"Modern\" TSTL uses <> by\ndefault, though if for some reason you need <> in your code (and to\nprepare for a future C++ version) this can be turned off and only % supported.\n\nNote that documentation above is preliminary. The best way to get started, once you understand the basic tools (`tstl`, `tstl_rt`, `tstl_replay`, and `tstl_reduce`) is to examine the examples directory and try out real TSTL test\nharnesses. For the brave, reading tstl/randomtester.py provides\nconsiderable guidance in how to (efficiently) use TSTL in a generic\ntesting tool, with TSTL providing an interface to the underlying\napplication/library to be tested.\n\nCaveats\n-------\n\nNote that TSTL was originally written for Python 2.7, has mostly been developed/tested that way, and is not extremely well-tested yet with Python 3.0+.\nHowever, it should work ok, thanks to mrbean-bremen, and the Travis\ntests check that TSTL works fine on Python 3.6. Earlier 3.0+ versions\nmay have some \"gotchas.\"\n\nDeveloper Info\n--------------\n\nThere are no developer docs yet, which will hopefully change in the future.\nThe best shakedown test for tstl is to compile and run (using `tstl_rt`) the AVL\nexample. Removing any call to the balancing function in the avl.py\ncode should cause TSTL to produce a failing test case.\n\nCredits\n--------------\n\nWho is responsible for TSTL?\n\n- Alex Groce (agroce) wrote this file, and most of the current code base, and is running the show. If there is a problem with TSTL, it is my fault, and don't blame anyone below.\n\n- Josie Holmes (josieholmes) contributed to core language design changes, and is responsible for the ideas (and some of the code) for the various slippage reduction strategies, plus the LOC bias work and Markov things. Before Josie's work, TSTL was extremely hard to read, and considerably less efficient.\n\n- Jervis Pinto was the other original TSTL-er, and has his fingerprints on various parts of the early design and code that form the foundations of TSTL.\n\n- Pranjal Mittal contributed a number of critical elements, including the initial effort to prepare TSTL for a pip release as a useful tool, and has helped publicize TSTL.\n\n- Pooria Azimi added the `` notation, which turns out to be one of the most important changes, and eliminated the need for the exceedingly awkward way of handling binding via Python functions and commit point based guards. Without this, you really don't have a useful TSTL.\n\n- Kevin Kellar developed a (beta) Java version of TSTL: https://github.com/flipturnapps/TSTL-Java.\n\n- My (Alex's) other graduate students (Amin Alipour, Rahul Gopinath, Arpit Christi, Chaoqiang Zhang, Shalini Shamasunder) and almost-mine graduate student (Iftekhar Ahmed) contributed to the general intellectual climate in which TSTL was born.\n\n- Students in CS 499 at Northern Arizona University and CS 362, 562, and 569 at Oregon State University contributed a lot of ideas, and a few concrete language/tool changes or bug reports. These are too numerous to mention, and in some cases I don't recall who asked \"why do you do it that stupid way?\" in class, and got me thinking that it was in fact a stupid way to do things.\n\n- Ned Batchelder, David R. MacIver, and John Regehr have no actual code in TSTL, but all contributed in significant ways to various implementation aspects, in ways that go beyond the general disclaimer that TSTL freely steals from the entire software testing (research) community.\n\n- The pyfakefs team (mrbean-bremen and jmcgeheeiv on github) really\n worked with me to test pyfakefs, which resulted in a number of nice\n improvements to TSTL and to differential testing in particular.\n More recently, mrbean-bremen has taken the lead in making TSTL\n compatible with Python 3, which seems to mostly be done now!\n\n- Jakub Wilk helped with modifications to python-afl that made\n TSTL/AFL integration work much better.\n\n- Corey Kosak helped turn this README into something that you might\n actually enjoy reading, and gets to the point much faster than\n previous versions.\n\n\\* Do you actually remember that asterisk way up there? The footnote is that TSTL _is_ a little language. However, in another sense, it embeds all of Python which makes it pretty big. It depends on how you think about it.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/agroce/tstl", "keywords": "testing tstl", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "tstl", "package_url": "https://pypi.org/project/tstl/", "platform": "", "project_url": "https://pypi.org/project/tstl/", "project_urls": { "Homepage": "https://github.com/agroce/tstl" }, "release_url": "https://pypi.org/project/tstl/1.2.28/", "requires_dist": [ "coverage (==4.5.2)" ], "requires_python": "", "summary": "Template scripting testing language (TSTL)", "version": "1.2.28" }, "last_serial": 5353536, "releases": { "0.1": [], "0.9": [ { "comment_text": "", "digests": { "md5": "ce5e81fdc2534c6f0e7c94361f365b22", "sha256": "7b44cafa583fbb90cd72171cdeef124a9a11ac80953f375b92965a25356f52d5" }, "downloads": -1, "filename": "tstl-0.9-py2-none-any.whl", "has_sig": false, "md5_digest": "ce5e81fdc2534c6f0e7c94361f365b22", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 59410, "upload_time": "2017-03-02T00:03:26", "url": "https://files.pythonhosted.org/packages/b1/e1/9d820181d5df701142f25404ac1d1176625a1844f5ae0e706e12006f16f8/tstl-0.9-py2-none-any.whl" } ], "0.9.1": [ { "comment_text": "", "digests": { "md5": "2753ab47416b124df439a644933e1719", "sha256": "5ff0ccd911ee563c6cc200ed5de53e269332a68aded7b74b184ff0ac9bed7b60" }, "downloads": -1, "filename": "tstl-0.9.1-py2-none-any.whl", "has_sig": false, "md5_digest": "2753ab47416b124df439a644933e1719", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 59537, "upload_time": "2017-03-02T00:25:51", "url": "https://files.pythonhosted.org/packages/77/63/f764c6ef0499afa79ffb570c04b2fae92d7b54511feea900d0566f524aa4/tstl-0.9.1-py2-none-any.whl" } ], "0.9.2": [ { "comment_text": "", "digests": { "md5": "f65c2226dbaaba25809056c2979f7f9f", "sha256": "20c032b9d08ab16e13413d6078268911d0fb10bb5dbf8da5eafe945e390ecc34" }, "downloads": -1, "filename": "tstl-0.9.2-py2-none-any.whl", "has_sig": false, "md5_digest": "f65c2226dbaaba25809056c2979f7f9f", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 59805, "upload_time": "2017-03-02T03:06:22", "url": "https://files.pythonhosted.org/packages/b9/5c/9757e3a05d07d419988953f6babf1b527a130cec1ef4ef5e8d9deed73c30/tstl-0.9.2-py2-none-any.whl" } ], "0.9.3": [ { "comment_text": "", "digests": { "md5": "cf794c334be7a3aacc41ae8b7c49dbc7", "sha256": "79ffd31a0039c757000c66e03b71da5dd317fed6048127027709842cd6536a22" }, "downloads": -1, "filename": "tstl-0.9.3-py2-none-any.whl", "has_sig": false, "md5_digest": "cf794c334be7a3aacc41ae8b7c49dbc7", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 60182, "upload_time": "2017-03-03T01:54:19", "url": "https://files.pythonhosted.org/packages/de/ba/cd0b9c0eaea8bf01a09fb1520c80239e51667c4def16e36d68d3aa559336/tstl-0.9.3-py2-none-any.whl" } ], "0.9.4": [ { "comment_text": "", "digests": { "md5": "3f5f14edb3de7c59d871659d871edcd5", "sha256": "b4078d3dee5fb122488730800231fbc8b84fdceabccb041b63d337260d970241" }, "downloads": -1, "filename": "tstl-0.9.4-py2-none-any.whl", "has_sig": false, "md5_digest": "3f5f14edb3de7c59d871659d871edcd5", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 60773, "upload_time": "2017-03-22T05:14:25", "url": "https://files.pythonhosted.org/packages/cd/0b/3d4b2ad748f829a98b41191a862fdf0e91bcd034258d13d1b94c1eeecb41/tstl-0.9.4-py2-none-any.whl" } ], "0.9.5": [ { "comment_text": "", "digests": { "md5": "fd7ea13d87297faff8282137e586ea1e", "sha256": "3478e8df7faa5d1d78c720eedc42ecbbb5504ed47f1f23542097f9417031b928" }, "downloads": -1, "filename": "tstl-0.9.5-py2-none-any.whl", "has_sig": false, "md5_digest": "fd7ea13d87297faff8282137e586ea1e", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 60773, "upload_time": "2017-03-31T21:28:23", "url": "https://files.pythonhosted.org/packages/c4/c5/1ae6bdc8a4d5d53e6059da6c9163d2c680002f4f2f20cfb88e59a18a4727/tstl-0.9.5-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "89ad8690caab644813bdfd94ae310df0", "sha256": "f4826750ea382c73c150341a08b62f4fb7c0e6dfef50b7818e30f0564a26326d" }, "downloads": -1, "filename": "tstl-0.9.5.tar.gz", "has_sig": false, "md5_digest": "89ad8690caab644813bdfd94ae310df0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 55555, "upload_time": "2017-03-31T21:28:27", "url": "https://files.pythonhosted.org/packages/61/54/7cb0e7599ef0938e667ccc6d6c717bcc535e53f8aa5471390900bc4d7317/tstl-0.9.5.tar.gz" } ], "0.9.6": [ { "comment_text": "", "digests": { "md5": "5d8eda7db6fc94245f191e181787aa5d", "sha256": "39f978f12993c95e65bbea0e9b741ecdb265b6888740ef3afbfc1c14bec9d850" }, "downloads": -1, "filename": "tstl-0.9.6-py2-none-any.whl", "has_sig": false, "md5_digest": "5d8eda7db6fc94245f191e181787aa5d", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 60973, "upload_time": "2017-04-03T01:18:31", "url": "https://files.pythonhosted.org/packages/1c/9b/6b2d2d9ad2af06a550d196e6dc76a761fa9a3e9933fc7f0ad8a665db4aaa/tstl-0.9.6-py2-none-any.whl" } ], "0.9.7": [ { "comment_text": "", "digests": { "md5": "09a4b5bec08076b9b53f7b71aa094abe", "sha256": "83fce5435c79166af7e1ae1be0db574765f998617313f3ff9acf97bdca873d3b" }, "downloads": -1, "filename": "tstl-0.9.7-py2-none-any.whl", "has_sig": false, "md5_digest": "09a4b5bec08076b9b53f7b71aa094abe", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 61381, "upload_time": "2017-04-17T22:45:22", "url": "https://files.pythonhosted.org/packages/ba/3f/48964d082d430f8dda14fcb5cde0e2d792264d6cdcf8e066913309abb1e5/tstl-0.9.7-py2-none-any.whl" } ], "0.9.9": [ { "comment_text": "", "digests": { "md5": "08932aff64c223bef6cec3c0c6757f05", "sha256": "689ae1045b6b824404c32f7cfa9658f50fdd0f6482e3901b0aef1c2e13123f5c" }, "downloads": -1, "filename": "tstl-0.9.9-py2-none-any.whl", "has_sig": false, "md5_digest": "08932aff64c223bef6cec3c0c6757f05", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 64051, "upload_time": "2017-04-30T09:18:08", "url": "https://files.pythonhosted.org/packages/3d/20/018758f781e0d60acf71611bc09453877cd12149fb6e923dd2b13eea43fe/tstl-0.9.9-py2-none-any.whl" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "e1896b03baa8ed6ff5588a0ba01d41d2", "sha256": "a7d4bec3fc525f3434fee561c70e37bbf2ea34532ba9bf5e3d98d9d4dbc5605e" }, "downloads": -1, "filename": "tstl-1.0.1-py2-none-any.whl", "has_sig": false, "md5_digest": "e1896b03baa8ed6ff5588a0ba01d41d2", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 76716, "upload_time": "2017-05-01T20:27:30", "url": "https://files.pythonhosted.org/packages/34/de/b24093f704e699cd975f1e7ddefe06b990cefb9bc5cf46b8c45649ed9d9f/tstl-1.0.1-py2-none-any.whl" } ], "1.0.10": [ { "comment_text": "", "digests": { "md5": "333f6ba6e15f94a791ca9844beb25810", "sha256": "5c41928ee0cb714769a73e5c74e8b35bd95749c41024f0cab41bc3f7842a1a35" }, "downloads": -1, "filename": "tstl-1.0.10-py2-none-any.whl", "has_sig": false, "md5_digest": "333f6ba6e15f94a791ca9844beb25810", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 81700, "upload_time": "2017-06-16T23:09:56", "url": "https://files.pythonhosted.org/packages/33/ba/d812004060a4c20b70641b62fd6c4dabdcf4311065c4ae02caf1a1f64a7a/tstl-1.0.10-py2-none-any.whl" } ], "1.0.11": [ { "comment_text": "", "digests": { "md5": "8b67c642b67a1687fffbff2e1ae6b541", "sha256": "b57976bd3f4e99a1fd0bff62026d500b7888a73ec62a34f80d2a31a6e67d266e" }, "downloads": -1, "filename": "tstl-1.0.11-py2-none-any.whl", "has_sig": false, "md5_digest": "8b67c642b67a1687fffbff2e1ae6b541", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 82555, "upload_time": "2017-06-25T22:39:37", "url": "https://files.pythonhosted.org/packages/e2/24/84393a4b3e014f74ee9b5006df05750d7270054984c56e0388f4bfdad1bc/tstl-1.0.11-py2-none-any.whl" } ], "1.0.12": [ { "comment_text": "", "digests": { "md5": "b281440dd3fb22e26e793dab7141fdb6", "sha256": "8293dd38b6f2165d90d3ccf9d20adf5a0e174c40b6c130a420de1dd6c1caa5e6" }, "downloads": -1, "filename": "tstl-1.0.12-py2-none-any.whl", "has_sig": false, "md5_digest": "b281440dd3fb22e26e793dab7141fdb6", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 82556, "upload_time": "2017-06-25T23:18:37", "url": "https://files.pythonhosted.org/packages/a6/51/7c0fa7aee8f725b2116c24507cf5057efc65d70aa3a5b683113f19aed194/tstl-1.0.12-py2-none-any.whl" } ], "1.0.13": [ { "comment_text": "", "digests": { "md5": "eb960ba1cda2fa9b48a75e7e26dd013c", "sha256": "53697a38ddfa025cdf1b357cd05ca14dbd5acfac2b949e6758987127ce1d7bf5" }, "downloads": -1, "filename": "tstl-1.0.13-py2-none-any.whl", "has_sig": false, "md5_digest": "eb960ba1cda2fa9b48a75e7e26dd013c", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 82559, "upload_time": "2017-06-25T23:39:19", "url": "https://files.pythonhosted.org/packages/f6/2c/16fe6339e5f7c45b58a175e8781010676f14b2a0eaedb25704b5a3b6f6f8/tstl-1.0.13-py2-none-any.whl" } ], "1.0.14": [ { "comment_text": "", "digests": { "md5": "da81d6f03938bceda39d84d210ec2650", "sha256": "20100d7ee45f004c057e38cb97016dadb38c14a6dd3f8772a07feffec5d6b73f" }, "downloads": -1, "filename": "tstl-1.0.14-py2-none-any.whl", "has_sig": false, "md5_digest": "da81d6f03938bceda39d84d210ec2650", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 82960, "upload_time": "2017-07-02T00:44:45", "url": "https://files.pythonhosted.org/packages/f0/f8/9954eeb81ef8be0ce1d66392704572395773160c7c804de54937db363e81/tstl-1.0.14-py2-none-any.whl" } ], "1.0.15": [ { "comment_text": "", "digests": { "md5": "a9242fd6fc20e5d0db721eda2f1df09d", "sha256": "20a119f4939946010866d01aabf8c69a0eed425c51b59f8e5f3cdef75d759ad2" }, "downloads": -1, "filename": "tstl-1.0.15-py2-none-any.whl", "has_sig": false, "md5_digest": "a9242fd6fc20e5d0db721eda2f1df09d", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 82961, "upload_time": "2017-07-10T20:59:17", "url": "https://files.pythonhosted.org/packages/9f/a0/45af22797e6a75118f93dbfaad831a48576e3f9d130852378f47bfb00536/tstl-1.0.15-py2-none-any.whl" } ], "1.0.16": [ { "comment_text": "", "digests": { "md5": "cb09a1274ee5f90ae26502612513aa76", "sha256": "cd3eb4f6ffd17b11bc0649520bb6e6ce5f4781c32147b3231861dbed253c251d" }, "downloads": -1, "filename": "tstl-1.0.16-py2-none-any.whl", "has_sig": false, "md5_digest": "cb09a1274ee5f90ae26502612513aa76", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 83349, "upload_time": "2017-08-05T20:49:44", "url": "https://files.pythonhosted.org/packages/f2/71/7c65837938a09baed3c010a75b71a4167b4094f3e02271c137c55071237e/tstl-1.0.16-py2-none-any.whl" } ], "1.0.17": [ { "comment_text": "", "digests": { "md5": "68a9a19c6b9012785324ae08e1867557", "sha256": "344fe1381788b06f29b9bdb5d8db027a59bd74e331e9d743074f49dbd5a479d1" }, "downloads": -1, "filename": "tstl-1.0.17-py2-none-any.whl", "has_sig": false, "md5_digest": "68a9a19c6b9012785324ae08e1867557", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 84011, "upload_time": "2017-08-27T19:03:05", "url": "https://files.pythonhosted.org/packages/f4/1c/a02972aecb5b12c4902f2bf340367dac7688cfac5393cdf1fcfb59a5c8dd/tstl-1.0.17-py2-none-any.whl" } ], "1.0.18": [ { "comment_text": "", "digests": { "md5": "24ca186c4cc8f7cab56d8221dd950407", "sha256": "c81f45300629c95291ce106592e0da0b3d9c43723284c04e1667d001823b8eb2" }, "downloads": -1, "filename": "tstl-1.0.18-py2-none-any.whl", "has_sig": false, "md5_digest": "24ca186c4cc8f7cab56d8221dd950407", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 86918, "upload_time": "2017-08-29T19:17:10", "url": "https://files.pythonhosted.org/packages/ea/41/ec5dbbada8ff4a48bc022280e7721cbd9496a47e9722bc5173726aeafe0a/tstl-1.0.18-py2-none-any.whl" } ], "1.0.19": [ { "comment_text": "", "digests": { "md5": "6016b1067ae21c87308fc7ed011b3bb1", "sha256": "5c3928a92e51136c5d0b3a73b877e10a73fe7e9edc169bca4ec82a15378821a3" }, "downloads": -1, "filename": "tstl-1.0.19-py2-none-any.whl", "has_sig": false, "md5_digest": "6016b1067ae21c87308fc7ed011b3bb1", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 87498, "upload_time": "2017-09-10T20:27:49", "url": "https://files.pythonhosted.org/packages/0b/94/f383238ab3a1069fcbf79bd8e3a2983d495126f7da82ff75d5f575599f59/tstl-1.0.19-py2-none-any.whl" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "279518ede4ac4472c3d37f441eb01718", "sha256": "b7e92cbcafefd912e1d9233e0d70a67e5f67fb485bac581423295502a7898558" }, "downloads": -1, "filename": "tstl-1.0.2-py2-none-any.whl", "has_sig": false, "md5_digest": "279518ede4ac4472c3d37f441eb01718", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 77064, "upload_time": "2017-05-01T21:09:23", "url": "https://files.pythonhosted.org/packages/87/40/5b4f82cae7c8eb1703c5b82f8eecb722aa65741a3581f718a7104fbc93fb/tstl-1.0.2-py2-none-any.whl" } ], "1.0.3": [ { "comment_text": "", "digests": { "md5": "965c8fa4f24826d78645323d1ffe4b27", "sha256": "de6538882998824d85e5dd28687ae2195b96d1cfbc1d1df341f00bf6db6498b1" }, "downloads": -1, "filename": "tstl-1.0.3-py2-none-any.whl", "has_sig": false, "md5_digest": "965c8fa4f24826d78645323d1ffe4b27", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 78692, "upload_time": "2017-05-02T09:21:23", "url": "https://files.pythonhosted.org/packages/e7/65/988749b3c7326be5e4e2aedf14c061ebf01fb15703bd549170b7841ff607/tstl-1.0.3-py2-none-any.whl" } ], "1.0.4": [ { "comment_text": "", "digests": { "md5": "eeec046323a8fc9a1ce63d788b8ffbe4", "sha256": "a1972f28d3e52f47553410c0ff1be652deb173b061d98e1d754bdb141a331466" }, "downloads": -1, "filename": "tstl-1.0.4-py2-none-any.whl", "has_sig": false, "md5_digest": "eeec046323a8fc9a1ce63d788b8ffbe4", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 78861, "upload_time": "2017-05-02T09:38:23", "url": "https://files.pythonhosted.org/packages/ff/d2/cd47aff78274b2c7e0fede01b8cfb0aa473ab32ae95686a1c687b6d2fcae/tstl-1.0.4-py2-none-any.whl" } ], "1.0.5": [ { "comment_text": "", "digests": { "md5": "6905f31936a9d55546c42283465434d1", "sha256": "8a26f15f99891b3354d1a08892387283bbddf8a0620a0b0f4c4513d73ad065bd" }, "downloads": -1, "filename": "tstl-1.0.5-py2-none-any.whl", "has_sig": false, "md5_digest": "6905f31936a9d55546c42283465434d1", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 79799, "upload_time": "2017-05-27T18:41:05", "url": "https://files.pythonhosted.org/packages/d7/52/241bcc40358afea872f9fb002f979804dec6dbde3544dcb0635b0cacf00d/tstl-1.0.5-py2-none-any.whl" } ], "1.0.6": [ { "comment_text": "", "digests": { "md5": "092cbc9917d07eca54d0535eedb99dfe", "sha256": "abdad45694538601827f72b62f90d24b8eb332d53f11335315158d0a24ea4f84" }, "downloads": -1, "filename": "tstl-1.0.6-py2-none-any.whl", "has_sig": false, "md5_digest": "092cbc9917d07eca54d0535eedb99dfe", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 80420, "upload_time": "2017-06-12T10:53:50", "url": "https://files.pythonhosted.org/packages/81/eb/77d457716689fee1616e95a8aa5f8d513c64b640da39db1cdc68a35bb4ef/tstl-1.0.6-py2-none-any.whl" } ], "1.0.7": [ { "comment_text": "", "digests": { "md5": "e4fc3251e609fba6a12b149a749de58d", "sha256": "a98d7f5154d110b2076427b8edddea80f768d8184aecb3e5160b02150a4d0f0e" }, "downloads": -1, "filename": "tstl-1.0.7-py2-none-any.whl", "has_sig": false, "md5_digest": "e4fc3251e609fba6a12b149a749de58d", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 80682, "upload_time": "2017-06-14T19:35:27", "url": "https://files.pythonhosted.org/packages/6e/bd/ea64b92aedc057284c81623e8daa578bcfe67c6ed9b637a29fe2ca78bce5/tstl-1.0.7-py2-none-any.whl" } ], "1.0.8": [ { "comment_text": "", "digests": { "md5": "359f3ae55cb0eaef5cb47798b34541d9", "sha256": "48b575eb81df727ff12d5119feeb824f55948213b2cfcfbeead8a870710ee39d" }, "downloads": -1, "filename": "tstl-1.0.8-py2-none-any.whl", "has_sig": false, "md5_digest": "359f3ae55cb0eaef5cb47798b34541d9", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 80775, "upload_time": "2017-06-14T22:46:19", "url": "https://files.pythonhosted.org/packages/7d/a5/b8eace3fcb9caa94f8c9b6200ae204bbeaf5cc3b16a38dddb5c2f443e79d/tstl-1.0.8-py2-none-any.whl" } ], "1.0.9": [ { "comment_text": "", "digests": { "md5": "97e21c69d7632ebcb35637959747def8", "sha256": "14b23d7e24cf75ad0eedc04115a941283fbd1f80a222fd1ecc6dacb9f28dbc99" }, "downloads": -1, "filename": "tstl-1.0.9-py2-none-any.whl", "has_sig": false, "md5_digest": "97e21c69d7632ebcb35637959747def8", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 81677, "upload_time": "2017-06-16T21:27:21", "url": "https://files.pythonhosted.org/packages/51/a1/eca5913c943b0f876b41940bc93c988be6915b6d593de3dfb9cd17f64e02/tstl-1.0.9-py2-none-any.whl" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "4dbe593092ec64eef89e07f6aab7bd00", "sha256": "4fc6b79d6211820be5ba44fb100c4727cbc576e6263f6a4ec4b9745b2b6a7f2d" }, "downloads": -1, "filename": "tstl-1.1.0-py2-none-any.whl", "has_sig": false, "md5_digest": "4dbe593092ec64eef89e07f6aab7bd00", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 87552, "upload_time": "2017-09-15T19:15:32", "url": "https://files.pythonhosted.org/packages/64/88/335bc5fd9d3abf03194be64ae501c5d67b4542296e3657afe127c5da3be4/tstl-1.1.0-py2-none-any.whl" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "98df0668635de5e5504b8fed4a385c1a", "sha256": "e6fe73654fef9316a927e74b071d8d10de2e5f634ea5906fb062efd54422cbc4" }, "downloads": -1, "filename": "tstl-1.1.1-py2-none-any.whl", "has_sig": false, "md5_digest": "98df0668635de5e5504b8fed4a385c1a", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 101539, "upload_time": "2017-09-18T00:01:37", "url": "https://files.pythonhosted.org/packages/b6/14/2d47abc13282a47572cfeb41466fae2049331532a5d78ebad17be90104d7/tstl-1.1.1-py2-none-any.whl" } ], "1.1.10": [ { "comment_text": "", "digests": { "md5": "a3b9e6da2c8add8dc7c3e1074d7dbdd0", "sha256": "afcb4d83325d68f770dfb62a096d1a3c19f8b3861a51cb645896f84fd048ba8b" }, "downloads": -1, "filename": "tstl-1.1.10-py2-none-any.whl", "has_sig": false, "md5_digest": "a3b9e6da2c8add8dc7c3e1074d7dbdd0", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 111548, "upload_time": "2018-03-05T22:01:40", "url": "https://files.pythonhosted.org/packages/f1/6a/564cbb167d3012a84c6d324c2436bde06dcc475cf1acdd3f354703a902fd/tstl-1.1.10-py2-none-any.whl" } ], "1.1.11": [ { "comment_text": "", "digests": { "md5": "fc0c2c1d5339f9439d844d6efdd4db83", "sha256": "cf01ec9f1050f0fa57c19b966304c2f80ed7a1e6ec7d5aee5b7887019354e2ef" }, "downloads": -1, "filename": "tstl-1.1.11-py2-none-any.whl", "has_sig": false, "md5_digest": "fc0c2c1d5339f9439d844d6efdd4db83", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 111857, "upload_time": "2018-03-13T18:49:50", "url": "https://files.pythonhosted.org/packages/64/9f/ff8eb163af9391483bda87095786efc210d1bdc708797c0313a8fafaab5d/tstl-1.1.11-py2-none-any.whl" } ], "1.1.12": [ { "comment_text": "", "digests": { "md5": "3cc0f3e1f2847da864ed07a3c5f244f8", "sha256": "266bdc52bcb1d06a656af19429157e21c40044e68c449ea1cb4de29b2f32b635" }, "downloads": -1, "filename": "tstl-1.1.12-py2-none-any.whl", "has_sig": false, "md5_digest": "3cc0f3e1f2847da864ed07a3c5f244f8", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 111899, "upload_time": "2018-03-15T23:29:08", "url": "https://files.pythonhosted.org/packages/8e/09/1fd0cd762be278a2e16e45d205a3c72f9f1a0b5c52f409a865873541ec75/tstl-1.1.12-py2-none-any.whl" } ], "1.1.2": [ { "comment_text": "", "digests": { "md5": "489c856faef05f95d02e57f55baec1b4", "sha256": "88795d36c09cd0299a4ec96607bb8b7c3ca574b7b2804badb39656e94d61efbd" }, "downloads": -1, "filename": "tstl-1.1.2-py2-none-any.whl", "has_sig": false, "md5_digest": "489c856faef05f95d02e57f55baec1b4", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 101562, "upload_time": "2017-09-19T18:21:41", "url": "https://files.pythonhosted.org/packages/aa/75/da8f3735e5196628dc4055f1e4c66c9dc21d657b535b41d50aa9e623a7a5/tstl-1.1.2-py2-none-any.whl" } ], "1.1.3": [ { "comment_text": "", "digests": { "md5": "cf17b9a738e4badff8ac631b75140a90", "sha256": "12ee6ffab0d59d35df7fbabeec96ee34de1c24e3ea91d633eba3e57cc4022d36" }, "downloads": -1, "filename": "tstl-1.1.3-py2-none-any.whl", "has_sig": false, "md5_digest": "cf17b9a738e4badff8ac631b75140a90", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 102004, "upload_time": "2017-09-19T20:20:43", "url": "https://files.pythonhosted.org/packages/29/a0/a51cb067fc2765645c4d1ec16fb3ee5881ce5ae3d2a3619937322847a738/tstl-1.1.3-py2-none-any.whl" } ], "1.1.4": [ { "comment_text": "", "digests": { "md5": "96189829ebf2bf092533481f013ab424", "sha256": "afdc9d49d7863e76736533559a886d82d82b146c1408538dcd52dc43e4bf94bf" }, "downloads": -1, "filename": "tstl-1.1.4-py2-none-any.whl", "has_sig": false, "md5_digest": "96189829ebf2bf092533481f013ab424", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 106376, "upload_time": "2017-10-09T21:18:11", "url": "https://files.pythonhosted.org/packages/4e/36/400e2d5db39c4cc864a956c564b454a24c97e3c090862168e1a12734998f/tstl-1.1.4-py2-none-any.whl" } ], "1.1.5": [ { "comment_text": "", "digests": { "md5": "8ad3af4e1ac643b79d8c360ce0212121", "sha256": "a5dd9960b4c47ae68b48690c2a12fb9dd3dcfec83f8bf80c7da6c77029d81531" }, "downloads": -1, "filename": "tstl-1.1.5-py2-none-any.whl", "has_sig": false, "md5_digest": "8ad3af4e1ac643b79d8c360ce0212121", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 109632, "upload_time": "2017-12-27T20:44:06", "url": "https://files.pythonhosted.org/packages/42/ff/a00537ace17c832cefae2b81577452974b1939aeb357103f97abff849fcf/tstl-1.1.5-py2-none-any.whl" } ], "1.1.6": [ { "comment_text": "", "digests": { "md5": "e78976e310ad87fa654e43c4368f7a22", "sha256": "09d6ec2e93de6490db47332285b372e7641e666bc8e14398aba3774db9eb4e48" }, "downloads": -1, "filename": "tstl-1.1.6-py2-none-any.whl", "has_sig": false, "md5_digest": "e78976e310ad87fa654e43c4368f7a22", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 109745, "upload_time": "2017-12-30T04:49:12", "url": "https://files.pythonhosted.org/packages/cb/92/8ae2848fd54620beee07d2a85bd51e4926424be869e3eec99e87f4fb8aa5/tstl-1.1.6-py2-none-any.whl" } ], "1.1.7": [ { "comment_text": "", "digests": { "md5": "5063a0d855eadb42204fc5938c64be57", "sha256": "31a69d14f310915b7a8822e3d2dccf9cac078c7211333e0571ce3fb2b8536300" }, "downloads": -1, "filename": "tstl-1.1.7-py2-none-any.whl", "has_sig": false, "md5_digest": "5063a0d855eadb42204fc5938c64be57", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 109823, "upload_time": "2017-12-30T23:03:39", "url": "https://files.pythonhosted.org/packages/e8/fb/ed9961ddfbf60dcce283afa6cd6757c59d5e471218c045bd25813a56a33c/tstl-1.1.7-py2-none-any.whl" } ], "1.1.8": [ { "comment_text": "", "digests": { "md5": "a9721c2464d32e5c542f34f062dcdf2a", "sha256": "cabaf62fd30c4462ea09bd0080abdd0f8f74017f67245317e35f80229c24f590" }, "downloads": -1, "filename": "tstl-1.1.8-py2-none-any.whl", "has_sig": false, "md5_digest": "a9721c2464d32e5c542f34f062dcdf2a", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 109928, "upload_time": "2018-01-01T21:28:36", "url": "https://files.pythonhosted.org/packages/bd/38/eaaeaa1dc898b848168cb558a4cbc6075136d70b09bb23df129b2db5b33c/tstl-1.1.8-py2-none-any.whl" } ], "1.1.9": [ { "comment_text": "", "digests": { "md5": "f6e80f7ec5c03e15794ef00d08d3078f", "sha256": "c3b6da68be83f247ea3b9ba629b040da83dd5d04b5da7a21a8ea66a5acfe2784" }, "downloads": -1, "filename": "tstl-1.1.9-py2-none-any.whl", "has_sig": false, "md5_digest": "f6e80f7ec5c03e15794ef00d08d3078f", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 111064, "upload_time": "2018-03-02T19:52:52", "url": "https://files.pythonhosted.org/packages/9d/8d/ba5c80f64c2d75243b345e7a7b43938c09bae6cd55acbaf0fab125f0e067/tstl-1.1.9-py2-none-any.whl" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "01702f65803dad4b3731ae02e87cdf53", "sha256": "3197057dede35f8f2c7b1ae94f76c284273964fd9cef190fbe21f1018a945e3e" }, "downloads": -1, "filename": "tstl-1.2.1-py2-none-any.whl", "has_sig": false, "md5_digest": "01702f65803dad4b3731ae02e87cdf53", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 112160, "upload_time": "2018-03-23T06:42:07", "url": "https://files.pythonhosted.org/packages/01/16/ecea4a606fb16733d726fd3fa6ede24c9edc3a32ec3fcbbdf8720634ebdb/tstl-1.2.1-py2-none-any.whl" } ], "1.2.10": [ { "comment_text": "", "digests": { "md5": "f8c58a389f5e8cd4cfb97e1ce3401278", "sha256": "a5cb20ba04f97f8fcc51ffd8e8ad3f41c5ae4aca3e187788d457bb7fec547fdf" }, "downloads": -1, "filename": "tstl-1.2.10-py2-none-any.whl", "has_sig": false, "md5_digest": "f8c58a389f5e8cd4cfb97e1ce3401278", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 124266, "upload_time": "2018-04-09T06:41:25", "url": "https://files.pythonhosted.org/packages/7e/e4/e925ae1d50d56697391e415082248ac532adada9449e6be008b44c20a509/tstl-1.2.10-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e91989add8280a1132f5a335427afc66", "sha256": "3207cb5876075a198711cecff117332087b990438f1cbc4256126be7967297be" }, "downloads": -1, "filename": "tstl-1.2.10-py3-none-any.whl", "has_sig": false, "md5_digest": "e91989add8280a1132f5a335427afc66", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 124234, "upload_time": "2018-04-09T06:41:50", "url": "https://files.pythonhosted.org/packages/34/38/77c9fc2faab466ca143095d59d4af23a88fa665d08fd61d07d7e77c4716b/tstl-1.2.10-py3-none-any.whl" } ], "1.2.11": [ { "comment_text": "", "digests": { "md5": "770820729ec1a00a065b008b9cbc1639", "sha256": "9a0562ab7014db4b80aab43db243ca79defdd6505c6707e27497bd16a627b3dd" }, "downloads": -1, "filename": "tstl-1.2.11-py2-none-any.whl", "has_sig": false, "md5_digest": "770820729ec1a00a065b008b9cbc1639", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 126277, "upload_time": "2018-04-09T19:59:23", "url": "https://files.pythonhosted.org/packages/90/0a/d983eeb0a0a910faecd30c5f3b28f4c6de809764f781c2ed1c8a3afb6604/tstl-1.2.11-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "645a6a6f0a4435722d7aa3e4cb2cc8f5", "sha256": "c24e679e3fc85cd57461e622585b806b6b571f0b90adf55332382e5613aaee01" }, "downloads": -1, "filename": "tstl-1.2.11-py3-none-any.whl", "has_sig": false, "md5_digest": "645a6a6f0a4435722d7aa3e4cb2cc8f5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 126236, "upload_time": "2018-04-09T19:59:52", "url": "https://files.pythonhosted.org/packages/81/bc/2a3e7f4e3fa624eb5699fe63b5cba7d2daef2ccd8e6dad064b85028cbe7e/tstl-1.2.11-py3-none-any.whl" } ], "1.2.12": [ { "comment_text": "", "digests": { "md5": "cb2008e8725f9c2c58167c93df132645", "sha256": "bda83877f1d08e73a8d1800c7fcaa74cf417ff155980ecb4a2101a56c22fe0cc" }, "downloads": -1, "filename": "tstl-1.2.12-py2-none-any.whl", "has_sig": false, "md5_digest": "cb2008e8725f9c2c58167c93df132645", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 128721, "upload_time": "2018-04-17T21:54:05", "url": "https://files.pythonhosted.org/packages/78/74/d99de6ffee6eb73fe0eeaf8c39570258b978daba681e0a0ca9ca9cee7212/tstl-1.2.12-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c70fa614ea319c23796551f0292c96ab", "sha256": "306d96dee3ceb872da52afb1a7641ce749b41a1412c5be14a579f02a3de9621f" }, "downloads": -1, "filename": "tstl-1.2.12-py3-none-any.whl", "has_sig": false, "md5_digest": "c70fa614ea319c23796551f0292c96ab", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 128682, "upload_time": "2018-04-17T21:54:24", "url": "https://files.pythonhosted.org/packages/61/9f/616ec8055ca6a3cfcf5e4eb15e004bce11f7be9251c1e375a1bd47ff0c6b/tstl-1.2.12-py3-none-any.whl" } ], "1.2.13": [ { "comment_text": "", "digests": { "md5": "c5d092cbd41c61a27b6a598ec77828f1", "sha256": "c51b8a17fcf05966f88d0678326f083a07b1755dc1ff8eada453469fd2fb5fef" }, "downloads": -1, "filename": "tstl-1.2.13-py2-none-any.whl", "has_sig": false, "md5_digest": "c5d092cbd41c61a27b6a598ec77828f1", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 130943, "upload_time": "2018-04-18T22:31:37", "url": "https://files.pythonhosted.org/packages/d0/a7/bbdd50ff6bb9913dca08a7b9ed0ab71e91dee89bc26560112c2e8f239f9b/tstl-1.2.13-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "64e6dc269a56d4b7b5d5d5cd378579ad", "sha256": "2776f1ac611928c54668b4bad8e7ec964e9aef46f4232e9409489a89dc79fea3" }, "downloads": -1, "filename": "tstl-1.2.13-py3-none-any.whl", "has_sig": false, "md5_digest": "64e6dc269a56d4b7b5d5d5cd378579ad", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 130910, "upload_time": "2018-04-18T22:32:23", "url": "https://files.pythonhosted.org/packages/45/08/5f417ef2f16fe4d909e50b18de8bb87c4cee69a00d8c1ba4e528ae0d0283/tstl-1.2.13-py3-none-any.whl" } ], "1.2.14": [ { "comment_text": "", "digests": { "md5": "c023afdc98055e70a5e821ad931fb43b", "sha256": "d3159e4b2d89be3fbebe1373c25ddb6f08965d8b8a53ea1a8fd4aa83674c4063" }, "downloads": -1, "filename": "tstl-1.2.14-py2-none-any.whl", "has_sig": false, "md5_digest": "c023afdc98055e70a5e821ad931fb43b", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 131823, "upload_time": "2018-04-24T21:01:04", "url": "https://files.pythonhosted.org/packages/0b/9f/ee9375dbca40eafd01dcd049c28b6cc3f580257877a4a074fa202bfac8d0/tstl-1.2.14-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "58ff2fbc201acb16e71d72fb9b2ce2fb", "sha256": "e772c676df1e5d63d6f13bd0b0d6da6d81cd1025434f703949d112ad4c52ac2b" }, "downloads": -1, "filename": "tstl-1.2.14-py3-none-any.whl", "has_sig": false, "md5_digest": "58ff2fbc201acb16e71d72fb9b2ce2fb", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 131788, "upload_time": "2018-04-24T21:01:28", "url": "https://files.pythonhosted.org/packages/c6/64/b009723077361eba5ef778636a90481888a0f51f00ff7f1e8f7fdde29f0b/tstl-1.2.14-py3-none-any.whl" } ], "1.2.15": [ { "comment_text": "", "digests": { "md5": "e7933bc27c7912a3f77ded56b4b73a8f", "sha256": "5345146511b27836ad02c31f36cbbe47e53842fb70b1e11188f1aa08fdb4e091" }, "downloads": -1, "filename": "tstl-1.2.15-py2-none-any.whl", "has_sig": false, "md5_digest": "e7933bc27c7912a3f77ded56b4b73a8f", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 131820, "upload_time": "2018-04-25T23:14:02", "url": "https://files.pythonhosted.org/packages/0b/86/be42d9c7300f0af75c8bee8c94d0b59fe7e3f0a52491ecada72ab06d3886/tstl-1.2.15-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "80e9f2083087a74a86313d9eccd070cd", "sha256": "9484d5c4f246bae363f78568ccdadabf21dbc4afdfb9b0eee64c053ddfe9882d" }, "downloads": -1, "filename": "tstl-1.2.15-py3-none-any.whl", "has_sig": false, "md5_digest": "80e9f2083087a74a86313d9eccd070cd", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 131787, "upload_time": "2018-04-25T23:14:30", "url": "https://files.pythonhosted.org/packages/ed/92/4bc1f3c4cdd4714a5ed73d536a2f8c76157ed4a0245bf2033fbf80c3b74b/tstl-1.2.15-py3-none-any.whl" } ], "1.2.16": [ { "comment_text": "", "digests": { "md5": "53c14fd43f57c9f85ce83999ce798b22", "sha256": "877ed999a1c466fbcd72f5f7cb1212bd8473681f63e5aa2f88d5e14e5e9cea79" }, "downloads": -1, "filename": "tstl-1.2.16-py2-none-any.whl", "has_sig": false, "md5_digest": "53c14fd43f57c9f85ce83999ce798b22", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 132015, "upload_time": "2018-04-26T18:46:52", "url": "https://files.pythonhosted.org/packages/dd/ad/8c47b737f45a1416a19f404fc56506ec21ae1c9d25d2a6ee0404d3b87655/tstl-1.2.16-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "428403fd091e0aa74cc1e8128d411a66", "sha256": "0b5f69c9ad23553c99b9908a9a47b9367049d8827cf30afc610cec589559632f" }, "downloads": -1, "filename": "tstl-1.2.16-py3-none-any.whl", "has_sig": false, "md5_digest": "428403fd091e0aa74cc1e8128d411a66", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 131984, "upload_time": "2018-04-26T18:47:24", "url": "https://files.pythonhosted.org/packages/64/cf/c1089e17d1cfb6d752127cfd513cceada8f4eed0f7c4fe4abc303e9b0326/tstl-1.2.16-py3-none-any.whl" } ], "1.2.17": [ { "comment_text": "", "digests": { "md5": "0d2203a47f4da29a2a0db2b226d8d409", "sha256": "89c211ae3f02dd4ed51fba787b721d98c9554bb0c6d5a18c975807c7ab2ce361" }, "downloads": -1, "filename": "tstl-1.2.17-py2-none-any.whl", "has_sig": false, "md5_digest": "0d2203a47f4da29a2a0db2b226d8d409", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 130790, "upload_time": "2018-04-27T17:39:29", "url": "https://files.pythonhosted.org/packages/51/e5/7fd521948029c643e0ce702e8b6c3ba7dda2cfe65f2658b973b742dc80a6/tstl-1.2.17-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "77bd804e21f60255a538f675950fc40d", "sha256": "62b5aa6aba6967e5c381eafd7897f0830023eed9b7bcde072f979dd6748b49e0" }, "downloads": -1, "filename": "tstl-1.2.17-py3-none-any.whl", "has_sig": false, "md5_digest": "77bd804e21f60255a538f675950fc40d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 130752, "upload_time": "2018-04-27T17:39:55", "url": "https://files.pythonhosted.org/packages/4a/d5/8509d57ed07ef6f065b469b435054a4017982766d6f6d0f1cce8488795e4/tstl-1.2.17-py3-none-any.whl" } ], "1.2.18": [ { "comment_text": "", "digests": { "md5": "e5ff4761b4b8f650a2266933823e696e", "sha256": "1b17de31e867ba686a98c09579087da1f34a4fc40c40c7181f5c349fa6f3f486" }, "downloads": -1, "filename": "tstl-1.2.18-py2-none-any.whl", "has_sig": false, "md5_digest": "e5ff4761b4b8f650a2266933823e696e", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 131013, "upload_time": "2018-04-30T22:54:47", "url": "https://files.pythonhosted.org/packages/8e/3f/6d210de501bb3c9d191a6189d0541fdee69d9b4fccf62a1e5fd6bd1c3666/tstl-1.2.18-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1b42fbc075b1b1261ec341329e98ab93", "sha256": "068dd3b4afa8c53b8bb47a85168fb9afdcc3af4205d27f5eda07a06d16fd260c" }, "downloads": -1, "filename": "tstl-1.2.18-py3-none-any.whl", "has_sig": false, "md5_digest": "1b42fbc075b1b1261ec341329e98ab93", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 130978, "upload_time": "2018-04-30T22:55:08", "url": "https://files.pythonhosted.org/packages/8b/b2/50e03d2f703f35708bb321359d036288c261eaf9747f0dac844458ec2b28/tstl-1.2.18-py3-none-any.whl" } ], "1.2.19": [ { "comment_text": "", "digests": { "md5": "c3eefb199c1de9d08fae949b73627b3a", "sha256": "f84c75498aab1c09a0a1965aebb1c4b2a59d6e171ed3aa2a9e451794d4dbd618" }, "downloads": -1, "filename": "tstl-1.2.19-py2-none-any.whl", "has_sig": false, "md5_digest": "c3eefb199c1de9d08fae949b73627b3a", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 133556, "upload_time": "2018-05-03T22:31:22", "url": "https://files.pythonhosted.org/packages/b0/f3/2ba35bef6f7c59cc394d09a1deed1d103b69e437ed9597da07987f7b302d/tstl-1.2.19-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ac7844eaff2f55e523c9c0a5a1131397", "sha256": "bc54840fb20f468ca11219b1e2c2742d3fdfe179d4bc72b0cf978fbeee52812c" }, "downloads": -1, "filename": "tstl-1.2.19-py3-none-any.whl", "has_sig": false, "md5_digest": "ac7844eaff2f55e523c9c0a5a1131397", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 133525, "upload_time": "2018-05-03T22:31:44", "url": "https://files.pythonhosted.org/packages/ea/05/a68063412156bf75be9c4161699a603ca163f305eb149a776456522cf26f/tstl-1.2.19-py3-none-any.whl" } ], "1.2.2": [ { "comment_text": "", "digests": { "md5": "c0eeb2118214750db2a543ea48334fee", "sha256": "c8bab18419ff634e851a8848f2afb5c3edac856e8997ddea25906ed8d492829e" }, "downloads": -1, "filename": "tstl-1.2.2-py2-none-any.whl", "has_sig": false, "md5_digest": "c0eeb2118214750db2a543ea48334fee", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 113204, "upload_time": "2018-03-23T21:49:59", "url": "https://files.pythonhosted.org/packages/8d/8a/aad989cb32dce43d51d62b1c06676501d6265aa0ee4a07551ba22af5c135/tstl-1.2.2-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4b9fa7afb4f3d7faeb494263446d0490", "sha256": "6980273fc95d6fd234678ad77aacb8eaa871ed2956f221495ab733c3b7d3f796" }, "downloads": -1, "filename": "tstl-1.2.2-py3-none-any.whl", "has_sig": false, "md5_digest": "4b9fa7afb4f3d7faeb494263446d0490", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 113167, "upload_time": "2018-03-28T16:07:13", "url": "https://files.pythonhosted.org/packages/e6/44/a5669a20570605837553349485d4a03c02917ff8c12610ee7e0a1ef29fdf/tstl-1.2.2-py3-none-any.whl" } ], "1.2.20": [ { "comment_text": "", "digests": { "md5": "f6290a035885c1307db17b0aa517a9d6", "sha256": "7eea299d728d382c4619a8cafd2c32c237fc51ecc593df9c0f818213ea04d2bf" }, "downloads": -1, "filename": "tstl-1.2.20-py2-none-any.whl", "has_sig": false, "md5_digest": "f6290a035885c1307db17b0aa517a9d6", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 133629, "upload_time": "2018-05-04T07:00:08", "url": "https://files.pythonhosted.org/packages/de/67/26c5b569d9e8ed1e52157af188bbfe52c801fe521d608866210a01ada413/tstl-1.2.20-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5b7fc7732fc88a778f44816351777ae1", "sha256": "8ab5e751325577d7eff0e90e811d99f239fe7225f42072ada324b3de1078b339" }, "downloads": -1, "filename": "tstl-1.2.20-py3-none-any.whl", "has_sig": false, "md5_digest": "5b7fc7732fc88a778f44816351777ae1", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 133597, "upload_time": "2018-05-04T07:00:28", "url": "https://files.pythonhosted.org/packages/35/0b/a2438fd048500c3593f77b899c743c0e6adb9e1fb6964dc6c5a7b9072cfc/tstl-1.2.20-py3-none-any.whl" } ], "1.2.21": [ { "comment_text": "", "digests": { "md5": "ab710f9b85a34005c23378c9cd6d6ed3", "sha256": "2adc48ea7a197c117d14c0305efa3215d62f3ff6ab70be55657c85e77ece6270" }, "downloads": -1, "filename": "tstl-1.2.21-py2-none-any.whl", "has_sig": false, "md5_digest": "ab710f9b85a34005c23378c9cd6d6ed3", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 136758, "upload_time": "2018-05-06T01:41:05", "url": "https://files.pythonhosted.org/packages/99/e8/d615b98a42793dda8a3b15498fe2e82d5bd226df4dcb80c0f308181c169f/tstl-1.2.21-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "8d9ba62841e37c6d347bd3489ec91763", "sha256": "793d0be968fcfe0576184ec0668de8374152168353229983e3a3c2d7c1a3de8a" }, "downloads": -1, "filename": "tstl-1.2.21-py3-none-any.whl", "has_sig": false, "md5_digest": "8d9ba62841e37c6d347bd3489ec91763", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 136722, "upload_time": "2018-05-06T01:41:57", "url": "https://files.pythonhosted.org/packages/27/32/85450ca09db5917188ede1b9b0adbb2a4dad8bb830173f0f8ace1762eb80/tstl-1.2.21-py3-none-any.whl" } ], "1.2.22": [ { "comment_text": "", "digests": { "md5": "6a555eee169e57d1ec9b0001bdc7f6f0", "sha256": "4aabd8804257934fc6e0e2029fa4dce2c4c9adb7b018bf8ff954648c0b5831c9" }, "downloads": -1, "filename": "tstl-1.2.22-py2-none-any.whl", "has_sig": false, "md5_digest": "6a555eee169e57d1ec9b0001bdc7f6f0", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 216450, "upload_time": "2018-05-06T18:42:53", "url": "https://files.pythonhosted.org/packages/f8/71/7602c54f0aeba266e8d31abbaac38c6c32ad8b2b704acddd44692921afc6/tstl-1.2.22-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1b181bf714c0a048f79cd3f7297ffaf7", "sha256": "1754730d962682f2998c5771083cb4a22376956ea96ff4d9584cd27150bea29b" }, "downloads": -1, "filename": "tstl-1.2.22-py3-none-any.whl", "has_sig": false, "md5_digest": "1b181bf714c0a048f79cd3f7297ffaf7", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 216416, "upload_time": "2018-05-06T18:43:32", "url": "https://files.pythonhosted.org/packages/f9/fe/54a37eb124c77c789625e273e501124dc84364d41b9653bca439f3d77b56/tstl-1.2.22-py3-none-any.whl" } ], "1.2.23": [ { "comment_text": "", "digests": { "md5": "fba59c05c4e10f7a48ce5b28e5f7cb1e", "sha256": "52649affaf1bf974dfcd99652acbb0d1e53af508456ddd8ee29645012359a4c1" }, "downloads": -1, "filename": "tstl-1.2.23-py2-none-any.whl", "has_sig": false, "md5_digest": "fba59c05c4e10f7a48ce5b28e5f7cb1e", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 237016, "upload_time": "2018-05-11T21:00:05", "url": "https://files.pythonhosted.org/packages/db/89/568818e093962166b3ee6f82f7366a13665ac4733f7dbb41cc8cc0611a9a/tstl-1.2.23-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d25bb147e93e939a232eb7a4cc988e13", "sha256": "28ed867222e3c7605f2f2e85b2fc0b01cdb9dec2d34289901d1810314d7d8aba" }, "downloads": -1, "filename": "tstl-1.2.23-py3-none-any.whl", "has_sig": false, "md5_digest": "d25bb147e93e939a232eb7a4cc988e13", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 236981, "upload_time": "2018-05-11T21:00:26", "url": "https://files.pythonhosted.org/packages/38/94/3912949e81f9de3d9977075372e95c1dab879c8bffd58b66fa4dd2200096/tstl-1.2.23-py3-none-any.whl" } ], "1.2.24": [ { "comment_text": "", "digests": { "md5": "546b69f0ad12821e34af2c3d49940f88", "sha256": "88a96a1e9b7bb22d7cbee46591ad5157eb2d1c58d171dfc1314fb39a00ac2f05" }, "downloads": -1, "filename": "tstl-1.2.24-py2-none-any.whl", "has_sig": false, "md5_digest": "546b69f0ad12821e34af2c3d49940f88", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 238167, "upload_time": "2018-05-18T18:13:03", "url": "https://files.pythonhosted.org/packages/03/e7/5cc341b4698e37ab11139398e5570729796eed2a4b27c9ca41744cc52171/tstl-1.2.24-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6dc328f9b3a81f95a53761fd1becc385", "sha256": "2562d3ec1a9820caa67c093614f31edbcdd484055b0211a08e122de65688ee6e" }, "downloads": -1, "filename": "tstl-1.2.24-py3-none-any.whl", "has_sig": false, "md5_digest": "6dc328f9b3a81f95a53761fd1becc385", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 238132, "upload_time": "2018-05-18T18:13:22", "url": "https://files.pythonhosted.org/packages/cf/4a/fc1f5636480552a600884bb20df464698a0ca7f3d41228475bda64e33577/tstl-1.2.24-py3-none-any.whl" } ], "1.2.25": [ { "comment_text": "", "digests": { "md5": "935ce50f5b2dbb8ef0deb3fac38fae9f", "sha256": "c47ed8a37a21a20c8dec05d4041beeaf15b52ad24606ee28eb285b62656facc2" }, "downloads": -1, "filename": "tstl-1.2.25-py2-none-any.whl", "has_sig": false, "md5_digest": "935ce50f5b2dbb8ef0deb3fac38fae9f", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 228480, "upload_time": "2018-05-26T18:39:11", "url": "https://files.pythonhosted.org/packages/3b/c1/521e2b02aa80b1dde6a3a236d283858e54ed84996224ece446f60580cdc1/tstl-1.2.25-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "13d885f637af23c084848e982cc3159d", "sha256": "653c1483fc07a77bbe1df0f08d7fb95325404d532cf748ddac40a34052291f36" }, "downloads": -1, "filename": "tstl-1.2.25-py3-none-any.whl", "has_sig": false, "md5_digest": "13d885f637af23c084848e982cc3159d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 228480, "upload_time": "2018-05-26T18:39:35", "url": "https://files.pythonhosted.org/packages/80/5a/9e41d822cb7918334ef343c2a113b4dde884d83c3c1bb6f63e7d78048e0f/tstl-1.2.25-py3-none-any.whl" } ], "1.2.26": [ { "comment_text": "", "digests": { "md5": "51d14793f5313933a3b2a7b4d48bd1a2", "sha256": "c312360907f122130d1bb4a94786ecf7f72834bfb24cd18d54947d96a4f5bb10" }, "downloads": -1, "filename": "tstl-1.2.26-py2-none-any.whl", "has_sig": false, "md5_digest": "51d14793f5313933a3b2a7b4d48bd1a2", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 234938, "upload_time": "2019-01-17T20:45:19", "url": "https://files.pythonhosted.org/packages/9f/34/c81ac0ec4014d3563f02320f8b6d9f9f7871528a6f57bcd4eba02b79ba73/tstl-1.2.26-py2-none-any.whl" } ], "1.2.27": [ { "comment_text": "", "digests": { "md5": "dbadc5e87bea5ed687147d5df68e3626", "sha256": "6503535d58b82f0078e4a099512eeb06858cd6ea52d2bf838c161ad67e3a50aa" }, "downloads": -1, "filename": "tstl-1.2.27-py2-none-any.whl", "has_sig": false, "md5_digest": "dbadc5e87bea5ed687147d5df68e3626", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 234938, "upload_time": "2019-01-18T02:40:46", "url": "https://files.pythonhosted.org/packages/05/96/222627df4df77b271e7f2d516e9294127b19843a27b825e3b2cac4bb3e46/tstl-1.2.27-py2-none-any.whl" } ], "1.2.28": [ { "comment_text": "", "digests": { "md5": "45f427a7af18d0c19422f96ded8acf71", "sha256": "76b17c37d982c8725b97c3efc07a19c011c1eb98eb25447bd92d7b8d8ef0a177" }, "downloads": -1, "filename": "tstl-1.2.28-py2-none-any.whl", "has_sig": false, "md5_digest": "45f427a7af18d0c19422f96ded8acf71", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 107496, "upload_time": "2019-02-25T19:07:25", "url": "https://files.pythonhosted.org/packages/5a/9a/7b9625cd7e392af6aa42eaab4b650273e82a4fd40e6d8e654c8cb1850c51/tstl-1.2.28-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "88bf3e672ca1a63abdd825bed99abe16", "sha256": "f7561d08cc436fa17f7279c0cdf2403d7d898e35ce95488649137c42404c082f" }, "downloads": -1, "filename": "tstl-1.2.28-py3-none-any.whl", "has_sig": false, "md5_digest": "88bf3e672ca1a63abdd825bed99abe16", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 2401396, "upload_time": "2019-06-03T16:59:46", "url": "https://files.pythonhosted.org/packages/7e/59/b016c5920aad3f2d383c40b290e0a5b978d0da9bab5b9c064293b8176d8f/tstl-1.2.28-py3-none-any.whl" } ], "1.2.3": [ { "comment_text": "", "digests": { "md5": "3489f80235f3e3f9c13dda31df259c6c", "sha256": "f43a77fac986cc96ea55c5087b6ce0305ad1adf08311f3233696f182c19f5adb" }, "downloads": -1, "filename": "tstl-1.2.3-py2-none-any.whl", "has_sig": false, "md5_digest": "3489f80235f3e3f9c13dda31df259c6c", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 113962, "upload_time": "2018-03-28T22:49:19", "url": "https://files.pythonhosted.org/packages/7a/89/7be1cf03180313b32132452a93abfbf81819b8f55938f5af3b3a6e8436c7/tstl-1.2.3-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "938d9728faf4149007ee61541aa27cc0", "sha256": "cd9196a42fc6ec640442a19891a2353ea8ba9df80168a305a9f606eb9ec005e5" }, "downloads": -1, "filename": "tstl-1.2.3-py3-none-any.whl", "has_sig": false, "md5_digest": "938d9728faf4149007ee61541aa27cc0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 113924, "upload_time": "2018-03-28T22:49:57", "url": "https://files.pythonhosted.org/packages/0d/6a/b00ce032ecfee667620363e5f4c55bfabe9749abc245809f997892313ebe/tstl-1.2.3-py3-none-any.whl" } ], "1.2.4": [ { "comment_text": "", "digests": { "md5": "900cb442505bfcf2aa954552eddb13a8", "sha256": "891c4495c3c3780a663605b16b84a18d1236a447895e13b1e8750ece66acb637" }, "downloads": -1, "filename": "tstl-1.2.4-py2-none-any.whl", "has_sig": false, "md5_digest": "900cb442505bfcf2aa954552eddb13a8", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 116314, "upload_time": "2018-03-29T20:44:42", "url": "https://files.pythonhosted.org/packages/4f/72/28ce38792e093720a9681645f5a56d92636f646c69ad8d6541d351da7421/tstl-1.2.4-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2ced7afa2510c7fd7360c149083547b0", "sha256": "48882dfac328ef8c45aa4f40ff1165f641aea6bb1c475e0f37714ff230aeea18" }, "downloads": -1, "filename": "tstl-1.2.4-py3-none-any.whl", "has_sig": false, "md5_digest": "2ced7afa2510c7fd7360c149083547b0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 116277, "upload_time": "2018-03-29T20:45:13", "url": "https://files.pythonhosted.org/packages/b0/38/fc6740ad04342a1a7531e98423fa9978b76c1c922111507a71dba98e499e/tstl-1.2.4-py3-none-any.whl" } ], "1.2.5": [ { "comment_text": "", "digests": { "md5": "ef3a5e77a1a33a3b14e66d6ce21a2b37", "sha256": "74e32354db6e5bcc728036e38b43a27798451476bd8e1bf9dc87dab69afd0839" }, "downloads": -1, "filename": "tstl-1.2.5-py2-none-any.whl", "has_sig": false, "md5_digest": "ef3a5e77a1a33a3b14e66d6ce21a2b37", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 116335, "upload_time": "2018-04-01T06:46:27", "url": "https://files.pythonhosted.org/packages/65/c6/ae03fdaf6fa80c0535c8d6788586fd4bb3f2b35532873a7b55a81fccb3f7/tstl-1.2.5-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6ab58ce591c5eeb37e529a25e0defd83", "sha256": "42e74a843c00a035b2b9a47cc1572d8018456436310c2f230e0cf98f1dcc2966" }, "downloads": -1, "filename": "tstl-1.2.5-py3-none-any.whl", "has_sig": false, "md5_digest": "6ab58ce591c5eeb37e529a25e0defd83", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 116301, "upload_time": "2018-04-01T06:48:08", "url": "https://files.pythonhosted.org/packages/95/f4/6dbe98421ea9f176472981f4078d3ec7a0e20dcbfffe0ec4ab0d15e9ef2a/tstl-1.2.5-py3-none-any.whl" } ], "1.2.6": [ { "comment_text": "", "digests": { "md5": "dd73381e1924f27a4dfd10e8cbf60d4f", "sha256": "e6c83448f1eb739f9b7d7c51594c2b21a273aeda588958bf2cdf81035fca8b91" }, "downloads": -1, "filename": "tstl-1.2.6-py2-none-any.whl", "has_sig": false, "md5_digest": "dd73381e1924f27a4dfd10e8cbf60d4f", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 116790, "upload_time": "2018-04-03T20:54:12", "url": "https://files.pythonhosted.org/packages/6a/4f/04d26bbcaaf1ac3569820b503c53258eaf5e2726126038eb4342a84c6bc4/tstl-1.2.6-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0dfef5e456e45e03d0d4ca6fce196a92", "sha256": "77e126893b6d95c90e40d9006b3665950cfcf7166b189c78fd7388f28f07ac92" }, "downloads": -1, "filename": "tstl-1.2.6-py3-none-any.whl", "has_sig": false, "md5_digest": "0dfef5e456e45e03d0d4ca6fce196a92", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 116758, "upload_time": "2018-04-03T20:54:37", "url": "https://files.pythonhosted.org/packages/b7/2d/652d2b18dd1e8fe5c9300418d11a876577ba78129f99027855677ba6e94a/tstl-1.2.6-py3-none-any.whl" } ], "1.2.7": [ { "comment_text": "", "digests": { "md5": "cd85e4b010d7b6ec8a6c6d7e99238582", "sha256": "61b0b777495cb4e27913112b55844707f02c670cb5654d7a96d6d17a9b196fb8" }, "downloads": -1, "filename": "tstl-1.2.7-py2-none-any.whl", "has_sig": false, "md5_digest": "cd85e4b010d7b6ec8a6c6d7e99238582", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 117612, "upload_time": "2018-04-07T16:55:19", "url": "https://files.pythonhosted.org/packages/d2/68/c28d0276ae947540f173e2ec306997d306c13f3f88225f51e5784d4d3d8b/tstl-1.2.7-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1e41182808d9230ea38e7e5c07448171", "sha256": "2058d0e7328c2bd309d991f611fa5fbc5ff89afd067380bc237a2ce43dd1bd07" }, "downloads": -1, "filename": "tstl-1.2.7-py3-none-any.whl", "has_sig": false, "md5_digest": "1e41182808d9230ea38e7e5c07448171", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 117577, "upload_time": "2018-04-07T16:55:47", "url": "https://files.pythonhosted.org/packages/ef/d5/e2ebf02ebde5ddd8f99e35e62a72e030862990cd0c2f5fee0e312b29151f/tstl-1.2.7-py3-none-any.whl" } ], "1.2.8": [ { "comment_text": "", "digests": { "md5": "fccb45388d71c38559eb29c8c4210f32", "sha256": "734f121ec0c89c47159653c2d38ccde6cd2322e21aebc14f428b565dc12ea927" }, "downloads": -1, "filename": "tstl-1.2.8-py2-none-any.whl", "has_sig": false, "md5_digest": "fccb45388d71c38559eb29c8c4210f32", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 119136, "upload_time": "2018-04-08T04:49:13", "url": "https://files.pythonhosted.org/packages/e0/43/56cf02eeb6a3c0669485b1816993649dcbfcbfb156009252b1c591d72562/tstl-1.2.8-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "cca9281901be35a6766611554d97d4c4", "sha256": "79dafd0615c4d1a1b3a186c1c7a8033e5acad42078763dffac63a707c0dc6394" }, "downloads": -1, "filename": "tstl-1.2.8-py3-none-any.whl", "has_sig": false, "md5_digest": "cca9281901be35a6766611554d97d4c4", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 119102, "upload_time": "2018-04-08T04:49:35", "url": "https://files.pythonhosted.org/packages/ac/ed/8f168d130b356851d33a838fe4f8e9abe1c51d57e918f911b0c76f77ac73/tstl-1.2.8-py3-none-any.whl" } ], "1.2.9": [ { "comment_text": "", "digests": { "md5": "595277729c659c2a7c518f19c81fc3a4", "sha256": "c0152fbfd33dbe7281d4ce96cbb04fb3a638819a6661146c8314deb30a0a2baf" }, "downloads": -1, "filename": "tstl-1.2.9-py2-none-any.whl", "has_sig": false, "md5_digest": "595277729c659c2a7c518f19c81fc3a4", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 123724, "upload_time": "2018-04-08T18:25:15", "url": "https://files.pythonhosted.org/packages/af/a4/742e5ebcf8f9f033068ef4fcb3006df4387b78843b328aeab2088ce885fe/tstl-1.2.9-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9a3ee45bbcd3c074fbee6011b5aab9aa", "sha256": "482653ea606e60390115a33512913a6cf9ba38c899f9c0a20047ed70996a41e2" }, "downloads": -1, "filename": "tstl-1.2.9-py3-none-any.whl", "has_sig": false, "md5_digest": "9a3ee45bbcd3c074fbee6011b5aab9aa", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 123685, "upload_time": "2018-04-08T18:25:47", "url": "https://files.pythonhosted.org/packages/cb/10/54b60d74532b3ae2ed811cac36aadfc9de45dadb946bdcc4bb991e7c4d19/tstl-1.2.9-py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "45f427a7af18d0c19422f96ded8acf71", "sha256": "76b17c37d982c8725b97c3efc07a19c011c1eb98eb25447bd92d7b8d8ef0a177" }, "downloads": -1, "filename": "tstl-1.2.28-py2-none-any.whl", "has_sig": false, "md5_digest": "45f427a7af18d0c19422f96ded8acf71", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 107496, "upload_time": "2019-02-25T19:07:25", "url": "https://files.pythonhosted.org/packages/5a/9a/7b9625cd7e392af6aa42eaab4b650273e82a4fd40e6d8e654c8cb1850c51/tstl-1.2.28-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "88bf3e672ca1a63abdd825bed99abe16", "sha256": "f7561d08cc436fa17f7279c0cdf2403d7d898e35ce95488649137c42404c082f" }, "downloads": -1, "filename": "tstl-1.2.28-py3-none-any.whl", "has_sig": false, "md5_digest": "88bf3e672ca1a63abdd825bed99abe16", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 2401396, "upload_time": "2019-06-03T16:59:46", "url": "https://files.pythonhosted.org/packages/7e/59/b016c5920aad3f2d383c40b290e0a5b978d0da9bab5b9c064293b8176d8f/tstl-1.2.28-py3-none-any.whl" } ] }