FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
pythonnet/src/runtime/Types/ReflectedClrType.cs at v3.2.1 · pythonnet/pythonnet · GitHub
pythonnet
pythonnet
Repository navigation
Code
Issues
147
(147)
Pull requests
11
(11)
Discussions
Actions
Projects
Wiki
Security and quality
Insights
Expand file tree
Breadcrumbs
pythonnet
/
src
/
runtime
/
Types
/
ReflectedClrType.cs
Copy path
More file actions
More file actions
Latest commit
History
History
History
139 lines (115 loc) · 4.95 KB
Breadcrumbs
pythonnet
/
src
/
runtime
/
Types
/
ReflectedClrType.cs
Copy path
File metadata and controls
139 lines (115 loc) · 4.95 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
using
System
;
using
System
.
Collections
.
Generic
;
using
System
.
Diagnostics
;
using
System
.
Runtime
.
Serialization
;
using
static
Python
.
Runtime
.
PythonException
;
namespace
Python
.
Runtime
;
[
Serializable
]
internal
sealed
class
ReflectedClrType
:
PyType
{
private
ReflectedClrType
(
StolenReference
reference
)
:
base
(
reference
,
prevalidated
:
true
)
{
}
internal
ReflectedClrType
(
ReflectedClrType
original
)
:
base
(
original
,
prevalidated
:
true
)
{
}
internal
ReflectedClrType
(
BorrowedReference
original
)
:
base
(
original
)
{
}
ReflectedClrType
(
SerializationInfo
info
,
StreamingContext
context
)
:
base
(
info
,
context
)
{
}
internal
ClassBase
Impl
=>
(
ClassBase
)
ManagedType
.
GetManagedObject
(
this
)
!
;
/// <summary>
/// Get the Python type that reflects the given CLR type.
/// </summary>
/// <remarks>
/// Returned <see cref="ReflectedClrType"/> might be partially initialized.
/// </remarks>
public
static
ReflectedClrType
GetOrCreate
(
Type
type
)
{
// Fast path: `cache` holds only fully-initialised types.
if
(
ClassManager
.
cache
.
TryGetValue
(
type
,
out
var
pyType
)
)
return
pyType
;
// Shared with ClassManager.cache + TypeManager._slotsHolders writes
// so the multi-step type build below is atomic.
lock
(
ClassManager
.
_cacheCreateLock
)
{
// Re-check now that we hold the lock; another thread may have finished.
if
(
ClassManager
.
cache
.
TryGetValue
(
type
,
out
pyType
)
)
return
pyType
;
// Reentrant call from the same thread (self-referential class) sees the
// partial type that the outer frame allocated.
if
(
ClassManager
.
_inProgressCache
.
TryGetValue
(
type
,
out
pyType
)
)
return
pyType
;
try
{
pyType
=
AllocateClass
(
type
)
;
ClassManager
.
_inProgressCache
[
type
]
=
pyType
;
var
impl
=
ClassManager
.
CreateClass
(
type
)
;
TypeManager
.
InitializeClassCore
(
type
,
pyType
,
impl
)
;
ClassManager
.
InitClassBase
(
type
,
impl
,
pyType
)
;
TypeManager
.
InitializeClass
(
pyType
,
impl
,
type
)
;
// Publish the completed type so the fast path can see it.
ClassManager
.
cache
[
type
]
=
pyType
;
}
catch
(
Exception
e
)
{
throw
new
InternalPythonnetException
(
$
"Failed to create Python type for
{
type
.
FullName
}
"
,
e
)
;
}
finally
{
ClassManager
.
_inProgressCache
.
Remove
(
type
)
;
}
return
pyType
;
}
}
internal
void
Restore
(
Dictionary
<
string
,
object
?
>
context
)
{
var
cb
=
(
ClassBase
)
context
[
"impl"
]
!
;
Debug
.
Assert
(
cb
is
not
null
)
;
cb
!
.
Load
(
this
,
context
)
;
Restore
(
cb
)
;
}
internal
void
Restore
(
ClassBase
cb
)
{
ClassManager
.
InitClassBase
(
cb
.
type
.
Value
,
cb
,
this
)
;
TypeManager
.
InitializeClass
(
this
,
cb
,
cb
.
type
.
Value
)
;
}
internal
static
NewReference
CreateSubclass
(
ClassBase
baseClass
,
IList
<
Type
>
interfaces
,
string
name
,
string
?
assembly
,
string
?
ns
,
BorrowedReference
dict
)
{
try
{
Type
subType
=
ClassDerivedObject
.
CreateDerivedType
(
name
,
baseClass
.
type
.
Value
,
interfaces
,
dict
,
ns
,
assembly
)
;
var
py_type
=
GetOrCreate
(
subType
)
;
// by default the class dict will have all the C# methods in it, but as this is a
// derived class we want the python overrides in there instead if they exist.
var
cls_dict
=
Util
.
ReadRef
(
py_type
,
TypeOffset
.
tp_dict
)
;
ThrowIfIsNotZero
(
Runtime
.
PyDict_Update
(
cls_dict
,
dict
)
)
;
// Update the __classcell__ if it exists
BorrowedReference
cell
=
Runtime
.
PyDict_GetItemString
(
cls_dict
,
"__classcell__"
)
;
if
(
!
cell
.
IsNull
)
{
ThrowIfIsNotZero
(
Runtime
.
PyCell_Set
(
cell
,
py_type
)
)
;
ThrowIfIsNotZero
(
Runtime
.
PyDict_DelItemString
(
cls_dict
,
"__classcell__"
)
)
;
}
return
new
NewReference
(
py_type
)
;
}
catch
(
Exception
e
)
{
return
Exceptions
.
RaiseTypeError
(
e
.
Message
)
;
}
}
static
ReflectedClrType
AllocateClass
(
Type
clrType
)
{
string
name
=
TypeManager
.
GetPythonTypeName
(
clrType
)
;
var
type
=
TypeManager
.
AllocateTypeObject
(
name
,
Runtime
.
PyCLRMetaType
)
;
type
.
Flags
=
TypeFlags
.
Default
|
TypeFlags
.
HasClrInstance
|
TypeFlags
.
HeapType
|
TypeFlags
.
BaseType
|
TypeFlags
.
HaveGC
;
return
new
ReflectedClrType
(
type
.
Steal
(
)
)
;
}
public
override
bool
Equals
(
PyObject
?
other
)
=>
rawPtr
==
other
?
.
DangerousGetAddressOrNull
(
)
;
public
override
int
GetHashCode
(
)
=>
rawPtr
.
GetHashCode
(
)
;
}
Back
|
FazBrowse Home
|
New Git URL