mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -27,6 +27,8 @@ but seemingly no one uses them in C extensions yet anyway.
|
||||
VERSION = "1.99" # Must be a number-dot-number string, updated with each change that affects generated skeletons
|
||||
# Note: DON'T FORGET TO UPDATE!
|
||||
|
||||
VERSION_CONTROL_HEADER_FORMAT = '# from %s by generator %s'
|
||||
|
||||
import sys
|
||||
import os
|
||||
import string
|
||||
@@ -1789,8 +1791,7 @@ class ModuleRedeclarator(object):
|
||||
else:
|
||||
mod_name = " does not know its name"
|
||||
out(0, "# module ", p_name, mod_name) # line 2
|
||||
version_control_header_format = '# from %s by generator %s'
|
||||
out(0, version_control_header_format % (
|
||||
out(0, VERSION_CONTROL_HEADER_FORMAT % (
|
||||
self.mod_filename or getattr(self.module, "__file__", "(built-in)"), VERSION)
|
||||
) # line 3
|
||||
if p_name == BUILTIN_MOD_NAME and version[0] == 2 and version[1] >= 6:
|
||||
@@ -2115,7 +2116,7 @@ def buildOutputName(subdir, name):
|
||||
fname = target_name + ".py"
|
||||
return fname
|
||||
|
||||
def redoModule(name, out_name, mod_file_name, doing_builtins, imported_module_names):
|
||||
def redoModule(name, outfile, mod_file_name, doing_builtins, imported_module_names):
|
||||
# gobject does 'del _gobject' in its __init__.py, so the chained attribute lookup code
|
||||
# fails to find 'gobject._gobject'. thus we need to pull the module directly out of
|
||||
# sys.modules
|
||||
@@ -2134,15 +2135,11 @@ def redoModule(name, out_name, mod_file_name, doing_builtins, imported_module_na
|
||||
report("Failed to find CLR module " + name)
|
||||
break
|
||||
if mod:
|
||||
action("opening %r", out_name)
|
||||
outfile = fopen(out_name, "w")
|
||||
action("restoring")
|
||||
r = ModuleRedeclarator(mod, outfile, mod_file_name, doing_builtins=doing_builtins)
|
||||
r.redo(name, imported_module_names)
|
||||
action("flushing")
|
||||
r.flush()
|
||||
action("closing %r", out_name)
|
||||
outfile.close()
|
||||
else:
|
||||
report("Failed to find imported module in sys.modules")
|
||||
|
||||
@@ -2283,57 +2280,72 @@ def processOne(name, mod_file_name, doing_builtins):
|
||||
sys.stdout.flush()
|
||||
action("doing nothing")
|
||||
#noinspection PyBroadException
|
||||
outfile = None
|
||||
try:
|
||||
fname = buildOutputName(subdir, name)
|
||||
|
||||
old_modules = list(sys.modules.keys())
|
||||
imported_module_names = []
|
||||
class MyFinder:
|
||||
def find_module(self, fullname, path=None):
|
||||
if fullname != name:
|
||||
imported_module_names.append(fullname)
|
||||
return None
|
||||
|
||||
my_finder = None
|
||||
if hasattr(sys, 'meta_path'):
|
||||
my_finder = MyFinder()
|
||||
sys.meta_path.append(my_finder)
|
||||
else:
|
||||
imported_module_names = None
|
||||
|
||||
action("importing %r", name)
|
||||
try:
|
||||
fname = buildOutputName(subdir, name)
|
||||
action("opening %r", fname)
|
||||
outfile = fopen(fname, "w")
|
||||
old_modules = list(sys.modules.keys())
|
||||
imported_module_names = []
|
||||
class MyFinder:
|
||||
def find_module(self, fullname, path=None):
|
||||
if fullname != name:
|
||||
imported_module_names.append(fullname)
|
||||
return None
|
||||
|
||||
my_finder = None
|
||||
if hasattr(sys, 'meta_path'):
|
||||
my_finder = MyFinder()
|
||||
sys.meta_path.append(my_finder)
|
||||
else:
|
||||
imported_module_names = None
|
||||
|
||||
action("importing")
|
||||
__import__(name) # sys.modules will fill up with what we want
|
||||
except ImportError:
|
||||
|
||||
if my_finder:
|
||||
sys.meta_path.remove(my_finder)
|
||||
if imported_module_names is None:
|
||||
imported_module_names = [m for m in sys.modules.keys() if m not in old_modules]
|
||||
|
||||
redoModule(name, outfile, mod_file_name, doing_builtins, imported_module_names)
|
||||
# The C library may have called Py_InitModule() multiple times to define several modules (gtk._gtk and gtk.gdk);
|
||||
# restore all of them
|
||||
if imported_module_names:
|
||||
for m in sys.modules.keys():
|
||||
action("looking at possible submodule %r", m)
|
||||
# if module has __file__ defined, it has Python source code and doesn't need a skeleton
|
||||
if m not in old_modules and m not in imported_module_names and m != name and not hasattr(sys.modules[m], '__file__'):
|
||||
if not quiet:
|
||||
say(m)
|
||||
sys.stdout.flush()
|
||||
fname = buildOutputName(subdir, m)
|
||||
action("opening %r", fname)
|
||||
subfile = fopen(fname, "w")
|
||||
try:
|
||||
redoModule(m, subfile, mod_file_name, doing_builtins, imported_module_names)
|
||||
finally:
|
||||
action("closing %r", fname)
|
||||
subfile.close()
|
||||
except:
|
||||
exctype, value = sys.exc_info()[:2]
|
||||
report("Name %r failed to import: %r", name, str(value))
|
||||
msg = "Failed to process %r while %s: %s" % (name, _current_action, str(value))
|
||||
report(msg)
|
||||
if outfile is not None and not outfile.closed:
|
||||
outfile.write("# encoding: %s\n" % OUT_ENCODING)
|
||||
outfile.write("# module %s\n" % name)
|
||||
outfile.write(VERSION_CONTROL_HEADER_FORMAT % (mod_file_name, VERSION))
|
||||
outfile.write("\n\n")
|
||||
outfile.write("# Skeleton generation error:\n#\n# " + msg + "\n")
|
||||
if debug_mode:
|
||||
if sys.platform == 'cli':
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
raise
|
||||
return False
|
||||
|
||||
if my_finder:
|
||||
sys.meta_path.remove(my_finder)
|
||||
if imported_module_names is None:
|
||||
imported_module_names = [m for m in sys.modules.keys() if m not in old_modules]
|
||||
|
||||
redoModule(name, fname, mod_file_name, doing_builtins, imported_module_names)
|
||||
# The C library may have called Py_InitModule() multiple times to define several modules (gtk._gtk and gtk.gdk);
|
||||
# restore all of them
|
||||
if imported_module_names:
|
||||
for m in sys.modules.keys():
|
||||
action("looking at possible submodule %r", m)
|
||||
# if module has __file__ defined, it has Python source code and doesn't need a skeleton
|
||||
if m not in old_modules and m not in imported_module_names and m != name and not hasattr(sys.modules[m], '__file__'):
|
||||
if not quiet:
|
||||
say(m)
|
||||
sys.stdout.flush()
|
||||
fname = buildOutputName(subdir, m)
|
||||
redoModule(m, fname, mod_file_name, doing_builtins, imported_module_names)
|
||||
except:
|
||||
report("Failed to process %r while %s", name, _current_action)
|
||||
if debug_mode:
|
||||
if sys.platform == 'cli':
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
raise
|
||||
return False
|
||||
finally:
|
||||
if outfile is not None and not outfile.closed:
|
||||
outfile.close()
|
||||
return True
|
||||
|
||||
if __name__ == "__main__":
|
||||
@@ -2434,7 +2446,7 @@ if __name__ == "__main__":
|
||||
names.remove('__main__') # we don't want ourselves processed
|
||||
ok = True
|
||||
for name in names:
|
||||
ok = ok and processOne(name, None, True)
|
||||
ok = processOne(name, None, True) and ok
|
||||
if not ok:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@@ -15,14 +15,13 @@ try:
|
||||
from pydev_ipython_console_010 import PyDevFrontEnd
|
||||
|
||||
sys.stderr.write('PyDev console: using IPython 0.10\n')
|
||||
except ImportError:
|
||||
except :
|
||||
#IPython 0.11 broke compatibility...
|
||||
from pydev_ipython_console_011 import PyDevFrontEnd
|
||||
|
||||
sys.stderr.write('PyDev console: using IPython 0.11\n')
|
||||
|
||||
|
||||
|
||||
#=======================================================================================================================
|
||||
# InterpreterInterface
|
||||
#=======================================================================================================================
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from pydevd_constants import DebugInfoHolder
|
||||
|
||||
logger = logging.getLogger('pydev')
|
||||
#hdlr = logging.FileHandler('/var/tmp/pycharm-debug-%d.log'%os.getpid())
|
||||
#formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
|
||||
#hdlr.setFormatter(formatter)
|
||||
#logger.addHandler(hdlr)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
def debug(message):
|
||||
logger.debug(message)
|
||||
if DebugInfoHolder.DEBUG_TRACE_LEVEL>2:
|
||||
sys.stderr.write(message)
|
||||
|
||||
def warn(message):
|
||||
logger.warn(message)
|
||||
if DebugInfoHolder.DEBUG_TRACE_LEVEL>1:
|
||||
sys.stderr.write(message)
|
||||
|
||||
def info(message):
|
||||
logger.info(message)
|
||||
sys.stderr.write(message)
|
||||
|
||||
def error(message):
|
||||
logger.error(message)
|
||||
sys.stderr.write(message)
|
||||
|
||||
@@ -46,9 +46,10 @@ def patch_args(args):
|
||||
return new_args
|
||||
|
||||
def monkey_patch_os(funcname, create_func):
|
||||
original_name = 'original_' + funcname
|
||||
setattr(os, original_name, getattr(os, funcname))
|
||||
setattr(os, funcname, create_func(original_name))
|
||||
if hasattr(os, funcname):
|
||||
original_name = 'original_' + funcname
|
||||
setattr(os, original_name, getattr(os, funcname))
|
||||
setattr(os, funcname, create_func(original_name))
|
||||
|
||||
def create_execl(original_name):
|
||||
def new_execl(path, *args):
|
||||
|
||||
@@ -63,6 +63,7 @@ import traceback
|
||||
import pydevd_vm_type
|
||||
import pydevd_tracing
|
||||
import pydevd_io
|
||||
import pydev_log
|
||||
from pydevd_additional_thread_info import PyDBAdditionalThreadInfo
|
||||
import time
|
||||
import os
|
||||
@@ -623,12 +624,12 @@ class PyDB:
|
||||
except:
|
||||
pass
|
||||
|
||||
if DEBUG_TRACE_BREAKPOINTS > 0:
|
||||
if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
|
||||
sys.stderr.write('Removed breakpoint:%s\n' % (file,))
|
||||
sys.stderr.flush()
|
||||
except KeyError:
|
||||
#ok, it's not there...
|
||||
if DEBUG_TRACE_BREAKPOINTS > 0:
|
||||
if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
|
||||
#Sometimes, when adding a breakpoint, it adds a remove command before (don't really know why)
|
||||
sys.stderr.write("breakpoint not found: %s - %s\n" % (file, line))
|
||||
sys.stderr.flush()
|
||||
@@ -660,10 +661,13 @@ class PyDB:
|
||||
|
||||
if is_notify_on_terminate:
|
||||
update_exception_hook(self)
|
||||
if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
|
||||
pydev_log.error("Exceptions to hook on terminate: %s\n" % (self.always_exception_set,))
|
||||
|
||||
if is_notify_always:
|
||||
self.always_exception_set.add(exception)
|
||||
if DEBUG_TRACE_BREAKPOINTS > 0:
|
||||
sys.stderr.write("Exceptions to hook : %s\n" % (self.always_exception_set,))
|
||||
if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
|
||||
pydev_log.error("Exceptions to hook always: %s\n" % (self.always_exception_set,))
|
||||
self.setTracingForUntracedContexts()
|
||||
|
||||
elif cmd_id == CMD_REMOVE_EXCEPTION_BREAK:
|
||||
@@ -1023,43 +1027,48 @@ class PyDB:
|
||||
def processCommandLine(argv):
|
||||
""" parses the arguments.
|
||||
removes our arguments from the command line """
|
||||
retVal = {}
|
||||
retVal['client'] = ''
|
||||
retVal['server'] = False
|
||||
retVal['port'] = 0
|
||||
retVal['file'] = ''
|
||||
retVal['multiproc'] = False
|
||||
setup = {}
|
||||
setup['client'] = ''
|
||||
setup['server'] = False
|
||||
setup['port'] = 0
|
||||
setup['file'] = ''
|
||||
setup['multiproc'] = False
|
||||
i = 0
|
||||
del argv[0]
|
||||
while (i < len(argv)):
|
||||
if (argv[i] == '--port'):
|
||||
del argv[i]
|
||||
retVal['port'] = int(argv[i])
|
||||
setup['port'] = int(argv[i])
|
||||
del argv[i]
|
||||
elif (argv[i] == '--vm_type'):
|
||||
del argv[i]
|
||||
retVal['vm_type'] = argv[i]
|
||||
setup['vm_type'] = argv[i]
|
||||
del argv[i]
|
||||
elif (argv[i] == '--client'):
|
||||
del argv[i]
|
||||
retVal['client'] = argv[i]
|
||||
setup['client'] = argv[i]
|
||||
del argv[i]
|
||||
elif (argv[i] == '--server'):
|
||||
del argv[i]
|
||||
retVal['server'] = True
|
||||
setup['server'] = True
|
||||
elif (argv[i] == '--file'):
|
||||
del argv[i]
|
||||
retVal['file'] = argv[i]
|
||||
setup['file'] = argv[i]
|
||||
i = len(argv) # pop out, file is our last argument
|
||||
elif (argv[i] == '--DEBUG_RECORD_SOCKET_READS'):
|
||||
del argv[i]
|
||||
retVal['DEBUG_RECORD_SOCKET_READS'] = True
|
||||
setup['DEBUG_RECORD_SOCKET_READS'] = True
|
||||
elif (argv[i] == '--DEBUG'):
|
||||
del argv[i]
|
||||
setup['DEBUG_RECORD_SOCKET_READS'] = True
|
||||
setup['DEBUG_TRACE_BREAKPOINTS'] = 1
|
||||
setup['DEBUG_TRACE_LEVEL'] = 3
|
||||
elif (argv[i] == '--multiproc'):
|
||||
del argv[i]
|
||||
retVal['multiproc'] = True
|
||||
setup['multiproc'] = True
|
||||
else:
|
||||
raise ValueError("unexpected option " + argv[i])
|
||||
return retVal
|
||||
return setup
|
||||
|
||||
def usage(doExit=0):
|
||||
sys.stdout.write('Usage:\n')
|
||||
@@ -1262,26 +1271,36 @@ if __name__ == '__main__':
|
||||
sys.modules['psyco'] = pydevd_psyco_stub
|
||||
|
||||
|
||||
PydevdLog(2, "Executing file ", setup['file'])
|
||||
PydevdLog(2, "arguments:", str(sys.argv))
|
||||
pydev_log.debug("Executing file %s" % setup['file'])
|
||||
pydev_log.debug("arguments: %s"% str(sys.argv))
|
||||
|
||||
|
||||
|
||||
pydevd_vm_type.SetupType(setup.get('vm_type', None))
|
||||
|
||||
DebugInfoHolder.DEBUG_RECORD_SOCKET_READS = setup.get('DEBUG_RECORD_SOCKET_READS', False)
|
||||
DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS = setup.get('', -1)
|
||||
DebugInfoHolder.DEBUG_TRACE_LEVEL = setup.get('DEBUG_TRACE_LEVEL', -1)
|
||||
|
||||
port = setup['port']
|
||||
if setup['multiproc']:
|
||||
pydev_log.debug("Started in multiproc mode")
|
||||
dispatcher = Dispatcher()
|
||||
dispatcher.connect(setup)
|
||||
if dispatcher.port is not None:
|
||||
port = dispatcher.port
|
||||
sys.stderr.write("pydev debugger: process %d is connecting\n"% os.getpid())
|
||||
pydev_log.debug("Received port %d" %port)
|
||||
pydev_log.info("pydev debugger: process %d is connecting\n"% os.getpid())
|
||||
|
||||
import pydev_monkey
|
||||
pydev_monkey.patch_new_process_functions()
|
||||
try:
|
||||
pydev_monkey.patch_new_process_functions()
|
||||
except:
|
||||
logger.error("Error patching process functions")
|
||||
else:
|
||||
sys.stderr.write("pydev debugger: couldn't get port for new debug process\n")
|
||||
pydev_log.error("pydev debugger: couldn't get port for new debug process\n")
|
||||
else:
|
||||
sys.stderr.write("pydev debugger: starting\n")
|
||||
pydev_log.info("pydev debugger: starting\n")
|
||||
|
||||
debugger = PyDB()
|
||||
debugger.connect(setup['client'], port)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from pydevd_constants import *
|
||||
import sys
|
||||
import pydev_log
|
||||
|
||||
_original_excepthook = None
|
||||
_handle_exceptions = None
|
||||
@@ -44,8 +45,8 @@ class LineBreakpoint:
|
||||
return breakDict
|
||||
|
||||
def trace(self, file, line, func_name):
|
||||
if DEBUG_TRACE_BREAKPOINTS > 0:
|
||||
sys.stderr.write('Added breakpoint:%s - line:%s - func_name:%s\n' % (file, line, func_name))
|
||||
if DebugInfoHolder.DEBUG_TRACE_BREAKPOINTS > 0:
|
||||
pydev_log.debug('Added breakpoint:%s - line:%s - func_name:%s\n' % (file, line, func_name))
|
||||
sys.stderr.flush()
|
||||
|
||||
def add(self, breakpoints, file, line, func_name):
|
||||
|
||||
@@ -166,7 +166,7 @@ def PydevdLog(level, *args):
|
||||
1 warnings/significant events
|
||||
2 informational trace
|
||||
"""
|
||||
if level <= DEBUG_TRACE_LEVEL:
|
||||
if level <= DebugInfoHolder.DEBUG_TRACE_LEVEL:
|
||||
#yes, we can have errors printing if the console of the program has been finished (and we're still trying to print something)
|
||||
try:
|
||||
sys.stderr.write('%s\n' % (args,))
|
||||
@@ -325,7 +325,7 @@ class WriterThread(PyDBDaemonThread):
|
||||
#but the thread was still not liberated
|
||||
return
|
||||
out = cmd.getOutgoing()
|
||||
if DEBUG_TRACE_LEVEL >= 1:
|
||||
if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 1:
|
||||
out_message = 'sending cmd: '
|
||||
out_message += ID_TO_MEANING.get(out[:3], 'UNKNOWN')
|
||||
out_message += ' '
|
||||
@@ -343,7 +343,7 @@ class WriterThread(PyDBDaemonThread):
|
||||
time.sleep(self.timeout)
|
||||
except Exception:
|
||||
GlobalDebuggerHolder.globalDbg.FinishDebuggingSession()
|
||||
if DEBUG_TRACE_LEVEL >= 0:
|
||||
if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 0:
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
@@ -434,7 +434,7 @@ class NetCommandFactory:
|
||||
|
||||
def makeErrorMessage(self, seq, text):
|
||||
cmd = NetCommand(CMD_ERROR, seq, text)
|
||||
if DEBUG_TRACE_LEVEL > 2:
|
||||
if DebugInfoHolder.DEBUG_TRACE_LEVEL > 2:
|
||||
sys.stderr.write("Error: %s" % (text,))
|
||||
return cmd
|
||||
|
||||
|
||||
@@ -16,13 +16,14 @@ except:
|
||||
setattr(__builtin__, 'True', 1)
|
||||
setattr(__builtin__, 'False', 0)
|
||||
|
||||
DEBUG_TRACE_LEVEL = -1
|
||||
DEBUG_TRACE_BREAKPOINTS = -1
|
||||
|
||||
|
||||
class DebugInfoHolder:
|
||||
#we have to put it here because it can be set through the command line (so, the
|
||||
#already imported references would not have it).
|
||||
DEBUG_RECORD_SOCKET_READS = False
|
||||
DEBUG_TRACE_LEVEL = -1
|
||||
DEBUG_TRACE_BREAKPOINTS = -1
|
||||
|
||||
#Optimize with psyco? This gave a 50% speedup in the debugger in tests
|
||||
USE_PSYCO_OPTIMIZATION = True
|
||||
|
||||
@@ -8,6 +8,7 @@ from pydevd_breakpoints import * #@UnusedWildImport
|
||||
import traceback #@Reimport
|
||||
import os.path
|
||||
import sys
|
||||
import pydev_log
|
||||
|
||||
basename = os.path.basename
|
||||
|
||||
@@ -166,8 +167,8 @@ class PyDBFrame:
|
||||
return self.trace_dispatch
|
||||
|
||||
except:
|
||||
sys.stderr.write('Error while evaluating condition \'%s\': %s\n' % (breakpoint.condition, sys.exc_info()[1]))
|
||||
sys.stderr.flush()
|
||||
pydev_log.info('Error while evaluating condition \'%s\': %s\n' % (breakpoint.condition, sys.exc_info()[1]))
|
||||
|
||||
return self.trace_dispatch
|
||||
|
||||
if breakpoint.expression is not None:
|
||||
@@ -332,8 +333,7 @@ class PyDBFrame:
|
||||
if not val:
|
||||
flag = False
|
||||
except:
|
||||
sys.stderr.write('Error while evaluating condition \'%s\': %s\n' % (django_breakpoint.condition, sys.exc_info()[1]))
|
||||
sys.stderr.flush()
|
||||
pydev_log.info('Error while evaluating condition \'%s\': %s\n' % (django_breakpoint.condition, sys.exc_info()[1]))
|
||||
|
||||
if django_breakpoint.expression is not None:
|
||||
try:
|
||||
|
||||
@@ -8,6 +8,7 @@ from types import * #@UnusedWildImport
|
||||
from code import compile_command
|
||||
from code import InteractiveInterpreter
|
||||
import pydevconsole
|
||||
import pydev_log
|
||||
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
@@ -244,8 +245,8 @@ def frameVarsToXML(frame):
|
||||
xml += varToXML(v, str(k))
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
sys.stderr.write("Unexpected error, recovered safely.\n")
|
||||
sys.stderr.flush()
|
||||
pydev_log.error("Unexpected error, recovered safely.\n")
|
||||
|
||||
return xml
|
||||
|
||||
def iterFrames(initialFrame):
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.jetbrains.python.debugger;
|
||||
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class PySourcePosition {
|
||||
|
||||
@@ -8,10 +10,22 @@ public abstract class PySourcePosition {
|
||||
private final int line;
|
||||
|
||||
protected PySourcePosition(final String file, final int line) {
|
||||
this.file = FileUtil.toSystemIndependentName(file);
|
||||
this.file = normalize(file);
|
||||
this.line = line;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String normalize(@Nullable String file) {
|
||||
if (file == null) {
|
||||
return file;
|
||||
}
|
||||
String res = FileUtil.toSystemIndependentName(file);
|
||||
if (SystemInfo.isWindows) {
|
||||
res = res.toLowerCase();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public String getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
@@ -586,7 +586,7 @@
|
||||
<localInspection language="GQL" shortName="Query_bound_parameters" bundle="com.jetbrains.appengine.ui.Messages" key="query-bound-param-inspection-name"
|
||||
groupKey="app-engine-python" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="com.jetbrains.appengine.inspection.QueryBoundParametersInspection"/>
|
||||
<localInspection language="GQL" shortName="Restricted_Python_calls" bundle="com.jetbrains.appengine.ui.Messages" key="sandbox-inspection-name"
|
||||
<localInspection language="Python" shortName="Restricted_Python_calls" bundle="com.jetbrains.appengine.ui.Messages" key="sandbox-inspection-name"
|
||||
groupKey="app-engine-python" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="com.jetbrains.appengine.inspection.SandboxInspection"/>
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ public class CreatePackageAction extends DumbAwareAction {
|
||||
}
|
||||
}
|
||||
|
||||
private static void createInitPyInHierarchy(PsiDirectory created, PsiDirectory ancestor) {
|
||||
public static void createInitPyInHierarchy(PsiDirectory created, PsiDirectory ancestor) {
|
||||
do {
|
||||
createInitPy(created);
|
||||
created = created.getParent();
|
||||
@@ -58,6 +58,9 @@ public class CreatePackageAction extends DumbAwareAction {
|
||||
private static void createInitPy(PsiDirectory directory) {
|
||||
final FileTemplateManager fileTemplateManager = FileTemplateManager.getInstance();
|
||||
final FileTemplate template = fileTemplateManager.getInternalTemplate("Python Script");
|
||||
if (directory.findFile(PyNames.INIT_DOT_PY) != null) {
|
||||
return;
|
||||
}
|
||||
if (template != null) {
|
||||
try {
|
||||
FileTemplateUtil.createFromTemplate(template, PyNames.INIT_DOT_PY, fileTemplateManager.getDefaultProperties(), directory);
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ReadWriteInstruction;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyBinaryExpressionNavigator;
|
||||
@@ -76,6 +77,9 @@ public class PyCodeFragmentUtil {
|
||||
if (next instanceof ConditionalInstruction){
|
||||
continue;
|
||||
}
|
||||
if (next instanceof ReadWriteInstruction && ((ReadWriteInstruction)next).getAccess().isAssertTypeAccess()) {
|
||||
continue;
|
||||
}
|
||||
final PsiElement nextElement = next.getElement();
|
||||
// Ignore binary operations control flow
|
||||
if (nextElement != null && PyBinaryExpressionNavigator.getBinaryExpressionByOperand(nextElement) != null){
|
||||
|
||||
@@ -29,7 +29,7 @@ public class PyNamedTupleType extends PyClassType implements PyCallableType {
|
||||
private final boolean myDefinition;
|
||||
private final PsiElement myDeclaration;
|
||||
private final List<String> myFields;
|
||||
|
||||
|
||||
private static final ImmutableSet<String> ourClassMembers = ImmutableSet.of("_fields", "_make");
|
||||
private static final ImmutableSet<String> ourInstanceMembers = ImmutableSet.of("_asdict", "_replace");
|
||||
|
||||
@@ -83,7 +83,7 @@ public class PyNamedTupleType extends PyClassType implements PyCallableType {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "namedtuple '" + myName + "'";
|
||||
return myName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,6 +99,16 @@ public class PyNamedTupleType extends PyClassType implements PyCallableType {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PyClassType toInstance() {
|
||||
return myIsDefinition ? new PyNamedTupleType(myDeclaration, myName, myFields, false) : this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PyNamedTupleType: " + myName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PyType fromCall(PyCallExpression call) {
|
||||
final String name = PyUtil.strValue(call.getArgument(0, PyExpression.class));
|
||||
|
||||
@@ -128,7 +128,7 @@ __builtin__.int.__sub__ = \
|
||||
:rtype: int \n\
|
||||
|
||||
__builtin__.int.__mul__ = \
|
||||
:type y: int or long or float or complex or string or list \n\
|
||||
:type y: int or long or float or complex \n\
|
||||
:rtype: int \n\
|
||||
|
||||
__builtin__.int.__floordiv__ = \
|
||||
@@ -631,7 +631,7 @@ __builtin__.str.encode = \
|
||||
:rtype: bytes \n\
|
||||
|
||||
__builtin__.str.endswith = \
|
||||
:type suffix: string \n\
|
||||
:type suffix: string or tuple \n\
|
||||
:type start: int or long or None \n\
|
||||
:type end: int or long or None \n\
|
||||
:rtype: bool \n\
|
||||
@@ -730,7 +730,7 @@ __builtin__.str.splitlines = \
|
||||
:rtype: list of bytes \n\
|
||||
|
||||
__builtin__.str.startswith = \
|
||||
:type prefix: string \n\
|
||||
:type prefix: string or tuple \n\
|
||||
:type start: int or long or None \n\
|
||||
:type end: int or long or None \n\
|
||||
:rtype: bool \n\
|
||||
@@ -805,7 +805,7 @@ __builtin__.unicode.encode = \
|
||||
:rtype: bytes \n\
|
||||
|
||||
__builtin__.unicode.endswith = \
|
||||
:type suffix: string \n\
|
||||
:type suffix: string or tuple \n\
|
||||
:type start: int or long or None \n\
|
||||
:type end: int or long or None \n\
|
||||
:rtype: bool \n\
|
||||
@@ -910,7 +910,7 @@ __builtin__.unicode.splitlines = \
|
||||
:rtype: list of unicode \n\
|
||||
|
||||
__builtin__.unicode.startswith = \
|
||||
:type prefix: string \n\
|
||||
:type prefix: string or tuple \n\
|
||||
:type start: int or long or None \n\
|
||||
:type end: int or long or None \n\
|
||||
:rtype: bool \n\
|
||||
@@ -1108,6 +1108,82 @@ __builtin__.file.writelines = \
|
||||
:type sequence_of_strings: collections.Iterable of string \n\
|
||||
|
||||
|
||||
## 9.4. decimal
|
||||
|
||||
decimal.Decimal.as_tuple = \
|
||||
:rtype: decimal.DecimalTuple \n\
|
||||
|
||||
decimal.Decimal.__add__ = \
|
||||
:type other: decimal.Decimal or int or long or float or complex \n\
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__sub__ = \
|
||||
:type other: decimal.Decimal or int or long or float or complex \n\
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__mul__ = \
|
||||
:type other: decimal.Decimal or int or long or float or complex \n\
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__floordiv__ = \
|
||||
:type other: decimal.Decimal or int or long or float or complex \n\
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__mod__ = \
|
||||
:type other: decimal.Decimal or int or long or float or complex \n\
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__pow__ = \
|
||||
:type other: decimal.Decimal or int or long or float or complex \n\
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__div__ = \
|
||||
:type other: decimal.Decimal or int or long or float or complex \n\
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__truediv__ = \
|
||||
:type other: decimal.Decimal or int or long or float or complex \n\
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__radd__ = \
|
||||
:type other: decimal.Decimal or int or long or float or complex \n\
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__rsub__ = \
|
||||
:type other: decimal.Decimal or int or long or float or complex \n\
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__rmul__ = \
|
||||
:type other: decimal.Decimal or int or long or float or complex \n\
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__rfloordiv__ = \
|
||||
:type other: decimal.Decimal or int or long or float or complex \n\
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__rmod__ = \
|
||||
:type other: decimal.Decimal or int or long or float or complex \n\
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__rpow__ = \
|
||||
:type other: decimal.Decimal or int or long or float or complex \n\
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__rdiv__ = \
|
||||
:type other: decimal.Decimal or int or long or float or complex \n\
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__rtruediv__ = \
|
||||
:type other: decimal.Decimal or int or long or float or complex \n\
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__pos__ = \
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
decimal.Decimal.__neg__ = \
|
||||
:rtype: decimal.Decimal \n\
|
||||
|
||||
|
||||
## 18.2. json
|
||||
|
||||
json.loads = \
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.jetbrains.python.console;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.jetbrains.python.console.completion.PydevConsoleElement;
|
||||
import com.jetbrains.python.inspections.*;
|
||||
import com.jetbrains.python.validation.DocStringAnnotator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -12,9 +14,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public class ConsoleVisitorFilter implements PythonVisitorFilter {
|
||||
@Override
|
||||
public boolean isSupported(@NotNull Class visitorClass, @NotNull PsiElement element) {
|
||||
public boolean isSupported(@NotNull Class visitorClass, @NotNull PsiElement element, PsiFile containingFile) {
|
||||
//if we're in console
|
||||
if (PydevConsoleRunner.isInPydevConsole(element)) {
|
||||
if (element instanceof PydevConsoleElement || containingFile.getCopyableUserData(PydevConsoleRunner.CONSOLE_KEY) != null) {
|
||||
//inspections
|
||||
if (visitorClass == PyUnusedLocalInspectionVisitor.class || visitorClass == PyUnboundLocalVariableInspection.Visitor.class ||
|
||||
visitorClass == PyStatementEffectInspection.class || visitorClass == PySingleQuotedDocstringInspection.class ||
|
||||
|
||||
@@ -476,8 +476,15 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr
|
||||
XBreakpoint<?> breakpoint = null;
|
||||
if (threadInfo.isStopOnBreakpoint()) {
|
||||
final PySourcePosition position = frames.get(0).getPosition();
|
||||
|
||||
breakpoint = myRegisteredBreakpoints.get(position);
|
||||
if (breakpoint == null) {
|
||||
System.out.println("Stopped:" + position.getFile() + ", " + position.getLine());
|
||||
System.out.println("Registered:");
|
||||
for (PySourcePosition s: myRegisteredBreakpoints.keySet()) {
|
||||
System.out.println(s.getFile() + ", " + s.getLine());
|
||||
}
|
||||
|
||||
myDebugger.removeTempBreakpoint(position.getFile(), position.getLine());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ public class PyDebugRunner extends GenericProgramRunner {
|
||||
}
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
debugParams.addParameter("--DEBUG_RECORD_SOCKET_READS");
|
||||
debugParams.addParameter("--DEBUG");
|
||||
}
|
||||
|
||||
final String[] debuggerArgs = new String[]{
|
||||
|
||||
@@ -4,13 +4,10 @@ import com.intellij.codeInspection.LocalInspectionToolSession;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.*;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.documentation.PythonDocumentationProvider;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
import com.jetbrains.python.psi.types.*;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -53,21 +50,34 @@ public class PyTypeCheckerInspection extends PyInspection {
|
||||
}
|
||||
final PyType argType = entry.getKey().getType(myTypeEvalContext);
|
||||
final PyType paramType = p.getType(myTypeEvalContext);
|
||||
checkTypes(paramType, argType, entry.getKey(), myTypeEvalContext);
|
||||
checkTypes(paramType, argType, entry.getKey(), myTypeEvalContext, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyBinaryExpression(PyBinaryExpression node) {
|
||||
// TODO: Support operators besides PyBinaryExpression
|
||||
final PsiReference ref = node.getReference(PyResolveContext.noImplicits().withTypeEvalContext(myTypeEvalContext));
|
||||
final PsiPolyVariantReference ref = node.getReference(resolveWithoutImplicits());
|
||||
if (ref != null) {
|
||||
final PsiElement resolved = ref.resolve();
|
||||
if (resolved instanceof PyFunction) {
|
||||
final PyFunction fun = (PyFunction)resolved;
|
||||
final PyExpression arg = PyNames.isRightOperatorName(fun.getName()) ? node.getLeftExpression() : node.getRightExpression();
|
||||
checkSingleArgumentFunction(fun, arg);
|
||||
final ResolveResult[] results = ref.multiResolve(false);
|
||||
String error = null;
|
||||
PyExpression arg = null;
|
||||
for (ResolveResult result : results) {
|
||||
final PsiElement resolved = result.getElement();
|
||||
if (resolved instanceof PyFunction) {
|
||||
final PyFunction fun = (PyFunction)resolved;
|
||||
arg = PyNames.isRightOperatorName(fun.getName()) ? node.getLeftExpression() : node.getRightExpression();
|
||||
error = checkSingleArgumentFunction(fun, arg, false);
|
||||
if (error == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (error != null) {
|
||||
registerProblem(arg, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,16 +85,17 @@ public class PyTypeCheckerInspection extends PyInspection {
|
||||
@Override
|
||||
public void visitPySubscriptionExpression(PySubscriptionExpression node) {
|
||||
// TODO: Support slice PySliceExpressions
|
||||
final PsiReference ref = node.getReference(PyResolveContext.noImplicits().withTypeEvalContext(myTypeEvalContext));
|
||||
final PsiReference ref = node.getReference(resolveWithoutImplicits());
|
||||
if (ref != null) {
|
||||
final PsiElement resolved = ref.resolve();
|
||||
if (resolved instanceof PyFunction) {
|
||||
checkSingleArgumentFunction((PyFunction)resolved, node.getIndexExpression());
|
||||
checkSingleArgumentFunction((PyFunction)resolved, node.getIndexExpression(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkSingleArgumentFunction(@NotNull PyFunction fun, @Nullable PyExpression argument) {
|
||||
@Nullable
|
||||
private String checkSingleArgumentFunction(@NotNull PyFunction fun, @Nullable PyExpression argument, boolean registerProblem) {
|
||||
if (argument != null) {
|
||||
final PyParameter[] parameters = fun.getParameterList().getParameters();
|
||||
if (parameters.length == 2) {
|
||||
@@ -92,22 +103,29 @@ public class PyTypeCheckerInspection extends PyInspection {
|
||||
if (p != null) {
|
||||
final PyType argType = argument.getType(myTypeEvalContext);
|
||||
final PyType paramType = p.getType(myTypeEvalContext);
|
||||
checkTypes(paramType, argType, argument, myTypeEvalContext);
|
||||
return checkTypes(paramType, argType, argument, myTypeEvalContext, registerProblem);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void checkTypes(PyType superType, PyType subType, PsiElement node, TypeEvalContext context) {
|
||||
@Nullable
|
||||
private String checkTypes(PyType superType, PyType subType, PsiElement node, TypeEvalContext context, boolean registerPoblem) {
|
||||
if (subType != null && superType != null) {
|
||||
if (!PyTypeChecker.match(superType, subType, context)) {
|
||||
registerProblem(node, String.format("Expected type '%s', got '%s' instead",
|
||||
PythonDocumentationProvider.getTypeName(superType, context),
|
||||
PythonDocumentationProvider.getTypeName(subType, myTypeEvalContext)));
|
||||
final String msg = String.format("Expected type '%s', got '%s' instead",
|
||||
PythonDocumentationProvider.getTypeName(superType, context),
|
||||
PythonDocumentationProvider.getTypeName(subType, myTypeEvalContext));
|
||||
if (registerPoblem) {
|
||||
registerProblem(node, msg);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inspectionFinished(LocalInspectionToolSession session, ProblemsHolder problemsHolder) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.jetbrains.python.inspections;
|
||||
|
||||
import com.intellij.lang.LanguageExtension;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -11,8 +12,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
* check if we should visit element
|
||||
*/
|
||||
public interface PythonVisitorFilter {
|
||||
public static final LanguageExtension<PythonVisitorFilter> INSTANCE =
|
||||
new LanguageExtension<PythonVisitorFilter>("Pythonid.visitorFilter");
|
||||
LanguageExtension<PythonVisitorFilter> INSTANCE = new LanguageExtension<PythonVisitorFilter>("Pythonid.visitorFilter");
|
||||
|
||||
boolean isSupported(@NotNull Class visitorClass, @NotNull PsiElement element);
|
||||
boolean isSupported(@NotNull Class visitorClass, @NotNull PsiElement element, PsiFile containingFile);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.intellij.ide.fileTemplates.FileTemplateManager;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
@@ -498,7 +499,7 @@ public class PyUtil {
|
||||
return false;
|
||||
}
|
||||
return PsiTreeUtil.isAncestor(statement.getLeftHandSideExpression(), element, false);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isDocString(PyExpression expression) {
|
||||
final PyDocStringOwner docStringOwner = PsiTreeUtil.getParentOfType(expression, PyDocStringOwner.class);
|
||||
@@ -783,22 +784,32 @@ public class PyUtil {
|
||||
return selfName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VirtualFile findInRoots(Module module, String path) {
|
||||
final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
|
||||
VirtualFile result = findInRoots(moduleRootManager.getContentRoots(), path);
|
||||
if (result == null) {
|
||||
result = findInRoots(moduleRootManager.getSourceRoots(), path);
|
||||
@NotNull
|
||||
public static List<VirtualFile> getSourceRoots(@NotNull PsiElement foothold) {
|
||||
final Module module = ModuleUtil.findModuleForPsiElement(foothold);
|
||||
if (module != null) {
|
||||
return getSourceRoots(module);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<VirtualFile> getSourceRoots(@NotNull Module module) {
|
||||
final List<VirtualFile> result = new ArrayList<VirtualFile>();
|
||||
final ModuleRootManager manager = ModuleRootManager.getInstance(module);
|
||||
result.addAll(Arrays.asList(manager.getSourceRoots()));
|
||||
result.addAll(Arrays.asList(manager.getContentRoots()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VirtualFile findInRoots(VirtualFile[] roots, String path) {
|
||||
for (VirtualFile root : roots) {
|
||||
VirtualFile settingsFile = root.findFileByRelativePath(path);
|
||||
if (settingsFile != null) {
|
||||
return settingsFile;
|
||||
public static VirtualFile findInRoots(Module module, String path) {
|
||||
if (module != null) {
|
||||
for (VirtualFile root : getSourceRoots(module)) {
|
||||
VirtualFile file = root.findFileByRelativePath(path);
|
||||
if (file != null) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -12,7 +12,6 @@ import com.intellij.psi.templateLanguages.OuterLanguageElement;
|
||||
import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.PythonFileType;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.inspections.PythonVisitorFilter;
|
||||
@@ -73,7 +72,7 @@ public class PyBaseElementImpl<T extends StubElement> extends StubBasedPsiElemen
|
||||
}
|
||||
|
||||
public static boolean isAcceptedFor(@NotNull final PsiElement element, @NotNull Class clazz) {
|
||||
PsiFile file = PsiTreeUtil.getNonStrictParentOfType(element, PsiFile.class);
|
||||
PsiFile file = element.getContainingFile();
|
||||
if (file != null) {
|
||||
Language lang = file.getLanguage();
|
||||
FileViewProvider vProvider = file.getViewProvider();
|
||||
@@ -81,7 +80,7 @@ public class PyBaseElementImpl<T extends StubElement> extends StubBasedPsiElemen
|
||||
lang = vProvider.getBaseLanguage();
|
||||
}
|
||||
PythonVisitorFilter filter = PythonVisitorFilter.INSTANCE.forLanguage(lang);
|
||||
return filter != null ? filter.isSupported(clazz, element) : true;
|
||||
return filter != null ? filter.isSupported(clazz, element, file) : true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.SoftHashMap;
|
||||
import com.jetbrains.python.PyElementTypes;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
@@ -56,6 +57,8 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
|
||||
return CachedValuesManager.getManager(getProject()).createCachedValue(new NewStyleCachedValueProvider(), false);
|
||||
}
|
||||
};
|
||||
|
||||
private final SoftHashMap<String, Property> myPropertyCache = new SoftHashMap<String, Property>();
|
||||
|
||||
@Override
|
||||
public PyType getType(@NotNull TypeEvalContext context) {
|
||||
@@ -604,7 +607,16 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
|
||||
@Nullable
|
||||
@Override
|
||||
public Property findProperty(@NotNull final String name) {
|
||||
return scanProperties(name, null, true);
|
||||
synchronized (myPropertyCache) {
|
||||
if (myPropertyCache.containsKey(name)) {
|
||||
return myPropertyCache.get(name);
|
||||
}
|
||||
}
|
||||
final Property result = scanProperties(name, null, true);
|
||||
synchronized (myPropertyCache) {
|
||||
myPropertyCache.put(name, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1025,6 +1037,9 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
|
||||
if (myInstanceAttributes != null) {
|
||||
myInstanceAttributes = null;
|
||||
}
|
||||
synchronized (myPropertyCache) {
|
||||
myPropertyCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -43,7 +43,8 @@ public class PyImportElementImpl extends PyBaseElementImpl<PyImportElementStub>
|
||||
|
||||
@Nullable
|
||||
public PyReferenceExpression getImportReference() {
|
||||
return findChildByClass(PyReferenceExpression.class);
|
||||
final ASTNode node = getNode().findChildByType(PyElementTypes.REFERENCE_EXPRESSION);
|
||||
return node == null ? null : (PyReferenceExpression) node.getPsi();
|
||||
}
|
||||
|
||||
public PyQualifiedName getImportedQName() {
|
||||
|
||||
@@ -39,20 +39,18 @@ public class PyOperatorReferenceImpl extends PyReferenceImpl {
|
||||
typeEvalContext.trace("Trying to resolve left operator");
|
||||
typeEvalContext.traceIndent();
|
||||
try {
|
||||
res = resolveMember(expr.getLeftExpression(), name);
|
||||
res.addAll(resolveMember(expr.getLeftExpression(), name));
|
||||
}
|
||||
finally {
|
||||
typeEvalContext.traceUnindent();
|
||||
}
|
||||
if (res.isEmpty()) {
|
||||
typeEvalContext.trace("Trying to resolve right operator");
|
||||
typeEvalContext.traceIndent();
|
||||
try {
|
||||
res = resolveMember(expr.getRightExpression(), leftToRightOperatorName(name));
|
||||
}
|
||||
finally {
|
||||
typeEvalContext.traceUnindent();
|
||||
}
|
||||
typeEvalContext.trace("Trying to resolve right operator");
|
||||
typeEvalContext.traceIndent();
|
||||
try {
|
||||
res.addAll(resolveMember(expr.getRightExpression(), leftToRightOperatorName(name)));
|
||||
}
|
||||
finally {
|
||||
typeEvalContext.traceUnindent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-6
@@ -25,7 +25,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
* @author oleg
|
||||
*/
|
||||
public class PyExtractMethodHandler implements RefactoringActionHandler {
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file, final DataContext dataContext) {
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||
// select editor text fragment
|
||||
@@ -35,12 +35,11 @@ public class PyExtractMethodHandler implements RefactoringActionHandler {
|
||||
invokeOnEditor(project, editor, file);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull final Project project, @NotNull final PsiElement[] elements, final DataContext dataContext) {
|
||||
// ignore this
|
||||
}
|
||||
|
||||
private void invokeOnEditor(final Project project, final Editor editor, final PsiFile file) {
|
||||
private static void invokeOnEditor(final Project project, final Editor editor, final PsiFile file) {
|
||||
CommonRefactoringUtil.checkReadOnlyStatus(project, file);
|
||||
PsiElement element1 = null;
|
||||
PsiElement element2 = null;
|
||||
@@ -112,7 +111,7 @@ public class PyExtractMethodHandler implements RefactoringActionHandler {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiElement[] getStatementsRange(final PsiElement element1, final PsiElement element2) {
|
||||
private static PsiElement[] getStatementsRange(final PsiElement element1, final PsiElement element2) {
|
||||
final PsiElement parent = PsiTreeUtil.findCommonParent(element1, element2);
|
||||
if (parent == null) {
|
||||
return null;
|
||||
@@ -136,5 +135,4 @@ public class PyExtractMethodHandler implements RefactoringActionHandler {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+25
-12
@@ -2,6 +2,7 @@ package com.jetbrains.python.refactoring.extractmethod;
|
||||
|
||||
import com.intellij.codeInsight.codeFragment.CodeFragment;
|
||||
import com.intellij.lang.LanguageNamesValidation;
|
||||
import com.intellij.lang.refactoring.NamesValidator;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -45,7 +46,6 @@ import java.util.Map;
|
||||
* @author oleg
|
||||
*/
|
||||
public class PyExtractMethodUtil {
|
||||
|
||||
public static final String NAME = "extract.method.name";
|
||||
|
||||
private PyExtractMethodUtil() {
|
||||
@@ -71,6 +71,9 @@ public class PyExtractMethodUtil {
|
||||
// collect statements
|
||||
final List<PsiElement> elementsRange = PyPsiUtils.collectElements(statement1, statement2);
|
||||
if (elementsRange.isEmpty()) {
|
||||
CommonRefactoringUtil.showErrorHint(project, editor,
|
||||
"Cannot perform refactoring from empty code fragment",
|
||||
RefactoringBundle.message("extract.method.title"), "refactoring.extractMethod");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -108,16 +111,17 @@ public class PyExtractMethodUtil {
|
||||
builder.append("(").append(createCallArgsString(variableData)).append(")");
|
||||
PsiElement callElement = PyElementGenerator.getInstance(project).createFromText(LanguageLevel.getDefault(), PyCallExpression.class, builder.toString());
|
||||
|
||||
//# replace statements with call
|
||||
// Replace statements with call
|
||||
callElement = replaceElements(elementsRange, callElement);
|
||||
|
||||
// # Set editor
|
||||
// Set editor
|
||||
setSelectionAndCaret(editor, callElement);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, "Extract method", null);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@@ -210,8 +214,10 @@ public class PyExtractMethodUtil {
|
||||
|
||||
if (fragment.getOutputVariables().isEmpty()) {
|
||||
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Generate method
|
||||
PyFunction generatedMethod = generateMethodFromExpression(project, methodName, variableData, expression, flags);
|
||||
@@ -234,7 +240,9 @@ public class PyExtractMethodUtil {
|
||||
PsiElement callElement = fragment.isReturnInstructionInside() ? returnStatement : returnStatement.getExpression();
|
||||
|
||||
// replace statements with call
|
||||
callElement = PyPsiUtils.replaceExpression(expression, callElement);
|
||||
if (callElement != null) {
|
||||
callElement = PyPsiUtils.replaceExpression(expression, callElement);
|
||||
}
|
||||
|
||||
// Set editor
|
||||
setSelectionAndCaret(editor, callElement);
|
||||
@@ -372,15 +380,18 @@ public class PyExtractMethodUtil {
|
||||
addFakeParameters(builder, variableData);
|
||||
final PyFunction method = builder.buildFunction(project, LanguageLevel.getDefault());
|
||||
final PyStatementList statementList = method.getStatementList();
|
||||
|
||||
assert statementList != null;
|
||||
for (PsiElement element : elementsRange) {
|
||||
if (element instanceof PsiWhiteSpace){
|
||||
if (element instanceof PsiWhiteSpace) {
|
||||
continue;
|
||||
}
|
||||
statementList.add(element);
|
||||
}
|
||||
// remove last instruction
|
||||
statementList.getFirstChild().delete();
|
||||
final PsiElement child = statementList.getFirstChild();
|
||||
if (child != null) {
|
||||
child.delete();
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
@@ -406,15 +417,15 @@ public class PyExtractMethodUtil {
|
||||
final PsiElement element,
|
||||
final boolean isClassMethod,
|
||||
final boolean isStaticMethod) {
|
||||
final ExtractMethodValidator validator = new PyExtractMethodValidator(element, project);
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()){
|
||||
final ExtractMethodValidator validator = new PyExtractMethodValidator(element, project);
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
String name = System.getProperty(NAME);
|
||||
if (name == null){
|
||||
name = "foo";
|
||||
}
|
||||
final String error = validator.check(name);
|
||||
if (error != null){
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()){
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
throw new CommonRefactoringUtil.RefactoringErrorHintException(error);
|
||||
}
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
@@ -517,7 +528,9 @@ public class PyExtractMethodUtil {
|
||||
}
|
||||
|
||||
public boolean isValidName(final String name) {
|
||||
return LanguageNamesValidation.INSTANCE.forLanguage(PythonLanguage.getInstance()).isIdentifier(name, myProject);
|
||||
final NamesValidator validator = LanguageNamesValidation.INSTANCE.forLanguage(PythonLanguage.getInstance());
|
||||
assert validator != null;
|
||||
return validator.isIdentifier(name, myProject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package com.jetbrains.python.refactoring.move;
|
||||
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFileHandler;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.jetbrains.python.actions.CreatePackageAction;
|
||||
import com.jetbrains.python.codeInsight.imports.PyImportOptimizer;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyQualifiedName;
|
||||
@@ -33,6 +35,16 @@ public class PyMoveFileHandler extends MoveFileHandler {
|
||||
|
||||
@Override
|
||||
public void prepareMovedFile(PsiFile file, PsiDirectory moveDestination, Map<PsiElement, PsiElement> oldToNewMap) {
|
||||
if (file != null) {
|
||||
final List<VirtualFile> roots = PyUtil.getSourceRoots(file);
|
||||
PsiDirectory root = moveDestination;
|
||||
while (root != null && !roots.contains(root.getVirtualFile())) {
|
||||
root = root.getParentDirectory();
|
||||
}
|
||||
if (moveDestination != root && root != null) {
|
||||
CreatePackageAction.createInitPyInHierarchy(moveDestination, root);
|
||||
}
|
||||
}
|
||||
// TODO: Update relative imports
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ public class IronPythonSdkFlavor extends PythonSdkFlavor {
|
||||
|
||||
@Override
|
||||
public String getVersionString(String sdkHome) {
|
||||
return "IronPython " + getVersionFromOutput(sdkHome, "-V", "\\w+ ([0-9\\.]+).*", true);
|
||||
return "IronPython " + getVersionFromOutput(sdkHome, "-V", "\\w+ ([0-9\\.]+).*");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -36,7 +36,7 @@ public class JythonSdkFlavor extends PythonSdkFlavor {
|
||||
|
||||
@Override
|
||||
public String getVersionString(String sdkHome) {
|
||||
return getVersionFromOutput(sdkHome, "--version", "(Jython \\S+)( on .*)?", false);
|
||||
return getVersionFromOutput(sdkHome, "--version", "(Jython \\S+)( on .*)?");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,6 +21,6 @@ public class PyPySdkFlavor extends PythonSdkFlavor {
|
||||
|
||||
@Override
|
||||
public String getVersionString(String sdkHome) {
|
||||
return getVersionFromOutput(sdkHome, "--version", "\\[(PyPy .+)\\]", true);
|
||||
return getVersionFromOutput(sdkHome, "--version", "\\[(PyPy [^ ]+).*\\]");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,11 +80,11 @@ public abstract class PythonSdkFlavor {
|
||||
|
||||
@Nullable
|
||||
public String getVersionString(String sdkHome) {
|
||||
return getVersionFromOutput(sdkHome, "-V", "(Python \\S+).*", false);
|
||||
return getVersionFromOutput(sdkHome, "-V", "(Python \\S+).*");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected static String getVersionFromOutput(String sdkHome, String version_opt, String version_regexp, boolean stdout) {
|
||||
protected static String getVersionFromOutput(String sdkHome, String version_opt, String version_regexp) {
|
||||
Pattern pattern = Pattern.compile(version_regexp);
|
||||
String run_dir = new File(sdkHome).getParent();
|
||||
final ProcessOutput process_output = SdkUtil.getProcessOutput(run_dir, new String[]{sdkHome, version_opt});
|
||||
@@ -97,8 +97,11 @@ public abstract class PythonSdkFlavor {
|
||||
);
|
||||
return null;
|
||||
}
|
||||
final List<String> lines = stdout ? process_output.getStdoutLines() : process_output.getStderrLines();
|
||||
return SdkUtil.getFirstMatch(lines, pattern);
|
||||
final String result = SdkUtil.getFirstMatch(process_output.getStderrLines(), pattern);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
return SdkUtil.getFirstMatch(process_output.getStdoutLines(), pattern);
|
||||
}
|
||||
|
||||
public Collection<String> getExtraDebugOptions() {
|
||||
|
||||
@@ -10,3 +10,6 @@ print p.__add__
|
||||
print p._asdict()
|
||||
print Point._fields
|
||||
print p._replace
|
||||
|
||||
if isinstance(p, Point):
|
||||
p.x
|
||||
@@ -0,0 +1,10 @@
|
||||
class C:
|
||||
def baz(self, arg_new):
|
||||
self.bar(arg_new)
|
||||
|
||||
def foo(self, option, arg):
|
||||
if option:
|
||||
self.baz(arg)
|
||||
|
||||
def bar(self, arg):
|
||||
pass
|
||||
@@ -0,0 +1,7 @@
|
||||
class C:
|
||||
def foo(self, option, arg):
|
||||
if option:
|
||||
<selection>self.bar(arg)</selection>
|
||||
|
||||
def bar(self, arg):
|
||||
pass
|
||||
@@ -0,0 +1,7 @@
|
||||
from nonp3 import m1
|
||||
from nonp3.m1 import foo
|
||||
|
||||
m1.foo
|
||||
m1.bar
|
||||
m1
|
||||
foo
|
||||
@@ -0,0 +1 @@
|
||||
__author__ = 'user1'
|
||||
@@ -0,0 +1,2 @@
|
||||
foo = 42
|
||||
bar = -1
|
||||
@@ -0,0 +1,9 @@
|
||||
from p1.p2 import m1
|
||||
from p1.p2.m1 import foo
|
||||
import p1.p2.m1
|
||||
import p1
|
||||
|
||||
p1.p2.m1.foo
|
||||
m1.bar
|
||||
m1
|
||||
foo
|
||||
@@ -0,0 +1,2 @@
|
||||
foo = 42
|
||||
bar = -1
|
||||
@@ -26,7 +26,7 @@ public abstract class PyCommandLineTestCase extends PyTestCase {
|
||||
|
||||
protected static int verifyPyDevDParameters(List<String> params) {
|
||||
params = Lists.newArrayList(params);
|
||||
int debugParam = params.remove("--DEBUG_RECORD_SOCKET_READS") ? 1 : 0;
|
||||
int debugParam = params.remove("--DEBUG") ? 1 : 0;
|
||||
assertEquals(PythonHelpersLocator.getHelperPath("pydev/pydevd.py"), params.get(0));
|
||||
assertEquals("--client", params.get(1));
|
||||
assertEquals("--port", params.get(3));
|
||||
|
||||
@@ -147,4 +147,9 @@ public class PyExtractMethodTest extends LightMarkedTestCase {
|
||||
public void testStaticMethod() {
|
||||
doTest("staticmethod.before.py", "baz", "staticmethod.after.py");
|
||||
}
|
||||
|
||||
// PY-5123
|
||||
public void testMethodInIf() {
|
||||
doTest("methodInIf.before.py", "baz", "methodInIf.after.py");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,11 @@ public class PyMoveTest extends PyTestCase {
|
||||
doMoveFileTest("p1/p2/m1.py", "p1");
|
||||
}
|
||||
|
||||
// PY-5168
|
||||
public void testModuleToNonPackage() {
|
||||
doMoveFileTest("p1/p2/m1.py", "nonp3");
|
||||
}
|
||||
|
||||
private void doMoveFileTest(String fileName, String toDirName) {
|
||||
Project project = myFixture.getProject();
|
||||
PsiManager manager = PsiManager.getInstance(project);
|
||||
|
||||
Reference in New Issue
Block a user