First version of Python module.

This commit is contained in:
Matthias Koefferlein 2018-05-26 21:31:39 +02:00
parent 108f90e382
commit 0b0393ce56
10 changed files with 675 additions and 456 deletions

View File

@ -39,6 +39,8 @@ equals(HAVE_PYTHON, "1") {
SUBDIRS += pya
LANG_DEPENDS += pya
pya.depends += gsi db
SUBDIRS += pymod
pymod.depends += pya
} else {
SUBDIRS += pyastub
pyastub.depends += gsi

View File

@ -1190,10 +1190,7 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
const gsi::MethodBase::MethodSynonym &syn = i->second.first->begin_synonyms () [i->second.second];
DocumentationParser method_doc (i->second.first);
std::string pydoc;
if (pya::PythonInterpreter::instance ()) {
pydoc = pya::PythonInterpreter::instance ()->python_doc (i->second.first);
}
std::string pydoc = pya::PythonModule::python_doc (i->second.first);
os << "<tr>";
if (i->first != prev_title) {

File diff suppressed because it is too large Load Diff

View File

@ -34,6 +34,7 @@
#include <list>
#include <string>
#include <set>
#include <memory>
struct _typeobject;
typedef _typeobject PyTypeObject;
@ -89,6 +90,84 @@ public:
class MethodTable;
/**
* @brief A representative for a Python module
* Instantiate this object to represent a python module.
* If used externally (for a library), call init with the module name.
* Then call make_classes to create the individual classes.
*/
class PYA_PUBLIC PythonModule
{
public:
/**
* @brief Constructor
*/
PythonModule ();
/**
* @brief Destructor
*/
~PythonModule ();
/**
* @brief Initializes the module
* This entry point is for external use where the module has not been created yet
*/
void init (const char *mod_name, const char *description);
/**
* @brief Initializes the module
* This entry point is for internal use where the module is created by the interpreter
*/
void init (const char *mod_name, PyObject *module);
/**
* @brief Creates the classes after init has been called
*/
void make_classes ();
/**
* @brief Gets the GSI class for a Python class
*/
static const gsi::ClassBase *cls_for_type (PyTypeObject *type);
/**
* @brief The reverse: gets a Python class for a GSI class or NULL if there is no binding
*/
static PyTypeObject *type_for_cls (const gsi::ClassBase *cls);
/**
* @brief Returns additional Python-specific documentation for the given method
* If no specific documentation exists, an empty string is returned.
*/
static std::string python_doc (const gsi::MethodBase *method);
/**
* @brief Gets the PyObject for the module
*/
PyObject *module ();
private:
void add_python_doc (const gsi::ClassBase &cls, const MethodTable *mt, int mid, const std::string &doc);
PyMethodDef *make_method_def ();
PyGetSetDef *make_getset_def ();
char *make_string (const std::string &s);
std::list<std::string> m_string_heap;
std::vector<PyMethodDef *> m_methods_heap;
std::vector<PyGetSetDef *> m_getseters_heap;
std::string m_mod_name, m_mod_description;
std::string m_base_class_name;
PythonRef mp_module;
PythonRef mp_base_class;
char *mp_mod_def;
static std::map<const gsi::MethodBase *, std::string> m_python_doc;
static std::map <PyTypeObject *, const gsi::ClassBase *> m_cls_map;
static std::map <const gsi::ClassBase *, PyTypeObject *> m_rev_cls_map;
};
/**
* @brief The python interpreter wrapper class
*/
@ -214,16 +293,6 @@ public:
*/
std::string version () const;
/**
* @brief Gets the GSI class for a Python class
*/
const gsi::ClassBase *cls_for_type (PyTypeObject *type) const;
/**
* @brief The reverse: gets a Python class for a GSI class or NULL if there is no binding
*/
PyTypeObject *type_for_cls (const gsi::ClassBase *cls) const;
/**
* @brief Returns the current console
*/
@ -246,12 +315,6 @@ public:
*/
int trace_func (PyFrameObject *frame, int event, PyObject *arg);
/**
* @brief Returns additional Python-specific documentation for the given method
* If no specific documentation exists, an empty string is returned.
*/
std::string python_doc (const gsi::MethodBase *method) const;
/**
* @brief Returns the singleton reference
*/
@ -266,22 +329,11 @@ private:
size_t prepare_trace (PyObject *);
tl::Variant eval_int (const char *string, const char *filename, int line, bool eval_expr, int context);
void get_context (int context, PythonRef &globals, PythonRef &locals, const char *file);
void add_python_doc (const gsi::ClassBase &cls, const MethodTable *mt, int mid, const std::string &doc);
PyMethodDef *make_method_def ();
PyGetSetDef *make_getset_def ();
char *make_string (const std::string &s);
std::list<PythonRef> m_object_heap;
std::list<std::string> m_string_heap;
std::map<const gsi::MethodBase *, std::string> m_python_doc;
std::set<std::string> m_package_paths;
std::vector<PyMethodDef *> m_methods_heap;
std::vector<PyGetSetDef *> m_getseters_heap;
PythonRef m_stdout_channel, m_stderr_channel;
PythonPtr m_stdout, m_stderr;
std::set<std::string> m_package_paths;
std::map <PyTypeObject *, const gsi::ClassBase *> m_cls_map;
std::map <const gsi::ClassBase *, PyTypeObject *> m_rev_cls_map;
gsi::Console *mp_current_console;
std::vector<gsi::Console *> m_consoles;
gsi::ExecutionHandler *mp_current_exec_handler;
@ -296,6 +348,7 @@ private:
PyFrameObject *mp_current_frame;
std::map<PyObject *, size_t> m_file_id_map;
wchar_t *mp_py3_app_name;
pya::PythonModule m_pya_module;
};
}

View File

@ -20,32 +20,19 @@
*/
#include "tlDefs.h"
#if !defined(HDR_pyaCommon_h)
# define HDR_pyaCommon_h
# if defined _WIN32 || defined __CYGWIN__
# ifdef MAKE_PYA_LIBRARY
# define PYA_PUBLIC __declspec(dllexport)
# else
# define PYA_PUBLIC __declspec(dllimport)
# endif
# define PYA_LOCAL
# define PYA_PUBLIC_TEMPLATE
# ifdef MAKE_PYA_LIBRARY
# define PYA_PUBLIC DEF_INSIDE_PUBLIC
# define PYA_PUBLIC_TEMPLATE DEF_INSIDE_PUBLIC_TEMPLATE
# define PYA_LOCAL DEF_INSIDE_LOCAL
# else
# if __GNUC__ >= 4 || defined(__clang__)
# define PYA_PUBLIC __attribute__ ((visibility ("default")))
# define PYA_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define PYA_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define PYA_PUBLIC
# define PYA_PUBLIC_TEMPLATE
# define PYA_LOCAL
# endif
# define PYA_PUBLIC DEF_OUTSIDE_PUBLIC
# define PYA_PUBLIC_TEMPLATE DEF_OUTSIDE_PUBLIC_TEMPLATE
# define PYA_LOCAL DEF_OUTSIDE_LOCAL
# endif
#endif

View File

@ -309,7 +309,7 @@ tl::Variant python2c<tl::Variant> (PyObject *rval, tl::Heap *heap)
} else {
const gsi::ClassBase *cls = PythonInterpreter::instance ()->cls_for_type (Py_TYPE (rval));
const gsi::ClassBase *cls = PythonModule::cls_for_type (Py_TYPE (rval));
if (cls) {
PYAObjectBase *p = (PYAObjectBase *) rval;
@ -438,7 +438,7 @@ object_to_python (void *obj, PYAObjectBase *self, const gsi::ClassBase *cls, boo
// can't guarantee the lifetime of the container will exceed that
// of the exposed property. Hence copying is safer.
PyTypeObject *type = PythonInterpreter::instance ()->type_for_cls (clsact);
PyTypeObject *type = PythonModule::type_for_cls (clsact);
tl_assert (type != NULL);
// create a instance and copy the value
@ -459,7 +459,7 @@ object_to_python (void *obj, PYAObjectBase *self, const gsi::ClassBase *cls, boo
} else {
PyTypeObject *type = PythonInterpreter::instance ()->type_for_cls (clsact);
PyTypeObject *type = PythonModule::type_for_cls (clsact);
tl_assert (type != NULL);
// create a instance and copy the value

View File

@ -36,9 +36,9 @@ namespace pya
// Serialization adaptors for strings, variants, vectors and maps
/**
* @brief An adaptor for a string from ruby objects
* @brief An adaptor for a string from ruby objects
*/
class PythonBasedStringAdaptor
class PythonBasedStringAdaptor
: public gsi::StringAdaptor
{
public:
@ -69,9 +69,9 @@ private:
};
/**
* @brief An adaptor for a variant from ruby objects
* @brief An adaptor for a variant from ruby objects
*/
class PythonBasedVariantAdaptor
class PythonBasedVariantAdaptor
: public gsi::VariantAdaptor
{
public:
@ -106,7 +106,7 @@ private:
/**
* @brief An adaptor for a vector from Python objects
*/
class PythonBasedVectorAdaptor
class PythonBasedVectorAdaptor
: public gsi::VectorAdaptor
{
public:
@ -132,7 +132,7 @@ class PythonBasedMapAdaptorIterator
public:
PythonBasedMapAdaptorIterator (const PythonPtr &hash, const gsi::ArgType *ainner, const gsi::ArgType *ainner_k);
virtual void get (gsi::SerialArgs &w, tl::Heap &heap) const;
virtual void get (gsi::SerialArgs &w, tl::Heap &heap) const;
virtual bool at_end () const;
virtual void inc ();
@ -147,7 +147,7 @@ private:
/**
* @brief An adaptor for a map from Python objects
*/
class PythonBasedMapAdaptor
class PythonBasedMapAdaptor
: public gsi::MapAdaptor
{
public:
@ -171,8 +171,8 @@ template <class R>
struct get_boxed_value_func
{
void operator() (void **ret, PyObject *arg, tl::Heap *heap)
{
const gsi::ClassBase *cls_decl = PythonInterpreter::instance ()->cls_for_type (Py_TYPE (arg));
{
const gsi::ClassBase *cls_decl = PythonModule::cls_for_type (Py_TYPE (arg));
if (! cls_decl) {
R *v = new R (python2c<R> (arg, heap));
@ -187,7 +187,7 @@ struct get_boxed_value_func
throw tl::Exception (tl::sprintf (tl::to_string (QObject::tr ("Passing an object to pointer or reference requires a boxed type (pya.%s)")), bt->name ()));
}
PYAObjectBase *p = (PYAObjectBase *) arg;
PYAObjectBase *p = (PYAObjectBase *) arg;
gsi::Value *bo = reinterpret_cast<gsi::Value *> (p->obj ());
if (bo) {
*ret = bo->value ().template morph<R> ().native_ptr ();
@ -254,8 +254,8 @@ struct writer
}
};
/**
* @brief Serialization for strings
/**
* @brief Serialization for strings
*/
template <>
struct writer<gsi::StringType>
@ -362,7 +362,7 @@ struct writer<gsi::MapType>
/**
* @brief A serialization wrapper (write mode)
* Specialisation for objects
* Specialisation for objects
*/
template <>
struct writer<gsi::ObjectType>
@ -382,14 +382,14 @@ struct writer<gsi::ObjectType>
if (atype.is_ptr () || atype.is_cptr () || atype.is_ref () || atype.is_cref ()) {
const gsi::ClassBase *cls_decl = PythonInterpreter::instance ()->cls_for_type (Py_TYPE (arg));
const gsi::ClassBase *cls_decl = PythonModule::cls_for_type (Py_TYPE (arg));
if (! cls_decl) {
throw tl::Exception (tl::sprintf (tl::to_string (QObject::tr ("Unexpected object type (expected argument of class %s, got %s)")), atype.cls ()->name (), Py_TYPE (arg)->tp_name));
}
if (cls_decl->is_derived_from (atype.cls ())) {
PYAObjectBase *p = (PYAObjectBase *) (arg);
PYAObjectBase *p = (PYAObjectBase *) (arg);
if (cls_decl->adapted_type_info ()) {
// resolved adapted type
@ -400,7 +400,7 @@ struct writer<gsi::ObjectType>
} else if (cls_decl->can_convert_to (atype.cls ())) {
PYAObjectBase *p = (PYAObjectBase *) (arg);
PYAObjectBase *p = (PYAObjectBase *) (arg);
// We can convert objects for cref and cptr, but ownership over these objects is not transferred.
// Hence we have to keep them on the heap.
@ -414,14 +414,14 @@ struct writer<gsi::ObjectType>
} else {
const gsi::ClassBase *cls_decl = PythonInterpreter::instance ()->cls_for_type (Py_TYPE (arg));
const gsi::ClassBase *cls_decl = PythonModule::cls_for_type (Py_TYPE (arg));
if (! cls_decl) {
throw tl::Exception (tl::sprintf (tl::to_string (QObject::tr ("Unexpected object type (expected argument of class %s, got %s)")), atype.cls ()->name (), Py_TYPE (arg)->tp_name));
}
if (cls_decl->is_derived_from (atype.cls ())) {
PYAObjectBase *p = (PYAObjectBase *) (arg);
PYAObjectBase *p = (PYAObjectBase *) (arg);
if (cls_decl->adapted_type_info ()) {
// resolved adapted type
@ -432,7 +432,7 @@ struct writer<gsi::ObjectType>
} else if (cls_decl->can_convert_to (atype.cls ())) {
PYAObjectBase *p = (PYAObjectBase *) (arg);
PYAObjectBase *p = (PYAObjectBase *) (arg);
aa->write<void *> (atype.cls ()->create_obj_from (cls_decl, p->obj ()));
} else {
@ -446,7 +446,7 @@ struct writer<gsi::ObjectType>
/**
* @brief A serialization wrapper (write mode)
* Specialisation for void
* Specialisation for void
*/
template <>
struct writer<gsi::VoidType>
@ -464,11 +464,11 @@ push_arg (const gsi::ArgType &atype, gsi::SerialArgs &aserial, PyObject *arg, tl
}
/**
* @brief Deseralisation wrapper
* @brief Deseralisation wrapper
*
* The default implementation is for POD types, strings and variants
*/
template <class R>
template <class R>
struct reader
{
void operator() (gsi::SerialArgs *rr, PythonRef *ret, PyObject * /*self*/, const gsi::ArgType &arg, tl::Heap *heap)
@ -503,7 +503,7 @@ struct reader
* Without that would would have to handle void *&, void * const &, ...
* TODO: right now these types are not supported.
*/
template <>
template <>
struct reader<void *>
{
void operator() (gsi::SerialArgs *rr, PythonRef *ret, PyObject * /*self*/, const gsi::ArgType &arg, tl::Heap *heap)
@ -519,7 +519,7 @@ struct reader<void *>
/**
* @brief Deseralisation wrapper: specialization for strings
*/
template <>
template <>
struct reader<gsi::StringType>
{
void operator() (gsi::SerialArgs *rr, PythonRef *ret, PYAObjectBase * /*self*/, const gsi::ArgType &, tl::Heap *heap)
@ -589,7 +589,7 @@ PyObject *object_from_variant (const tl::Variant &var, PYAObjectBase *self, cons
/**
* @brief Deseralisation wrapper: specialization for variants
*/
template <>
template <>
struct reader<gsi::VariantType>
{
void operator() (gsi::SerialArgs *rr, PythonRef *ret, PYAObjectBase *self, const gsi::ArgType &atype, tl::Heap *heap)
@ -612,7 +612,7 @@ struct reader<gsi::VariantType>
/**
* @brief Deseralisation wrapper: specialization for vectors
*/
template <>
template <>
struct reader<gsi::VectorType>
{
void operator() (gsi::SerialArgs *rr, PythonRef *ret, PYAObjectBase * /*self*/, const gsi::ArgType &atype, tl::Heap *heap)
@ -624,7 +624,7 @@ struct reader<gsi::VectorType>
*ret = PyList_New (0);
tl_assert (atype.inner () != 0);
PythonBasedVectorAdaptor t (*ret, atype.inner ());
a->copy_to (&t, *heap);
a->copy_to (&t, *heap);
}
}
};
@ -632,7 +632,7 @@ struct reader<gsi::VectorType>
/**
* @brief Deseralisation wrapper: specialization for maps
*/
template <>
template <>
struct reader<gsi::MapType>
{
void operator() (gsi::SerialArgs *rr, PythonRef *ret, PYAObjectBase * /*self*/, const gsi::ArgType &atype, tl::Heap *heap)
@ -651,9 +651,9 @@ struct reader<gsi::MapType>
};
/**
* @brief Deseralisation wrapper: specialization for object
* @brief Deseralisation wrapper: specialization for object
*/
template <>
template <>
struct reader<gsi::ObjectType>
{
void operator() (gsi::SerialArgs *rr, PythonRef *ret, PYAObjectBase *self, const gsi::ArgType &atype, tl::Heap *heap)
@ -670,7 +670,7 @@ struct reader<gsi::ObjectType>
/**
* @brief Deseralisation wrapper: specialization for void
*/
template <>
template <>
struct reader<gsi::VoidType>
{
void operator() (gsi::SerialArgs *, PythonRef *, PYAObjectBase *, const gsi::ArgType &, tl::Heap *)
@ -679,7 +679,7 @@ struct reader<gsi::VoidType>
}
};
PythonRef
PythonRef
pop_arg (const gsi::ArgType &atype, gsi::SerialArgs &aserial, PYAObjectBase *self, tl::Heap &heap)
{
PythonRef ret;
@ -701,7 +701,7 @@ tl::Variant PythonBasedVariantAdaptor::var () const
return python2c<tl::Variant> (m_var.get ());
}
void PythonBasedVariantAdaptor::set (const tl::Variant & /*v*/)
void PythonBasedVariantAdaptor::set (const tl::Variant & /*v*/)
{
// TODO: is there a setter for a string?
}
@ -715,7 +715,7 @@ PythonBasedVectorAdaptorIterator::PythonBasedVectorAdaptorIterator (const Python
// .. nothing yet ..
}
void PythonBasedVectorAdaptorIterator::get (gsi::SerialArgs &w, tl::Heap &heap) const
void PythonBasedVectorAdaptorIterator::get (gsi::SerialArgs &w, tl::Heap &heap) const
{
PyObject *member = NULL;
if (PyTuple_Check (m_array.get ())) {
@ -726,12 +726,12 @@ void PythonBasedVectorAdaptorIterator::get (gsi::SerialArgs &w, tl::Heap &heap)
gsi::do_on_type<writer> () (mp_ainner->type (), &w, member, *mp_ainner, &heap);
}
bool PythonBasedVectorAdaptorIterator::at_end () const
bool PythonBasedVectorAdaptorIterator::at_end () const
{
return m_i == m_len;
}
void PythonBasedVectorAdaptorIterator::inc ()
void PythonBasedVectorAdaptorIterator::inc ()
{
++m_i;
}
@ -750,7 +750,7 @@ gsi::VectorAdaptorIterator *PythonBasedVectorAdaptor::create_iterator () const
return new PythonBasedVectorAdaptorIterator (m_array, size (), mp_ainner);
}
void PythonBasedVectorAdaptor::push (gsi::SerialArgs &r, tl::Heap &heap)
void PythonBasedVectorAdaptor::push (gsi::SerialArgs &r, tl::Heap &heap)
{
if (PyList_Check (m_array.get ())) {
PythonRef member;
@ -761,7 +761,7 @@ void PythonBasedVectorAdaptor::push (gsi::SerialArgs &r, tl::Heap &heap)
}
}
void PythonBasedVectorAdaptor::clear ()
void PythonBasedVectorAdaptor::clear ()
{
if (PySequence_Check (m_array.get ())) {
PySequence_DelSlice (m_array.get (), 0, PySequence_Length (m_array.get ()));
@ -777,7 +777,7 @@ size_t PythonBasedVectorAdaptor::size () const
}
}
size_t PythonBasedVectorAdaptor::serial_size () const
size_t PythonBasedVectorAdaptor::serial_size () const
{
return mp_ainner->size ();
}
@ -793,18 +793,18 @@ PythonBasedMapAdaptorIterator::PythonBasedMapAdaptorIterator (const PythonPtr &h
inc ();
}
void PythonBasedMapAdaptorIterator::get (gsi::SerialArgs &w, tl::Heap &heap) const
void PythonBasedMapAdaptorIterator::get (gsi::SerialArgs &w, tl::Heap &heap) const
{
gsi::do_on_type<writer> () (mp_ainner_k->type (), &w, m_key, *mp_ainner_k, &heap);
gsi::do_on_type<writer> () (mp_ainner->type (), &w, m_value, *mp_ainner, &heap);
}
bool PythonBasedMapAdaptorIterator::at_end () const
bool PythonBasedMapAdaptorIterator::at_end () const
{
return ! m_has_items;
}
void PythonBasedMapAdaptorIterator::inc ()
void PythonBasedMapAdaptorIterator::inc ()
{
m_has_items = PyDict_Next(m_hash.get (), &m_pos, &m_key, &m_value);
}
@ -813,7 +813,7 @@ void PythonBasedMapAdaptorIterator::inc ()
// PythonBasedMapAdaptor implementation
PythonBasedMapAdaptor::PythonBasedMapAdaptor (const PythonPtr &hash, const gsi::ArgType *ainner, const gsi::ArgType *ainner_k)
: mp_ainner (ainner), mp_ainner_k (ainner_k), m_hash (hash)
: mp_ainner (ainner), mp_ainner_k (ainner_k), m_hash (hash)
{
}
@ -822,7 +822,7 @@ gsi::MapAdaptorIterator *PythonBasedMapAdaptor::create_iterator () const
return new PythonBasedMapAdaptorIterator (m_hash, mp_ainner, mp_ainner_k);
}
void PythonBasedMapAdaptor::insert (gsi::SerialArgs &r, tl::Heap &heap)
void PythonBasedMapAdaptor::insert (gsi::SerialArgs &r, tl::Heap &heap)
{
PythonRef k, v;
gsi::do_on_type<reader> () (mp_ainner_k->type (), &r, &k, (PYAObjectBase *) 0, *mp_ainner_k, &heap);
@ -830,7 +830,7 @@ void PythonBasedMapAdaptor::insert (gsi::SerialArgs &r, tl::Heap &heap)
PyDict_SetItem (m_hash.get (), k.get (), v.get ());
}
void PythonBasedMapAdaptor::clear ()
void PythonBasedMapAdaptor::clear ()
{
PyDict_Clear (m_hash.get ());
}
@ -840,7 +840,7 @@ size_t PythonBasedMapAdaptor::size () const
return PyDict_Size (m_hash.get ());
}
size_t PythonBasedMapAdaptor::serial_size () const
size_t PythonBasedMapAdaptor::serial_size () const
{
return mp_ainner_k->size () + mp_ainner->size ();
}
@ -876,7 +876,7 @@ struct test_arg_func
if (atype.is_ptr () || atype.is_ref ()) {
// check if we have a boxed type
const gsi::ClassBase *cls_decl = PythonInterpreter::instance ()->cls_for_type (Py_TYPE (arg));
const gsi::ClassBase *cls_decl = PythonModule::cls_for_type (Py_TYPE (arg));
if (cls_decl) {
const gsi::ClassBase *bc = gsi::cls_decl <gsi::Value> ();
if (cls_decl->is_derived_from (bc)) {
@ -914,11 +914,11 @@ struct test_arg_func<gsi::StringType>
#if PY_MAJOR_VERSION < 3
if (PyString_Check (arg)) {
*ret = true;
} else
} else
#else
if (PyBytes_Check (arg)) {
*ret = true;
} else
} else
#endif
if (PyUnicode_Check (arg)) {
*ret = true;
@ -981,7 +981,7 @@ struct test_arg_func<gsi::MapType>
const gsi::ArgType &ainner = *atype.inner ();
const gsi::ArgType &ainner_k = *atype.inner ();
// Note: we test key and value separately. That way we don't need to
// Note: we test key and value separately. That way we don't need to
// instantiate a 2d template with do_on_type2.
*ret = true;
@ -1010,7 +1010,7 @@ struct test_arg_func<gsi::ObjectType>
return;
}
const gsi::ClassBase *cls_decl = PythonInterpreter::instance ()->cls_for_type (Py_TYPE (arg));
const gsi::ClassBase *cls_decl = PythonModule::cls_for_type (Py_TYPE (arg));
if (! cls_decl) {
*ret = false;
return;
@ -1037,6 +1037,5 @@ test_arg (const gsi::ArgType &atype, PyObject *arg, bool loose)
gsi::do_on_type<test_arg_func> () (atype.type (), &ret, arg, atype, loose);
return ret;
}
}
}

View File

@ -102,7 +102,8 @@ HEADERS = \
tlUnitTest.h \
tlInt128Support.h \
tlHttpStreamCurl.h \
tlHttpStreamQt.h
tlHttpStreamQt.h \
tlDefs.h
INCLUDEPATH =
DEPENDPATH =

57
src/tl/tl/tlDefs.h Normal file
View File

@ -0,0 +1,57 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2018 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if !defined(HDR_tlDefs_h)
# define HDR_tlDefs_h
// templates provided for building the external symbol
// declarations per library
# if defined _WIN32 || defined __CYGWIN__
# define DEF_INSIDE_PUBLIC __declspec(dllexport)
# define DEF_INSIDE_LOCAL
# define DEF_INSIDE_PUBLIC_TEMPLATE
# define DEF_OUTSIDE_PUBLIC __declspec(dllimport)
# define DEF_OUTSIDE_LOCAL
# define DEF_OUTSIDE_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4 || defined(__clang__)
# define DEF_INSIDE_PUBLIC __attribute__ ((visibility ("default")))
# define DEF_INSIDE_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define DEF_INSIDE_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define DEF_INSIDE_PUBLIC
# define DEF_INSIDE_PUBLIC_TEMPLATE
# define DEF_INSIDE_LOCAL
# endif
# define DEF_OUTSIDE_PUBLIC DEF_INSIDE_PUBLIC
# define DEF_OUTSIDE_PUBLIC_TEMPLATE DEF_INSIDE_PUBLIC_TEMPLATE
# define DEF_OUTSIDE_LOCAL DEF_INSIDE_LOCAL
# endif
#endif

View File

@ -25,6 +25,7 @@ import gc
# Set this to True to disable some tests involving exceptions
leak_check = "TEST_LEAK_CHECK" in os.environ
print("@@@1")
# see test_21
class AEXT(pya.A):
def __init__(self):
@ -134,16 +135,23 @@ class BasicTest(unittest.TestCase):
def test_00(self):
print("@@@00")
# all references of PA are released now:
ac0 = pya.A.a0()
print("@@@00-1")
a = pya.A.new_a(100)
self.assertEqual( pya.A.a0(), ac0 + 1 )
print("@@@00-2")
a = pya.A()
print("@@@00-31")
self.assertEqual(a.a1(), 17)
print("@@@00-32")
a.assign(pya.A(110))
print("@@@00-33")
self.assertEqual(a.a1(), 110)
print("@@@00-3")
a = None
self.assertEqual( pya.A.a0(), ac0 )
@ -384,6 +392,7 @@ class BasicTest(unittest.TestCase):
def test_12(self):
print("@@@12")
a1 = pya.A()
a1.a5( -15 )
a2 = a1
@ -584,6 +593,7 @@ class BasicTest(unittest.TestCase):
def test_13(self):
print("@@@13")
b = pya.B()
if not leak_check:
@ -810,6 +820,7 @@ class BasicTest(unittest.TestCase):
def test_13b(self):
print("@@@13b")
b = pya.B()
bb = pya.B()
@ -913,6 +924,7 @@ class BasicTest(unittest.TestCase):
def test_14(self):
print("@@@14")
a = pya.A()
a.a5( 22 )
@ -926,6 +938,7 @@ class BasicTest(unittest.TestCase):
def test_15(self):
print("@@@15")
a = pya.A_NC()
self.assertEqual( True, isinstance(a, pya.A) )
a.a5( 22 )
@ -940,6 +953,7 @@ class BasicTest(unittest.TestCase):
def test_16(self):
print("@@@16")
if leak_check:
return
@ -966,6 +980,7 @@ class BasicTest(unittest.TestCase):
def test_17(self):
print("@@@17")
# test copies of objects being returned
b = pya.B()
@ -991,6 +1006,7 @@ class BasicTest(unittest.TestCase):
def test_18(self):
print("@@@18")
# Test references to objects (returned by b.b7)
b = pya.B()
@ -1017,6 +1033,7 @@ class BasicTest(unittest.TestCase):
def test_19(self):
print("@@@19")
c0 = pya.C()
self.assertEqual( c0.g("x"), 1977 );
@ -1062,6 +1079,7 @@ class BasicTest(unittest.TestCase):
def test_20(self):
print("@@@20")
b = pya.B()
a1 = b.b14a( True )
@ -1081,6 +1099,7 @@ class BasicTest(unittest.TestCase):
def test_21(self):
print("@@@21")
# Python does not allow extending built-in types - the following test
# is taken from the Ruby binding. I don't know how to implement it for
# Python however.
@ -1112,6 +1131,7 @@ class BasicTest(unittest.TestCase):
def test_22(self):
print("@@@22")
# test client data binding to C++ objects
b = pya.B()
@ -1230,6 +1250,7 @@ class BasicTest(unittest.TestCase):
def test_23(self):
print("@@@23")
b = pya.B()
a = pya.A()
@ -1277,6 +1298,7 @@ class BasicTest(unittest.TestCase):
def test_24(self):
print("@@@24")
n = [ 0, 0 , "" ]
# Events
@ -1362,6 +1384,7 @@ class BasicTest(unittest.TestCase):
def test_25(self):
print("@@@25")
# destruction of an instance via c++
pya.A.a20(None)
ac0 = pya.A.a0()
@ -1414,6 +1437,7 @@ class BasicTest(unittest.TestCase):
def test_26(self):
print("@@@26")
# cyclic references - event bound to itself
base_count = EEXT.inst_count()
@ -1457,6 +1481,7 @@ class BasicTest(unittest.TestCase):
def test_27(self):
print("@@@27")
# destruction of an instance via c++
pya.A.a20(None)
ac0 = pya.A.a0()
@ -1493,6 +1518,7 @@ class BasicTest(unittest.TestCase):
def test_28(self):
print("@@@28")
self.assertEqual(pya.B.inst() == None, True)
self.assertEqual(pya.B.has_inst(), False)
@ -1528,6 +1554,7 @@ class BasicTest(unittest.TestCase):
def test_30(self):
print("@@@30")
# some basic tests for the *Value boxing classes
val = pya.Value()
@ -1704,6 +1731,7 @@ class BasicTest(unittest.TestCase):
def test_31(self):
print("@@@31")
# some basic tests with derived and base classes
pya.X.init()
@ -1760,6 +1788,7 @@ class BasicTest(unittest.TestCase):
def test_32(self):
print("@@@32")
# run test only if we have Qt bindings
if not "QStringPair" in pya.__dict__:
return
@ -1788,6 +1817,7 @@ class BasicTest(unittest.TestCase):
def test_33(self):
print("@@@33")
def str_from_bytearray(ba):
if (sys.version_info > (3, 0)):
return ba
@ -1822,6 +1852,7 @@ class BasicTest(unittest.TestCase):
def test_34(self):
print("@@@34")
# run test only if we have Qt bindings
if not "QDialog" in pya.__dict__:
return
@ -1840,6 +1871,7 @@ class BasicTest(unittest.TestCase):
def test_35(self):
print("@@@35")
# vectors of pointers
pya.X.init()
@ -1940,12 +1972,14 @@ class BasicTest(unittest.TestCase):
def test_36(self):
print("@@@36")
x = XEdge()
self.assertEqual("XEdge", type(x).__name__)
self.assertEqual("(1,2;3,4)", str(x))
def test_37(self):
print("@@@37")
# This test is taken from the Ruby binding, but
# Python does not have protected methods:
return
@ -1965,6 +1999,7 @@ class BasicTest(unittest.TestCase):
def test_38(self):
print("@@@38")
# mixed const / non-const reference and events
ec = pya.E.ic()
self.assertEqual(ec.is_const_object(), True)
@ -1996,6 +2031,7 @@ class BasicTest(unittest.TestCase):
def test_39(self):
print("@@@39")
# mixed const / non-const reference and events
fc = pya.F.ic()
self.assertEqual(fc.is_const_object(), True)
@ -2026,6 +2062,7 @@ class BasicTest(unittest.TestCase):
def test_40(self):
print("@@@40")
# optional arguments
g = pya.G()
@ -2109,6 +2146,7 @@ class BasicTest(unittest.TestCase):
def test_41(self):
print("@@@41")
# maps
b = pya.B()
@ -2170,6 +2208,7 @@ class BasicTest(unittest.TestCase):
def test_42(self):
print("@@@42")
# virtual functions and sub-classes
z = pya.Z()
self.assertEqual(z.f(None), "(nil)")
@ -2198,6 +2237,7 @@ class BasicTest(unittest.TestCase):
def test_50(self):
print("@@@50")
# advanced containers and out parameters
b = pya.B()
@ -2372,6 +2412,7 @@ class BasicTest(unittest.TestCase):
self.assertEqual(b.qhash_is(), {})
def test_51(self):
print("@@@51")
# new subclass and child class declarations
y2 = pya.Y2()
@ -2389,6 +2430,7 @@ class BasicTest(unittest.TestCase):
self.assertEqual(isinstance(y4, pya.X), False)
def test_60(self):
print("@@@60")
class SignalCollector(object):
@ -2482,6 +2524,7 @@ class BasicTest(unittest.TestCase):
self.assertEqual(sc.got_s2_2, None)
def test_61(self):
print("@@@61")
class SignalCollector(object):
@ -2565,6 +2608,7 @@ class BasicTest(unittest.TestCase):
self.assertEqual(sc.got_s0b, 0)
def test_70(self):
print("@@@70")
class SignalCollector(object):
@ -2613,6 +2657,7 @@ class BasicTest(unittest.TestCase):
self.assertEqual(sc.got_s2_2.tag, 111)
def test_71(self):
print("@@@71")
class SignalCollector(object):
@ -2697,6 +2742,7 @@ class BasicTest(unittest.TestCase):
# Custom factory implemented in Python
def test_80(self):
print("@@@80")
gc = pya.GObject.g_inst_count()
gf = PyGFactory()
go = pya.GFactory.create_f(gf, 17)
@ -2706,6 +2752,7 @@ class BasicTest(unittest.TestCase):
go = None
self.assertEqual(pya.GObject.g_inst_count(), gc)
print("@@@2")
# run unit tests
if __name__ == '__main__':
suite = unittest.TestSuite()
@ -2715,4 +2762,5 @@ if __name__ == '__main__':
if not unittest.TextTestRunner(verbosity = 1).run(suite).wasSuccessful():
sys.exit(1)
print("@@@3")