Question: I have this Point class. I want it to be able to recieve double and SomeType parameters. Point.pxd: from libcpp.memory cimport shared_ptr, weak_ptr, make_shared from SomeType cimport _SomeType, SomeType cdef extern from "Point.h": cdef cppclass _Point: _Point(shared_ptr[double] x, shared_ptr[double] y) _Point(shared_ptr[double] x, shared_ptr[double] y, shared_ptr[double] z) _Point(shared_ptr[_SomeType] x, shared_ptr[_SomeType] y) _Point(shared_ptr[_SomeType] x, shared_ptr[_SomeType] y, shared_ptr[_SomeType] z) shared_ptr[_SomeType] get_x() shared_ptr[_SomeType] get_y() shared_ptr[_SomeType] get_z() cdef class Point: cdef shared_ptr[_Point] c_point  Point.pyx: from Point cimport * cdef class Point: def __cinit__(self, SomeType x=SomeType("0", None), SomeType y=SomeType("0", None), SomeType z=SomeType("0", None)): self.c_point = make_shared[_Point](x.thisptr, y.thisptr, z.thisptr) def __dealloc(self): self.c_point.reset() def get_x(self) -> SomeType: cdef shared_ptr[_SomeType] result = self.c_point.get().get_x() cdef SomeType coord = SomeType("", None, make_with_pointer = True) coord.thisptr = result return coord def get_y(self) -> SomeType: cdef shared_ptr[_SomeType] result = self.c_point.get().get_y() cdef SomeType coord = SomeType("", None, make_with_pointer = True) coord.thisptr = result return coord def get_z(self) -> SomeType: cdef shared_ptr[_SomeType] result = self.c_point.get().get_z() cdef SomeType coord = SomeType("", None, make_with_pointer = True) coord.thisptr = result return coord property x: def __get__(self): return self.get_x() property y: def __get__(self): return self.get_y() property z: def __get__(self): return self.get_z()  How should I write my .pxd and .pyx files so that my Point constructor can receive different type of parameters?

Answer: In Cython, you cannot directly overload constructors (or any methods) as you might in C++ or other languages that support method overloading. However, you can achieve similar functionality by using factory methods or by using Python's flexibility with arguments. Given your scenario where the Point class needs to accept different types of parameters (either double or SomeType objects), you can implement this flexibility using Python's *args and **kwargs in combination with type checking and processing logic inside the constructor. Additionally, you can define class methods that act as alternative constructors, which is a common Pythonic approach to solve this issue. Here’s how you might adjust your .pxd and .pyx files to accommodate these requirements:  Point.pxd  This file remains largely the same but ensure it correctly declares everything you need: # Point.pxd from libcpp.memory cimport shared_ptr, make_shared from SomeType cimport _SomeType, SomeType cdef extern from "Point.h": cdef cppclass _Point: _Point(shared_ptr[double] x, shared_ptr[double] y) _Point(shared_ptr[double] x, shared_ptr[double] y, shared_ptr[double] z) _Point(shared_ptr[_SomeType] x, shared_ptr[_SomeType] y) _Point(shared_ptr[_SomeType] x, shared_ptr[_SomeType] y, shared_ptr[_SomeType] z) cdef class Point: cdef shared_ptr[_Point] c_point   Point.pyx  Modify this file to include a flexible constructor and additional class methods for different initialisations: # Point.pyx from Point cimport * from libc.stdlib cimport atof cdef class Point: def __cinit__(self, *args): if len(args) == 2 or len(args) == 3: if isinstance(args[0], SomeType): ptrs = [arg.thisptr for arg in args] else: ptrs = [make_shared[double](atof(arg)) for arg in args] if len(args) == 2: self.c_point = make_shared[_Point](ptrs[0], ptrs[1]) elif len(args) == 3: self.c_point = make_shared[_Point](ptrs[0], ptrs[1], ptrs[2]) else: raise ValueError("Invalid number of arguments") def __dealloc__(self): self.c_point.reset() @staticmethod def from_doubles(x, y, z=None): cdef shared_ptr[double] px = make_shared[double](x) cdef shared_ptr[double] py = make_shared[double](y) cdef shared_ptr[double] pz = make_shared[double](z) if z is not None else None if z is None: return Point(px, py) return Point(px, py, pz) # ... rest of the methods ...  Here, __cinit__ accepts variable arguments (*args). It determines the type of each argument and constructs the c_point appropriately, based on the number of arguments and their types. The from_doubles static method provides a clearer, type-specific way to create instances from double values. This approach gives you the flexibility to initialise Point objects with different types while maintaining clean, readable code. Make sure that the make_shared[double](x) conversions handle input correctly, and adjust the type-checking and conversions as necessary for your specific needs and types.