Re: Python 3.12.1, Windows 11: shebang line #!/usr/bin/env python3 doesn't work any more

2024-01-03 Thread Barry Scott via Python-list



> On 2 Jan 2024, at 17:24, Thomas Passin via Python-list 
>  wrote:
> 
> You might learn about this if you happen to read and remember the right part 
> of the Python docs.  Otherwise you have no idea what py.exe is up to nor how 
> it does it.  I would say that most people don't know there's an ini file, let 
> alone what it can do.  Of course this situation isn't unique to py.exe!

On discuss.python.org we will share the link to the python windows docs and
often to this specific section: 
https://docs.python.org/3/using/windows.html#python-launcher-for-windows

To create a py.ini does require a user to understand what %localappdata% means.
Some windows users, reasonable, do not use the CLI and know about that syntax 
for environment variables.

Barry


-- 
https://mail.python.org/mailman/listinfo/python-list


Using my routines as functions AND methods

2024-01-03 Thread Guenther Sohler via Python-list
Hi,

In my cpython i have written quite some functions to modify "objects".
and their python syntax is e.g.\

translate(obj, vec). e.g whereas obj is ALWAYS first argument.

on c side this functions looks like:
PyObject *python_translate(PyObject *self, PyObject *args, PyObject *kwargs)

this works great when specifying a list of functions in PyModuleDef
structure.

However, I also want to use these functions as class methods without having
to
write the function , twice. When using the SAME function as a methos, the
args tuple must insert/contain "self" in the first location, so i have
written a function to do that:

PyObject *python_oo_args(PyObject *self, PyObject *args) // returns new
reference,
{
  int i;
  PyObject *item;
  int n = PyTuple_Size(args);
  PyObject *new_args = PyTuple_New(n + 1);
  PyTuple_SetItem(new_args, 0, self);

  for (i = 0; i < PyTuple_Size(args); i++) {
item = PyTuple_GetItem(args, i);
PyTuple_SetItem(new_args, i + 1, item);
  }
  return new_args;
}

To fill in method array, i have created a #define like this:

#define OO_METHOD_ENTRY(name,desc) \
  { #name, (PyCFunction) ( [ ] (PyObject *self, PyObject *args) -> PyObject
* { \
  PyObject *new_args = python_oo_args(self, args); \
  PyObject *result = python_##name(self, new_args, NULL); \
  return result;  } ),  METH_VARARGS | METH_KEYWORDS, (desc)},

(this uses a lambda function)

and use this in the array as:

PyMethodDef PyOpenSCADMethods[] = {
  OO_METHOD_ENTRY(translate,"Move Object")
  OO_METHOD_ENTRY(right,"Right Object")

Using this  i can reuse all the functions as methods,
but its not 100% stable/bulletproof and crashes sometimes.
So there is the bug ?
Is there a better approach to reach my goal ?


thank you
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Using my routines as functions AND methods

2024-01-03 Thread Alan Gauld via Python-list
On 03/01/2024 22:47, Guenther Sohler via Python-list wrote:
> Hi,
> 
> In my cpython i have written quite some functions to modify "objects".
> and their python syntax is e.g.\
> 
> translate(obj, vec). e.g whereas obj is ALWAYS first argument.

> However, I also want to use these functions as class methods without having
> to
> write the function , twice. When using the SAME function as a methos, the
> args tuple must insert/contain "self" in the first location, so i have
> written a function to do that:

I'm probably missing something obvious here but can't you
just assign your function to a class member?

def myFunction(obj, ...): ...

class MyClass:
myMethod = myFunction


Then you can call it as

myObject = MyClass()
myObject.myMethod()

A naive example seems to work but I haven't tried anything
complex so there is probably a catch. But sometimes the simple
things just work?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Using my routines as functions AND methods

2024-01-03 Thread Thomas Passin via Python-list

On 1/3/2024 11:17 PM, Thomas Passin wrote:

On 1/3/2024 8:00 PM, Alan Gauld via Python-list wrote:

On 03/01/2024 22:47, Guenther Sohler via Python-list wrote:

Hi,

In my cpython i have written quite some functions to modify "objects".
and their python syntax is e.g.\

translate(obj, vec). e.g whereas obj is ALWAYS first argument.


However, I also want to use these functions as class methods without 
having

to
write the function , twice. When using the SAME function as a methos, 
the

args tuple must insert/contain "self" in the first location, so i have
written a function to do that:


I'm probably missing something obvious here but can't you
just assign your function to a class member?

def myFunction(obj, ...): ...

class MyClass:
 myMethod = myFunction


Then you can call it as

myObject = MyClass()
myObject.myMethod()

A naive example seems to work but I haven't tried anything
complex so there is probably a catch. But sometimes the simple
things just work?


That works if you assign the function to a class instance, but not if 
you assign it to a class.


def f1(x):
     print(x)
f1('The plain function')

class Class1:
     pass

class Class2:
     pass

c1 = Class1()
c1.newfunc = f1
c1.newfunc('f1 assigned to instance') # Works as intended

Class2.newfunc = f1
c2 = Class2()
c2.newfunc('f1 assigned to class')  # Complains about extra argument


If your requirements are not very tricky, you can write a 
convert-to-method function yourself:


def f1(x):
print(x)
f1('The plain function')

class Class2:
pass

def convert_method(f):
"""Assign existing method without a "self" arg
   as a class's method.
"""
def fnew(instance, *args):
f(*args)
return fnew

Class2.newfunc = convert_method(f1)
c2 = Class2()
c2.newfunc('f1 assigned as method of Class2') # Prints the arg

This example does not make f1 aware of the self argument, but you asked 
to convert an existing function, and that function would not be aware of 
the self parameter. It's much like a decorator function, but is not here 
being used as a decorator. If you meant something else, please think out 
what you want and explain that.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Using my routines as functions AND methods

2024-01-03 Thread Guenther Sohler via Python-list
Thank you for your answers.
apparently I did not express myself clear enough. Let me rephrase.

I got an embedded  C function like this:

==
PyObject *python_translate(PyObject *self, PyObject *args, PyObject *kwargs)
{
  char *kwlist[] = {"obj", "v", NULL};
  PyObject *v = NULL;
  PyObject *obj = NULL;
  double x = 0, y = 0, z = 0;
  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist,
   &obj,
   &v
   )) {
PyErr_SetString(PyExc_TypeError, "Error during parsing
translate(object,vec3)");
return NULL;
  }
...

PyMethodDef PyOpenSCADFunctions[] = {
  {"translate", (PyCFunction) python_translate, METH_VARARGS |
METH_KEYWORDS, "Move  Object."},
 ...

static PyModuleDef OpenSCADModule = {
  PyModuleDef_HEAD_INIT,
  "openscad",
  "OpenSCAD Python Module",
  -1,
  PyOpenSCADFunctions,
...
};


From within python i can successfully use it with

translate(my_object, [2,0,0])

my_object is an instance of embedded class PyOpenSCADType, so alternatively
I want to use my function as method too, like so:

my_object.translate([2,0,0])

WITHOUT duplicating the code for python_translate

So the idea is to call the translate-function from within the translate
method and insert "self" into the args tuple.
However my solution somewhat works but is not very stable and quite prone
to crash.

Which are my alertnatives ?


On Wed, Jan 3, 2024 at 11:47 PM Guenther Sohler 
wrote:

> Hi,
>
> In my cpython i have written quite some functions to modify "objects".
> and their python syntax is e.g.\
>
> translate(obj, vec). e.g whereas obj is ALWAYS first argument.
>
> on c side this functions looks like:
> PyObject *python_translate(PyObject *self, PyObject *args, PyObject
> *kwargs)
>
> this works great when specifying a list of functions in PyModuleDef
> structure.
>
> However, I also want to use these functions as class methods without
> having to
> write the function , twice. When using the SAME function as a methos, the
> args tuple must insert/contain "self" in the first location, so i have
> written a function to do that:
>
> PyObject *python_oo_args(PyObject *self, PyObject *args) // returns new
> reference,
> {
>   int i;
>   PyObject *item;
>   int n = PyTuple_Size(args);
>   PyObject *new_args = PyTuple_New(n + 1);
>   PyTuple_SetItem(new_args, 0, self);
>
>   for (i = 0; i < PyTuple_Size(args); i++) {
> item = PyTuple_GetItem(args, i);
> PyTuple_SetItem(new_args, i + 1, item);
>   }
>   return new_args;
> }
>
> To fill in method array, i have created a #define like this:
>
> #define OO_METHOD_ENTRY(name,desc) \
>   { #name, (PyCFunction) ( [ ] (PyObject *self, PyObject *args) ->
> PyObject * { \
>   PyObject *new_args = python_oo_args(self, args); \
>   PyObject *result = python_##name(self, new_args, NULL); \
>   return result;  } ),  METH_VARARGS | METH_KEYWORDS, (desc)},
>
> (this uses a lambda function)
>
> and use this in the array as:
>
> PyMethodDef PyOpenSCADMethods[] = {
>   OO_METHOD_ENTRY(translate,"Move Object")
>   OO_METHOD_ENTRY(right,"Right Object")
>
> Using this  i can reuse all the functions as methods,
> but its not 100% stable/bulletproof and crashes sometimes.
> So there is the bug ?
> Is there a better approach to reach my goal ?
>
>
> thank you
>
>
-- 
https://mail.python.org/mailman/listinfo/python-list