Commit Graph

59 Commits

Author SHA1 Message Date
Petr Viktorin 25c7bbfbf1 Python stable ABI: Disable instantiation "manually" for some types
Some of rpm's types can't be instantiated by calling the class.
The flag for this was only added in Python 3.10.
Replace it by a tp_new slot with the same effect: raising an exception.
2023-10-05 13:39:37 +03:00
Petr Viktorin 2e74eec244 Python stable ABI: Adjust type usage & declarations
The previous commit removed all *_Type variables.
This adds them back, but as *pointers* to Python type objects
rather than type objects themselves.

All usages now need an extra pointer dereference (or removing an
address-of).
(The compiler will complain of type safety if we miss a spot,
so I'm OK using the original names.)

Also, add header declarations for the Spec structs.
2023-10-05 13:39:37 +03:00
Petr Viktorin 0d33ad8530 Python stable ABI: Change type definitions to heap type specs
In the stable ABI Python's type objects aren't defined in structs
that reference other structs, but by an array of "slots" from which
type objects are created.

(This commit was generated semi-automatically. The automation
is too messy and bespoke to share widely, but if you're interested
in undocumented work in progress, look in
https://github.com/encukou/api-limiter/tree/rpm-mess )
2023-10-05 13:39:37 +03:00
Petr Viktorin 46897602ff Python stable ABI: Make calls to `tp_alloc` go through PyType_GetSlot
The Python type struct changes between versions, and thus direct access to
its fields is not allowed in Stable ABI.
The members can, however, be retrieved using `PyType_GetSlot`.

Commit generated with this semantic patch (see https://coccinelle.lip6.fr ):
```
@@
identifier subtype;
type t;
expression size;
identifier var;
@@

- t var = (t)subtype->tp_alloc(subtype, size);
+ allocfunc subtype_alloc = (allocfunc)PyType_GetSlot(subtype, Py_tp_alloc);
+ t var = (t)subtype_alloc(subtype, size);

@@
identifier subtype;
type t;
expression size;
identifier var;
@@

- var = (t)subtype->tp_alloc(subtype, size);
+ allocfunc subtype_alloc = (allocfunc)PyType_GetSlot(subtype, Py_tp_alloc);
+ var = (t)subtype_alloc(subtype, size);
```

applied using:

    spatch --sp-file patch.cocci --dir python/ --in-place
2023-10-05 13:39:37 +03:00
Petr Viktorin a532a0d8c2 Python stable ABI: Make calls to `tp_free` go through PyType_GetSlot
The Python type struct changes between versions, and thus direct access to
its fields is not allowed in Stable ABI.
The members can, however, be retrieved using `PyType_GetSlot`.

Commit generated with this semantic patch (see https://coccinelle.lip6.fr ):
```
@@
identifier s;
type t;
@@

- Py_TYPE(s)->tp_free((t*) s);
+ Py_TYPE(s)->tp_free(s);

@@
@@

- Py_TYPE(s)->tp_free(s);
+ freefunc free = PyType_GetSlot(Py_TYPE(s), Py_tp_free);
+ free(s);
```

applied using:

    spatch --sp-file patch.cocci --dir python/ --in-place
2023-10-05 13:39:37 +03:00
Jerry James 375bac6ffb Remove redundant code in the python interface 2021-03-29 09:33:00 +03:00
Panu Matilainen 84920f8983 In Python 3, return all our string data as surrogate-escaped utf-8 strings
In the almost ten years of rpm sort of supporting Python 3 bindings, quite
obviously nobody has actually tried to use them. There's a major mismatch
between what the header API outputs (bytes) and what all the other APIs
accept (strings), resulting in hysterical TypeErrors all over the place,
including but not limited to labelCompare() (RhBug:1631292). Also a huge
number of other places have been returning strings and silently assuming
utf-8 through use of Py_BuildValue("s", ...), which will just irrevocably
fail when non-utf8 data is encountered.

The politically Python 3-correct solution would be declaring all our data
as bytes with unspecified encoding - that's exactly what it historically is.
However doing so would by definition break every single rpm script people
have developed on Python 2. And when 99% of the rpm content in the world
actually is utf-8 encoded even if it doesn't say so (and in recent times
packages even advertise themselves as utf-8 encoded), the bytes-only route
seems a wee bit too draconian, even to this grumpy old fella.

Instead, route all our string returns through a single helper macro
which on Python 2 just does what we always did, but in Python 3 converts
the data to surrogate-escaped utf-8 strings. This makes stuff "just work"
out of the box pretty much everywhere even with Python 3 (including
our own test-suite!), while still allowing to handle the non-utf8 case.
Handling the non-utf8 case is a bit more uglier but still possible,
which is exactly how you want corner-cases to be. There might be some
uses for retrieving raw byte data from the header, but worrying about
such an API is a case for some other rainy day, for now we mostly only
care that stuff works again.

Also add test-cases for mixed data source labelCompare() and
non-utf8 insert to + retrieve from header.
2019-02-22 20:37:20 +02:00
David Malcolm 3157d6d7b7 handle errors when constructing lists in the Python bindings
- Various functions in the Python bindings construct lists of objects, but
  assume that all calls succeed. Each of these could segfault under
  low-memory conditions: if the PyList_New() call fails,
  PyList_Append(NULL, item ) will segfault. Similarly, although
  Py_List_Append(list, NULL) is safe, Py_DECREF(NULL) will segfault.

Signed-off-by: Ales Kozumplik <akozumpl@redhat.com>
2011-12-21 08:45:52 +01:00
Panu Matilainen 99f9c67ad4 Python bindings dont need our debug.h for anything 2011-03-09 15:06:11 +02:00
Panu Matilainen 0d68cbf48e Use the new problem set iterator where it makes more sense 2010-03-26 09:31:00 +02:00
Panu Matilainen c4b4944e8f Add a helper function for turning rpm problem set into python list 2010-03-13 12:28:26 +02:00
Panu Matilainen 698c141fe3 Oops, tp_dealloc doesn't return anything 2009-11-18 12:21:41 +02:00
Panu Matilainen c6a2f7f3f2 Fix rpmProblem reference counting in python bindings 2009-11-18 11:33:57 +02:00
Panu Matilainen 66dd52d94c Make python ts.problems() return a python list, not rpm.ps object
- rpm.ps object only supports iteration and subscript (with wonderfully
  wacko semantics), returning a regular list serves us better
- rip the now useless rpm.ps object type
2009-11-18 10:41:26 +02:00
Panu Matilainen a237f1eee0 Remove unused psFromPs() 2009-11-18 09:40:30 +02:00
Panu Matilainen a2a4599fc6 Eliminate broken rpmps append() method from python bindings (RhBug:538218)
- The code to insert new problems has been using invalid conversion code
  causing crashes since 2004 and nobody noticed, safe to say this is an
  unused interface. Additionally the method argument flags were wrong, it
  was declared as METH_VARARGS but actually expected METH_O semantics. RIP.
2009-11-18 09:35:41 +02:00
Panu Matilainen 16f9d7f4dc Remove unnecessary (cmpfunc) casts from our type objects
- cmpfunc is no more in Python 3 and casting NULL to anything makes
  little sense anyhow
2009-10-28 16:35:32 +02:00
David Malcolm 4b8e0ebde6 Generalize type object initialization to work with both Python 2.* and Python 3.*
The layout of PyVarObject changed between python 2 and python 3, and this leads
to the existing code for all of the various PyTypeObject initializers failing to
compile with python 3

Change the way we initialize these structs to use PyVarObject_HEAD_INIT directly,
rather than merely PyObject_HEAD_INIT, so that it compiles cleanly with both major
versions of Python
2009-10-19 11:02:13 +03:00
David Malcolm 7b51c4a1eb Generalize access to ob_type so that they work with both Python 2.* and Python 3.*
Python 2's various object structs use macros to implement common fields at the top of each
struct.

Python 3's objects instead embed a PyObject struct as the first member within the more refined
object structs.

Use the Py_TYPE() macro when accessing ob_type in order to encapsulate this difference.
2009-10-19 10:50:24 +03:00
Panu Matilainen dc6946e72e Revert explicit PyErr_NoMemory() returns to just returning NULL
- tp_alloc failing is likely to be OOM but we dont know that for a fact,
  and the failing method is responsible for setting the exception
2009-10-09 11:57:46 +03:00
Panu Matilainen 4e647fd780 Enable retrieving problem key from python too 2009-10-05 13:12:05 +03:00
Panu Matilainen a15bfa40ad Add minimal python wrapping for rpmProblem objects
- for now, only expose the basic attributes and return problem string
  representation on %s
- return problem objects on rpmps iteration
2009-10-05 11:09:05 +03:00
Panu Matilainen 2507ab6797 Enable subtyping on the rest of our type-objects
- not very useful atm as various places return hard-wired built-in types
2009-09-24 13:57:55 +03:00
Panu Matilainen df40d9b27b Eliminate all custom tp_free() type methods
- tp_free()'s purpose is only to free up the memory used by the python
  object structure, cleaning up our own allocations belongs to tp_dealloc()
2009-09-24 13:40:44 +03:00
Panu Matilainen 74c1040dbc Call (sub)type tp_free from destructors
- more preliminaries for subtyping
- remove pointless NULL checks
2009-09-24 12:52:32 +03:00
Panu Matilainen 36ada6c116 Make object allocation type agnostic
- pass (sub)type down to wrappers
- call subtype tp_alloc() instead of PyObject_New()
- preliminaries for allowing subtyping
2009-09-24 11:42:17 +03:00
Panu Matilainen c29492242c Remove tp_print methods from all rpm-python objects
- these violate the intended use of tp_print, python docs state
  "A type should never implement tp_print in a way that produces
  different output than tp_repr or tp_str would."
2009-09-23 10:44:41 +03:00
Panu Matilainen 6bbc19fb22 Lose the debug junk from python bindings 2009-09-23 10:39:40 +03:00
Panu Matilainen 39d79f9142 Rename python system.h for disambiguation 2009-09-22 23:02:47 +03:00
Panu Matilainen 14d5aaedcb Lose the empty doxygen markers
- nothing wrong with comments but empty comment placeholders
  are not exactly useful
2009-09-22 22:42:06 +03:00
Panu Matilainen 864220c441 Put some consistency to python object creation
- all type object creation goes through foo_Wrap() which handle OOM
  and all type specific initialization
2009-09-22 21:53:21 +03:00
Panu Matilainen ed557bbcf0 Make all python object creation wrappers return PyObject pointers
- this way the only place where casts are needed are in the wrapper itself
2009-09-22 21:24:55 +03:00
Panu Matilainen 0793b2cf23 All rpm-python iterators are self-iterators, just use PyObject_SelfIter 2009-09-22 20:20:07 +03:00
Panu Matilainen 00d683ce88 Move allocations out of rpmps object init method
- tp_init can be called several times, allocating from there leaks memory
- tp_init gets called automatically on object creation, dont call manually
- nothing to initialize for rpmps...
2009-09-22 18:55:09 +03:00
Panu Matilainen 96a1b0a681 Use Py_RETURN_NONE macro for returning None everywhere 2009-09-22 17:49:53 +03:00
Panu Matilainen 43f585fced Eliminate unnecessary custom object allocation functions
- these are just calling python defaults, no point at all...
2009-09-22 17:33:07 +03:00
Panu Matilainen ca6591e86c Use generic python get/set attribute functions directly where appropriate
- no point in wrapping all this stuff in our own functions
2009-09-22 17:27:44 +03:00
Panu Matilainen ae1fd3fa47 Make the python object structures opaque 2009-09-22 16:47:07 +03:00
Panu Matilainen ae1e7d8389 We dont support ancient python versions... 2009-09-22 16:28:58 +03:00
Panu Matilainen eb5dc35c19 Include spring-cleaning
- put some consistency into include ordering
- everything (apart from bits missed ;) is now ordered like this
  1. "system.h"
  2. other system includes
  3. rpm public headers
  4. rpm private headers
  5. "debug.h"
2008-01-30 17:05:29 +02:00
Panu Matilainen 99faa2735b rpmlib.h mass eviction
- explicitly include what's really needed instead
- document remaining uses
2008-01-30 13:53:51 +02:00
Panu Matilainen b4588a1202 Remove bogus const from rpmProblemString() return type
- its malloced so it needs to be freed
- fix all users to actually free
2007-12-15 11:47:47 +02:00
Panu Matilainen 9ce13e09ef Switch to <rpm/foo.h> style for public headers
- adjust include paths accordingly
2007-12-08 14:02:32 +02:00
Panu Matilainen 47b6892500 Avoid building rpmdebug-py 2007-11-29 10:09:43 +02:00
Ralf Corsépius abeea80a38 Use #include <x.h> syntax to include public headers. 2007-11-23 06:46:19 +01:00
Ralf Corsépius f25c04c1e4 Include "rpmlib.h" instead of <rpmlib.h>. 2007-10-28 06:47:31 +01:00
Panu Matilainen 8e59724a58 Rename rpmpsProblem() -> rpmpsGetProblem() to make purpose clearer 2007-10-19 13:25:08 +03:00
Panu Matilainen dffede2350 Only permit appending to a problem set from python
- remove subscript assignment (which mucks about rpmps internals way
  too deeply)
- add append() method instead
2007-10-19 12:15:35 +03:00
Panu Matilainen b882a428bd Implement python rpmps iteration with rpmlib level iterator 2007-10-19 12:36:11 +03:00
Ralf Corsépius 3aad15624e Remove split tags. 2007-09-11 15:28:26 +02:00