473,396 Members | 2,030 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Is this possible in Python?

Hi

I wonder if Python is capable of the following: define a function which
returns its argument.
I mean:
def magic_function(arg):
...... some magic code ...

that behaves the following way:

assert magic_function(3+4)=="3+4"
assert magic_function([i for i in range(10)])=="i for i in range(10)]"

It is not trivial at all and might require some bytecode hacking that i
am unable to do myself BUT you are the experts ;-)

Alain

Mar 13 '06 #1
20 1537
al********@yahoo.fr writes:
assert magic_function(3+4)=="3+4"
assert magic_function([i for i in range(10)])=="i for i in range(10)]"

It is not trivial at all and might require some bytecode hacking that i
am unable to do myself BUT you are the experts ;-)


Guhhh... you'd want to use the traceback system and reach back into
the source code to get and parse the statement that called the magic
function, sort of like a debugger does. I don't think messing with
the bytecode would help.
Mar 13 '06 #2
Paul Rubin wrote:
al********@yahoo.fr writes:
assert magic_function(3+4)=="3+4"
assert magic_function([i for i in range(10)])=="i for i in range(10)]"

It is not trivial at all and might require some bytecode hacking that i
am unable to do myself BUT you are the experts ;-)
Guhhh... you'd want to use the traceback system and reach back into
the source code to get and parse the statement that called the magic
function, sort of like a debugger does.


That's one way
I don't think messing with
the bytecode would help.


Well, the following package

http://packages.debian.org/stable/python/decompyle

might permit something like that.
Mar 13 '06 #3

al********@yahoo.fr wrote:
Hi

I wonder if Python is capable of the following: define a function which
returns its argument.
I mean:
def magic_function(arg):
...... some magic code ...

that behaves the following way:

assert magic_function(3+4)=="3+4"
assert magic_function([i for i in range(10)])=="i for i in range(10)]"

It is not trivial at all and might require some bytecode hacking that i
am unable to do myself BUT you are the experts ;-)

Alain


Storing arguments away before they are evaluated doesn't work in
Python. You have to hack the compiler in order to access the parsetree.
You might take a look at the compiler package of the standard library
that enables access to ASTs. Thus you could define lazy evaluation and
just-in-time compilation of some particular ASTs. I do not recommend
doing this for real purposes, but it is a good excercise and sooner or
later you become an expert yourself :)

Kay

Mar 13 '06 #4

Kay Schluehr wrote:
Storing arguments away before they are evaluated doesn't work in
Python. You have to hack the compiler in order to access the parsetree.
You might take a look at the compiler package of the standard library
that enables access to ASTs. Thus you could define lazy evaluation and
just-in-time compilation of some particular ASTs. I do not recommend
doing this for real purposes, but it is a good excercise and sooner or
later you become an expert yourself :)

Kay


I made some investigation and reached a (partial) solution to my
problem. It is inspired from a cookbook recipe but it only works for
generator expressions.:
import tokenize
import token
def magic_function(s):
cursor = None # to be set to the cursor of the connection
return_type = object # can be set to dict or list
_iterating = False # used in next()
readline = open(s.gi_frame.f_code.co_filename).readline
first_line = s.gi_frame.f_code.co_firstlineno
flag = False
source = '' # the source code
for t in
tokenize.generate_tokens(open(s.gi_frame.f_code.co _filename).readline):
# check all tokens until the last parenthesis is closed
t_type,t_string,(r_start,c_start),(r_end,c_end),li ne = t
t_name = token.tok_name[t_type]
if r_start == first_line:
if t_name == 'NAME' and t_string=="magic_function":
flag = True
res = t_string
start = 0 # number of parenthesis
continue
if flag:
source += ' '+t_string
if t_name == 'OP':
if t_string=='(':
start += 1
elif t_string == ')':
start -= 1
if start == 0:
break
return source[2:-2]

assert magic_function(i+2 for i in [1,2])=="i+2 for i in [1,2]"
or
print magic_function(i+2 for i in [1,2])

A general solution is possible and i am sure there are people around
that will provide such a solution

Alain

Mar 13 '06 #5
In article <11**********************@p10g2000cwp.googlegroups .com>,
al********@yahoo.fr wrote:
Hi

I wonder if Python is capable of the following: define a function which
returns its argument.
I mean:
def magic_function(arg):
...... some magic code ...

that behaves the following way:

assert magic_function(3+4)=="3+4"
assert magic_function([i for i in range(10)])=="i for i in range(10)]"

It is not trivial at all and might require some bytecode hacking that i
am unable to do myself BUT you are the experts ;-)

Alain


You probably want to learn Lisp, where what you want to do is trivial:

(defmacro magic (arg) arg)

rg
Mar 13 '06 #6

<al********@yahoo.fr> wrote in message
news:11**********************@p10g2000cwp.googlegr oups.com...
Hi

I wonder if Python is capable of the following: define a function which
returns its argument.
I mean:
def magic_function(arg):
...... some magic code ...

that behaves the following way:

assert magic_function(3+4)=="3+4"
assert magic_function([i for i in range(10)])=="i for i in range(10)]"


The arguments to Python functions are Python objects. In order to return
the argument as a string, you must pass it as a string.
def magic(s): return s, eval(s) magic('3+4') ('3+4', 7) magic('[i**2 for i in [1,2,3]]')

('[i**2 for i in [1,2,3]]', [1, 4, 9])

Terry Jan Reedy

Mar 13 '06 #7
Hi

I don't think this is what you want (a string representation of the
argument passed to a function as that argument is at runtime is way
beyond my abilities), but this can retrieve the literal text in the
function call as it appears in the .py file, assuming you have the .py
file available and not just the .pyc:

### Call this file "pyfunargtest.py"
def fun(i):
pass

fun(8+7)

def test():
fname = 'pyfunargtest.py'
testfunname = 'f'
flines = open(fname,'r').readlines()
for i in flines:
if i.find(testfunname)>-1 and i.find('def '+testfunname)==-1:
s = i
break
leftbracketposition = s.find('(')
rightbracketposition = s.find(')')
arg = s[leftbracketposition+1:rightbracketposition]
return arg

print test()
### Output:
# 8+7

al********@yahoo.fr wrote:
Hi

I wonder if Python is capable of the following: define a function which
returns its argument.
I mean:
def magic_function(arg):
...... some magic code ...

that behaves the following way:

assert magic_function(3+4)=="3+4"
assert magic_function([i for i in range(10)])=="i for i in range(10)]"

It is not trivial at all and might require some bytecode hacking that i
am unable to do myself BUT you are the experts ;-)

Alain

Mar 13 '06 #8
Hello again,
I am disappointed. You are the experts, you've got to try harder ;-)
What i want is a generalisation of this tiny function:
import tokenize
import token
def magic_function(s):
readline = open(s.gi_frame.f_code.co_filename).readline
for t in
tokenize.generate_tokens(open(s.gi_frame.f_code.co _filename).readline):
t_type,t_string,(r_start,c_start),(r_end,c_end),li ne = t
if r_start == s.gi_frame.f_code.co_firstlineno:
if t_string=="magic_function":
args= line.split(t_string)
arg=args[1]
return arg
# returns its own argument !
print magic_function(i+2 for i in [1,2])

There ought to be a way to make it work for more than generator
expressions !!!

Mar 13 '06 #9
al********@yahoo.fr wrote:
Hello again,
I am disappointed. You are the experts, you've got to try harder ;-)
What i want is a generalisation of this tiny function:


Why? Maybe we can find a better way...

Kent
Mar 13 '06 #10
Hi Kent,
My intention is to be able to retrieve any line of code in a running
program, in the following way:
def magic_funct(s):
for line in file(s.gi_frame.f_code.co_filename):
print line
magic_funct(i for i in [1,2,3])

I just find it stupid to be obliged to use a generator expression, just
because it has got the gi_frame attribute. Such a kind of introspection
can be very useful.
I don't want a better way, i just want a solution to the problem as
described!

Alain

Mar 13 '06 #11
al********@yahoo.fr writes:
I don't want a better way, i just want a solution to the problem as
described!


I once did something like:

try:
raise ValueError
except ValueError, e:
pass

then get the traceback object out of e, and snarf the relevant source
line as mentioned before.
Mar 13 '06 #12
al********@yahoo.fr wrote:
I don't want a better way, i just want a solution to the problem as
described!


any special reason you cannot use Python to write Python programs,
instead of demanding that someone else wastes time inventing a non-
portable solution to a braindead problem?

what's wrong with you?

</F>

Mar 13 '06 #13
On 2006-03-13, al********@yahoo.fr <al********@yahoo.fr> wrote:
Hello again,
I am disappointed.


Yea, life's like that.

Sucks, eh?

--
Grant Edwards grante Yow! ... The waitress's
at UNIFORM sheds TARTAR SAUCE
visi.com like an 8" by 10" GLOSSY...
Mar 13 '06 #14
You might like the version here:
http://www.jorendorff.com/toys/out.html

Especially the "need to know" presentation, which is cute

--
Alan
http://aivipi.blogspot.com

Mar 14 '06 #15
"jalanb" wrote:
You might like the version here:
http://www.jorendorff.com/toys/out.html
which only works if 1) you're using a Python implementation that supports
those attributes, 2) the source code is available, 3) the expression is written
on a single line, and 4) you don't use confusing comments after the function
call (and probably some more things I cannot think of right now).

perfectly valid Python constructs like

out(
temp
)

or

out(temp) # XXX: should use gettemp() instead

breaks the function.
Especially the "need to know" presentation, which is cute


indeed.

</F>

Mar 14 '06 #16

jalanb wrote:
You might like the version here:
http://www.jorendorff.com/toys/out.html

Especially the "need to know" presentation, which is cute

--
Alan
http://aivipi.blogspot.com


Thank you for the tip.
Meanwhile, I found a shorter solution to my problem:
def magic(arg):
import inspect
return inspect.stack()[1][4][0].split("magic")[-1][1:-1]

assert magic(3+4)=="3+4"

Alain

Mar 14 '06 #17

al********@yahoo.fr wrote:
jalanb wrote:
You might like the version here:
http://www.jorendorff.com/toys/out.html

Especially the "need to know" presentation, which is cute

--
Alan
http://aivipi.blogspot.com


Thank you for the tip.
Meanwhile, I found a shorter solution to my problem:
def magic(arg):
import inspect
return inspect.stack()[1][4][0].split("magic")[-1][1:-1]

assert magic(3+4)=="3+4"

Alain


Does it? Using your function I keep an assertion error. Storing the
return value of magic()in a variable s I receive the following result:

def magic(arg):
import inspect
return inspect.stack()[1][4][0].split("magic")[-1][1:-1]

s = magic(3+4) # magic line
s

'lin'
BTW grepping the stack will likely cause context sensitive results.

Kay

Mar 14 '06 #18

Kay Schluehr wrote:
al********@yahoo.fr wrote:
jalanb wrote:
You might like the version here:
http://www.jorendorff.com/toys/out.html

Especially the "need to know" presentation, which is cute

--
Alan
http://aivipi.blogspot.com


Thank you for the tip.
Meanwhile, I found a shorter solution to my problem:
def magic(arg):
import inspect
return inspect.stack()[1][4][0].split("magic")[-1][1:-1]

assert magic(3+4)=="3+4"

Alain


Does it? Using your function I keep an assertion error. Storing the
return value of magic()in a variable s I receive the following result:

def magic(arg):
import inspect
return inspect.stack()[1][4][0].split("magic")[-1][1:-1]

s = magic(3+4) # magic line
s

'lin'
BTW grepping the stack will likely cause context sensitive results.

Kay

This is no production-ready code, just a proof of concept.
Adding 3 or 4 lines would make it more robust.
Just hope someone else will benefit from this discussion.

Alain

Mar 14 '06 #19
On Tue, 14 Mar 2006 13:33:01 -0800, alainpoint wrote:

Kay Schluehr wrote:
al********@yahoo.fr wrote:
> jalanb wrote:
> > You might like the version here:
> > http://www.jorendorff.com/toys/out.html
> >
> > Especially the "need to know" presentation, which is cute
> >
> > --
> > Alan
> > http://aivipi.blogspot.com
>
> Thank you for the tip.
> Meanwhile, I found a shorter solution to my problem:
> def magic(arg):
> import inspect
> return inspect.stack()[1][4][0].split("magic")[-1][1:-1]
>
> assert magic(3+4)=="3+4"
>
> Alain


Does it? Using your function I keep an assertion error. Storing the
return value of magic()in a variable s I receive the following result:

def magic(arg):
import inspect
return inspect.stack()[1][4][0].split("magic")[-1][1:-1]

s = magic(3+4) # magic line
>>> s

'lin'
BTW grepping the stack will likely cause context sensitive results.

Kay

This is no production-ready code, just a proof of concept.
Adding 3 or 4 lines would make it more robust.
Just hope someone else will benefit from this discussion.


Doesn't work for me either:
def magic(arg): .... import inspect
.... return inspect.stack()[1][4][0].split("magic")[-1][1:-1]
.... magic(3+4)

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in magic
TypeError: unsubscriptable object
Kay gets an AssertionError, I get a TypeError. I think describing it as
"proof of concept" is rather optimistic.

Here is the inspect.stack() I get:

[(<frame object at 0x825d974>, '<stdin>', 2, 'magic', None, None),
(<frame object at 0x8256534>, '<stdin>', 1, '?', None, None)]
--
Steven.

Mar 14 '06 #20

Steven D'Aprano wrote:

Doesn't work for me either:
def magic(arg): ... import inspect
... return inspect.stack()[1][4][0].split("magic")[-1][1:-1]
... magic(3+4)

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in magic
TypeError: unsubscriptable object
Kay gets an AssertionError, I get a TypeError. I think describing it as
"proof of concept" is rather optimistic.

Here is the inspect.stack() I get:

[(<frame object at 0x825d974>, '<stdin>', 2, 'magic', None, None),
(<frame object at 0x8256534>, '<stdin>', 1, '?', None, None)]
--
Steven.


You just proved what i was saying: this is no robust code. It
apparently does not work from the command line. It has problems with
comments on the same line. It might have problems with multi-line
arguments, etc ....
Please feel free to improve the above function and make it robust.
(meanwhile, i removed the SOLUTION FOUND from the subject title, until
you come up with such a robust version ;-))
Alain

Mar 15 '06 #21

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Pierre Rouleau | last post by:
I have a GUI application written in Python (with WxPython) which uses some low level classes also written in Python. These low level Python classes are given a pointer to some GUI Python object. ...
5
by: AMD | last post by:
Hi, I need to write a Win32 DLL and I would like to use Python instead of VB, C++ or Delphi. Is this possible? Thank you, Andre M. Descombes
5
by: Maurice Ling | last post by:
Hi, I have read that this had been asked before but there's no satisfactory replies then. I have a module (pA) written in python, which originally is called by another python module (pB), and...
3
by: Xah Lee | last post by:
20050226 exercise: generate all possible pairings given a list that is a set partitioned into subsets, generate a list of all possible pairings of elements in any two subset. Example: ...
9
by: Evil Bastard | last post by:
Hi, Has anyone done any serious work on producing a subset of python's language definition that would suit it to a tiny microcontroller environment? In its full form, python is a resource...
5
by: sylcheung | last post by:
Is it possible to use python to unit test C++ code? If yes, is there any example available? Thank you.
1
by: Joe Peterson | last post by:
I've been doing a lot of searching on the topic of one of Python's more disturbing issues (at least to me): the fact that if a __del__ finalizer is defined and a cyclic (circular) reference is...
1
by: gregory.lielens | last post by:
Hello, We are currently writing python bindings to an existing C++ library, and we encountered a problem that some of you may have solved (or that has found unsolvable :( ): A C++ class...
25
by: jwrweatherley | last post by:
I'm pretty new to python, but am very happy with it. As well as using it at work I've been using it to solve various puzzles on the Project Euler site - http://projecteuler.net. So far it has not...
71
by: Jack | last post by:
I understand that the standard Python distribution is considered the C-Python. Howerver, the current C-Python is really a combination of C and Python implementation. There are about 2000 Python...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.