Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing issue #1793 (problem with default arguments in Python) #1795

Merged
merged 7 commits into from
Jul 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/db/db/dbLayoutToNetlist.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@


/*

KLayout Layout Viewer
Expand Down Expand Up @@ -397,7 +396,7 @@ void LayoutToNetlist::join_nets (const tl::GlobPattern &cell, const std::set<std
m_joined_nets_per_cell.push_back (std::make_pair (cell, gp));
}

#if defined(_DEBUG)
#if defined(HAVE_DEBUG)
static bool check_many_pins (const db::Netlist *netlist)
{
bool ok = true;
Expand Down Expand Up @@ -430,7 +429,7 @@ void LayoutToNetlist::extract_netlist ()
do_soft_connections ();

// implement the "join_nets" (aka "must connect") feature
#if defined(_DEBUG)
#if defined(HAVE_DEBUG)
// NOTE: the join_nets feature only works for "one pin per net" case
// TODO: either fix that or make sure we do not get multiple pins per net.
// Right now, there no known case that produces multiple pins on a net at
Expand Down
15 changes: 12 additions & 3 deletions src/gsi/gsi/gsiClassBase.cc
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ static const std::set<std::pair<std::string, bool> > &name_map_for_class (const
return cc->second;
}

#if defined(_DEBUG)
#if defined(HAVE_DEBUG)
static std::string type_signature (const gsi::ArgType &t)
{
gsi::ArgType tr (t);
Expand Down Expand Up @@ -622,7 +622,7 @@ ClassBase::merge_declarations ()
tl_assert (! c->declaration () || c->declaration () == &*c);
}

#if defined(_DEBUG)
#if defined(HAVE_DEBUG)
// do a sanity check
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {

Expand All @@ -634,6 +634,16 @@ ClassBase::merge_declarations ()
method_counts [signature (*m, *s)] += 1;
}
}
// try to obtain the default values to find potential binding issues
for (gsi::MethodBase::argument_iterator a = (*m)->begin_arguments (); a != (*m)->end_arguments (); ++a) {
if (a->spec ()) {
try {
a->spec ()->default_value ();
} catch (tl::Exception &ex) {
tl::warn << "Method " << signature (*m, *(*m)->begin_synonyms ()) << ": error obtaining default value for argument '" << a->spec ()->name () << "': " << ex.msg ();
}
}
}
}

for (std::map<std::string, int>::const_iterator mc = method_counts.begin (); mc != method_counts.end (); ++mc) {
Expand Down Expand Up @@ -925,4 +935,3 @@ bool has_class (const std::type_info &ti)
}

}

8 changes: 4 additions & 4 deletions src/gsi/gsi/gsiExpression.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1036,10 +1036,10 @@ VariantUserClassImpl::execute_gsi (const tl::ExpressionParserContext & /*context
// leave it to the consumer to establish the default values (that is faster)
break;
}
const tl::Variant &def_value = a->spec ()->default_value ();
// NOTE: this const_cast means we need to take care that we do not use default values on "out" parameters.
// Otherwise there is a chance we will modify the default value.
gsi::push_arg (arglist, *a, const_cast<tl::Variant &> (def_value), &heap);
// Note: we will use the default value variant for longer, so push it to the heap (#1793)
tl::Variant *def_value = new tl::Variant (a->spec ()->default_value ());
heap.push (def_value);
gsi::push_arg (arglist, *a, *def_value, &heap);
} else {
throw tl::Exception (tl::to_string ("No argument provided (positional or keyword) and no default value available"));
}
Expand Down
3 changes: 3 additions & 0 deletions src/klayout.pri
Original file line number Diff line number Diff line change
Expand Up @@ -359,3 +359,6 @@ DEFINES += \

VERSION = $$KLAYOUT_VERSION

CONFIG(debug, debug|release) {
DEFINES += HAVE_DEBUG
}
8 changes: 4 additions & 4 deletions src/pya/pya/pyaCallables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -764,10 +764,10 @@ push_args (gsi::SerialArgs &arglist, const gsi::MethodBase *meth, PyObject *args
// leave it to the consumer to establish the default values (that is faster)
break;
}
const tl::Variant &def_value = a->spec ()->default_value ();
// NOTE: this const_cast means we need to take care that we do not use default values on "out" parameters.
// Otherwise there is a chance we will modify the default value.
gsi::push_arg (arglist, *a, const_cast<tl::Variant &> (def_value), &heap);
// Note: we will use the default value variant for longer, so push it to the heap (#1793)
tl::Variant *def_value = new tl::Variant (a->spec ()->default_value ());
heap.push (def_value);
gsi::push_arg (arglist, *a, *def_value, &heap);
} else {
throw tl::Exception (tl::to_string (tr ("No argument provided (positional or keyword) and no default value available")));
}
Expand Down
8 changes: 4 additions & 4 deletions src/rba/rba/rba.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1125,10 +1125,10 @@ push_args (gsi::SerialArgs &arglist, const gsi::MethodBase *meth, VALUE *argv, i
// leave it to the consumer to establish the default values (that is faster)
break;
}
const tl::Variant &def_value = a->spec ()->default_value ();
// NOTE: this const_cast means we need to take care that we do not use default values on "out" parameters.
// Otherwise there is a chance we will modify the default value.
gsi::push_arg (arglist, *a, const_cast<tl::Variant &> (def_value), &heap);
// Note: we will use the default value variant for longer, so push it to the heap (#1793)
tl::Variant *def_value = new tl::Variant (a->spec ()->default_value ());
heap.push (def_value);
gsi::push_arg (arglist, *a, *def_value, &heap);
} else {
throw tl::Exception (tl::to_string (tr ("No argument provided (positional or keyword) and no default value available")));
}
Expand Down
40 changes: 27 additions & 13 deletions src/tl/tl/tlVariant.cc
Original file line number Diff line number Diff line change
Expand Up @@ -317,15 +317,19 @@ Variant::Variant (const std::vector<char> &ba)
#if defined(HAVE_QT)

Variant::Variant (const QByteArray &qba)
: m_type (t_qbytearray), m_string (0)
: m_type (qba.isNull () ? t_nil : t_qbytearray), m_string (0)
{
m_var.m_qbytearray = new QByteArray (qba);
if (! qba.isNull ()) {
m_var.m_qbytearray = new QByteArray (qba);
}
}

Variant::Variant (const QString &qs)
: m_type (t_qstring), m_string (0)
: m_type (qs.isNull () ? t_nil : t_qstring), m_string (0)
{
m_var.m_qstring = new QString (qs);
if (! qs.isNull ()) {
m_var.m_qstring = new QString (qs);
}
}

Variant::Variant (const QVariant &v)
Expand Down Expand Up @@ -526,10 +530,14 @@ Variant::Variant (const std::string &s)
}

Variant::Variant (const char *s)
: m_type (t_string)
: m_type (s != 0 ? t_string : t_nil)
{
m_string = new char [strlen (s) + 1];
strcpy (m_string, s);
if (s) {
m_string = new char [strlen (s) + 1];
strcpy (m_string, s);
} else {
m_string = 0;
}
}

Variant::Variant (double d)
Expand Down Expand Up @@ -676,7 +684,9 @@ Variant::reset ()
Variant &
Variant::operator= (const char *s)
{
if (m_type == t_string && s == m_string) {
if (! s) {
reset ();
} else if (m_type == t_string && s == m_string) {
// we are assigning to ourselves
} else {
char *snew = new char [strlen (s) + 1];
Expand Down Expand Up @@ -721,7 +731,9 @@ Variant::operator= (const std::vector<char> &s)
Variant &
Variant::operator= (const QByteArray &qs)
{
if (m_type == t_qbytearray && &qs == m_var.m_qbytearray) {
if (qs.isNull ()) {
reset ();
} else if (m_type == t_qbytearray && &qs == m_var.m_qbytearray) {
// we are assigning to ourselves
} else {
QByteArray *snew = new QByteArray (qs);
Expand All @@ -735,7 +747,9 @@ Variant::operator= (const QByteArray &qs)
Variant &
Variant::operator= (const QString &qs)
{
if (m_type == t_qstring && &qs == m_var.m_qstring) {
if (qs.isNull ()) {
reset ();
} else if (m_type == t_qstring && &qs == m_var.m_qstring) {
// we are assigning to ourselves
} else {
QString *snew = new QString (qs);
Expand Down Expand Up @@ -1784,9 +1798,9 @@ Variant::to_string () const
if (m_type == t_nil) {
r = "nil";
} else if (m_type == t_double) {
r = tl::to_string (m_var.m_double);
r = tl::to_string (m_var.m_double, 15);
} else if (m_type == t_float) {
r = tl::to_string (m_var.m_float);
r = tl::to_string (m_var.m_float, 7);
} else if (m_type == t_char) {
r = tl::to_string ((int) m_var.m_char);
} else if (m_type == t_schar) {
Expand Down Expand Up @@ -2421,7 +2435,7 @@ Variant::to_parsable_string () const
} else if (is_ulonglong ()) {
return "#lu" + tl::to_string (to_ulonglong ());
} else if (is_double ()) {
return "##" + tl::to_string (to_double ());
return "##" + tl::to_string (to_double (), 15);
} else if (is_bool ()) {
return m_var.m_bool ? "true" : "false";
} else if (is_nil ()) {
Expand Down
105 changes: 104 additions & 1 deletion src/tl/tl/tlVariant.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include <string>
#include <vector>
#include <map>
#include <set>
#include <list>
#include <stdexcept>
#include <typeinfo>

Expand Down Expand Up @@ -358,14 +360,115 @@ class TL_PUBLIC Variant
}

/**
* @brief Initialize the Variant with an explicit vector or variants
* @brief Initialize with a const user type (will always create a reference and NOT own the object)
*/
template <class T>
Variant (const T *obj)
: m_type (t_nil), m_string (0)
{
if (obj) {
*this = make_variant_ref (obj);
}
}

/**
* @brief Initialize with a non-const user type (will always create a reference and NOT own the object)
*/
template <class T>
Variant (T *obj)
: m_type (t_nil), m_string (0)
{
if (obj) {
*this = make_variant_ref (obj);
}
}

/**
* @brief Initialize the Variant with a STL vector
*/
template <class T>
Variant (const std::vector<T> &list)
: m_type (t_list), m_string (0)
{
m_var.m_list = new std::vector<tl::Variant> ();
m_var.m_list->reserve (list.size ());
for (auto i = list.begin (); i != list.end (); ++i) {
m_var.m_list->push_back (tl::Variant (*i));
}
}

/**
* @brief Initialize the Variant with a STL list
*/
template <class T>
Variant (const std::list<T> &list)
: m_type (t_list), m_string (0)
{
m_var.m_list = new std::vector<tl::Variant> ();
m_var.m_list->reserve (list.size ());
for (auto i = list.begin (); i != list.end (); ++i) {
m_var.m_list->push_back (tl::Variant (*i));
}
}

/**
* @brief Initialize the Variant with a STL set (not maintaining the set character)
*/
template <class T>
Variant (const std::set<T> &list)
: m_type (t_list), m_string (0)
{
m_var.m_list = new std::vector<tl::Variant> ();
m_var.m_list->reserve (list.size ());
for (auto i = list.begin (); i != list.end (); ++i) {
m_var.m_list->push_back (tl::Variant (*i));
}
}

/**
* @brief Initialize the Variant with a STL pair
*/
template <class A, class B>
Variant (const std::pair<A, B> &pair)
: m_type (t_list), m_string (0)
{
m_var.m_list = new std::vector<tl::Variant> ();
m_var.m_list->reserve (2);
m_var.m_list->push_back (tl::Variant (pair.first));
m_var.m_list->push_back (tl::Variant (pair.second));
}

/**
* @brief Initialize the Variant with a STL map
*/
template <class K, class V>
Variant (const std::map<K, V> &map)
: m_type (t_array), m_string (0)
{
m_var.m_array = new std::map<tl::Variant, tl::Variant> ();
for (auto i = map.begin (); i != map.end (); ++i) {
m_var.m_array->insert (std::make_pair (tl::Variant (i->first), tl::Variant (i->second)));
}
}

/**
* @brief Initialize the Variant with an explicit vector of variants
*/
Variant (const std::vector<tl::Variant> &list)
: m_type (t_list), m_string (0)
{
m_var.m_list = new std::vector<tl::Variant> (list);
}

/**
* @brief Initialize the Variant with an explicit map of variants
*/
Variant (const std::map<tl::Variant, tl::Variant> &map)
: m_type (t_array), m_string (0)
{
m_var.m_array = new std::map<tl::Variant, tl::Variant> (map);
}

/**
* @brief Initialize the Variant with a list
*/
Expand Down
2 changes: 1 addition & 1 deletion src/tl/unit_tests/tlExpressionTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -927,7 +927,7 @@ TEST(8)
bool t;

v = e.parse ("1==2?log('a'):log(2)").execute ();
EXPECT_EQ (v.to_string (), std::string ("0.69314718056"));
EXPECT_EQ (v.to_string (), std::string ("0.693147180559945"));
t = false;
try {
v = e.parse ("1==1?log('a'):log(2)").execute ();
Expand Down
Loading
Loading