Try this tool today

Accelerate your vibe coding workflow with our partner link.

Get Started →

GitHub Copilot is an AI pair programmer that suggests code, entire functions, and even full test suites directly in the editor, powered by large language models trained on public GitHub repositories. It matters most when writing new code, refactoring legacy systems, or learning unfamiliar APIs—especially during the first 20 minutes of a new task, where context and syntax are still forming.

Writing Functions

When writing a new function, GitHub Copilot generates suggestions based on the function signature, docstring, and surrounding code. The model uses the current file context, including imports, class definitions, and prior functions.

To trigger a suggestion, place the cursor inside a function definition and press Ctrl+Space (or Cmd+Space on macOS). The editor displays one or more code completions in a sidebar or inline.

def calculate_total_price(items: list[dict]) -> float:
    """
    Compute the total price of a list of items with quantity and unit price.
    """
    total = 0.0
    for item in items:
        total += item["quantity"] * item["unit_price"]
    return total

Copilot suggests:

  • A full implementation using sum and generator expressions.
  • A version using map and operator.mul.
  • A test case using unittest.TestCase.

The user can accept a suggestion with Enter, navigate through alternatives with Tab, and apply all suggestions with Ctrl+Enter.

The model also infers type hints from the code body and suggests them in the function signature:

def process_user_data(data: dict) -> dict:
    """
    Transform raw user data into a standardized format.
    """
    transformed = {}
    for key, value in data.items():
        if isinstance(value, str):
            transformed[key] = value.strip().lower()
        elif isinstance(value, (int, float)):
            transformed[key] = round(value, 2)
        else:
            transformed[key] = str(value)
    return transformed

Copilot may suggest:

  • Adding from typing import Dict, List, Any to the imports.
  • Adding @dataclass to the function body.
  • Adding @staticmethod to a related utility function.

Writing Tests

When writing tests, Copilot generates test cases based on the function signature and docstring. It assumes standard test patterns: unittest.TestCase, pytest, or nose style.

In a test_calculations.py file:

import unittest
from mylib import calculate_total_price

class TestCalculateTotalPrice(unittest.TestCase):
    def test_empty_list(self):
        self.assertEqual(calculate_total_price([]), 0.0)

    def test_single_item(self):
        items = [{"quantity": 2, "unit_price": 10.0}]
        self.assertEqual(calculate_total_price(items), 20.0)

Place the cursor inside test_single_item and press Ctrl+Space. Copilot suggests:

  • A test case with multiple items, varying quantities and prices.
  • A test with assertAlmostEqual instead of assertEqual.
  • A test that checks edge cases: negative quantities, zero prices, nested data.

Copilot also generates the setUp method:

def setUp(self):
    self.items = [
        {"quantity": 1, "unit_price": 5.0},
        {"quantity": 3, "unit_price": 2.5},
        {"quantity": 2, "unit_price": 1.0},
    ]

The model uses the full scope of the test class and module, including imported functions and fixtures.

Refactoring Code

When refactoring, Copilot suggests entire rewrites based on a code comment or function purpose.

Given a function with a comment:

def find_users_with_active_orders():
    """
    Fetch users who have at least one active order.
    Returns a list of user dictionaries with 'id', 'name', and 'email'.
    """
    # Fetch all users
    users = db.execute("SELECT id, name, email FROM users")
    # Fetch all active orders
    active_orders = db.execute("SELECT user_id FROM orders WHERE status = 'active'")
    # Filter users with active orders
    result = []
    for user in users:
        for order in active_orders:
            if user["id"] == order["user_id"]:
                result.append(user)
                break
    return result

Copilot suggests replacing the nested loop with a JOIN query:

def find_users_with_active_orders():
    """
    Fetch users who have at least one active order.
    Returns a list of user dictionaries with 'id', 'name', and 'email'.
    """
    query = """
        SELECT DISTINCT u.id, u.name, u.email
        FROM users u
        INNER JOIN orders o ON u.id = o.user_id
        WHERE o.status = 'active'
    """
    return db.execute(query)

It also suggests adding @cached_property to a class method, or extracting a helper function from a long block.

Writing Configuration Files

In configuration files, Copilot generates structure, keys, and example values.

For a pyproject.toml file:

[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[tool.black]
line-length = 88
target-version = ["py38"]

Place the cursor at the tool.black section and press Ctrl+Space. Copilot suggests:

  • Adding include and exclude patterns.
  • Setting string_normalization = true.
  • Adding [tool.mypy] section with python_version = "3.10" and strict = true.

The suggestions are based on the typical structure of pyproject.toml files and common patterns in Python projects.

In docker-compose.yml:

version: "3.8"
services:
  web:
    build: .
    ports:
      - "8000:8000"

Copilot suggests:

  • Adding environment variables.
  • Adding volumes to mount source code.
  • Adding depends_on for a database service.

Writing Documentation

When writing docstrings, Copilot generates the full body based on the function’s purpose.

In a README.md file:



This library provides tools for processing user data.

## Usage

```python
from mylib import process_user_data
data = {
    "name": "Alice",
    "age": 30,
    "preferences": {"theme": "dark", "notifications": True}
}
result = process_user_data(data)

Place the cursor inside the ## Usage section and press Ctrl+Space. Copilot suggests:

  • A full example with json serialization.
  • A try-except block for error handling.
  • A # Configuration section with environment variables.
  • A # Example Output section with a sample JSON response.

Copilot also generates the docstring for a function based on its name and parameters:

def extract_user_id(user_data: dict) -> int:
    """
    Extract the user ID from a dictionary of user data.
    Returns the ID, or raises a KeyError if missing.
    """
    return user_data["id"]

Working with APIs

When writing API clients, Copilot suggests complete request bodies and response handlers.

In a api.py file:

import requests

def fetch_user_profile(user_id: int) -> dict:
    """
    Fetch the profile of a user by ID.
    Returns a dictionary with user information.
    """
    url = f"https://api.example.com/users/{user_id}"
    response = requests.get(url)
    return response.json()

Copilot suggests:

  • Adding error handling with try-except and raise.
  • Adding headers and timeout to the request.
  • Adding @lru_cache to the function.
def fetch_user_profile(user_id: int) -> dict:
    """
    Fetch the profile of a user by ID.
    Returns a dictionary with user information.
    """
    url = f"https://api.example.com/users/{user_id}"
    headers = {"Accept": "application/json", "Authorization": "Bearer <token>"}
    try:
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        raise RuntimeError(f"Failed to fetch user {user_id}") from e

Copilot also generates the schema for the expected response:

# Expected response schema:
{
    "id": 123,
    "name": "Alice",
    "email": "[email protected]",
    "created_at": "2023-01-01T10:00:00Z",
    "preferences": {
        "theme": "dark",
        "notifications": True
    }
}

Common Failure Modes

  • Copilot suggests incorrect function signature: The model infers types from the code body, but sometimes the inferred types don’t match the actual API. For example, a function expecting List[dict] receives List[User] where User is a dataclass. The suggestion uses User fields but the function expects dict keys.
  • Copilot generates code that uses undefined variables: The model assumes a variable exists but it is not in scope. For example, a function uses config, but config is defined in a settings.py file not imported.
  • Copilot suggests redundant imports: It adds import os and import json even though both are already imported in the file.
  • Copilot does not update suggestions after changes: After editing a function, Copilot does not re-suggest changes unless the cursor is moved or a new line is added.
  • Copilot misses context from other files: When a function is called from another file, Copilot often fails to include that file’s content in the context.
  • Copilot suggests code that is too abstract or too specific: It generates code that is too generic (e.g., using map and filter for simple loops) or too concrete (e.g., hardcoding values instead of using variables).

Configuration Keys

Copilot is configured via a .github/copilot.yml file in the repository root. The file supports the following keys:

# .github/copilot.yml
# Configuration for GitHub Copilot in this repository.

# Enable Copilot in all files
enable: true

# Define file-specific rules
files:
  # Apply to all Python files
  "*.py":
    # Enable all suggestions
    suggest-all: true
    # Enable test generation
    generate-tests: true
    # Enable documentation generation
    generate-docstrings: true
    # Include docstrings in suggestions
    include-docstrings: true
    # Set maximum context size
    context-size: 1000

  # Apply to test files
  "test_*.py":
    suggest-all: true
    generate-tests: true
    include-docstrings: true
    context-size: 1500

  # Apply to API-related files
  "api/*.py":
    suggest-all: true
    generate-tests: true
    generate-docstrings: true
    context-size: 2000

# Enable Copilot in specific directories
directories:
  "src/":
    suggest-all: true
    generate-tests: true
    generate-docstrings: true
    context-size: 1000

  "docs/":
    suggest-all: false
    generate-docstrings: true
    context-size: 500

The context-size value is the number of tokens (words and punctuation) used from the file and surrounding files to generate suggestions.

Integration with Editor Extensions

Copilot integrates with all major editors via standard extension mechanisms. The following extensions are used:

  • VS Code: GitHub Copilot extension, version 1.20.0, with copilot as the language server.
  • Neovim: nvim-copilot with copilot-lua as the backend.
  • Sublime Text: GitHub Copilot via sublime-copilot.

The extension communicates with the Copilot backend via a WebSocket connection. The server sends textDocument/completion requests with the current file, cursor position, and context.

The server responds with a list of CompletionItem objects, each with:

  • label: the suggested code snippet.
  • insertText: the code to insert.
  • documentation: a Markdown-formatted description.
  • detail: a short description.
  • additionalTextEdits: a list of TextEdit objects to apply after insertion.

Example response:

{
  "items": [
    {
      "label": "calculate_total_price",
      "insertText": "def calculate_total_price(items: list[dict]) -> float:\n    total = 0.0\n    for item in items:\n        total += item[\"quantity\"] * item[\"unit_price\"]\n    return total",
      "documentation": "Compute the total price of a list of items with quantity and unit price.",
      "detail": "Calculate total price from list of items.",
      "additionalTextEdits": [
        {
          "range": {
            "start": { "line": 0, "character": 0 },
            "end": { "line": 0, "character": 0 }
          },
          "newText": "from typing import List, Dict\n\n"
        }
      ]
    }
  ]
}

Error Messages

When Copilot fails to generate a suggestion, the editor displays an error message:

Copilot: Failed to generate suggestions
Reason: Timeout while waiting for server response

The user can manually trigger a refresh with Ctrl+Shift+P and selecting Copilot: Refresh Suggestions.

When a suggestion is incomplete, the editor shows a warning:

Copilot: Missing context for function 'process_user_data'
Suggested context: ['user_data', 'db', 'settings']
Missing files: ['database.py', 'settings.py']

When a file is too large, Copilot truncates the context and shows:

Copilot: Context truncated
Context includes only first 1000 tokens of file.

Advanced Usage

  • Custom Prompts: Users can write custom prompts in copilot.prompts files, which are loaded on startup.
  • Inline Suggestions: Copilot shows suggestions inline, with multiple suggestions side by side.
  • Tab Completion: Tab cycles through multiple suggestions; Shift+Tab cycles backward.
  • Accept All Suggestions: Ctrl+Enter applies all suggestions in the current file.
  • Suggestion History: The editor maintains a history of past suggestions, accessible via Ctrl+Shift+P.
  • Copilot Chat: A sidebar panel allows users to chat with Copilot about code, design, or deployment.

This page was rewritten on 11 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.