internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: DataBiosphere/toil

Issue:
'make docs' falls back to an installed toil rather than the source
_From @hannes-ucsc on October 22, 2015 23:1_

Benedict ran `cd docs && make html` without having run `make develop` first. He also had installed an older version of toil. Sphinx then fell back to using that older version to generate the docs. This should not happen. The build should either produce an error or it should hardcode the path to the src directory so it doesn't fall back to an external installation.

_Copied from original issue: BD2KGenomics/cgl-docker-lib#46_

'make docs' falls back to an installed toil rather than the source
_From @hannes-ucsc on October 22, 2015 23:1_

Benedict ran `cd docs && make html` without having run `make develop` first. He also had installed an older version of toil. Sphinx then fell back to using that older version to generate the docs. This should not happen. The build should either produce an error or it should hardcode the path to the src directory so it doesn't fall back to an external installation.

_Copied from original issue: BD2KGenomics/cgl-docker-lib#46_



Discussion:

Resolving patch:
diff --git a/docs/conf.py b/docs/conf.py
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 # Toil documentation build configuration file, created by
 # sphinx-quickstart on Tue Aug 25 12:37:16 2015.
@@ -16,13 +15,26 @@
 import os
 import inspect
 import re
-import shlex
-from toil.version import version as toilVersion
 
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
-sys.path.insert(0, os.path.abspath('../src/toil/'))
+sys.path.insert(0, os.path.abspath('../src'))
+
+import toil.version
+
+
+def real_dir_name(p, n=1):
+    p = os.path.realpath(p)
+    for i in range(n):
+        p = os.path.dirname(p)
+    print p
+    return p
+
+
+assert real_dir_name(__file__, 2) == real_dir_name(toil.version.__file__, 3), \
+    "Another Toil installation seems to have precedence over this working directory."
+toilVersion = toil.version.version
 
 # -- General configuration ------------------------------------------------
 


Test patch:
Repository: DataBiosphere/toil

Issue:
cwltoil raises schema-related ValidationException
Tests started failing just now.

http://jenkins.cgcloud.info/job/toil-pull-requests/lastCompletedBuild/testReport/src.toil.test.cwl.cwlTest/CWLTest/test_run_revsort/

It would be nice if the schema didn't change underneath a particular cwl version. IOW, if I pin my cwl version, the schema used by it should never change. But that's just my hunch. I don't understand the intricacies involved here.

@tetron would you have time to take a look?



Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -39,7 +39,7 @@
         'encryption': [
             'pynacl==0.3.0'],
         'cwl': [
-            'cwltool==1.0.20151122025918']},
+            'cwltool==1.0.20151211141743']},
     package_dir={'': 'src'},
     packages=find_packages('src', exclude=['*.test']),
     entry_points={
diff --git a/src/toil/cwl/cwltoil.py b/src/toil/cwl/cwltoil.py
--- a/src/toil/cwl/cwltoil.py
+++ b/src/toil/cwl/cwltoil.py
@@ -412,7 +412,8 @@ def main(args=None):
 
     job, _ = loader.resolve_ref(uri)
 
-    t = cwltool.main.load_tool(options.cwltool, False, False, cwltool.workflow.defaultMakeTool,
+    t = cwltool.main.load_tool(options.cwltool, False, True,
+                               cwltool.workflow.defaultMakeTool,
                                True)
 
     if type(t) == int:


Test patch:
diff --git a/src/toil/test/cwl/cwlTest.py b/src/toil/test/cwl/cwlTest.py
--- a/src/toil/test/cwl/cwlTest.py
+++ b/src/toil/test/cwl/cwlTest.py
@@ -20,7 +20,6 @@
 
 @needs_cwl
 class CWLTest(ToilTest):
-    @skip("https://github.com/BD2KGenomics/toil/issues/621")
     def test_run_revsort(self):
         from toil.cwl import cwltoil
         outDir = self._createTempDir()
Repository: DataBiosphere/toil

Issue:
Mesos batch system doesn't favor bigger tasks
https://github.com/BD2KGenomics/toil/blob/d08fe8c43d0d18d4d4bdafb9c9c921fd937557bd/src/toil/batchSystems/mesos/batchSystem.py#L298

Sort is ineffective as it sorts by the property descriptor, not the value of the property.

Mesos batch system doesn't favor bigger tasks
https://github.com/BD2KGenomics/toil/blob/d08fe8c43d0d18d4d4bdafb9c9c921fd937557bd/src/toil/batchSystems/mesos/batchSystem.py#L298

Sort is ineffective as it sorts by the property descriptor, not the value of the property.



Discussion:

Resolving patch:
diff --git a/src/toil/batchSystems/mesos/batchSystem.py b/src/toil/batchSystems/mesos/batchSystem.py
--- a/src/toil/batchSystems/mesos/batchSystem.py
+++ b/src/toil/batchSystems/mesos/batchSystem.py
@@ -295,7 +295,7 @@ def _sortJobsByResourceReq(self):
         job_types = self.jobQueueList.keys()
         # sorts from largest to smallest core usage
         # TODO: add a size() method to ResourceSummary and use it as the key. Ask me why.
-        job_types.sort(key=lambda resourceRequirement: ResourceRequirement.cores)
+        job_types.sort(key=lambda resourceRequirement: resourceRequirement.cores)
         job_types.reverse()
         return job_types
 


Test patch:
Repository: DataBiosphere/toil

Issue:
Azure job store should support multiple storage accounts

Azure job store should support multiple storage accounts



Discussion:

Resolving patch:
diff --git a/src/toil/jobStores/azureJobStore.py b/src/toil/jobStores/azureJobStore.py
--- a/src/toil/jobStores/azureJobStore.py
+++ b/src/toil/jobStores/azureJobStore.py
@@ -48,23 +48,27 @@ def _fetchAzureAccountKey(accountName):
     """
     Find the account key for a given Azure storage account.
 
-    The account key is taken from the AZURE_ACCOUNT_KEY environment
-    variable if it exists, or from looking in the file
-    "~/.toilAzureCredentials". That file has format:
+    The account key is taken from the AZURE_ACCOUNT_KEY_<account> environment variable if it
+    exists, then from plain AZURE_ACCOUNT_KEY, and then from looking in the file
+    ~/.toilAzureCredentials. That file has format:
 
     [AzureStorageCredentials]
     accountName1=ACCOUNTKEY1==
     accountName2=ACCOUNTKEY2==
     """
-    if 'AZURE_ACCOUNT_KEY' in os.environ:
-        return os.environ['AZURE_ACCOUNT_KEY']
-    configParser = RawConfigParser()
-    configParser.read(os.path.expanduser(credential_file_path))
     try:
-        return configParser.get('AzureStorageCredentials', accountName)
-    except NoOptionError:
-        raise RuntimeError("No account key found for %s, please provide it in %s" %
-                           (accountName, credential_file_path))
+        return os.environ['AZURE_ACCOUNT_KEY_' + accountName]
+    except KeyError:
+        try:
+            return os.environ['AZURE_ACCOUNT_KEY']
+        except KeyError:
+            configParser = RawConfigParser()
+            configParser.read(os.path.expanduser(credential_file_path))
+            try:
+                return configParser.get('AzureStorageCredentials', accountName)
+            except NoOptionError:
+                raise RuntimeError("No account key found for '%s', please provide it in '%s'" %
+                                   (accountName, credential_file_path))
 
 
 maxAzureTablePropertySize = 64 * 1024


Test patch:
Repository: DataBiosphere/toil

Issue:
Occasional KeyError during testJobFileStoreWithSmallCache
http://jenkins.cgcloud.info/job/toil-branches/branch/master/77/testReport/junit/src.toil.test.src.jobFileStoreTest/JobFileStoreTest/testJobFileStoreWithSmallCache/

```
Exception in thread Thread-13:
WARNING:toil.leader:t/V/job0sJG0Z:  Traceback (most recent call last):
WARNING:toil.leader:t/V/job0sJG0Z:    File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
WARNING:toil.leader:t/V/job0sJG0Z:      self.run()
WARNING:toil.leader:t/V/job0sJG0Z:    File "/usr/lib/python2.7/threading.py", line 763, in run
WARNING:toil.leader:t/V/job0sJG0Z:      self.__target(*self.__args, **self.__kwargs)
WARNING:toil.leader:t/V/job0sJG0Z:    File "/mnt/ephemeral/workspace/toil-branches/master/src/toil/job.py", line 506, in asyncWrite
WARNING:toil.leader:t/V/job0sJG0Z:      self._lockFiles.remove(jobStoreFileID)
WARNING:toil.leader:t/V/job0sJG0Z:  KeyError: 'I/O/tmpOiPrLG.tmp'
```



Discussion:
Duplicated by #596.


Resolving patch:
diff --git a/src/toil/job.py b/src/toil/job.py
--- a/src/toil/job.py
+++ b/src/toil/job.py
@@ -571,12 +571,15 @@ def writeGlobalFile(self, localFileName, cleanup=False):
             cleanupID = None if not cleanup else self.jobWrapper.jobStoreID
             if absLocalFileName.startswith(self.localTempDir):
                 jobStoreFileID = self.jobStore.getEmptyFileStoreID(cleanupID)
-                self.queue.put((open(absLocalFileName, 'r'), jobStoreFileID))
+                fileHandle = open(absLocalFileName, 'r')
                 if os.stat(absLocalFileName).st_uid == os.getuid():
                     #Chmod if permitted to make file read only to try to prevent accidental user modification
                     os.chmod(absLocalFileName, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
                 with self._lockFilesLock:
                     self._lockFiles.add(jobStoreFileID)
+                # A file handle added to the queue allows the asyncWrite threads to remove their jobID from _lockFiles.
+                # Therefore, a file should only be added after its fileID is added to _lockFiles
+                self.queue.put((fileHandle, jobStoreFileID))
                 self._jobStoreFileIDToCacheLocation[jobStoreFileID] = absLocalFileName
             else:
                 #Write the file directly to the file store


Test patch:
Repository: DataBiosphere/toil

Issue:
Sporadic sortTest failure
self = toil.test.sort.sortTest.SortTest testMethod=testFileMesos

src/toil/test/sort/sortTest.py:134: in _toilSort
    Job.Runner.startToil(firstJob, options)
src/toil/job.py:425: in startToil
    for jobWrapper in jobStore.jobs()}
src/toil/job.py:424: in <dictcomp>
    jobCache = {jobWrapper.jobStoreID: jobWrapper
src/toil/jobStores/fileJobStore.py:137: in jobs
    yield self.load(self._getRelativePath(os.path.join(tempDir, i)))
src/toil/jobStores/fileJobStore.py:103: in load
    self._checkJobStoreId(jobStoreID)

self = toil.jobStores.fileJobStore.FileJobStore object at 0x2b57deab1150
jobStoreID = 'l/K/jobo2Q6W5'

```
def _checkJobStoreId(self, jobStoreID):
    if not self.exists(jobStoreID):
        raise NoSuchJobException(jobStoreID)
       NoSuchJobException: The job 'l/K/jobo2Q6W5' does not exist
```

src/toil/jobStores/fileJobStore.py:279: NoSuchJobException



Discussion:
Discovered in #594. This test failed after making only documentation changes. I retested and it failed again. While looking through the changes for an explanation I found a couple typos in my comments, and when I pushed these fixes the test passed on this 3rd try. 

I didn't touch any code or even anything in the Mesos batchsystem, so it seems to me like this may be an issue in the master branch

Another case?

http://jenkins.cgcloud.info/job/toil-branches/branch/releases%2F3.1.x/19/testReport/src.toil.test.sort.sortTest/SortTest/testFileSingle10000/


Resolving patch:
diff --git a/src/toil/jobStores/abstractJobStore.py b/src/toil/jobStores/abstractJobStore.py
--- a/src/toil/jobStores/abstractJobStore.py
+++ b/src/toil/jobStores/abstractJobStore.py
@@ -317,7 +317,9 @@ def delete(self, jobStoreID):
 
     def jobs(self):
         """
-        Returns iterator on the jobs in the store.
+        Returns iterator on all jobs in the store. The iterator will contain all jobs, but may also
+        contain orphaned jobs that have already finished succesfully and should not be rerun.
+        To guarantee you only get jobs that can be run, instead construct a ToilState object
         
         :rtype : iterator
         """
diff --git a/src/toil/jobStores/fileJobStore.py b/src/toil/jobStores/fileJobStore.py
--- a/src/toil/jobStores/fileJobStore.py
+++ b/src/toil/jobStores/fileJobStore.py
@@ -137,7 +137,11 @@ def jobs(self):
         for tempDir in self._tempDirectories():
             for i in os.listdir(tempDir):
                 if i.startswith( 'job' ):
-                    yield self.load(self._getRelativePath(os.path.join(tempDir, i)))
+                    try:
+                        yield self.load(self._getRelativePath(os.path.join(tempDir, i)))
+                    except NoSuchJobException:
+                        # An orphaned job may leave an empty or incomplete job file which we can safely ignore
+                        pass  
 
     ##########################################
     #Functions that deal with temporary files associated with jobs


Test patch:
Repository: DataBiosphere/toil

Issue:
Another Mesos scheduler failure
```
Failed to call scheduler's statusUpdate
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/toil/batchSystems/mesos/batchSystem.py", line 456, in statusUpdate
    self.__updateState(taskID, 0)
  File "/usr/local/lib/python2.7/dist-packages/toil/batchSystems/mesos/batchSystem.py", line 433, in __updateState
    del self.runningJobMap[intID]
KeyError: 42199
```



Discussion:

Resolving patch:
diff --git a/src/toil/batchSystems/mesos/batchSystem.py b/src/toil/batchSystems/mesos/batchSystem.py
--- a/src/toil/batchSystems/mesos/batchSystem.py
+++ b/src/toil/batchSystems/mesos/batchSystem.py
@@ -430,7 +430,11 @@ def _createTask(self, jt_job, offer):
 
     def __updateState(self, intID, exitStatus):
         self.updatedJobsQueue.put((intID, exitStatus))
-        del self.runningJobMap[intID]
+        try:
+            del self.runningJobMap[intID]
+        except KeyError:
+            log.warning('Cannot find %i among running jobs. '
+                        'Sent update about its exit code of %i anyways.', intID, exitStatus)
 
     def statusUpdate(self, driver, update):
         """


Test patch:
Repository: DataBiosphere/toil

Issue:
Silence boto logs with --logDebug
When running with --logDebug against AWS job store, there's just too much noise from boto.

This should also suppress the expected error caused by eventual consistency that happen when creating the job store.



Discussion:

Resolving patch:
diff --git a/src/toil/lib/bioio.py b/src/toil/lib/bioio.py
--- a/src/toil/lib/bioio.py
+++ b/src/toil/lib/bioio.py
@@ -61,6 +61,10 @@ def setLogLevel(level):
     numericLevel = logging.getLevelName(level)
     assert logging.getLevelName(numericLevel) == level
     rootLogger.setLevel(numericLevel)
+    # There are quite a few cases where we expect AWS requests to fail, but it seems
+    # that boto handles these by logging the error *and* raising an exception. We
+    # don't want to confuse the user with those error messages.
+    logging.getLogger( 'boto' ).setLevel( logging.CRITICAL )
 
 def logFile(fileName, printFunction=logger.info):
     """Writes out a formatted version of the given log file


Test patch:
diff --git a/src/toil/test/jobStores/jobStoreTest.py b/src/toil/test/jobStores/jobStoreTest.py
--- a/src/toil/test/jobStores/jobStoreTest.py
+++ b/src/toil/test/jobStores/jobStoreTest.py
@@ -48,6 +48,12 @@ class hidden:
     class AbstractJobStoreTest(ToilTest):
         __metaclass__ = ABCMeta
 
+        @classmethod
+        def setUpClass(cls):
+            super(hidden.AbstractJobStoreTest, cls).setUpClass()
+            logging.basicConfig(level=logging.DEBUG)
+            logging.getLogger('boto').setLevel(logging.CRITICAL)
+
         def _createConfig(self):
             return Config()
 
@@ -455,9 +461,9 @@ def testCleanCache(self):
             cacheEnd = time.time()
             
             cacheTime = cacheEnd - cacheStart
-            
-            print("Without cache: %s With cache: %s" % (str(noCacheTime), str(cacheTime)))
-            
+
+            logger.info("Without cache: %f, with cache: %f.", noCacheTime, cacheTime)
+
             # Running with the cache should be faster.
             self.assertTrue(cacheTime <= noCacheTime)
Repository: DataBiosphere/toil

Issue:
Silence boto logs with --logDebug
When running with --logDebug against AWS job store, there's just too much noise from boto.

This should also suppress the expected error caused by eventual consistency that happen when creating the job store.

Silence boto logs with --logDebug
When running with --logDebug against AWS job store, there's just too much noise from boto.

This should also suppress the expected error caused by eventual consistency that happen when creating the job store.



Discussion:

Resolving patch:
diff --git a/src/toil/lib/bioio.py b/src/toil/lib/bioio.py
--- a/src/toil/lib/bioio.py
+++ b/src/toil/lib/bioio.py
@@ -65,6 +65,10 @@ def setLogLevel(level, logger=rootLogger):
     numericLevel = logging.getLevelName(level)
     assert logging.getLevelName(numericLevel) == level
     logger.setLevel(numericLevel)
+    # There are quite a few cases where we expect AWS requests to fail, but it seems
+    # that boto handles these by logging the error *and* raising an exception. We
+    # don't want to confuse the user with those error messages.
+    logging.getLogger( 'boto' ).setLevel( logging.CRITICAL )
 
 def logFile(fileName, printFunction=logger.info):
     """Writes out a formatted version of the given log file


Test patch:
diff --git a/src/toil/test/jobStores/jobStoreTest.py b/src/toil/test/jobStores/jobStoreTest.py
--- a/src/toil/test/jobStores/jobStoreTest.py
+++ b/src/toil/test/jobStores/jobStoreTest.py
@@ -48,6 +48,12 @@ class hidden:
     class AbstractJobStoreTest(ToilTest):
         __metaclass__ = ABCMeta
 
+        @classmethod
+        def setUpClass(cls):
+            super(hidden.AbstractJobStoreTest, cls).setUpClass()
+            logging.basicConfig(level=logging.DEBUG)
+            logging.getLogger('boto').setLevel(logging.CRITICAL)
+
         def _createConfig(self):
             return Config()
 
@@ -455,9 +461,9 @@ def testCleanCache(self):
             cacheEnd = time.time()
             
             cacheTime = cacheEnd - cacheStart
-            
-            print("Without cache: %s With cache: %s" % (str(noCacheTime), str(cacheTime)))
-            
+
+            logger.info("Without cache: %f, with cache: %f.", noCacheTime, cacheTime)
+
             # Running with the cache should be faster.
             self.assertTrue(cacheTime <= noCacheTime)
Repository: DataBiosphere/toil

Issue:
logToMaster() doesn't work
This is an example from the docs. It does not print the logToMaster() message, neither on master nor on 3.1.x.

```
from toil.job import Job

class HelloWorld(Job):
    def __init__(self, message):
        Job.__init__(self,  memory="2G", cores=2, disk="3G")
        self.message = message

    def run(self, fileStore):
        fileStore.logToMaster("Hello, world!, I have a message: %s"
                              % self.message)

if __name__=="__main__":
    options = Job.Runner.getDefaultOptions("./toilWorkflowRun")
    options.logLevel = "INFO"
    Job.Runner.startToil(HelloWorld("woot"), options)
```

logToMaster() doesn't work
This is an example from the docs. It does not print the logToMaster() message, neither on master nor on 3.1.x.

```
from toil.job import Job

class HelloWorld(Job):
    def __init__(self, message):
        Job.__init__(self,  memory="2G", cores=2, disk="3G")
        self.message = message

    def run(self, fileStore):
        fileStore.logToMaster("Hello, world!, I have a message: %s"
                              % self.message)

if __name__=="__main__":
    options = Job.Runner.getDefaultOptions("./toilWorkflowRun")
    options.logLevel = "INFO"
    Job.Runner.startToil(HelloWorld("woot"), options)
```



Discussion:

Resolving patch:
diff --git a/src/toil/leader.py b/src/toil/leader.py
--- a/src/toil/leader.py
+++ b/src/toil/leader.py
@@ -45,7 +45,7 @@ def statsAndLoggingAggregatorProcess(jobStore, stop):
     def callback(fileHandle):
         stats = json.load(fileHandle, object_hook=Expando)
         try:
-            logs = stats.workers.log
+            logs = stats.workers.logsToMaster
         except AttributeError:
             # To be expected if there were no calls to logToMaster()
             pass
diff --git a/src/toil/worker.py b/src/toil/worker.py
--- a/src/toil/worker.py
+++ b/src/toil/worker.py
@@ -392,8 +392,9 @@ def badWorker():
             statsDict.workers.time = str(time.time() - startTime)
             statsDict.workers.clock = str(totalCPUTime - startClock)
             statsDict.workers.memory = str(totalMemoryUsage)
-            statsDict.workers.log = messages
-        
+
+        statsDict.workers.logsToMaster = messages  # logToMaster messages should be always be passed
+
         logger.info("Finished running the chain of jobs on this node, we ran for a total of %f seconds", time.time() - startTime)
     
     ##########################################


Test patch:
Repository: DataBiosphere/toil

Issue:
Module Index link is broken on Sphinx docs index page
http://toil.readthedocs.org/en/latest/py-modindex.html

This link is broken. We should have a way of browsing all the modules in the docs.



Discussion:
Hmm, this is still broken on the doc site:

https://toil.readthedocs.org/en/releases-3.1.x/py-modindex.html

On Thu, Feb 25, 2016 at 12:55 PM, Hannes Schmidt notifications@github.com
wrote:

> Closed #611 https://github.com/BD2KGenomics/toil/issues/611 via 455b6be
> https://github.com/BD2KGenomics/toil/commit/455b6be4c815a1bff366e34934f74916f24578c6
> .
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/BD2KGenomics/toil/issues/611#event-566330187.
> 
> ## 
> 
> You received this message because you are subscribed to the Google Groups
> "cgloud-jenkins" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to cgloud-jenkins+unsubscribe@googlegroups.com.
> To post to this group, send email to cgloud-jenkins@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/cgloud-jenkins/BD2KGenomics/toil/issue/611/issue_event/566330187%40github.com
> https://groups.google.com/d/msgid/cgloud-jenkins/BD2KGenomics/toil/issue/611/issue_event/566330187%40github.com?utm_medium=email&utm_source=footer
> .
> For more options, visit https://groups.google.com/d/optout.

The fix has been merged into master but not yet into the 3.1.x branch which is displayed on read the docs

> Hmm, this is still broken on the doc site:

Who wrote this?

> The fix has been merged into master but not yet into the 3.1.x branch which is displayed on read the docs

It never will be merged into 3.1.x. Too big a change for a small issue.

However, the "latest" version on RTD (which is build from master) is also broken. The problem is that RTD does not invoke our Makefile. I think it still invokes the code in conf.py so we will have to move this logic

https://github.com/BD2KGenomics/toil/commit/455b6be4c815a1bff366e34934f74916f24578c6#diff-b67911656ef5d18c4ae36cb6741b7965R89

to conf.py. Care must be taken to do so idempotently so as to not be too invasive.


Resolving patch:
diff --git a/docs/conf.py b/docs/conf.py
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -15,6 +15,7 @@
 import os
 import inspect
 import re
+import subprocess
 
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
@@ -31,6 +32,9 @@ def real_dir_name(p, n=1):
     print p
     return p
 
+path_to_dir = os.path.dirname(os.path.abspath(__file__))
+subprocess.check_call('mkdir -p %s/generated_rst' % path_to_dir, shell=True)
+subprocess.check_call('cd %s/generated_rst && sphinx-apidoc -fo . ../../src/' % path_to_dir, shell=True)
 
 assert real_dir_name(__file__, 2) == real_dir_name(toil.version.__file__, 3), \
     "Another Toil installation seems to have precedence over this working directory."


Test patch: