พาธไปยังการพิมพ์โค้ด Python 4 ล้านบรรทัด ส่วนที่ 3

เรานำเสนอให้คุณทราบถึงส่วนที่สามของการแปลเนื้อหาเกี่ยวกับเส้นทางที่ Dropbox ใช้เมื่อใช้ระบบตรวจสอบประเภทสำหรับโค้ด Python

พาธไปยังการพิมพ์โค้ด Python 4 ล้านบรรทัด ส่วนที่ 3

→ ส่วนก่อนหน้า: เป็นครั้งแรก и ที่สอง

จำนวนโค้ดที่พิมพ์ถึง 4 ล้านบรรทัด

ความท้าทายที่สำคัญอีกประการหนึ่ง (และข้อกังวลที่พบบ่อยเป็นอันดับสองในบรรดาผู้ตอบแบบสำรวจภายใน) คือการเพิ่มจำนวนโค้ดที่ครอบคลุมโดยการตรวจสอบประเภทใน Dropbox เราได้ลองใช้แนวทางต่างๆ มากมายในการแก้ปัญหานี้ ตั้งแต่การเพิ่มขนาดของโค้ดเบสที่พิมพ์อย่างเป็นธรรมชาติ ไปจนถึงการเน้นไปที่ความพยายามของทีม mypy ในการอนุมานประเภทอัตโนมัติแบบคงที่และไดนามิก ในท้ายที่สุด ดูเหมือนว่าไม่มีกลยุทธ์ง่ายๆ ในการเอาชนะ แต่เราสามารถบรรลุการเติบโตอย่างรวดเร็วในปริมาณของโค้ดที่มีคำอธิบายประกอบด้วยการผสมผสานหลายๆ แนวทางเข้าด้วยกัน

ด้วยเหตุนี้ พื้นที่เก็บข้อมูล Python ที่ใหญ่ที่สุดของเรา (พร้อมโค้ดแบ็กเอนด์) จึงมีโค้ดที่มีคำอธิบายประกอบเกือบ 4 ล้านบรรทัด งานเกี่ยวกับการพิมพ์โค้ดแบบคงที่แล้วเสร็จภายในเวลาประมาณสามปี ขณะนี้ Mypy รองรับรายงานการครอบคลุมโค้ดหลายประเภท ซึ่งทำให้ง่ายต่อการตรวจสอบความคืบหน้าในการพิมพ์ โดยเฉพาะเราสามารถสร้างรายงานเกี่ยวกับโค้ดที่มีความคลุมเครือในประเภทต่างๆ เช่น การใช้ประเภทอย่างชัดเจน Any ในคำอธิบายประกอบที่ไม่สามารถตรวจสอบได้ หรือกับสิ่งต่างๆ เช่น การนำเข้าไลบรารีของบุคคลที่สามที่ไม่มีคำอธิบายประกอบประเภท ในฐานะส่วนหนึ่งของโครงการเพื่อปรับปรุงความแม่นยำของการตรวจสอบประเภทใน Dropbox เราได้มีส่วนในการปรับปรุงคำจำกัดความของประเภท (ที่เรียกว่าไฟล์ stub) สำหรับไลบรารีโอเพ่นซอร์สยอดนิยมบางรายการในพื้นที่เก็บข้อมูล Python แบบรวมศูนย์ พิมพ์แล้ว.

เราใช้ (และเป็นมาตรฐานใน PEP ต่อมา) คุณสมบัติใหม่ของระบบประเภทที่ช่วยให้ประเภทที่แม่นยำยิ่งขึ้นสำหรับรูปแบบ Python เฉพาะบางอย่าง ตัวอย่างที่โดดเด่นของเรื่องนี้ก็คือ TypeDictซึ่งจัดเตรียมประเภทสำหรับพจนานุกรมที่คล้ายกับ JSON ซึ่งมีชุดคีย์สตริงคงที่ โดยแต่ละประเภทมีค่าเป็นประเภทของตัวเอง เราจะขยายระบบประเภทต่อไป ขั้นตอนต่อไปของเราน่าจะเป็นการปรับปรุงการรองรับความสามารถเชิงตัวเลขของ Python

พาธไปยังการพิมพ์โค้ด Python 4 ล้านบรรทัด ส่วนที่ 3
จำนวนบรรทัดของโค้ดที่มีคำอธิบายประกอบ: เซิร์ฟเวอร์

พาธไปยังการพิมพ์โค้ด Python 4 ล้านบรรทัด ส่วนที่ 3
จำนวนบรรทัดของโค้ดที่มีคำอธิบายประกอบ: client

พาธไปยังการพิมพ์โค้ด Python 4 ล้านบรรทัด ส่วนที่ 3
จำนวนบรรทัดทั้งหมดของโค้ดที่มีคำอธิบายประกอบ

ต่อไปนี้คือภาพรวมของคุณสมบัติหลักของสิ่งที่เราทำเพื่อเพิ่มจำนวนโค้ดที่มีคำอธิบายประกอบใน Dropbox:

ความเข้มงวดของคำอธิบายประกอบ เราค่อยๆ เพิ่มข้อกำหนดสำหรับความเข้มงวดในการใส่คำอธิบายประกอบโค้ดใหม่ เราเริ่มต้นด้วยคำแนะนำเบื้องต้นที่แนะนำให้เพิ่มคำอธิบายประกอบให้กับไฟล์ที่มีคำอธิบายประกอบอยู่แล้ว ตอนนี้เราต้องการคำอธิบายประกอบประเภทในไฟล์ Python ใหม่และในไฟล์ที่มีอยู่ส่วนใหญ่

การพิมพ์รายงาน เราส่งรายงานประจำสัปดาห์ให้กับทีมเกี่ยวกับระดับการพิมพ์โค้ดและให้คำแนะนำเกี่ยวกับสิ่งที่ควรใส่คำอธิบายประกอบก่อน

ความนิยมของ mypy เราพูดคุยเกี่ยวกับ mypy ในกิจกรรมต่างๆ และพูดคุยกับทีมเพื่อช่วยพวกเขาในการเริ่มต้นใช้คำอธิบายประกอบประเภท

โพล เราทำการสำรวจผู้ใช้เป็นระยะเพื่อระบุปัญหาสำคัญ เราพร้อมที่จะแก้ไขปัญหาเหล่านี้ไปไกลแล้ว (แม้แต่การสร้างภาษาใหม่เพื่อเร่งความเร็ว mypy!)

ผลงาน. เราได้ปรับปรุงประสิทธิภาพของ mypy อย่างมากโดยใช้ daemon และ mypyc ซึ่งทำเพื่อลดความไม่สะดวกที่เกิดขึ้นระหว่างกระบวนการใส่คำอธิบายประกอบ และเพื่อให้สามารถทำงานกับโค้ดจำนวนมากได้

บูรณาการกับบรรณาธิการ เราได้สร้างเครื่องมือเพื่อรองรับการรัน mypy ในโปรแกรมแก้ไขที่ได้รับความนิยมบน Dropbox ซึ่งรวมถึง PyCharm, Vim และ VS Code สิ่งนี้ทำให้กระบวนการใส่คำอธิบายประกอบโค้ดและตรวจสอบการทำงานของโค้ดง่ายขึ้นอย่างมาก การดำเนินการประเภทนี้เป็นเรื่องปกติเมื่อใส่คำอธิบายประกอบโค้ดที่มีอยู่

การวิเคราะห์แบบคงที่ เราสร้างเครื่องมือเพื่ออนุมานลายเซ็นของฟังก์ชันโดยใช้เครื่องมือวิเคราะห์แบบคงที่ เครื่องมือนี้สามารถทำงานได้ในสถานการณ์ที่ค่อนข้างง่ายเท่านั้น แต่ช่วยให้เราเพิ่มความครอบคลุมประเภทโค้ดได้โดยไม่ต้องใช้ความพยายามมากนัก

การสนับสนุนห้องสมุดบุคคลที่สาม หลายโครงการของเราใช้ชุดเครื่องมือ SQLAlchemy ใช้ประโยชน์จากความสามารถแบบไดนามิกของ Python ซึ่งประเภท PEP 484 ไม่สามารถสร้างแบบจำลองได้โดยตรง ตาม PEP 561 เราได้สร้างไฟล์ stub ที่เกี่ยวข้องและเขียนปลั๊กอินสำหรับ mypy (โอเพ่นซอร์ส) ซึ่งปรับปรุงการสนับสนุน SQLAlchemy

ความยากลำบากที่เราพบเจอ

เส้นทางสู่โค้ดที่พิมพ์จำนวน 4 ล้านบรรทัดไม่ใช่เรื่องง่ายสำหรับเราเสมอไป บนเส้นทางนี้เราเจอหลุมบ่อมากมายและทำผิดพลาดหลายประการ นี่คือปัญหาบางส่วนที่เราพบ เราหวังว่าการเล่าเรื่องเหล่านี้จะช่วยให้ผู้อื่นหลีกเลี่ยงปัญหาที่คล้ายกันได้

ไฟล์ที่หายไป เราเริ่มทำงานโดยการตรวจสอบไฟล์จำนวนเล็กน้อยเท่านั้น สิ่งใดที่ไม่รวมอยู่ในไฟล์เหล่านี้ไม่ได้ถูกตรวจสอบ ไฟล์ถูกเพิ่มเข้าไปในรายการการสแกนเมื่อมีคำอธิบายประกอบแรกปรากฏขึ้น หากมีการนำเข้าบางสิ่งจากโมดูลที่อยู่นอกขอบเขตการตรวจสอบ แสดงว่าเรากำลังพูดถึงการทำงานกับค่าต่างๆ เช่น Anyซึ่งไม่ได้ถูกทดสอบเลย ส่งผลให้ความแม่นยำในการพิมพ์ลดลงอย่างมาก โดยเฉพาะในช่วงแรกของการย้ายข้อมูล จนถึงขณะนี้แนวทางนี้ใช้ได้ผลดีอย่างน่าประหลาดใจ แม้ว่าสถานการณ์ทั่วไปก็คือการเพิ่มไฟล์ในขอบเขตของการตรวจสอบเผยให้เห็นปัญหาในส่วนอื่นๆ ของโค้ดเบส ในกรณีที่เลวร้ายที่สุดเมื่อมีการรวมโค้ดสองพื้นที่ที่แยกออกจากกันซึ่งมีการตรวจสอบประเภทแล้วโดยไม่แยกจากกัน ปรากฎว่าประเภทของพื้นที่เหล่านี้เข้ากันไม่ได้ สิ่งนี้นำไปสู่ความจำเป็นในการเปลี่ยนแปลงคำอธิบายประกอบหลายประการ เมื่อมองย้อนกลับไป เราตระหนักดีว่าเราควรเพิ่มโมดูลไลบรารีหลักลงในพื้นที่การตรวจสอบประเภทของ mypy เร็วกว่านี้ นี่จะทำให้งานของเราคาดเดาได้มากขึ้น

การใส่คำอธิบายประกอบโค้ดเก่า เมื่อเราเริ่มต้น เรามีโค้ด Python ที่มีอยู่ประมาณ 4 ล้านบรรทัด เห็นได้ชัดว่าการใส่คำอธิบายประกอบโค้ดทั้งหมดนี้ไม่ใช่เรื่องง่าย เราได้สร้างเครื่องมือที่เรียกว่า PyAnnotate ซึ่งสามารถรวบรวมข้อมูลประเภทในขณะที่การทดสอบดำเนินการ และสามารถเพิ่มคำอธิบายประกอบประเภทให้กับโค้ดของคุณตามข้อมูลที่รวบรวมได้ อย่างไรก็ตาม เรายังไม่เห็นการนำเครื่องมือนี้ไปใช้อย่างแพร่หลายเป็นพิเศษ การรวบรวมข้อมูลประเภททำได้ช้า และคำอธิบายประกอบที่สร้างขึ้นโดยอัตโนมัติมักต้องมีการแก้ไขด้วยตนเองหลายครั้ง เราคิดถึงการเรียกใช้เครื่องมือนี้โดยอัตโนมัติทุกครั้งที่ตรวจสอบโค้ด หรือเกี่ยวกับการรวบรวมข้อมูลประเภทตามการวิเคราะห์คำขอเครือข่ายจริงจำนวนเล็กน้อย แต่ตัดสินใจว่าจะไม่ทำเช่นนั้นเนื่องจากวิธีใดวิธีหนึ่งมีความเสี่ยงเกินไป

ด้วยเหตุนี้ จึงสามารถสังเกตได้ว่าโค้ดส่วนใหญ่ได้รับการใส่คำอธิบายประกอบด้วยตนเองโดยเจ้าของ เพื่อเป็นแนวทางให้กับกระบวนการนี้ในทิศทางที่ถูกต้อง เราได้เตรียมรายงานเกี่ยวกับโมดูลและฟังก์ชันที่สำคัญเป็นพิเศษซึ่งต้องมีการใส่คำอธิบายประกอบ ตัวอย่างเช่น สิ่งสำคัญคือต้องจัดเตรียมคำอธิบายประกอบประเภทสำหรับโมดูลไลบรารีที่ใช้ในหลายร้อยตำแหน่ง แต่บริการเก่าที่ถูกแทนที่ด้วยบริการใหม่ไม่สำคัญอีกต่อไปในการใส่คำอธิบายประกอบ เรากำลังทดลองใช้การวิเคราะห์แบบคงที่เพื่อสร้างคำอธิบายประกอบประเภทสำหรับโค้ดดั้งเดิม

การนำเข้าแบบวนรอบ ข้างต้น ฉันได้พูดคุยเกี่ยวกับการนำเข้าแบบวน (“การพันกันของการพึ่งพา”) ซึ่งการมีอยู่ของสิ่งนี้ทำให้ยากต่อการเร่งความเร็ว mypy นอกจากนี้เรายังต้องทำงานอย่างหนักเพื่อให้ mypy รองรับสำนวนทุกประเภทที่เกิดจากการนำเข้าแบบวนรอบเหล่านี้ เมื่อเร็วๆ นี้เราได้เสร็จสิ้นโครงการออกแบบระบบใหม่ที่สำคัญซึ่งแก้ไขปัญหาส่วนใหญ่ของ mypy เกี่ยวกับการนำเข้าแบบวงกลม ปัญหาเหล่านี้จริงๆ แล้วมีต้นกำเนิดมาจากช่วงแรกๆ ของโปรเจ็กต์ ย้อนกลับไปจาก Alore ซึ่งเป็นภาษาทางการศึกษาที่โปรเจ็กต์ mypy ให้ความสำคัญแต่แรก ไวยากรณ์ Alore ทำให้ง่ายต่อการแก้ไขปัญหาด้วยคำสั่งนำเข้าแบบวนรอบ mypy ยุคใหม่ได้สืบทอดข้อจำกัดบางประการมาจากการใช้งานก่อนหน้านี้ที่มีแนวคิดเรียบง่าย (ซึ่งเหมาะอย่างยิ่งสำหรับ Alore) Python ทำให้การทำงานกับการนำเข้าแบบวงกลมทำได้ยาก สาเหตุหลักมาจากนิพจน์มีความคลุมเครือ ตัวอย่างเช่น การดำเนินการมอบหมายอาจกำหนดนามแฝงประเภทจริงๆ Mypy ไม่สามารถตรวจจับสิ่งนี้ได้เสมอไปจนกว่าลูปการนำเข้าส่วนใหญ่จะได้รับการประมวลผล ไม่มีความคลุมเครือดังกล่าวใน Alore การตัดสินใจที่ไม่ดีในช่วงแรกของการพัฒนาระบบสามารถสร้างความประหลาดใจอันไม่พึงประสงค์ให้กับโปรแกรมเมอร์ในอีกหลายปีต่อมา

ผลลัพธ์: เส้นทางสู่โค้ด 5 ล้านบรรทัดและขอบเขตใหม่

โปรเจ็กต์ mypy พัฒนาไปไกลมาก ตั้งแต่ต้นแบบในยุคแรกๆ ไปจนถึงระบบที่ควบคุมประเภทรหัสการผลิต 4 ล้านบรรทัด เมื่อ mypy พัฒนาขึ้น คำใบ้ประเภทของ Python ก็เป็นมาตรฐาน ทุกวันนี้ ระบบนิเวศอันทรงพลังได้พัฒนาเกี่ยวกับการพิมพ์โค้ด Python มีสถานที่สำหรับการสนับสนุนห้องสมุด มีเครื่องมือเสริมสำหรับ IDE และบรรณาธิการ มีระบบควบคุมหลายประเภท ซึ่งแต่ละประเภทมีข้อดีและข้อเสียของตัวเอง

แม้ว่าการตรวจสอบประเภทจะมีให้ที่ Dropbox แล้ว แต่ฉันเชื่อว่าเรายังอยู่ในช่วงเริ่มต้นของการพิมพ์โค้ด Python ฉันคิดว่าเทคโนโลยีการตรวจสอบประเภทจะยังคงพัฒนาและปรับปรุงต่อไป

หากคุณยังไม่ได้ใช้การตรวจสอบประเภทในโปรเจ็กต์ Python ขนาดใหญ่ โปรดทราบว่าตอนนี้เป็นเวลาที่ดีมากที่จะเริ่มเปลี่ยนไปใช้การพิมพ์แบบคงที่ ฉันได้พูดคุยกับผู้ที่ทำการเปลี่ยนแปลงที่คล้ายกัน ไม่มีใครเสียใจเลย การตรวจสอบประเภททำให้ Python เป็นภาษาที่เหมาะกับการพัฒนาโครงการขนาดใหญ่มากกว่า “Python ทั่วไป”

เรียนผู้อ่าน! คุณใช้การตรวจสอบประเภทในโครงการ Python ของคุณหรือไม่?

พาธไปยังการพิมพ์โค้ด Python 4 ล้านบรรทัด ส่วนที่ 3
พาธไปยังการพิมพ์โค้ด Python 4 ล้านบรรทัด ส่วนที่ 3

ที่มา: will.com

เพิ่มความคิดเห็น