From 5bff479a31a1182c920395627c9c146e20518816 Mon Sep 17 00:00:00 2001 From: Guillaume Horel Date: Fri, 19 Apr 2024 17:34:19 -0400 Subject: [PATCH] prevent circular import --- quantlib/time/calendar.pxd | 5 +-- quantlib/time/calendars/poland.pyx | 3 +- quantlib/time/calendars/target.pxd | 4 +++ quantlib/time/calendars/target.pyx | 1 - quantlib/time/daycounter.pxd | 2 +- quantlib/time/daycounter.pyx | 36 ++++++++++----------- quantlib/time/daycounters/actual_actual.pxd | 3 -- quantlib/time/daycounters/actual_actual.pyx | 14 ++------ quantlib/time/daycounters/simple.pyx | 29 ++++++----------- quantlib/time/daycounters/thirty360.pxd | 3 -- quantlib/time/daycounters/thirty360.pyx | 6 ---- 11 files changed, 36 insertions(+), 70 deletions(-) create mode 100644 quantlib/time/calendars/target.pxd diff --git a/quantlib/time/calendar.pxd b/quantlib/time/calendar.pxd index d4edbdc07..117c48a8f 100644 --- a/quantlib/time/calendar.pxd +++ b/quantlib/time/calendar.pxd @@ -1,9 +1,6 @@ -cimport quantlib.time._calendar as _calendar +from . cimport _calendar from libcpp.vector cimport vector cdef class Calendar: cdef _calendar.Calendar _thisptr - -cdef class TARGET(Calendar): - pass diff --git a/quantlib/time/calendars/poland.pyx b/quantlib/time/calendars/poland.pyx index 47e8512fa..3af9f6bf9 100644 --- a/quantlib/time/calendars/poland.pyx +++ b/quantlib/time/calendars/poland.pyx @@ -1,6 +1,5 @@ -from .. cimport _calendar as _calendar from . cimport _poland -from .. calendar cimport Calendar +from ..calendar cimport Calendar cdef class Poland(Calendar): """Poland calendars""" diff --git a/quantlib/time/calendars/target.pxd b/quantlib/time/calendars/target.pxd new file mode 100644 index 000000000..5573b931e --- /dev/null +++ b/quantlib/time/calendars/target.pxd @@ -0,0 +1,4 @@ +from ..calendar cimport Calendar + +cdef class TARGET(Calendar): + pass diff --git a/quantlib/time/calendars/target.pyx b/quantlib/time/calendars/target.pyx index 2b5dcd00e..acb125099 100644 --- a/quantlib/time/calendars/target.pyx +++ b/quantlib/time/calendars/target.pyx @@ -1,5 +1,4 @@ cimport quantlib.time.calendars._target as _tg -from quantlib.time.calendar cimport Calendar cdef class TARGET(Calendar): '''TARGET calendar diff --git a/quantlib/time/daycounter.pxd b/quantlib/time/daycounter.pxd index 132b2e82f..ba8e132ef 100644 --- a/quantlib/time/daycounter.pxd +++ b/quantlib/time/daycounter.pxd @@ -1,4 +1,4 @@ -cimport quantlib.time._daycounter as _daycounter +from . cimport _daycounter cdef class DayCounter: diff --git a/quantlib/time/daycounter.pyx b/quantlib/time/daycounter.pyx index 12d498c4c..fb1abadc1 100644 --- a/quantlib/time/daycounter.pyx +++ b/quantlib/time/daycounter.pyx @@ -4,9 +4,6 @@ from . cimport _daycounter from . cimport _date from .date cimport Date -from quantlib.time.daycounters.actual_actual cimport from_name as aa_from_name -from quantlib.time.daycounters.thirty360 cimport from_name as th_from_name -cimport quantlib.time.daycounters._simple as _simple cdef class DayCounter: '''This class provides methods for determining the length of a time @@ -60,10 +57,8 @@ cdef class DayCounter: @classmethod def from_name(cls, name): - cdef DayCounter cnt = cls.__new__(cls) name, convention = _get_daycounter_type_from_name(name) - cnt._thisptr = daycounter_from_name(name, convention) - return cnt + return daycounter_from_name(name, convention) def _get_daycounter_type_from_name(name): """ Returns a tuple (counter type, convention) from the DayCounter name. """ @@ -77,37 +72,40 @@ def _get_daycounter_type_from_name(name): return (name, None) -cdef _daycounter.DayCounter* daycounter_from_name(str name, str convention) except NULL: +cdef DayCounter daycounter_from_name(str name, str convention): """ Returns a new DayCounter pointer. The QuantLib DayCounter don't have a copy constructor or any other easy way to get copy of a given DayCounter. """ name_u = name.upper() - - cdef _daycounter.DayCounter* cnt = NULL + from .daycounters.simple import Actual365Fixed, Actual360, OneDayCounter, SimpleDayCounter + from .daycounters.actual_actual import ActualActual, Convention as aaConvention + from .daycounters.thirty360 import Thirty360, Convention as thConvention if name_u in ['ACTUAL360', 'ACTUAL/360', 'ACT/360']: - if convention == 'inc': - cnt = new _simple.Actual360(True) - else: - cnt = new _simple.Actual360() + return Actual360(convention == "inc") elif name_u in ['ACTUAL365FIXED', 'ACTUAL/365', 'ACT/365']: - cnt = new _simple.Actual365Fixed() + return Actual365Fixed() elif name_u == 'BUSINESS252': raise ValueError( 'Business252 from name is not supported. Requires a calendar' ) elif name_u in ['1/1', 'ONEDAYCOUNTER']: - cnt = new _simple.OneDayCounter() + return OneDayCounter() elif name_u == 'SIMPLEDAYCOUNTER': - cnt = new _simple.SimpleDayCounter() + return SimpleDayCounter elif name.startswith('Actual/Actual') or name.startswith('ACT/ACT') : - cnt = aa_from_name(convention) + try: + return ActualActual(aaConvention[convention]) + except KeyError as e: + raise ValueError(str(e)) elif name == "30/360" or name == "30E/360": if convention is None: convention = 'BondBasis' convention = convention.replace(" ", "") - cnt = th_from_name(convention) + try: + return Thirty360(thConvention[convention]) + except KeyError as e: + raise ValueError(str(e)) else: raise ValueError("Unkown day counter type: {}".format(name)) - return cnt diff --git a/quantlib/time/daycounters/actual_actual.pxd b/quantlib/time/daycounters/actual_actual.pxd index 79d5526ad..dfebb2ac0 100644 --- a/quantlib/time/daycounters/actual_actual.pxd +++ b/quantlib/time/daycounters/actual_actual.pxd @@ -1,4 +1,3 @@ -cimport quantlib.time._daycounter as _daycounter from quantlib.time.daycounter cimport DayCounter @@ -14,5 +13,3 @@ cdef extern from 'ql/time/daycounters/actualactual.hpp' namespace 'QuantLib::Act Actual365 AFB Euro - -cdef _daycounter.DayCounter* from_name(str convention) diff --git a/quantlib/time/daycounters/actual_actual.pyx b/quantlib/time/daycounters/actual_actual.pyx index ef3d7968b..14b17db43 100644 --- a/quantlib/time/daycounters/actual_actual.pyx +++ b/quantlib/time/daycounters/actual_actual.pyx @@ -13,11 +13,8 @@ For more details, refer to https://www.isda.org/a/pIJEE/The-Actual-Actual-Day-Count-Fraction-1999.pdf ''' -from cython.operator cimport dereference as deref -cimport quantlib.time._daycounter as _daycounter -cimport quantlib.time.daycounters._actual_actual as _aa +from . cimport _actual_actual as _aa from quantlib.time.schedule cimport Schedule -from quantlib.time.daycounter cimport DayCounter cdef class ActualActual(DayCounter): @@ -36,11 +33,4 @@ cdef class ActualActual(DayCounter): For more details, refer to https://www.isda.org/a/pIJEE/The-Actual-Actual-Day-Count-Fraction-1999.pdf """ - self._thisptr = <_daycounter.DayCounter*> new \ - _aa.ActualActual(convention, schedule._thisptr) - -cdef _daycounter.DayCounter* from_name(str convention): - - cdef Convention ql_convention = Convention[convention] - - return new _aa.ActualActual(ql_convention) + self._thisptr = new _aa.ActualActual(convention, schedule._thisptr) diff --git a/quantlib/time/daycounters/simple.pyx b/quantlib/time/daycounters/simple.pyx index 6861cf3e5..92c9eaa9d 100644 --- a/quantlib/time/daycounters/simple.pyx +++ b/quantlib/time/daycounters/simple.pyx @@ -1,46 +1,37 @@ """This module contains "simple" Daycounter classes, i.e. which do not depend on a convention""" -from cython.operator cimport dereference as deref - -cimport quantlib.time._daycounter as _daycounter from . cimport _simple from quantlib.time.daycounter cimport DayCounter -cimport quantlib.time.calendars._target as _tg -cimport quantlib.time._calendar as _calendar +from quantlib.time.calendars.target cimport TARGET from quantlib.time.calendar cimport Calendar from libcpp cimport bool cdef class Actual365Fixed(DayCounter): - def __cinit__(self, *args): - self._thisptr = <_daycounter.DayCounter*> new _simple.Actual365Fixed() + def __cinit__(self): + self._thisptr = new _simple.Actual365Fixed() cdef class Actual360(DayCounter): def __cinit__(self, bool include_last_day = False): - self._thisptr = <_daycounter.DayCounter*> new _simple.Actual360(include_last_day) + self._thisptr = new _simple.Actual360(include_last_day) cdef class Business252(DayCounter): - def __cinit__(self, *args, calendar=None): - cdef _calendar.Calendar cl - if calendar is None: - cl = _tg.TARGET() - else: - cl = (calendar)._thisptr - self._thisptr = <_daycounter.DayCounter*> new _simple.Business252(cl) + def __cinit__(self, Calendar calendar=TARGET()): + self._thisptr = new _simple.Business252(calendar._thisptr) cdef class OneDayCounter(DayCounter): - def __cinit__(self, *args): - self._thisptr = <_daycounter.DayCounter*> new _simple.OneDayCounter() + def __cinit__(self): + self._thisptr = new _simple.OneDayCounter() cdef class SimpleDayCounter(DayCounter): - def __cinit__(self, *args): - self._thisptr = <_daycounter.DayCounter*> new _simple.SimpleDayCounter() + def __cinit__(self): + self._thisptr = new _simple.SimpleDayCounter() diff --git a/quantlib/time/daycounters/thirty360.pxd b/quantlib/time/daycounters/thirty360.pxd index d3f099340..868f231b8 100644 --- a/quantlib/time/daycounters/thirty360.pxd +++ b/quantlib/time/daycounters/thirty360.pxd @@ -1,4 +1,3 @@ -cimport quantlib.time._daycounter as _daycounter from quantlib.time.daycounter cimport DayCounter cdef class Thirty360(DayCounter): @@ -15,5 +14,3 @@ cdef extern from 'ql/time/daycounters/thirty360.hpp' namespace 'QuantLib::Thirty ISMA ISDA NASD - -cdef _daycounter.DayCounter* from_name(str convention) except NULL diff --git a/quantlib/time/daycounters/thirty360.pyx b/quantlib/time/daycounters/thirty360.pyx index b18fa7d9b..a93950268 100644 --- a/quantlib/time/daycounters/thirty360.pyx +++ b/quantlib/time/daycounters/thirty360.pyx @@ -62,9 +62,3 @@ cdef class Thirty360(DayCounter): def __cinit__(self, Convention convention=Convention.BondBasis, Date termination_date=Date()): self._thisptr = new _th.Thirty360(convention, deref(termination_date._thisptr)) - -cdef _daycounter.DayCounter* from_name(str convention) except NULL: - try: - return new _th.Thirty360(Convention[convention]) - except KeyError: - raise ValueError("Unknown convention: {}".format(convention))