Skip to content

Commit 983f8c0

Browse files
authored
Merge branch 'main' into dependabot/pip/pyarrow-gte-15-and-lt-25
2 parents 2f13334 + cd851ee commit 983f8c0

21 files changed

Lines changed: 219 additions & 499 deletions

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,7 @@ jobs:
756756
run: ls -R ./dist
757757

758758
- name: Publish to github releases
759-
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
759+
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
760760
with:
761761
draft: true
762762
generate_release_notes: true

conda/dev-environment-unix.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ dependencies:
1717
- flex
1818
- graphviz
1919
- gtest
20-
- httpx>=0.20,<1
20+
- httpx2>=2,<3
2121
- libarrow<25
2222
- libboost>=1.80.0
2323
- libboost-headers>=1.80.0
@@ -47,7 +47,7 @@ dependencies:
4747
- rapidjson
4848
- requests
4949
- ruamel.yaml
50-
- ruff>=0.9,<0.15
50+
- ruff>=0.9,<0.16
5151
- scikit-build
5252
- setuptools>=69,<74
5353
- sqlalchemy

conda/dev-environment-win.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ dependencies:
1717
# - flex # not available on windows
1818
- graphviz
1919
- gtest
20-
- httpx>=0.20,<1
20+
- httpx2>=2,<3
2121
- libarrow<25
2222
- libboost>=1.80.0
2323
- libboost-headers>=1.80.0
@@ -47,7 +47,7 @@ dependencies:
4747
- rapidjson
4848
- requests
4949
- ruamel.yaml
50-
- ruff>=0.9,<0.15
50+
- ruff>=0.9,<0.16
5151
- scikit-build
5252
- setuptools>=69,<74
5353
- sqlalchemy

cpp/csp/core/DynamicBitSet.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,19 +155,12 @@ class DynamicBitSet
155155
private:
156156
using nbit_type = uint8_t;
157157

158-
#ifndef WIN32
159-
#define CLZ_CONSTEXPR constexpr
160-
#else
161-
#define CLZ_CONSTEXPR
162-
#endif
163-
164158
template<typename value_type,
165159
std::enable_if_t<std::is_unsigned<value_type>::value, bool> = true>
166160
static constexpr nbit_type nbits() { return sizeof( value_type ) * 8; }
167161

168162
template<typename U, std::enable_if_t<std::is_unsigned<U>::value, bool> = true>
169-
static CLZ_CONSTEXPR nbit_type log2( U n ) { return nbits<uint32_t>() - clz(static_cast<uint32_t>( n )) - 1; } //upcast to 32 bit to avoid truncation for log2
170-
static CLZ_CONSTEXPR nbit_type log2(uint64_t n) { return nbits<uint64_t>() - clz(n) - 1; }
163+
static constexpr nbit_type log2( U n ) { return nbits<U>() - clz( n ) - 1; }
171164

172165
static constexpr node_type mask( nbit_type bitIndex ) { return ( node_type )1 << bitIndex; }
173166

@@ -182,7 +175,7 @@ class DynamicBitSet
182175
}
183176

184177
static constexpr nbit_type _bits = nbits<NodeT>();
185-
static inline CLZ_CONSTEXPR nbit_type _logBits = log2( _bits );
178+
static inline constexpr nbit_type _logBits = log2( _bits );
186179

187180
node_type * m_nodes;
188181
index_type m_size;

cpp/csp/core/Platform.h

Lines changed: 6 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#ifndef _IN_CSP_CORE_PLATFORM_H
22
#define _IN_CSP_CORE_PLATFORM_H
3+
#include <bit>
34
#include <type_traits>
45
#include <stdint.h>
56
#include <time.h>
@@ -47,47 +48,11 @@ inline tm * localtime_r( const time_t * timep, tm * result )
4748
inline int nanosleep(const timespec* req, timespec* rem)
4849
{
4950
assert(rem == nullptr);
50-
int64_t millis = req->tv_sec * 1000 + req->tv_nsec * 1000000;
51+
int64_t millis = req->tv_sec * 1000 + req->tv_nsec / 1000000;
5152
Sleep(millis);
5253
return 0;
5354
}
5455

55-
inline uint8_t clz(uint64_t n)
56-
{
57-
unsigned long index = 0;
58-
if (_BitScanReverse64(&index, n))
59-
return 64 - index - 1;
60-
return 0;
61-
}
62-
63-
inline uint8_t clz(uint32_t n)
64-
{
65-
unsigned long index = 0;
66-
if (_BitScanReverse(&index, n))
67-
return 32 - index - 1;
68-
return 0;
69-
}
70-
71-
inline uint8_t clz(uint16_t n) { return clz(static_cast<uint32_t>(n)) - 16; }
72-
inline uint8_t clz(uint8_t n) { return clz(static_cast<uint32_t>(n)) - 24; }
73-
74-
template<typename U, std::enable_if_t<std::is_unsigned<U>::value, bool> = true>
75-
inline uint8_t ffs(U n)
76-
{
77-
unsigned long index = 0;
78-
if (_BitScanForward(&index, n))
79-
return index + 1;
80-
return 0;
81-
}
82-
83-
inline uint8_t ffs(uint64_t n)
84-
{
85-
unsigned long index = 0;
86-
if (_BitScanForward64(&index, n))
87-
return index + 1;
88-
return 0;
89-
}
90-
9156
#else
9257

9358
#define CSPIMPL_EXPORT
@@ -100,19 +65,14 @@ inline uint8_t ffs(uint64_t n)
10065

10166
#define NO_INLINE __attribute__ ((noinline))
10267

103-
inline constexpr uint8_t clz(uint32_t n) { return __builtin_clz(n); }
104-
inline constexpr uint8_t clz(uint64_t n) { return __builtin_clzl(n); }
68+
#endif
10569

10670
// clz (count leading zeros) returns number of leading zeros before MSB (i.e. clz(00110..) = 2 )
107-
// __builtin_clz auto-promotes to 32-bits: need to subtract off extra leading zeros
108-
inline constexpr uint8_t clz(uint16_t n) { return clz(static_cast<uint32_t>(n)) - 16; }
109-
inline constexpr uint8_t clz(uint8_t n) { return clz(static_cast<uint32_t>(n)) - 24; }
71+
template<typename U, std::enable_if_t<std::is_unsigned<U>::value, bool> = true>
72+
inline constexpr uint8_t clz( U n ) { return std::countl_zero(n); }
11073

11174
// ffs (find first set) returns offset of first set bit (i.e. ffs(..0110) = 2 ), with ffs(0) = 0
11275
template<typename U, std::enable_if_t<std::is_unsigned<U>::value, bool> = true>
113-
inline constexpr uint8_t ffs( U n ) { return __builtin_ffs(n); }
114-
inline constexpr uint8_t ffs( uint64_t n ) { return __builtin_ffsl(n); }
115-
116-
#endif
76+
inline constexpr uint8_t ffs( U n ) { return n ? std::countr_zero(n) + 1 : 0; }
11777

11878
#endif

cpp/csp/python/Conversions.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ inline PyObject * toPython( const CspEnum & e, const CspType & type )
446446
auto & enumType = static_cast<const CspEnumType&>( type );
447447
const auto * emeta = static_cast<const DialectCspEnumMeta*>( enumType.meta().get() );
448448

449-
PyObject * obj = emeta -> pyMeta() -> toPyEnum( e );
449+
PyObject * obj = emeta -> toPyEnum( e.value() );
450450
if( !obj ) [[unlikely]]
451451
CSP_THROW( ValueError, e.value() << " is not a valid value on csp.enum type " << emeta -> name() );
452452
return obj;
@@ -457,11 +457,13 @@ inline CspEnum fromPython( PyObject * o, const CspType & type )
457457
{
458458
assert( type.type() == CspType::Type::ENUM );
459459

460-
if( !PyType_IsSubtype( Py_TYPE( o ), &PyCspEnum::PyType ) ||
461-
static_cast<PyCspEnum *>( o ) -> meta() != static_cast<const CspEnumType &>( type ).meta().get() )
462-
CSP_THROW( TypeError, "Invalid enum type, expected enum type " << static_cast<const CspEnumType &>( type ).meta() -> name() << " got " << Py_TYPE( o ) -> tp_name );
463-
464-
return static_cast<PyCspEnum *>( o ) -> enum_;
460+
auto & enumType = static_cast<const CspEnumType&>( type );
461+
const auto * emeta = static_cast<const DialectCspEnumMeta*>( enumType.meta().get() );
462+
463+
if( !PyObject_IsInstance( o, ( PyObject * ) emeta -> pyType().get() ) )
464+
CSP_THROW( TypeError, "Invalid enum type, expected enum type " << emeta -> pyType() -> tp_name << " got " << Py_TYPE( o ) -> tp_name );
465+
466+
return static_cast<const CspEnumType &>( type ).meta() -> create( fromPython<int64_t>( o ) );
465467
}
466468

467469
//TimeDelta

cpp/csp/python/CspTypeFactory.cpp

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,23 @@
77
namespace csp::python
88
{
99

10+
CspTypeFactory::CspTypeFactory()
11+
{
12+
PyObject *enum_mod = PyImport_ImportModule( "enum" );
13+
m_intEnumPyType = ( PyTypeObject * ) PyObject_GetAttrString( enum_mod, "IntEnum" );
14+
}
15+
1016
CspTypeFactory & CspTypeFactory::instance()
1117
{
12-
static CspTypeFactory s_instance;
13-
return s_instance;
18+
//We let this leak since some csp types ( ie CspEnum ) can hold a ref to DialectCspEnumMeta which holds Ptrs
19+
//to python objects, which cant be destroyed statically after python interpreter is shutdown
20+
static CspTypeFactory * s_instance = new CspTypeFactory();
21+
return *s_instance;
22+
}
23+
24+
bool CspTypeFactory::isCspEnumPyType( PyTypeObject * pyType )
25+
{
26+
return PyType_IsSubtype( pyType, m_intEnumPyType );
1427
}
1528

1629
CspTypePtr & CspTypeFactory::typeFromPyType( PyObject * pyTypeObj )
@@ -59,9 +72,9 @@ CspTypePtr & CspTypeFactory::typeFromPyType( PyObject * pyTypeObj )
5972
auto meta = ( ( PyStructMeta * ) pyType ) -> structMeta;
6073
rv.first -> second = std::make_shared<csp::CspStructType>( meta );
6174
}
62-
else if( PyType_IsSubtype( pyType, &PyCspEnum::PyType ) )
75+
else if( isCspEnumPyType( pyType ) )
6376
{
64-
auto meta = ( ( PyCspEnumMeta * ) pyType ) -> enumMeta;
77+
auto meta = createCspEnumMetaFromIntEnum( PyTypeObjectPtr::incref( pyType ) );
6578
rv.first -> second = std::make_shared<csp::CspEnumType>( meta );
6679
}
6780
else if( pyType == PyDateTimeAPI -> DateTimeType )
@@ -88,4 +101,30 @@ void CspTypeFactory::removeCachedType( PyTypeObject * pyType )
88101
m_cache.erase( pyType );
89102
}
90103

104+
std::shared_ptr<CspEnumMeta> CspTypeFactory::createCspEnumMetaFromIntEnum( PyTypeObjectPtr pyIntEnumType )
105+
{
106+
CspEnumMeta::ValueDef metadef;
107+
108+
PyObjectPtr iter = PyObjectPtr::check( PyObject_GetIter( ( PyObject * ) pyIntEnumType.get() ) );
109+
PyObject * member;
110+
while( ( member = PyIter_Next( iter.get() ) ) != NULL )
111+
{
112+
PyObjectPtr name = PyObjectPtr::check( PyObject_GetAttrString( member, "name" ) );
113+
114+
const char * namestr = PyUnicode_AsUTF8( name.get() );
115+
if( !namestr )
116+
CSP_THROW( PythonPassthrough, "" );
117+
118+
if( !PyLong_Check( member ) )
119+
CSP_THROW( TypeError, "enum key " << namestr << " expected an integer got " << PyObjectPtr::incref( member ) );
120+
121+
int64_t value = fromPython<int64_t>( member );
122+
metadef[ namestr ] = value;
123+
124+
Py_DECREF( member );
125+
}
126+
127+
return std::make_shared<DialectCspEnumMeta>( pyIntEnumType, pyIntEnumType -> tp_name, metadef );
128+
}
129+
91130
}

cpp/csp/python/CspTypeFactory.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <csp/core/Platform.h>
55
#include <csp/engine/CspType.h>
6+
#include <csp/python/PyObjectPtr.h>
67
#include <unordered_map>
78
#include <Python.h>
89

@@ -17,9 +18,17 @@ class CSPTYPESIMPL_EXPORT CspTypeFactory
1718
CspTypePtr & typeFromPyType( PyObject * );
1819
void removeCachedType( PyTypeObject * );
1920

21+
bool isCspEnumPyType( PyTypeObject * pyType );
22+
2023
private:
2124
using Cache = std::unordered_map<PyTypeObject *, CspTypePtr>;
25+
26+
std::shared_ptr<CspEnumMeta> createCspEnumMetaFromIntEnum( PyTypeObjectPtr pyIntEnumType );
27+
28+
CspTypeFactory();
2229
Cache m_cache;
30+
31+
PyTypeObject * m_intEnumPyType;
2332
};
2433

2534
}

0 commit comments

Comments
 (0)