Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(199345)

Delta Between Two Patch Sets: Lib/inspect.py

Issue 20334: make inspect Signature hashable
Left Patch Set: Created 4 years, 10 months ago
Right Patch Set: Created 4 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | Lib/test/test_inspect.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 """Get useful information from live Python objects. 1 """Get useful information from live Python objects.
2 2
3 This module encapsulates the interface provided by the internal special 3 This module encapsulates the interface provided by the internal special
4 attributes (co_*, im_*, tb_*, etc.) in a friendlier fashion. 4 attributes (co_*, im_*, tb_*, etc.) in a friendlier fashion.
5 It also provides some help for examining source code and class layout. 5 It also provides some help for examining source code and class layout.
6 6
7 Here are some of the useful functions provided by this module: 7 Here are some of the useful functions provided by this module:
8 8
9 ismodule(), isclass(), ismethod(), isfunction(), isgeneratorfunction(), 9 ismodule(), isclass(), ismethod(), isfunction(), isgeneratorfunction(),
10 isgenerator(), istraceback(), isframe(), iscode(), isbuiltin(), 10 isgenerator(), istraceback(), isframe(), iscode(), isbuiltin(),
(...skipping 2221 matching lines...) Expand 10 before | Expand all | Expand 10 after
2232 elif kind == _VAR_KEYWORD: 2232 elif kind == _VAR_KEYWORD:
2233 formatted = '**' + formatted 2233 formatted = '**' + formatted
2234 2234
2235 return formatted 2235 return formatted
2236 2236
2237 def __repr__(self): 2237 def __repr__(self):
2238 return '<{} at {:#x} "{}">'.format(self.__class__.__name__, 2238 return '<{} at {:#x} "{}">'.format(self.__class__.__name__,
2239 id(self), self) 2239 id(self), self)
2240 2240
2241 def __hash__(self): 2241 def __hash__(self):
2242 hash_tuple = (self.name, int(self.kind)) 2242 return hash((self.name, self.kind, self._annotation, self._default))
2243
2244 if self._annotation is not _empty:
2245 hash_tuple += (self._annotation,)
2246 if self._default is not _empty:
2247 hash_tuple += (self._default,)
2248
2249 return hash(hash_tuple)
2250 2243
2251 def __eq__(self, other): 2244 def __eq__(self, other):
2252 return (issubclass(other.__class__, Parameter) and 2245 return (issubclass(other.__class__, Parameter) and
2253 self._name == other._name and 2246 self._name == other._name and
2254 self._kind == other._kind and 2247 self._kind == other._kind and
2255 self._default == other._default and 2248 self._default == other._default and
2256 self._annotation == other._annotation) 2249 self._annotation == other._annotation)
2257 2250
2258 def __ne__(self, other): 2251 def __ne__(self, other):
2259 return not self.__eq__(other) 2252 return not self.__eq__(other)
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
2534 2527
2535 if parameters is _void: 2528 if parameters is _void:
2536 parameters = self.parameters.values() 2529 parameters = self.parameters.values()
2537 2530
2538 if return_annotation is _void: 2531 if return_annotation is _void:
2539 return_annotation = self._return_annotation 2532 return_annotation = self._return_annotation
2540 2533
2541 return type(self)(parameters, 2534 return type(self)(parameters,
2542 return_annotation=return_annotation) 2535 return_annotation=return_annotation)
2543 2536
2537 def _hash_helper(self):
2538 return (tuple(param for param in self.parameters.values()
2539 if param.kind != _KEYWORD_ONLY),
2540 {param.name: param for param in self.parameters.values()
2541 if param.kind == _KEYWORD_ONLY},
2542 self._return_annotation)
2543
2544 def __hash__(self): 2544 def __hash__(self):
2545 params = tuple(param for param in self.parameters.values() 2545 params, kwo_params, return_annotation = self._hash_helper()
2546 if param.kind != _KEYWORD_ONLY) 2546 return hash((params, frozenset(kwo_params.items()), return_annotation))
2547
2548 kwo_params = frozenset(param for param in self.parameters.values()
2549 if param.kind == _KEYWORD_ONLY)
2550
2551 hash_tuple = (params, kwo_params)
2552
2553 if self._return_annotation is not _empty:
2554 hash_tuple += (self._return_annotation,)
2555
2556 return hash(hash_tuple)
2557 2547
2558 def __eq__(self, other): 2548 def __eq__(self, other):
2559 if (not issubclass(type(other), Signature) or 2549 return (isinstance(other, Signature) and
2560 self.return_annotation != other.return_annotation or 2550 self._hash_helper() == other._hash_helper())
2561 len(self.parameters) != len(other.parameters)):
2562 return False
2563
2564 other_positions = {param: idx
2565 for idx, param in enumerate(other.parameters.keys())}
2566
2567 for idx, (param_name, param) in enumerate(self.parameters.items()):
2568 if param.kind == _KEYWORD_ONLY:
2569 try:
2570 other_param = other.parameters[param_name]
2571 except KeyError:
2572 return False
2573 else:
2574 if param != other_param:
2575 return False
2576 else:
2577 try:
2578 other_idx = other_positions[param_name]
2579 except KeyError:
2580 return False
2581 else:
2582 if (idx != other_idx or
2583 param != other.parameters[param_name]):
2584 return False
2585
2586 return True
2587 2551
2588 def __ne__(self, other): 2552 def __ne__(self, other):
2589 return not self.__eq__(other) 2553 return not self.__eq__(other)
2590 2554
2591 def _bind(self, args, kwargs, *, partial=False): 2555 def _bind(self, args, kwargs, *, partial=False):
2592 """Private method. Don't use directly.""" 2556 """Private method. Don't use directly."""
2593 2557
2594 arguments = OrderedDict() 2558 arguments = OrderedDict()
2595 2559
2596 parameters = iter(self.parameters.values()) 2560 parameters = iter(self.parameters.values())
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
2845 else: 2809 else:
2846 print('Line: {}'.format(lineno)) 2810 print('Line: {}'.format(lineno))
2847 2811
2848 print('\n') 2812 print('\n')
2849 else: 2813 else:
2850 print(getsource(obj)) 2814 print(getsource(obj))
2851 2815
2852 2816
2853 if __name__ == "__main__": 2817 if __name__ == "__main__":
2854 _main() 2818 _main()
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+