Developing behave steps with PyDev - python

Behave is a great tool for behavior driven development in Python. However, in combination with PyDev I've got two Problems:
PyDev can't resolve behave's #given, #when and #then annotations. This probably happens because behave does some name magic the behave package.
behave suggests to name all methods step as every method has an annotation which defines the "real" name. PyDev complains about these "duplicate" methods.
Example:
from behave import given, when, then
#given('I navigate to Google')
def step(context):
# ...
#when('I enter coffee into the search field')
def step(context):
# ...
By now, I work around both Problems by including ##PydevCodeAnalysisIgnore, which turns off any PyDev analysis. I'd like to keep PyDev analysis for all other parts of the code.
Any suggestions how to solve this?

Just a guess. Have You tried with import redefinitions?
from behave import given as given_behaviour, when as when_behaviour, then as then_behaviour
#given_behaviour('I navigate to Google')
You can also check the eclipse settings: menu Window -> Preferences -> PyDev -> Interpreters -> Python Interpreters. Sometimes it might help to remove and re-add the python interpreter if new libraries has been added after that the interpreter was configured in order to include those in the System PYTHONPATH in eclipse.
Try adding ## followed by the message in camel case to the end of the method name to turn off the warning message in PyDev. Something like:
def step(context): ##DuplicatedSignature

Related

Get Autocomplete for a special variable in python

I am using vs code for python scripts. These scripts run on the server only.
The server however, passes certain variables to the script while executing the script.
e.g mbo is always passed in it. mbo is special keyword which corresponds to a some class.
Sample mbo.py
class Mbo:
def getString(column: str)-> str:
return 'ABC'
def setString(columnName: str)-> None:
# do something with columnName.
Goal:
In my project in any python file whenever the user types mbo followed by a . vs code should show autoscomplete for .getString() and .setString() without importing this class as it is passed to the script by server.
I can try to write an extension for vs code to add this feature.
Here, I am stuck that what kind of extension is needed here. A LSP? I don't want to loose the feature of the existing python LSP for python.
Can any one proficient with vs code extension API guide me in right direction.
Note: I cannot import this Mbo class just for autocompletion in vscode because I import it. Then I run the same script on server. The server throws errors about the file.
You could try making the imports conditional:
try:
mbo
except NameError:
import mbo
That might be enough to make one of the two IntelliSense engines in the Python extension work.
Otherwise you are looking at your own extension. LSP is obviously the best option but there's also the classic style of registering classes. The VS Code docs have the details. But you are still probably going to clash with the Python extension as both it and your extension will be registered to work with Python files.

Code completion not giving recommendations

Say I'm working with the 'requests' Python library.
req = requests.get("http://google.com")
Now after this, if I type req., I'm supposed to get a list of all methods I can access. But for some reason I don't, even if I manually press Ctrl+Space.
If I try this in iPython, I get autocomplete recommendations. Even if I try it via the built in Python console in PyCharm, I get recommendations.
Why's this happening?
As Python is a dynamically typed language, you need to ensure it can work out what type things are, and inspect on the libraries on your system correctly. Try to make sure it's obvious what type the object is in your code.
One good way as of PyCharm 2.7 (back when versions were numbers) is to enable runtime type detection - PyCharm hooks into your program while it runs (while debugging), and checks the types of variables as they are used.
You can enable this by going to settings, going to the "Build, Execution, Deployment" section and then the "Python Debugger" subsection and enabling "Collect run-time types information for code insight".
Obviously it is worth noting that this isn't perfect - if you make changes, this won't be updated til the code is executed, and it can only tell you about values it has seen - other code paths you haven't tried could set other types.
You can also 'tell' PyCharm by using Epydoc or Sphinx style docstrings that contain information about parameter and return value types. PyCharm will use these to improve it's inspections.
Python also gained support for function annotations as of Python 3. These can be used for type hints as per PEP 484. See the typing module for more. This is more formal, so it can also be used for tools like mypy which a type checker that can programmatically check these types for consistency, giving Python a TypeScript-style optional static typing.
Python is a dynamically typed language, which means that the "get" function does not declare its return type. When you're entering code in IPython or in the PyCharm console, the code is actually being executed, and it's possible to inspect the object instance in the running interpreter and to get the list of its methods. When you're entering code in PyCharm or in any other Python IDE, it is not executed, and it's only possible to use static analysis to infer the return type of the method. This is not possible in all cases.
PyCharm has no idea what the dict contains if you fill it dynamically. So you have to hint PyCharm about the keys of dict beforehand. Prodict does exactly this to hint PyCharm, so you get code completion.
First, if you want to be able to access the response object, then you have to get a json response and convert it to dict. That's achieved with .json() method of requests like this:
response = requests.get("https://some.restservice.com/user/1").json()
OK, we loaded it to a dict object, now you can access keys with bracket syntax:
print(response['name'])
Since you ask for auto code completion, you certainly need to hint PyCharm about the keys of dict. If you already know the respone schema, you can use Prodict to hint PyCharm:
class Response(Prodict):
name: str
price: float
response_dict = requests.get("https://some.restservice.com/user/1").json()
response = Response.from_dict(response_dict)
print(response.name)
print(response.price)
In the above code, both name and price attributes are auto-complated.
If you don't know the schema of the response, then you can still use dot-notation to access dict attributes like this:
response_dict = requests.get("https://some.restservice.com/user/1").json()
response = Prodict.from_dict(response_dict)
print(response.name)
But code-completion will not be available since PyCharm can't know what the schema is.
What's more is, Prodict class is derived directly from dict, so you can use it as dict too.
This is the screenshot from Prodict repo that illustrates code completion:
Disclaimer: I am the author of Prodict.
if will just detect methods or variables and... with write some part of it:
File->Setting -> Editor -> General -> Code Completion
in top of opened window , unCheck [ Mach Case ]
It's an old question but probably all the provided answers missed the mark by a margin as wide as Sun's distance to Betelgeuse (none of the answers is accepted and #user1265125 is an active guy with 8 yrs here and more cred than me).
As it happens, I've just had exactly the same problem as OP and the solution was:
A NON-ASCII CHAR SOMEWHERE IN THE PROJECT'S FOLDER PATH
Seriously, PyCharm devs...[doubleFacepalm]
In my case the solution is to reset the settings, everething else wasn`t working for me.
"From the main menu, select File | Manage IDE Settings | Restore Default Settings.Alternatively, press Shift twice and type Restore default settings."
I had a similar problem. Only functions I had already used were suggested and only as plain text and not recognised as methods.
What fixed that for me was deleting the /.idea folder in the project directory. (Afterwards you will have to set your run configurations again)
With the latest version update to 2022.2, even auto-complete stopped working for me. After quite a bit of reading articles, I just found the https://youtrack.jetbrains.com/issue/PY-50489 issue which was the root problem. The old plugins were pending update, after that, the code completion issue was fixed.
So, try and check if you are facing the same problem, if the plugins are up to date in Settings —> Plugins.

pydev breakpoints not working

I am working on a project using python 2.7.2, sqlalchemy 0.7, unittest, eclipse 3.7.2 and pydev 2.4. I am setting breakpoints in python files (unit test files), but they are completely ignored (before, at some point, they worked). By now i have upgraded all related software (see above), started new projects, played around with settings, hypnotized my screen, but nothing works.
The only idea i got from some post is that it has something to de with changing some .py file names to lower case.
Does anyone have any ideas?
added: I even installed the aptana version of eclipse and copied the .py files to it => same result; breakpoints are still ignored.
still no progress: I have changed some code that might be seen as unusual and replaced it with a more straightforward solution.
some more info: it probably has something to do with module unittest:
breakpoints in my files defining test suites work,
breakpoints in the standard unittest files themselves work
breakpoints in my tests methods in classes derived from unittest.TestCase do not work
breakpoints in my code being tested in the test cases do not work
at some point before i could define working breakpoints in test methods or the code being tested
some things i changed after that are: started using test suites, changed some filenames to lowercase, ...
this problem also occurs if my code works without exceptions or test failures.
what I already tried is:
remove .pyc files
define new project and copy only .py files to it
rebooted several times in between
upgraded to eclipse 3.7.2
installed latest pydev on eclipse 3.7.2
switch to aptana (and back)
removed code that 'manually' added classes to my module
fiddled with some configurations
what I can still do is:
start new project with my code, start removing/changing code until breakpoints work and sort of black box figure out if this has something to do with some part of my code
Does anyone have any idea what might cause these problems or how they might be solved?
Is there any other place i could look for a solution?
Do pydev developers look into the questions on stackoverflow?
Is there an older version of pydev that i might try?
I have been working with pydev/eclipse for a long time and it works well for me, but without debugging i'd forced to switch IDE.
In answer to Fabio's questions below:
The python version is 2.7.2,
The sys.gettrace gives None (but I have no idea what in my code could influence that)
This is the output of the debugger after changing the suggested parameters:
pydev debugger:
starting
('Executing file ', 'D:\\.eclipse\\org.eclipse.platform_3.7.0_248562372\\plugins\\org.python.pydev.debug_2.4.0.2012020116\\pysrc\\runfiles.py')
('arguments:', "['D:\\\\.eclipse\\\\org.eclipse.platform_3.7.0_248562372\\\\plugins\\\\org.python.pydev.debug_2.4.0.2012020116\\\\pysrc\\\\runfiles.py', 'D:\\\\Documents\\\\Code\\\\Eclipse\\\\workspace\\\\sqladata\\\\src\\\\unit_test.py', '--port', '49856', '--verbosity', '0']")
('Connecting to ', '127.0.0.1', ':', '49857')
('Connected.',)
('received command ', '501\t1\t1.1')
sending cmd: CMD_VERSION 501 1 1.1
sending cmd: CMD_THREAD_CREATE 103 2 <xml><thread name="pydevd.reader" id="-1"/></xml>
sending cmd: CMD_THREAD_CREATE 103 4 <xml><thread name="pydevd.writer" id="-1"/></xml>
('received command ', '111\t3\tD:\\Documents\\Code\\Eclipse\\workspace\\sqladata\\src\\testData.py\t85\t**FUNC**testAdjacency\tNone')
Added breakpoint:d:\documents\code\eclipse\workspace\sqladata\src\testdata.py - line:85 - func_name:testAdjacency
('received command ', '122\t5\t;;')
Exceptions to hook : []
('received command ', '124\t7\t')
('received command ', '101\t9\t')
Finding files... done.
Importing test modules ... testAtomic (testTypes.TypeTest) ... ok
testCyclic (testTypes.TypeTest) ...
The rest is output of the unit test.
Continuing from Fabio's answer part 2:
I have added the code at the start of the program and the debugger stops working at the last line of following the method in sqlalchemy\orm\attributes.py (it is a descriptor, but how or whther it interferes with the debugging is beyond my current knowledge):
class InstrumentedAttribute(QueryableAttribute):
"""Class bound instrumented attribute which adds descriptor methods."""
def __set__(self, instance, value):
self.impl.set(instance_state(instance),
instance_dict(instance), value, None)
def __delete__(self, instance):
self.impl.delete(instance_state(instance), instance_dict(instance))
def __get__(self, instance, owner):
if instance is None:
return self
dict_ = instance_dict(instance)
if self._supports_population and self.key in dict_:
return dict_[self.key]
else:
return self.impl.get(instance_state(instance),dict_) #<= last line of debugging
From there the debugger steps into the __getattr__ method of one of my own classes, derived from a declarative_base() class of sqlalchemy.
Probably solved (though not understood):
The problem seemed to be that the __getattr__ mentioned above, created something similar to infinite recursion, however the program/unittest/sqlalchemy recovered without reporting any error. I do not understand the sqlalchemy code sufficiently to understand why the __getattr__ method was called.
I changed the __getattr__ method to call super for the attribute name for which the recursion occurred (most likely not my final solution) and the breakpoint problem seems gone.
If i can formulate the problem in a consise manner, i will probably try to get some more info on the google sqlalchemy newsgroup, or at least check my solution for robustness.
Thank you Fabio for your support, the trace_func() function pinpointed the problem for me.
Seems really strange... I need some more info to better diagnose the issue:
Open \plugins\org.python.pydev.debug\pysrc\pydevd_constants.py and change
DEBUG_TRACE_LEVEL = 3
DEBUG_TRACE_BREAKPOINTS = 3
run your use-case with the problem and add the output to your question...
Also, it could be that for some reason the debugging facility is reset in some library you use or in your code, so, do the following: in the same place that you'd put the breakpoint do:
import sys
print 'current trace function', sys.gettrace()
(note: when running in the debugger, it'd be expected that the trace function is something as: <bound method PyDB.trace_dispatch of <__main__.PyDB instance at 0x01D44878>> )
Also, please post which Python version you're using.
Answer part 2:
The fact that sys.gettrace() returns None is probably the real issue... I know some external libraries which mess with it (i.e.:DecoratorTools -- read: http://pydev.blogspot.com/2007/06/why-cant-pydev-debugger-work-with.html) and have even seen Python bugs and compiled extensions break it...
Still, the most common reason it breaks is probably because Python will silently disable the tracing (and thus the debugger) when a recursion throws a stack overflow error (i.e.: RuntimeError: maximum recursion depth exceeded).
You can probably put a breakpoint in the very beginning of your program and step in the debugger until it stops working.
Or maybe simpler is the following: Add the code below to the very beginning of your program and see how far it goes with the printing... The last thing printed is the code just before it broke (so, you could put a breakpoint at the last line printed knowing it should be the last line where it'd work) -- note that if it's a large program, printing may take a long time -- it may even be faster printing to a file instead of a console (such as cmd, bash or eclipse) and later opening that file (just redirect the print from the example to a file).
import sys
def trace_func(frame, event, arg):
print 'Context: ', frame.f_code.co_name, '\tFile:', frame.f_code.co_filename, '\tLine:', frame.f_lineno, '\tEvent:', event
return trace_func
sys.settrace(trace_func)
If you still can't figure it out, please post more information on the obtained results...
Note: a workaround until you don't find the actual place is using:
import pydevd;pydevd.settrace()
on the place where you'd put the breakpoint -- that way you'd have a breakpoint in code which should definitely work, as it'll force setting the tracing facility at that point (it's very similar to the remote debugging: http://pydev.org/manual_adv_remote_debugger.html except that as the debugger was already previously connected, you don't really have to start the remote debugger, just do the settrace to emulate a breakpoint)
Coming late into the conversation, but just in case it helps. I just run into a similar problem and I found that the debugger is very particular w.r.t. what lines it considers "executable" and available to break on.
If you are using line continuations, or multi-line expressions (e.g. inside a list), put the breakpoint in the last line of the statement.
I hope it helps.
Try removing the corresponding .pyc file (compiled) and then running.
Also I have sometimes realized I was running more than one instance of a program.. which confused pydev.
I've definitely seen this before too. Quite a few times.
Ran into a similar situation running a django app in Eclipse/pydev. what was happening was that the code that was running was the one installed in my virtualenv, not my source code. I removed my project from my virtual env site-packages, restarted the django up in the eclipse/pydev debugger and everything was fine.
I had similar-sounding symptoms. It turned out that my module import sequence was rexec'ing my entry-point python module because a binary (non-Python) library had to be dynamically loaded, i.e., the LD_LIBRARY_PATH was dynamically reset. I don't know why this causes the debugger to ignore subsequent breakpoints. Perhaps the rexec call is not specifying debug=true; it should specify debug=true/false based on the calling context state?
Try setting a breakpoint at your first import statement being cognizant of whether you are then s(tep)'ing into or n(ext)'ing over the imports. When I would "next" over the 3rdparty import that required the dynamic lib loading, the debug interpreter would just continue past all breakpoints.

Eclipse+PyDev+GAE memcache "Undefined variable from import: get"

I've started using Eclipe+PyDev as an environment for developing my first app for Google App Engine. Eclipse is configured according to this tutorial.
Everything was working until I start to use memcache. PyDev reports the errors and I don't know how to fix it:
Error: Undefined variable from import: get
How to fix this?
Sure, it is only PyDev checker problem. Code is correct and run on GAE.
UPDATE:
I'm using PyDev 1.5.0 but experienced the same with 1.4.8.
My PYTHONPATH includes (set in Project Properties/PyDev - PYTHONPATH):
C:\Program Files\Google\google_appengine
C:\Program Files\Google\google_appengine\lib\django
C:\Program Files\Google\google_appengine\lib\webob
C:\Program Files\Google\google_appengine\lib\yaml\lib
UPDATE 2:
I took a look at C:\Program Files\Google\google_appengine\google\appengine\api\memcache\__init__.py and found get() is not declared as memcache module function. They use the following trick to do that (I didn't hear about such possibility):
_CLIENT = None
def setup_client(client_obj):
"""Sets the Client object instance to use for all module-level methods.
Use this method if you want to have customer persistent_id() or
persistent_load() functions associated with your client.
Args:
client_obj: Instance of the memcache.Client object.
"""
global _CLIENT
var_dict = globals()
_CLIENT = client_obj
var_dict['set_servers'] = _CLIENT.set_servers
var_dict['disconnect_all'] = _CLIENT.disconnect_all
var_dict['forget_dead_hosts'] = _CLIENT.forget_dead_hosts
var_dict['debuglog'] = _CLIENT.debuglog
var_dict['get'] = _CLIENT.get
var_dict['get_multi'] = _CLIENT.get_multi
var_dict['set'] = _CLIENT.set
var_dict['set_multi'] = _CLIENT.set_multi
var_dict['add'] = _CLIENT.add
var_dict['add_multi'] = _CLIENT.add_multi
var_dict['replace'] = _CLIENT.replace
var_dict['replace_multi'] = _CLIENT.replace_multi
var_dict['delete'] = _CLIENT.delete
var_dict['delete_multi'] = _CLIENT.delete_multi
var_dict['incr'] = _CLIENT.incr
var_dict['decr'] = _CLIENT.decr
var_dict['flush_all'] = _CLIENT.flush_all
var_dict['get_stats'] = _CLIENT.get_stats
setup_client(Client())
Hmm... Any idea how to force PyDev to recognize that?
There is a cleaner solution: Try adding GAE's memcache to your forced builtins.
In your PyDev->Interpreter-Python->ForcedBuiltins window, add the "google.appengine.api.memcache" entry and apply.
Double-click on the memcache errors to check them back, they disappear!
Please make sure that system pythonpath includes google APE install directory.
I'm a bit late to the party, but you can add the following comment in all of your files that use memcache to selectively switch off pydev analysis:
##PydevCodeAnalysisIgnore
If you don't want to turn off all code analysis for your project/module, then just turn it off for that line. This answer explains that you can hit Ctrl+1 to bring up quick fix and insert ##UndefinedVariable at the end of the line.
What version of PyDev are you using? A recent one (1.5) or the old one referred by the Google tutorial?
See this thread.
There is a similar issue with PyROOT
Since PyDEV plugin does not read $HOME/.pystartup, touching functions/ classes is not a solution. Because it analyze the syntax and structures of python modules to be imported not on-the-fly but when I set the PYTHONPATH from Eclipse's preference panel.
So does your PYTHONPATH reference the Google library?
They might be an issue with code completion in 1.5 which could force you to disable code analysis: Pydev 1.5.0 code anlaysis breaks code pyqt4 code completion - ID: 2855598
have pyqt 4.5.4 installed.
Initially I had pydev 1.4.8 the open source version installed and code completion worked fine.
After updating to pydev 1.5.0, pyqt code completion stopped functioning.
After disabling the Pydev code analysis in "eclipse preferences -> pydev -> editor -> code analysis -> do code analysis?", code completion began working again for PyQt
classes etc.
This worked for me and it's different than the solutions above.
Pretty straight forward:
http://blog.kicaj.com/fixing-pydev-memcache-unresolved-import/
Just says to add the google_appengine folder to the pydev python interpreter library.
I fixed that by adding this few lines to my code on the top of my file:
from google.appengine.api import memcache
# work-around for Eclipse+PyDev+GAE memcache error
if not hasattr(memcache, 'set'):
Client=None
memcache.setup_client(Client)
memcache = Client
You can commnet it out in production version.
It's only to keep eclipse happy and to let code completion work.

How can I make the PyDev editor selectively ignore errors?

I'm using PyDev under Eclipse to write some Jython code. I've got numerous instances where I need to do something like this:
import com.work.project.component.client.Interface.ISubInterface as ISubInterface
The problem is that PyDev will always flag this as an error and say "Unresolved import: ISubInterface". The code works just fine, it's just that I'd rather not have these little white/red X-marks next to my code and have my Problems tab littered with these errors.
Is there a way I can add a magic comment or something like that to the end of the line to make PyDev ignore the false error, similar to how you can sprinkle comments like "# pylint: disable-msg=E1101" to make PyLint ignore errors?
Also, there's a possibility I'm just doing it wrong when it comes to using Java interfaces in Jython. In which case a little bit of guidance would be very much appreciated.
You can add a comment
##UnresolvedImport
##UnusedVariable
So your import becomes:
import com.work.project.component.client.Interface.ISubInterface as ISubInterface ##UnresolvedImport
That should remove the error/warning. There are other comments you can add as well.
Add the hash character # at the end of the line then with the cursor on the flagged error, press Ctrl-1. One of the options in the menu will be something like #UndefinedVariable. Adding this comment will cause PyDev to ignore the error.
You can make the ignore like the other posts suggest, but the real problem is that Pydev cannot find that class... If you add a .jar that contains that class to your PYTHONPATH it should be able to resolve it (or if you have a Java project that has that class, you should be able to mark that project as a Pydev project and add its bin folder to the project PYTHONPATH -- in which case that class should be found too).
It is not a PYTHONPATH issue. It is related to importing/using static class-internal members of a Java class. I am getting the same sort of thing all over the place e.g. when trying to use constants in java.awt.Color:
import java.awt.Color as Color
borderColor = Color.BLACK # get "Undefined variable from import: BLACK" error
There is no way I've found to import Color.BLACK in this case. Thanks to iceman for at least pointing out the ##UndefinedVariable flag. That helps a lot. Note also that this is NOT a jython problem, the code runs just fine. It's just an issue with PyDev.

Categories

Resources