I am trying to get code completion for the psycopg2 library in PyCharm 2018.1 but it is not showing cursor class methods like .execute() or .fetchone().
Here is my code:
import logging
import psycopg2 as pg
#Code completion works fine here.
logger = logging.getLogger()
logger.info("Hello World!")
#Code completion works fine here.
con = pg.connect("dbname='postgres' port='5432'")
#Code completion not working!
cur = con.cursor()
That's because:
Psycopg 2 is mostly implemented in C as a libpq wrapper
So you have autocomletion for pg.connect() because it exists in __init__.py and mostly the rest of features are listed as .c and .h files https://github.com/psycopg/psycopg2/tree/master/psycopg that are being handled by setup.py.
In my case the solution is to reset the settings.
From the main menu, select File > Manage IDE Settings > Restore Default Settings.
Alternatively, press Shift twice and type Restore default settings
Related
I have a simple script which parses a file and loads it's contents to a database. I don't need a UI, but right now I'm prompting the user for the file to parse using raw_input which is most unfriendly, especially because the user can't copy/paste the path. I would like a quick and easy way to present a file selection dialog to the user, they can select the file, and then it's loaded to the database. (In my use case, if they happened to chose the wrong file, it would fail parsing, and wouldn't be a problem even if it was loaded to the database.)
import tkFileDialog
file_path_string = tkFileDialog.askopenfilename()
This code is close to what I want, but it leaves an annoying empty frame open (which isn't able to be closed, probably because I haven't registered a close event handler).
I don't have to use tkInter, but since it's in the Python standard library it's a good candidate for quickest and easiest solution.
Whats a quick and easy way to prompt for a file or filename in a script without any other UI?
Tkinter is the easiest way if you don't want to have any other dependencies.
To show only the dialog without any other GUI elements, you have to hide the root window using the withdraw method:
import tkinter as tk
from tkinter import filedialog
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename()
Python 2 variant:
import Tkinter, tkFileDialog
root = Tkinter.Tk()
root.withdraw()
file_path = tkFileDialog.askopenfilename()
You can use easygui:
import easygui
path = easygui.fileopenbox()
To install easygui, you can use pip:
pip3 install easygui
It is a single pure Python module (easygui.py) that uses tkinter.
Try with wxPython:
import wx
def get_path(wildcard):
app = wx.App(None)
style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
dialog = wx.FileDialog(None, 'Open', wildcard=wildcard, style=style)
if dialog.ShowModal() == wx.ID_OK:
path = dialog.GetPath()
else:
path = None
dialog.Destroy()
return path
print get_path('*.txt')
pywin32 provides access to the GetOpenFileName win32 function. From the example
import win32gui, win32con, os
filter='Python Scripts\0*.py;*.pyw;*.pys\0Text files\0*.txt\0'
customfilter='Other file types\0*.*\0'
fname, customfilter, flags=win32gui.GetOpenFileNameW(
InitialDir=os.environ['temp'],
Flags=win32con.OFN_ALLOWMULTISELECT|win32con.OFN_EXPLORER,
File='somefilename', DefExt='py',
Title='GetOpenFileNameW',
Filter=filter,
CustomFilter=customfilter,
FilterIndex=0)
print 'open file names:', repr(fname)
print 'filter used:', repr(customfilter)
print 'Flags:', flags
for k,v in win32con.__dict__.items():
if k.startswith('OFN_') and flags & v:
print '\t'+k
Using tkinter (python 2) or Tkinter (python 3) it's indeed possible to display file open dialog (See other answers here). Please notice however that user interface of that dialog is outdated and does not corresponds to newer file open dialogs available in Windows 10.
Moreover - if you're looking on way to embedd python support into your own application - you will find out soon that tkinter library is not open source code and even more - it is commercial library.
(For example search for "activetcl pricing" will lead you to this web page: https://reviews.financesonline.com/p/activetcl/)
So tkinter library will cost money for any application wanting to embedd python.
I by myself managed to find pythonnet library:
Overview here: http://pythonnet.github.io/
Source code here: https://github.com/pythonnet/pythonnet
(MIT License)
Using following command it's possible to install pythonnet:
pip3 install pythonnet
And here you can find out working example for using open file dialog:
https://stackoverflow.com/a/50446803/2338477
Let me copy an example also here:
import sys
import ctypes
co_initialize = ctypes.windll.ole32.CoInitialize
# Force STA mode
co_initialize(None)
import clr
clr.AddReference('System.Windows.Forms')
from System.Windows.Forms import OpenFileDialog
file_dialog = OpenFileDialog()
ret = file_dialog.ShowDialog()
if ret != 1:
print("Cancelled")
sys.exit()
print(file_dialog.FileName)
If you also miss more complex user interface - see Demo folder
in pythonnet git.
I'm not sure about portability to other OS's, haven't tried, but .net 5 is planned to be ported to multiple OS's (Search ".net 5 platforms", https://devblogs.microsoft.com/dotnet/introducing-net-5/ ) - so this technology is also future proof.
If you don't need the UI or expect the program to run in a CLI, you could parse the filepath as an argument. This would allow you to use the autocomplete feature of your CLI to quickly find the file you need.
This would probably only be handy if the script is non-interactive besides the filepath input.
Another os-agnostic option, use pywebview:
import webview
def webview_file_dialog():
file = None
def open_file_dialog(w):
nonlocal file
try:
file = w.create_file_dialog(webview.OPEN_DIALOG)[0]
except TypeError:
pass # user exited file dialog without picking
finally:
w.destroy()
window = webview.create_window("", hidden=True)
webview.start(open_file_dialog, window)
# file will either be a string or None
return file
print(webview_file_dialog())
Environment: python3.8.6 on Mac - though I've used pywebview on windows 10 before.
I just stumbled on this little trick for Windows only: run powershell.exe from subprocess.
import subprocess
sys_const = ssfDESKTOP # Starts at the top level
# sys_const = 0x2a # Correct value for "Program Files (0x86)" folder
powershell_browse = "(new-object -COM 'Shell.Application')."
powershell_browse += "BrowseForFolder(0,'window title here',0,sys_const).self.path"
ret = subprocess.run(["powershell.exe",powershell_browse], stdout=subprocess.PIPE)
print(ret.stdout.decode())
Note the optional use of system folder constants. (There's an obscure typo in shldisp.h that the "Program Files (0x86)" constant was assigned wrong. I added a comment with the correct value. Took me a bit to figure that one out.)
More info below:
System folder constants
I'm building a desktop app in python 2.7 and I'm making the GUI in PyQt4. I'm using PyCharm and when I run the inspect code I get a warning message. "Passing str instead of PyQt4.QtSql.QSqlDatabase. Is this intentional?".
My code looks like this:
self.db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
self.db.setHostName("localhost")
self.db.setDatabaseName("templateDb.db")
self.db.open()
The warning appears to the first line and it's about this string "QSQLITE".
The app is working ok, no problems with that. But I'm curious if it's a PyCharm problem or there is another way to write the first line?
Thank you.
Convert your database name into QString.
"addDatabase" function takes an argument as Qstring not in string format.
from PyQt4.QtCore import *
a = QString("QSQLITE")
self.db = QtSql.QSqlDatabase.addDatabase(a)
I am not sure this will work or not. But try this.
I have stucked with a specific problem. I am working on Python script which reads data from MS Access database (.mdb) using VBA API and displays it in GUI tables using tkintertable module.
The problem is that after script terminates the MSACCESS.exe process is keeping alive in the process list.
When I comment mainloop() method for the root window the problem disappears.
Explicit call of access.quit() does not solve the problem. It makes it worse: the script terminates, but the MS Access process makes visible, I see it's window, but can't close it, because it appears more and more.
I removed all the unnecessary lines from the code to localize the problem:
#!C:\Python343\python
from comtypes.client import CreateObject
from tkinter import *
access = CreateObject('Access.Application')
root = Tk()
root.mainloop() # if I comment this line, everything works
# access.quit() - does not help: MS Access window gets visible and immortal
#
Can one give any clue of why this happens?
Thanks in advance for any advice.
Python version: 3.4.3.
MS Office: 2013.
Unfortunately, I can't switch to pypyodbc or other packages, because the script is big and it is not convenient to redesign it. Now it uses VBA API (OpenRecordSet, MoveFirst, MoveLast methods etc.), but pypyodbc does not mirror this API AFAIK.
Now I use a workaround (killing of the MSACCESS.EXE application). I will post it here. Probably, it will be useful for one who stuck with the same problem:
def close_by_force(app): # Took this function from https://stackoverflow.com/
# questions/10221150/cant-close-excel-completely-using-win32com-on-python,
# but had to redesign it to be usable to work with COM objects
import win32process
import win32gui
import win32api
import win32con
# Get the window's process id's
hwnd = app.hWndAccessApp()
t, p = win32process.GetWindowThreadProcessId(hwnd)
# Ask window nicely to close
win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)
# Allow some time for app to close
time.sleep(10) # not really necessary
# If the application didn't close, force close
try:
#print('pid='+str(p))
handle = win32api.OpenProcess(win32con.PROCESS_TERMINATE, 0, p)
if handle:
win32api.TerminateProcess(handle, 0)
win32api.CloseHandle(handle)
except:
pass
...
access = CreateObject('Access.Application')
DBEngine = access.DBEngine
db = DBEngine.OpenDatabase("C:\<my_db_path>")
.... some code (working with the database) ...
close_by_force(access.Application) # this is the crucial line
As I found in web, this problem is an old one and was discussed on different topics, but I don't see the exact solution anywhere, for example:
http://www.xtremevbtalk.com/showthread.php?t=298607
In C#, How should i close running threads ( Access DB )?
http://python-list.python.narkive.com/gCMlrB8M/using-excel-with-python
Found also that I can use something like
System.Runtime.InteropServices.Marshal.ReleaseComObject(access), but I can't found any link where may I get the related Python packages to use these classes.
--
Kind Regards,
Alexander.
I'm sure this is a simple fix, but I'd like to view log messages in the PyCharm console while running a unit test. The modules I'm testing have their own loggers, and normally I'd set a root logger to catch the debugging messages at a certain level, and pipe the other logs to a file. But I can't figure out how this works with unit tests.
I'm using the unittest2 module, and using PyCharm's automatic test discovery (which probably is based on nose, but I don't know).
I've tried fooling with the run configurations, but there doesn't seem to be a straightforward way to do this.
The PyCharm documentation isn't particularly helpful here either, if any of you work there.
In edit: It DOES appear that the console catches critical level log messages. I want to know if there is a way to configure this to catch debug level messages.
This post (Pycharm unit test interactive debug command line doesn't work) suggests adding the -s option to the build configuration, which does not produce the desired result.
The only solution I've found is to do the normal logging setup at the top of the file with tests in it (assuming you're just running one test or test class): logging.basicConfig(level=logging.DEBUG). Make sure you put that before most import statements or the default logging for those modules will have already been set (that was a hard one to figure out!).
I needed to add too the option --nologcapture to nosetests as param in pycharm 2016.3.2
Run>Edit COnfigurations > Defaults > Python Tests > Nosetests : activate the check for Prams option and add --nologcapture
In Edit Configurations:
delete old configurations
go to Defaults / Python tests / NoseTests
add --nologcapture to "additional Arguments"
worked like a "charm" for me in pyCharm 2017.2.3
thanks bott
My problem was similar, I only saw messages with level WARNING or higher while running tests in PyCharm. A colleague suggested to configure the logger in __init__.py which is in the directory of my tests.
# in tests/__init__.py
import logging
import sys
# Reconfiguring the logger here will also affect test running in the PyCharm IDE
log_format = '%(asctime)s %(levelname)s %(filename)s:%(lineno)d %(message)s'
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format=log_format)
Then I can simply log in the test code like:
import logging
logging.info('whatever')
I experienced this problem all of a sudden after updating Pycharm. I had been running my tests with the Unittest runner, and all of a sudden Pycharm decided the default should be the pytest runner. When I changed the default test runner back to Unittest the logs appeared as I expected they would.
You can change the default test runner in Project Settings/Preferences >> Tools >> Python Integrated Tools
I assume adding the -nologcapture flag as noted in other answers probably would have worked in my case as well, but I prefer a solution that's exposed by the IDE rather than a manual override.
BTW choosing Unittest also solves an additional error that I got once when trying to run tests - No module named 'nose'
The -s option mentioned in the question in combination with adding the StreamHandler using stream=sys.stdout did work for me.
import logging
import sys
logger = logging.getLogger('foo')
logger.addHandler(logging.StreamHandler(stream=sys.stdout))
logger.warning('foo')
Pycharm unit test interactive debug command line doesn't work
Add a stream handler, pointing to sys.stdout if doctest or pytest is running:
import logging
import sys
logger = logging.getLogger()
def setup_doctest_logger(log_level:int=logging.DEBUG):
"""
:param log_level:
:return:
>>> logger.info('test') # there is no output in pycharm by default
>>> setup_doctest_logger()
>>> logger.info('test') # now we have the output we want
test
"""
if is_pycharm_running():
logger_add_streamhandler_to_sys_stdout()
logger.setLevel(log_level)
def is_pycharm_running()->bool:
if ('docrunner.py' in sys.argv[0]) or ('pytest_runner.py' in sys.argv[0]):
return True
else:
return False
def logger_add_streamhandler_to_sys_stdout():
stream_handler=logging.StreamHandler(stream=sys.stdout)
logger.addHandler(stream_handler)
I am working with OpenERP 6.1 and i am not able to debug the python code
by giving print statements in the python code.
This was quite easy/possible with OpenERP 6.0 where we give the server path
followed by module name and database name to debug the code.
How can i achieve this with OpenERP 6.1??
Please help!!
Thanks in advance..
Hi friend you can install ipython. Using ipython you can debug openerp 6.1 at command prompt. kindly make sure that you have installed these packages before hands.
sudo apt-get install python-dateutil python-feedparser python-gdata python-ldap python-libxslt1 python-lxml python-mako python-openid python-psycopg2 python-pybabel python-pychart python-pydot python-pyparsing python-reportlab python-simplejson python-tz python-vatnumber python-vobject python-webdav python-werkzeug python-xlwt python-yaml python-zsi
I took this list from
http://www.theopensourcerer.com/2012/02/22/how-to-install-openerp-6-1-on-ubuntu-10-04-lts/
you can also try pycharm.
To debug your Openerp+python code in eclipse, start eclipse in debug perspective and follow the given steps:
1: Stop your openERP running server by pressing "ctr+c".
2: In eclipse go to Menu "Run/Debug Configurations". In configuration window under "Python Run", create new debug configuration(Double click on 'Python Run').
3: After creating new debug configuration follow the given steps:
3.1: In "Main" tab under "Project", select the "server" project or folder (in which Openerp Server resides) from your workspace.
3.2: Write location of 'openerp-server' under "Main Module".
Ex: ${workspace_loc:server/openerp-server}.
3.3: In "Arguments" tab under "Program Arguments", click on button "Variables" and new window will appear.
3.4: Then create new "Variable" by clicking on "Edit Variables" button and new window will appear.
3.5: Press on "New" button and give your addons path as value.
Ex: --addons ../addons,../your_module_path
3.6: Press Ok in all the opened windows and then "Apply".
4: Now into "PyDev Package Explorer" view go to 6.1/server and right click on "openerp-server" file, Select 'Debug As --> Python Run'.
5: Now in "Console" you can see your server has been started.
6: Now open your .py file which you want to debug and set a break-point.
7: Now start your module's form from 'gtk' or 'web-client' and execution will stop when execution will reach to break-point.
8: Now enjoy by debugging your code by pressing "F5, F6, F7" and you can see value of your variables.
I run the 6.1 server under Eclipse and PyDev without any problems. That lets me add breakpoints and step through the code. Here are the arguments I use:
--addons-path ${workspace_loc:openerp-addons-trunk},${workspace_loc:openerp-web-trunk}/addons --config ${workspace_loc:openerp-config/src/server.config}
The two breakpoints I find most useful are at either end of the RPC call. On the server side, I put a breakpoint on this line in netsvc.dispatch_rpc():
result = ExportService.getService(service_name).dispatch(method, params)
I don't debug the client as often, and not all requests come through the same path, but one useful breakpoint is the first line of rpc.tinySocket_gw.execute().
Of course, both these breakpoints see a lot of traffic, so I only use them if I'm exploring some feature I'm not familiar with, and I don't know where the code will execute. It can also be useful to put a condition on the breakpoint so it only triggers when a request comes through for a specific model or parameter value.
Here is the config file I use:
[options]
debug_mode = False
admin_passwd = ******
db_user = ******
db_password = *******
price_accuracy = 5
smtp_server = **********
ftp_server_port = 8022
ftp_server_passive_ports = 8192:8447
translate_data = False
#log_level = debug_rpc_answer
Check that you have:
logfile = None
in your openerp-server.conf, that gives you the log through the standard output.
Does it helps ?
First: import logging
Then :
def ExampleFunction(self,cr,uid,ids,context):
log = logging.getLogger("ExampleClass -- ExampleFunction")
log.info('test')
return True
And in your openerp folder /server/server/openerp-server.log file
you will see the log.info content here ( ExampleClass -- ExampleFunction: test)