619 lines
20 KiB
Python
619 lines
20 KiB
Python
"""
|
|
Type definitions for EdgarTools parameters with limited value sets.
|
|
|
|
This module provides StrEnum types for common EdgarTools parameters to enable:
|
|
- IDE autocomplete and better developer experience
|
|
- Parameter validation with helpful error messages
|
|
- Type safety while maintaining backwards compatibility
|
|
|
|
Examples:
|
|
from edgar import Company
|
|
from edgar.enums import FormType, PeriodType
|
|
|
|
# New usage with autocomplete
|
|
filings = company.get_filings(form=FormType.ANNUAL_REPORT)
|
|
facts = company.get_facts(period=PeriodType.ANNUAL)
|
|
statement = company.get_statement(StatementType.INCOME_STATEMENT)
|
|
|
|
# Existing usage still works
|
|
filings = company.get_filings(form="10-K")
|
|
facts = company.get_facts(annual=True)
|
|
statement = company.get_income_statement()
|
|
"""
|
|
|
|
try:
|
|
from enum import StrEnum
|
|
except ImportError:
|
|
# Python < 3.11 compatibility
|
|
from enum import Enum
|
|
|
|
class StrEnum(str, Enum):
|
|
"""Compatibility StrEnum for Python < 3.11"""
|
|
def __new__(cls, value):
|
|
obj = str.__new__(cls, value)
|
|
obj._value_ = value
|
|
return obj
|
|
|
|
def __str__(self):
|
|
return str(self._value_)
|
|
|
|
import difflib
|
|
from typing import Any, List, Optional, Set, Union
|
|
|
|
__all__ = ['FormType', 'PeriodType', 'StatementType', 'ValidationError', 'enhanced_validate']
|
|
|
|
|
|
class FormType(StrEnum):
|
|
"""
|
|
Enumeration of common SEC form types with IDE autocomplete support.
|
|
|
|
This enum provides type-safe access to SEC form identifiers while maintaining
|
|
backwards compatibility with string parameters through Union types.
|
|
|
|
Values are the actual SEC form identifiers used in API calls.
|
|
"""
|
|
|
|
# Most common periodic reports
|
|
ANNUAL_REPORT = "10-K"
|
|
QUARTERLY_REPORT = "10-Q"
|
|
ANNUAL_REPORT_AMENDED = "10-K/A"
|
|
QUARTERLY_REPORT_AMENDED = "10-Q/A"
|
|
|
|
# Current reports
|
|
CURRENT_REPORT = "8-K"
|
|
FOREIGN_CURRENT_REPORT = "6-K"
|
|
|
|
# Proxy statements
|
|
PROXY_STATEMENT = "DEF 14A"
|
|
PRELIMINARY_PROXY = "PRE 14A"
|
|
ADDITIONAL_PROXY = "DEFA14A"
|
|
MERGER_PROXY = "DEFM14A"
|
|
|
|
# Foreign issuers
|
|
FOREIGN_ANNUAL = "20-F"
|
|
CANADIAN_ANNUAL = "40-F"
|
|
|
|
# Registration statements (most common)
|
|
REGISTRATION_S1 = "S-1"
|
|
REGISTRATION_S3 = "S-3"
|
|
REGISTRATION_S4 = "S-4"
|
|
REGISTRATION_S8 = "S-8"
|
|
|
|
# Foreign registration
|
|
FOREIGN_REGISTRATION_F1 = "F-1"
|
|
FOREIGN_REGISTRATION_F3 = "F-3"
|
|
FOREIGN_REGISTRATION_F4 = "F-4"
|
|
|
|
# Prospectus supplements
|
|
PROSPECTUS_424B1 = "424B1"
|
|
PROSPECTUS_424B2 = "424B2"
|
|
PROSPECTUS_424B3 = "424B3"
|
|
PROSPECTUS_424B4 = "424B4"
|
|
PROSPECTUS_424B5 = "424B5"
|
|
|
|
# Ownership reports
|
|
BENEFICIAL_OWNERSHIP_13D = "SC 13D"
|
|
BENEFICIAL_OWNERSHIP_13G = "SC 13G"
|
|
|
|
# Other important filings
|
|
EMPLOYEE_BENEFIT_PLAN = "11-K"
|
|
SPECIALIZED_DISCLOSURE = "SD"
|
|
ASSET_BACKED_SECURITIES = "ARS"
|
|
|
|
# Late filing notifications
|
|
LATE_10K_NOTICE = "NT 10-K"
|
|
LATE_10Q_NOTICE = "NT 10-Q"
|
|
|
|
|
|
class PeriodType(StrEnum):
|
|
"""
|
|
Enumeration of financial reporting period types with IDE autocomplete support.
|
|
|
|
This enum provides type-safe access to period specifications while maintaining
|
|
backwards compatibility with boolean annual parameters through Union types.
|
|
|
|
Values correspond to common financial reporting periods.
|
|
"""
|
|
|
|
# Primary period types
|
|
ANNUAL = "annual" # Annual reporting periods (full fiscal year)
|
|
QUARTERLY = "quarterly" # Quarterly reporting periods (3-month periods)
|
|
MONTHLY = "monthly" # Monthly reporting periods (rarely used)
|
|
|
|
# Special period types
|
|
TTM = "ttm" # Trailing Twelve Months
|
|
YTD = "ytd" # Year to Date
|
|
|
|
# Alternative names for convenience
|
|
YEARLY = "annual" # Alias for ANNUAL
|
|
QUARTER = "quarterly" # Alias for QUARTERLY
|
|
|
|
|
|
class StatementType(StrEnum):
|
|
"""
|
|
Enumeration of financial statement types with IDE autocomplete support.
|
|
|
|
This enum provides type-safe access to statement specifications while maintaining
|
|
backwards compatibility with string parameters through Union types.
|
|
|
|
Values correspond to common financial statement categories.
|
|
"""
|
|
|
|
# Primary financial statements (The Big Four)
|
|
INCOME_STATEMENT = "income_statement" # Profit & Loss Statement
|
|
BALANCE_SHEET = "balance_sheet" # Statement of Financial Position
|
|
CASH_FLOW = "cash_flow_statement" # Statement of Cash Flows
|
|
CHANGES_IN_EQUITY = "changes_in_equity" # Statement of Changes in Equity
|
|
|
|
# Comprehensive income statement
|
|
COMPREHENSIVE_INCOME = "comprehensive_income" # Statement of Comprehensive Income
|
|
|
|
# Segment and subsidiary reporting
|
|
SEGMENTS = "segment_reporting" # Segment Information
|
|
SUBSIDIARIES = "subsidiaries" # Subsidiary Information
|
|
|
|
# Notes and disclosures
|
|
FOOTNOTES = "footnotes" # Notes to Financial Statements
|
|
ACCOUNTING_POLICIES = "accounting_policies" # Significant Accounting Policies
|
|
|
|
# Special purpose statements
|
|
REGULATORY_CAPITAL = "regulatory_capital" # Regulatory Capital (banks)
|
|
INSURANCE_RESERVES = "insurance_reserves" # Insurance Reserves (insurance cos)
|
|
|
|
# Alternative names for user convenience and compatibility
|
|
PROFIT_LOSS = "income_statement" # Alias for income statement
|
|
PL_STATEMENT = "income_statement" # Another P&L alias
|
|
FINANCIAL_POSITION = "balance_sheet" # Alias for balance sheet
|
|
STATEMENT_OF_POSITION = "balance_sheet" # Another balance sheet alias
|
|
CASH_FLOWS = "cash_flow_statement" # Alias for cash flow
|
|
EQUITY_CHANGES = "changes_in_equity" # Alias for equity statement
|
|
|
|
|
|
# Type aliases for function signatures
|
|
FormInput = Union[FormType, str, List[Union[FormType, str]]]
|
|
PeriodInput = Union[PeriodType, str]
|
|
StatementInput = Union[StatementType, str]
|
|
|
|
|
|
# FEAT-004: Enhanced Parameter Validation Framework
|
|
class ValidationError(ValueError):
|
|
"""Enhanced validation error with suggestions and context."""
|
|
|
|
def __init__(self, message: str, parameter: str, invalid_value: Any, suggestions: Optional[List[str]] = None):
|
|
self.parameter = parameter
|
|
self.invalid_value = invalid_value
|
|
self.suggestions = suggestions or []
|
|
super().__init__(message)
|
|
|
|
|
|
def fuzzy_match(value: str, valid_options: Set[str], threshold: float = 0.6) -> List[str]:
|
|
"""
|
|
Find fuzzy matches for a value against valid options using conservative similarity scoring.
|
|
|
|
Args:
|
|
value: The input value to match
|
|
valid_options: Set of valid option strings
|
|
threshold: Similarity threshold (0.0 to 1.0). Higher values = more restrictive
|
|
|
|
Returns:
|
|
List of suggested matches, ordered by similarity (max 3 results)
|
|
"""
|
|
if not isinstance(value, str) or len(value.strip()) == 0:
|
|
return []
|
|
|
|
value_lower = value.lower().strip()
|
|
|
|
# Use more conservative matching for very short inputs to avoid poor suggestions
|
|
adjusted_threshold = threshold
|
|
if len(value_lower) <= 2:
|
|
adjusted_threshold = max(threshold, 0.8) # Require high similarity for short inputs
|
|
elif len(value_lower) <= 4:
|
|
adjusted_threshold = max(threshold, 0.7) # Moderate similarity for medium inputs
|
|
|
|
# Get close matches using difflib with adjusted threshold
|
|
matches = difflib.get_close_matches(
|
|
value_lower,
|
|
[opt.lower() for opt in valid_options],
|
|
n=3, # Limit to top 3 to avoid overwhelming users
|
|
cutoff=adjusted_threshold
|
|
)
|
|
|
|
# Return original case matches, preserving order
|
|
original_matches = []
|
|
for match in matches:
|
|
for option in valid_options:
|
|
if option.lower() == match:
|
|
original_matches.append(option)
|
|
break
|
|
|
|
return original_matches
|
|
|
|
|
|
def _is_case_mismatch(value: str, option: str) -> bool:
|
|
"""Check if strings match except for case differences."""
|
|
return value == option
|
|
|
|
|
|
def _is_missing_hyphen(value: str, option: str) -> bool:
|
|
"""Check if value is missing hyphens compared to option (e.g., '10k' vs '10-K')."""
|
|
return value.replace('-', '') == option.replace('-', '')
|
|
|
|
|
|
def _is_missing_character(value: str, option: str) -> bool:
|
|
"""Check if value is missing exactly one character from option."""
|
|
return (len(value) == len(option) - 1 and
|
|
all(char in option for char in value))
|
|
|
|
|
|
def _is_extra_character(value: str, option: str) -> bool:
|
|
"""Check if value has exactly one extra character compared to option."""
|
|
return (len(value) == len(option) + 1 and
|
|
all(char in value for char in option))
|
|
|
|
|
|
def _is_single_substitution(value: str, option: str) -> bool:
|
|
"""Check if strings differ by exactly one character substitution."""
|
|
return (len(value) == len(option) and
|
|
sum(c1 != c2 for c1, c2 in zip(value, option, strict=False)) == 1)
|
|
|
|
|
|
def _is_transposed_characters(value: str, option: str) -> bool:
|
|
"""Check if strings differ by exactly one pair of transposed adjacent characters."""
|
|
if len(value) != len(option) or len(value) < 2:
|
|
return False
|
|
return any(value[:i] + value[i+1] + value[i] + value[i+2:] == option
|
|
for i in range(len(value)-1))
|
|
|
|
|
|
def detect_common_typos(value: str, valid_options: Set[str]) -> List[str]:
|
|
"""
|
|
Detect common typos and provide specific suggestions.
|
|
|
|
Args:
|
|
value: The input value that might contain typos
|
|
valid_options: Set of valid option strings
|
|
|
|
Returns:
|
|
List of likely intended values based on common typo patterns
|
|
"""
|
|
suggestions = []
|
|
value_lower = value.lower()
|
|
|
|
# Define typo detection patterns with their corresponding functions
|
|
typo_patterns = [
|
|
(_is_case_mismatch, "case mismatch"),
|
|
(_is_missing_hyphen, "missing hyphen"),
|
|
(_is_missing_character, "missing character"),
|
|
(_is_extra_character, "extra character"),
|
|
(_is_single_substitution, "character substitution"),
|
|
(_is_transposed_characters, "transposed characters")
|
|
]
|
|
|
|
for option in valid_options:
|
|
option_lower = option.lower()
|
|
|
|
# Check each typo pattern
|
|
for pattern_func, _pattern_name in typo_patterns:
|
|
if pattern_func(value_lower, option_lower):
|
|
suggestions.append(option)
|
|
break # Only match first pattern per option
|
|
|
|
return suggestions[:3] # Return top 3 suggestions
|
|
|
|
|
|
def enhanced_validate(value: Any,
|
|
valid_options: Set[str],
|
|
parameter_name: str,
|
|
enum_type: Optional[type] = None,
|
|
context_hint: Optional[str] = None) -> str:
|
|
"""
|
|
Enhanced parameter validation with intelligent error messages.
|
|
|
|
Args:
|
|
value: The parameter value to validate
|
|
valid_options: Set of valid string options
|
|
parameter_name: Name of the parameter for error messages
|
|
enum_type: Optional enum type for enhanced suggestions
|
|
context_hint: Optional context for better error messages
|
|
|
|
Returns:
|
|
Validated and normalized parameter value
|
|
|
|
Raises:
|
|
ValidationError: With intelligent suggestions for invalid values
|
|
TypeError: For completely wrong parameter types
|
|
"""
|
|
# Handle None values
|
|
if value is None:
|
|
raise ValidationError(
|
|
f"Parameter '{parameter_name}' cannot be None. "
|
|
f"Valid options: {', '.join(sorted(valid_options)[:5])}{'...' if len(valid_options) > 5 else ''}",
|
|
parameter_name,
|
|
value
|
|
)
|
|
|
|
# Handle enum types
|
|
if enum_type and hasattr(value, 'value'):
|
|
return value.value
|
|
|
|
# Handle string values
|
|
if isinstance(value, str):
|
|
if value in valid_options:
|
|
return value
|
|
|
|
# Try case-insensitive match
|
|
for option in valid_options:
|
|
if value.lower() == option.lower():
|
|
return option
|
|
|
|
# Generate suggestions
|
|
typo_suggestions = detect_common_typos(value, valid_options)
|
|
fuzzy_suggestions = fuzzy_match(value, valid_options, threshold=0.6)
|
|
|
|
# Combine and deduplicate suggestions
|
|
all_suggestions = list(dict.fromkeys(typo_suggestions + fuzzy_suggestions))
|
|
|
|
# Build error message
|
|
if all_suggestions:
|
|
suggestions_text = "', '".join(all_suggestions[:3])
|
|
error_msg = (
|
|
f"Invalid {parameter_name} '{value}'. Did you mean '{suggestions_text}'? "
|
|
f"{f'Use {enum_type.__name__} enum for autocomplete or ' if enum_type else ''}"
|
|
f"see documentation for all valid {parameter_name}s."
|
|
)
|
|
else:
|
|
# No good suggestions, show valid options
|
|
sorted_options = sorted(valid_options)
|
|
if len(sorted_options) <= 8:
|
|
options_text = "', '".join(sorted_options)
|
|
else:
|
|
options_text = "', '".join(sorted_options[:8]) + "', ..."
|
|
|
|
error_msg = (
|
|
f"Invalid {parameter_name} '{value}'. "
|
|
f"Valid {parameter_name}s: ['{options_text}']. "
|
|
f"{f'Use {enum_type.__name__} enum for autocomplete or ' if enum_type else ''}"
|
|
f"see documentation for complete list."
|
|
)
|
|
|
|
if context_hint:
|
|
error_msg += f" {context_hint}"
|
|
|
|
raise ValidationError(error_msg, parameter_name, value, all_suggestions)
|
|
|
|
# Handle wrong types
|
|
expected_types = f"{enum_type.__name__} or " if enum_type else ""
|
|
raise TypeError(
|
|
f"Parameter '{parameter_name}' must be {expected_types}str, not {type(value).__name__}. "
|
|
f"{f'Use {enum_type.__name__} enum for autocomplete.' if enum_type else ''}"
|
|
)
|
|
|
|
|
|
def validate_form_type(form: Union[FormType, str]) -> str:
|
|
"""
|
|
Validate and normalize form type parameter using enhanced validation.
|
|
|
|
Args:
|
|
form: Form type as FormType enum or string
|
|
|
|
Returns:
|
|
Normalized form string
|
|
|
|
Raises:
|
|
ValidationError: If form string is not recognized with helpful suggestions
|
|
TypeError: For wrong parameter types
|
|
"""
|
|
return enhanced_validate(
|
|
form,
|
|
_CACHED_FORM_TYPES,
|
|
"form type",
|
|
enum_type=FormType,
|
|
context_hint="Common forms: '10-K' (annual), '10-Q' (quarterly), '8-K' (current report)."
|
|
)
|
|
|
|
|
|
def validate_period_type(period: Union[PeriodType, str]) -> str:
|
|
"""
|
|
Validate and normalize period type parameter using enhanced validation.
|
|
|
|
Args:
|
|
period: Period type as PeriodType enum or string
|
|
|
|
Returns:
|
|
Normalized period string
|
|
|
|
Raises:
|
|
ValidationError: If period string is not recognized with helpful suggestions
|
|
TypeError: For wrong parameter types
|
|
"""
|
|
return enhanced_validate(
|
|
period,
|
|
_CACHED_PERIOD_TYPES,
|
|
"period type",
|
|
enum_type=PeriodType,
|
|
context_hint="Common periods: 'annual' (full year), 'quarterly' (3 months), 'ttm' (trailing 12 months)."
|
|
)
|
|
|
|
|
|
def validate_statement_type(statement: Union[StatementType, str]) -> str:
|
|
"""
|
|
Validate and normalize statement type parameter using enhanced validation.
|
|
|
|
Args:
|
|
statement: Statement type as StatementType enum or string
|
|
|
|
Returns:
|
|
Normalized statement string
|
|
|
|
Raises:
|
|
ValidationError: If statement string is not recognized with helpful suggestions
|
|
TypeError: For wrong parameter types
|
|
"""
|
|
return enhanced_validate(
|
|
statement,
|
|
_CACHED_STATEMENT_TYPES,
|
|
"statement type",
|
|
enum_type=StatementType,
|
|
context_hint="Primary statements: 'income_statement' (P&L), 'balance_sheet' (financial position), 'cash_flow_statement' (cash movements)."
|
|
)
|
|
|
|
|
|
def _get_form_display_name(form: Union[FormType, str]) -> str:
|
|
"""
|
|
Get human-readable display name for form type.
|
|
|
|
Args:
|
|
form: Form type as FormType enum or string
|
|
|
|
Returns:
|
|
Human-readable form description
|
|
"""
|
|
if isinstance(form, FormType):
|
|
# Convert enum name to readable format
|
|
# ANNUAL_REPORT -> Annual Report
|
|
return form.name.replace('_', ' ').title()
|
|
|
|
return str(form)
|
|
|
|
|
|
# Commonly used form collections for convenience
|
|
|
|
PERIODIC_FORMS = [
|
|
FormType.ANNUAL_REPORT,
|
|
FormType.QUARTERLY_REPORT,
|
|
FormType.ANNUAL_REPORT_AMENDED,
|
|
FormType.QUARTERLY_REPORT_AMENDED
|
|
]
|
|
"""
|
|
Collection of periodic reporting forms (annual and quarterly reports).
|
|
Includes both original filings and amended versions.
|
|
Most commonly used forms for ongoing company reporting.
|
|
"""
|
|
|
|
CURRENT_REPORT_FORMS = [
|
|
FormType.CURRENT_REPORT,
|
|
FormType.FOREIGN_CURRENT_REPORT
|
|
]
|
|
"""
|
|
Collection of current report forms for immediate disclosure of material events.
|
|
Includes domestic (8-K) and foreign issuer (6-K) current reports.
|
|
"""
|
|
|
|
PROXY_FORMS = [
|
|
FormType.PROXY_STATEMENT,
|
|
FormType.PRELIMINARY_PROXY,
|
|
FormType.ADDITIONAL_PROXY,
|
|
FormType.MERGER_PROXY
|
|
]
|
|
"""
|
|
Collection of proxy statement forms for shareholder voting and corporate governance.
|
|
Includes definitive, preliminary, additional, and merger-related proxy statements.
|
|
"""
|
|
|
|
REGISTRATION_FORMS = [
|
|
FormType.REGISTRATION_S1,
|
|
FormType.REGISTRATION_S3,
|
|
FormType.REGISTRATION_S4,
|
|
FormType.REGISTRATION_S8
|
|
]
|
|
"""
|
|
Collection of the most common SEC registration statement forms.
|
|
Used for registering securities offerings with the SEC.
|
|
S-1: General registration, S-3: Shelf registration, S-4: Business combinations, S-8: Employee benefit plans.
|
|
"""
|
|
|
|
# Period type collections for convenience
|
|
|
|
STANDARD_PERIODS = [
|
|
PeriodType.ANNUAL,
|
|
PeriodType.QUARTERLY
|
|
]
|
|
"""
|
|
Collection of standard financial reporting periods.
|
|
Annual reports cover full fiscal years, quarterly reports cover 3-month periods.
|
|
These are the most commonly requested periods for financial analysis.
|
|
"""
|
|
|
|
SPECIAL_PERIODS = [
|
|
PeriodType.TTM,
|
|
PeriodType.YTD
|
|
]
|
|
"""
|
|
Collection of special calculation periods for financial metrics.
|
|
TTM (Trailing Twelve Months): Rolling 12-month calculation.
|
|
YTD (Year to Date): From fiscal year start to current period.
|
|
"""
|
|
|
|
ALL_PERIODS = [
|
|
PeriodType.ANNUAL,
|
|
PeriodType.QUARTERLY,
|
|
PeriodType.MONTHLY,
|
|
PeriodType.TTM,
|
|
PeriodType.YTD
|
|
]
|
|
"""
|
|
Complete collection of all available period types.
|
|
Includes standard reporting periods (annual, quarterly, monthly) and
|
|
special calculation periods (TTM, YTD).
|
|
"""
|
|
|
|
# Statement type collections for convenience
|
|
|
|
PRIMARY_STATEMENTS = [
|
|
StatementType.INCOME_STATEMENT,
|
|
StatementType.BALANCE_SHEET,
|
|
StatementType.CASH_FLOW,
|
|
StatementType.CHANGES_IN_EQUITY
|
|
]
|
|
"""
|
|
Collection of the four primary financial statements required by GAAP.
|
|
These form the core of financial reporting and analysis:
|
|
- Income Statement: Revenue, expenses, and net income
|
|
- Balance Sheet: Assets, liabilities, and equity at a point in time
|
|
- Cash Flow Statement: Cash receipts and payments by activity
|
|
- Changes in Equity: Movements in shareholders' equity accounts
|
|
"""
|
|
|
|
COMPREHENSIVE_STATEMENTS = [
|
|
StatementType.INCOME_STATEMENT,
|
|
StatementType.BALANCE_SHEET,
|
|
StatementType.CASH_FLOW,
|
|
StatementType.CHANGES_IN_EQUITY,
|
|
StatementType.COMPREHENSIVE_INCOME
|
|
]
|
|
"""
|
|
Collection of primary financial statements plus comprehensive income.
|
|
Includes all primary statements plus the Statement of Comprehensive Income,
|
|
which reports total comprehensive income including other comprehensive income items.
|
|
"""
|
|
|
|
ANALYTICAL_STATEMENTS = [
|
|
StatementType.SEGMENTS,
|
|
StatementType.SUBSIDIARIES,
|
|
StatementType.FOOTNOTES,
|
|
StatementType.ACCOUNTING_POLICIES
|
|
]
|
|
"""
|
|
Collection of supplementary financial information for detailed analysis.
|
|
Includes segment reporting, subsidiary information, footnote disclosures,
|
|
and accounting policy descriptions that provide context to the primary statements.
|
|
"""
|
|
|
|
SPECIALIZED_STATEMENTS = [
|
|
StatementType.REGULATORY_CAPITAL,
|
|
StatementType.INSURANCE_RESERVES
|
|
]
|
|
"""
|
|
Collection of industry-specific financial statements.
|
|
Regulatory Capital: Required for banking institutions.
|
|
Insurance Reserves: Required for insurance companies.
|
|
These statements address specialized regulatory reporting requirements.
|
|
"""
|
|
|
|
ALL_STATEMENTS = PRIMARY_STATEMENTS + [StatementType.COMPREHENSIVE_INCOME] + ANALYTICAL_STATEMENTS + SPECIALIZED_STATEMENTS
|
|
|
|
# Cached validation sets to avoid recreating on every validation call
|
|
_CACHED_FORM_TYPES = set(FormType.__members__.values())
|
|
_CACHED_PERIOD_TYPES = set(PeriodType.__members__.values())
|
|
_CACHED_STATEMENT_TYPES = set(StatementType.__members__.values())
|