parent
7a66cbd705
commit
f82a57d70e
@ -1,203 +0,0 @@
|
||||
from typing import Any
|
||||
import inspect
|
||||
from functools import partial
|
||||
import logging
|
||||
|
||||
|
||||
class NameResolver:
|
||||
"""Utility class for resolving names of various objects"""
|
||||
|
||||
@staticmethod
|
||||
def get_name(obj: Any, default: str = "unnamed_callable") -> str:
|
||||
"""
|
||||
Get the name of any object with multiple fallback strategies.
|
||||
|
||||
Args:
|
||||
obj: The object to get the name from
|
||||
default: Default name if all strategies fail
|
||||
|
||||
Returns:
|
||||
str: The resolved name
|
||||
"""
|
||||
strategies = [
|
||||
# Try getting __name__ attribute
|
||||
lambda x: getattr(x, "__name__", None),
|
||||
# Try getting class name
|
||||
lambda x: (
|
||||
x.__class__.__name__
|
||||
if hasattr(x, "__class__")
|
||||
else None
|
||||
),
|
||||
# Try getting function name if it's a partial
|
||||
lambda x: (
|
||||
x.func.__name__ if isinstance(x, partial) else None
|
||||
),
|
||||
# Try getting the name from the class's type
|
||||
lambda x: type(x).__name__,
|
||||
# Try getting qualname
|
||||
lambda x: getattr(x, "__qualname__", None),
|
||||
# Try getting the module and class name
|
||||
lambda x: (
|
||||
f"{x.__module__}.{x.__class__.__name__}"
|
||||
if hasattr(x, "__module__")
|
||||
else None
|
||||
),
|
||||
# For async functions
|
||||
lambda x: (
|
||||
x.__name__ if inspect.iscoroutinefunction(x) else None
|
||||
),
|
||||
# For classes with custom __str__
|
||||
lambda x: (
|
||||
str(x)
|
||||
if hasattr(x, "__str__")
|
||||
and x.__str__ != object.__str__
|
||||
else None
|
||||
),
|
||||
# For wrapped functions
|
||||
lambda x: (
|
||||
getattr(x, "__wrapped__", None).__name__
|
||||
if hasattr(x, "__wrapped__")
|
||||
else None
|
||||
),
|
||||
]
|
||||
|
||||
# Try each strategy
|
||||
for strategy in strategies:
|
||||
try:
|
||||
name = strategy(obj)
|
||||
if name and isinstance(name, str):
|
||||
return name.replace(" ", "_").replace("-", "_")
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
# Return default if all strategies fail
|
||||
return default
|
||||
|
||||
@staticmethod
|
||||
def get_callable_details(obj: Any) -> dict:
|
||||
"""
|
||||
Get detailed information about a callable object.
|
||||
|
||||
Returns:
|
||||
dict: Dictionary containing:
|
||||
- name: The resolved name
|
||||
- type: The type of callable
|
||||
- signature: The signature if available
|
||||
- module: The module name if available
|
||||
- doc: The docstring if available
|
||||
"""
|
||||
details = {
|
||||
"name": NameResolver.get_name(obj),
|
||||
"type": "unknown",
|
||||
"signature": None,
|
||||
"module": getattr(obj, "__module__", "unknown"),
|
||||
"doc": inspect.getdoc(obj)
|
||||
or "No documentation available",
|
||||
}
|
||||
|
||||
# Determine the type
|
||||
if inspect.isclass(obj):
|
||||
details["type"] = "class"
|
||||
elif inspect.iscoroutinefunction(obj):
|
||||
details["type"] = "async_function"
|
||||
elif inspect.isfunction(obj):
|
||||
details["type"] = "function"
|
||||
elif isinstance(obj, partial):
|
||||
details["type"] = "partial"
|
||||
elif callable(obj):
|
||||
details["type"] = "callable"
|
||||
|
||||
# Try to get signature
|
||||
try:
|
||||
details["signature"] = str(inspect.signature(obj))
|
||||
except (ValueError, TypeError):
|
||||
details["signature"] = "Unknown signature"
|
||||
|
||||
return details
|
||||
|
||||
@classmethod
|
||||
def get_safe_name(cls, obj: Any, max_retries: int = 3) -> str:
|
||||
"""
|
||||
Safely get a name with retries and validation.
|
||||
|
||||
Args:
|
||||
obj: Object to get name from
|
||||
max_retries: Maximum number of retry attempts
|
||||
|
||||
Returns:
|
||||
str: A valid name string
|
||||
"""
|
||||
retries = 0
|
||||
last_error = None
|
||||
|
||||
while retries < max_retries:
|
||||
try:
|
||||
name = cls.get_name(obj)
|
||||
|
||||
# Validate and clean the name
|
||||
if name:
|
||||
# Remove invalid characters
|
||||
clean_name = "".join(
|
||||
c
|
||||
for c in name
|
||||
if c.isalnum() or c in ["_", "."]
|
||||
)
|
||||
|
||||
# Ensure it starts with a letter or underscore
|
||||
if (
|
||||
not clean_name[0].isalpha()
|
||||
and clean_name[0] != "_"
|
||||
):
|
||||
clean_name = f"_{clean_name}"
|
||||
|
||||
return clean_name
|
||||
|
||||
except Exception as e:
|
||||
last_error = e
|
||||
retries += 1
|
||||
|
||||
# If all retries failed, generate a unique fallback name
|
||||
import uuid
|
||||
|
||||
fallback = f"callable_{uuid.uuid4().hex[:8]}"
|
||||
logging.warning(
|
||||
f"Failed to get name after {max_retries} retries. Using fallback: {fallback}. "
|
||||
f"Last error: {str(last_error)}"
|
||||
)
|
||||
return fallback
|
||||
|
||||
|
||||
# # Example usage
|
||||
# if __name__ == "__main__":
|
||||
# def test_resolver():
|
||||
# # Test cases
|
||||
# class TestClass:
|
||||
# def method(self):
|
||||
# pass
|
||||
|
||||
# async def async_func():
|
||||
# pass
|
||||
|
||||
# test_cases = [
|
||||
# TestClass, # Class
|
||||
# TestClass(), # Instance
|
||||
# async_func, # Async function
|
||||
# lambda x: x, # Lambda
|
||||
# partial(print, end=""), # Partial
|
||||
# TestClass.method, # Method
|
||||
# print, # Built-in function
|
||||
# str, # Built-in class
|
||||
# ]
|
||||
|
||||
# resolver = NameResolver()
|
||||
|
||||
# print("\nName Resolution Results:")
|
||||
# print("-" * 50)
|
||||
# for obj in test_cases:
|
||||
# details = resolver.get_callable_details(obj)
|
||||
# safe_name = resolver.get_safe_name(obj)
|
||||
# print(f"\nObject: {obj}")
|
||||
# print(f"Safe Name: {safe_name}")
|
||||
# print(f"Details: {details}")
|
||||
|
||||
# test_resolver()
|
@ -1,51 +0,0 @@
|
||||
import json
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
def remove_whitespace_from_json(json_string: str) -> str:
|
||||
"""
|
||||
Removes unnecessary whitespace from a JSON string.
|
||||
|
||||
This function parses the JSON string into a Python object and then
|
||||
serializes it back into a JSON string without unnecessary whitespace.
|
||||
|
||||
Args:
|
||||
json_string (str): The JSON string.
|
||||
|
||||
Returns:
|
||||
str: The JSON string with whitespace removed.
|
||||
"""
|
||||
parsed = json.loads(json_string)
|
||||
return json.dumps(parsed, separators=(",", ":"))
|
||||
|
||||
|
||||
# # Example usage for JSON
|
||||
# json_string = '{"field1": 123, "field2": "example text"}'
|
||||
# print(remove_whitespace_from_json(json_string))
|
||||
|
||||
|
||||
def remove_whitespace_from_yaml(yaml_string: str) -> str:
|
||||
"""
|
||||
Removes unnecessary whitespace from a YAML string.
|
||||
|
||||
This function parses the YAML string into a Python object and then
|
||||
serializes it back into a YAML string with minimized whitespace.
|
||||
Note: This might change the representation style of YAML data.
|
||||
|
||||
Args:
|
||||
yaml_string (str): The YAML string.
|
||||
|
||||
Returns:
|
||||
str: The YAML string with whitespace reduced.
|
||||
"""
|
||||
parsed = yaml.safe_load(yaml_string)
|
||||
return yaml.dump(parsed, default_flow_style=True)
|
||||
|
||||
|
||||
# # Example usage for YAML
|
||||
# yaml_string = """
|
||||
# field1: 123
|
||||
# field2: example text
|
||||
# """
|
||||
# print(remove_whitespace_from_yaml(yaml_string))
|
Loading…
Reference in new issue