Skip to content

Conversation

@G-Rath
Copy link
Contributor

@G-Rath G-Rath commented May 26, 2025

As discussed this adds an initial pyi file that types markdownify enough that checkers like mypy should be happy for consumers to use markdownify in a strongly typed context.

The types are by no means compete, but from here they can be easily iterated on and improved - I've not included setting up mypy checking as part of this as my understanding is it won't do anything given this is a single file

Resolves #215

@G-Rath
Copy link
Contributor Author

G-Rath commented Jun 29, 2025

@AlexVonB @chrispy-snps friendly bump in case you missed this 🙂

@AlexVonB
Copy link
Collaborator

AlexVonB commented Jul 9, 2025

Sorry for the wait! Quick question before I merge this: is there a sensible way to test this in our pipeline? Or even manually? I just would like to check this branch out, do something that confirms that this works, and the merge it.

@G-Rath
Copy link
Contributor Author

G-Rath commented Jul 9, 2025

Let me fire up a codespace and have a playaround - I can say they work as we're using them in this repository and so if I remove that file then poetry run mypy . will give errors about the package being untyped.

I expect you should be able to replicate that to some degree, but I'm not sure how much it will just work when you're running mypy in the source package

@G-Rath
Copy link
Contributor Author

G-Rath commented Jul 9, 2025

ok so it looks like an easy way to get very basic checking is to just run mypy without strict mode - this means it doesn't catch much (notably things like parameters don't seemed to be checked, which is sad for this), but it's still better than nothing.

For more strict type checking without requiring the whole codebase to immediately use types, we should be fine to add a dedicated Python file that we can run --strict mode on, and then that'd catch more stuff (in fact, doing so already found a bug in the types!); for now I've just pushed up the basic CI check to get the ball rolling - I've also done this as a new job as I'm not super familiar with tox and co, but happy to be told what to do for integrating it into the existing job

@chrispy-snps
Copy link
Collaborator

The advantage of a sidefile-based approach is that it imposes no constraint on the Python version. The disadvantage is that it requires more work to keep it synchronized with the code itself, especially when code is refactored and functions get changed/added/deleted.

PEP 484 typing annotations were introduced in Python 3.5, which was released ten years ago. Perhaps it is time to raise our minimum required Python version and modernize our code?

@G-Rath
Copy link
Contributor Author

G-Rath commented Jul 10, 2025

@chrispy-snps I think that is a good idea, but I expect it would take longer than shipping these types which is why my recommendation is to do this in the short-term so that downstream consumers (like myself) can start relying on the types from the package rather than having to maintain them ourselves (especially as I expect dropping Python versions will require a new major version of the package)

@chrispy-snps
Copy link
Collaborator

@G-Rath - is your thinking to release the *.pyi files now in a minor release, then replace them with inline typing annotations (i.e., delete the *.pyi files) in a future major release?

@G-Rath
Copy link
Contributor Author

G-Rath commented Jul 10, 2025

@chrispy-snps yup exactly

@chrispy-snps
Copy link
Collaborator

@G-Rath - thanks!

@AlexVonB - I did not do any testing, but if both of you are agreeable to it, I'm also agreeable to merging this and shipping a release to get this into production for @G-Rath.

@G-Rath G-Rath force-pushed the G-Rath-patch-1 branch 2 times, most recently from f793b87 to b54501e Compare July 14, 2025 19:54
@G-Rath G-Rath force-pushed the G-Rath-patch-1 branch 3 times, most recently from 1f50d19 to c3a85b2 Compare July 14, 2025 20:57
@G-Rath G-Rath force-pushed the G-Rath-patch-1 branch 3 times, most recently from 5ee2435 to 4ed274b Compare July 14, 2025 21:06
@G-Rath
Copy link
Contributor Author

G-Rath commented Jul 14, 2025

@AlexVonB @chrispy-snps I think this should be very good to go now!

I've introduced a new tests/types.py file with some real-world function calls based on the docs and tests that we can run strict typechecking on to ensure the types are right - there are still some types missing, but this should definitely let someone get started in a type-safe context and it should be easy to add to later (which I'm happy to help with too).

Some general notes:

  • In Python v3.10+ the Union type can be replaced with x | y syntax
  • In Python v3.12+ the options can be deduplicated using TypedDict and Unpack
  • I've not used types from BeautifulSoup for code_language_callback as I'm not sure how the dependency specification works i.e. would this package need to somehow expression it has an optional dependency on types-beautifulsoup4, will tools handle that themselves, or ...?
  • I've typed a lot of the constant-based options like bullets and heading_style as accepting strings, when they should probably accept a more specific type in the long-run

I'm happy to do follow-ups for these, I just think the current types are a good starting point to ship first

@AlexVonB
Copy link
Collaborator

AlexVonB commented Jul 15, 2025

Looks good to me! @chrispy-snps we should take extra care with future new options: they should be not only added to the CLI, but now also to the types. Maybe we could add a merge request template for this? If you are fine with this MR, please merge it! :)

@G-Rath Thank you very much for your work and patience! It is greatly appreciated!

@chrispy-snps chrispy-snps merged commit 85ef82e into matthewwithanm:develop Aug 3, 2025
2 checks passed
@chrispy-snps
Copy link
Collaborator

@AlexVonB - I'm on vacation for the next week. If you have time to spin a new public build, that's great! If not, I can do it when I get back.

@G-Rath G-Rath deleted the G-Rath-patch-1 branch August 3, 2025 18:59
@AlexVonB
Copy link
Collaborator

AlexVonB commented Aug 9, 2025

@chrispy-snps done! :) have a nice vacation!

@G-Rath
Copy link
Contributor Author

G-Rath commented Aug 9, 2025

@AlexVonB thanks for the release, but I think the package needs to include a py.typed file as well to have mypy pick it up:

drupal-advisory-database on  update-markdownify [$✘!?] via  v20.19.0 via 🐍 v3.13.5
❯ poetry run mypy .
scripts/generate_osv_advisories.py:19: error: Skipping analyzing "markdownify": module is installed, but missing library stubs or py.typed marker  [import-untyped]
scripts/generate_osv_advisories.py:19: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
Found 1 error in 1 file (checked 11 source files)

From https://mypy.readthedocs.io/en/stable/installed_packages.html#creating-pep-561-compatible-packages:

Some packages have a mix of stub files and runtime files. These packages also require a py.typed file.

I have opened #235 adding this

G-Rath added a commit to DrupalSecurityTeam/drupal-advisory-database that referenced this pull request Nov 19, 2025
The type definitions have been landed upstream so we no longer need to
maintain them here

~(this is blocked until [a new version is released with a `py.typed`
file](matthewwithanm/python-markdownify#221 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Shipping types for type-checking

3 participants