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

Commitd9e15a7

Browse files
authored
Incorrectly using a non-generic type with type parameters now produces a helpful Python error instead of throwing NullReferenceException (#1326)
Inlined GenericUtil.GenericsByName into GenericByName.Removed unused GenericUtil.GenericsForType.Other code quality improvements.
1 parent7149d5e commitd9e15a7

File tree

5 files changed

+48
-60
lines changed

5 files changed

+48
-60
lines changed

‎AUTHORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
- Sean Freitag ([@cowboygneox](https://github.com/cowboygneox))
6161
- Serge Weinstock ([@sweinst](https://github.com/sweinst))
6262
- Simon Mourier ([@smourier](https://github.com/smourier))
63+
- Tom Minka ([@tminka](https://github.com/tminka))
6364
- Viktoria Kovescses ([@vkovec](https://github.com/vkovec))
6465
- Ville M. Vainio ([@vivainio](https://github.com/vivainio))
6566
- Virgil Dupras ([@hsoft](https://github.com/hsoft))

‎CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ details about the cause of the failure
4242
- Made it possible to use`__len__` also on`ICollection<>` interface objects
4343
- Made it possible to call`ToString`,`GetHashCode`, and`GetType` on inteface objects
4444
- Fixed objects returned by enumerating`PyObject` being disposed too soon
45+
- Incorrectly using a non-generic type with type parameters now produces a helpful Python error instead of throwing NullReferenceException
4546

4647
###Removed
4748

‎src/runtime/classbase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public virtual IntPtr type_subscript(IntPtr idx)
5454
returnc.pyHandle;
5555
}
5656

57-
returnExceptions.RaiseTypeError("notype matches params");
57+
returnExceptions.RaiseTypeError($"{type.Namespace}.{type.Name} does not accept{types.Length} generic parameters");
5858
}
5959

6060
/// <summary>

‎src/runtime/genericutil.cs

Lines changed: 40 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@ namespace Python.Runtime
99
/// This class is responsible for efficiently maintaining the bits
1010
/// of information we need to support aliases with 'nice names'.
1111
/// </summary>
12-
internalclassGenericUtil
12+
internalstaticclassGenericUtil
1313
{
14+
/// <summary>
15+
/// Maps namespace -> generic base name -> list of generic type names
16+
/// </summary>
1417
privatestaticDictionary<string,Dictionary<string,List<string>>>mapping;
1518

16-
privateGenericUtil()
17-
{
18-
}
19-
2019
publicstaticvoidReset()
2120
{
2221
mapping=newDictionary<string,Dictionary<string,List<string>>>();
@@ -25,29 +24,23 @@ public static void Reset()
2524
/// <summary>
2625
/// Register a generic type that appears in a given namespace.
2726
/// </summary>
27+
/// <param name="t">A generic type definition (<c>t.IsGenericTypeDefinition</c> must be true)</param>
2828
internalstaticvoidRegister(Typet)
2929
{
3030
if(null==t.Namespace||null==t.Name)
3131
{
3232
return;
3333
}
3434

35-
Dictionary<string,List<string>>nsmap=null;
36-
mapping.TryGetValue(t.Namespace,outnsmap);
37-
if(nsmap==null)
35+
Dictionary<string,List<string>>nsmap;
36+
if(!mapping.TryGetValue(t.Namespace,outnsmap))
3837
{
3938
nsmap=newDictionary<string,List<string>>();
4039
mapping[t.Namespace]=nsmap;
4140
}
42-
stringbasename=t.Name;
43-
inttick=basename.IndexOf("`");
44-
if(tick>-1)
45-
{
46-
basename=basename.Substring(0,tick);
47-
}
48-
List<string>gnames=null;
49-
nsmap.TryGetValue(basename,outgnames);
50-
if(gnames==null)
41+
stringbasename=GetBasename(t.Name);
42+
List<string>gnames;
43+
if(!nsmap.TryGetValue(basename,outgnames))
5144
{
5245
gnames=newList<string>();
5346
nsmap[basename]=gnames;
@@ -60,9 +53,8 @@ internal static void Register(Type t)
6053
/// </summary>
6154
publicstaticList<string>GetGenericBaseNames(stringns)
6255
{
63-
Dictionary<string,List<string>>nsmap=null;
64-
mapping.TryGetValue(ns,outnsmap);
65-
if(nsmap==null)
56+
Dictionary<string,List<string>>nsmap;
57+
if(!mapping.TryGetValue(ns,outnsmap))
6658
{
6759
returnnull;
6860
}
@@ -75,84 +67,73 @@ public static List<string> GetGenericBaseNames(string ns)
7567
}
7668

7769
/// <summary>
78-
///xxx
70+
///Finds a generic type with the given number of generic parameters and the same name and namespace as <paramref name="t"/>.
7971
/// </summary>
8072
publicstaticTypeGenericForType(Typet,intparamCount)
8173
{
8274
returnGenericByName(t.Namespace,t.Name,paramCount);
8375
}
8476

85-
publicstaticTypeGenericByName(stringns,stringname,intparamCount)
86-
{
87-
foreach(TypetinGenericsByName(ns,name))
88-
{
89-
if(t.GetGenericArguments().Length==paramCount)
90-
{
91-
returnt;
92-
}
93-
}
94-
returnnull;
95-
}
96-
97-
publicstaticList<Type>GenericsForType(Typet)
98-
{
99-
returnGenericsByName(t.Namespace,t.Name);
100-
}
101-
102-
publicstaticList<Type>GenericsByName(stringns,stringbasename)
77+
/// <summary>
78+
/// Finds a generic type in the given namespace with the given name and number of generic parameters.
79+
/// </summary>
80+
publicstaticTypeGenericByName(stringns,stringbasename,intparamCount)
10381
{
104-
Dictionary<string,List<string>>nsmap=null;
105-
mapping.TryGetValue(ns,outnsmap);
106-
if(nsmap==null)
82+
Dictionary<string,List<string>>nsmap;
83+
if(!mapping.TryGetValue(ns,outnsmap))
10784
{
10885
returnnull;
10986
}
11087

111-
inttick=basename.IndexOf("`");
112-
if(tick>-1)
113-
{
114-
basename=basename.Substring(0,tick);
115-
}
116-
117-
List<string>names=null;
118-
nsmap.TryGetValue(basename,outnames);
119-
if(names==null)
88+
List<string>names;
89+
if(!nsmap.TryGetValue(GetBasename(basename),outnames))
12090
{
12191
returnnull;
12292
}
12393

124-
varresult=newList<Type>();
12594
foreach(stringnameinnames)
12695
{
12796
stringqname=ns+"."+name;
12897
Typeo=AssemblyManager.LookupTypes(qname).FirstOrDefault();
129-
if(o!=null)
98+
if(o!=null&&o.GetGenericArguments().Length==paramCount)
13099
{
131-
result.Add(o);
100+
returno;
132101
}
133102
}
134103

135-
returnresult;
104+
returnnull;
136105
}
137106

138107
/// <summary>
139108
/// xxx
140109
/// </summary>
141110
publicstaticstringGenericNameForBaseName(stringns,stringname)
142111
{
143-
Dictionary<string,List<string>>nsmap=null;
144-
mapping.TryGetValue(ns,outnsmap);
145-
if(nsmap==null)
112+
Dictionary<string,List<string>>nsmap;
113+
if(!mapping.TryGetValue(ns,outnsmap))
146114
{
147115
returnnull;
148116
}
149-
List<string>gnames=null;
117+
List<string>gnames;
150118
nsmap.TryGetValue(name,outgnames);
151119
if(gnames?.Count>0)
152120
{
153121
returngnames[0];
154122
}
155123
returnnull;
156124
}
125+
126+
privatestaticstringGetBasename(stringname)
127+
{
128+
inttick=name.IndexOf("`");
129+
if(tick>-1)
130+
{
131+
returnname.Substring(0,tick);
132+
}
133+
else
134+
{
135+
returnname;
136+
}
137+
}
157138
}
158139
}

‎src/tests/test_generic.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,3 +745,8 @@ def test_nested_generic_class():
745745
"""Check nested generic classes."""
746746
# TODO NotImplemented
747747
pass
748+
749+
deftest_missing_generic_type():
750+
fromSystem.CollectionsimportIList
751+
withpytest.raises(TypeError):
752+
IList[bool]

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp