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

Add NumPy Scalars #3544

Open
wants to merge 295 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 250 commits
Commits
Show all changes
295 commits
Select commit Hold shift + click to select a range
fe3a766
Merge branch 'pybind:master' into master
sun1638650145 Mar 31, 2022
2c6d4f1
Merge branch 'pybind:master' into master
sun1638650145 Apr 1, 2022
ed5fb65
Merge branch 'pybind:master' into master
sun1638650145 Apr 6, 2022
44265a1
Merge branch 'pybind:master' into master
sun1638650145 Apr 12, 2022
d841dbc
Merge branch 'pybind:master' into master
sun1638650145 Apr 14, 2022
9a3eab1
Merge branch 'pybind:master' into master
sun1638650145 Apr 15, 2022
61040ef
Merge branch 'pybind:master' into master
sun1638650145 Apr 19, 2022
f0d6068
Merge branch 'pybind:master' into master
sun1638650145 Apr 24, 2022
c8d52c4
Merge branch 'pybind:master' into master
sun1638650145 Apr 26, 2022
081d5af
Merge branch 'pybind:master' into master
sun1638650145 May 3, 2022
19258b5
Merge branch 'pybind:master' into master
sun1638650145 May 5, 2022
bd722e0
Merge branch 'pybind:master' into master
sun1638650145 May 5, 2022
05fa0d1
Merge branch 'pybind:master' into master
sun1638650145 May 7, 2022
bad8c52
Merge branch 'pybind:master' into master
sun1638650145 May 10, 2022
e2614dc
Merge branch 'pybind:master' into master
sun1638650145 May 17, 2022
a3e7271
Merge branch 'pybind:master' into master
sun1638650145 May 19, 2022
fef5f12
Merge branch 'pybind:master' into master
sun1638650145 May 20, 2022
87e3a81
Merge branch 'pybind:master' into master
sun1638650145 May 21, 2022
1500804
Merge branch 'pybind:master' into master
sun1638650145 May 24, 2022
260313f
Merge branch 'pybind:master' into master
sun1638650145 May 25, 2022
0ca3c2c
Merge branch 'pybind:master' into master
sun1638650145 May 26, 2022
c79813b
Merge branch 'pybind:master' into master
sun1638650145 May 27, 2022
d9ece32
Merge branch 'pybind:master' into master
sun1638650145 May 28, 2022
dfc0689
Merge branch 'pybind:master' into master
sun1638650145 May 29, 2022
8f7779a
Merge branch 'pybind:master' into master
sun1638650145 Jun 1, 2022
960b7b8
Merge branch 'pybind:master' into master
sun1638650145 Jun 2, 2022
a5521f0
Merge branch 'pybind:master' into master
sun1638650145 Jun 3, 2022
e9a70ce
Merge branch 'pybind:master' into master
sun1638650145 Jun 4, 2022
bb6ae50
Merge branch 'pybind:master' into master
sun1638650145 Jun 7, 2022
a2ec914
Merge branch 'pybind:master' into master
sun1638650145 Jun 7, 2022
a40a444
Merge branch 'pybind:master' into master
sun1638650145 Jun 9, 2022
46a1b76
Merge branch 'pybind:master' into master
sun1638650145 Jun 14, 2022
fafcb82
Merge branch 'pybind:master' into master
sun1638650145 Jun 21, 2022
3de9be9
Merge branch 'pybind:master' into master
sun1638650145 Jun 28, 2022
196a544
Merge branch 'pybind:master' into master
sun1638650145 Jun 29, 2022
5fad266
Merge branch 'pybind:master' into master
sun1638650145 Jun 29, 2022
0acf526
Merge branch 'pybind:master' into master
sun1638650145 Jul 5, 2022
ae1880f
Merge branch 'pybind:master' into master
sun1638650145 Jul 5, 2022
5ef5a14
Merge branch 'pybind:master' into master
sun1638650145 Jul 7, 2022
2d3af75
Merge branch 'pybind:master' into master
sun1638650145 Jul 8, 2022
8f4556f
Merge branch 'pybind:master' into master
sun1638650145 Jul 11, 2022
17f60cb
Merge branch 'pybind:master' into master
sun1638650145 Jul 13, 2022
0056a3e
Merge branch 'pybind:master' into master
sun1638650145 Jul 14, 2022
940d9dc
Merge branch 'pybind:master' into master
sun1638650145 Jul 15, 2022
84ef55f
Merge branch 'pybind:master' into master
sun1638650145 Jul 16, 2022
7f2daa0
Merge branch 'pybind:master' into master
sun1638650145 Jul 17, 2022
a336603
Merge branch 'pybind:master' into master
sun1638650145 Jul 19, 2022
b991042
Merge branch 'pybind:master' into master
sun1638650145 Jul 21, 2022
349090c
Merge branch 'pybind:master' into master
sun1638650145 Jul 22, 2022
5164d16
Merge branch 'pybind:master' into master
sun1638650145 Jul 23, 2022
5cec631
Merge branch 'pybind:master' into master
sun1638650145 Jul 29, 2022
1fd6490
Merge branch 'pybind:master' into master
sun1638650145 Aug 2, 2022
9650080
Merge branch 'pybind:master' into master
sun1638650145 Aug 4, 2022
3311cc9
Merge branch 'pybind:master' into master
sun1638650145 Aug 8, 2022
56b14f2
Merge branch 'pybind:master' into master
sun1638650145 Aug 9, 2022
82146ab
Merge branch 'pybind:master' into master
sun1638650145 Aug 9, 2022
7fa86a3
Merge branch 'pybind:master' into master
sun1638650145 Aug 12, 2022
c2f9bcd
Merge branch 'pybind:master' into master
sun1638650145 Aug 13, 2022
516a3de
Merge branch 'pybind:master' into master
sun1638650145 Aug 21, 2022
e654825
Merge branch 'pybind:master' into master
sun1638650145 Aug 22, 2022
a8a90fc
Merge branch 'pybind:master' into master
sun1638650145 Aug 25, 2022
06345fd
Merge branch 'pybind:master' into master
sun1638650145 Aug 30, 2022
6ed73dc
Merge branch 'pybind:master' into master
sun1638650145 Sep 8, 2022
9e7114b
Merge branch 'pybind:master' into master
sun1638650145 Sep 13, 2022
02db5fb
Merge branch 'pybind:master' into master
sun1638650145 Sep 14, 2022
e3fa429
Merge branch 'pybind:master' into master
sun1638650145 Sep 20, 2022
b238590
Merge branch 'pybind:master' into master
sun1638650145 Sep 21, 2022
8fd14ab
Merge branch 'pybind:master' into master
sun1638650145 Sep 22, 2022
5f31ef3
Merge branch 'pybind:master' into master
sun1638650145 Sep 26, 2022
155d992
Merge branch 'pybind:master' into master
sun1638650145 Sep 27, 2022
0e7a9d0
Merge branch 'pybind:master' into master
sun1638650145 Oct 4, 2022
77df600
Merge branch 'pybind:master' into master
sun1638650145 Oct 6, 2022
812293c
Merge branch 'pybind:master' into master
sun1638650145 Oct 9, 2022
92d00b1
Merge branch 'pybind:master' into master
sun1638650145 Oct 11, 2022
f8fab5a
Merge branch 'pybind:master' into master
sun1638650145 Oct 12, 2022
bca73e3
Merge branch 'pybind:master' into master
sun1638650145 Oct 13, 2022
a5fee6f
Merge branch 'pybind:master' into master
sun1638650145 Oct 18, 2022
61fb91c
Merge branch 'pybind:master' into master
sun1638650145 Oct 19, 2022
23f69dd
Merge branch 'pybind:master' into master
sun1638650145 Oct 21, 2022
73b286d
Merge branch 'pybind:master' into master
sun1638650145 Oct 24, 2022
cd3268c
Merge branch 'pybind:master' into master
sun1638650145 Oct 27, 2022
9a398b8
Merge branch 'pybind:master' into master
sun1638650145 Oct 30, 2022
a7f83b3
Merge branch 'pybind:master' into master
sun1638650145 Oct 31, 2022
50fa74e
Merge branch 'pybind:master' into master
sun1638650145 Nov 1, 2022
3a04867
Merge branch 'pybind:master' into master
sun1638650145 Nov 1, 2022
3eaf02c
Merge branch 'pybind:master' into master
sun1638650145 Nov 2, 2022
71f1d13
Merge branch 'pybind:master' into master
sun1638650145 Nov 3, 2022
f762bbe
Merge branch 'pybind:master' into master
sun1638650145 Nov 11, 2022
bbe7e7b
Merge branch 'pybind:master' into master
sun1638650145 Nov 13, 2022
4985156
Merge branch 'pybind:master' into master
sun1638650145 Nov 23, 2022
7559d87
Merge branch 'pybind:master' into master
sun1638650145 Nov 24, 2022
3196c13
Merge branch 'pybind:master' into master
sun1638650145 Nov 26, 2022
2a0399d
Merge branch 'pybind:master' into master
sun1638650145 Nov 29, 2022
f33b2e9
Merge branch 'pybind:master' into master
sun1638650145 Dec 2, 2022
6da7b51
Merge branch 'pybind:master' into master
sun1638650145 Dec 5, 2022
50bf9df
Merge branch 'pybind:master' into master
sun1638650145 Dec 6, 2022
8f50fcd
Merge branch 'pybind:master' into master
sun1638650145 Dec 7, 2022
beed6a6
Merge branch 'pybind:master' into master
sun1638650145 Dec 8, 2022
cb3791f
Merge branch 'pybind:master' into master
sun1638650145 Dec 10, 2022
d176433
Merge branch 'pybind:master' into master
sun1638650145 Dec 12, 2022
0420181
Merge branch 'pybind:master' into master
sun1638650145 Dec 14, 2022
3bcab95
Merge branch 'pybind:master' into master
sun1638650145 Dec 26, 2022
db7ad7f
Merge branch 'pybind:master' into master
sun1638650145 Dec 28, 2022
de0600e
Merge branch 'pybind:master' into master
sun1638650145 Dec 29, 2022
d461292
Merge branch 'pybind:master' into master
sun1638650145 Dec 31, 2022
b28593e
Merge branch 'pybind:master' into master
sun1638650145 Jan 3, 2023
a1f63c4
Merge branch 'pybind:master' into master
sun1638650145 Jan 4, 2023
b2b6271
Merge branch 'pybind:master' into master
sun1638650145 Jan 14, 2023
86d96b6
Merge branch 'pybind:master' into master
sun1638650145 Jan 15, 2023
590fc5b
Merge branch 'pybind:master' into master
sun1638650145 Jan 19, 2023
9f574a7
Merge branch 'pybind:master' into master
sun1638650145 Jan 20, 2023
b6edf66
Merge branch 'pybind:master' into master
sun1638650145 Feb 2, 2023
7821798
Merge branch 'pybind:master' into master
sun1638650145 Feb 5, 2023
c1cfc6a
Merge branch 'pybind:master' into master
sun1638650145 Feb 13, 2023
47ff113
Merge branch 'pybind:master' into master
sun1638650145 Feb 16, 2023
bb06ad7
Merge branch 'pybind:master' into master
sun1638650145 Feb 18, 2023
f6cf8ce
Merge branch 'pybind:master' into master
sun1638650145 Feb 21, 2023
affda02
Merge branch 'pybind:master' into master
sun1638650145 Feb 23, 2023
8eb33fe
style: pre-commit fixes
pre-commit-ci[bot] Feb 23, 2023
e89e835
Merge branch 'pybind:master' into master
sun1638650145 Feb 24, 2023
88f4a48
style: pre-commit fixes
pre-commit-ci[bot] Feb 24, 2023
54e68c5
Merge branch 'pybind:master' into master
sun1638650145 Mar 8, 2023
decc032
Merge branch 'pybind:master' into master
sun1638650145 Mar 10, 2023
b66c98d
Merge branch 'pybind:master' into master
sun1638650145 Mar 17, 2023
d4386b2
Merge branch 'pybind:master' into master
sun1638650145 Mar 23, 2023
2c647f1
Merge branch 'pybind:master' into master
sun1638650145 Mar 25, 2023
9ac2d08
Merge branch 'pybind:master' into master
sun1638650145 Mar 28, 2023
0987bb2
Merge branch 'pybind:master' into master
sun1638650145 Mar 28, 2023
5ebcfa5
Merge branch 'pybind:master' into master
sun1638650145 Mar 31, 2023
123a8fc
Merge branch 'pybind:master' into master
sun1638650145 Apr 4, 2023
86f6611
Merge branch 'pybind:master' into master
sun1638650145 Apr 8, 2023
e61a359
Merge branch 'pybind:master' into master
sun1638650145 Apr 24, 2023
f80d415
Merge branch 'pybind:master' into master
sun1638650145 Apr 25, 2023
0d65ba3
Merge branch 'pybind:master' into master
sun1638650145 Apr 26, 2023
459874e
Merge branch 'pybind:master' into master
sun1638650145 Apr 28, 2023
64b675d
Merge branch 'pybind:master' into master
sun1638650145 Apr 29, 2023
3470abc
Merge branch 'pybind:master' into master
sun1638650145 May 3, 2023
18bad66
Merge branch 'pybind:master' into master
sun1638650145 May 6, 2023
d0d2673
Merge branch 'pybind:master' into master
sun1638650145 May 8, 2023
31d656a
Merge branch 'pybind:master' into master
sun1638650145 May 9, 2023
ae56a3b
Merge branch 'pybind:master' into master
sun1638650145 May 10, 2023
a7c3647
Merge branch 'pybind:master' into master
sun1638650145 May 16, 2023
58f02c5
Merge branch 'pybind:master' into master
sun1638650145 May 23, 2023
3fe6688
Merge branch 'pybind:master' into master
sun1638650145 May 24, 2023
b7185b4
Merge branch 'pybind:master' into master
sun1638650145 May 26, 2023
15c5e06
Merge branch 'pybind:master' into master
sun1638650145 Jun 8, 2023
27ea902
Merge branch 'pybind:master' into master
sun1638650145 Jun 11, 2023
1d69aeb
Merge branch 'pybind:master' into master
sun1638650145 Jun 17, 2023
41b41c0
Merge branch 'pybind:master' into master
sun1638650145 Jun 19, 2023
8b4623b
Merge branch 'pybind:master' into master
sun1638650145 Jun 22, 2023
63216ae
Merge branch 'pybind:master' into master
sun1638650145 Jun 25, 2023
1771e1e
Merge branch 'pybind:master' into master
sun1638650145 Jun 28, 2023
c3d3ec4
Merge branch 'pybind:master' into master
sun1638650145 Jul 5, 2023
128ff3c
Merge branch 'pybind:master' into master
sun1638650145 Jul 14, 2023
616937b
Merge branch 'pybind:master' into master
sun1638650145 Jul 15, 2023
b2ffda1
Merge branch 'pybind:master' into master
sun1638650145 Jul 16, 2023
9789730
Merge branch 'pybind:master' into master
sun1638650145 Jul 17, 2023
74e1a8e
Merge branch 'pybind:master' into master
sun1638650145 Jul 18, 2023
3ef803c
Merge branch 'pybind:master' into master
sun1638650145 Jul 24, 2023
887a7af
Merge branch 'pybind:master' into master
sun1638650145 Aug 4, 2023
e7086ad
Merge branch 'pybind:master' into master
sun1638650145 Aug 7, 2023
c903947
Merge branch 'pybind:master' into master
sun1638650145 Aug 9, 2023
88430cb
Merge branch 'pybind:master' into master
sun1638650145 Aug 11, 2023
a6c8bbf
Merge branch 'pybind:master' into master
sun1638650145 Aug 16, 2023
6b905e5
Merge branch 'pybind:master' into master
sun1638650145 Aug 23, 2023
ab96a97
Merge branch 'pybind:master' into master
sun1638650145 Aug 30, 2023
38d23b9
Merge branch 'pybind:master' into master
sun1638650145 Aug 31, 2023
366591a
Merge branch 'pybind:master' into master
sun1638650145 Sep 2, 2023
e9306bd
Merge branch 'pybind:master' into master
sun1638650145 Sep 6, 2023
15ff9f4
style: pre-commit fixes
pre-commit-ci[bot] Sep 6, 2023
b16f121
Merge branch 'pybind:master' into master
sun1638650145 Sep 7, 2023
ae96fd6
Merge branch 'pybind:master' into master
sun1638650145 Sep 13, 2023
41e182b
Merge branch 'pybind:master' into master
sun1638650145 Sep 15, 2023
4669771
Merge branch 'pybind:master' into master
sun1638650145 Sep 18, 2023
df86c5d
Merge branch 'pybind:master' into master
sun1638650145 Sep 26, 2023
eebdc43
Merge branch 'pybind:master' into master
sun1638650145 Sep 28, 2023
140463a
Merge branch 'pybind:master' into master
sun1638650145 Oct 5, 2023
2eb545f
Merge branch 'pybind:master' into master
sun1638650145 Oct 7, 2023
4ab72ba
Merge branch 'pybind:master' into master
sun1638650145 Oct 14, 2023
873685e
Merge branch 'pybind:master' into master
sun1638650145 Oct 17, 2023
0bcfee3
Merge branch 'pybind:master' into master
sun1638650145 Oct 18, 2023
6b7cc9e
Merge branch 'pybind:master' into master
sun1638650145 Oct 23, 2023
a572fe7
Merge branch 'pybind:master' into master
sun1638650145 Oct 24, 2023
e8ab9f1
Merge branch 'pybind:master' into master
sun1638650145 Oct 25, 2023
b6a2661
Merge branch 'pybind:master' into master
sun1638650145 Oct 28, 2023
27e0e0d
Merge branch 'pybind:master' into master
sun1638650145 Nov 1, 2023
8d5e5f3
Merge branch 'pybind:master' into master
sun1638650145 Nov 6, 2023
6b3ac19
Merge branch 'pybind:master' into master
sun1638650145 Nov 9, 2023
03e4069
Merge branch 'pybind:master' into master
sun1638650145 Nov 16, 2023
4cc3b04
Merge branch 'pybind:master' into master
sun1638650145 Nov 17, 2023
3299c99
Merge branch 'pybind:master' into master
sun1638650145 Nov 28, 2023
b5e632b
Merge branch 'pybind:master' into master
sun1638650145 Nov 30, 2023
0a3d010
Merge branch 'pybind:master' into master
sun1638650145 Dec 6, 2023
aed56f4
Merge branch 'pybind:master' into master
sun1638650145 Dec 8, 2023
7aaf5a8
Merge branch 'pybind:master' into master
sun1638650145 Dec 15, 2023
e2bf289
Merge branch 'pybind:master' into master
sun1638650145 Dec 31, 2023
90e9dd6
Merge branch 'pybind:master' into master
sun1638650145 Jan 3, 2024
3c06260
Merge branch 'pybind:master' into master
sun1638650145 Jan 9, 2024
9a1cded
Merge branch 'pybind:master' into master
sun1638650145 Jan 15, 2024
c4fc231
Merge branch 'pybind:master' into master
sun1638650145 Jan 18, 2024
23c60bf
Merge branch 'pybind:master' into master
sun1638650145 Jan 31, 2024
c14dba3
Merge branch 'pybind:master' into master
sun1638650145 Feb 7, 2024
48823c0
Merge branch 'pybind:master' into master
sun1638650145 Feb 22, 2024
e1385e2
Merge branch 'pybind:master' into master
sun1638650145 Mar 26, 2024
3c61edf
Merge branch 'pybind:master' into master
sun1638650145 Mar 27, 2024
b53af63
Merge branch 'pybind:master' into master
sun1638650145 Mar 28, 2024
af4200c
Bugfix.
sun1638650145 Mar 29, 2024
6ed90b7
Merge branch 'pybind:master' into master
sun1638650145 Apr 3, 2024
9d86bb2
Merge branch 'pybind:master' into master
sun1638650145 Apr 10, 2024
2c26d12
Merge branch 'pybind:master' into master
sun1638650145 May 7, 2024
a51ee57
Merge branch 'pybind:master' into master
sun1638650145 May 13, 2024
5b95c06
Merge branch 'pybind:master' into master
sun1638650145 May 24, 2024
aeebb92
Merge branch 'pybind:master' into master
sun1638650145 May 25, 2024
dc4da1c
Merge branch 'pybind:master' into master
sun1638650145 May 28, 2024
5c48f48
Merge branch 'pybind:master' into master
sun1638650145 May 29, 2024
eb54c19
Merge branch 'pybind:master' into master
sun1638650145 May 30, 2024
2b774ea
Merge branch 'pybind:master' into master
sun1638650145 May 31, 2024
9262665
Merge branch 'pybind:master' into master
sun1638650145 Jun 6, 2024
0075abb
Merge branch 'pybind:master' into master
sun1638650145 Jun 12, 2024
c2ccd08
Merge branch 'pybind:master' into master
sun1638650145 Jun 17, 2024
670fe39
Merge branch 'pybind:master' into master
sun1638650145 Jun 18, 2024
4899b3b
Merge branch 'pybind:master' into master
sun1638650145 Jun 19, 2024
4ecbcdd
Merge branch 'pybind:master' into master
sun1638650145 Jun 22, 2024
4c1a41e
Merge branch 'pybind:master' into master
sun1638650145 Jun 24, 2024
894234b
style: pre-commit fixes
pre-commit-ci[bot] Jun 24, 2024
59e162e
Merge branch 'pybind:master' into master
sun1638650145 Jun 25, 2024
1b9bd80
Merge branch 'pybind:master' into master
sun1638650145 Jun 26, 2024
f72d4c4
Merge branch 'pybind:master' into master
sun1638650145 Jun 27, 2024
d2d7ea5
Merge branch 'pybind:master' into master
sun1638650145 Jul 1, 2024
b6049a1
Merge branch 'pybind:master' into master
sun1638650145 Jul 2, 2024
a46371c
Merge branch 'pybind:master' into master
sun1638650145 Jul 3, 2024
835ec96
Merge branch 'pybind:master' into master
sun1638650145 Jul 8, 2024
35ee1c1
Merge branch 'pybind:master' into master
sun1638650145 Jul 16, 2024
044e3d7
Merge branch 'pybind:master' into master
sun1638650145 Jul 17, 2024
0c24110
Merge branch 'pybind:master' into master
sun1638650145 Jul 19, 2024
c189ade
Merge branch 'pybind:master' into master
sun1638650145 Jul 24, 2024
8d22552
Merge branch 'pybind:master' into master
sun1638650145 Jul 30, 2024
64c871e
Merge branch 'pybind:master' into master
sun1638650145 Jul 31, 2024
9e3db44
Merge branch 'pybind:master' into master
sun1638650145 Aug 3, 2024
d92ad15
Merge branch 'pybind:master' into master
sun1638650145 Aug 6, 2024
32f9c84
Merge branch 'pybind:master' into master
sun1638650145 Aug 7, 2024
46e6ec6
Merge branch 'pybind:master' into master
sun1638650145 Aug 13, 2024
60fd565
Merge branch 'pybind:master' into master
sun1638650145 Aug 14, 2024
a4b4a91
Merge branch 'pybind:master' into master
sun1638650145 Aug 15, 2024
e3df9d8
Merge branch 'pybind:master' into master
sun1638650145 Aug 16, 2024
4ee5a89
Merge branch 'pybind:master' into master
sun1638650145 Aug 22, 2024
9e62497
Merge branch 'pybind:master' into master
sun1638650145 Aug 23, 2024
ffec979
Merge branch 'pybind:master' into master
sun1638650145 Aug 27, 2024
ae43d51
Merge branch 'pybind:master' into master
sun1638650145 Aug 29, 2024
5b5863a
Merge branch 'pybind:master' into master
sun1638650145 Aug 30, 2024
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
40 changes: 40 additions & 0 deletions docs/advanced/pycpp/numpy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,46 @@ prevent many types of unsupported structures, it is still the user's
responsibility to use only "plain" structures that can be safely manipulated as
raw memory without violating invariants.

Scalar types
============

In some cases we may want to accept or return NumPy scalar values such as
``np.float32`` or ``np.float64``. We hope to be able to handle single-precision
and double-precision on the C-side. However, both are bound to Python's
double-precision builtin float by default, so they cannot be processed separately.
We used the ``py::buffer`` trick to implement the previous approach, which
will cause the readability of the code to drop significantly.

Luckily, there's a helper type for this occasion - ``py::numpy_scalar``:

.. code-block:: cpp

m.def("add", [](py::numpy_scalar<float> a, py::numpy_scalar<float> b) {
return py::make_scalar(a + b);
});
m.def("add", [](py::numpy_scalar<double> a, py::numpy_scalar<double> b) {
return py::make_scalar(a + b);
});

This type is trivially convertible to and from the type it wraps; currently
supported scalar types are NumPy arithmetic types: ``bool_``, ``int8``,
``int16``, ``int32``, ``int64``, ``uint8``, ``uint16``, ``uint32``,
``uint64``, ``float32``, ``float64``, ``complex64``, ``complex128``, all of
them mapping to respective C++ counterparts.

.. note::

This is a strict type, it will only allows to specify NumPy type as input
arguments, and does not allow other types of input parameters (e.g.,
``py::numpy_scalar<int64_t>`` will not accept Python's builtin ``int`` ).

.. note::

Native C types are mapped to NumPy types in a platform specific way: for
instance, ``char`` may be mapped to either ``np.int8`` or ``np.uint8``
and ``long`` may use 4 or 8 bytes depending on the platform. Unless you
clearly understand the difference and your needs, please use ``<cstdint>``.

Vectorizing functions
=====================

Expand Down
209 changes: 163 additions & 46 deletions include/pybind11/numpy.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ PYBIND11_WARNING_DISABLE_MSVC(4127)
class dtype; // Forward declaration
class array; // Forward declaration

template <typename>
struct numpy_scalar; // Forward declaration

PYBIND11_NAMESPACE_BEGIN(detail)

template <>
Expand Down Expand Up @@ -200,15 +203,15 @@ struct same_size {
using as = bool_constant<sizeof(T) == sizeof(U)>;
};

template <typename Concrete>
template <std::size_t>
constexpr int platform_lookup() {
return -1;
}

// Lookup a type according to its size, and return a value corresponding to the NumPy typenum.
template <typename Concrete, typename T, typename... Ts, typename... Ints>
template <std::size_t size, typename T, typename... Ts, typename... Ints>
constexpr int platform_lookup(int I, Ints... Is) {
return sizeof(Concrete) == sizeof(T) ? I : platform_lookup<Concrete, Ts...>(Is...);
return sizeof(size) == sizeof(T) ? I : platform_lookup<size, Ts...>(Is...);
}

struct npy_api {
Expand Down Expand Up @@ -249,15 +252,23 @@ struct npy_api {
// `npy_common.h` defines the integer aliases. In order, it checks:
// NPY_BITSOF_LONG, NPY_BITSOF_LONGLONG, NPY_BITSOF_INT, NPY_BITSOF_SHORT, NPY_BITSOF_CHAR
// and assigns the alias to the first matching size, so we should check in this order.
NPY_INT32_
= platform_lookup<std::int32_t, long, int, short>(NPY_LONG_, NPY_INT_, NPY_SHORT_),
NPY_UINT32_ = platform_lookup<std::uint32_t, unsigned long, unsigned int, unsigned short>(
NPY_INT32_ = platform_lookup<4, long, int, short>(NPY_LONG_, NPY_INT_, NPY_SHORT_),
NPY_UINT32_ = platform_lookup<4, unsigned long, unsigned int, unsigned short>(
NPY_ULONG_, NPY_UINT_, NPY_USHORT_),
NPY_INT64_
= platform_lookup<std::int64_t, long, long long, int>(NPY_LONG_, NPY_LONGLONG_, NPY_INT_),
NPY_UINT64_
= platform_lookup<std::uint64_t, unsigned long, unsigned long long, unsigned int>(
NPY_INT64_ = platform_lookup<8, long, long long, int>(NPY_LONG_, NPY_LONGLONG_, NPY_INT_),
NPY_UINT64_ = platform_lookup<8, unsigned long, unsigned long long, unsigned int>(
NPY_ULONG_, NPY_ULONGLONG_, NPY_UINT_),
NPY_FLOAT32_
= platform_lookup<4, double, float, long double>(NPY_DOUBLE_, NPY_FLOAT_, NPY_LONGDOUBLE_),
NPY_FLOAT64_
= platform_lookup<8, double, float, long double>(NPY_DOUBLE_, NPY_FLOAT_, NPY_LONGDOUBLE_),
NPY_COMPLEX64_
= platform_lookup<8, std::complex<double>, std::complex<float>, std::complex<long double>>(
NPY_DOUBLE_, NPY_FLOAT_, NPY_LONGDOUBLE_),
NPY_COMPLEX128_
= platform_lookup<8, std::complex<double>, std::complex<float>, std::complex<long double>>(
NPY_DOUBLE_, NPY_FLOAT_, NPY_LONGDOUBLE_),
NPY_CHAR_ = std::is_signed<char>::value ? NPY_BYTE_ : NPY_UBYTE_,
};

unsigned int PyArray_RUNTIME_VERSION_;
Expand All @@ -281,6 +292,7 @@ struct npy_api {

unsigned int (*PyArray_GetNDArrayCFeatureVersion_)();
PyObject *(*PyArray_DescrFromType_)(int);
PyObject *(*PyArray_TypeObjectFromType_)(int);
PyObject *(*PyArray_NewFromDescr_)(PyTypeObject *,
PyObject *,
int,
Expand All @@ -297,6 +309,8 @@ struct npy_api {
PyTypeObject *PyVoidArrType_Type_;
PyTypeObject *PyArrayDescr_Type_;
PyObject *(*PyArray_DescrFromScalar_)(PyObject *);
PyObject *(*PyArray_Scalar_)(void *, PyObject *, PyObject *);
void (*PyArray_ScalarAsCtype_)(PyObject *, void *);
PyObject *(*PyArray_FromAny_)(PyObject *, PyObject *, int, int, int, PyObject *);
int (*PyArray_DescrConverter_)(PyObject *, PyObject **);
bool (*PyArray_EquivTypes_)(PyObject *, PyObject *);
Expand Down Expand Up @@ -324,7 +338,10 @@ struct npy_api {
API_PyArrayDescr_Type = 3,
API_PyVoidArrType_Type = 39,
API_PyArray_DescrFromType = 45,
API_PyArray_TypeObjectFromType = 46,
API_PyArray_DescrFromScalar = 57,
API_PyArray_Scalar = 60,
API_PyArray_ScalarAsCtype = 62,
API_PyArray_FromAny = 69,
API_PyArray_Resize = 80,
// CopyInto was slot 82 and 50 was effectively an alias. NumPy 2 removed 82.
Expand Down Expand Up @@ -362,7 +379,10 @@ struct npy_api {
DECL_NPY_API(PyVoidArrType_Type);
DECL_NPY_API(PyArrayDescr_Type);
DECL_NPY_API(PyArray_DescrFromType);
DECL_NPY_API(PyArray_TypeObjectFromType);
DECL_NPY_API(PyArray_DescrFromScalar);
DECL_NPY_API(PyArray_Scalar);
DECL_NPY_API(PyArray_ScalarAsCtype);
DECL_NPY_API(PyArray_FromAny);
DECL_NPY_API(PyArray_Resize);
DECL_NPY_API(PyArray_CopyInto);
Expand All @@ -384,6 +404,88 @@ struct npy_api {
}
};

template <typename T>
struct is_complex : std::false_type {};
template <typename T>
struct is_complex<std::complex<T>> : std::true_type {};

template <typename T, typename = void>
struct npy_format_descriptor_name;

template <typename T>
struct npy_format_descriptor_name<T, enable_if_t<std::is_integral<T>::value>> {
static constexpr auto name = const_name<std::is_same<T, bool>::value>(
const_name("bool"),
const_name<std::is_signed<T>::value>("int", "uint") + const_name<sizeof(T) * 8>());
};

template <typename T>
struct npy_format_descriptor_name<T, enable_if_t<std::is_floating_point<T>::value>> {
static constexpr auto name
= const_name < std::is_same<T, float>::value
|| std::is_same<T, double>::value
> (const_name("float") + const_name<sizeof(T) * 8>(), const_name("longdouble"));
};

template <typename T>
struct npy_format_descriptor_name<T, enable_if_t<is_complex<T>::value>> {
static constexpr auto name
= const_name < std::is_same<typename T::value_type, float>::value
|| std::is_same<typename T::value_type, double>::value
> (const_name("complex") + const_name<sizeof(typename T::value_type) * 16>(),
const_name("longcomplex"));
};

template <typename T>
struct numpy_scalar_info {};

#define DECL_NPY_SCALAR(ctype_, typenum_) \
template <> \
struct numpy_scalar_info<ctype_> { \
static constexpr auto name = npy_format_descriptor_name<ctype_>::name; \
static constexpr int typenum = npy_api::typenum_##_; \
}

// boolean type
DECL_NPY_SCALAR(bool, NPY_BOOL);

// character types
DECL_NPY_SCALAR(char, NPY_CHAR);
DECL_NPY_SCALAR(signed char, NPY_BYTE);
DECL_NPY_SCALAR(unsigned char, NPY_UBYTE);

// signed integer types
DECL_NPY_SCALAR(std::int16_t, NPY_SHORT);
DECL_NPY_SCALAR(std::int32_t, NPY_INT);
DECL_NPY_SCALAR(std::int64_t, NPY_LONG);
#if defined(__linux__)
DECL_NPY_SCALAR(long long, NPY_LONG);
#else
DECL_NPY_SCALAR(long, NPY_LONG);
#endif

// unsigned integer types
DECL_NPY_SCALAR(std::uint16_t, NPY_USHORT);
DECL_NPY_SCALAR(std::uint32_t, NPY_UINT);
DECL_NPY_SCALAR(std::uint64_t, NPY_ULONG);
#if defined(__linux__)
DECL_NPY_SCALAR(unsigned long long, NPY_ULONG);
#else
DECL_NPY_SCALAR(unsigned long, NPY_ULONG);
#endif

// floating point types
DECL_NPY_SCALAR(float, NPY_FLOAT);
DECL_NPY_SCALAR(double, NPY_DOUBLE);
DECL_NPY_SCALAR(long double, NPY_LONGDOUBLE);

// complex types
DECL_NPY_SCALAR(std::complex<float>, NPY_CFLOAT);
DECL_NPY_SCALAR(std::complex<double>, NPY_CDOUBLE);
DECL_NPY_SCALAR(std::complex<long double>, NPY_CLONGDOUBLE);

#undef DECL_NPY_SCALAR

inline PyArray_Proxy *array_proxy(void *ptr) { return reinterpret_cast<PyArray_Proxy *>(ptr); }

inline const PyArray_Proxy *array_proxy(const void *ptr) {
Expand Down Expand Up @@ -414,10 +516,6 @@ template <typename T>
struct is_std_array : std::false_type {};
template <typename T, size_t N>
struct is_std_array<std::array<T, N>> : std::true_type {};
template <typename T>
struct is_complex : std::false_type {};
template <typename T>
struct is_complex<std::complex<T>> : std::true_type {};

template <typename T>
struct array_info_scalar {
Expand Down Expand Up @@ -631,8 +729,59 @@ template <typename T, ssize_t Dim>
struct type_caster<unchecked_mutable_reference<T, Dim>>
: type_caster<unchecked_reference<T, Dim>> {};

template <typename T>
struct type_caster<numpy_scalar<T>> {
using value_type = T;
using type_info = numpy_scalar_info<T>;

PYBIND11_TYPE_CASTER(numpy_scalar<T>, type_info::name);

static handle &target_type() {
static handle tp = npy_api::get().PyArray_TypeObjectFromType_(type_info::typenum);
return tp;
}

static handle &target_dtype() {
static handle tp = npy_api::get().PyArray_DescrFromType_(type_info::typenum);
return tp;
}

bool load(handle src, bool) {
if (isinstance(src, target_type())) {
npy_api::get().PyArray_ScalarAsCtype_(src.ptr(), &value.value);
return true;
}
return false;
}

static handle cast(numpy_scalar<T> src, return_value_policy, handle) {
return npy_api::get().PyArray_Scalar_(&src.value, target_dtype().ptr(), nullptr);
}
};

PYBIND11_NAMESPACE_END(detail)

template <typename T>
struct numpy_scalar {
using value_type = T;

value_type value;

numpy_scalar() = default;
numpy_scalar(value_type value) : value(value) {}

operator value_type() { return value; }
numpy_scalar &operator=(value_type value) {
this->value = value;
return *this;
}
};

template <typename T>
numpy_scalar<T> make_scalar(T value) {
return numpy_scalar<T>(value);
}

class dtype : public object {
public:
PYBIND11_OBJECT_DEFAULT(dtype, object, detail::npy_api::get().PyArrayDescr_Check_)
Expand Down Expand Up @@ -1362,38 +1511,6 @@ struct compare_buffer_info<T, detail::enable_if_t<detail::is_pod_struct<T>::valu
}
};

template <typename T, typename = void>
struct npy_format_descriptor_name;

template <typename T>
struct npy_format_descriptor_name<T, enable_if_t<std::is_integral<T>::value>> {
static constexpr auto name = const_name<std::is_same<T, bool>::value>(
const_name("bool"),
const_name<std::is_signed<T>::value>("numpy.int", "numpy.uint")
+ const_name<sizeof(T) * 8>());
};

template <typename T>
struct npy_format_descriptor_name<T, enable_if_t<std::is_floating_point<T>::value>> {
static constexpr auto name = const_name < std::is_same<T, float>::value
|| std::is_same<T, const float>::value
|| std::is_same<T, double>::value
|| std::is_same<T, const double>::value
> (const_name("numpy.float") + const_name<sizeof(T) * 8>(),
const_name("numpy.longdouble"));
};

template <typename T>
struct npy_format_descriptor_name<T, enable_if_t<is_complex<T>::value>> {
static constexpr auto name = const_name < std::is_same<typename T::value_type, float>::value
|| std::is_same<typename T::value_type, const float>::value
|| std::is_same<typename T::value_type, double>::value
|| std::is_same<typename T::value_type, const double>::value
> (const_name("numpy.complex")
+ const_name<sizeof(typename T::value_type) * 16>(),
const_name("numpy.longcomplex"));
};

template <typename T>
struct npy_format_descriptor<
T,
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ set(PYBIND11_TEST_FILES
test_multiple_inheritance
test_numpy_array
test_numpy_dtypes
test_numpy_scalars
test_numpy_vectorize
test_opaque_types
test_operator_overloading
Expand Down
Loading
Loading