Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Intern string#1254

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
lostmsu merged 2 commits intopythonnet:masterfromamos402:intern-string
Nov 6, 2020
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
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
4 changes: 2 additions & 2 deletionssrc/embed_tests/TestDomainReload.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -203,13 +203,13 @@ def test_obj_call():
// Create a new module
IntPtr module = PyRuntime.PyModule_New(name);
Assert.That(module != IntPtr.Zero);
IntPtr globals = PyRuntime.PyObject_GetAttrString(module,"__dict__");
IntPtr globals = PyRuntime.PyObject_GetAttr(module,PyIdentifier.__dict__);
Assert.That(globals != IntPtr.Zero);
try
{
// import builtins
// module.__dict__[__builtins__] = builtins
int res = PyRuntime.PyDict_SetItemString(globals,"__builtins__",
int res = PyRuntime.PyDict_SetItem(globals,PyIdentifier.__builtins__,
PyRuntime.PyEval_GetBuiltins());
PythonException.ThrowIfIsNotZero(res);

Expand Down
16 changes: 16 additions & 0 deletionssrc/runtime/Python.Runtime.15.csproj
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -143,6 +143,22 @@
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>

<ItemGroup>
<None Update="intern_.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>intern_.cs</LastGenOutput>
</None>
</ItemGroup>


<ItemGroup>
<Compile Update="intern_.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>intern_.tt</DependentUpon>
</Compile>
</ItemGroup>

<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />

<PropertyGroup>
Expand Down
8 changes: 5 additions & 3 deletionssrc/runtime/Python.Runtime.csproj
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -82,14 +82,16 @@
<Compile Include="Codecs\TupleCodecs.cs" />
<Compile Include="converterextensions.cs" />
<Compile Include="finalizer.cs" />
<Compile Include="intern.cs" />
<Compile Include="intern_.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="..\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="arrayobject.cs" />
<Compile Include="assemblymanager.cs" />
<Compile Include="BorrowedReference.cs" />
<Compile Include="bufferinterface.cs" />
<Compile Include="bufferinterface.cs" />
<Compile Include="classderived.cs" />
<Compile Include="classbase.cs" />
<Compile Include="classmanager.cs" />
Expand DownExpand Up@@ -131,7 +133,7 @@
<Compile Include="overload.cs" />
<Compile Include="propertyobject.cs" />
<Compile Include="pyansistring.cs" />
<Compile Include="pybuffer.cs" />
<Compile Include="pybuffer.cs" />
<Compile Include="pydict.cs" />
<Compile Include="PyExportAttribute.cs" />
<Compile Include="pyfloat.cs" />
Expand DownExpand Up@@ -185,4 +187,4 @@
<Copy SourceFiles="$(TargetAssembly)" DestinationFolder="$(PythonBuildDir)" />
<!--Copy SourceFiles="$(TargetAssemblyPdb)" Condition="Exists('$(TargetAssemblyPdb)')" DestinationFolder="$(PythonBuildDir)" /-->
</Target>
</Project>
</Project>
2 changes: 1 addition & 1 deletionsrc/runtime/classbase.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -279,7 +279,7 @@ public static IntPtr tp_repr(IntPtr ob)
IntPtr args = Runtime.PyTuple_New(1);
Runtime.XIncref(ob);
Runtime.PyTuple_SetItem(args, 0, ob);
IntPtr reprFunc = Runtime.PyObject_GetAttrString(Runtime.PyBaseObjectType,"__repr__");
IntPtr reprFunc = Runtime.PyObject_GetAttr(Runtime.PyBaseObjectType,PyIdentifier.__repr__);
var output = Runtime.PyObject_Call(reprFunc, args, IntPtr.Zero);
Runtime.XDecref(args);
Runtime.XDecref(reprFunc);
Expand Down
8 changes: 4 additions & 4 deletionssrc/runtime/classmanager.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -232,7 +232,7 @@ private static void InitClassBase(Type type, ClassBase impl)
var attr = (DocStringAttribute)attrs[0];
string docStr = attr.DocString;
doc = Runtime.PyString_FromString(docStr);
Runtime.PyDict_SetItemString(dict,"__doc__", doc);
Runtime.PyDict_SetItem(dict,PyIdentifier.__doc__, doc);
Runtime.XDecref(doc);
}

Expand All@@ -249,16 +249,16 @@ private static void InitClassBase(Type type, ClassBase impl)
var ctors = new ConstructorBinding(type, tp, co.binder);
// ExtensionType types are untracked, so don't Incref() them.
// TODO: deprecate __overloads__ soon...
Runtime.PyDict_SetItemString(dict,"__overloads__", ctors.pyHandle);
Runtime.PyDict_SetItemString(dict,"Overloads", ctors.pyHandle);
Runtime.PyDict_SetItem(dict,PyIdentifier.__overloads__, ctors.pyHandle);
Runtime.PyDict_SetItem(dict,PyIdentifier.Overloads, ctors.pyHandle);
ctors.DecrRefCount();
}

// don't generate the docstring if one was already set from a DocStringAttribute.
if (!CLRModule._SuppressDocs && doc == IntPtr.Zero)
{
doc = co.GetDocString();
Runtime.PyDict_SetItemString(dict,"__doc__", doc);
Runtime.PyDict_SetItem(dict,PyIdentifier.__doc__, doc);
Runtime.XDecref(doc);
}
}
Expand Down
2 changes: 1 addition & 1 deletionsrc/runtime/exceptions.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -284,7 +284,7 @@ public static void SetError(Exception e)
}

IntPtr op = CLRObject.GetInstHandle(e);
IntPtr etype = Runtime.PyObject_GetAttrString(op,"__class__");
IntPtr etype = Runtime.PyObject_GetAttr(op,PyIdentifier.__class__);
Runtime.PyErr_SetObject(new BorrowedReference(etype), new BorrowedReference(op));
Runtime.XDecref(etype);
Runtime.XDecref(op);
Expand Down
6 changes: 3 additions & 3 deletionssrc/runtime/importhook.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,11 +43,11 @@ static void InitImport()
// look in CLR modules, then if we don't find any call the default
// Python __import__.
IntPtr builtins = Runtime.GetBuiltins();
py_import = Runtime.PyObject_GetAttrString(builtins,"__import__");
py_import = Runtime.PyObject_GetAttr(builtins,PyIdentifier.__import__);
PythonException.ThrowIfIsNull(py_import);

hook = new MethodWrapper(typeof(ImportHook), "__import__", "TernaryFunc");
int res = Runtime.PyObject_SetAttrString(builtins,"__import__", hook.ptr);
int res = Runtime.PyObject_SetAttr(builtins,PyIdentifier.__import__, hook.ptr);
PythonException.ThrowIfIsNotZero(res);

Runtime.XDecref(builtins);
Expand All@@ -60,7 +60,7 @@ static void RestoreImport()
{
IntPtr builtins = Runtime.GetBuiltins();

int res = Runtime.PyObject_SetAttrString(builtins,"__import__", py_import);
int res = Runtime.PyObject_SetAttr(builtins,PyIdentifier.__import__, py_import);
PythonException.ThrowIfIsNotZero(res);
Runtime.XDecref(py_import);
py_import = IntPtr.Zero;
Expand Down
74 changes: 74 additions & 0 deletionssrc/runtime/intern.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace Python.Runtime
{
static partial class InternString
{
private static Dictionary<string, IntPtr> _string2interns;
private static Dictionary<IntPtr, string> _intern2strings;

static InternString()
{
var identifierNames = typeof(PyIdentifier).GetFields().Select(fi => fi.Name);
var validNames = new HashSet<string>(identifierNames);
if (validNames.Count != _builtinNames.Length)
{
throw new InvalidOperationException("Identifiers args not matching");
}
foreach (var name in _builtinNames)
{
if (!validNames.Contains(name))
{
throw new InvalidOperationException($"{name} is not declared");
}
}
}

public static void Initialize()
{
_string2interns = new Dictionary<string, IntPtr>();
_intern2strings = new Dictionary<IntPtr, string>();

Type type = typeof(PyIdentifier);
foreach (string name in _builtinNames)
{
IntPtr op = Runtime.PyUnicode_InternFromString(name);
SetIntern(name, op);
type.GetField(name).SetValue(null, op);
}
}

public static void Shutdown()
{
foreach (var ptr in _intern2strings.Keys)
{
Runtime.XDecref(ptr);
}
_string2interns = null;
_intern2strings = null;
}

public static string GetManagedString(IntPtr op)
{
string s;
if (TryGetInterned(op, out s))
{
return s;
}
return Runtime.GetManagedString(op);
}

public static bool TryGetInterned(IntPtr op, out string s)
{
return _intern2strings.TryGetValue(op, out s);
}

private static void SetIntern(string s, IntPtr op)
{
_string2interns.Add(s, op);
_intern2strings.Add(op, s);
}
}
}
48 changes: 48 additions & 0 deletionssrc/runtime/intern_.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
using System;

namespace Python.Runtime
{
static class PyIdentifier
{
public static IntPtr __name__;
public static IntPtr __dict__;
public static IntPtr __doc__;
public static IntPtr __class__;
public static IntPtr __module__;
public static IntPtr __file__;
public static IntPtr __slots__;
public static IntPtr __self__;
public static IntPtr __annotations__;
public static IntPtr __init__;
public static IntPtr __repr__;
public static IntPtr __import__;
public static IntPtr __builtins__;
public static IntPtr builtins;
public static IntPtr __overloads__;
public static IntPtr Overloads;
}


static partial class InternString
{
private static readonly string[] _builtinNames = new string[]
{
"__name__",
"__dict__",
"__doc__",
"__class__",
"__module__",
"__file__",
"__slots__",
"__self__",
"__annotations__",
"__init__",
"__repr__",
"__import__",
"__builtins__",
"builtins",
"__overloads__",
"Overloads",
};
}
}
58 changes: 58 additions & 0 deletionssrc/runtime/intern_.tt
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
<#@ template debug="true" hostSpecific="true" #>
<#@ output extension=".cs" #>
<#
string[] internNames = new string[]
Comment on lines +1 to +4
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Why use a template generator, when you can simply getinternNames from reflection? It looks like unnecessary complication.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Two reasons make this scenario happened.

  1. You need to make sure the string is a c# intern string too to make code like this work without extra checking
conststrings="1";switch(    case"1":// both "1" point to the same stringbreak;
  1. If you need (1), you have to make theinternNames set on compile.
    Of course, if you don't (1), internNames can just set by using reflection from readingPyIdentities.

christabella reacted with thumbs up emoji
{
"__name__",
"__dict__",
"__doc__",
"__class__",
"__module__",
"__file__",
"__slots__",
"__self__",
"__annotations__",

"__init__",
"__repr__",
"__import__",
"__builtins__",

"builtins",

"__overloads__",
"Overloads",
};
#>
using System;

namespace Python.Runtime
{
static class PyIdentifier
{
<#
foreach (var name in internNames)
{
#>
public static IntPtr <#= name #>;
<#
}
#>
}


static partial class InternString
{
private static readonly string[] _builtinNames = new string[]
{
<#
foreach (var name in internNames)
{
#>
"<#= name #>",
<#
}
#>
};
}
}
4 changes: 2 additions & 2 deletionssrc/runtime/metatype.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -109,7 +109,7 @@ public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
}
}

IntPtr slots = Runtime.PyDict_GetItemString(dict,"__slots__");
IntPtr slots = Runtime.PyDict_GetItem(dict,PyIdentifier.__slots__);
if (slots != IntPtr.Zero)
{
return Exceptions.RaiseTypeError("subclasses of managed classes do not support __slots__");
Expand DownExpand Up@@ -197,7 +197,7 @@ public static IntPtr tp_call(IntPtr tp, IntPtr args, IntPtr kw)
return IntPtr.Zero;
}

var init = Runtime.PyObject_GetAttrString(obj,"__init__");
var init = Runtime.PyObject_GetAttr(obj,PyIdentifier.__init__);
Runtime.PyErr_Clear();

if (init != IntPtr.Zero)
Expand Down
2 changes: 1 addition & 1 deletionsrc/runtime/methodbinding.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -84,7 +84,7 @@ public static IntPtr tp_getattro(IntPtr ob, IntPtr key)
return IntPtr.Zero;
}

string name =Runtime.GetManagedString(key);
string name =InternString.GetManagedString(key);
switch (name)
{
case "__doc__":
Expand Down
3 changes: 1 addition & 2 deletionssrc/runtime/methodobject.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -133,8 +133,7 @@ public static IntPtr tp_getattro(IntPtr ob, IntPtr key)
return Exceptions.RaiseTypeError("string expected");
}

string name = Runtime.GetManagedString(key);
if (name == "__doc__")
if (Runtime.PyUnicode_Compare(key, PyIdentifier.__doc__) == 0)
{
IntPtr doc = self.GetDocString();
Runtime.XIncref(doc);
Expand Down
10 changes: 5 additions & 5 deletionssrc/runtime/moduleobject.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,10 +48,10 @@ public ModuleObject(string name)
IntPtr pyfilename = Runtime.PyString_FromString(filename);
IntPtr pydocstring = Runtime.PyString_FromString(docstring);
IntPtr pycls = TypeManager.GetTypeHandle(GetType());
Runtime.PyDict_SetItemString(dict,"__name__", pyname);
Runtime.PyDict_SetItemString(dict,"__file__", pyfilename);
Runtime.PyDict_SetItemString(dict,"__doc__", pydocstring);
Runtime.PyDict_SetItemString(dict,"__class__", pycls);
Runtime.PyDict_SetItem(dict,PyIdentifier.__name__, pyname);
Runtime.PyDict_SetItem(dict,PyIdentifier.__file__, pyfilename);
Runtime.PyDict_SetItem(dict,PyIdentifier.__doc__, pydocstring);
Runtime.PyDict_SetItem(dict,PyIdentifier.__class__, pycls);
Runtime.XDecref(pyname);
Runtime.XDecref(pyfilename);
Runtime.XDecref(pydocstring);
Expand DownExpand Up@@ -282,7 +282,7 @@ public static IntPtr tp_getattro(IntPtr ob, IntPtr key)
return op;
}

string name =Runtime.GetManagedString(key);
string name =InternString.GetManagedString(key);
if (name == "__dict__")
{
Runtime.XIncref(self.dict);
Expand Down
4 changes: 2 additions & 2 deletionssrc/runtime/pyscope.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -68,8 +68,8 @@ internal PyScope(IntPtr ptr, PyScopeManager manager)
variables = Runtime.PyModule_GetDict(obj);
PythonException.ThrowIfIsNull(variables);

int res = Runtime.PyDict_SetItemString(
variables,"__builtins__",
int res = Runtime.PyDict_SetItem(
variables,PyIdentifier.__builtins__,
Runtime.PyEval_GetBuiltins()
);
PythonException.ThrowIfIsNotZero(res);
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp