Compare commits
No commits in common. 'main' and 'wangjing' have entirely different histories.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,90 +0,0 @@
|
||||
classDiagram
|
||||
direction TB
|
||||
|
||||
class OpenRankDashboard {
|
||||
-currentTab: string
|
||||
-mode: string
|
||||
-charts: object
|
||||
-mockData: object
|
||||
-projectState: object
|
||||
+init()
|
||||
+setupEventListeners()
|
||||
+setupTabNavigation()
|
||||
+switchTab(tab: string)
|
||||
+switchMode(mode: string)
|
||||
+loadMockData()
|
||||
+initCharts()
|
||||
+generateMockData()
|
||||
}
|
||||
|
||||
class Overview {
|
||||
+updateStats()
|
||||
+updateRankingTable()
|
||||
+initDistributionChart()
|
||||
+initActivityChart()
|
||||
}
|
||||
|
||||
class Repositories {
|
||||
+updateRepositoryGrid()
|
||||
+filterRepositories(filter: string)
|
||||
+onViewRepoDetails(repoName: string)
|
||||
+onViewRepoContributions(repoName: string)
|
||||
+showRepoDetails(owner: string, repo: string)
|
||||
}
|
||||
|
||||
class Developers {
|
||||
+displayDeveloperAnalysis(developers: array)
|
||||
+filterDevelopers(keyword: string)
|
||||
}
|
||||
|
||||
class Network {
|
||||
+initNetworkGraph()
|
||||
}
|
||||
|
||||
class CodeReview {
|
||||
+setupCodeReviewPage()
|
||||
+loadExampleCode()
|
||||
+runCodeLinting()
|
||||
+simulatePylintAnalysis(code: string)
|
||||
+displayLintResults(score: number, issues: array)
|
||||
+resetCodeReviewResults()
|
||||
}
|
||||
|
||||
class Settings {
|
||||
+setupConfigListeners()
|
||||
+updateConfig(id: string, value: any)
|
||||
}
|
||||
|
||||
class ProjectMode {
|
||||
+buildProjectListFromGlobal()
|
||||
+renderProjectList(keyword: string)
|
||||
+renderApproxProject(fullName: string, days: number)
|
||||
+mountProjectView(snapshot: object)
|
||||
+triggerFullProjectCalculation(fullName: string)
|
||||
+autoTriggerFull(fullName: string, days: number)
|
||||
+pollTask(taskId: string, fullName: string, silent: boolean)
|
||||
}
|
||||
|
||||
OpenRankDashboard --> Overview: contains
|
||||
OpenRankDashboard --> Repositories: contains
|
||||
OpenRankDashboard --> Developers: contains
|
||||
OpenRankDashboard --> Network: contains
|
||||
OpenRankDashboard --> CodeReview: contains
|
||||
OpenRankDashboard --> Settings: contains
|
||||
OpenRankDashboard --> ProjectMode: contains
|
||||
|
||||
class DataLoader {
|
||||
+fetchProjectOverview(owner: string, repo: string)
|
||||
+fetchRepoDetails(owner: string, repo: string)
|
||||
+fetchContributors(owner: string, repo: string)
|
||||
}
|
||||
|
||||
class UIHelper {
|
||||
+showNotification(message: string, type: string)
|
||||
+updateLastUpdateTime()
|
||||
+pushURLState()
|
||||
+hydrateFromURL()
|
||||
}
|
||||
|
||||
OpenRankDashboard --> DataLoader: uses
|
||||
OpenRankDashboard --> UIHelper: uses
|
||||
Binary file not shown.
@ -1,166 +0,0 @@
|
||||
classDiagram
|
||||
direction TB
|
||||
|
||||
%% 核心算法类
|
||||
class OpenRankCalculator {
|
||||
- config: OpenRankConfig
|
||||
- graph: Graph
|
||||
- calculationStatus: CalculationStatus
|
||||
+ calculate(activityData: ActivityData[], lastMonthOpenRank: Map~string, number~): Promise~OpenRankResult[]~
|
||||
- buildGraph(activityData: ActivityData[], lastMonthOpenRank: Map~string, number~): void
|
||||
- iterativeCalculation(): Promise~void~
|
||||
- generateResults(): OpenRankResult[]
|
||||
+ getCalculationStatus(): CalculationStatus
|
||||
+ getGraphStats()
|
||||
+ cleanup(): void
|
||||
}
|
||||
|
||||
class ProjectOpenRankCalculator {
|
||||
- config: OpenRankConfig
|
||||
- graph: Graph
|
||||
- calculationStatus: CalculationStatus
|
||||
- weightingFramework: WeightingFramework
|
||||
+ calculateProjectOpenRank(issueData: IssueData[], pullRequestData: PullRequestData[], lastMonthOpenRank: Map~string, number~, repoEvents?: RepoEventActivity[]): Promise~OpenRankResult[]~
|
||||
- buildProjectGraph(issueData: IssueData[], pullRequestData: PullRequestData[], lastMonthOpenRank: Map~string, number~, repoEvents?: RepoEventActivity[]): void
|
||||
- computeCodeImpactPools(pr: any, totalLines: number, filesChanged: number, ...): object
|
||||
}
|
||||
|
||||
class SimpleGraph {
|
||||
+ nodes: Map~string, GraphNode~
|
||||
+ edges: GraphEdge[]
|
||||
- adjacencyList: Map~string, Set~string~~
|
||||
- incomingEdges: Map~string, GraphEdge[]~
|
||||
- outgoingEdges: Map~string, GraphEdge[]~
|
||||
+ addNode(node: GraphNode): void
|
||||
+ addEdge(edge: GraphEdge): void
|
||||
+ getNode(id: string): GraphNode | undefined
|
||||
+ getNeighbors(nodeId: string): GraphNode[]
|
||||
+ getIncomingEdges(nodeId: string): GraphEdge[]
|
||||
+ getOutgoingEdges(nodeId: string): GraphEdge[]
|
||||
+ clear(): void
|
||||
+ getStats()
|
||||
+ isConnected(): boolean
|
||||
+ getDegree(nodeId: string)
|
||||
+ getNodesByType(type: string): GraphNode[]
|
||||
}
|
||||
|
||||
%% 数据收集类
|
||||
class ProjectData {
|
||||
issues: IssueData[]
|
||||
pullRequests: PullRequestData[]
|
||||
}
|
||||
class GitHubDataCollector {
|
||||
- config: GitHubConfig
|
||||
- baseUrl: string
|
||||
+ collectProjectData(repo: GitHubRepo, startDate: Date, endDate: Date): Promise~ProjectData~
|
||||
- listIssues(repo: GitHubRepo, startDate: Date, endDate: Date): Promise~number[]~
|
||||
- listPulls(repo: GitHubRepo, startDate: Date, endDate: Date): Promise~number[]~
|
||||
- collectIssueData(repo: GitHubRepo, issueIds: number[], events: any[]): Promise~IssueData[]~
|
||||
- collectPullRequestData(repo: GitHubRepo, prIds: number[], events: any[]): Promise~PullRequestData[]~
|
||||
}
|
||||
|
||||
%% API服务类
|
||||
class APIServer {
|
||||
- app: Express.Application
|
||||
- calculationCache: Record~string, CalcCacheEntry~
|
||||
- projectCache: Record~string, ProjectSnapshotCacheEntry~
|
||||
- tasks: Record~string, TaskEntry~
|
||||
+ start(): void
|
||||
- cleanupCaches(): void
|
||||
- createTask(): TaskEntry
|
||||
- getTask(id: string): TaskEntry | null
|
||||
- updateTask(id: string, patch: Partial~TaskEntry~): void
|
||||
}
|
||||
|
||||
%% 数据库类
|
||||
class MySQLConnection {
|
||||
+ pool: Pool
|
||||
+ closePool(): Promise~void~
|
||||
}
|
||||
|
||||
%% 接口和类型
|
||||
class ActivityData {
|
||||
platform: PlatformType
|
||||
repoId: number
|
||||
repoName: string
|
||||
orgId?: number
|
||||
orgName?: string
|
||||
actorId: number
|
||||
actorLogin: string
|
||||
issueComment: number
|
||||
openIssue: number
|
||||
openPull: number
|
||||
reviewComment: number
|
||||
mergedPull: number
|
||||
createdAt: Date
|
||||
}
|
||||
|
||||
class IssueData {
|
||||
id: number
|
||||
number?: number
|
||||
platform: PlatformType
|
||||
repoId: number
|
||||
repoName: string
|
||||
title: string
|
||||
authorId: number
|
||||
authorLogin: string
|
||||
createdAt: Date
|
||||
closedAt?: Date
|
||||
state: 'open' | 'closed'
|
||||
activities: any[]
|
||||
reactions: any
|
||||
}
|
||||
|
||||
class PullRequestData {
|
||||
id: number
|
||||
number?: number
|
||||
platform: PlatformType
|
||||
repoId: number
|
||||
repoName: string
|
||||
title: string
|
||||
authorId: number
|
||||
authorLogin: string
|
||||
createdAt: Date
|
||||
mergedAt?: Date
|
||||
closedAt?: Date
|
||||
state: 'open' | 'closed' | 'merged'
|
||||
activities: any[]
|
||||
reactions: any
|
||||
filesChanged?: number
|
||||
additions?: number
|
||||
deletions?: number
|
||||
}
|
||||
|
||||
class GraphNode {
|
||||
id: string
|
||||
type: NodeType
|
||||
platform: PlatformType
|
||||
name: string
|
||||
openrank: number
|
||||
lastOpenrank: number
|
||||
initValue: number
|
||||
retentionFactor: number
|
||||
converged: boolean
|
||||
metadata?: Record~string, any~
|
||||
}
|
||||
|
||||
class GraphEdge {
|
||||
source: string
|
||||
target: string
|
||||
weight: number
|
||||
type: 'activity' | 'belong' | 'reverse_belong' | 'reverse_activity'
|
||||
activityDetails?: any
|
||||
}
|
||||
|
||||
%% 关系
|
||||
OpenRankCalculator --> SimpleGraph: uses
|
||||
ProjectOpenRankCalculator --> SimpleGraph: uses
|
||||
APIServer --> OpenRankCalculator: calls
|
||||
APIServer --> ProjectOpenRankCalculator: calls
|
||||
APIServer --> GitHubDataCollector: uses
|
||||
APIServer --> MySQLConnection: uses
|
||||
OpenRankCalculator --> ActivityData: processes
|
||||
ProjectOpenRankCalculator --> IssueData: processes
|
||||
ProjectOpenRankCalculator --> PullRequestData: processes
|
||||
SimpleGraph --> GraphNode: contains
|
||||
SimpleGraph --> GraphEdge: contains
|
||||
Binary file not shown.
@ -1,58 +0,0 @@
|
||||
@startuml
|
||||
|
||||
skinparam class {
|
||||
BackgroundColor<<boundary>> LightSkyBlue
|
||||
BackgroundColor<<control>> LightGreen
|
||||
BackgroundColor<<entity>> Gold
|
||||
}
|
||||
|
||||
class MainUI <<boundary>> {
|
||||
- algorithmController: AlgorithmController
|
||||
- chartController: ChartController
|
||||
+ startPage()
|
||||
+ displayDataAndChart(data: ProjectData, chart: Chart)
|
||||
+ openOpenRankSegment()
|
||||
}
|
||||
|
||||
class AlgorithmController <<control>> {
|
||||
- database: DateBase
|
||||
+ getProjectData(): ProjectData
|
||||
}
|
||||
|
||||
class ChartController <<control>> {
|
||||
+ generateChart(data: ProjectData): Chart
|
||||
}
|
||||
|
||||
class DateBase <<entity>> {
|
||||
- projectData: List<ProjectData>
|
||||
+ getProjectData(): ProjectData
|
||||
}
|
||||
|
||||
class ProjectData <<entity>> {
|
||||
- id: String
|
||||
- name: String
|
||||
- openRankData: List<Double>
|
||||
+ getId(): String
|
||||
+ getName(): String
|
||||
+ getOpenRankData(): List<Double>
|
||||
}
|
||||
|
||||
class Chart <<entity>> {
|
||||
- type: String
|
||||
- data: Object
|
||||
- title: String
|
||||
+ render(): void
|
||||
+ getType(): String
|
||||
}
|
||||
|
||||
' 关联关系
|
||||
MainUI --> AlgorithmController : "调用"
|
||||
MainUI --> ChartController : "调用"
|
||||
AlgorithmController --> DateBase : "查询"
|
||||
AlgorithmController ..> ProjectData : "返回"
|
||||
ChartController ..> Chart : "生成"
|
||||
DateBase "1" *-- "many" ProjectData : "包含"
|
||||
|
||||
|
||||
|
||||
@enduml
|
||||
@ -1,135 +0,0 @@
|
||||
@startuml
|
||||
|
||||
skinparam class {
|
||||
BackgroundColor<<boundary>> LightSkyBlue
|
||||
BackgroundColor<<control>> LightGreen
|
||||
BackgroundColor<<entity>> Gold
|
||||
}
|
||||
|
||||
class MainUI <<boundary>> {
|
||||
- checkUI: CheckUI
|
||||
+ startPage()
|
||||
+ showMainInterface()
|
||||
+ navigateToCodeAssessmentPage()
|
||||
}
|
||||
|
||||
class CheckUI <<boundary>> {
|
||||
- pylint: Pylint
|
||||
- currentAssessment: CodeAssessment
|
||||
+ showCodeAssessmentPage()
|
||||
+ uploadCodeToBeTested(code: CodeFile): boolean
|
||||
+ displayAssessmentResult(result: AssessmentResult)
|
||||
}
|
||||
|
||||
class Pylint <<control>> {
|
||||
- database: DateBase
|
||||
+ assessCodeQuality(code: CodeFile): AssessmentResult
|
||||
+ generateQualityReport(assessment: AssessmentResult): QualityReport
|
||||
}
|
||||
|
||||
class DateBase <<entity>> {
|
||||
- codeAssessments: List<CodeAssessment>
|
||||
- qualityScores: List<QualityScore>
|
||||
- assessmentHistory: List<AssessmentHistory>
|
||||
+ storeCodeScore(assessment: CodeAssessment): boolean
|
||||
+ getAssessmentHistory(codeId: String): List<AssessmentHistory>
|
||||
+ getAverageQualityScore(projectId: String): double
|
||||
}
|
||||
|
||||
class CodeFile <<entity>> {
|
||||
- codeId: String
|
||||
- fileName: String
|
||||
- filePath: String
|
||||
- language: String
|
||||
- content: String
|
||||
- size: long
|
||||
+ getCodeId(): String
|
||||
+ getFileName(): String
|
||||
+ getLanguage(): String
|
||||
+ getContent(): String
|
||||
}
|
||||
|
||||
class AssessmentResult <<entity>> {
|
||||
- assessmentId: String
|
||||
- codeId: String
|
||||
- qualityScore: double
|
||||
- issues: List<CodeIssue>
|
||||
- assessmentTime: Date
|
||||
+ getQualityScore(): double
|
||||
+ getIssues(): List<CodeIssue>
|
||||
+ generateSummary(): String
|
||||
}
|
||||
|
||||
class CodeAssessment <<entity>> {
|
||||
- assessmentId: String
|
||||
- codeFile: CodeFile
|
||||
- result: AssessmentResult
|
||||
- assessmentDate: Date
|
||||
+ getAssessmentId(): String
|
||||
+ getAssessmentDate(): Date
|
||||
+ getResult(): AssessmentResult
|
||||
}
|
||||
|
||||
class CodeIssue <<entity>> {
|
||||
- issueId: String
|
||||
- type: String
|
||||
- severity: String
|
||||
- lineNumber: int
|
||||
- description: String
|
||||
- suggestion: String
|
||||
+ getIssueId(): String
|
||||
+ getType(): String
|
||||
+ getSeverity(): String
|
||||
+ getDescription(): String
|
||||
}
|
||||
|
||||
class QualityScore <<entity>> {
|
||||
- scoreId: String
|
||||
- codeId: String
|
||||
- overallScore: double
|
||||
- maintainabilityScore: double
|
||||
- reliabilityScore: double
|
||||
- efficiencyScore: double
|
||||
+ getOverallScore(): double
|
||||
+ getMaintainabilityScore(): double
|
||||
+ calculateCompositeScore(): double
|
||||
}
|
||||
|
||||
class QualityReport <<entity>> {
|
||||
- reportId: String
|
||||
- assessmentId: String
|
||||
- summary: String
|
||||
- detailedAnalysis: String
|
||||
- recommendations: List<String>
|
||||
+ generateReport(): String
|
||||
+ exportAsPDF(): void
|
||||
}
|
||||
|
||||
class AssessmentHistory <<entity>> {
|
||||
- historyId: String
|
||||
- codeId: String
|
||||
- assessmentDate: Date
|
||||
- qualityScore: double
|
||||
- trend: String
|
||||
+ getHistoryId(): String
|
||||
+ getAssessmentDate(): Date
|
||||
+ getQualityScore(): double
|
||||
+ calculateTrend(): String
|
||||
}
|
||||
|
||||
' 关联关系
|
||||
MainUI --> CheckUI : "跳转"
|
||||
CheckUI --> Pylint : "调用测评"
|
||||
Pylint --> DateBase : "存储分数"
|
||||
Pylint ..> AssessmentResult : "生成"
|
||||
DateBase "1" *-- "many" CodeAssessment : "存储"
|
||||
DateBase "1" *-- "many" QualityScore : "包含"
|
||||
DateBase "1" *-- "many" AssessmentHistory : "记录历史"
|
||||
CodeAssessment "1" *-- "1" CodeFile : "测评"
|
||||
CodeAssessment "1" *-- "1" AssessmentResult : "包含结果"
|
||||
AssessmentResult "1" *-- "many" CodeIssue : "包含问题"
|
||||
AssessmentResult "1" *-- "1" QualityScore : "关联分数"
|
||||
Pylint ..> QualityReport : "生成报告"
|
||||
|
||||
|
||||
@enduml
|
||||
@ -1,141 +0,0 @@
|
||||
@startuml
|
||||
|
||||
skinparam class {
|
||||
BackgroundColor<<boundary>> LightSkyBlue
|
||||
BackgroundColor<<control>> LightGreen
|
||||
BackgroundColor<<entity>> Gold
|
||||
}
|
||||
|
||||
class MainUI <<boundary>> {
|
||||
- webUI: WebUI
|
||||
+ startPage()
|
||||
+ showMainInterface()
|
||||
+ navigateToNetworkGraphPage()
|
||||
}
|
||||
|
||||
class WebUI <<boundary>> {
|
||||
- algorithmController: AlgorithmController
|
||||
- chartController: ChartController
|
||||
+ showNetworkGraphPage()
|
||||
+ displayNetworkGraph(graph: NetworkGraph)
|
||||
}
|
||||
|
||||
class AlgorithmController <<control>> {
|
||||
- database: DateBase
|
||||
+ getNetworkGraphData(): NetworkData
|
||||
}
|
||||
|
||||
class ChartController <<control>> {
|
||||
+ drawNetworkGraph(data: NetworkData): NetworkGraph
|
||||
}
|
||||
|
||||
class DateBase <<entity>> {
|
||||
- developerData: List<DeveloperData>
|
||||
- projectData: List<ProjectData>
|
||||
- relationshipData: List<RelationshipData>
|
||||
+ getDeveloperData(): List<DeveloperData>
|
||||
+ getProjectData(): List<ProjectData>
|
||||
+ getRelationshipData(): List<RelationshipData>
|
||||
}
|
||||
|
||||
class NetworkData <<entity>> {
|
||||
- developers: List<DeveloperData>
|
||||
- projects: List<ProjectData>
|
||||
- relationships: List<RelationshipData>
|
||||
+ getDevelopers(): List<DeveloperData>
|
||||
+ getProjects(): List<ProjectData>
|
||||
+ getRelationships(): List<RelationshipData>
|
||||
}
|
||||
|
||||
class NetworkGraph <<entity>> {
|
||||
- graphId: String
|
||||
- graphType: String
|
||||
- nodes: List<GraphNode>
|
||||
- edges: List<GraphEdge>
|
||||
- layout: GraphLayout
|
||||
+ render(): void
|
||||
+ exportAsImage(format: String): void
|
||||
+ getGraphData(): Object
|
||||
}
|
||||
|
||||
class DeveloperData <<entity>> {
|
||||
- developerId: String
|
||||
- name: String
|
||||
- avatar: String
|
||||
- projects: List<String>
|
||||
+ getDeveloperId(): String
|
||||
+ getName(): String
|
||||
+ getProjects(): List<String>
|
||||
}
|
||||
|
||||
class ProjectData <<entity>> {
|
||||
- projectId: String
|
||||
- name: String
|
||||
- description: String
|
||||
- contributors: List<String>
|
||||
+ getProjectId(): String
|
||||
+ getName(): String
|
||||
+ getContributors(): List<String>
|
||||
}
|
||||
|
||||
class RelationshipData <<entity>> {
|
||||
- sourceId: String
|
||||
- targetId: String
|
||||
- relationshipType: String
|
||||
- strength: double
|
||||
+ getSourceId(): String
|
||||
+ getTargetId(): String
|
||||
+ getRelationshipType(): String
|
||||
+ getStrength(): double
|
||||
}
|
||||
|
||||
class GraphNode <<entity>> {
|
||||
- nodeId: String
|
||||
- nodeType: String
|
||||
- label: String
|
||||
- position: Point
|
||||
- properties: Map<String, Object>
|
||||
+ getNodeId(): String
|
||||
+ getLabel(): String
|
||||
+ getPosition(): Point
|
||||
}
|
||||
|
||||
class GraphEdge <<entity>> {
|
||||
- edgeId: String
|
||||
- sourceNodeId: String
|
||||
- targetNodeId: String
|
||||
- weight: double
|
||||
- label: String
|
||||
+ getSourceNodeId(): String
|
||||
+ getTargetNodeId(): String
|
||||
+ getWeight(): double
|
||||
}
|
||||
|
||||
class GraphLayout <<entity>> {
|
||||
- layoutType: String
|
||||
- parameters: Map<String, Object>
|
||||
- nodePositions: Map<String, Point>
|
||||
+ calculateLayout(nodes: List<GraphNode>, edges: List<GraphEdge>): void
|
||||
+ getNodePosition(nodeId: String): Point
|
||||
}
|
||||
|
||||
' 关联关系
|
||||
MainUI --> WebUI : "跳转"
|
||||
WebUI --> AlgorithmController : "调用"
|
||||
WebUI --> ChartController : "调用"
|
||||
AlgorithmController --> DateBase : "查询"
|
||||
AlgorithmController ..> NetworkData : "返回"
|
||||
ChartController ..> NetworkGraph : "生成"
|
||||
DateBase "1" *-- "many" DeveloperData : "包含"
|
||||
DateBase "1" *-- "many" ProjectData : "包含"
|
||||
DateBase "1" *-- "many" RelationshipData : "包含"
|
||||
NetworkData "1" *-- "many" DeveloperData : "包含"
|
||||
NetworkData "1" *-- "many" ProjectData : "包含"
|
||||
NetworkData "1" *-- "many" RelationshipData : "包含"
|
||||
NetworkGraph "1" *-- "many" GraphNode : "包含"
|
||||
NetworkGraph "1" *-- "many" GraphEdge : "包含"
|
||||
NetworkGraph "1" *-- "1" GraphLayout : "使用"
|
||||
|
||||
|
||||
|
||||
@enduml
|
||||
@ -1,126 +0,0 @@
|
||||
@startuml
|
||||
|
||||
skinparam class {
|
||||
BackgroundColor<<boundary>> LightSkyBlue
|
||||
BackgroundColor<<control>> LightGreen
|
||||
BackgroundColor<<entity>> Gold
|
||||
}
|
||||
|
||||
class MainUI <<boundary>> {
|
||||
- dateController: DateController
|
||||
+ startPage()
|
||||
+ showMainInterface()
|
||||
+ displayPRData(prData: List<PullRequestData>)
|
||||
+ displayIssueData(issueData: List<IssueData>)
|
||||
}
|
||||
|
||||
class DateController <<control>> {
|
||||
- githubApi: GithubApi
|
||||
- database: DateBase
|
||||
+ getProjectIssueData(): List<IssueData>
|
||||
+ getProjectPRData(): List<PullRequestData>
|
||||
+ storeIssueData(issueData: List<IssueData>): boolean
|
||||
+ storePRData(prData: List<PullRequestData>): boolean
|
||||
}
|
||||
|
||||
class GithubApi <<boundary>> {
|
||||
- apiKey: String
|
||||
- baseUrl: String
|
||||
+ requestProjectIssueData(projectId: String): List<IssueData>
|
||||
+ requestProjectPRData(projectId: String): List<PullRequestData>
|
||||
+ authenticate(apiKey: String): boolean
|
||||
}
|
||||
|
||||
class DateBase <<entity>> {
|
||||
- issueData: List<IssueData>
|
||||
- prData: List<PullRequestData>
|
||||
- projects: List<Project>
|
||||
+ storeIssueData(issueData: List<IssueData>): boolean
|
||||
+ storePRData(prData: List<PullRequestData>): boolean
|
||||
+ getIssueData(projectId: String): List<IssueData>
|
||||
+ getPRData(projectId: String): List<PullRequestData>
|
||||
}
|
||||
|
||||
class IssueData <<entity>> {
|
||||
- issueId: String
|
||||
- projectId: String
|
||||
- title: String
|
||||
- state: String
|
||||
- creator: String
|
||||
- createdAt: Date
|
||||
- closedAt: Date
|
||||
- labels: List<String>
|
||||
- commentsCount: int
|
||||
+ getIssueId(): String
|
||||
+ getProjectId(): String
|
||||
+ getState(): String
|
||||
+ calculateDuration(): long
|
||||
+ isClosed(): boolean
|
||||
}
|
||||
|
||||
class PullRequestData <<entity>> {
|
||||
- prId: String
|
||||
- projectId: String
|
||||
- title: String
|
||||
- state: String
|
||||
- author: String
|
||||
- createdAt: Date
|
||||
- mergedAt: Date
|
||||
- closedAt: Date
|
||||
- reviewComments: int
|
||||
- commits: int
|
||||
+ getPRId(): String
|
||||
+ getProjectId(): String
|
||||
+ getState(): String
|
||||
+ isMerged(): boolean
|
||||
+ calculateMergeTime(): long
|
||||
}
|
||||
|
||||
class Project <<entity>> {
|
||||
- projectId: String
|
||||
- name: String
|
||||
- repositoryUrl: String
|
||||
- description: String
|
||||
+ getProjectId(): String
|
||||
+ getName(): String
|
||||
+ getRepositoryUrl(): String
|
||||
}
|
||||
|
||||
class IssueStatistics <<entity>> {
|
||||
- projectId: String
|
||||
- totalIssues: int
|
||||
- openIssues: int
|
||||
- closedIssues: int
|
||||
- averageResolutionTime: double
|
||||
- issueTrend: Map<Date, int>
|
||||
+ calculateStatistics(issueData: List<IssueData>): void
|
||||
+ getOpenIssueCount(): int
|
||||
+ getClosedIssueCount(): int
|
||||
}
|
||||
|
||||
class PRStatistics <<entity>> {
|
||||
- projectId: String
|
||||
- totalPRs: int
|
||||
- openPRs: int
|
||||
- mergedPRs: int
|
||||
- averageMergeTime: double
|
||||
- prTrend: Map<Date, int>
|
||||
+ calculateStatistics(prData: List<PullRequestData>): void
|
||||
+ getMergedPRCount(): int
|
||||
+ getOpenPRCount(): int
|
||||
}
|
||||
|
||||
' 关联关系
|
||||
MainUI --> DateController : "调用"
|
||||
DateController --> GithubApi : "请求数据"
|
||||
DateController --> DateBase : "存储/查询"
|
||||
GithubApi ..> IssueData : "返回"
|
||||
GithubApi ..> PullRequestData : "返回"
|
||||
DateBase "1" *-- "many" IssueData : "存储"
|
||||
DateBase "1" *-- "many" PullRequestData : "存储"
|
||||
DateBase "1" *-- "many" Project : "包含"
|
||||
IssueStatistics ..> IssueData : "分析"
|
||||
PRStatistics ..> PullRequestData : "分析"
|
||||
|
||||
|
||||
@enduml
|
||||
@ -1,163 +0,0 @@
|
||||
@startuml
|
||||
|
||||
skinparam class {
|
||||
BackgroundColor<<boundary>> LightSkyBlue
|
||||
BackgroundColor<<control>> LightGreen
|
||||
BackgroundColor<<entity>> Gold
|
||||
}
|
||||
|
||||
class MainUI <<boundary>> {
|
||||
- dateController: DateController
|
||||
+ startPage()
|
||||
+ showMainInterface()
|
||||
+ displayDeveloperData(developerData: List<DeveloperData>)
|
||||
+ displayRepositoryData(repositoryData: List<RepositoryData>)
|
||||
}
|
||||
|
||||
class DateController <<control>> {
|
||||
- githubApi: GithubApi
|
||||
- database: DateBase
|
||||
+ getProjectDeveloperData(): List<DeveloperData>
|
||||
+ getRepositoryData(): List<RepositoryData>
|
||||
+ storeProjectDeveloperData(developerData: List<DeveloperData>): boolean
|
||||
+ storeRepositoryData(repositoryData: List<RepositoryData>): boolean
|
||||
}
|
||||
|
||||
class GithubApi <<boundary>> {
|
||||
- apiKey: String
|
||||
- baseUrl: String
|
||||
+ requestProjectDeveloperData(projectId: String): List<DeveloperData>
|
||||
+ requestRepositoryData(projectId: String): List<RepositoryData>
|
||||
+ authenticate(apiKey: String): boolean
|
||||
}
|
||||
|
||||
class DateBase <<entity>> {
|
||||
- developerData: List<DeveloperData>
|
||||
- repositoryData: List<RepositoryData>
|
||||
- organizations: List<Organization>
|
||||
+ storeProjectDeveloperData(developerData: List<DeveloperData>): boolean
|
||||
+ storeRepositoryData(repositoryData: List<RepositoryData>): boolean
|
||||
+ getDeveloperData(projectId: String): List<DeveloperData>
|
||||
+ getRepositoryData(organizationId: String): List<RepositoryData>
|
||||
}
|
||||
|
||||
class DeveloperData <<entity>> {
|
||||
- developerId: String
|
||||
- username: String
|
||||
- email: String
|
||||
- organization: String
|
||||
- repositories: List<String>
|
||||
- joinDate: Date
|
||||
+ getDeveloperId(): String
|
||||
+ getUsername(): String
|
||||
+ getOrganization(): String
|
||||
+ getRepositories(): List<String>
|
||||
}
|
||||
|
||||
class RepositoryData <<entity>> {
|
||||
- repositoryId: String
|
||||
- name: String
|
||||
- description: String
|
||||
- organization: String
|
||||
- createdAt: Date
|
||||
- lastUpdated: Date
|
||||
- language: String
|
||||
+ getRepositoryId(): String
|
||||
+ getName(): String
|
||||
+ getOrganization(): String
|
||||
+ getLanguage(): String
|
||||
}
|
||||
|
||||
class Organization <<entity>> {
|
||||
- organizationId: String
|
||||
- name: String
|
||||
- description: String
|
||||
- memberCount: int
|
||||
- repositoryCount: int
|
||||
+ getOrganizationId(): String
|
||||
+ getName(): String
|
||||
+ getMemberCount(): int
|
||||
+ getRepositoryCount(): int
|
||||
}
|
||||
|
||||
class DeveloperStatistics <<entity>> {
|
||||
- organizationId: String
|
||||
- totalDevelopers: int
|
||||
- activeDevelopers: int
|
||||
- newDevelopersThisMonth: int
|
||||
- developerGrowthRate: double
|
||||
- topLanguages: Map<String, int>
|
||||
+ calculateStatistics(developerData: List<DeveloperData>): void
|
||||
+ getTotalDevelopers(): int
|
||||
+ getDeveloperGrowthRate(): double
|
||||
}
|
||||
|
||||
class RepositoryStatistics <<entity>> {
|
||||
- organizationId: String
|
||||
- totalRepositories: int
|
||||
- publicRepositories: int
|
||||
- privateRepositories: int
|
||||
- newRepositoriesThisMonth: int
|
||||
- repositoryGrowthRate: double
|
||||
- topLanguages: Map<String, int>
|
||||
+ calculateStatistics(repositoryData: List<RepositoryData>): void
|
||||
+ getTotalRepositories(): int
|
||||
+ getRepositoryGrowthRate(): double
|
||||
}
|
||||
|
||||
class LanguageStatistics <<entity>> {
|
||||
- language: String
|
||||
- developerCount: int
|
||||
- repositoryCount: int
|
||||
- popularityScore: double
|
||||
+ getLanguage(): String
|
||||
+ getDeveloperCount(): int
|
||||
+ getRepositoryCount(): int
|
||||
+ calculatePopularityScore(): double
|
||||
}
|
||||
|
||||
' 关联关系
|
||||
MainUI --> DateController : "调用"
|
||||
DateController --> GithubApi : "请求数据"
|
||||
DateController --> DateBase : "存储/查询"
|
||||
GithubApi ..> DeveloperData : "返回"
|
||||
GithubApi ..> RepositoryData : "返回"
|
||||
DateBase "1" *-- "many" DeveloperData : "存储"
|
||||
DateBase "1" *-- "many" RepositoryData : "存储"
|
||||
DateBase "1" *-- "many" Organization : "包含"
|
||||
DeveloperStatistics ..> DeveloperData : "分析"
|
||||
RepositoryStatistics ..> RepositoryData : "分析"
|
||||
LanguageStatistics ..> DeveloperData : "关联"
|
||||
LanguageStatistics ..> RepositoryData : "关联"
|
||||
|
||||
note right of DateController::getProjectDeveloperData
|
||||
获取项目开发者数据
|
||||
包括从API获取和存储
|
||||
end note
|
||||
|
||||
note right of DateController::getRepositoryData
|
||||
获取仓库数据
|
||||
包括从API获取和存储
|
||||
end note
|
||||
|
||||
note right of GithubApi::requestProjectDeveloperData
|
||||
调用GitHub API
|
||||
获取项目开发者数据
|
||||
end note
|
||||
|
||||
note right of GithubApi::requestRepositoryData
|
||||
调用GitHub API
|
||||
获取仓库数据
|
||||
end note
|
||||
|
||||
note right of DeveloperStatistics::calculateStatistics
|
||||
计算开发者统计信息
|
||||
包括数量和增长率
|
||||
end note
|
||||
|
||||
note right of RepositoryStatistics::calculateStatistics
|
||||
计算仓库统计信息
|
||||
包括数量和增长率
|
||||
end note
|
||||
|
||||
@enduml
|
||||
@ -1,143 +0,0 @@
|
||||
@startuml
|
||||
|
||||
skinparam class {
|
||||
BackgroundColor<<boundary>> LightSkyBlue
|
||||
BackgroundColor<<control>> LightGreen
|
||||
BackgroundColor<<entity>> Gold
|
||||
}
|
||||
|
||||
class MainUI <<boundary>> {
|
||||
- dateController: DateController
|
||||
+ startPage()
|
||||
+ showMainInterface()
|
||||
+ displayCommitData(commitData: List<CommitData>)
|
||||
+ displayRepositoryStarData(starData: List<RepositoryStarData>)
|
||||
}
|
||||
|
||||
class DateController <<control>> {
|
||||
- githubApi: GithubApi
|
||||
- database: DateBase
|
||||
+ getRepositoryStarData(): List<RepositoryStarData>
|
||||
+ getCommitData(): List<CommitData>
|
||||
+ storeRepositoryStarData(starData: List<RepositoryStarData>): boolean
|
||||
+ storeCommitData(commitData: List<CommitData>): boolean
|
||||
}
|
||||
|
||||
class GithubApi <<boundary>> {
|
||||
- apiKey: String
|
||||
- baseUrl: String
|
||||
+ requestRepositoryStarData(projectId: String): List<RepositoryStarData>
|
||||
+ requestCommitData(projectId: String): List<CommitData>
|
||||
+ authenticate(apiKey: String): boolean
|
||||
}
|
||||
|
||||
class DateBase <<entity>> {
|
||||
- repositoryStarData: List<RepositoryStarData>
|
||||
- commitData: List<CommitData>
|
||||
- projects: List<Project>
|
||||
+ storeRepositoryStarData(starData: List<RepositoryStarData>): boolean
|
||||
+ storeCommitData(commitData: List<CommitData>): boolean
|
||||
+ getRepositoryStarData(projectId: String): List<RepositoryStarData>
|
||||
+ getCommitData(projectId: String): List<CommitData>
|
||||
}
|
||||
|
||||
class RepositoryStarData <<entity>> {
|
||||
- repositoryId: String
|
||||
- starCount: int
|
||||
- stargazers: List<Stargazer>
|
||||
- starHistory: Map<Date, int>
|
||||
- date: Date
|
||||
+ getRepositoryId(): String
|
||||
+ getStarCount(): int
|
||||
+ getStargazers(): List<Stargazer>
|
||||
+ calculateStarGrowth(startDate: Date, endDate: Date): int
|
||||
}
|
||||
|
||||
class CommitData <<entity>> {
|
||||
- commitId: String
|
||||
- repositoryId: String
|
||||
- author: String
|
||||
- date: Date
|
||||
- message: String
|
||||
- filesChanged: int
|
||||
- linesAdded: int
|
||||
- linesDeleted: int
|
||||
+ getCommitId(): String
|
||||
+ getRepositoryId(): String
|
||||
+ getAuthor(): String
|
||||
+ getDate(): Date
|
||||
+ getChangeSummary(): String
|
||||
}
|
||||
|
||||
class Project <<entity>> {
|
||||
- projectId: String
|
||||
- name: String
|
||||
- repositoryUrl: String
|
||||
- description: String
|
||||
+ getProjectId(): String
|
||||
+ getName(): String
|
||||
+ getRepositoryUrl(): String
|
||||
}
|
||||
|
||||
class Stargazer <<entity>> {
|
||||
- userId: String
|
||||
- username: String
|
||||
- starredAt: Date
|
||||
+ getUserId(): String
|
||||
+ getUsername(): String
|
||||
+ getStarredAt(): Date
|
||||
}
|
||||
|
||||
class StarStatistics <<entity>> {
|
||||
- repositoryId: String
|
||||
- totalStars: int
|
||||
- starsThisMonth: int
|
||||
- starsThisYear: int
|
||||
- starGrowthRate: double
|
||||
- topStargazers: List<Stargazer>
|
||||
+ calculateStatistics(starData: List<RepositoryStarData>): void
|
||||
+ getStarGrowthRate(): double
|
||||
+ getTopStargazers(count: int): List<Stargazer>
|
||||
}
|
||||
|
||||
class CommitStatistics <<entity>> {
|
||||
- repositoryId: String
|
||||
- totalCommits: int
|
||||
- commitsThisMonth: int
|
||||
- commitsThisYear: int
|
||||
- topContributors: List<Contributor>
|
||||
- commitFrequency: Map<Date, int>
|
||||
+ calculateStatistics(commitData: List<CommitData>): void
|
||||
+ getTotalCommits(): int
|
||||
+ getTopContributors(count: int): List<Contributor>
|
||||
}
|
||||
|
||||
class Contributor <<entity>> {
|
||||
- contributorId: String
|
||||
- username: String
|
||||
- commitCount: int
|
||||
- firstCommit: Date
|
||||
- lastCommit: Date
|
||||
+ getContributorId(): String
|
||||
+ getUsername(): String
|
||||
+ getCommitCount(): int
|
||||
+ getActivityPeriod(): TimeSpan
|
||||
}
|
||||
|
||||
' 关联关系
|
||||
MainUI --> DateController : "调用"
|
||||
DateController --> GithubApi : "请求数据"
|
||||
DateController --> DateBase : "存储/查询"
|
||||
GithubApi ..> RepositoryStarData : "返回"
|
||||
GithubApi ..> CommitData : "返回"
|
||||
DateBase "1" *-- "many" RepositoryStarData : "存储"
|
||||
DateBase "1" *-- "many" CommitData : "存储"
|
||||
DateBase "1" *-- "many" Project : "包含"
|
||||
RepositoryStarData "1" *-- "many" Stargazer : "包含"
|
||||
StarStatistics ..> RepositoryStarData : "分析"
|
||||
CommitStatistics ..> CommitData : "分析"
|
||||
CommitStatistics "1" *-- "many" Contributor : "统计"
|
||||
|
||||
|
||||
|
||||
@enduml
|
||||
@ -1,102 +0,0 @@
|
||||
@startuml
|
||||
|
||||
skinparam class {
|
||||
BackgroundColor<<boundary>> LightSkyBlue
|
||||
BackgroundColor<<control>> LightGreen
|
||||
BackgroundColor<<entity>> Gold
|
||||
}
|
||||
|
||||
class MainUI <<boundary>> {
|
||||
- codehubUI: CodehubUI
|
||||
+ startPage()
|
||||
+ showMainInterface()
|
||||
+ navigateToRepositoryAnalysis()
|
||||
}
|
||||
|
||||
class CodehubUI <<boundary>> {
|
||||
- algorithmController: AlgorithmController
|
||||
+ showRepositoryAnalysisPage()
|
||||
+ displayRepositoryAnalysisResult(result: RepositoryAnalysisResult)
|
||||
}
|
||||
|
||||
class AlgorithmController <<control>> {
|
||||
- database: DateBase
|
||||
- pylint: Pylint
|
||||
+ getRepositoryCodeData(): RepositoryAnalysisResult
|
||||
}
|
||||
|
||||
class Pylint <<control>> {
|
||||
+ analyzeRepository(codeData: RepositoryCodeData): RepositoryAnalysisResult
|
||||
}
|
||||
|
||||
class DateBase <<entity>> {
|
||||
- repositoryData: List<RepositoryCodeData>
|
||||
+ getRepositoryCodeData(): RepositoryCodeData
|
||||
}
|
||||
|
||||
class RepositoryCodeData <<entity>> {
|
||||
- repositoryId: String
|
||||
- repositoryName: String
|
||||
- codeFiles: List<CodeFile>
|
||||
- commitHistory: List<Commit>
|
||||
- contributors: List<Contributor>
|
||||
+ getRepositoryId(): String
|
||||
+ getRepositoryName(): String
|
||||
+ getCodeFiles(): List<CodeFile>
|
||||
+ getCommitHistory(): List<Commit>
|
||||
}
|
||||
|
||||
class RepositoryAnalysisResult <<entity>> {
|
||||
- repositoryId: String
|
||||
- repositoryName: String
|
||||
- qualityScore: double
|
||||
- activityScore: double
|
||||
- communityScore: double
|
||||
- overallScore: double
|
||||
- analysisMetrics: Map<String, Object>
|
||||
+ getOverallScore(): double
|
||||
+ getDetailedScores(): Map<String, double>
|
||||
+ generateReport(): String
|
||||
}
|
||||
|
||||
class CodeFile <<entity>> {
|
||||
- fileName: String
|
||||
- filePath: String
|
||||
- language: String
|
||||
- size: long
|
||||
- complexity: int
|
||||
+ getComplexity(): int
|
||||
+ getLanguage(): String
|
||||
}
|
||||
|
||||
class Commit <<entity>> {
|
||||
- commitId: String
|
||||
- author: String
|
||||
- date: Date
|
||||
- message: String
|
||||
- changes: int
|
||||
+ getAuthor(): String
|
||||
+ getChanges(): int
|
||||
}
|
||||
|
||||
class Contributor <<entity>> {
|
||||
- contributorId: String
|
||||
- name: String
|
||||
- commitCount: int
|
||||
+ getCommitCount(): int
|
||||
}
|
||||
|
||||
' 关联关系
|
||||
MainUI --> CodehubUI : "跳转"
|
||||
CodehubUI --> AlgorithmController : "调用"
|
||||
AlgorithmController --> DateBase : "查询"
|
||||
AlgorithmController --> Pylint : "委托分析"
|
||||
Pylint ..> RepositoryAnalysisResult : "生成"
|
||||
DateBase "1" *-- "many" RepositoryCodeData : "包含"
|
||||
RepositoryCodeData "1" *-- "many" CodeFile : "包含"
|
||||
RepositoryCodeData "1" *-- "many" Commit : "包含"
|
||||
RepositoryCodeData "1" *-- "many" Contributor : "包含"
|
||||
|
||||
|
||||
|
||||
@enduml
|
||||
@ -1,76 +0,0 @@
|
||||
@startuml
|
||||
|
||||
skinparam class {
|
||||
BackgroundColor<<boundary>> LightSkyBlue
|
||||
BackgroundColor<<control>> LightGreen
|
||||
BackgroundColor<<entity>> Gold
|
||||
}
|
||||
|
||||
class MainUI <<boundary>> {
|
||||
- developerUI: DeveloperUI
|
||||
+ startPage()
|
||||
+ showMainInterface()
|
||||
+ navigateToDeveloperAnalysis()
|
||||
}
|
||||
|
||||
class DeveloperUI <<boundary>> {
|
||||
- algorithmController: AlgorithmController
|
||||
+ showDeveloperAnalysisPage()
|
||||
+ displayDeveloperAnalysisResult(result: DeveloperAnalysisResult)
|
||||
}
|
||||
|
||||
class AlgorithmController <<control>> {
|
||||
- database: DateBase
|
||||
+ getDeveloperContributionData(): DeveloperAnalysisResult
|
||||
}
|
||||
|
||||
class DateBase <<entity>> {
|
||||
- developerData: List<DeveloperData>
|
||||
+ getDeveloperData(): DeveloperData
|
||||
}
|
||||
|
||||
class DeveloperData <<entity>> {
|
||||
- developerId: String
|
||||
- developerName: String
|
||||
- contributions: List<Contribution>
|
||||
- commitCount: int
|
||||
- codeLines: int
|
||||
+ getDeveloperId(): String
|
||||
+ getDeveloperName(): String
|
||||
+ getContributions(): List<Contribution>
|
||||
+ calculateContributionScore(): double
|
||||
}
|
||||
|
||||
class DeveloperAnalysisResult <<entity>> {
|
||||
- developerId: String
|
||||
- developerName: String
|
||||
- contributionScore: double
|
||||
- analysisDetails: Map<String, Object>
|
||||
- ranking: int
|
||||
+ getContributionScore(): double
|
||||
+ getAnalysisDetails(): Map<String, Object>
|
||||
+ getRanking(): int
|
||||
+ generateReport(): String
|
||||
}
|
||||
|
||||
class Contribution <<entity>> {
|
||||
- type: String
|
||||
- value: double
|
||||
- date: Date
|
||||
+ getType(): String
|
||||
+ getValue(): double
|
||||
+ getDate(): Date
|
||||
}
|
||||
|
||||
' 关联关系
|
||||
MainUI --> DeveloperUI : "跳转"
|
||||
DeveloperUI --> AlgorithmController : "调用"
|
||||
AlgorithmController --> DateBase : "查询"
|
||||
AlgorithmController ..> DeveloperAnalysisResult : "生成"
|
||||
DateBase "1" *-- "many" DeveloperData : "包含"
|
||||
DeveloperData "1" *-- "many" Contribution : "包含"
|
||||
DeveloperAnalysisResult ..> DeveloperData : "基于"
|
||||
|
||||
|
||||
|
||||
@enduml
|
||||
@ -1,94 +0,0 @@
|
||||
@startuml
|
||||
|
||||
skinparam class {
|
||||
BackgroundColor<<boundary>> LightSkyBlue
|
||||
BackgroundColor<<control>> LightGreen
|
||||
BackgroundColor<<entity>> Gold
|
||||
}
|
||||
|
||||
class MainUI <<boundary>> {
|
||||
- configUI: ConfigUI
|
||||
+ startPage()
|
||||
+ showMainInterface()
|
||||
+ navigateToSystemConfigPage()
|
||||
}
|
||||
|
||||
class ConfigUI <<boundary>> {
|
||||
- algorithmController: AlgorithmController
|
||||
- currentConfig: SystemConfig
|
||||
+ showSystemConfigPage()
|
||||
+ displayModificationSuccess(message: String)
|
||||
+ modifyAlgorithmParameters(params: Map<String, Object>)
|
||||
}
|
||||
|
||||
class AlgorithmController <<control>> {
|
||||
- database: DateBase
|
||||
+ modifyAlgorithmParameters(params: Map<String, Object>): boolean
|
||||
+ getCurrentConfig(): SystemConfig
|
||||
}
|
||||
|
||||
class DateBase <<entity>> {
|
||||
- systemConfig: SystemConfig
|
||||
- configHistory: List<ConfigHistory>
|
||||
+ getSystemConfig(): SystemConfig
|
||||
+ updateSystemConfig(config: SystemConfig): boolean
|
||||
+ saveConfigHistory(history: ConfigHistory): boolean
|
||||
}
|
||||
|
||||
class SystemConfig <<entity>> {
|
||||
- configId: String
|
||||
- version: String
|
||||
- parameters: Map<String, Object>
|
||||
- lastModified: Date
|
||||
- modifiedBy: String
|
||||
+ getParameter(key: String): Object
|
||||
+ setParameter(key: String, value: Object): void
|
||||
+ getAllParameters(): Map<String, Object>
|
||||
+ validateParameters(): boolean
|
||||
}
|
||||
|
||||
class ConfigHistory <<entity>> {
|
||||
- historyId: String
|
||||
- configId: String
|
||||
- oldValues: Map<String, Object>
|
||||
- newValues: Map<String, Object>
|
||||
- modifiedBy: String
|
||||
- modificationTime: Date
|
||||
+ getChangeDescription(): String
|
||||
+ rollback(): SystemConfig
|
||||
}
|
||||
|
||||
class AlgorithmParameter <<entity>> {
|
||||
- parameterName: String
|
||||
- parameterType: String
|
||||
- defaultValue: Object
|
||||
- minValue: Object
|
||||
- maxValue: Object
|
||||
- description: String
|
||||
+ validateValue(value: Object): boolean
|
||||
+ getDescription(): String
|
||||
}
|
||||
|
||||
class User <<entity>> {
|
||||
- userId: String
|
||||
- username: String
|
||||
- role: String
|
||||
- permissions: List<String>
|
||||
+ getUserId(): String
|
||||
+ getUsername(): String
|
||||
+ hasPermission(permission: String): boolean
|
||||
}
|
||||
|
||||
' 关联关系
|
||||
MainUI --> ConfigUI : "跳转"
|
||||
ConfigUI --> AlgorithmController : "调用"
|
||||
AlgorithmController --> DateBase : "更新"
|
||||
DateBase "1" *-- "1" SystemConfig : "当前配置"
|
||||
DateBase "1" *-- "many" ConfigHistory : "配置历史"
|
||||
SystemConfig "1" *-- "many" AlgorithmParameter : "包含参数"
|
||||
ConfigHistory ..> SystemConfig : "关联"
|
||||
ConfigHistory ..> User : "记录操作者"
|
||||
|
||||
|
||||
|
||||
@enduml
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 48 KiB |
@ -1,22 +0,0 @@
|
||||
[paths]
|
||||
source =
|
||||
pylint
|
||||
|
||||
[report]
|
||||
include =
|
||||
pylint/*
|
||||
omit =
|
||||
*/test/*
|
||||
exclude_also =
|
||||
# Debug-only code
|
||||
def __repr__
|
||||
|
||||
# Type checking code not executed during pytest runs
|
||||
if TYPE_CHECKING:
|
||||
@overload
|
||||
|
||||
# Abstract methods are not executed during pytest runs
|
||||
raise NotImplementedError()
|
||||
|
||||
# Fallback cases which should never be executed
|
||||
raise AssertionError
|
||||
@ -1 +0,0 @@
|
||||
3f2842400795ae1aaffc4ae6c35c4ef26857c239
|
||||
@ -1,7 +0,0 @@
|
||||
* text=auto
|
||||
tests/**/functional/** -text
|
||||
tests/input/** -text
|
||||
tests/**/data/** -text
|
||||
tests/regrtest_data/** -text
|
||||
doc/data/messages/u/unexpected-line-ending-format/bad.py -text
|
||||
doc/data/messages/m/mixed-line-endings/bad.py -text
|
||||
@ -1,35 +0,0 @@
|
||||
# Lines starting with '#' are comments.
|
||||
# Each line is a file pattern followed by one or more owners.
|
||||
|
||||
# These owners will be the default owners for everything in the repo.
|
||||
# Right now there is not default owner to avoid spam
|
||||
# * @pierre-sassoulas @DanielNoord @cdce8p @jacobtylerwalls @hippo91
|
||||
|
||||
# Order is important. The last matching pattern has the most precedence.
|
||||
|
||||
### Core components
|
||||
|
||||
# internal message handling
|
||||
pylint/message/* @pierre-sassoulas
|
||||
tests/message/* @pierre-sassoulas
|
||||
|
||||
# typing
|
||||
pylint/typing.py @DanielNoord
|
||||
|
||||
# multiprocessing (doublethefish is not yet a contributor with write access)
|
||||
# pylint/lint/parallel.py @doublethefish
|
||||
# tests/test_check_parallel.py @doublethefish
|
||||
|
||||
### Pyreverse
|
||||
pylint/pyreverse/* @DudeNr33
|
||||
tests/pyreverse/* @DudeNr33
|
||||
|
||||
### Extensions
|
||||
|
||||
# CodeStyle
|
||||
pylint/extensions/code_style.* @cdce8p
|
||||
tests/functional/ext/code_style/* @cdce8p
|
||||
|
||||
# Typing
|
||||
pylint/extensions/typing.* @cdce8p
|
||||
tests/functional/ext/typing/* @cdce8p
|
||||
@ -1,2 +0,0 @@
|
||||
Please read the
|
||||
[contribute doc](https://pylint.readthedocs.io/en/latest/development_guide/contributor_guide/contribute.html).
|
||||
@ -1,3 +0,0 @@
|
||||
# These are supported funding model platforms
|
||||
tidelift: "pypi/pylint"
|
||||
github: [cdce8p, DanielNoord, jacobtylerwalls,Pierre-Sassoulas]
|
||||
@ -1,108 +0,0 @@
|
||||
name: 🐛 Bug report
|
||||
description: Report a bug in pylint
|
||||
labels: ["Needs triage :inbox_tray:"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Thank you for wanting to report a bug in pylint!**
|
||||
|
||||
⚠ Please make sure that this [issue wasn't already requested][issue search], or already implemented in the main branch.
|
||||
|
||||
|
||||
[issue search]: https://github.com/pylint-dev/pylint/issues?q=is%3Aissue+is%3Aopen+
|
||||
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: Bug description
|
||||
description:
|
||||
What is the bug about? Please provide the code that is causing the issue, and
|
||||
configurations used if required
|
||||
placeholder: |
|
||||
# Please disable message unrelated to the bug
|
||||
# pylint: disable=missing-docstring,
|
||||
<a> = b + 1
|
||||
render: python
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: configuration
|
||||
attributes:
|
||||
label: Configuration
|
||||
description:
|
||||
Please provide the part of the configuration that is causing the bug if required
|
||||
(Leave this part blank if the configuration is not relevant)
|
||||
placeholder: |
|
||||
# Leave this blank if the configuration is not relevant!
|
||||
|
||||
[MAIN]
|
||||
load-plugins=
|
||||
pylint.extensions.code_style
|
||||
|
||||
[MESSAGE CONTROL]
|
||||
enable=
|
||||
useless-suppression
|
||||
|
||||
# ...
|
||||
render: ini
|
||||
- type: textarea
|
||||
id: cmd-used
|
||||
attributes:
|
||||
label: Command used
|
||||
description: What was the command used to invoke pylint?
|
||||
placeholder: |
|
||||
pylint a.py
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: current-behavior
|
||||
attributes:
|
||||
label: Pylint output
|
||||
description: What is the current pylint output?
|
||||
placeholder: |
|
||||
************* Module a
|
||||
a.py:3:1: E0001: invalid syntax (<unknown>, line 1) (syntax-error)
|
||||
render: python
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: future-behavior
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description:
|
||||
What would you expect instead? For example expected output or behavior
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: python-interpreter
|
||||
attributes:
|
||||
label: Pylint version
|
||||
description: >-
|
||||
Please copy and paste the result of `pylint --version` or specify the range of
|
||||
versions affected.
|
||||
placeholder: |
|
||||
pylint 3.3.0
|
||||
astroid 3.3.0
|
||||
Python 3.12.0 (v3.12.0:0fb18b02c8, Oct 2 2023, 09:45:56)
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: OS / Environment
|
||||
description: >-
|
||||
Provide all relevant information below, e.g. OS version, terminal etc.
|
||||
placeholder: Fedora 33, Cygwin, etc.
|
||||
- type: textarea
|
||||
id: additional-deps
|
||||
attributes:
|
||||
label: Additional dependencies
|
||||
description:
|
||||
If applicable ie, if we can't reproduce without it. Please copy and paste the
|
||||
result of `pip freeze`.
|
||||
placeholder: |
|
||||
pandas==0.23.2
|
||||
marshmallow==3.10.0
|
||||
render: python
|
||||
@ -1,45 +0,0 @@
|
||||
name: ✨ Feature request
|
||||
description: Suggest an idea for pylint
|
||||
labels: ["Needs triage :inbox_tray:"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Thank you for wanting to make a suggestion for pylint!**
|
||||
|
||||
⚠ Please make sure that [this feature wasn't already requested][issue search] or already implemented in the main branch.
|
||||
|
||||
|
||||
[issue search]: https://github.com/pylint-dev/pylint/issues?q=is%3Aissue+is%3Aopen+
|
||||
|
||||
- type: textarea
|
||||
id: current-problem
|
||||
attributes:
|
||||
label: Current problem
|
||||
description:
|
||||
What are you trying to do, that you are unable to achieve with pylint as it
|
||||
currently stands?
|
||||
placeholder: >-
|
||||
I'm trying to do X and I'm missing feature Y for this to be easily achievable.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: proposed-solution
|
||||
attributes:
|
||||
label: Desired solution
|
||||
description: A clear and concise description of what you want to happen.
|
||||
placeholder: >-
|
||||
When I do X, I want to achieve Y in a situation when Z.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: >
|
||||
Add any other context, links, etc. about the feature here. Describe how the
|
||||
feature would be used, why it is needed and what it would solve.
|
||||
|
||||
**HINT:** You can paste https://gist.github.com links for larger files.
|
||||
placeholder: >-
|
||||
I asked on https://stackoverflow.com/... and the community advised me to do X, Y
|
||||
and Z.
|
||||
@ -1,49 +0,0 @@
|
||||
name: 🤔 Support question
|
||||
description: Questions about pylint that are not covered in the documentation
|
||||
labels: ["Needs triage :inbox_tray:", "Question", "Documentation :green_book:"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
**Thank you for wanting to report a problem with pylint documentation!**
|
||||
|
||||
|
||||
Please fill out your suggestions below. If the problem seems straightforward,
|
||||
feel free to go ahead and submit a pull request instead!
|
||||
|
||||
|
||||
⚠ Verify first that your issue is not [already reported on GitHub][issue
|
||||
search].
|
||||
|
||||
💬 If you are seeking community support, please consider [starting a discussion
|
||||
on Discord][Discussions].
|
||||
|
||||
|
||||
[issue search]:
|
||||
https://github.com/pylint-dev/pylint/issues?q=is%3Aissue+is%3Aopen+
|
||||
|
||||
[Discussions]: https://discord.com/invite/Egy6P8AMB5
|
||||
|
||||
- type: textarea
|
||||
id: question
|
||||
attributes:
|
||||
label: Question
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: documentation
|
||||
attributes:
|
||||
label: Documentation for future user
|
||||
description:
|
||||
Where did you expect this information to be? What do we need to add or what do
|
||||
we need to reorganize?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: >
|
||||
Add any other context, links, etc. about the question here.
|
||||
placeholder: >-
|
||||
I asked on https://stackoverflow.com/... and the community advised me to do X, Y
|
||||
and Z.
|
||||
@ -1,5 +0,0 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: 💬 Discord
|
||||
url: https://discord.com/invite/Egy6P8AMB5
|
||||
about: Astroid and pylint informal dev discussion
|
||||
@ -1,41 +0,0 @@
|
||||
<!--
|
||||
Thank you for submitting a PR to pylint!
|
||||
|
||||
To ease the process of reviewing your PR, do make sure to complete the following boxes.
|
||||
|
||||
- [ ] Document your change, if it is a non-trivial one.
|
||||
- A maintainer might label the issue ``skip-news`` if the change does not need to be in the changelog.
|
||||
- Otherwise, create a news fragment with ``towncrier create <IssueNumber>.<type>`` which will be
|
||||
included in the changelog. ``<type>`` can be one of the types defined in `./towncrier.toml`.
|
||||
If necessary you can write details or offer examples on how the new change is supposed to work.
|
||||
- Generating the doc is done with ``tox -e docs``
|
||||
- [ ] Relate your change to an issue in the tracker if such an issue exists (Refs #1234, Closes #1234)
|
||||
- [ ] Write comprehensive commit messages and/or a good description of what the PR does.
|
||||
- [ ] Keep the change small, separate the consensual changes from the opinionated one.
|
||||
Don't hesitate to open multiple PRs if the change requires it. If your review is so
|
||||
big it requires to actually plan and allocate time to review, it's more likely
|
||||
that it's going to go stale.
|
||||
- [ ] If you used multiple emails or multiple names when contributing, add your mails
|
||||
and preferred name in ``script/.contributors_aliases.json``
|
||||
-->
|
||||
|
||||
## Type of Changes
|
||||
|
||||
<!-- Leave the corresponding lines for the applicable type of change: -->
|
||||
|
||||
| | Type |
|
||||
| --- | ---------------------- |
|
||||
| ✓ | :bug: Bug fix |
|
||||
| ✓ | :sparkles: New feature |
|
||||
| ✓ | :hammer: Refactoring |
|
||||
| ✓ | :scroll: Docs |
|
||||
|
||||
## Description
|
||||
|
||||
<!-- If this PR references an issue without fixing it: -->
|
||||
|
||||
Refs #XXXX
|
||||
|
||||
<!-- If this PR fixes an issue, use the following to automatically close when we merge: -->
|
||||
|
||||
Closes #XXXX
|
||||
@ -1 +0,0 @@
|
||||
Coordinated Disclosure Plan: https://tidelift.com/security
|
||||
@ -1,255 +0,0 @@
|
||||
# Pylint Development Instructions
|
||||
|
||||
Always follow these instructions first and fallback to additional search and context
|
||||
gathering only if the information in these instructions is incomplete or found to be in
|
||||
error.
|
||||
|
||||
## Issue Label Guidelines
|
||||
|
||||
Before attempting to fix any issue, check the GitHub issue labels using the GitHub API:
|
||||
|
||||
- If an issue is labeled with "Astroid", "Needs astroid update", "Needs astroid
|
||||
constraint", or "Needs astroid Brain 🧠", **ONLY** create regression tests
|
||||
- Do **NOT** attempt to fix astroid-related issues as you cannot modify astroid from
|
||||
this repository
|
||||
- For astroid-related issues, focus on creating comprehensive regression tests that
|
||||
reproduce the problem
|
||||
- All other issues can be fixed normally following the standard development workflow
|
||||
|
||||
## Development Environment Setup
|
||||
|
||||
### Basic Installation
|
||||
|
||||
Clone and set up pylint development environment:
|
||||
|
||||
- `git clone https://github.com/pylint-dev/pylint` -- clone repository
|
||||
- `cd pylint` -- enter directory
|
||||
- `python3 -m venv venv` -- create virtual environment
|
||||
- `source venv/bin/activate` -- activate virtual environment (Linux/Mac)
|
||||
- `pip install -r requirements_test_min.txt` -- install test dependencies (~30 seconds)
|
||||
- `pip install -e .` -- install pylint in editable mode (~30-60 seconds)
|
||||
|
||||
### Optional Setup Steps
|
||||
|
||||
- `pre-commit install` -- enable pre-commit hooks for autoformatting
|
||||
- `pip install pre-commit` -- install pre-commit separately if needed
|
||||
|
||||
### Astroid Development (if needed)
|
||||
|
||||
If working on astroid changes:
|
||||
|
||||
- `git clone https://github.com/pylint-dev/astroid.git` -- clone astroid
|
||||
- `pip install -e astroid/` -- install astroid in editable mode
|
||||
- `cd astroid/ && git switch my-astroid-dev-branch` -- switch to development branch
|
||||
|
||||
## Running Tests
|
||||
|
||||
### Core Test Commands
|
||||
|
||||
- `pytest tests/test_functional.py -k test_functional` -- run functional tests (~60
|
||||
seconds, NEVER CANCEL, set timeout to 120+ seconds)
|
||||
- `pytest tests/` -- run all tests (several minutes, NEVER CANCEL, set timeout to 300+
|
||||
seconds)
|
||||
- `python3 -m pytest` -- run tests with local python
|
||||
- `pytest tests/test_check_parallel.py -v` -- quick test file (~2 seconds)
|
||||
|
||||
### Specific Test Types
|
||||
|
||||
- **Functional tests:**
|
||||
`pytest "tests/test_functional.py::test_functional[missing_kwoa_py3]"` -- single
|
||||
functional test (~1 second)
|
||||
- **Unit tests:** Located in `/tests/` directory, test specific pylint functionality
|
||||
- **Configuration tests:** In `/tests/config/functional/` for testing configuration
|
||||
loading
|
||||
- **Primer tests:** `pytest -m primer_stdlib --primer-stdlib` -- test on stdlib for
|
||||
crashes
|
||||
|
||||
### Test with Coverage
|
||||
|
||||
- `pytest tests/message/ --cov=pylint.message` -- run with coverage
|
||||
- `coverage html` -- generate HTML coverage report
|
||||
|
||||
### Tox Usage (Optional)
|
||||
|
||||
- `python -m tox` -- run all tox environments
|
||||
- `python -m tox -epy313` -- run Python 3.13 suite only
|
||||
- `python -m tox -epylint` -- run pylint on pylint's codebase
|
||||
- `python -m tox -eformatting` -- run formatting checks
|
||||
- `python -m tox --recreate` -- recreate environments (recommended)
|
||||
- `python -m tox -e py310 -- -k test_functional` -- run specific tests in tox
|
||||
|
||||
## Documentation
|
||||
|
||||
### Building Documentation
|
||||
|
||||
- `make -C doc/ install-dependencies` -- install doc dependencies (~10 seconds)
|
||||
- `make -C doc/ html` -- build documentation (~3 minutes, NEVER CANCEL, set timeout to
|
||||
300+ seconds)
|
||||
- `make -C doc/ clean` -- clean build files when starting from scratch
|
||||
- `tox -e docs` -- alternative way to build docs
|
||||
|
||||
**Network dependency:** Documentation build requires internet access to fetch external
|
||||
inventories.
|
||||
|
||||
## Validation and Quality Checks
|
||||
|
||||
### Running Pylint on Code
|
||||
|
||||
- `pylint --help` -- verify pylint installation works
|
||||
- `pylint --disable=all --enable=E,F pylint/` -- run pylint on itself for errors only
|
||||
(~20 seconds)
|
||||
- `pylint --rcfile=pylintrc --fail-on=I path/to/your/changes.py` -- standard pylint run
|
||||
- `pylint --disable=all --enable=E,F,W path/to/your/changes.py` -- focus on errors and
|
||||
warnings
|
||||
|
||||
### Pre-commit and Formatting
|
||||
|
||||
- `pre-commit run --all-files` -- run all formatting checks (requires network for
|
||||
initial setup)
|
||||
- **Network dependency:** pre-commit may fail in isolated environments due to hook
|
||||
downloads
|
||||
|
||||
### Validation Test Scenarios
|
||||
|
||||
Always test your changes with these validation scenarios:
|
||||
|
||||
- `echo "def badFunction(): pass" > /tmp/test_sample.py && pylint --enable=C0103 /tmp/test_sample.py`
|
||||
-- should find naming issues
|
||||
- `pylint --help` and `pylint --list-msgs | head -10` -- verify CLI functionality
|
||||
- `pylint --help-msg=C0103` -- should show invalid-name help
|
||||
- `pylint --rcfile=pylintrc --fail-on=I pylint/__init__.py` -- should get 10.00/10
|
||||
rating
|
||||
|
||||
## Writing Tests
|
||||
|
||||
### Functional Tests
|
||||
|
||||
Located in `/tests/functional/`, consists of `.py` test files with corresponding `.txt`
|
||||
expected output files:
|
||||
|
||||
- Annotate lines where messages are expected:
|
||||
`a, b, c = 1 # [unbalanced-tuple-unpacking]`
|
||||
- Multiple messages on same line:
|
||||
`a, b, c = 1.test # [unbalanced-tuple-unpacking, no-member]`
|
||||
- Use offset syntax for special cases: `# +1: [singleton-comparison]`
|
||||
- **Run and update:**
|
||||
`python tests/test_functional.py --update-functional-output -k "test_functional[test_name]"`
|
||||
|
||||
### Test File Organization
|
||||
|
||||
- **New checkers:** Create `new_checker_message.py` in `/tests/functional/n/`
|
||||
- **Extensions:** Place in `/tests/functional/ext/extension_name/`
|
||||
- **Regression tests:** Place in `/tests/r/regression/` with `regression_` prefix
|
||||
- **Configuration tests:** Place in `/tests/config/functional/`
|
||||
|
||||
### Configuration Test Files
|
||||
|
||||
Create `.result.json` files with configuration differences from standard config:
|
||||
|
||||
```json
|
||||
{
|
||||
"functional_append": {
|
||||
"disable": [["a-message-to-be-added"]]
|
||||
},
|
||||
"jobs": 10
|
||||
}
|
||||
```
|
||||
|
||||
## Codebase Structure
|
||||
|
||||
```
|
||||
pylint/ # Main package
|
||||
├── checkers/ # All pylint checkers (rules implementation)
|
||||
├── config/ # Configuration handling and parsing
|
||||
├── message/ # Message system and formatting
|
||||
├── reporters/ # Output formatters (text, json, etc.)
|
||||
├── testutils/ # Testing utilities and helpers
|
||||
└── extensions/ # Optional extensions and plugins
|
||||
|
||||
tests/ # Test suite
|
||||
├── functional/ # Functional test files (.py + .txt expected output)
|
||||
├── config/functional/ # Configuration functional tests
|
||||
├── r/regression/ # Regression tests
|
||||
├── test_*.py # Unit tests
|
||||
└── regrtest_data/ # Test data files
|
||||
|
||||
doc/ # Documentation
|
||||
├── user_guide/ # User documentation
|
||||
├── development_guide/ # Developer and contributor documentation
|
||||
│ ├── contributor_guide/ # Setup, testing, contribution guidelines
|
||||
│ ├── technical_reference/ # Technical implementation details
|
||||
│ └── how_tos/ # Guides for custom checkers, plugins
|
||||
└── additional_tools/ # Tools documentation
|
||||
|
||||
script/ # Development utility scripts
|
||||
```
|
||||
|
||||
### Key Files
|
||||
|
||||
- `pyproject.toml` -- Main configuration (dependencies, build, tools)
|
||||
- `tox.ini` -- Multi-environment testing configuration
|
||||
- `.pre-commit-config.yaml` -- Code quality checks configuration
|
||||
- `pylintrc` -- Pylint's own configuration
|
||||
- `requirements_test_min.txt` -- Minimal test dependencies
|
||||
- `.gitignore` do not add the 'venv' inside the .gitignore, don't commit the venv in the
|
||||
first place (humans add it to their global gitignore)
|
||||
|
||||
## Creating New Checkers
|
||||
|
||||
### Getting Started
|
||||
|
||||
- `python script/get_unused_message_id_category.py` -- get next available message ID
|
||||
- Study existing checkers in `pylint/checkers/` for patterns
|
||||
- Read technical reference documentation in `doc/development_guide/technical_reference/`
|
||||
- Use `astroid.extract_node` for AST manipulation
|
||||
|
||||
### Workflow
|
||||
|
||||
1. Create checker class in appropriate `pylint/checkers/` file
|
||||
2. Add functional tests in `tests/functional/`
|
||||
3. Search existing code for warning message to find where logic exists
|
||||
4. Test with sample code to ensure functionality works
|
||||
|
||||
## Pull Request Guidelines
|
||||
|
||||
### Before Submitting
|
||||
|
||||
- Use Python 3.8+ for development (required for latest AST parser and pre-commit hooks)
|
||||
- Write comprehensive commit messages relating to tracker issues
|
||||
- Keep changes small and separate consensual from opinionated changes
|
||||
- Add news fragment: `towncrier create <IssueNumber>.<type>`
|
||||
- Always launch `pre-commit run -a` before committing
|
||||
|
||||
### Documentation Changes
|
||||
|
||||
- Document non-trivial changes
|
||||
- Generate docs with `tox -e docs`
|
||||
- Maintainers may label issues `skip-news` if no changelog needed
|
||||
|
||||
### Contribution Credits
|
||||
|
||||
- Add emails/names to `script/.contributors_aliases.json` if using multiple identities
|
||||
|
||||
## Critical Timing Information
|
||||
|
||||
- **NEVER CANCEL:** All operations that show "NEVER CANCEL" may take significant time
|
||||
- **Full test suite:** 60+ seconds (set timeout to 120+ seconds)
|
||||
- **Documentation build:** 180 seconds (set timeout to 300+ seconds)
|
||||
- **Functional tests:** 60 seconds (set timeout to 120+ seconds)
|
||||
- **Pylint self-check:** 20 seconds (set timeout to 60+ seconds)
|
||||
- **Individual test files:** 1-15 seconds
|
||||
- **Installation steps:** 30-60 seconds each
|
||||
|
||||
## Environment Limitations and Workarounds
|
||||
|
||||
- **Network connectivity required:** Documentation build and pre-commit setup require
|
||||
internet access
|
||||
- **Tox failures:** In isolated environments, use direct pytest and pip commands instead
|
||||
of tox
|
||||
- **Import errors in self-check:** Some import errors when running pylint on itself are
|
||||
expected (git dependencies not installed)
|
||||
- **Build environments:** Use direct pip/pytest commands when tox environments fail to
|
||||
build
|
||||
|
||||
Always validate your changes by running pylint on sample code to ensure functionality
|
||||
works correctly.
|
||||
@ -1,21 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "pip"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
labels:
|
||||
- "dependency"
|
||||
- "Skip news :mute:"
|
||||
open-pull-requests-limit: 10
|
||||
rebase-strategy: "disabled"
|
||||
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
labels:
|
||||
- "dependency"
|
||||
- "Skip news :mute:"
|
||||
open-pull-requests-limit: 10
|
||||
rebase-strategy: "disabled"
|
||||
@ -1,40 +0,0 @@
|
||||
name: Backport
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- closed
|
||||
- labeled
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
backport:
|
||||
name: Backport
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: Backport
|
||||
# Only react to merged PRs for security reasons.
|
||||
# See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target.
|
||||
if: >
|
||||
github.event.pull_request.merged && (
|
||||
github.event.action == 'closed'
|
||||
|| (
|
||||
github.event.action == 'labeled'
|
||||
&& contains(github.event.label.name, 'backport')
|
||||
)
|
||||
)
|
||||
steps:
|
||||
- uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ vars.BACKPORT_APP_ID }}
|
||||
private-key: ${{ secrets.PRIVATE_KEY }}
|
||||
permission-contents: write # push branch to Github
|
||||
permission-pull-requests: write # create PR / add comment for manual backport
|
||||
permission-workflows: write # modify files in .github/workflows
|
||||
- uses: pylint-dev/backport@94367840595495e101f9a31415897c05da1f08d9 # v2.1.1
|
||||
with:
|
||||
github_token: ${{ steps.app-token.outputs.token }}
|
||||
user_name: ${{ vars.BACKPORT_USER_NAME }}
|
||||
user_email: ${{ vars.BACKPORT_USER_EMAIL }}
|
||||
@ -1,65 +0,0 @@
|
||||
name: changelog
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, labeled, unlabeled, reopened]
|
||||
branches-ignore:
|
||||
- "maintenance/**"
|
||||
env:
|
||||
CACHE_VERSION: 1
|
||||
KEY_PREFIX: base-venv
|
||||
DEFAULT_PYTHON: "3.13"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check-changelog:
|
||||
if: contains(github.event.pull_request.labels.*.name, 'skip news :mute:') != true
|
||||
name: Changelog Entry Check
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v5.0.0
|
||||
with:
|
||||
# `towncrier check` runs `git diff --name-only origin/main...`, which
|
||||
# needs a non-shallow clone.
|
||||
fetch-depth: 0
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v6.0.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Generate partial Python venv restore key
|
||||
id: generate-python-key
|
||||
run: >-
|
||||
echo "key=${{ env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{
|
||||
hashFiles('pyproject.toml', 'requirements_test.txt',
|
||||
'requirements_test_min.txt', 'requirements_test_pre_commit.txt') }}" >>
|
||||
$GITHUB_OUTPUT
|
||||
- name: Restore Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@v4.3.0
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||
steps.generate-python-key.outputs.key }}
|
||||
- name: Create Python virtual environment
|
||||
if: steps.cache-venv.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
python -m venv venv
|
||||
. venv/bin/activate
|
||||
python -m pip install --upgrade pip
|
||||
pip install --upgrade --requirement requirements_test.txt --requirement doc/requirements.txt
|
||||
- name: Emit warning if news fragment is missing
|
||||
env:
|
||||
BASE_BRANCH: ${{ github.base_ref }}
|
||||
run: |
|
||||
# Fetch the pull request' base branch so towncrier will be able to
|
||||
# compare the current branch with the base branch.
|
||||
git fetch --no-tags origin +refs/heads/${BASE_BRANCH}:refs/remotes/origin/${BASE_BRANCH}
|
||||
. venv/bin/activate
|
||||
towncrier check --compare-with origin/${{ github.base_ref }}
|
||||
@ -1,160 +0,0 @@
|
||||
name: Checks
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "maintenance/**"
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- "maintenance/**"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
CACHE_VERSION: 3
|
||||
KEY_PREFIX: base-venv
|
||||
DEFAULT_PYTHON: "3.13"
|
||||
PRE_COMMIT_CACHE: ~/.cache/pre-commit
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
prepare-base:
|
||||
name: Prepare base dependencies
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
outputs:
|
||||
python-key: ${{ steps.generate-python-key.outputs.key }}
|
||||
pre-commit-key: ${{ steps.generate-pre-commit-key.outputs.key }}
|
||||
steps:
|
||||
- &checkout
|
||||
name: Check out code from GitHub
|
||||
uses: actions/checkout@v5.0.0
|
||||
- &setup-python
|
||||
name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v6.0.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Generate partial Python venv restore key
|
||||
id: generate-python-key
|
||||
run: >-
|
||||
echo "key=${{ env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{
|
||||
hashFiles('pyproject.toml', 'requirements_test.txt',
|
||||
'requirements_test_min.txt', 'requirements_test_pre_commit.txt') }}" >>
|
||||
$GITHUB_OUTPUT
|
||||
- name: Restore Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@v4.3.0
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||
steps.generate-python-key.outputs.key }}
|
||||
- name: Create Python virtual environment
|
||||
if: steps.cache-venv.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
python -m venv venv
|
||||
. venv/bin/activate
|
||||
python -m pip install --upgrade pip
|
||||
pip install --upgrade --requirement requirements_test.txt --requirement doc/requirements.txt
|
||||
pip install pre-commit
|
||||
- name: Generate pre-commit restore key
|
||||
id: generate-pre-commit-key
|
||||
run: >-
|
||||
echo "key=pre-commit-${{ env.CACHE_VERSION }}-${{
|
||||
hashFiles('.pre-commit-config.yaml') }}" >> $GITHUB_OUTPUT
|
||||
- name: Restore pre-commit environment
|
||||
id: cache-precommit
|
||||
uses: actions/cache@v4.3.0
|
||||
with:
|
||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||
key: >-
|
||||
${{ runner.os }}-${{ steps.generate-pre-commit-key.outputs.key }}
|
||||
- name: Install pre-commit dependencies
|
||||
if: steps.cache-precommit.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
pre-commit install --install-hooks
|
||||
|
||||
pylint:
|
||||
name: pylint
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
needs: [prepare-base]
|
||||
steps:
|
||||
- *checkout
|
||||
- *setup-python
|
||||
- &cache-restore-python
|
||||
name: Restore Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.3.0
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
key:
|
||||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||
needs.prepare-base.outputs.python-key }}
|
||||
- name: Restore pre-commit environment
|
||||
id: cache-precommit
|
||||
uses: actions/cache/restore@v4.3.0
|
||||
with:
|
||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||
fail-on-cache-miss: true
|
||||
key: ${{ runner.os }}-${{ needs.prepare-base.outputs.pre-commit-key }}
|
||||
- name: Install enchant and aspell
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install enchant-2 aspell-en
|
||||
- name: Run pylint checks
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
pip install . --no-deps
|
||||
pip list | grep 'astroid\|pylint'
|
||||
pre-commit run --hook-stage manual pylint-with-spelling --all-files
|
||||
|
||||
spelling:
|
||||
name: spelling tests
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
needs: [prepare-base]
|
||||
steps:
|
||||
- *checkout
|
||||
- *setup-python
|
||||
- *cache-restore-python
|
||||
- name: Run spelling checks
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
pip install . --no-deps
|
||||
pytest tests/ -k unittest_spelling --benchmark-disable
|
||||
|
||||
documentation:
|
||||
name: documentation
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
needs: [prepare-base]
|
||||
steps:
|
||||
- *checkout
|
||||
- *setup-python
|
||||
- *cache-restore-python
|
||||
- name: Run checks on documentation code examples
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
tox -e test_doc
|
||||
- name: Check documentation build and links
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
tox -e docs || {
|
||||
echo "git diff:" ; \
|
||||
git diff ; \
|
||||
echo "End of 'git diff'" ; \
|
||||
echo "Make sure that 'tox -e docs' succeed without any modifications locally." ; \
|
||||
exit 1; \
|
||||
}
|
||||
@ -1,95 +0,0 @@
|
||||
name: Primer
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
paths:
|
||||
- "pylint/**"
|
||||
- "tests/primer/**"
|
||||
- "requirements*"
|
||||
- ".github/workflows/primer-test.yaml"
|
||||
branches:
|
||||
- main
|
||||
env:
|
||||
CACHE_VERSION: 4
|
||||
KEY_PREFIX: venv
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
prepare-tests-linux:
|
||||
name: prepare / ${{ matrix.python-version }} / Linux
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: &matrix-python-version ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
||||
outputs:
|
||||
python-key: ${{ steps.generate-python-key.outputs.key }}
|
||||
steps:
|
||||
- &checkout
|
||||
name: Check out code from GitHub
|
||||
uses: actions/checkout@v5.0.0
|
||||
- &setup-python
|
||||
name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@v6.0.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
allow-prereleases: true
|
||||
check-latest: true
|
||||
- name: Generate partial Python venv restore key
|
||||
id: generate-python-key
|
||||
run: >-
|
||||
echo "key=${{ env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{
|
||||
hashFiles('pyproject.toml', 'requirements_test.txt',
|
||||
'requirements_test_min.txt', 'requirements_test_pre_commit.txt') }}" >>
|
||||
$GITHUB_OUTPUT
|
||||
- name: Restore Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@v4.3.0
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||
steps.generate-python-key.outputs.key }}
|
||||
- name: Create Python virtual environment
|
||||
if: steps.cache-venv.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
python -m venv venv
|
||||
. venv/bin/activate
|
||||
python -m pip install --upgrade pip
|
||||
pip install --upgrade --requirement requirements_test.txt
|
||||
|
||||
pytest-primer-stdlib:
|
||||
name: run on stdlib / ${{ matrix.python-version }} / Linux
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
needs: prepare-tests-linux
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: *matrix-python-version
|
||||
steps:
|
||||
- *checkout
|
||||
- *setup-python
|
||||
- name: Restore Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.3.0
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
key:
|
||||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||
needs.prepare-tests-linux.outputs.python-key }}
|
||||
- name: Run pytest
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
pip install . --no-deps
|
||||
pytest -m primer_stdlib --primer-stdlib -n auto -vv --benchmark-disable
|
||||
@ -1,125 +0,0 @@
|
||||
# Most of this is inspired by the mypy primer
|
||||
# See: https://github.com/hauntsaninja/mypy_primer
|
||||
# This is the primer job that creates the comment on the PR
|
||||
# It needs to trigger on workflow_run instead of pull_request
|
||||
# as we need repository wide access to create a comment
|
||||
|
||||
name: Primer / Comment
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [Primer / Run]
|
||||
types:
|
||||
- completed
|
||||
|
||||
env:
|
||||
# This needs to be the SAME as in the Main and PR job
|
||||
CACHE_VERSION: 4
|
||||
KEY_PREFIX: venv-primer
|
||||
# If you change this, also change PRIMER_CURRENT_INTERPRETER in
|
||||
# tests/testutils/_primer/test_primer.py
|
||||
DEFAULT_PYTHON: "3.13"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
primer-comment:
|
||||
# Skip job if the workflow failed
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
name: Run
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v5.0.0
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v6.0.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
|
||||
# Restore cached Python environment
|
||||
- name: Restore Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@v4.3.0
|
||||
with:
|
||||
path: venv
|
||||
key:
|
||||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||
env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{ hashFiles('pyproject.toml',
|
||||
'requirements_test.txt', 'requirements_test_min.txt',
|
||||
'requirements_test_pre_commit.txt') }}
|
||||
|
||||
- name: Download outputs
|
||||
uses: actions/github-script@v8.0.0
|
||||
with:
|
||||
script: |
|
||||
// Download workflow pylint output
|
||||
const fs = require('fs');
|
||||
const artifacts_workflow = await github.rest.actions.listWorkflowRunArtifacts({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
run_id: ${{ github.event.workflow_run.id }},
|
||||
});
|
||||
|
||||
// Get 'main' and 'PR' outputs and PR number
|
||||
const artifacts = artifacts_workflow.data.artifacts.filter((artifact) =>
|
||||
artifact.name.startsWith(`primer_output_main_${process.env.DEFAULT_PYTHON}`)
|
||||
|| artifact.name.startsWith(`primer_output_pr_${process.env.DEFAULT_PYTHON}`)
|
||||
|| artifact.name === 'pr_number'
|
||||
);
|
||||
for (const artifact of artifacts) {
|
||||
const downloaded = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: artifact.id,
|
||||
archive_format: "zip",
|
||||
});
|
||||
fs.writeFileSync(`${artifact.name}.zip`, Buffer.from(downloaded.data));
|
||||
}
|
||||
|
||||
- name: Unzip outputs
|
||||
run: |
|
||||
unzip primer_output_main_${{ env.DEFAULT_PYTHON }}_batch0.zip
|
||||
unzip primer_output_main_${{ env.DEFAULT_PYTHON }}_batch1.zip
|
||||
unzip primer_output_main_${{ env.DEFAULT_PYTHON }}_batch2.zip
|
||||
unzip primer_output_main_${{ env.DEFAULT_PYTHON }}_batch3.zip
|
||||
unzip primer_output_pr_${{ env.DEFAULT_PYTHON }}_batch0.zip
|
||||
unzip primer_output_pr_${{ env.DEFAULT_PYTHON }}_batch1.zip
|
||||
unzip primer_output_pr_${{ env.DEFAULT_PYTHON }}_batch2.zip
|
||||
unzip primer_output_pr_${{ env.DEFAULT_PYTHON }}_batch3.zip
|
||||
unzip pr_number.zip
|
||||
- name: Compare outputs
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
python tests/primer/__main__.py compare \
|
||||
--commit=${{ github.event.workflow_run.head_sha }} \
|
||||
--base-file=output_${{ env.DEFAULT_PYTHON }}_main_BATCHIDX.txt \
|
||||
--new-file=output_${{ env.DEFAULT_PYTHON }}_pr_BATCHIDX.txt \
|
||||
--batches=4
|
||||
- name: Post comment
|
||||
id: post-comment
|
||||
uses: actions/github-script@v8.0.0
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs')
|
||||
const comment = fs.readFileSync('tests/.pylint_primer_tests/comment.txt', { encoding: 'utf8' })
|
||||
console.log("Comment to post:")
|
||||
console.log(comment)
|
||||
const prNumber = parseInt(fs.readFileSync("pr_number.txt", { encoding: "utf8" }))
|
||||
await github.rest.issues.createComment({
|
||||
issue_number: prNumber,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: comment
|
||||
})
|
||||
return prNumber
|
||||
- name: Hide old comments
|
||||
# Taken from mypy primer
|
||||
uses: kanga333/comment-hider@c12bb20b48aeb8fc098e35967de8d4f8018fffdf # v0.4.0
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
leave_visible: 1
|
||||
issue_number: ${{ steps.post-comment.outputs.result }}
|
||||
@ -1,132 +0,0 @@
|
||||
# Most of this is inspired by the mypy primer
|
||||
# See: https://github.com/hauntsaninja/mypy_primer
|
||||
# This is the primer job that runs on the default 'main' branch
|
||||
# It is also responsible for caching the packages to prime on
|
||||
|
||||
name: Primer / Main
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
# This needs to be the SAME as in the PR and comment job
|
||||
CACHE_VERSION: 4
|
||||
KEY_PREFIX: venv-primer
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
run-primer:
|
||||
name: Run / ${{ matrix.python-version }} / batch index ${{ matrix.batchIdx }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.10", "3.13"]
|
||||
batches: [4]
|
||||
batchIdx: [0, 1, 2, 3]
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v5.0.0
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@v6.0.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
|
||||
# Create a re-usable virtual environment
|
||||
- name: Restore Python virtual environment cache
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.3.0
|
||||
with:
|
||||
path: venv
|
||||
key:
|
||||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||
env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{ hashFiles('pyproject.toml',
|
||||
'requirements_test.txt', 'requirements_test_min.txt',
|
||||
'requirements_test_pre_commit.txt') }}
|
||||
- name: Create Python virtual environment
|
||||
if: steps.cache-venv.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
python -m venv venv
|
||||
. venv/bin/activate
|
||||
python -m pip install --upgrade pip
|
||||
pip install --upgrade --requirement requirements_test.txt
|
||||
# Save cached Python environment (explicit because cancel-in-progress: true)
|
||||
- name: Save Python virtual environment to cache
|
||||
if: steps.cache-venv.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v4.3.0
|
||||
with:
|
||||
path: venv
|
||||
key:
|
||||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||
env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{ hashFiles('pyproject.toml',
|
||||
'requirements_test.txt', 'requirements_test_min.txt',
|
||||
'requirements_test_pre_commit.txt') }}
|
||||
|
||||
# Cache primer packages
|
||||
- name: Get commit string
|
||||
id: commitstring
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
python tests/primer/__main__.py prepare --make-commit-string
|
||||
output=$(python tests/primer/__main__.py prepare --read-commit-string)
|
||||
echo "commitstring=$output" >> $GITHUB_OUTPUT
|
||||
- name: Restore projects cache
|
||||
id: cache-projects
|
||||
uses: actions/cache/restore@v4.3.0
|
||||
with:
|
||||
path: tests/.pylint_primer_tests/
|
||||
key: >-
|
||||
${{ runner.os }}-${{ matrix.python-version }}-${{
|
||||
steps.commitstring.outputs.commitstring }}-primer
|
||||
- name: Regenerate cache
|
||||
if: steps.cache-projects.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
python tests/primer/__main__.py prepare --clone
|
||||
- name: Save projects cache
|
||||
if: steps.cache-projects.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v4.3.0
|
||||
with:
|
||||
path: tests/.pylint_primer_tests/
|
||||
key: >-
|
||||
${{ runner.os }}-${{ matrix.python-version }}-${{
|
||||
steps.commitstring.outputs.commitstring }}-primer
|
||||
- name: Upload commit string
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
if: matrix.batchIdx == 0
|
||||
with:
|
||||
name: primer_commitstring_${{ matrix.python-version }}
|
||||
path:
|
||||
tests/.pylint_primer_tests/commit_string_${{ matrix.python-version }}.txt
|
||||
|
||||
# Run primer
|
||||
- name: Run pylint primer
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
pip install . --no-deps
|
||||
python tests/primer/__main__.py run --type=main --batches=${{ matrix.batches }} --batchIdx=${{ matrix.batchIdx }} 2>warnings.txt
|
||||
- name: Echo warnings
|
||||
if: success() || failure()
|
||||
run: |
|
||||
WARNINGS=$(head -c 65000 < warnings.txt)
|
||||
if [[ $WARNINGS ]]
|
||||
then echo "::warning ::$WARNINGS"
|
||||
fi
|
||||
- name: Upload output
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
with:
|
||||
name:
|
||||
primer_output_main_${{ matrix.python-version }}_batch${{ matrix.batchIdx }}
|
||||
path: >-
|
||||
tests/.pylint_primer_tests/output_${{ matrix.python-version }}_main_batch${{
|
||||
matrix.batchIdx }}.txt
|
||||
@ -1,225 +0,0 @@
|
||||
# Most of this is inspired by the mypy primer
|
||||
# See: https://github.com/hauntsaninja/mypy_primer
|
||||
# This is the primer job that runs on every PR
|
||||
|
||||
name: Primer / Run
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "pylint/**"
|
||||
- "tests/primer/**"
|
||||
- "requirements*"
|
||||
- ".github/workflows/**"
|
||||
# We ignore these specific files because they need to be changed
|
||||
# on 'main' and will always fail the PR run.
|
||||
- "!.github/workflows/primer_run_main.yaml"
|
||||
- "!.github/workflows/primer_comment.yaml"
|
||||
- "!tests/primer/packages_to_prime.json"
|
||||
branches:
|
||||
- main
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
# This needs to be the SAME as in the Main and comment job
|
||||
CACHE_VERSION: 4
|
||||
KEY_PREFIX: venv-primer
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
run-primer:
|
||||
name: Run / ${{ matrix.python-version }} / batch index ${{ matrix.batchIdx }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 45
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.10", "3.13"]
|
||||
batches: [4]
|
||||
batchIdx: [0, 1, 2, 3]
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@v6.0.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
|
||||
# Restore cached Python environment
|
||||
- name: Restore Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.3.0
|
||||
with:
|
||||
path: venv
|
||||
key:
|
||||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||
env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{ hashFiles('pyproject.toml',
|
||||
'requirements_test.txt', 'requirements_test_min.txt',
|
||||
'requirements_test_pre_commit.txt') }}
|
||||
# Create environment must match step in 'Primer / Main'
|
||||
- name: Create Python virtual environment
|
||||
if: steps.cache-venv.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
python -m venv venv
|
||||
. venv/bin/activate
|
||||
python -m pip install --upgrade pip
|
||||
pip install --upgrade --requirement requirements_test.txt
|
||||
# Save cached Python environment (explicit because cancel-in-progress: true)
|
||||
- name: Save Python virtual environment
|
||||
if: steps.cache-venv.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v4.3.0
|
||||
with:
|
||||
path: venv
|
||||
key:
|
||||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||
env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{ hashFiles('pyproject.toml',
|
||||
'requirements_test.txt', 'requirements_test_min.txt',
|
||||
'requirements_test_pre_commit.txt') }}
|
||||
|
||||
# Cache primer packages
|
||||
- name: Download last 'main' run info
|
||||
id: download-main-run
|
||||
uses: actions/github-script@v8.0.0
|
||||
env:
|
||||
COMMIT_STRING_ARTIFACT: primer_commitstring_${{ matrix.python-version }}
|
||||
OUTPUT_ARTIFACT:
|
||||
primer_output_main_${{ matrix.python-version }}_batch${{ matrix.batchIdx }}
|
||||
with:
|
||||
script: |
|
||||
const { COMMIT_STRING_ARTIFACT, OUTPUT_ARTIFACT } = process.env
|
||||
// Download 'main' pylint output
|
||||
const fs = require('fs');
|
||||
const runs = await github.rest.actions.listWorkflowRuns({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
workflow_id: ".github/workflows/primer_run_main.yaml",
|
||||
status: "success"
|
||||
});
|
||||
const lastRunMain = runs.data.workflow_runs.reduce(function(prev, current) {
|
||||
return (prev.run_number > current.run_number) ? prev : current
|
||||
})
|
||||
console.log("Last run on main:")
|
||||
console.log(lastRunMain.html_url)
|
||||
const artifacts_main = await github.rest.actions.listWorkflowRunArtifacts({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
run_id: lastRunMain.id,
|
||||
});
|
||||
|
||||
// Get commitstring
|
||||
const [matchArtifactMain] = artifacts_main.data.artifacts.filter((artifact) =>
|
||||
artifact.name === COMMIT_STRING_ARTIFACT);
|
||||
const downloadWorkflow = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: matchArtifactMain.id,
|
||||
archive_format: "zip",
|
||||
});
|
||||
fs.writeFileSync(`${COMMIT_STRING_ARTIFACT}.zip`, Buffer.from(downloadWorkflow.data));
|
||||
|
||||
// Get output
|
||||
const [matchArtifactMainOutput] = artifacts_main.data.artifacts.filter((artifact) =>
|
||||
artifact.name === OUTPUT_ARTIFACT);
|
||||
const downloadWorkflowTwo = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: matchArtifactMainOutput.id,
|
||||
archive_format: "zip",
|
||||
});
|
||||
fs.writeFileSync(`${OUTPUT_ARTIFACT}.zip`, Buffer.from(downloadWorkflowTwo.data));
|
||||
return lastRunMain.head_sha;
|
||||
- name: Copy and unzip the commit string
|
||||
run: |
|
||||
unzip primer_commitstring_${{ matrix.python-version }}.zip
|
||||
cp commit_string_${{ matrix.python-version }}.txt tests/.pylint_primer_tests/commit_string_${{ matrix.python-version }}.txt
|
||||
- name: Unzip the output of 'main'
|
||||
run: |
|
||||
unzip primer_output_main_${{ matrix.python-version }}_batch${{ matrix.batchIdx }}.zip
|
||||
- name: Get commit string
|
||||
id: commitstring
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
output=$(python tests/primer/__main__.py prepare --read-commit-string)
|
||||
echo "commitstring=$output" >> $GITHUB_OUTPUT
|
||||
- name: Restore projects cache
|
||||
id: cache-projects
|
||||
uses: actions/cache/restore@v4.3.0
|
||||
with:
|
||||
path: tests/.pylint_primer_tests/
|
||||
key: >-
|
||||
${{ runner.os }}-${{ matrix.python-version }}-${{
|
||||
steps.commitstring.outputs.commitstring }}-primer
|
||||
- name: Regenerate cache
|
||||
if: steps.cache-projects.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
python tests/primer/__main__.py prepare --clone
|
||||
- name: Save projects cache
|
||||
if: steps.cache-projects.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v4.3.0
|
||||
with:
|
||||
path: tests/.pylint_primer_tests/
|
||||
key: >-
|
||||
${{ runner.os }}-${{ matrix.python-version }}-${{
|
||||
steps.commitstring.outputs.commitstring }}-primer
|
||||
- name: Check cache
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
python tests/primer/__main__.py prepare --check
|
||||
|
||||
# Merge the 'main' commit of last successful run
|
||||
- name: Pull 'main'
|
||||
shell: bash
|
||||
run: |
|
||||
git config --global user.email "primer@example.com"
|
||||
git config --global user.name "Pylint Primer"
|
||||
git pull origin ${{ steps.download-main-run.outputs.result }} --no-edit --no-commit --no-rebase
|
||||
|
||||
# Run primer
|
||||
- name: Run pylint primer
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
pip install . --no-deps
|
||||
python tests/primer/__main__.py run --type=pr --batches=${{ matrix.batches }} --batchIdx=${{ matrix.batchIdx }} 2>warnings.txt
|
||||
- name: Echo warnings
|
||||
if: success() || failure()
|
||||
run: |
|
||||
WARNINGS=$(head -c 65000 < warnings.txt)
|
||||
if [[ $WARNINGS ]]
|
||||
then echo "::warning ::$WARNINGS"
|
||||
fi
|
||||
- name: Upload output of PR
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
with:
|
||||
name:
|
||||
primer_output_pr_${{ matrix.python-version }}_batch${{ matrix.batchIdx }}
|
||||
path:
|
||||
tests/.pylint_primer_tests/output_${{ matrix.python-version }}_pr_batch${{
|
||||
matrix.batchIdx }}.txt
|
||||
- name: Upload output of 'main'
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
with:
|
||||
name:
|
||||
primer_output_main_${{ matrix.python-version }}_batch${{ matrix.batchIdx }}
|
||||
path: output_${{ matrix.python-version }}_main_batch${{ matrix.batchIdx }}.txt
|
||||
|
||||
# Save PR number so we know which PR to comment on
|
||||
- name: Save PR number
|
||||
run: |
|
||||
echo ${{ github.event.pull_request.number }} | tee pr_number.txt
|
||||
- name: Upload PR number
|
||||
if:
|
||||
startsWith(steps.python.outputs.python-version, '3.10') && matrix.batchIdx ==
|
||||
0
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
with:
|
||||
name: pr_number
|
||||
path: pr_number.txt
|
||||
@ -1,80 +0,0 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
|
||||
env:
|
||||
DEFAULT_PYTHON: "3.13"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build release assets
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'release'
|
||||
steps:
|
||||
- name: Check out code from Github
|
||||
uses: actions/checkout@v5.0.0
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v6.0.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Install requirements
|
||||
run: |
|
||||
# Remove dist, build, and pylint.egg-info
|
||||
# when building locally for testing!
|
||||
python -m pip install build
|
||||
- name: Build distributions
|
||||
run: |
|
||||
python -m build
|
||||
- name: Upload release assets
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
with:
|
||||
name: release-assets
|
||||
path: dist/
|
||||
|
||||
release-pypi:
|
||||
name: Upload release to PyPI
|
||||
runs-on: ubuntu-latest
|
||||
needs: ["build"]
|
||||
environment:
|
||||
name: PyPI
|
||||
url: https://pypi.org/project/pylint/
|
||||
permissions:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Download release assets
|
||||
uses: actions/download-artifact@v5.0.0
|
||||
with:
|
||||
name: release-assets
|
||||
path: dist/
|
||||
- name: Upload to PyPI
|
||||
if: github.event_name == 'release'
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
|
||||
release-github:
|
||||
name: Upload assets to Github release
|
||||
runs-on: ubuntu-latest
|
||||
needs: ["build"]
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Download release assets
|
||||
uses: actions/download-artifact@v5.0.0
|
||||
with:
|
||||
name: release-assets
|
||||
path: dist/
|
||||
- name: Sign the dists with Sigstore and upload assets to Github release
|
||||
if: github.event_name == 'release'
|
||||
uses: sigstore/gh-action-sigstore-python@v3.0.1
|
||||
with:
|
||||
inputs: |
|
||||
./dist/*.tar.gz
|
||||
./dist/*.whl
|
||||
@ -1,44 +0,0 @@
|
||||
name: close stale issues and pr
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
close-issues:
|
||||
if: github.repository_owner == 'pylint-dev'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v10
|
||||
with:
|
||||
operations-per-run: 100
|
||||
|
||||
days-before-issue-stale: 28
|
||||
days-before-issue-close: 7
|
||||
any-of-issue-labels:
|
||||
"Waiting on author,Cannot reproduce 🤷,python past end of life,Won't fix/not
|
||||
planned"
|
||||
exempt-issue-labels: "High priority,Blocked 🚧,Needs decision 🔒"
|
||||
stale-issue-message:
|
||||
"This issue is stale because it has been open 4 weeks with no activity.
|
||||
Remove 'Stale' label or comment or this will be closed in a week."
|
||||
close-issue-message:
|
||||
"This issue was closed because it has been stalled for five weeks with no
|
||||
activity."
|
||||
|
||||
any-of-pr-labels:
|
||||
"Waiting on author,python past end of life,Won't fix/not planned"
|
||||
exempt-pr-labels: "High priority,Blocked 🚧,Needs review 🔍"
|
||||
days-before-pr-stale: 56
|
||||
days-before-pr-close: -1
|
||||
stale-pr-label: "Needs take over 🛎️"
|
||||
close-pr-message:
|
||||
"This PR was closed because it needed to be taken over for 16 weeks with no
|
||||
one stepping up."
|
||||
stale-pr-message:
|
||||
"This PR needs take over because because it has been open 8 weeks with no
|
||||
activity."
|
||||
@ -1,208 +0,0 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- "maintenance/**"
|
||||
paths-ignore:
|
||||
- doc/data/messages/**
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- "maintenance/**"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
CACHE_VERSION: 5
|
||||
KEY_PREFIX: venv
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
name: run / ${{ matrix.python-version }} / ${{ matrix.os }}
|
||||
timeout-minutes: 25
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
python-version: &matrix-python-version ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
||||
include:
|
||||
- os: macos-latest
|
||||
python-version: "3.10"
|
||||
- os: ubuntu-latest
|
||||
python-version: "pypy-3.10"
|
||||
- os: ubuntu-latest
|
||||
python-version: "pypy-3.11"
|
||||
runs-on: ${{ matrix.os }}
|
||||
outputs:
|
||||
python-key: ${{ steps.generate-python-key.outputs.key }}
|
||||
steps:
|
||||
- &checkout
|
||||
name: Check out code from GitHub
|
||||
uses: actions/checkout@v5.0.0
|
||||
- &setup-python
|
||||
name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@v6.0.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
allow-prereleases: true
|
||||
check-latest: true
|
||||
- name: Generate partial Python venv restore key
|
||||
id: generate-python-key
|
||||
run: >-
|
||||
echo "key=${{ env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{
|
||||
hashFiles('pyproject.toml', 'requirements_test.txt',
|
||||
'requirements_test_min.txt', 'requirements_test_pre_commit.txt') }}" >>
|
||||
$GITHUB_OUTPUT
|
||||
- &cache-python
|
||||
name: Restore Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@v4.3.0
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||
steps.generate-python-key.outputs.key }}
|
||||
- name: Create Python virtual environment
|
||||
if: steps.cache-venv.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
python -m venv venv
|
||||
. venv/bin/activate
|
||||
python -m pip install --upgrade pip
|
||||
pip install --upgrade --requirement requirements_test.txt
|
||||
- name: Run pytest
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
pip install . --no-deps
|
||||
pip list | grep 'astroid\|pylint'
|
||||
python -m pytest --durations=10 --benchmark-disable --cov --cov-report= tests/
|
||||
- name: Run functional tests with minimal messages config
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
pip list | grep 'astroid\|pylint'
|
||||
python -m pytest -vv --minimal-messages-config tests/test_functional.py --benchmark-disable
|
||||
- name: Upload coverage artifact
|
||||
if: runner.os == 'Linux'
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
with:
|
||||
name: coverage-${{ matrix.python-version }}
|
||||
include-hidden-files: true
|
||||
path: .coverage
|
||||
|
||||
coverage:
|
||||
name: process / coverage
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
needs: [tests]
|
||||
steps:
|
||||
- *checkout
|
||||
- name: Set up Python 3.13
|
||||
id: python
|
||||
uses: actions/setup-python@v6.0.0
|
||||
with:
|
||||
python-version: "3.13"
|
||||
check-latest: true
|
||||
- &cache-restore-python
|
||||
name: Restore Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v4.3.0
|
||||
with:
|
||||
path: venv
|
||||
fail-on-cache-miss: true
|
||||
key:
|
||||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||
needs.tests.outputs.python-key }}
|
||||
- name: Download all coverage artifacts
|
||||
uses: actions/download-artifact@v5.0.0
|
||||
- name: Combine coverage results
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
coverage combine coverage*/.coverage
|
||||
coverage xml
|
||||
- uses: codecov/codecov-action@v5
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
fail_ci_if_error: true
|
||||
verbose: true
|
||||
|
||||
benchmark-linux:
|
||||
name: run benchmark / ${{ matrix.python-version }} / Linux
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
needs: [tests]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ["3.13"]
|
||||
steps:
|
||||
- *checkout
|
||||
- *setup-python
|
||||
- *cache-restore-python
|
||||
- name: Run pytest
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
pip install pygal
|
||||
pip install . --no-deps
|
||||
pip list | grep 'astroid\|pylint'
|
||||
pytest --exitfirst \
|
||||
--benchmark-only \
|
||||
--benchmark-autosave \
|
||||
--benchmark-save-data \
|
||||
--benchmark-group-by="group"
|
||||
- name: Create partial artifact name suffix
|
||||
id: artifact-name-suffix
|
||||
run: >-
|
||||
echo "datetime="$(date "+%Y%m%d_%H%M") >> $GITHUB_OUTPUT
|
||||
- name: Upload benchmark artifact
|
||||
uses: actions/upload-artifact@v4.6.2
|
||||
with:
|
||||
name:
|
||||
benchmark-${{ runner.os }}-${{ matrix.python-version }}_${{
|
||||
steps.artifact-name-suffix.outputs.datetime }}
|
||||
include-hidden-files: true
|
||||
path: .benchmarks/
|
||||
|
||||
tests-windows:
|
||||
name: run / ${{ matrix.python-version }} / Windows
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 25
|
||||
needs: [tests]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: *matrix-python-version
|
||||
steps:
|
||||
- name: Set temp directory
|
||||
run: echo "TEMP=$env:USERPROFILE\AppData\Local\Temp" >> $env:GITHUB_ENV
|
||||
# Workaround to set correct temp directory on Windows
|
||||
# https://github.com/actions/virtual-environments/issues/712
|
||||
- *checkout
|
||||
- *setup-python
|
||||
- name: Generate partial Python venv restore key
|
||||
id: generate-python-key
|
||||
run: >-
|
||||
echo "key=venv-${{ env.CACHE_VERSION }}-${{
|
||||
hashFiles('pyproject.toml', 'requirements_test_min.txt')
|
||||
}}" >> $env:GITHUB_OUTPUT
|
||||
- *cache-python
|
||||
- name: Create Python virtual environment
|
||||
if: steps.cache-venv.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
python -m venv venv
|
||||
. venv\\Scripts\\activate
|
||||
python -m pip install --upgrade pip
|
||||
pip install --upgrade --requirement requirements_test_min.txt
|
||||
- name: Run pytest
|
||||
run: |
|
||||
. venv\\Scripts\\activate
|
||||
pip install . --no-deps
|
||||
pip list | grep 'astroid\|pylint'
|
||||
python -m pytest --durations=10 --benchmark-disable tests/
|
||||
@ -1,29 +0,0 @@
|
||||
# Do not add entries specific to your dev environment or development
|
||||
# preferences in this file. You can use the global .gitignore for that:
|
||||
# git config --global core.excludesFile '~/.gitignore'
|
||||
/log
|
||||
*.py[cod]
|
||||
/build
|
||||
/doc/_build
|
||||
/dist/
|
||||
/pylint.egg-info/
|
||||
.tox
|
||||
*.sw[a-z]
|
||||
# Can't use | operator in .gitignore, see
|
||||
# https://unix.stackexchange.com/a/31806/189111
|
||||
doc/user_guide/messages/convention/
|
||||
doc/user_guide/messages/error/
|
||||
doc/user_guide/messages/fatal/
|
||||
doc/user_guide/messages/information/
|
||||
doc/user_guide/messages/refactor/
|
||||
doc/user_guide/messages/warning/
|
||||
tests/.pylint_primer_tests/
|
||||
pyve
|
||||
build-stamp
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache/
|
||||
.eggs/
|
||||
.pytest_cache/
|
||||
.mypy_cache/
|
||||
.benchmarks/
|
||||
@ -1,174 +0,0 @@
|
||||
ci:
|
||||
skip: [pylint]
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v6.0.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
exclude: tests(/\w*)*/functional/t/trailing_whitespaces.py|tests/pyreverse/data/.*.html|doc/data/messages/t/trailing-whitespace/bad.py
|
||||
# - id: file-contents-sorter # commented out because it does not preserve comments order
|
||||
# args: ["--ignore-case", "--unique"]
|
||||
# files: "custom_dict.txt"
|
||||
- id: end-of-file-fixer
|
||||
exclude: |
|
||||
(?x)^(
|
||||
tests(/\w*)*/functional/m/missing/missing_final_newline.py|
|
||||
tests/functional/t/trailing_newlines.py|
|
||||
doc/data/messages/t/trailing-newlines/bad.py|
|
||||
doc/data/messages/m/missing-final-newline/bad/lf.py|
|
||||
doc/data/messages/m/missing-final-newline/bad/crlf.py
|
||||
)$
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: "v0.14.0"
|
||||
hooks:
|
||||
- id: ruff-check
|
||||
args: ["--fix"]
|
||||
exclude: doc/data/messages
|
||||
- id: ruff-check
|
||||
name: ruff-doc
|
||||
files: doc/data/messages
|
||||
# Please exclude using doc/data/ruff.toml
|
||||
# exclude: "" # Leave empty
|
||||
- repo: https://github.com/Pierre-Sassoulas/copyright_notice_precommit
|
||||
rev: 0.1.2
|
||||
hooks:
|
||||
- id: copyright-notice
|
||||
args: ["--notice=script/copyright.txt", "--enforce-all"]
|
||||
exclude: tests(/\w*)*/functional/|tests/input|doc/data/messages|examples/|setup.py|tests(/\w*)*data/
|
||||
types: [python]
|
||||
- repo: https://github.com/PyCQA/isort
|
||||
rev: 7.0.0
|
||||
hooks:
|
||||
- id: isort
|
||||
exclude: doc/data/messages/
|
||||
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||
rev: 25.9.0
|
||||
hooks:
|
||||
- id: black
|
||||
args: [--safe, --quiet]
|
||||
exclude: &fixtures tests(/\w*)*/functional/|tests/input|doc/data/messages|tests(/\w*)*data/
|
||||
- id: black
|
||||
name: black-doc
|
||||
args: [--safe, --quiet]
|
||||
files: doc/data/messages/
|
||||
exclude: |
|
||||
(?x)^(
|
||||
doc/data/messages/b/bad-indentation/bad.py|
|
||||
doc/data/messages/i/inconsistent-quotes/bad.py|
|
||||
doc/data/messages/i/invalid-format-index/bad.py|
|
||||
doc/data/messages/l/line-too-long/bad.py|
|
||||
doc/data/messages/m/missing-final-newline/bad/crlf.py|
|
||||
doc/data/messages/m/missing-final-newline/bad/lf.py|
|
||||
doc/data/messages/m/multiple-statements/bad.py|
|
||||
doc/data/messages/r/redundant-u-string-prefix/bad.py|
|
||||
doc/data/messages/s/superfluous-parens/bad/example_1.py|
|
||||
doc/data/messages/s/syntax-error/bad.py|
|
||||
doc/data/messages/t/too-many-ancestors/bad.py|
|
||||
doc/data/messages/t/trailing-comma-tuple/bad.py|
|
||||
doc/data/messages/t/trailing-newlines/bad.py|
|
||||
doc/data/messages/t/trailing-whitespace/bad.py|
|
||||
doc/data/messages/u/unnecessary-semicolon/bad.py
|
||||
)$
|
||||
- repo: https://github.com/Pierre-Sassoulas/black-disable-checker
|
||||
rev: v1.1.3
|
||||
hooks:
|
||||
- id: black-disable-checker
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: pylint
|
||||
name: pylint
|
||||
entry: pylint
|
||||
language: system
|
||||
types: [python]
|
||||
# Not that problematic to run in parallel see Pre-commit
|
||||
# integration in the doc for details
|
||||
# require_serial: true
|
||||
args: ["-rn", "-sn", "--rcfile=pylintrc", "--fail-on=I"]
|
||||
exclude: tests(/\w*)*/functional/|tests/input|tests(/\w*)*data/|doc/
|
||||
- id: pyright
|
||||
name: pyright
|
||||
description: "Python command line wrapper for pyright, a static type checker"
|
||||
entry: pyright
|
||||
language: python
|
||||
"types_or": [python, pyi]
|
||||
require_serial: true
|
||||
minimum_pre_commit_version: "2.9.2"
|
||||
exclude: tests(/\w*)*/functional/|tests/input|tests(/.*)+/conftest.py|doc/data/messages|tests(/\w*)*data/
|
||||
stages: [manual]
|
||||
# We define an additional manual step to allow running pylint with a spelling
|
||||
# checker in CI.
|
||||
- id: pylint
|
||||
alias: pylint-with-spelling
|
||||
name: pylint
|
||||
entry: pylint
|
||||
language: system
|
||||
types: [python]
|
||||
args:
|
||||
[
|
||||
"-rn",
|
||||
"-sn",
|
||||
"--rcfile=pylintrc",
|
||||
"--fail-on=I",
|
||||
"--spelling-dict=en",
|
||||
"--output-format=github",
|
||||
]
|
||||
exclude: tests(/\w*)*/functional/|tests/input|tests(/\w*)*data/|doc/
|
||||
stages: [manual]
|
||||
- id: check-newsfragments
|
||||
name: Check newsfragments
|
||||
entry: python3 -m script.check_newsfragments
|
||||
language: system
|
||||
types: [text]
|
||||
files: ^(doc/whatsnew/fragments)
|
||||
exclude: doc/whatsnew/fragments/_.*.rst
|
||||
- repo: https://github.com/rstcheck/rstcheck
|
||||
rev: "v6.2.5"
|
||||
hooks:
|
||||
- id: rstcheck
|
||||
args: ["--report-level=warning"]
|
||||
files: ^(doc/(.*/)*.*\.rst)
|
||||
additional_dependencies: ["Sphinx==7.4.3"]
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.18.2
|
||||
hooks:
|
||||
- id: mypy
|
||||
name: mypy
|
||||
args: []
|
||||
additional_dependencies:
|
||||
["isort>=5", "platformdirs==2.2.0", "py==1.11", "tomlkit>=0.10.1"]
|
||||
exclude: tests(/\w*)*/functional/|tests/input|tests(/.*)+/conftest.py|doc/data/messages|tests(/\w*)*data/
|
||||
- repo: https://github.com/rbubley/mirrors-prettier
|
||||
rev: v3.6.2
|
||||
hooks:
|
||||
- id: prettier
|
||||
args: [--prose-wrap=always, --print-width=88]
|
||||
exclude: (tests(/\w*)*data/|.github/FUNDING.yml)
|
||||
- repo: https://github.com/DanielNoord/pydocstringformatter
|
||||
rev: v0.7.5
|
||||
hooks:
|
||||
- id: pydocstringformatter
|
||||
exclude: *fixtures
|
||||
args: ["--max-summary-lines=2", "--linewrap-full-docstring"]
|
||||
files: "pylint"
|
||||
- repo: https://github.com/PyCQA/bandit
|
||||
rev: 1.8.6
|
||||
hooks:
|
||||
- id: bandit
|
||||
args: ["-r", "-lll"]
|
||||
exclude: *fixtures
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.4.1
|
||||
hooks:
|
||||
- id: codespell
|
||||
args: ["--toml=pyproject.toml"]
|
||||
additional_dependencies:
|
||||
- tomli
|
||||
- repo: https://github.com/tox-dev/pyproject-fmt
|
||||
rev: "v2.10.0"
|
||||
hooks:
|
||||
- id: pyproject-fmt
|
||||
- repo: https://github.com/abravalheri/validate-pyproject
|
||||
rev: v0.24.1
|
||||
hooks:
|
||||
- id: validate-pyproject
|
||||
@ -1,6 +0,0 @@
|
||||
- id: pylint
|
||||
name: pylint
|
||||
entry: pylint
|
||||
language: python
|
||||
types: [python]
|
||||
require_serial: true
|
||||
@ -1,19 +0,0 @@
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
version: 2
|
||||
|
||||
sphinx:
|
||||
fail_on_warning: true
|
||||
configuration: doc/conf.py
|
||||
|
||||
python:
|
||||
install:
|
||||
- requirements: doc/readthedoc_requirements.txt
|
||||
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.11"
|
||||
jobs:
|
||||
pre_build:
|
||||
- towncrier build --yes --date TBA
|
||||
@ -1,14 +0,0 @@
|
||||
cff-version: 1.2.0
|
||||
title: "Pylint"
|
||||
message: >-
|
||||
If you use this software, please cite it using the metadata from this file.
|
||||
type: software
|
||||
authors:
|
||||
- name: "Pylint contributors"
|
||||
repository-code: "https://github.com/pylint-dev/pylint"
|
||||
url: "https://pylint.readthedocs.io/en/latest/"
|
||||
abstract: >-
|
||||
Pylint is a static code analyser for Python 2 or 3. Pylint analyses your code without
|
||||
actually running it. It checks for errors, enforces a coding standard, looks for code
|
||||
smells, and can make suggestions about how the code could be refactored.
|
||||
license: GPL-2.0
|
||||
@ -1,120 +0,0 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our community a
|
||||
harassment-free experience for everyone, regardless of age, body size, visible or
|
||||
invisible disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal appearance,
|
||||
race, religion, or sexual identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming, diverse,
|
||||
inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our community
|
||||
include:
|
||||
|
||||
- Demonstrating empathy and kindness toward other people
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our mistakes, and
|
||||
learning from the experience
|
||||
- Focusing on what is best not just for us as individuals, but for the overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
- The use of sexualized language or imagery, and sexual attention or advances of any
|
||||
kind
|
||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or email address, without
|
||||
their explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a professional
|
||||
setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in response to
|
||||
any behavior that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject comments,
|
||||
commits, code, wiki edits, issues, and other contributions that are not aligned to this
|
||||
Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when an
|
||||
individual is officially representing the community in public spaces. Examples of
|
||||
representing our community include using an official e-mail address, posting via an
|
||||
official social media account, or acting as an appointed representative at an online or
|
||||
offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to
|
||||
the community leaders responsible for enforcement at pierre.sassoulas at gmail.com. All
|
||||
complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the reporter
|
||||
of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining the
|
||||
consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing clarity
|
||||
around the nature of the violation and an explanation of why the behavior was
|
||||
inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No interaction with
|
||||
the people involved, including unsolicited interaction with those enforcing the Code of
|
||||
Conduct, for a specified period of time. This includes avoiding interactions in
|
||||
community spaces as well as external channels like social media. Violating these terms
|
||||
may lead to a temporary or permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including sustained
|
||||
inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public communication
|
||||
with the community for a specified period of time. No public or private interaction with
|
||||
the people involved, including unsolicited interaction with those enforcing the Code of
|
||||
Conduct, is allowed during this period. Violating these terms may lead to a permanent
|
||||
ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community standards,
|
||||
including sustained inappropriate behavior, harassment of an individual, or aggression
|
||||
toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the
|
||||
community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
|
||||
available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by
|
||||
[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
@ -1,699 +0,0 @@
|
||||
# This file is autocompleted by 'contributors-txt',
|
||||
# using the configuration in 'script/.contributors_aliases.json'.
|
||||
# Do not add new persons manually and only add information without
|
||||
# using '-' as the line first character.
|
||||
# Please verify that your change are stable if you modify manually.
|
||||
|
||||
Ex-maintainers
|
||||
--------------
|
||||
- Claudiu Popa <pcmanticore@gmail.com>
|
||||
- Sylvain Thénault <thenault@gmail.com> : main author / maintainer
|
||||
- Torsten Marek <shlomme@gmail.com>
|
||||
|
||||
|
||||
Maintainers
|
||||
-----------
|
||||
- Pierre Sassoulas <pierre.sassoulas@gmail.com>
|
||||
- Daniël van Noord <13665637+DanielNoord@users.noreply.github.com>
|
||||
- Jacob Walls <jacobtylerwalls@gmail.com>
|
||||
- Marc Mueller <30130371+cdce8p@users.noreply.github.com>
|
||||
- Hippo91 <guillaume.peillex@gmail.com>
|
||||
- Mark Byrne <31762852+mbyrnepr2@users.noreply.github.com>
|
||||
- Andreas Finkler <3929834+DudeNr33@users.noreply.github.com>
|
||||
- Matus Valo <matusvalo@users.noreply.github.com>
|
||||
- Dani Alcala <112832187+clavedeluna@users.noreply.github.com>
|
||||
- Łukasz Rogalski <rogalski.91@gmail.com>
|
||||
- Nick Drozd <nicholasdrozd@gmail.com>: performance improvements to astroid
|
||||
- Ashley Whetter <ashley@awhetter.co.uk>
|
||||
- Bryce Guinta <bryce.paul.guinta@gmail.com>
|
||||
- Yu Shao, Pang <36848472+yushao2@users.noreply.github.com>
|
||||
- Dimitri Prybysh <dmand@yandex.ru>
|
||||
* multiple-imports, not-iterable, not-a-mapping, various patches.
|
||||
- Roy Williams <roy.williams.iii@gmail.com> (Lyft)
|
||||
* added check for implementing __eq__ without implementing __hash__,
|
||||
* Added Python 3 check for accessing Exception.message.
|
||||
* Added Python 3 check for calling encode/decode with invalid codecs.
|
||||
* Added Python 3 check for accessing sys.maxint.
|
||||
* Added Python 3 check for bad import statements.
|
||||
* Added Python 3 check for accessing deprecated methods on the 'string' module,
|
||||
various patches.
|
||||
- Florian Bruhin <me@the-compiler.org>
|
||||
- Arianna Yang <areveny@protonmail.com>
|
||||
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
We would not be here without folks that contributed patches, pull requests,
|
||||
issues and their time to pylint. We're incredibly grateful to all of these
|
||||
contributors:
|
||||
|
||||
- Emile Anclin <emile.anclin@logilab.fr> (Logilab): python 3 support
|
||||
- Michal Nowikowski <godfryd@gmail.com>:
|
||||
* wrong-spelling-in-comment
|
||||
* wrong-spelling-in-docstring
|
||||
* parallel execution on multiple CPUs
|
||||
- Julthep Nandakwang <julthep@nandakwang.com>
|
||||
- Bruno Daniel <bruno.daniel@blue-yonder.com>: check_docs extension.
|
||||
- Sushobhit <31987769+sushobhit27@users.noreply.github.com> (sushobhit27)
|
||||
* Added new check 'comparison-with-itself'.
|
||||
* Added new check 'useless-import-alias'.
|
||||
* Added support of annotations in missing-type-doc and missing-return-type-doc.
|
||||
* Added new check 'comparison-with-callable'.
|
||||
* Removed six package dependency.
|
||||
* Added new check 'chained-comparison'.
|
||||
* Added new check 'useless-object-inheritance'.
|
||||
- Brett Cannon <brett@python.org>:
|
||||
* Port source code to be Python 2/3 compatible
|
||||
* Python 3 checker
|
||||
- Laura Médioni <laura.medioni@logilab.fr> (Logilab, on behalf of the CNES):
|
||||
* misplaced-comparison-constant
|
||||
* no-classmethod-decorator
|
||||
* no-staticmethod-decorator
|
||||
* too-many-nested-blocks,
|
||||
* too-many-boolean-expressions
|
||||
* unneeded-not
|
||||
* wrong-import-order
|
||||
* ungrouped-imports,
|
||||
* wrong-import-position
|
||||
* redefined-variable-type
|
||||
- Harutaka Kawamura <hkawamura0130@gmail.com>
|
||||
- Alexandre Fayolle <alexandre.fayolle@logilab.fr> (Logilab): TkInter gui, documentation, debian support
|
||||
- Ville Skyttä <ville.skytta@iki.fi>
|
||||
- Zen Lee <53538590+zenlyj@users.noreply.github.com>
|
||||
- Julien Cristau <julien.cristau@logilab.fr> (Logilab): python 3 support
|
||||
- Moisés López <6644187+moylop260@users.noreply.github.com>:
|
||||
* Support for deprecated-modules in modules not installed,
|
||||
* Refactor wrong-import-order to integrate it with `isort` library
|
||||
* Add check too-complex with mccabe for cyclomatic complexity
|
||||
* Refactor wrong-import-position to skip try-import and nested cases
|
||||
* Add consider-merging-isinstance, superfluous-else-return
|
||||
* Fix consider-using-ternary for 'True and True and True or True' case
|
||||
* Add bad-docstring-quotes and docstring-first-line-empty
|
||||
* Add missing-timeout
|
||||
* Fix false negative for `deprecated-module` when a `__import__` method is used instead of `import` sentence
|
||||
- Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
|
||||
- Frank Harrison <frank@doublethefish.com> (doublethefish)
|
||||
- Pierre-Yves David <pierre-yves.david@logilab.fr>
|
||||
- David Shea <dshea@redhat.com>: invalid sequence and slice index
|
||||
- Gunung P. Wibisono <55311527+gunungpw@users.noreply.github.com>
|
||||
- Derek Gustafson <degustaf@gmail.com>
|
||||
- Cezar Elnazli <cezar.elnazli2@gmail.com>: deprecated-method
|
||||
- Joseph Young <80432516+jpy-git@users.noreply.github.com> (jpy-git)
|
||||
- Tim Martin <tim@asymptotic.co.uk>
|
||||
- Ollie <46904826+ollie-iterators@users.noreply.github.com>
|
||||
- Julian Grimm <51880314+Julfried@users.noreply.github.com>
|
||||
- Tushar Sadhwani <tushar.sadhwani000@gmail.com> (tusharsadhwani)
|
||||
- Nicolas Chauvat <nicolas.chauvat@logilab.fr>
|
||||
- orSolocate <38433858+orSolocate@users.noreply.github.com>
|
||||
- Radu Ciorba <radu@devrandom.ro>: not-context-manager and confusing-with-statement warnings.
|
||||
- Holger Peters <email@holger-peters.de>
|
||||
- Cosmin Poieană <cmin@ropython.org>: unichr-builtin and improvements to bad-open-mode.
|
||||
- Yilei "Dolee" Yang <yileiyang@google.com>
|
||||
- Steven Myint <hg@stevenmyint.com>: duplicate-except.
|
||||
- Peter Kolbus <peter.kolbus@gmail.com> (Garmin)
|
||||
- Luigi Bertaco Cristofolini <lucristofolini@gmail.com> (luigibertaco)
|
||||
- Glenn Matthews <glenn@e-dad.net>:
|
||||
* autogenerated documentation for optional extensions,
|
||||
* bug fixes and enhancements for docparams (née check_docs) extension
|
||||
- crazybolillo <antonio@zoftko.com>
|
||||
- correctmost <134317971+correctmost@users.noreply.github.com>
|
||||
- Vlad Temian <vladtemian@gmail.com>: redundant-unittest-assert and the JSON reporter.
|
||||
- Julien Jehannet <julien.jehannet@logilab.fr>
|
||||
- Boris Feld <lothiraldan@gmail.com>
|
||||
- Anthony Sottile <asottile@umich.edu>
|
||||
- Andrew Haigh <nelfin@gmail.com> (nelfin)
|
||||
- Robert Hofer <hofrob@protonmail.com>
|
||||
- Pedro Algarvio <pedro@algarvio.me> (s0undt3ch)
|
||||
- Julien Palard <julien@palard.fr>
|
||||
- Hugo van Kemenade <hugovk@users.noreply.github.com>
|
||||
- David Liu <david@cs.toronto.edu> (david-yz-liu)
|
||||
- Dan Goldsmith <djgoldsmith@googlemail.com>: support for msg-template in HTML reporter.
|
||||
- Buck Evan <buck.2019@gmail.com>
|
||||
- Mariatta Wijaya <Mariatta@users.noreply.github.com>
|
||||
* Added new check `logging-fstring-interpolation`
|
||||
* Documentation typo fixes
|
||||
- Jakub Wilk <jwilk@jwilk.net>
|
||||
- Eli Fine <ejfine@gmail.com> (eli88fine): Fixed false positive duplicate code warning for lines with symbols only
|
||||
- Émile Crater <emile@crater.logilab.fr>
|
||||
- Pavel Roskin <proski@gnu.org>
|
||||
- David Gilman <davidgilman1@gmail.com>
|
||||
- へーさん <hira9603859504@gmail.com>
|
||||
- Thomas Hisch <t.hisch@gmail.com>
|
||||
- Marianna Polatoglou <mpolatoglou@bloomberg.net>: minor contribution for wildcard import check
|
||||
- Manuel Vázquez Acosta <mva.led@gmail.com>
|
||||
- Luis Escobar <lescobar@vauxoo.com> (Vauxoo): Add bad-docstring-quotes and docstring-first-line-empty
|
||||
- Lucas Cimon <lucas.cimon@gmail.com>
|
||||
- Konstantina Saketou <56515303+ksaketou@users.noreply.github.com>
|
||||
- Konstantin <Github@pheanex.de>
|
||||
- Jim Robertson <jrobertson98atx@gmail.com>
|
||||
- Ethan Leba <ethanleba5@gmail.com>
|
||||
- Enji Cooper <yaneurabeya@gmail.com>
|
||||
- Drum Ogilvie <me@daogilvie.com>
|
||||
- David Lindquist <dlindquist@google.com>: logging-format-interpolation warning.
|
||||
- Daniel Harding <dharding@gmail.com>
|
||||
- Anthony Truchet <anthony.truchet@logilab.fr>
|
||||
- Alexander Todorov <atodorov@otb.bg>:
|
||||
* added new error conditions to 'bad-super-call',
|
||||
* Added new check for incorrect len(SEQUENCE) usage,
|
||||
* Added new extension for comparison against empty string constants,
|
||||
* Added new extension which detects comparing integers to zero,
|
||||
* Added new useless-return checker,
|
||||
* Added new try-except-raise checker
|
||||
- theirix <theirix@gmail.com>
|
||||
- Téo Bouvard <teobouvard@gmail.com>
|
||||
- Sviatoslav Sydorenko <sviat@redhat.com>
|
||||
- Stavros Ntentos <133706+stdedos@users.noreply.github.com>
|
||||
- Nicolas Boulenguez <nicolas@debian.org>
|
||||
- Mihai Balint <balint.mihai@gmail.com>
|
||||
- Mark Bell <mark00bell@googlemail.com>
|
||||
- Levi Gruspe <mail.levig@gmail.com>
|
||||
- Jakub Kuczys <me@jacken.men>
|
||||
- Hornwitser <github@hornwitser.no>: fix import graph
|
||||
- Fureigh <rhys.fureigh@gsa.gov>
|
||||
- David Douard <david.douard@sdfa3.org>
|
||||
- Daniel Balparda <balparda@google.com> (Google): GPyLint maintainer (Google's pylint variant)
|
||||
- Christian Clauss <cclauss@me.com>
|
||||
- Bastien Vallet <bastien.vallet@gmail.com> (Djailla)
|
||||
- Aru Sahni <arusahni@gmail.com>: Git ignoring, regex-based ignores
|
||||
- Andreas Freimuth <andreas.freimuth@united-bits.de>: fix indentation checking with tabs
|
||||
- Alexandru Coman <fcoman@bitdefender.com>
|
||||
- jpkotta <jpkotta@gmail.com>
|
||||
- Thomas Grainger <tagrain@gmail.com>
|
||||
- Takahide Nojima <nozzy123nozzy@gmail.com>
|
||||
- Taewon D. Kim <kimt33@mcmaster.ca>
|
||||
- Sneaky Pete <sneakypete81@gmail.com>
|
||||
- Sergey B Kirpichev <skirpichev@gmail.com>
|
||||
- Sandro Tosi <sandro.tosi@gmail.com>: Debian packaging
|
||||
- Rogdham <contact@rogdham.net>
|
||||
- Rene Zhang <rz99@cornell.edu>
|
||||
- Paul Lichtenberger <paul.lichtenberger.rgbg@gmail.com>
|
||||
- Or Bahari <or.ba402@gmail.com>
|
||||
- Mr. Senko <atodorov@mrsenko.com>
|
||||
- Mike Frysinger <vapier@gmail.com>
|
||||
- Martin von Gagern <gagern@google.com> (Google): Added 'raising-format-tuple' warning.
|
||||
- Martin Vielsmaier <martin@vielsmaier.net>
|
||||
- Martin Pool <mbp@google.com> (Google):
|
||||
* warnings for anomalous backslashes
|
||||
* symbolic names for messages (like 'unused')
|
||||
* etc.
|
||||
- Martin Bašti <MartinBasti@users.noreply.github.com>
|
||||
* Added new check for shallow copy of os.environ
|
||||
* Added new check for useless `with threading.Lock():` statement
|
||||
- Marcus Näslund <naslundx@gmail.com> (naslundx)
|
||||
- Marco Pernigotti <7657251+mpernigo@users.noreply.github.com>
|
||||
- Marco Forte <fortemarco.irl@gmail.com>
|
||||
- James Addison <55152140+jayaddison@users.noreply.github.com>
|
||||
- Ionel Maries Cristian <contact@ionelmc.ro>
|
||||
- Gergely Kalmár <gergely.kalmar@logikal.jp>
|
||||
- Damien Baty <damien.baty@polyconseil.fr>
|
||||
- Benjamin Drung <benjamin.drung@profitbricks.com>: contributing Debian Developer
|
||||
- Anubhav <35621759+anubh-v@users.noreply.github.com>
|
||||
- Antonio Quarta <sgheppy88@gmail.com>
|
||||
- Andrew J. Simmons <anjsimmo@gmail.com>
|
||||
- Alvaro Frias <alvarofriasgaray@gmail.com>
|
||||
- Alexey Pelykh <alexey.pelykh@gmail.com>
|
||||
- Alex Prabhat Bara <alexpbara@gmail.com>
|
||||
- wtracy <afishionado@gmail.com>
|
||||
- jessebrennan <jesse@jesse.computer>
|
||||
- chohner <mail@chohner.com>
|
||||
- aatle <168398276+aatle@users.noreply.github.com>
|
||||
- Tiago Honorato <61059243+tiagohonorato@users.noreply.github.com>
|
||||
- Steven M. Vascellaro <svascellaro@gmail.com>
|
||||
- Robin Tweedie <70587124+robin-wayve@users.noreply.github.com>
|
||||
- Roberto Leinardi <leinardi@gmail.com>: PyCharm plugin maintainer
|
||||
- Ricardo Gemignani <ricardo.gemignani@gmail.com>
|
||||
- Piotr Idzik <65706193+vil02@users.noreply.github.com>
|
||||
- Pieter Engelbrecht <pengelbrecht@rems2.com>
|
||||
- Philipp Albrecht <flying-sheep@web.de> (pylbrecht)
|
||||
- Nicolas Dickreuter <dickreuter@gmail.com>
|
||||
- Nick Bastin <nick.bastin@gmail.com>
|
||||
- Nathaniel Manista <nathaniel@google.com>: suspicious lambda checking
|
||||
- Maksym Humetskyi <Humetsky@gmail.com> (mhumetskyi)
|
||||
* Fixed ignored empty functions by similarities checker with "ignore-signatures" option enabled
|
||||
* Ignore function decorators signatures as well by similarities checker with "ignore-signatures" option enabled
|
||||
* Ignore class methods and nested functions signatures as well by similarities checker with "ignore-signatures" option enabled
|
||||
- Kylian <development@goudcode.nl>
|
||||
- Konstantin Manna <Konstantin@Manna.uno>
|
||||
- Kai Mueller <15907922+kasium@users.noreply.github.com>
|
||||
- Joshua Cannon <joshdcannon@gmail.com>
|
||||
- John Leach <jfleach@jfleach.com>
|
||||
- James Morgensen <james.morgensen@gmail.com>: ignored-modules option applies to import errors.
|
||||
- Jaehoon Hwang <jaehoonhwang@users.noreply.github.com> (jaehoonhwang)
|
||||
- Huw Jones <huw@huwcbjones.co.uk>
|
||||
- Gideon <87426140+GideonBear@users.noreply.github.com>
|
||||
- Ganden Schaffner <gschaffner@pm.me>
|
||||
- Frost Ming <frostming@tencent.com>
|
||||
- Federico Bond <federicobond@gmail.com>
|
||||
- Erik Wright <erik.wright@shopify.com>
|
||||
- Erik Eriksson <molobrakos@users.noreply.github.com>: Added overlapping-except error check.
|
||||
- Emmanuel Ferdman <emmanuelferdman@gmail.com>
|
||||
- Dave Bunten <dave.bunten@cuanschutz.edu>
|
||||
- Daniel Wang <danielwang405@gmail.com>
|
||||
- Daniel Mouritzen <dmrtzn@gmail.com>
|
||||
- Dan Hemberger <846186+hemberger@users.noreply.github.com>
|
||||
- Chris Rebert <code@rebertia.com>: unidiomatic-typecheck.
|
||||
- Aurelien Campeas <aurelien.campeas@logilab.fr>
|
||||
- Alexander Pervakov <frost.nzcr4@jagmort.com>
|
||||
- Alain Leufroy <alain.leufroy@logilab.fr>
|
||||
- Akhil Kamat <akhil.kamat@gmail.com>
|
||||
- Adam Williamson <awilliam@redhat.com>
|
||||
- Aaron Liu <aaronliu0130@gmail.com>
|
||||
- xmo-odoo <xmo-odoo@users.noreply.github.com>
|
||||
- tbennett0 <tbennett0@users.noreply.github.com>
|
||||
- purajit <7026198+purajit@users.noreply.github.com>
|
||||
- omarandlorraine <64254276+omarandlorraine@users.noreply.github.com>
|
||||
- craig-sh <craig-sh@users.noreply.github.com>
|
||||
- bernie gray <bfgray3@users.noreply.github.com>
|
||||
- azinneck0485 <123660683+azinneck0485@users.noreply.github.com>
|
||||
- Wing Lian <wing.lian@gmail.com>
|
||||
- Wes Turner <westurner@google.com> (Google): added new check 'inconsistent-quotes'
|
||||
- Tyler Thieding <tyler@thieding.com>
|
||||
- Tobias Hernstig <30827238+thernstig@users.noreply.github.com>
|
||||
- Smixi <sismixx@hotmail.fr>
|
||||
- Simu Toni <simutoni@gmail.com>
|
||||
- Sergei Lebedev <185856+superbobry@users.noreply.github.com>
|
||||
- Scott Worley <scottworley@scottworley.com>
|
||||
- Saugat Pachhai <suagatchhetri@outlook.com>
|
||||
- Samuel FORESTIER <HorlogeSkynet@users.noreply.github.com>
|
||||
- Rémi Cardona <remi.cardona@polyconseil.fr>
|
||||
- Ryan Ozawa <ryan.ozawa21@gmail.com>
|
||||
- Roger Sheu <78449574+rogersheu@users.noreply.github.com>
|
||||
- Raphael Gaschignard <raphael@makeleaps.com>
|
||||
- Ram Rachum <ram@rachum.com> (cool-RR)
|
||||
- Radostin Stoyanov <rst0git@users.noreply.github.com>
|
||||
- Peter Bittner <django@bittner.it>
|
||||
- Paul Renvoisé <PaulRenvoise@users.noreply.github.com>
|
||||
- PHeanEX <github@pheanex.de>
|
||||
- Omega Weapon <OmegaPhil+hg@gmail.com>
|
||||
- Nikolai Kristiansen <nikolaik@gmail.com>
|
||||
- Nick Pesce <nickpesce22@gmail.com>
|
||||
- Nedelcu Ioan-Andrei <138256980+nedelcu-ioan@users.noreply.github.com>
|
||||
- Nathan Marrow <nmarrow@google.com>
|
||||
- Mikhail Fesenko <m.fesenko@corp.vk.com>
|
||||
- Matthew Suozzo <msuozzo@google.com>
|
||||
- Matthew Beckers <17108752+mattlbeck@users.noreply.github.com> (mattlbeck)
|
||||
- Mark Roman Miller <mtmiller@users.noreply.github.com>: fix inline defs in too-many-statements
|
||||
- MalanB <malan.kmu@gmail.com>
|
||||
- Mads Kiilerich <mads@kiilerich.com>
|
||||
- Maarten ter Huurne <maarten@treewalker.org>
|
||||
- Lefteris Karapetsas <lefteris@refu.co>
|
||||
- LCD 47 <lcd047@gmail.com>
|
||||
- Jérome Perrin <perrinjerome@gmail.com>
|
||||
- Justin Li <justinnhli@gmail.com>
|
||||
- John Kirkham <jakirkham@gmail.com>
|
||||
- Jens H. Nielsen <Jens.Nielsen@microsoft.com>
|
||||
- Jake Lishman <jake.lishman@ibm.com>
|
||||
- Ioana Tagirta <ioana.tagirta@gmail.com>: fix bad thread instantiation check
|
||||
- Ikraduya Edian <ikraduya@gmail.com>: Added new checks 'consider-using-generator' and 'use-a-generator'.
|
||||
- Hugues Bruant <hugues.bruant@affirm.com>
|
||||
- Hashem Nasarat <Hnasar@users.noreply.github.com>
|
||||
- Harut <yes@harutune.name>
|
||||
- Grygorii Iermolenko <gyermolenko@gmail.com>
|
||||
- Grizzly Nyo <grizzly.nyo@gmail.com>
|
||||
- Gabriel R. Sezefredo <g@briel.dev>: Fixed "exception-escape" false positive with generators
|
||||
- Filipe Brandenburger <filbranden@google.com>
|
||||
- Fantix King <fantix@uchicago.edu> (UChicago)
|
||||
- Eric McDonald <221418+emcd@users.noreply.github.com>
|
||||
- Elias Dorneles <eliasdorneles@gmail.com>: minor adjust to config defaults and docs
|
||||
- Elazrod56 <thomas.lf5629@gmail.com>
|
||||
- Edward K. Ream <edreamleo@gmail.com>
|
||||
- Derek Harland <derek.harland@finq.co.nz>
|
||||
- David Pursehouse <david.pursehouse@gmail.com>
|
||||
- Daniel Miller <millerdev@gmail.com>
|
||||
- Christoph Blessing <33834216+cblessing24@users.noreply.github.com>
|
||||
- Chris Murray <chris@chrismurray.scot>
|
||||
- Chris Lamb <chris@chris-lamb.co.uk>
|
||||
- Charles Hebert <charles.hebert@logilab.fr>
|
||||
- Carli Freudenberg <carli.freudenberg@energymeteo.de> (CarliJoy)
|
||||
* Fixed issue 5281, added Unicode checker
|
||||
* Improve non-ascii-name checker
|
||||
- Bruce Dawson <randomascii@users.noreply.github.com>
|
||||
- Brian Shaginaw <brian.shaginaw@warbyparker.com>: prevent error on exception check for functions
|
||||
- Benny Mueller <benny.mueller91@gmail.com>
|
||||
- Ben James <benjames1999@hotmail.co.uk>
|
||||
- Ben Green <benhgreen@icloud.com>
|
||||
- Batuhan Taskaya <batuhanosmantaskaya@gmail.com>
|
||||
- Artem Yurchenko <artemyurchenko@zoho.com>
|
||||
- Alexander Kapshuna <kapsh@kap.sh>
|
||||
- Akshay Choudhary <153769403+Akshay9715@users.noreply.github.com>
|
||||
- Adam Parkin <pzelnip@users.noreply.github.com>
|
||||
- 谭九鼎 <109224573@qq.com>
|
||||
- Łukasz Sznuk <ls@rdprojekt.pl>
|
||||
- zasca <gorstav@gmail.com>
|
||||
- y2kbugger <y2kbugger@users.noreply.github.com>
|
||||
- vinnyrose <vinnyrose@users.noreply.github.com>
|
||||
- ttenhoeve-aa <ttenhoeve@appannie.com>
|
||||
- thinwybk <florian.k@mailbox.org>
|
||||
- temyurchenko <44875844+temyurchenko@users.noreply.github.com>
|
||||
- syutbai <syutbai@gmail.com>
|
||||
- sur.la.route <17788706+christopherpickering@users.noreply.github.com>
|
||||
- sdet_liang <liangway@users.noreply.github.com>
|
||||
- pavan-msys <149513767+pavan-msys@users.noreply.github.com>
|
||||
- paschich <millen@gridium.com>
|
||||
- oittaa <8972248+oittaa@users.noreply.github.com>
|
||||
- nyabkun <75878387+nyabkun@users.noreply.github.com>
|
||||
- nhdsd <wyx070906@outlook.com>
|
||||
- moxian <aleftmail@inbox.ru>
|
||||
- mar-chi-pan <mar.polatoglou@gmail.com>
|
||||
- lrjball <50599110+lrjball@users.noreply.github.com>
|
||||
- levon-d <mycroft2003@gmail.com>
|
||||
- laike9m <laike9m@users.noreply.github.com>
|
||||
- kyoto7250 <50972773+kyoto7250@users.noreply.github.com>
|
||||
- kriek <sylvain.ackermann@gmail.com>
|
||||
- kdestin <101366538+kdestin@users.noreply.github.com>
|
||||
- jaydesl <35102795+jaydesl@users.noreply.github.com>
|
||||
- jab <jab@users.noreply.github.com>
|
||||
- gracejiang16 <70730457+gracejiang16@users.noreply.github.com>
|
||||
- glmdgrielson <32415403+glmdgrielson@users.noreply.github.com>
|
||||
- glegoux <gilles.legoux@gmail.com>
|
||||
- gaurikholkar <f2013002@goa.bits-pilani.ac.in>
|
||||
- flyingbot91 <flyingbot91@gmx.com>
|
||||
- fly <fly@users.noreply.github.com>
|
||||
- fahhem <fahhem>
|
||||
- fadedDexofan <fadedDexofan@gmail.com>
|
||||
- epenet <6771947+epenet@users.noreply.github.com>
|
||||
- danields <danields761@gmail.com>
|
||||
- cosven <cosven@users.noreply.github.com>
|
||||
- cordis-dev <darius@adroiti.com>
|
||||
- cherryblossom <31467609+cherryblossom000@users.noreply.github.com>
|
||||
- bluesheeptoken <louis.fruleux1@gmail.com>
|
||||
- anatoly techtonik <techtonik@gmail.com>
|
||||
- amelenty <ada.melentyeva@gmail.com>
|
||||
- akirchhoff-modular <github-work@kirchhoff.digital>
|
||||
- agutole <toldo_carp@hotmail.com>
|
||||
- Zeckie <49095968+Zeckie@users.noreply.github.com>
|
||||
- Zeb Nicholls <zebedee.nicholls@climate-energy-college.org>
|
||||
* Made W9011 compatible with 'of' syntax in return types
|
||||
- Yuval Langer <yuvallanger@mail.tau.ac.il>
|
||||
- Yury Gribov <tetra2005@gmail.com>
|
||||
- Yuri Bochkarev <baltazar.bz@gmail.com>: Added epytext support to docparams extension.
|
||||
- Youngsoo Sung <ysung@bepro11.com>
|
||||
- Yory <39745367+yory8@users.noreply.github.com>
|
||||
- Yoichi Nakayama <yoichi.nakayama@gmail.com>
|
||||
- Yeting Li <liyt@ios.ac.cn> (yetingli)
|
||||
- Yannack <yannack@users.noreply.github.com>
|
||||
- Yann Dirson <ydirson@free.fr>
|
||||
- Yang Yang <y4n9squared@gmail.com>
|
||||
- Xi Shen <davidshen84@gmail.com>
|
||||
- Winston H <56998716+winstxnhdw@users.noreply.github.com>
|
||||
- Will Shanks <wsha@posteo.net>
|
||||
- Viorel Știrbu <viorels@gmail.com>: intern-builtin warning.
|
||||
- VictorT <victor.taix@gmail.com>
|
||||
- Victor Jiajunsu <16359131+jiajunsu@users.noreply.github.com>
|
||||
- ViRuSTriNiTy <cradle-of-mail@gmx.de>
|
||||
- Val Lorentz <progval+github@progval.net>
|
||||
- Ulrich Eckhardt <UlrichEckhardt@users.noreply.github.com>
|
||||
- Udi Fuchs <udifuchs@gmail.com>
|
||||
- Trevor Bekolay <tbekolay@gmail.com>
|
||||
* Added --list-msgs-enabled command
|
||||
- Tomer Chachamu <tomer.chachamu@gmail.com>: simplifiable-if-expression
|
||||
- Tomasz Michalski <tomasz.michalski@rtbhouse.com>
|
||||
- Tomasz Magulski <tomasz@magullab.io>
|
||||
- Tom <tsarantis@proton.me>
|
||||
- Tim Hatch <tim@timhatch.com>
|
||||
- Tim Gates <tim.gates@iress.com>
|
||||
- Tianyu Chen <124018391+UTsweetyfish@users.noreply.github.com>
|
||||
- Théo Battrel <theo.util@protonmail.ch>
|
||||
- Thomas Benhamou <thomas@lightricks.com>
|
||||
- Theodore Ni <3806110+tjni@users.noreply.github.com>
|
||||
- Tanvi Moharir <74228962+tanvimoharir@users.noreply.github.com>: Fix for invalid toml config
|
||||
- T.Rzepka <Tobias.Rzepka@gmail.com>
|
||||
- Svetoslav Neykov <svet@hyperscience.com>
|
||||
- SubaruArai <78188579+SubaruArai@users.noreply.github.com>
|
||||
- Stéphane Wirtel <stephane@wirtel.be>: nonlocal-without-binding
|
||||
- Stephen Longofono <8992396+SLongofono@users.noreply.github.com>
|
||||
- Stephane Odul <1504511+sodul@users.noreply.github.com>
|
||||
- Stanislav Levin <slev@altlinux.org>
|
||||
- Sorin Sbarnea <ssbarnea@redhat.com>
|
||||
- Slavfox <slavfoxman@gmail.com>
|
||||
- Skip Montanaro <skip@pobox.com>
|
||||
- Sigurd Spieckermann <2206639+sisp@users.noreply.github.com>
|
||||
- Shiv Venkatasubrahmanyam <shvenkat@users.noreply.github.com>
|
||||
- Sebastian Müller <mueller.seb@posteo.de>
|
||||
- Sayyed Faisal Ali <80758388+C0DE-SLAYER@users.noreply.github.com>
|
||||
- Sasha Bagan <pnlbagan@gmail.com>
|
||||
- Sardorbek Imomaliev <sardorbek.imomaliev@gmail.com>
|
||||
- Santiago Castro <bryant@montevideo.com.uy>
|
||||
- Samuel Freilich <sfreilich@google.com> (sfreilich)
|
||||
- Sam Vermeiren <88253337+PaaEl@users.noreply.github.com>
|
||||
- Ryan McGuire <ryan@enigmacurry.com>
|
||||
- Ry4an Brase <ry4an-hg@ry4an.org>
|
||||
- Ruro <ruro.ruro@ya.ru>
|
||||
- Roshan Shetty <roshan.shetty2816@gmail.com>
|
||||
- Roman Ivanov <me@roivanov.com>
|
||||
- Robert Schweizer <robert_schweizer@gmx.de>
|
||||
- Reverb Chu <reverbc@users.noreply.github.com>
|
||||
- Renat Galimov <renat2017@gmail.com>
|
||||
- Rebecca Turner <rbt@sent.as> (9999years)
|
||||
- Randall Leeds <randall@bleeds.info>
|
||||
- Ranadheer Gorrepati <35244169+ranadheerg@users.noreply.github.com>
|
||||
- Ramon Saraiva <ramonsaraiva@gmail.com>
|
||||
- Ramiro Leal-Cavazos <ramiroleal050@gmail.com> (ramiro050): Fixed bug preventing pylint from working with Emacs tramp
|
||||
- RSTdefg <34202999+RSTdefg@users.noreply.github.com>
|
||||
- R. N. West <98110034+rnwst@users.noreply.github.com>
|
||||
- Qwiddle13 <32040075+Qwiddle13@users.noreply.github.com>
|
||||
- Quentin Young <qlyoung@users.noreply.github.com>
|
||||
- Prajwal Borkar <sunnyborkar7777@gmail.com>
|
||||
- Petr Pulc <petrpulc@gmail.com>: require whitespace around annotations
|
||||
- Peter Dawyndt <Peter.Dawyndt@UGent.be>
|
||||
- Peter Dave Hello <hsu@peterdavehello.org>
|
||||
- Peter Aronoff <peter@aronoff.org>
|
||||
- Paul Cochrane <paul@liekut.de>
|
||||
- Patrik <patrik.mrx@gmail.com>
|
||||
- Pascal Corpet <pcorpet@users.noreply.github.com>
|
||||
- Pablo Galindo Salgado <Pablogsal@gmail.com>
|
||||
* Fix false positive 'Non-iterable value' with async comprehensions.
|
||||
- Osher De Paz <odepaz@redhat.com>
|
||||
- Oisín Moran <OisinMoran@users.noreply.github.com>
|
||||
- Obscuron <Abscuron@gmail.com>
|
||||
- Noam Yorav-Raphael <noamraph@gmail.com>
|
||||
- Noah-Agnel <138210920+Noah-Agnel@users.noreply.github.com>
|
||||
- Nir Soffer <nirsof@gmail.com>
|
||||
- Niko Wenselowski <niko@nerdno.de>
|
||||
- Nikita Sobolev <mail@sobolevn.me>
|
||||
- Nick Smith <clickthisnick@users.noreply.github.com>
|
||||
- Neowizard <Neowizard@users.noreply.github.com>
|
||||
- Ned Batchelder <ned@nedbatchelder.com>
|
||||
- Natalie Serebryakova <natalie.serebryakova@Natalies-MacBook-Pro.local>
|
||||
- Naglis Jonaitis <827324+naglis@users.noreply.github.com>
|
||||
- Moody <mooodyhunter@outlook.com>
|
||||
- Mitchell Young <mitchelly@gmail.com>: minor adjustment to docparams
|
||||
- Mitar <mitar.github@tnode.com>
|
||||
- Ming Lyu <CareF.Lm@gmail.com>
|
||||
- Mikhail f. Shiryaev <mr.felixoid@gmail.com>
|
||||
- Mike Fiedler <miketheman@gmail.com> (miketheman)
|
||||
- Mike Bryant <leachim@leachim.info>
|
||||
- Mike Bernard <mdbernard@pm.me>
|
||||
- Michka Popoff <michkapopoff@gmail.com>
|
||||
- Michal Vasilek <michal@vasilek.cz>
|
||||
- Michael Scott Cuthbert <cuthbert@mit.edu>
|
||||
- Michael Kefeder <oss@multiwave.ch>
|
||||
- Michael K <michael-k@users.noreply.github.com>
|
||||
- Michael Hudson-Doyle <michael.hudson@canonical.com>
|
||||
- Michael Giuffrida <mgiuffrida@users.noreply.github.com>
|
||||
- Melvin Hazeleger <31448155+melvio@users.noreply.github.com>
|
||||
- Meltem Kenis <meltem.kenis@plentific.com>
|
||||
- Mehdi Drissi <mdrissi@hmc.edu>
|
||||
- Matěj Grabovský <mgrabovs@redhat.com>
|
||||
- Matthijs Blom <19817960+MatthijsBlom@users.noreply.github.com>
|
||||
- Matej Spiller Muys <matej.spiller-muys@bitstamp.net>
|
||||
- Matej Marušák <marusak.matej@gmail.com>
|
||||
- Marzuk Rashid <mail@marzuk.io>
|
||||
- Markus Siebenhaar <41283549+siehar@users.noreply.github.com>
|
||||
- Marco Edward Gorelli <marcogorelli@protonmail.com>: Documented Jupyter integration
|
||||
- Marcin Kurczewski <rr-@sakuya.pl> (rr-)
|
||||
- Maik Röder <maikroeder@gmail.com>
|
||||
- Lumír 'Frenzy' Balhar <frenzy.madness@gmail.com>
|
||||
- Ludovic Aubry <ludal@logilab.fr>
|
||||
- Louis Sautier <sautier.louis@gmail.com>
|
||||
- Lorena Buciu <46202743+lorena-b@users.noreply.github.com>
|
||||
- Logan Miller <14319179+komodo472@users.noreply.github.com>
|
||||
- Kári Tristan Helgason <kthelgason@gmail.com>
|
||||
- Kurian Benoy <70306694+kurianbenoy-aot@users.noreply.github.com>
|
||||
- Krzysztof Czapla <k.czapla68@gmail.com>
|
||||
- Kraig Brockschmidt <kraigbr@msn.com>
|
||||
- Kound <norman.freudenberg@posteo.de>
|
||||
- KotlinIsland <65446343+KotlinIsland@users.noreply.github.com>
|
||||
- Kosarchuk Sergey <sergeykosarchuk@gmail.com>
|
||||
- Konrad Weihmann <46938494+priv-kweihmann@users.noreply.github.com>
|
||||
- Kian Meng, Ang <kianmeng.ang@gmail.com>
|
||||
- Kevin Phillips <thefriendlycoder@gmail.com>
|
||||
- Kevin Jing Qiu <kevin.jing.qiu@gmail.com>
|
||||
- Kenneth Schackart <schackartk1@gmail.com>
|
||||
- Kayran Schmidt <59456929+yumasheta@users.noreply.github.com>
|
||||
- Karthik Nadig <kanadig@microsoft.com>
|
||||
- Jürgen Hermann <jh@web.de>
|
||||
- Josselin Feist <josselin@trailofbits.com>
|
||||
- Jonathan Kotta <KottaJonathan@JohnDeere.com>
|
||||
- John Paraskevopoulos <io.paraskev@gmail.com>: add 'differing-param-doc' and 'differing-type-doc'
|
||||
- John McGehee <jmcgehee@altera.com>
|
||||
- John Gabriele <jgabriele@fastmail.fm>
|
||||
- John Belmonte <john@neggie.net>
|
||||
- Johannes Maron <johannes@maron.family>
|
||||
- Joffrey Mander <joffrey.mander+pro@gmail.com>
|
||||
- Jochen Preusche <iilei@users.noreply.github.com>
|
||||
- Jeroen Seegers <jeroenseegers@users.noreply.github.com>:
|
||||
* Fixed `toml` dependency issue
|
||||
- Jeremy Fleischman <jeremyfleischman@gmail.com>
|
||||
- Jason Owen <jason.a.owen@gmail.com>
|
||||
- Jason Lau <github.com@dotkr.nl>
|
||||
- Jared Garst <cultofjared@gmail.com>
|
||||
- Jared Deckard <jared.deckard@gmail.com>
|
||||
- Janne Rönkkö <jannero@users.noreply.github.com>
|
||||
- Jamie Scott <jamie@jami.org.uk>
|
||||
- James Sinclair <james@nurfherder.com>
|
||||
- James M. Allen <james.m.allen@gmail.com>
|
||||
- James Lingard <jchl@aristanetworks.com>
|
||||
- James Broadhead <jamesbroadhead@gmail.com>
|
||||
- Jakub Kulík <Kulikjak@gmail.com>
|
||||
- Jakob Normark <jakobnormark@gmail.com>
|
||||
- Jacques Kvam <jwkvam@gmail.com>
|
||||
- Jace Browning <jacebrowning@gmail.com>: updated default report format with clickable paths
|
||||
- JZ <jzohrab@gmail.com>
|
||||
- JT Olds <jtolds@xnet5.com>
|
||||
- Iggy Eom <iggy.eom@sendbird.com>
|
||||
- Ige-kun <178478713+Ige-kun@users.noreply.github.com>
|
||||
- Hayden Richards <62866982+SupImDos@users.noreply.github.com>
|
||||
* Fixed "no-self-use" for async methods
|
||||
* Fixed "docparams" extension for async functions and methods
|
||||
- Harshil <37377066+harshil21@users.noreply.github.com>
|
||||
- Harry <harrymcwinters@gmail.com>
|
||||
- Gwanbin Park <bgb1028@gmail.com>
|
||||
- Grégoire <96051754+gregoire-mullvad@users.noreply.github.com>
|
||||
- Grant Welch <gwelch925+github@gmail.com>
|
||||
- Giuseppe Valente <gvalente@arista.com>
|
||||
- Gary Tyler McLeod <mail@garytyler.com>
|
||||
- Felix von Drigalski <FvDrigalski@gmail.com>
|
||||
- Felix Preuschoff <37065638+felixp98@users.noreply.github.com>
|
||||
- Fabrice Douchant <Fabrice.Douchant@logilab.fr>
|
||||
- Fabio Natali <me@fabionatali.com>
|
||||
- Fabian Damken <fdamken+github@frisp.org>
|
||||
- Eric Froemling <ericfroemling@gmail.com>
|
||||
- Emmanuel Chaudron <manu.chaud@hotmail.fr>
|
||||
- Elizabeth Bott <52465744+elizabethbott@users.noreply.github.com>
|
||||
- Ekin Dursun <ekindursun@gmail.com>
|
||||
- Eisuke Kawashima <e-kwsm@users.noreply.github.com>
|
||||
- Edgemaster <grand.edgemaster@gmail.com>
|
||||
- Eddie Darling <eddie.darling@genapsys.com>
|
||||
- Drew Risinger <drewrisinger@users.noreply.github.com>
|
||||
- Dr. Nick <das-intensity@users.noreply.github.com>
|
||||
- Don Kirkby <donkirkby@users.noreply.github.com>
|
||||
- Don Jayamanne <don.jayamanne@yahoo.com>
|
||||
- Dominic Lavery <che@thisdevice.co.uk>
|
||||
- Dmytro Kyrychuk <dmytro.kyrychuck@gmail.com>
|
||||
- Dionisio E Alonso <baco@users.noreply.github.com>
|
||||
- DetachHead <57028336+DetachHead@users.noreply.github.com>
|
||||
- Dennis Keck <26092524+fellhorn@users.noreply.github.com>
|
||||
- Denis Laxalde <denis.laxalde@logilab.fr>
|
||||
- David Lawson <dmrlawson@gmail.com>
|
||||
- David Cain <davidjosephcain@gmail.com>
|
||||
- Danny Hermes <daniel.j.hermes@gmail.com>
|
||||
- Daniele Procida <daniele@vurt.org>
|
||||
- Daniela Plascencia <daplascen@gmail.com>
|
||||
- Daniel Werner <daniel.werner@scalableminds.com>
|
||||
- Daniel R. Neal <dan.r.neal@gmail.com> (danrneal)
|
||||
- Daniel Draper <Germandrummer92@users.noreply.github.com>
|
||||
- Daniel Dorani <ddandd@gmail.com> (doranid)
|
||||
- Daniel Brookman <53625739+dbrookman@users.noreply.github.com>
|
||||
- Dan Garrette <dhgarrette@gmail.com>
|
||||
- Damien Nozay <damien.nozay@gmail.com>
|
||||
- Cubicpath <Cubicpath@protonmail.com>
|
||||
- Craig Citro <craigcitro@gmail.com>
|
||||
- Cosmo <cosmo@cosmo.red>
|
||||
- Clément Schreiner <clement@mux.me>
|
||||
- Clément Pit-Claudel <cpitclaudel@users.noreply.github.com>
|
||||
- Christopher Zurcher <zurcher@users.noreply.github.com>
|
||||
- ChandanChainani <chandan.chainani@ibm.com>
|
||||
- Carl Crowder <bitbucket@carlcrowder.com>: don't evaluate the value of arguments for 'dangerous-default-value'
|
||||
- Carey Metcalfe <carey@cmetcalfe.ca>: demoted `try-except-raise` from error to warning
|
||||
- Cameron Olechowski <camsterole@users.noreply.github.com>
|
||||
- Calin Don <calin.don@gmail.com>
|
||||
- Caio Carrara <ccarrara@redhat.com>
|
||||
- C.A.M. Gerlach <WIDEnetServices@gmail.com>
|
||||
- Bruno P. Kinoshita <kinow@users.noreply.github.com>
|
||||
- Brice Chardin <brice.chardin@gmail.com>
|
||||
- Brian C. Lane <bcl@redhat.com>
|
||||
- Brandon W Maister <quodlibetor@gmail.com>
|
||||
- BioGeek <jeroen.vangoey@gmail.com>
|
||||
- Berker ŞAL <brkr.sal@gmail.com>
|
||||
- Benjamin Partzsch <32679788+bnjmnp@users.noreply.github.com>
|
||||
- Benjamin Graham <benwilliamgraham@gmail.com>
|
||||
- Benedikt Morbach <benedikt.morbach@googlemail.com>
|
||||
- Ben Greiner <code@bnavigator.de>
|
||||
- Barak Shoshany <baraksh@gmail.com>
|
||||
- Banjamin Freeman <befreeman@users.noreply.github.com>
|
||||
- Ayushi Kotiyal <70513726+Ayushikotiyal@users.noreply.github.com>
|
||||
- Avram Lubkin <avylove@rockhopper.net>
|
||||
- Athos Ribeiro <athoscr@fedoraproject.org>: Fixed dict-keys-not-iterating false positive for inverse containment checks
|
||||
- Arun Persaud <arun@nubati.net>
|
||||
- Arthur Lutz <arthur.lutz@logilab.fr>
|
||||
- Antonio Ossa <aaossa@uc.cl>
|
||||
- Antonio Gámiz Delgado <73933988+antoniogamizbadger@users.noreply.github.com>
|
||||
- Anthony VEREZ <anthony.verez.external@cassidian.com>
|
||||
- Anthony Tan <tanant@users.noreply.github.com>
|
||||
- Anthony Foglia <afoglia@users.noreply.github.com> (Google): Added simple string slots check.
|
||||
- Anentropic <ego@anentropic.com>
|
||||
- Andy Young <a7young@ucsd.edu>
|
||||
- Andy Palmer <25123779+ninezerozeronine@users.noreply.github.com>
|
||||
- Andrzej Klajnert <github@aklajnert.pl>
|
||||
- Andrew Howe <howeaj@users.noreply.github.com>
|
||||
- Andres Perez Hortal <andresperezcba@gmail.com>
|
||||
- Andre Hora <andrehora@users.noreply.github.com>
|
||||
- Aman Salwan <121633121+AmanSal1@users.noreply.github.com>
|
||||
- Alok Singh <8325708+alok@users.noreply.github.com>
|
||||
- Allan Chandler <95424144+allanc65@users.noreply.github.com> (allanc65)
|
||||
* Fixed issue 5452, false positive missing-param-doc for multi-line Google-style params
|
||||
- Alex Waygood <alex.waygood@gmail.com>
|
||||
- Alex Mor <5476113+nashcontrol@users.noreply.github.com>
|
||||
- Alex Jurkiewicz <alex@jurkiewi.cz>
|
||||
- Alex Hearn <alex.d.hearn@gmail.com>
|
||||
- Alex Fortin <alex.antoine.fortin@gmail.com>
|
||||
- Aleksander Mamla <alek.mamla@gmail.com>
|
||||
- Alan Evangelista <alanoe@linux.vnet.ibm.com>
|
||||
- Alan Chan <achan961117@gmail.com>
|
||||
- Aivar Annamaa <aivarannamaa@users.noreply.github.com>
|
||||
- Aidan Haase <44787650+haasea@users.noreply.github.com>
|
||||
- Ahirnish Pareek <ahirnish@gmail.com>: 'keyword-arg-before-var-arg' check
|
||||
- Agustin Marquez <agusdmb@gmail.com>
|
||||
- Adrian Chirieac <chirieacam@gmail.com>
|
||||
- Aditya Gupta <adityagupta1089@users.noreply.github.com> (adityagupta1089)
|
||||
* Added ignore_signatures to duplicate checker
|
||||
- Adam Tuft <73994535+adamtuft@users.noreply.github.com>
|
||||
- Adam Dangoor <adamdangoor@gmail.com>
|
||||
- 243f6a88 85a308d3 <33170174+243f6a8885a308d313198a2e037@users.noreply.github.com>
|
||||
|
||||
|
||||
Co-Author
|
||||
---------
|
||||
The following persons were credited manually but did not commit themselves
|
||||
under this name, or we did not manage to find their commits in the history.
|
||||
|
||||
- Agustin Toledo
|
||||
- Amaury Forgeot d'Arc: check names imported from a module exists in the module
|
||||
- Anthony Tan
|
||||
- Axel Muller
|
||||
- Benjamin Niemann: allow block level enabling/disabling of messages
|
||||
- Bernard Nauwelaerts
|
||||
- Bill Wendling
|
||||
- Brian van den Broek: windows installation documentation
|
||||
- Craig Henriques
|
||||
- D. Alphus (Alphadelta14)
|
||||
- Daniil Kharkov
|
||||
- Eero Vuojolahti
|
||||
- Fabio Zadrozny
|
||||
- Gauthier Sebaux
|
||||
- James DesLauriers
|
||||
- manderj
|
||||
- Mirko Friedenhagen
|
||||
- Nicholas Smith
|
||||
- Nuzula H. Yudaka (Nuzhuka)
|
||||
- Pek Chhan
|
||||
- Peter Hammond
|
||||
- Pierre Rouleau
|
||||
- Richard Goodman: simplifiable-if-expression (with Tomer Chachamu)
|
||||
- Sebastian Ulrich
|
||||
- Takashi Hirashima
|
||||
- Thomas Snowden: fix missing-docstring for inner functions
|
||||
- Wolfgang Grafen
|
||||
- Yannick Brehon
|
||||
@ -1,340 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
@ -1,14 +0,0 @@
|
||||
include README.rst
|
||||
include requirements_test_min.txt
|
||||
include requirements_test_pre_commit.txt
|
||||
include requirements_test.txt
|
||||
include tox.ini
|
||||
graft doc
|
||||
graft examples
|
||||
graft script
|
||||
graft tests
|
||||
prune doc/_build
|
||||
prune tests/.benchmarks
|
||||
prune tests/.pylint_primer_tests
|
||||
global-exclude __pycache__
|
||||
global-exclude *.py[co]
|
||||
@ -1,225 +0,0 @@
|
||||
`Pylint`_
|
||||
=========
|
||||
|
||||
.. _`Pylint`: https://pylint.readthedocs.io/
|
||||
|
||||
.. This is used inside the doc to recover the start of the introduction
|
||||
|
||||
.. image:: https://github.com/pylint-dev/pylint/actions/workflows/tests.yaml/badge.svg?branch=main
|
||||
:target: https://github.com/pylint-dev/pylint/actions
|
||||
|
||||
.. image:: https://codecov.io/gh/pylint-dev/pylint/branch/main/graph/badge.svg?token=ZETEzayrfk
|
||||
:target: https://codecov.io/gh/pylint-dev/pylint
|
||||
|
||||
.. image:: https://img.shields.io/pypi/v/pylint.svg
|
||||
:alt: PyPI Package version
|
||||
:target: https://pypi.python.org/pypi/pylint
|
||||
|
||||
.. image:: https://readthedocs.org/projects/pylint/badge/?version=latest
|
||||
:target: https://pylint.readthedocs.io/en/latest/?badge=latest
|
||||
:alt: Documentation Status
|
||||
|
||||
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
|
||||
:target: https://github.com/ambv/black
|
||||
|
||||
.. image:: https://img.shields.io/badge/linting-pylint-yellowgreen
|
||||
:target: https://github.com/pylint-dev/pylint
|
||||
|
||||
.. image:: https://results.pre-commit.ci/badge/github/pylint-dev/pylint/main.svg
|
||||
:target: https://results.pre-commit.ci/latest/github/pylint-dev/pylint/main
|
||||
:alt: pre-commit.ci status
|
||||
|
||||
.. image:: https://bestpractices.coreinfrastructure.org/projects/6328/badge
|
||||
:target: https://bestpractices.coreinfrastructure.org/projects/6328
|
||||
:alt: CII Best Practices
|
||||
|
||||
.. image:: https://img.shields.io/ossf-scorecard/github.com/PyCQA/pylint?label=openssf%20scorecard&style=flat
|
||||
:target: https://api.securityscorecards.dev/projects/github.com/PyCQA/pylint
|
||||
:alt: OpenSSF Scorecard
|
||||
|
||||
.. image:: https://img.shields.io/discord/825463413634891776.svg
|
||||
:target: https://discord.gg/qYxpadCgkx
|
||||
:alt: Discord
|
||||
|
||||
What is Pylint?
|
||||
---------------
|
||||
|
||||
Pylint is a `static code analyser`_ for Python 2 or 3. The latest version supports Python
|
||||
3.10.0 and above.
|
||||
|
||||
.. _`static code analyser`: https://en.wikipedia.org/wiki/Static_code_analysis
|
||||
|
||||
Pylint analyses your code without actually running it. It checks for errors, enforces a
|
||||
coding standard, looks for `code smells`_, and can make suggestions about how the code
|
||||
could be refactored.
|
||||
|
||||
.. _`code smells`: https://martinfowler.com/bliki/CodeSmell.html
|
||||
|
||||
Install
|
||||
-------
|
||||
|
||||
.. This is used inside the doc to recover the start of the short text for installation
|
||||
|
||||
For command line use, pylint is installed with::
|
||||
|
||||
pip install pylint
|
||||
|
||||
Or if you want to also check spelling with ``enchant`` (you might need to
|
||||
`install the enchant C library <https://pyenchant.github.io/pyenchant/install.html#installing-the-enchant-c-library>`_):
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
pip install pylint[spelling]
|
||||
|
||||
It can also be integrated in most editors or IDEs. More information can be found
|
||||
`in the documentation`_.
|
||||
|
||||
.. _in the documentation: https://pylint.readthedocs.io/en/latest/user_guide/installation/index.html
|
||||
|
||||
.. This is used inside the doc to recover the end of the short text for installation
|
||||
|
||||
What differentiates Pylint?
|
||||
---------------------------
|
||||
|
||||
Pylint is not trusting your typing and is inferring the actual values of nodes (for a
|
||||
start because there was no typing when pylint started off) using its internal code
|
||||
representation (astroid). If your code is ``import logging as argparse``, Pylint
|
||||
can check and know that ``argparse.error(...)`` is in fact a logging call and not an
|
||||
argparse call. This makes pylint slower, but it also lets pylint find more issues if
|
||||
your code is not fully typed.
|
||||
|
||||
[inference] is the killer feature that keeps us using [pylint] in our project despite how painfully slow it is.
|
||||
- `Realist pylint user`_, 2022
|
||||
|
||||
.. _`Realist pylint user`: https://github.com/charliermarsh/ruff/issues/970#issuecomment-1381067064
|
||||
|
||||
pylint, not afraid of being a little slower than it already is, is also a lot more thorough than other linters.
|
||||
There are more checks, including some opinionated ones that are deactivated by default
|
||||
but can be enabled using configuration.
|
||||
|
||||
How to use pylint
|
||||
-----------------
|
||||
|
||||
Pylint isn't smarter than you: it may warn you about things that you have
|
||||
conscientiously done or check for some things that you don't care about.
|
||||
During adoption, especially in a legacy project where pylint was never enforced,
|
||||
it's best to start with the ``--errors-only`` flag, then disable
|
||||
convention and refactor messages with ``--disable=C,R`` and progressively
|
||||
re-evaluate and re-enable messages as your priorities evolve.
|
||||
|
||||
Pylint is highly configurable and permits to write plugins in order to add your
|
||||
own checks (for example, for internal libraries or an internal rule). Pylint also has an
|
||||
ecosystem of existing plugins for popular frameworks and third-party libraries.
|
||||
|
||||
.. note::
|
||||
|
||||
Pylint supports the Python standard library out of the box. Third-party
|
||||
libraries are not always supported, so a plugin might be needed. A good place
|
||||
to start is ``PyPI`` which often returns a plugin by searching for
|
||||
``pylint <library>``. `pylint-pydantic`_, `pylint-django`_ and
|
||||
`pylint-sonarjson`_ are examples of such plugins. More information about plugins
|
||||
and how to load them can be found at `plugins`_.
|
||||
|
||||
.. _`plugins`: https://pylint.readthedocs.io/en/latest/development_guide/how_tos/plugins.html#plugins
|
||||
.. _`pylint-pydantic`: https://pypi.org/project/pylint-pydantic
|
||||
.. _`pylint-django`: https://github.com/pylint-dev/pylint-django
|
||||
.. _`pylint-sonarjson`: https://github.com/cnescatlab/pylint-sonarjson-catlab
|
||||
|
||||
Advised linters alongside pylint
|
||||
--------------------------------
|
||||
|
||||
Projects that you might want to use alongside pylint include ruff_ (**really** fast,
|
||||
with builtin auto-fix and a large number of checks taken from popular linters, but
|
||||
implemented in ``rust``) or flake8_ (a framework to implement your own checks in python using ``ast`` directly),
|
||||
mypy_, pyright_ / pylance or pyre_ (typing checks), bandit_ (security oriented checks), black_ and
|
||||
isort_ (auto-formatting), autoflake_ (automated removal of unused imports or variables), pyupgrade_
|
||||
(automated upgrade to newer python syntax) and pydocstringformatter_ (automated pep257).
|
||||
|
||||
.. _ruff: https://github.com/astral-sh/ruff
|
||||
.. _flake8: https://github.com/PyCQA/flake8
|
||||
.. _bandit: https://github.com/PyCQA/bandit
|
||||
.. _mypy: https://github.com/python/mypy
|
||||
.. _pyright: https://github.com/microsoft/pyright
|
||||
.. _pyre: https://github.com/facebook/pyre-check
|
||||
.. _black: https://github.com/psf/black
|
||||
.. _autoflake: https://github.com/myint/autoflake
|
||||
.. _pyupgrade: https://github.com/asottile/pyupgrade
|
||||
.. _pydocstringformatter: https://github.com/DanielNoord/pydocstringformatter
|
||||
.. _isort: https://pycqa.github.io/isort/
|
||||
|
||||
Additional tools included in pylint
|
||||
-----------------------------------
|
||||
|
||||
Pylint ships with two additional tools:
|
||||
|
||||
- pyreverse_ (standalone tool that generates package and class diagrams.)
|
||||
- symilar_ (duplicate code finder that is also integrated in pylint)
|
||||
|
||||
.. _pyreverse: https://pylint.readthedocs.io/en/latest/additional_tools/pyreverse/index.html
|
||||
.. _symilar: https://pylint.readthedocs.io/en/latest/additional_tools/symilar/index.html
|
||||
|
||||
|
||||
.. This is used inside the doc to recover the end of the introduction
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
.. This is used inside the doc to recover the start of the short text for contribution
|
||||
|
||||
We welcome all forms of contributions such as updates for documentation, new code, checking issues for duplicates or telling us
|
||||
that we can close them, confirming that issues still exist, `creating issues because
|
||||
you found a bug or want a feature`_, etc. Everything is much appreciated!
|
||||
|
||||
Please follow the `code of conduct`_ and check `the Contributor Guides`_ if you want to
|
||||
make a code contribution.
|
||||
|
||||
.. _creating issues because you found a bug or want a feature: https://pylint.readthedocs.io/en/latest/contact.html#bug-reports-feedback
|
||||
.. _code of conduct: https://github.com/pylint-dev/pylint/blob/main/CODE_OF_CONDUCT.md
|
||||
.. _the Contributor Guides: https://pylint.readthedocs.io/en/latest/development_guide/contribute.html
|
||||
|
||||
.. This is used inside the doc to recover the end of the short text for contribution
|
||||
|
||||
Show your usage
|
||||
-----------------
|
||||
|
||||
You can place this badge in your README to let others know your project uses pylint.
|
||||
|
||||
.. image:: https://img.shields.io/badge/linting-pylint-yellowgreen
|
||||
:target: https://github.com/pylint-dev/pylint
|
||||
|
||||
Learn how to add a badge to your documentation in `the badge documentation`_.
|
||||
|
||||
.. _the badge documentation: https://pylint.readthedocs.io/en/latest/user_guide/installation/badge.html
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
pylint is, with a few exceptions listed below, `GPLv2 <https://github.com/pylint-dev/pylint/blob/main/LICENSE>`_.
|
||||
|
||||
The icon files are licensed under the `CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0/>`_ license:
|
||||
|
||||
- `doc/logo.png <https://raw.githubusercontent.com/pylint-dev/pylint/main/doc/logo.png>`_
|
||||
- `doc/logo.svg <https://raw.githubusercontent.com/pylint-dev/pylint/main/doc/logo.svg>`_
|
||||
|
||||
Support
|
||||
-------
|
||||
|
||||
Please check `the contact information`_.
|
||||
|
||||
.. _`the contact information`: https://pylint.readthedocs.io/en/latest/contact.html
|
||||
|
||||
.. |tideliftlogo| image:: https://raw.githubusercontent.com/pylint-dev/pylint/main/doc/media/Tidelift_Logos_RGB_Tidelift_Shorthand_On-White.png
|
||||
:width: 200
|
||||
:alt: Tidelift
|
||||
|
||||
.. list-table::
|
||||
:widths: 10 100
|
||||
|
||||
* - |tideliftlogo|
|
||||
- Professional support for pylint is available as part of the `Tidelift
|
||||
Subscription`_. Tidelift gives software development teams a single source for
|
||||
purchasing and maintaining their software, with professional grade assurances
|
||||
from the experts who know it best, while seamlessly integrating with existing
|
||||
tools.
|
||||
|
||||
.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-pylint?utm_source=pypi-pylint&utm_medium=referral&utm_campaign=readme
|
||||
@ -1,10 +0,0 @@
|
||||
coverage:
|
||||
status:
|
||||
patch:
|
||||
default:
|
||||
target: 100%
|
||||
project:
|
||||
default:
|
||||
target: 95%
|
||||
comment:
|
||||
layout: "reach, diff, flags, files"
|
||||
@ -1,396 +0,0 @@
|
||||
abc
|
||||
abcmeta
|
||||
abspath
|
||||
abstractproperty
|
||||
analyse
|
||||
analysed
|
||||
analysing
|
||||
arg
|
||||
argparse
|
||||
args
|
||||
argumentdefaultshelpformatter
|
||||
argumentparser
|
||||
argumentsparser
|
||||
argv
|
||||
ascii
|
||||
asend
|
||||
assignattr
|
||||
assignname
|
||||
AST
|
||||
ast
|
||||
astroid
|
||||
async
|
||||
asynccontextmanager
|
||||
attr
|
||||
attrib
|
||||
attrname
|
||||
backport
|
||||
BaseChecker
|
||||
basename
|
||||
behaviour
|
||||
bidi
|
||||
Bitbucket
|
||||
bla
|
||||
bom
|
||||
bool
|
||||
boolean
|
||||
booleaness
|
||||
boolop
|
||||
boundmethod
|
||||
builtins
|
||||
bw
|
||||
callables
|
||||
cardinality
|
||||
cd
|
||||
cfg
|
||||
changelog
|
||||
cheaders
|
||||
chroot
|
||||
chunker
|
||||
classdef
|
||||
classdiagram
|
||||
classmethod
|
||||
classmethod's
|
||||
classname
|
||||
classobj
|
||||
CLI
|
||||
cls
|
||||
cmp
|
||||
codebase
|
||||
codec
|
||||
codecs
|
||||
col's
|
||||
conf
|
||||
config
|
||||
const
|
||||
Const
|
||||
contextlib
|
||||
contextmanager
|
||||
contravariance
|
||||
contravariant
|
||||
cgroup
|
||||
CPython
|
||||
cpython
|
||||
csv
|
||||
CVE
|
||||
cwd
|
||||
cyclomatic
|
||||
dataclass
|
||||
dataclasses
|
||||
datetime
|
||||
debian
|
||||
deduplication
|
||||
deepcopy
|
||||
defaultdicts
|
||||
defframe
|
||||
defstmts
|
||||
deleter
|
||||
dependabot
|
||||
deque
|
||||
destructured
|
||||
destructuring
|
||||
diadefs
|
||||
diadefslib
|
||||
dictcomp
|
||||
dicts
|
||||
dir
|
||||
dirname
|
||||
docparams
|
||||
docstring
|
||||
docstrings
|
||||
dumpable
|
||||
dunder
|
||||
elif
|
||||
elif's
|
||||
elt
|
||||
emittable
|
||||
encodings
|
||||
endswith
|
||||
enum
|
||||
enums
|
||||
epilog
|
||||
epylint
|
||||
epytext
|
||||
erroring
|
||||
etree
|
||||
expr
|
||||
falsey
|
||||
favour
|
||||
filepath
|
||||
filestream
|
||||
finalbody
|
||||
# TODO Remove when we are able to remove our own symbols
|
||||
fixme
|
||||
Flymake
|
||||
fmt
|
||||
formatter
|
||||
formfeed
|
||||
fromlineno
|
||||
fullname
|
||||
func
|
||||
functiondef
|
||||
functiøn
|
||||
functools
|
||||
genexpr
|
||||
getattr
|
||||
globals
|
||||
globbing
|
||||
GPL
|
||||
graphname
|
||||
graphviz
|
||||
grey
|
||||
guido's
|
||||
gv
|
||||
hashable
|
||||
hmac
|
||||
html
|
||||
idgeneratormixin
|
||||
ifexpr
|
||||
igetattr
|
||||
importedname
|
||||
importfrom
|
||||
importnode
|
||||
importschecker
|
||||
InferenceError
|
||||
ini
|
||||
INI
|
||||
init
|
||||
initializer
|
||||
inlinevar
|
||||
instantiation
|
||||
isdir
|
||||
isfile
|
||||
isinstance
|
||||
isort
|
||||
iter
|
||||
iterable
|
||||
iterables
|
||||
itered
|
||||
iteritems
|
||||
iTerm
|
||||
jn
|
||||
jpg
|
||||
json
|
||||
jx
|
||||
jython
|
||||
# class is a reserved word
|
||||
klass
|
||||
kwarg
|
||||
kwargs
|
||||
kwonlyargs
|
||||
latin
|
||||
len
|
||||
lhs
|
||||
linecache
|
||||
lineno
|
||||
linenum
|
||||
lineset
|
||||
lineset's
|
||||
linesets
|
||||
linkers
|
||||
linter
|
||||
linux
|
||||
listcomp
|
||||
Logilab
|
||||
longstring
|
||||
lsp
|
||||
mapfile
|
||||
mapreduce
|
||||
maxsize
|
||||
maxsplit
|
||||
mcs
|
||||
mermaidjs
|
||||
metaclass
|
||||
metaclasses
|
||||
misdesign
|
||||
misdesigns
|
||||
mixin
|
||||
modname
|
||||
monkeypatch
|
||||
mro
|
||||
# Used so much that we need the abbreviation
|
||||
msg
|
||||
msg-template
|
||||
msgid
|
||||
msgids
|
||||
msgs
|
||||
mult
|
||||
multiline
|
||||
multiset
|
||||
multisets
|
||||
myattr
|
||||
myfunction
|
||||
mymain
|
||||
mymethod
|
||||
mymodule
|
||||
mypy
|
||||
namedtuple
|
||||
namespace
|
||||
newsfile
|
||||
newstyle
|
||||
nl
|
||||
nodename
|
||||
nodeng
|
||||
noinspection
|
||||
nonlocal
|
||||
nonlocals
|
||||
num
|
||||
numpy
|
||||
ok
|
||||
optdict
|
||||
optik
|
||||
optionals
|
||||
optiondict
|
||||
optname
|
||||
optparse
|
||||
optvalue
|
||||
orelse
|
||||
os
|
||||
outputfile
|
||||
overridable
|
||||
params
|
||||
paren
|
||||
parens
|
||||
passthru
|
||||
pathlib
|
||||
patternerror
|
||||
png
|
||||
positionals
|
||||
pragma
|
||||
pragma's
|
||||
pragmas
|
||||
pre
|
||||
preorder
|
||||
prepended
|
||||
proc
|
||||
py
|
||||
pyenchant
|
||||
pyfile
|
||||
pyi
|
||||
pylint
|
||||
pylint's
|
||||
pylintdict
|
||||
pylintrc
|
||||
pyproject
|
||||
pypy
|
||||
pyreverse
|
||||
pytest
|
||||
qname
|
||||
rawcheckers
|
||||
rc
|
||||
rcfile
|
||||
re-usable
|
||||
readlines
|
||||
recognise
|
||||
recurse
|
||||
recurses
|
||||
redef
|
||||
reportid
|
||||
rgx
|
||||
rheaders
|
||||
rhs
|
||||
roid
|
||||
rsplit
|
||||
rst
|
||||
rstrip
|
||||
rtype
|
||||
runtime
|
||||
se
|
||||
seaborn
|
||||
sep
|
||||
setcomp
|
||||
shortstrings
|
||||
singledispatch
|
||||
singledispatchmethod
|
||||
spammy
|
||||
sqlalchemy
|
||||
src
|
||||
starargs
|
||||
stateful
|
||||
staticmethod
|
||||
stderr
|
||||
stdin
|
||||
stdlib
|
||||
stdout
|
||||
stmt
|
||||
str
|
||||
stringified
|
||||
subclasses
|
||||
subcommands
|
||||
subdicts
|
||||
subgraphs
|
||||
sublists
|
||||
submodule
|
||||
submodules
|
||||
subparsers
|
||||
subparts
|
||||
subprocess
|
||||
subscriptable
|
||||
subscripted
|
||||
subtree
|
||||
supcls
|
||||
superclass
|
||||
symilar
|
||||
symlink
|
||||
symlinks
|
||||
sys
|
||||
tbump
|
||||
tempfile
|
||||
testcase
|
||||
testdata
|
||||
testoptions
|
||||
tmp
|
||||
tokencheckers
|
||||
tokeninfo
|
||||
tokenization
|
||||
tokenize
|
||||
tokenizer
|
||||
toml
|
||||
tomlkit
|
||||
toplevel
|
||||
towncrier
|
||||
tp
|
||||
truthey
|
||||
truthness
|
||||
truthy
|
||||
tryexcept
|
||||
txt
|
||||
typecheck
|
||||
typechecking
|
||||
typeddict
|
||||
typehint
|
||||
typeshed
|
||||
uid
|
||||
uml
|
||||
un
|
||||
unary
|
||||
unflattens
|
||||
unhandled
|
||||
unicode
|
||||
uninferable
|
||||
Uninferable
|
||||
unittest
|
||||
unraisablehook
|
||||
untriggered
|
||||
# prefix for string
|
||||
ur
|
||||
ureport
|
||||
ureports
|
||||
utf
|
||||
utils
|
||||
validator
|
||||
vararg
|
||||
varargs
|
||||
variadic
|
||||
variadics
|
||||
vcg
|
||||
vcg's
|
||||
vectorisation
|
||||
virtualized
|
||||
wc
|
||||
whitespaces
|
||||
xfails
|
||||
xml
|
||||
xyz
|
||||
yml
|
||||
yoda
|
||||
@ -1,47 +0,0 @@
|
||||
# You can set these variables from the command line, and also
|
||||
# from the environment for the first two.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= sphinx-build
|
||||
SOURCEDIR = .
|
||||
BUILDDIR = _build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
# --------------------------------
|
||||
# This part is specific to pylint.
|
||||
#---------------------------------
|
||||
|
||||
# Set PYLINT_SPHINX_FATAL_WARNINGS= on the command line to restore the default.
|
||||
PYLINT_SPHINX_FATAL_WARNINGS = -W --keep-going
|
||||
|
||||
# Do not use O, we abuse it for internal purposes.
|
||||
O = -d $(BUILDDIR)/doctrees -T $(PYLINT_SPHINX_FATAL_WARNINGS) -n
|
||||
|
||||
.PHONY clean: remove-generated-messages
|
||||
remove-generated-messages:
|
||||
rm -rf user_guide/messages/convention user_guide/messages/error \
|
||||
user_guide/messages/fatal user_guide/messages/information user_guide/messages/refactor \
|
||||
user_guide/messages/warning
|
||||
|
||||
# Generated by exts/*.py but kept in the VCS for easier review of changes:
|
||||
.PHONY: distclean
|
||||
distclean: clean
|
||||
rm -f user_guide/checkers/extensions.rst user_guide/checkers/features.rst \
|
||||
user_guide/configuration/all-options.rst user_guide/messages/messages_overview.rst
|
||||
|
||||
# Set PIP=true on the command line to skip installation of dependencies.
|
||||
PIP = pip
|
||||
|
||||
.PHONY html: install-dependencies
|
||||
install-dependencies:
|
||||
@echo "Install dependencies"
|
||||
cd ../ && $(PIP) install -r doc/requirements.txt
|
||||
@ -1,201 +0,0 @@
|
||||
.. This file is auto-generated. Make any changes to the associated
|
||||
.. docs extension in 'doc/exts/pyreverse_configuration.py'.
|
||||
|
||||
|
||||
Usage
|
||||
#####
|
||||
|
||||
|
||||
``pyreverse`` is run from the command line using the following syntax::
|
||||
|
||||
pyreverse [options] <packages>
|
||||
|
||||
where ``<packages>`` is one or more Python packages or modules to analyze.
|
||||
|
||||
The available options are organized into the following categories:
|
||||
|
||||
* :ref:`filtering-and-scope` - Control which classes and relationships appear in your diagrams
|
||||
* :ref:`display-options` - Customize the visual appearance including colors and labels
|
||||
* :ref:`output-control` - Select output formats and set the destination directory
|
||||
* :ref:`project-configuration` - Define project settings like source roots and ignored files
|
||||
|
||||
|
||||
.. _filtering-and-scope:
|
||||
|
||||
Filtering and Scope
|
||||
===================
|
||||
|
||||
|
||||
--all-ancestors
|
||||
---------------
|
||||
*Show all ancestors of all classes in <projects>.*
|
||||
|
||||
**Default:** ``None``
|
||||
|
||||
|
||||
--all-associated
|
||||
----------------
|
||||
*Show all classes associated with the target classes, including indirect associations.*
|
||||
|
||||
**Default:** ``None``
|
||||
|
||||
|
||||
--class
|
||||
-------
|
||||
*Create a class diagram with all classes related to <class>; this uses by default the options -ASmy*
|
||||
|
||||
**Default:** ``None``
|
||||
|
||||
|
||||
--filter-mode
|
||||
-------------
|
||||
*Filter attributes and functions according to <mode>. Correct modes are:
|
||||
'PUB_ONLY' filter all non public attributes [DEFAULT], equivalent to PRIVATE+SPECIAL
|
||||
'ALL' no filter
|
||||
'SPECIAL' filter Python special functions except constructor
|
||||
'OTHER' filter protected and private attributes*
|
||||
|
||||
**Default:** ``PUB_ONLY``
|
||||
|
||||
|
||||
--max-depth
|
||||
-----------
|
||||
*Maximum depth of packages/modules to include in the diagram, relative to the deepest specified package. A depth of 0 shows only the specified packages/modules, while 1 includes their immediate children, etc. When specifying nested packages, depth is calculated from the deepest package level. If not specified, all packages/modules in the hierarchy are shown.*
|
||||
|
||||
**Default:** ``None``
|
||||
|
||||
|
||||
--show-ancestors
|
||||
----------------
|
||||
*Show <ancestor> generations of ancestor classes not in <projects>.*
|
||||
|
||||
**Default:** ``None``
|
||||
|
||||
|
||||
--show-associated
|
||||
-----------------
|
||||
*Show <association_level> levels of associated classes not in <projects>.*
|
||||
|
||||
**Default:** ``None``
|
||||
|
||||
|
||||
--show-builtin
|
||||
--------------
|
||||
*Include builtin objects in representation of classes.*
|
||||
|
||||
**Default:** ``False``
|
||||
|
||||
|
||||
--show-stdlib
|
||||
-------------
|
||||
*Include standard library objects in representation of classes.*
|
||||
|
||||
**Default:** ``False``
|
||||
|
||||
|
||||
|
||||
|
||||
.. _display-options:
|
||||
|
||||
Display Options
|
||||
===============
|
||||
|
||||
|
||||
--color-palette
|
||||
---------------
|
||||
*Comma separated list of colors to use for the package depth coloring.*
|
||||
|
||||
**Default:** ``('#77AADD', '#99DDFF', '#44BB99', '#BBCC33', '#AAAA00', '#EEDD88', '#EE8866', '#FFAABB', '#DDDDDD')``
|
||||
|
||||
|
||||
--colorized
|
||||
-----------
|
||||
*Use colored output. Classes/modules of the same package get the same color.*
|
||||
|
||||
**Default:** ``False``
|
||||
|
||||
|
||||
--max-color-depth
|
||||
-----------------
|
||||
*Use separate colors up to package depth of <depth>. Higher depths will reuse colors.*
|
||||
|
||||
**Default:** ``2``
|
||||
|
||||
|
||||
--module-names
|
||||
--------------
|
||||
*Include module name in the representation of classes.*
|
||||
|
||||
**Default:** ``None``
|
||||
|
||||
|
||||
--no-standalone
|
||||
---------------
|
||||
*Only show nodes with connections.*
|
||||
|
||||
**Default:** ``False``
|
||||
|
||||
|
||||
--only-classnames
|
||||
-----------------
|
||||
*Don't show attributes and methods in the class boxes; this disables -f values.*
|
||||
|
||||
**Default:** ``False``
|
||||
|
||||
|
||||
|
||||
|
||||
.. _output-control:
|
||||
|
||||
Output Control
|
||||
==============
|
||||
|
||||
|
||||
--output
|
||||
--------
|
||||
*Create a *.<format> output file if format is available. Available formats are: .dot, .puml, .plantuml, .mmd, .html. Any other format will be tried to be created by using the 'dot' command line tool, which requires a graphviz installation. In this case, these additional formats are available (see `Graphviz output formats <https://graphviz.org/docs/outputs/>`_).*
|
||||
|
||||
**Default:** ``dot``
|
||||
|
||||
|
||||
--output-directory
|
||||
------------------
|
||||
*Set the output directory path.*
|
||||
|
||||
**Default:** ``""``
|
||||
|
||||
|
||||
|
||||
|
||||
.. _project-configuration:
|
||||
|
||||
Project Configuration
|
||||
=====================
|
||||
|
||||
|
||||
--ignore
|
||||
--------
|
||||
*Files or directories to be skipped. They should be base names, not paths.*
|
||||
|
||||
**Default:** ``('CVS',)``
|
||||
|
||||
|
||||
--project
|
||||
---------
|
||||
*Set the project name. This will later be appended to the output file names.*
|
||||
|
||||
**Default:** ``""``
|
||||
|
||||
|
||||
--source-roots
|
||||
--------------
|
||||
*Add paths to the list of the source roots. Supports globbing patterns. The source root is an absolute path or a path relative to the current working directory used to determine a package namespace for modules located under the source root.*
|
||||
|
||||
**Default:** ``()``
|
||||
|
||||
|
||||
--verbose
|
||||
---------
|
||||
*Makes pyreverse more verbose/talkative. Mostly useful for debugging.*
|
||||
|
||||
**Default:** ``False``
|
||||
@ -1,40 +0,0 @@
|
||||
.. _pyreverse:
|
||||
|
||||
=========
|
||||
Pyreverse
|
||||
=========
|
||||
|
||||
``pyreverse`` is a powerful tool that creates UML diagrams from your Python code. It helps you visualize:
|
||||
|
||||
- Package dependencies and structure
|
||||
- Class hierarchies and relationships
|
||||
- Method and attribute organization
|
||||
|
||||
Output Formats
|
||||
==============
|
||||
|
||||
``pyreverse`` supports multiple output formats:
|
||||
|
||||
* Native formats:
|
||||
* ``.dot``/``.gv`` (Graphviz)
|
||||
* ``.puml``/``.plantuml`` (PlantUML)
|
||||
* ``.mmd``/``.html`` (MermaidJS)
|
||||
|
||||
* Additional formats (requires Graphviz installation):
|
||||
* All `Graphviz output formats <https://graphviz.org/docs/outputs/>`_ (PNG, SVG, PDF, etc.)
|
||||
* ``pyreverse`` first generates a temporary ``.gv`` file, which is then fed to Graphviz to generate the final image
|
||||
|
||||
Getting Started
|
||||
===============
|
||||
|
||||
Check out the :doc:`configuration` guide to learn about available options, or see :doc:`output_examples`
|
||||
for sample diagrams and common use cases.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Pyreverse
|
||||
:titlesonly:
|
||||
:hidden:
|
||||
|
||||
configuration
|
||||
output_examples
|
||||
@ -1,40 +0,0 @@
|
||||
Example Output
|
||||
##############
|
||||
|
||||
Example diagrams generated with the ``.puml`` output format are shown below.
|
||||
|
||||
Package Diagram
|
||||
...............
|
||||
|
||||
.. image:: ../../media/pyreverse_example_packages.png
|
||||
:width: 344
|
||||
:height: 177
|
||||
:alt: Package diagram generated by pyreverse
|
||||
:align: center
|
||||
|
||||
Class Diagram
|
||||
.............
|
||||
|
||||
.. image:: ../../media/pyreverse_example_classes.png
|
||||
:width: 625
|
||||
:height: 589
|
||||
:alt: Class diagram generated by pyreverse
|
||||
:align: center
|
||||
|
||||
Creating Class Diagrams for Specific Classes
|
||||
''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
In many cases creating a single diagram depicting all classes in the project yields a rather unwieldy, giant diagram.
|
||||
While limiting the input path to a single package or module can already help greatly to narrow down the scope, the ``-c`` option
|
||||
provides another way to create a class diagram focusing on a single class and its collaborators.
|
||||
For example, running::
|
||||
|
||||
pyreverse -ASmy -c pylint.checkers.classes.ClassChecker pylint
|
||||
|
||||
will generate the full class and package diagrams for ``pylint``, but will additionally generate a file ``pylint.checkers.classes.ClassChecker.dot``:
|
||||
|
||||
.. image:: ../../media/ClassChecker_diagram.png
|
||||
:width: 757
|
||||
:height: 1452
|
||||
:alt: Package diagram generated by pyreverse
|
||||
:align: center
|
||||
@ -1,37 +0,0 @@
|
||||
.. _symilar:
|
||||
|
||||
Symilar
|
||||
-------
|
||||
|
||||
The console script ``symilar`` finds copy pasted block of text in a set of files. It provides a command line interface to check only the ``duplicate-code`` message.
|
||||
|
||||
It can be invoked with::
|
||||
|
||||
symilar [-d|--duplicates min_duplicated_lines] [-i|--ignore-comments] [--ignore-docstrings] [--ignore-imports] [--ignore-signatures] file1...
|
||||
|
||||
All files that shall be checked have to be passed in explicitly, e.g.::
|
||||
|
||||
symilar foo.py, bar.py, subpackage/spam.py, subpackage/eggs.py
|
||||
|
||||
``symilar`` produces output like the following::
|
||||
|
||||
17 similar lines in 2 files
|
||||
==tests/data/clientmodule_test.py:3
|
||||
==tests/data/suppliermodule_test.py:12
|
||||
class Ancestor:
|
||||
""" Ancestor method """
|
||||
cls_member = DoNothing()
|
||||
|
||||
def __init__(self, value):
|
||||
local_variable = 0
|
||||
self.attr = 'this method shouldn\'t have a docstring'
|
||||
self.__value = value
|
||||
|
||||
def get_value(self):
|
||||
""" nice docstring ;-) """
|
||||
return self.__value
|
||||
|
||||
def set_value(self, value):
|
||||
self.__value = value
|
||||
return 'this method shouldn\'t have a docstring'
|
||||
TOTAL lines=58 duplicates=17 percent=29.31
|
||||
@ -1,310 +0,0 @@
|
||||
# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
# For details: https://github.com/pylint-dev/pylint/blob/main/LICENSE
|
||||
# Copyright (c) https://github.com/pylint-dev/pylint/blob/main/CONTRIBUTORS.txt
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
# Pylint documentation build configuration file, created by
|
||||
# sphinx-quickstart on Thu Apr 4 20:31:25 2013.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use 'os.path.abspath' to make it absolute, like shown here.
|
||||
sys.path.append(os.path.abspath("exts"))
|
||||
sys.path.append(os.path.abspath(".."))
|
||||
|
||||
# pylint: disable=wrong-import-position
|
||||
from pylint import __version__
|
||||
from pylint.__pkginfo__ import numversion
|
||||
|
||||
# pylint: enable=wrong-import-position
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = [
|
||||
"pylint_features",
|
||||
"pylint_extensions",
|
||||
"pylint_messages",
|
||||
"pylint_options",
|
||||
"pyreverse_configuration",
|
||||
"sphinx.ext.autosectionlabel",
|
||||
"sphinx.ext.intersphinx",
|
||||
"sphinx_reredirects",
|
||||
]
|
||||
|
||||
|
||||
# Single file redirects are handled in this file and can be done by a pylint
|
||||
# contributor. We use the following extension:
|
||||
# https://documatt.gitlab.io/sphinx-reredirects/usage.html
|
||||
# Directory redirects are handled in ReadTheDoc admin interface and can only be done
|
||||
# by pylint maintainers at the following URL:
|
||||
# https://readthedocs.org/dashboard/pylint/redirects/
|
||||
redirects: dict[str, str] = {
|
||||
# "<source>": "<target>"
|
||||
"additional_commands/index": "../index.html",
|
||||
"development_guide/index": "api/index.html",
|
||||
"development_guide/contribute": "../development_guide/contributor_guide/index.html",
|
||||
"development_guide/contributor_guide": "contributor_guide/index.html",
|
||||
"development_guide/profiling": "../development_guide/contributor_guide/profiling.html",
|
||||
"development_guide/tests/index": "../contributor_guide/tests/index.html",
|
||||
"development_guide/tests/install": "../contributor_guide/tests/install.html",
|
||||
"development_guide/tests/launching_test": "../contributor_guide/tests/launching_test.html",
|
||||
# There was a typo in the original file, don't fix.
|
||||
"development_guide/tests/writting_test": "../contributor_guide/tests/writing_test.html",
|
||||
"development/testing": "tests/index.html",
|
||||
"how_tos/custom_checkers": "../development_guide/how_tos/custom_checkers.html",
|
||||
"how_tos/index": "../development_guide/how_tos/index.html",
|
||||
"how_tos/plugins": "../development_guide/how_tos/plugins.html",
|
||||
"how_tos/transform_plugins": "../development_guide/how_tos/transform_plugins.html",
|
||||
"intro": "index.html",
|
||||
"messages/messages_introduction": "../user_guide/messages/index.html",
|
||||
"messages/messages_list": "../user_guide/messages/messages_overview.html",
|
||||
"support": "contact.html",
|
||||
"technical_reference/c_extensions": "../user_guide/messages/error/no-member.html",
|
||||
"technical_reference/extensions": "../user_guide/checkers/extensions.html",
|
||||
"technical_reference/checkers": "../development_guide/technical_reference/checkers.html",
|
||||
"technical_reference/features": "../user_guide/checkers/features.html",
|
||||
"technical_reference/index": "../development_guide/technical_reference/index.html",
|
||||
"technical_reference/startup": "../development_guide/technical_reference/startup.html",
|
||||
"user_guide/configuration/naming-styles": "../user_guide/messages/convention/invalid-name.html",
|
||||
"user_guide/ide_integration/flymake-emacs": "../installation/ide_integration/flymake-emacs.html",
|
||||
"user_guide/ide_integration/ide-integration": "../installation/ide_integration/index.html",
|
||||
"user_guide/ide-integration": "installation.html",
|
||||
"user_guide/ide_integration/textmate": "../installation/ide_integration/textmate.html",
|
||||
"user_guide/index": "installation/index.html",
|
||||
"user_guide/message-control": "messages/message_control.html",
|
||||
"user_guide/options": "configuration/all-options.html",
|
||||
"user_guide/output": "usage/output.html",
|
||||
"user_guide/pre-commit-integration": "installation/pre-commit-integration.html",
|
||||
"user_guide/run": "usage/run.html",
|
||||
"pyreverse": "additional_tools/pyreverse/index.html",
|
||||
"symilar": "additional_tools/symilar/index.html",
|
||||
}
|
||||
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ["_templates"]
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = ".rst"
|
||||
|
||||
# The encoding of source files.
|
||||
# source_encoding = 'utf-8-sig'
|
||||
|
||||
# The root toctree document.
|
||||
root_doc = "index"
|
||||
|
||||
# General information about the project.
|
||||
project = "Pylint"
|
||||
current_year = datetime.utcnow().year
|
||||
contributors = "Logilab and Pylint contributors"
|
||||
copyright = f"2003-{current_year}, {contributors}" # pylint: disable=redefined-builtin
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
# The short X.Y version.
|
||||
version = f"{numversion[0]}.{numversion[1]}"
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = __version__
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
# language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
# today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
# today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ["_build", "data/**", "whatsnew/fragments"]
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
# default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
# add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
# add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
# show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = "sphinx"
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
# modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = "furo"
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
# Currently we use the default Furo configuration
|
||||
# html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
# html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
# html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
# html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
# html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
# html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
# html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
html_last_updated_fmt = "%b %d, %Y"
|
||||
|
||||
smartquotes = False
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
# Currently we use the default Furo Sidebar
|
||||
# html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
# html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
# html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
# html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
# html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
# html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
# html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
# html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
# html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = "Pylintdoc"
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
# The paper size ('letter' or 'a4').
|
||||
# latex_paper_size = 'letter'
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
# latex_font_size = '10pt'
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
(
|
||||
"index",
|
||||
"Pylint.tex",
|
||||
"Pylint Documentation",
|
||||
contributors,
|
||||
"manual",
|
||||
)
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
# latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
# latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
# latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
# latex_show_urls = False
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
# latex_preamble = ''
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
# latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
# latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [("index", "pylint", "Pylint Documentation", [contributors], 1)]
|
||||
|
||||
# pylint: disable-next=consider-using-namedtuple-or-dataclass
|
||||
intersphinx_mapping = {
|
||||
"astroid": ("https://pylint.readthedocs.io/projects/astroid/en/latest/", None),
|
||||
"python": ("https://docs.python.org/3", None),
|
||||
}
|
||||
|
||||
# Prevent label issues due to colliding section names
|
||||
# through including multiple documents
|
||||
autosectionlabel_prefix_document = True
|
||||
|
||||
# Permit duplicated titles in the resulting document.
|
||||
# See https://github.com/pylint-dev/pylint/issues/7362#issuecomment-1256932866
|
||||
autosectionlabel_maxdepth = 2
|
||||
|
||||
linkcheck_ignore = [
|
||||
"https://github.com/pylint-dev/pylint/blob/main/pylint/extensions/.*"
|
||||
]
|
||||
@ -1,58 +0,0 @@
|
||||
Contact
|
||||
=======
|
||||
|
||||
Bug reports, feedback
|
||||
---------------------
|
||||
.. _bug reports, feedback:
|
||||
|
||||
You think you have found a bug in Pylint? Well, this may be the case
|
||||
since Pylint and Python are under heavy development!
|
||||
|
||||
Please take the time to check if it is already in the issue tracker at
|
||||
https://github.com/pylint-dev/pylint
|
||||
|
||||
Note that the issue might also be reported in one of Pylint's major dependencies,
|
||||
astroid:
|
||||
|
||||
* https://github.com/pylint-dev/astroid
|
||||
|
||||
Discord server
|
||||
--------------
|
||||
|
||||
You can discuss your problem using the discord server:
|
||||
|
||||
https://discord.com/invite/Egy6P8AMB5
|
||||
|
||||
Mailing lists
|
||||
-------------
|
||||
|
||||
.. _Mailing lists:
|
||||
|
||||
The code-quality mailing list is shared with other tools that aim
|
||||
at improving the quality of python code.
|
||||
|
||||
You can subscribe to this mailing list at
|
||||
https://mail.python.org/mailman3/lists/code-quality.python.org/
|
||||
|
||||
Archives are available at
|
||||
https://mail.python.org/pipermail/code-quality/
|
||||
|
||||
Archives before April 2013 are not available anymore. At
|
||||
https://mail.python.org/pipermail/ it was under ``python-projects``.
|
||||
|
||||
Support
|
||||
-------
|
||||
|
||||
.. image:: media/Tidelift_Logos_RGB_Tidelift_Shorthand_On-White.png
|
||||
:height: 150
|
||||
:alt: Tidelift
|
||||
:align: left
|
||||
:class: tideliftlogo
|
||||
|
||||
Professional support for pylint is available as part of the `Tidelift
|
||||
Subscription`_. Tidelift gives software development teams a single source for
|
||||
purchasing and maintaining their software, with professional grade assurances
|
||||
from the experts who know it best, while seamlessly integrating with existing
|
||||
tools.
|
||||
|
||||
.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-pylint?utm_source=pypi-pylint&utm_medium=referral&utm_campaign=readme
|
||||
@ -1,10 +0,0 @@
|
||||
import abc
|
||||
|
||||
|
||||
class Animal(abc.ABC):
|
||||
@abc.abstractmethod
|
||||
def make_sound(self):
|
||||
pass
|
||||
|
||||
|
||||
sheep = Animal() # [abstract-class-instantiated]
|
||||
@ -1,15 +0,0 @@
|
||||
import abc
|
||||
|
||||
|
||||
class Animal(abc.ABC):
|
||||
@abc.abstractmethod
|
||||
def make_sound(self):
|
||||
pass
|
||||
|
||||
|
||||
class Sheep(Animal):
|
||||
def make_sound(self):
|
||||
print("bhaaaaa")
|
||||
|
||||
|
||||
sheep = Sheep()
|
||||
@ -1,11 +0,0 @@
|
||||
import abc
|
||||
|
||||
|
||||
class WildAnimal:
|
||||
@abc.abstractmethod
|
||||
def make_sound(self):
|
||||
pass
|
||||
|
||||
|
||||
class Panther(WildAnimal): # [abstract-method]
|
||||
pass
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue