Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #81795 > unrolled thread
| Started by | Kasper Peeters <kasper.peeters@phi-sci.com> |
|---|---|
| First post | 2014-12-02 09:35 +0000 |
| Last post | 2014-12-03 19:03 +1300 |
| Articles | 2 — 2 participants |
Back to article view | Back to comp.lang.python
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: PyEval_GetLocals and unreferenced variables Kasper Peeters <kasper.peeters@phi-sci.com> - 2014-12-02 09:35 +0000
Re: PyEval_GetLocals and unreferenced variables Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-12-03 19:03 +1300
| From | Kasper Peeters <kasper.peeters@phi-sci.com> |
|---|---|
| Date | 2014-12-02 09:35 +0000 |
| Subject | Re: PyEval_GetLocals and unreferenced variables |
| Message-ID | <mailman.16488.1417513104.18130.python-list@python.org> |
> > def fun():
> > cfun_that_creates_q_in_local_scope()
> > def fun2():
> > cfun_that_wants_to_see_if_q_is_available()
> >
> > So the Python side actually doesn't see 'q' directly at all.
>
> I think you will need to elaborate.
Ok, here goes (and thanks for listening).
The behaviour of the C side is determined by certain
settings/preferences. I want these settings to respect the Python
scope. I could in principle decide to make these settings a proper
Python object, and ask the user to create one and pass it along at
every C-function call. Something like
def fun():
settings = Cpp_Options()
settings.set_some_flag()
cfun(settings, ...)
def fun2():
settings = Cpp_Options(settings)
settings.set_some_other_flag()
cfun(settings, ...)
Then Python would automatically take care of the scope of 'settings'.
However, this is difficult for the user to keep track of. So my
idea was to allow for
def fun():
set_some_flag()
cfun(...)
def fun2():
set_some_other_flag()
cfun(...)
I let the C side create a Cpp_Options object on the locals stack
behind the scenes, and the 'cfun()' function takes it from there
directly, without requiring the user to pass it. Much easier for the
user.
This works, but the problem is that the C side does not see the
settings that were created in fun() when it gets called from fun2(). In
fun2(), the locals do not contain objects constructed earlier in fun(),
unless the Python side explicitly refers to them. So adding a line
settings.do_something()
inside fun2() would work and forces Python to pull the settings object
created in fun() into scope, but that sort of defeats the purpose.
Hence my question: how can I ask, purely on the C side, for Python to
pull objects into the local frame?
Final note: I am actually trying to make this look as close as possible
to an older custom-built language, which didn't require passing the
settings object either, so it's kinda important to make the user feel
'at home'.
Hope this makes it more clear, thanks for your patience.
Cheers,
Kasper
[toc] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2014-12-03 19:03 +1300 |
| Message-ID | <ce7ndcFgk8fU1@mid.individual.net> |
| In reply to | #81795 |
Kasper Peeters wrote:
> I could in principle decide to make these settings a proper
> Python object, and ask the user to create one and pass it along at
> every C-function call.
I would make the C functions methods of the object holding
the settings. Your nested function example would then look
something like this:
def fun():
cpp = Cpp()
cpp.set_some_flag()
cpp.cfun(...)
def fun2():
cpp2 = Cpp(cpp)
cpp2.set_some_other_flag()
cpp2.fun(...)
> Hence my question: how can I ask, purely on the C side, for Python to
> pull objects into the local frame?
You can't.
Firstly, it's not possible to add locals to a frame that
didn't exist when the bytecode was compiled. The compiler
figures out how many locals there are, allocates them in
an array, and generates bytecodes that reference them by
their array index.
I'm not sure how you think you're adding a local from C
code. If you're using PyEval_GetLocals(), that only gives
you a dict containing a *copy* of the locals; modifying
that dict doesn't change the locals in the function's frame.
Secondly, the way references to outer scopes is implemented
is by effectively passing the referenced variables as
implicit parameters. If the bytecode of the nested function
doesn't reference a given variable in the outer function,
it doesn't get passed in. Again, this is determined when
the bytecode is compiled and can't be changed at run time.
> Final note: I am actually trying to make this look as close as possible
> to an older custom-built language, which didn't require passing the
> settings object either, so it's kinda important to make the user feel
> 'at home'.
I doubt it's worth the extreme level of hackery that would
be required to make it work, though. I think it would be
better to provide a clean, pythonic API that makes the
scope of the options explicit, rather than try to mimic
another language's dubious implicit scoping features.
--
Greg
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web