{"action":"opened","issue":{"url":"https://api.github.com/repos/jorgenschaefer/elpy/issues/546","labels_url":"https://api.github.com/repos/jorgenschaefer/elpy/issues/546/labels{/name}","comments_url":"https://api.github.com/repos/jorgenschaefer/elpy/issues/546/comments","events_url":"https://api.github.com/repos/jorgenschaefer/elpy/issues/546/events","html_url":"https://github.com/jorgenschaefer/elpy/issues/546","id":70753419,"number":546,"title":"It told me to open a bug report, so ...","user":{"login":"offby1","id":3145,"avatar_url":"https://avatars.githubusercontent.com/u/3145?v=3","gravatar_id":"","url":"https://api.github.com/users/offby1","html_url":"https://github.com/offby1","followers_url":"https://api.github.com/users/offby1/followers","following_url":"https://api.github.com/users/offby1/following{/other_user}","gists_url":"https://api.github.com/users/offby1/gists{/gist_id}","starred_url":"https://api.github.com/users/offby1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/offby1/subscriptions","organizations_url":"https://api.github.com/users/offby1/orgs","repos_url":"https://api.github.com/users/offby1/repos","events_url":"https://api.github.com/users/offby1/events{/privacy}","received_events_url":"https://api.github.com/users/offby1/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-04-24T17:59:50Z","updated_at":"2015-04-24T17:59:50Z","closed_at":null,"body":"Elpy Error\r\n\r\nThe backend encountered an unexpected error. This indicates a bug in\r\nElpy. Please open a bug report with the data below in the Elpy bug\r\ntracker:\r\n\r\nhttps://github.com/jorgenschaefer/elpy/issues/new\r\n\r\n```\r\nError Message\r\n\r\nname sync_exec not found\r\n\r\nConfiguration\r\n\r\nVirtualenv........: rack (/Users/erichanchrow/.virtualenvs/rack)\r\nRPC Python........: 2.7.6 (/Users/erichanchrow/.virtualenvs/rack/bin/python)\r\nInteractive Python: python (/Users/erichanchrow/.virtualenvs/rack/bin/python)\r\nEmacs.............: 24.5.1\r\nElpy..............: 1.7.1\r\nJedi..............: 0.8.1\r\nRope..............: 0.10.2\r\nImportmagic.......: 0.1.3\r\nSyntax checker....: flake8 (/Users/erichanchrow/.virtualenvs/rack/bin/flake8)\r\n\r\nTraceback\r\n\r\nTraceback (most recent call last):\r\n  File \"/Users/erichanchrow/.emacs.d/elpa/elpy-20150226.1148/elpy/ropebackend.py\", line 96, in call_rope\r\n    **kwargs)\r\n  File \"/Users/erichanchrow/.virtualenvs/rack/lib/python2.7/site-packages/rope/contrib/codeassist.py\", line 92, in get_calltip\r\n    pyname = fixer.pyname_at(offset)\r\n  File \"/Users/erichanchrow/.virtualenvs/rack/lib/python2.7/site-packages/rope/contrib/fixsyntax.py\", line 61, in pyname_at\r\n    return new_pyname()\r\n  File \"/Users/erichanchrow/.virtualenvs/rack/lib/python2.7/site-packages/rope/contrib/fixsyntax.py\", line 59, in new_pyname\r\n    return rope.base.evaluate.eval_location(pymodule, newoffset)\r\n  File \"/Users/erichanchrow/.virtualenvs/rack/lib/python2.7/site-packages/rope/base/evaluate.py\", line 12, in eval_location\r\n    return eval_location2(pymodule, offset)[1]\r\n  File \"/Users/erichanchrow/.virtualenvs/rack/lib/python2.7/site-packages/rope/base/evaluate.py\", line 18, in eval_location2\r\n    return pyname_finder.get_primary_and_pyname_at(offset)\r\n  File \"/Users/erichanchrow/.virtualenvs/rack/lib/python2.7/site-packages/rope/base/evaluate.py\", line 102, in get_primary_and_pyname_at\r\n    return (None, holding_scope.parent[name])\r\n  File \"/Users/erichanchrow/.virtualenvs/rack/lib/python2.7/site-packages/rope/base/pyscopes.py\", line 30, in __getitem__\r\n    return self.get_name(key)\r\n  File \"/Users/erichanchrow/.virtualenvs/rack/lib/python2.7/site-packages/rope/base/pyscopes.py\", line 122, in get_name\r\n    raise exceptions.NameNotFoundError('name %s not found' % name)\r\nNameNotFoundError: name sync_exec not found\r\n\r\nRope Debug Information\r\n\r\n```\r\n\r\nReproduction:\r\n\r\n```Python\r\n\r\nsource = '''\r\n#!/usr/bin/env python2.7\r\n\r\n\"\"\"Fork and exec a subprocess, and sever all connection to it -- if it dies, we won't know about it.\r\n\r\nUseful for creating processes in a \"fire-and-forget\" fashion.\r\n\"\"\"\r\n\r\nfrom __future__ import print_function\r\nfrom __future__ import absolute_import\r\n\r\n__author__ = 'ehanchrow@ine.com'\r\n\r\nimport logging\r\nimport os\r\nimport resource\r\nimport signal\r\n\r\nlog = logging.getLogger(__name__)\r\n\r\n# TODO -- compare this to https://github.com/thesharp/daemonize, and\r\n# either use that wholesale, or steal ideas from it.  I didn't know of\r\n# that project when I wrote this.\r\n\r\n# How many file handles can a process have open at once?  This is\r\n# important to know, since we want to _close_ all possible open file\r\n# handles.\r\nMAXFD = 1024                    # fallback\r\n\r\n# http://legacy.python.org/dev/peps/pep-0446/#closing-all-open-file-descriptors\r\n# talks about this, and suggests that the \"subprocess\" module jumps\r\n# through roughly the same hoops.  In particular, it suggests that I\r\n# use os.sysconf(\"SC_OPEN_MAX\") to get MAXFD.\r\n\r\n\r\ndef _get_max_fd():\r\n    \"\"\"Return the maximum number of file handles that a process is\r\n    allowed to open.  Knowing this, we can safely close every possible\r\n    handle, without having to take forever.\r\n\r\n    \"\"\"\r\n    try:\r\n        from_sysconf = os.sysconf(\"SC_OPEN_MAX\")\r\n    except(AttributeError, ValueError):\r\n        from_sysconf = MAXFD\r\n\r\n    from_getrlimit = resource.getrlimit(resource.RLIMIT_NOFILE)[1]\r\n    if (from_getrlimit == resource.RLIM_INFINITY):\r\n        from_getrlimit = MAXFD\r\n\r\n    # TODO -- is \"min\" the right thing here?\r\n    return min(from_sysconf, from_getrlimit)\r\n\r\n\r\ndef _the_slow_way():\r\n    \"\"\"For development only: determine MAXFD (for this platform, anyway)\r\n    the slow, dumb, but accurate way: just keep opening files until we\r\n    can't open any more.\r\n\r\n    \"\"\"\r\n    num_opened = 0\r\n    handles = []\r\n    while True:\r\n        try:\r\n            print(\"num_opened is %d\" % num_opened)\r\n            handles.append(open(os.devnull, 'r'))\r\n            num_opened += 1\r\n        except OSError, e:\r\n            print(\"Ahoy! %s\" % e)\r\n            break\r\n    exit(0)\r\n\r\n\r\ndef async_exec(*args, **kwargs):\r\n    \"\"\"Run the given argument list asynchronously, rather as if we'd used\r\n    `nohup`.  Adapted from\r\n    http://code.activestate.com/recipes/278731/.  The new process is\r\n    in a separate session\r\n    (https://www.gnu.org/software/libc/manual/html_node/Process-Group-Functions.html#Process-Group-Functions)\r\n    so as to disconnect from the controlling tty (hence rendering it\r\n    impervious to some signals), and explicitly ignores SIGHUP.\r\n\r\n    This function actually forks twice, so that the final process is\r\n    our grandchild, not our child.  I suspect this is unnecessary;\r\n    http://stackoverflow.com/a/881434/20146 says that it's just so\r\n    that there's no chance that the final process can somehow acquire\r\n    a controlling terminal.  That seems pretty unlikely even if we\r\n    only forked once.\r\n\r\n    \"\"\"\r\n\r\n    log_directory = kwargs.get('log_directory')\r\n    if log_directory:\r\n        try:\r\n            os.makedirs(log_directory)\r\n        except OSError, e:\r\n            if e.errno != os.errno.EEXIST:\r\n                raise\r\n\r\n    grandpa_pid = os.getpid()\r\n\r\n    # If os.execl (below) fails, we could log the failure to stderr,\r\n    # but this exception is easier to notice.\r\n    program_name = args[0]\r\n    if not os.access(program_name, os.X_OK):\r\n\r\n        # TODO -- a plain Exception like this will get turned into an\r\n        # HTTP response with a 500 code, meaning \"internal error\".\r\n        # But it's possible that the problem was due to a malformed\r\n        # URL, which would call for a 4xx code, meaning \"the http\r\n        # client is on drugs\".  None of the HTTP status codes at\r\n        # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html seem\r\n        # appropriate for \"no such file or directory\".\r\n\r\n        message = [\"Cannot execute %r because it's not executable\", program_name]\r\n        log.exception(*message)\r\n        raise Exception (*message)\r\n\r\n    child = os.fork()\r\n    if child == 0:\r\n        # The first child\r\n        os.setsid()\r\n        signal.signal(signal.SIGHUP, signal.SIG_IGN)\r\n\r\n        # This prevents zombies.\r\n\r\n        # I originally had this in this module's __init__, but that\r\n        # caused a weird problem: every time the web service used\r\n        # \"pexpect\" to spawn a telnet process, and then called 'close'\r\n        # on it, the pexpect code got all freaked out: its \"isalive\"\r\n        # method called os.waitpid, but got ECHILD back; it then\r\n        # raised an exception since it wasn't prepared for that case.\r\n\r\n        # Anyway: putting the call to \"signal\" here is The Right\r\n        # Thing, since it only gets invoked if it's needed, and\r\n        # doesn't even affect the web server, since if you look\r\n        # closely you'll see that this code is actually in a _child_\r\n        # of the webserver process.\r\n\r\n        signal.signal(signal.SIGCHLD, signal.SIG_IGN)\r\n\r\n        child = os.fork()\r\n\r\n        if child == 0:\r\n            # The second child\r\n\r\n            # Restore the signal handler that we muffled in our\r\n            # parent.  This prevents a mysterious exception:\r\n            # ``IOError: [Errno 10] No child processes`` coming from a\r\n            # call to os.open deep inside code that gets invoked by\r\n            # the Pyramid Configurator.\r\n\r\n            # I suspect this is a bug in Python 2.7.5.  It's\r\n            # tantalizingly similar to\r\n            # http://bugs.python.org/issue9127, but that has been\r\n            # fixed.\r\n            signal.signal(signal.SIGCHLD, signal.SIG_DFL)\r\n\r\n            # I can't explain why this is necessary; I just know that\r\n            # if I don't do it, the parent or the child hangs.\r\n            os.closerange(0, _get_max_fd() - 1)\r\n\r\n            if log_directory:\r\n                logfile_basename = os.path.join(log_directory, '{}-{}.'.format (args[1], os.getpid ()))\r\n\r\n                stdout = open ('{}stdout'.format (logfile_basename), 'w')\r\n                stderr = open ('{}stderr'.format (logfile_basename), 'w')\r\n            else:\r\n                stdout = open(os.devnull, 'w')\r\n                stderr = open(os.devnull, 'w')\r\n\r\n            os.dup2(stdout.fileno(), 1)\r\n            os.dup2(stderr.fileno(), 2)\r\n\r\n            try:\r\n                os.execve(args[0], args[1:], dict(os.environ, INE_GRANDPA_PID=str(grandpa_pid)))\r\n            except OSError as e:\r\n                print(\"os.execl {!r} failed: {}\".format(args, e), file=stderr)\r\n                stderr.flush()\r\n                os._exit(0) # prevent zombies if execl fails\r\n        else:\r\n            # First child\r\n\r\n            log.info(\"Started grandchild process %d\", child)\r\n\r\n            os._exit(0)\r\n    else:\r\n        log.info(\"Started child process %d.  Grandchild log messages will be sent to syslog; its stdout and stderr will be %s\", child, 'in {!r}'.format(log_directory) if log_directory else 'ignored')\r\n\r\n        # This also prevents zombies.\r\n        os.waitpid(child, 0)\r\n\r\n\r\ndef main():\r\n    # _the_slow_way ()\r\n    logging.basicConfig()\r\n    print(\"Hello %s!  You are allowed %d open file handles.\" % (os.uname()[0], _get_max_fd()))\r\n    async_exec('/bin/bash', 'bash', '-c', \"date ; echo no wai > /dev/stderr\")\r\n\r\nif __name__ == \"__main__\":\r\n    main()\r\n'''\r\n\r\nproject = rope.base.project.Project(\r\n    \"/Users/erichanchrow/git-repositories/ine-rackcontrol/\",\r\n    ropefolder=None\r\n)\r\nresource = rope.base.libutils.path_to_resource(\r\n    project,\r\n    \"/Users/erichanchrow/git-repositories/ine-rackcontrol/rackcontrol/async.py\",\r\n    'file'\r\n)\r\nrope.contrib.codeassist.get_calltip(\r\n    project, source, 2099, resource, maxfixes=5, remove_self=True\r\n)\r\n```\r\n"}}