Replace gevent.spawn_link_exception - gevent

This old code makes a call to gevent.spawn_link_exception which no longer exists:
def start(self, checkpoint=None):
for gl in self._greenlets:
gl.kill()
self.load_config()
self._greenlets = [
gevent.spawn_link_exception(self.periodic_checkpoint, 5) ]
for master_uri in self._config:
self._greenlets.append(
gevent.spawn_link_exception(
self.replicate, master_uri, checkpoint))
Please help me to update this code so that it works with the latest version of gevent. Thanks.

You can approach the same thing via Greenlet.link_exception method. Here is your modified example:
def start(self, checkpoint=None):
for gl in self._greenlets:
gl.kill()
self.load_config()
def exception_callback(greenlet):
print "Exception happened in ", greenlet
self._greenlets = [gevent.spawn(self.periodic_checkpoint, 5)]
self._greenlets[-1].link_exception(exception_callback)
for master_uri in self._config:
self._greenlets.append(gevent.spawn(self.replicate, master_uri, checkpoint))
self._greenlets[-1].link_exception(exception_callback)

Related

Pyautogui and pyscreeze crash with windll.user32.ReleaseDC failed

I'm trying to compare certain pixel values in my pyautogui script, but it crashes with following error message after either multiple successful runs, or sometimes just straight on the first call:
Traceback (most recent call last):
File "F:\Koodit\Python\HeroWars NNet\Assets\autodataGet.py", line 219, in <module>
battle = observeBattle()
File "F:\Koodit\Python\HeroWars NNet\Assets\autodataGet.py", line 180, in observeBattle
statii = getHeroBattlePixels()
File "F:\Koodit\Python\HeroWars NNet\Assets\autodataGet.py", line 32, in getHeroBattlePixels
colormatch = pyautogui.pixelMatchesColor(location[0], location[1], alive, tolerance=5)
File "E:\Program Files\Python\lib\site-packages\pyscreeze\__init__.py", line 557, in pixelMatchesColor
pix = pixel(x, y)
File "E:\Program Files\Python\lib\site-packages\pyscreeze\__init__.py", line 582, in pixel
return (r, g, b)
File "E:\Program Files\Python\lib\contextlib.py", line 120, in __exit__
next(self.gen)
File "E:\Program Files\Python\lib\site-packages\pyscreeze\__init__.py", line 111, in __win32_openDC
raise WindowsError("windll.user32.ReleaseDC failed : return 0")
OSError: windll.user32.ReleaseDC failed : return 0
My code (this is called multiple times, sometimes it crashes on first run, sometimes it runs nicely for around 100 calls before failing, also, my screen is 4K, so the resolutions get big):
def getSomePixelStatuses():
someLocations= [
[1200, 990],
[1300, 990],
[1400, 990],
[1500, 990],
[1602, 990],
[1768, 990],
[1868, 990],
[1968, 990],
[2068, 990],
[2169, 990]
]
status = []
someValue= (92, 13, 12)
for location in someLocations:
colormatch = pyautogui.pixelMatchesColor(location[0], location[1], someValue, tolerance=5)
status.append(colormatch)
return status
I have no idea how to mitigate this problem. It would seem that pyautogui uses pyscreeze to read pixel values on screen, and most probable candidate for the place where error occurs is the pyscreeze pixel function:
def pixel(x, y):
"""
TODO
"""
if sys.platform == 'win32':
# On Windows, calling GetDC() and GetPixel() is twice as fast as using our screenshot() function.
with __win32_openDC(0) as hdc: # handle will be released automatically
color = windll.gdi32.GetPixel(hdc, x, y)
if color < 0:
raise WindowsError("windll.gdi32.GetPixel failed : return {}".format(color))
# color is in the format 0xbbggrr https://msdn.microsoft.com/en-us/library/windows/desktop/dd183449(v=vs.85).aspx
bbggrr = "{:0>6x}".format(color) # bbggrr => 'bbggrr' (hex)
b, g, r = (int(bbggrr[i:i+2], 16) for i in range(0, 6, 2))
return (r, g, b)
else:
# Need to select only the first three values of the color in
# case the returned pixel has an alpha channel
return RGB(*(screenshot().getpixel((x, y))[:3]))
I installed these libraries just yesterday, and I'm running python 3.8 on windows 10, and pyscreeze is version 0.1.25 so in theory everything should be up to date, but somehow something ends up crashing. Is there a way to mitigate this, either modifying my code, or even the library itself, or is my environment not suitable for this operation?
Well I know it's not particularly helpful; but for me, this error was fixed simply by running my code on 3.7 instead of 3.8. There shouldn't be any changes you have to make to your code, however (unless you were using walrus!)
On Windows, this can be done with the -3.7 command line flag, as long as 3.7 is installed
PyScreeze and PyAutoGUI maintainer here. This is an issue that has been fixed in PyScreeze 0.1.28, so you just need to update it by running pip install -U pyscreeze.
For more context, here's the GitHub issue where it was reported: https://github.com/asweigart/pyscreeze/pull/73
It's a bug. You were on the right track, as the problem is indeed in this line of the pixel() function:
with __win32_openDC(0) as hdc
That function uses cyptes.windll which doesn't seem to do well with the negative values sometimes returned from windll.user32.GetDC(), which subsequently creates an exception when windll.user32.ReleaseDC() is called.
The folks at pillow helped track this down and propose a fix.
issue filed at pyautogui
issue filed at pillow which led to the solution
pending PR at pyscreeze to address
I can use pixel function on Python 3.8 like this:
try:
a = pixel(100,100)
> except:
> a = pixel(100,100)
I don't have any clue why this works, but it works.
I had this error too and i fixed it. Just use try and except.
While true:
try:
x,y = pyautogui.position()
print(pyautogui.pixel(x,y))
except:
print("Cannot get pixel for the moment")
Given that you might be taking pixels multiple times, or you can do so, try and except works wonders to solve any pyscreeze for pyautogui issue. Honestly i dont know whats up with pyscreeze, but this works for me. Cheers

Problem with get_children() method when using TreeManager. Wrong result

I have encountered an strange problem with the use of TreeManager
Here is my code:
# other imports
from mptt.models import MPTTModel, TreeForeignKey
from mptt.managers import TreeManager
class SectionManager(TreeManager):
def get_queryset(self):
return super().get_queryset().filter(published=True)
class Section(MPTTModel):
published = models.BooleanField(
default=True,
help_text="If unpublished, this section will show only"
" to editors. Else, it will show for all."
)
objects = TreeManager()
published_objects = SectionManager()
When I test it. I get the following correct results:
# show all objects
Section.objects.count() # result is correct - 65
Section.objects.root_nodes().count() # result is correct - 12
# show published objects, just one is not published.
Section.published_objects.count() # result is correct - 64
Section.published_objects.root_nodes().count() # result is corrct - 12
But one child of the roots is unpublished and it does not show in the results. Here is the test:
for root in Section.objects.root_nodes():
print(f"root_section_{root.id} has {root.get_children().count()} children")
# results ...
root_section_57 has 13 children # correct - 13 items
# ... more results
for root in Section.published_objects.root_nodes():
print(f"root_section_{root.id} has {root.get_children().count()} children")
# results ...
root_section_57 has 13 children # WRONG - should be only 12 children
# ... more results
I may not understand something, or I may have hit a bug??
Any ideas?
NOTE: This issue has been posted on the django-mptt github issues page at: https://github.com/django-mptt/django-mptt/issues/689
https://github.com/django-mptt/django-mptt/blob/master/mptt/managers.py
You override wrong function call. root_nodes() call ._mptt_filter()
#delegate_manager
def root_nodes(self):
"""
Creates a ``QuerySet`` containing root nodes.
"""
return self._mptt_filter(parent=None)
And your _mptt_filter does not got any given qs.
#delegate_manager
def _mptt_filter(self, qs=None, **filters):
"""
Like ``self.filter()``, but translates name-agnostic filters for MPTT
fields.
"""
if qs is None:
qs = self
return qs.filter(**self._translate_lookups(**filters))
Now you need to customized based on your use case.
Hope it can be some help

Elixir: Nebulex (Caching library) error

I'm new to Elixir, trying to use Nebulex for making a simple local cache (Panda.Cache). I followed its tutorial but finally, by doing these commands:
data = %{id: 1, text: "hello"}
Mycache.set(data[:id], data)
I get this error:
** (ArgumentError) argument error
(stdlib) :ets.lookup_element(Panda.Cache, :metadata, 2)
(nebulex) lib/nebulex/adapters/local/metadata.ex:19: Nebulex.Adapters.Local.Metadata.get/1
(nebulex) lib/nebulex/adapters/local.ex:177: Nebulex.Adapters.Local.set/4
(panda) lib/panda/cache.ex:2: Panda.Cache.execute/2
Panda is the name of my Elixir app and Panda.Cache the name of the cache I'm trying to make.
Any help or solution would be appreciated. Thank you in advance.
Update:
Project folders and files are like:
panda
config
config.exs
lib
panda.ex
panda
application.ex
cache.ex
config.exs file:
use Mix.Config
config :panda, Panda.Cache,
adapter: Nebulex.Adapters.Local,
gc_interval: 86_400 # 24 hrs
cache.ex file:
defmodule Panda.Cache do
use Nebulex.Cache, otp_app: :panda
end
application.ex file:
defmodule Panda.Application do
use Application
def start(_type, _args) do
import Supervisor.Spec
children = [
supervisor(Panda.Cache, [])
]
opts = [strategy: :one_for_one, name: Panda.Supervisor]
Supervisor.start_link(children, opts)
end
end
And, how I tried to use the cache in my code:
defmodule Panda do
def mytest do
data = %{id: 1, text: "hello"}
Panda.Cache.set(data[:id], data)
end
end
According to your code in GitHub (https://github.com/ab00zar/FirstElixirCode), in the mix.exs file you are missing the app module, currently it is like this:
def application do
[
extra_applications: [:logger]
]
end
But it should be like this:
def application do
[
extra_applications: [:logger],
mod: {Panda.Application, []}
]
end
Because of this, your app (and supervision tree) it is not being started and the cache (Nebulex) is started as part of your supervision tree. Let me know if that works for you.
I tried the code you posted, but I cannot replicate the error.
When something like this happens I often do the following:
mix deps.clean --all
mix clean
mix deps.get
mix deps.compile
mix compile
and then I try again.
I hope this helps :)

ExecJS: keeping the context between two calls

I'm currently trying to use ExecJS to run Handlebars for one of the product I work on (note: I know the handlebars.rb gem which is really cool and I used it for some times but there is issues to get it installed on Windows, so I try another homemade solution).
One of the problem I'm having is that the Javascript context is not kept between each "call" to ExecJS.
Here the code where I instantiate the #js attribute:
class Context
attr_reader :js, :partials, :helpers
def initialize
src = File.open(::Handlebars::Source.bundled_path, 'r').read
#js = ExecJS.compile(src)
end
end
And here's a test showing the issue:
let(:ctx) { Hiptest::Handlebars::Context.new }
it "does not keep context properly (or I'm using the tool wrong" do
ctx.js.eval('my_variable = 42')
expect(ctx.js.eval('my_variable')).to eq(42)
end
And now when I run it:
rspec spec/handlebars_spec.rb:10 1 ↵
I, [2015-02-21T16:57:30.485774 #35939] INFO -- : Not reporting to Code Climate because ENV['CODECLIMATE_REPO_TOKEN'] is not set.
Run options: include {:locations=>{"./spec/handlebars_spec.rb"=>[10]}}
F
Failures:
1) Hiptest::Handlebars Context does not keep context properly (or I'm using the tool wrong
Failure/Error: expect(ctx.js.eval('my_variable')).to eq(42)
ExecJS::ProgramError:
ReferenceError: Can't find variable: my_variable
Note: I got the same issue with "exec" instead of "eval".
That is a silly example. What I really want to do it to run "Handlebars.registerPartial" and later on "Handlebars.compile". But when trying to use the partials in the template it fails because the one registered previously is lost.
Note that I've found a workaround but I find it pretty ugly :/
def register_partial(name, content)
#partials[name] = content
end
def call(*args)
#context.js.call([
"(function (partials, helpers, tmpl, args) {",
" Object.keys(partials).forEach(function (key) {",
" Handlebars.registerPartial(key, partials[key]);",
" })",
" return Handlebars.compile(tmpl).apply(null, args);",
"})"].join("\n"), #partials, #template, args)
end
Any idea on how to fix the issue ?
Only the context you create when you call ExecJS.compile is preserved between evals. Anything you want preserved needs to be part of the initial compile.

dajaxice: passing an argument to a python function

Using Dajaxice I want to pass a parameter to a python function.
In the html file I have the following statement
<i class="icon"></i>
and in my ajax.ps file I have the function
#dajaxice_register
def sayhello(request, dir):
print(dir)
It works fine if I remove the second argument dir in both the html and the python file, but with having dir, I get the error message "Something goes wrong".
Does anybody know what could be the issue here?
if you use Python 3.*, then in module dajaxIce make the changes file venv/lib/python3.2/site-packages/dajaxice/views.py
def safe_dict(d):
"""
Recursively clone json structure with UTF-8 dictionary keys
http://www.gossamer-threads.com/lists/python/bugs/684379
"""
if isinstance(d, dict):
return dict([(k, safe_dict(v)) for k, v in d.items()])
elif isinstance(d, list):
return [safe_dict(x) for x in d]
else:
return d
change the sayhello to :
def sayhello(request):
my_dict=json.loads(request.POST['argv'])
dir=my_dict['dir']
print(dir)

Resources