Skip to content

Conversation

@pjonsson
Copy link
Contributor

@pjonsson pjonsson commented Oct 5, 2025

Related Issue(s):

Description:

This takes 23 000us to import on
a Ryzen 9950X3D, and the import
does not seem to be used after
PR #591 was merged.

Tested by making a file called test.py containing:

import pystac

and then inside the Python 3.10 container running uv run python3 ./test.py followed by uv run python3 -X importtime ./test.py > timing.txt 2>&1 a couple of times.

Reasonable timing before change:

import time: self [us] | cumulative | imported package
import time:        89 |         89 |   _io
import time:        18 |         18 |   marshal
import time:       185 |        185 |   posix
import time:       338 |        629 | _frozen_importlib_external
import time:        58 |         58 |   time
import time:       106 |        163 | zipimport
import time:        69 |         69 |     _codecs
import time:       219 |        287 |   codecs
import time:       183 |        183 |   encodings.aliases
import time:       298 |        767 | encodings
import time:        97 |         97 | encodings.utf_8
import time:        41 |         41 | _signal
import time:        23 |         23 |     _abc
import time:       145 |        168 |   abc
import time:       193 |        360 | io
import time:        25 |         25 |       _stat
import time:        80 |        104 |     stat
import time:       564 |        564 |     _collections_abc
import time:        82 |         82 |       genericpath
import time:       136 |        217 |     posixpath
import time:       405 |       1289 |   os
import time:       119 |        119 |   _sitebuiltins
import time:       127 |        127 |     __future__
import time:       118 |        118 |         warnings
import time:        76 |        194 |       importlib
import time:        91 |        284 |     importlib.machinery
import time:        61 |         61 |       importlib._abc
import time:        90 |         90 |           itertools
import time:        92 |         92 |           keyword
import time:       310 |        310 |             _operator
import time:       137 |        447 |           operator
import time:        88 |         88 |           reprlib
import time:        31 |         31 |           _collections
import time:       505 |       1250 |         collections
import time:       173 |        173 |           types
import time:        28 |         28 |           _functools
import time:       298 |        497 |         functools
import time:       264 |       2009 |       contextlib
import time:       113 |       2182 |     importlib.util
import time:       343 |        343 |           enum
import time:        34 |         34 |             _sre
import time:       137 |        137 |               sre_constants
import time:       236 |        373 |             sre_parse
import time:       132 |        537 |           sre_compile
import time:        37 |         37 |           _locale
import time:        78 |         78 |           copyreg
import time:       298 |       1291 |         re
import time:       195 |       1486 |       fnmatch
import time:        30 |         30 |         _winapi
import time:        23 |         23 |         nt
import time:        21 |         21 |         nt
import time:        19 |         19 |         nt
import time:        19 |         19 |         nt
import time:       115 |        224 |       ntpath
import time:        30 |         30 |       errno
import time:        54 |         54 |         urllib
import time:       698 |        698 |         ipaddress
import time:       632 |       1383 |       urllib.parse
import time:       427 |       3549 |     pathlib
import time:       202 |       6342 |   __editable___pystac_1_14_1_finder
import time:        97 |         97 |   _virtualenv
import time:       124 |        124 |   _distutils_hack
import time:        51 |         51 |   sitecustomize
import time:       848 |       8868 | site
import time:        90 |         90 |     collections.abc
import time:      1013 |       1102 |   typing
import time:       189 |        189 |   pystac.errors
import time:        67 |         67 |   pystac.version
import time:       171 |        171 |         math
import time:       136 |        136 |         _datetime
import time:       538 |        844 |       datetime
import time:       145 |        145 |           dateutil._version
import time:       103 |        248 |         dateutil
import time:        28 |         28 |             _string
import time:       453 |        480 |           string
import time:       409 |        409 |             locale
import time:       235 |        643 |           calendar
import time:       165 |        165 |               _struct
import time:        89 |        253 |             struct
import time:       770 |       1023 |           six
import time:       210 |        210 |               numbers
import time:       392 |        601 |             _decimal
import time:       101 |        702 |           decimal
import time:        67 |         67 |           dateutil._common
import time:        90 |         90 |               _bisect
import time:       113 |        203 |             bisect
import time:       166 |        166 |               _weakrefset
import time:       215 |        381 |             weakref
import time:        45 |         45 |             six.moves
import time:       144 |        144 |             dateutil.tz._common
import time:        93 |         93 |             dateutil.tz._factories
import time:        14 |         14 |               six.moves.winreg
import time:        90 |        104 |             dateutil.tz.win
import time:       383 |       1349 |           dateutil.tz.tz
import time:       661 |       4921 |         dateutil.parser._parser
import time:       170 |        170 |         dateutil.parser.isoparser
import time:       121 |       5459 |       dateutil.parser
import time:       271 |       6573 |     pystac.utils
import time:       167 |       6739 |   pystac.media_type
import time:       148 |        148 |   pystac.rel_type
import time:       115 |        115 |           _json
import time:       230 |        345 |         json.scanner
import time:       297 |        641 |       json.decoder
import time:       290 |        290 |       json.encoder
import time:       140 |       1070 |     json
import time:       123 |        123 |             token
import time:       463 |        585 |           tokenize
import time:        73 |        657 |         linecache
import time:       150 |        807 |       traceback
import time:       318 |        318 |       threading
import time:        26 |         26 |       atexit
import time:      1005 |       2155 |     logging
import time:       206 |        206 |             zlib
import time:       109 |        109 |               _compression
import time:       145 |        145 |               _bz2
import time:       135 |        387 |             bz2
import time:       147 |        147 |               _lzma
import time:       117 |        263 |             lzma
import time:       360 |       1214 |           shutil
import time:        83 |         83 |             _random
import time:       110 |        110 |             _sha512
import time:       195 |        387 |           random
import time:       171 |       1771 |         tempfile
import time:       138 |       1908 |       urllib.response
import time:       130 |       2038 |     urllib.error
import time:       144 |        144 |         binascii
import time:       208 |        352 |       base64
import time:        91 |         91 |       email
import time:      1435 |       1435 |         _hashlib
import time:       104 |        104 |         _blake2
import time:       164 |       1702 |       hashlib
import time:       443 |        443 |         http
import time:       212 |        212 |             email.errors
import time:        98 |         98 |                 email.quoprimime
import time:        55 |         55 |                 email.base64mime
import time:        68 |         68 |                     quopri
import time:        84 |        151 |                   email.encoders
import time:       133 |        284 |                 email.charset
import time:       409 |        844 |               email.header
import time:       188 |        188 |                   _socket
import time:        96 |         96 |                     select
import time:       618 |        713 |                   selectors
import time:       173 |        173 |                   array
import time:       889 |       1962 |                 socket
import time:       148 |        148 |                 email._parseaddr
import time:       310 |       2419 |               email.utils
import time:       194 |       3456 |             email._policybase
import time:       319 |       3986 |           email.feedparser
import time:       126 |       4111 |         email.parser
import time:        93 |         93 |           uu
import time:       142 |        142 |           email._encoded_words
import time:        62 |         62 |           email.iterators
import time:       306 |        602 |         email.message
import time:       877 |        877 |           _ssl
import time:      1394 |       2270 |         ssl
import time:       539 |       7964 |       http.client
import time:       800 |      10907 |     urllib.request
import time:        37 |         37 |                 org
import time:        10 |         47 |               org.python
import time:         8 |         54 |             org.python.core
import time:       100 |        153 |           copy
import time:       108 |        261 |         pystac.cache
import time:       201 |        201 |         pystac.serialization.identify
import time:        94 |        555 |       pystac.serialization.common_properties
import time:        77 |         77 |       pystac.serialization.migrate
import time:       100 |        732 |     pystac.serialization
import time:       433 |        433 |               signal
import time:       108 |        108 |               fcntl
import time:        38 |         38 |               msvcrt
import time:        83 |         83 |               _posixsubprocess
import time:       285 |        944 |             subprocess
import time:      1291 |       2234 |           platform
import time:       165 |        165 |           _uuid
import time:       247 |       2646 |         uuid
import time:       475 |        475 |               _ast
import time:       626 |       1101 |             ast
import time:       112 |        112 |                 _opcode
import time:       138 |        250 |               opcode
import time:       322 |        571 |             dis
import time:      1570 |       3241 |           inspect
import time:       467 |       3708 |         dataclasses
import time:       154 |       6506 |       orjson.orjson
import time:        86 |       6592 |     orjson
import time:       562 |        562 |       urllib3.exceptions
import time:       192 |        192 |               urllib3.util.timeout
import time:       262 |        454 |             urllib3.util.connection
import time:       105 |        105 |               urllib3.util.util
import time:        48 |         48 |               brotlicffi
import time:        34 |         34 |               brotli
import time:        29 |         29 |               compression
import time:        28 |         28 |               zstandard
import time:       310 |        552 |             urllib3.util.request
import time:        76 |         76 |             urllib3.util.response
import time:       229 |        229 |             urllib3.util.retry
import time:       156 |        156 |               hmac
import time:      4434 |       4434 |               urllib3.util.url
import time:       183 |        183 |               urllib3.util.ssltransport
import time:       209 |       4981 |             urllib3.util.ssl_
import time:        70 |         70 |             urllib3.util.wait
import time:        98 |       6456 |           urllib3.util
import time:        13 |       6469 |         urllib3.util.connection
import time:       336 |       6804 |       urllib3._base_connection
import time:       453 |        453 |       urllib3._collections
import time:        89 |         89 |       urllib3._version
import time:       152 |        152 |             _heapq
import time:       103 |        254 |           heapq
import time:       108 |        108 |           _queue
import time:       279 |        640 |         queue
import time:        39 |         39 |                 _winapi
import time:        31 |         31 |                 winreg
import time:       139 |        208 |               mimetypes
import time:       125 |        332 |             urllib3.fields
import time:       112 |        443 |           urllib3.filepost
import time:        39 |         39 |             brotlicffi
import time:        32 |         32 |             brotli
import time:       131 |        131 |                     _csv
import time:       179 |        309 |                   csv
import time:       550 |        550 |                   zipfile
import time:       678 |        678 |                   textwrap
import time:        58 |         58 |                       importlib.metadata._functools
import time:       103 |        161 |                     importlib.metadata._text
import time:       219 |        380 |                   importlib.metadata._adapters
import time:       172 |        172 |                   importlib.metadata._meta
import time:       205 |        205 |                   importlib.metadata._collections
import time:        75 |         75 |                   importlib.metadata._itertools
import time:       284 |        284 |                   importlib.abc
import time:       757 |       3405 |                 importlib.metadata
import time:       202 |       3607 |               urllib3.http2
import time:       115 |        115 |               urllib3.http2.probe
import time:        88 |         88 |               urllib3.util.ssl_match_hostname
import time:       474 |       4282 |             urllib3.connection
import time:        56 |         56 |             compression
import time:        33 |         33 |             zstandard
import time:       335 |       4775 |           urllib3.response
import time:       138 |       5355 |         urllib3._request_methods
import time:        75 |         75 |         urllib3.util.proxy
import time:       227 |       6295 |       urllib3.connectionpool
import time:       598 |        598 |       urllib3.poolmanager
import time:       308 |      15106 |     urllib3
import time:       238 |      38834 |   pystac.stac_io
import time:       648 |        648 |       html.entities
import time:       329 |        976 |     html
import time:        71 |         71 |         pystac.html.jinja_env
import time:        88 |        159 |       pystac.html
import time:        11 |        170 |     pystac.html.jinja_env
import time:       211 |        211 |     pystac.link
import time:       283 |       1638 |   pystac.stac_object
import time:       170 |        170 |     pystac.layout
import time:       346 |        515 |   pystac.catalog
import time:        98 |         98 |       pystac.common_metadata
import time:       137 |        235 |     pystac.asset
import time:        92 |         92 |     pystac.item_assets
import time:       128 |        128 |     pystac.provider
import time:        95 |         95 |           importlib._adapters
import time:       107 |        201 |         importlib._common
import time:       120 |        321 |       importlib.resources
import time:       277 |        597 |     pystac.summaries
import time:       291 |       1340 |   pystac.collection
import time:       594 |        594 |   pystac.item
import time:       133 |        133 |   pystac.item_collection
import time:       157 |        157 |     pystac.validation.schema_uri_map
import time:       148 |        148 |             pprint
import time:        77 |         77 |                   attr._compat
import time:       138 |        138 |                     unicodedata
import time:        58 |         58 |                     attr._config
import time:       115 |        115 |                       attr.exceptions
import time:        55 |        170 |                     attr.setters
import time:      1605 |       1970 |                   attr._make
import time:       139 |       2185 |                 attr.converters
import time:        93 |         93 |                 attr.filters
import time:      2053 |       2053 |                 attr.validators
import time:       100 |        100 |                 attr._cmp
import time:       180 |        180 |                 attr._funcs
import time:        80 |         80 |                 attr._next_gen
import time:       286 |        286 |                 attr._version_info
import time:       200 |       5173 |               attr
import time:       126 |        126 |               attrs.converters
import time:        73 |         73 |               attrs.exceptions
import time:        46 |         46 |               attrs.filters
import time:        39 |         39 |               attrs.setters
import time:        94 |         94 |               attrs.validators
import time:       135 |       5684 |             attrs
import time:       555 |        555 |                     rpds.rpds
import time:        85 |        639 |                   rpds
import time:      1325 |       1325 |                   typing_extensions
import time:        75 |         75 |                     referencing._attrs
import time:      1516 |       1590 |                   referencing.exceptions
import time:       166 |        166 |                   referencing.typing
import time:      3620 |       7338 |                 referencing._core
import time:        98 |       7435 |               referencing
import time:        10 |       7444 |             referencing.exceptions
import time:       147 |        147 |             jsonschema._utils
import time:       563 |      13984 |           jsonschema.exceptions
import time:        57 |         57 |           fqdn
import time:       370 |        370 |               idna.idnadata
import time:       131 |        131 |               idna.intranges
import time:       374 |        874 |             idna.core
import time:        61 |         61 |             idna.package_data
import time:       107 |       1041 |           idna
import time:        41 |         41 |           rfc3987
import time:        34 |         34 |           rfc3986_validator
import time:        30 |         30 |           rfc3987_syntax
import time:        29 |         29 |           rfc3339_validator
import time:        31 |         31 |           webcolors
import time:        29 |         29 |           jsonpointer
import time:        27 |         27 |           uri_template
import time:        26 |         26 |           isoduration
import time:       303 |      15628 |         jsonschema._format
import time:       692 |        692 |         jsonschema._types
import time:       659 |        659 |             referencing.jsonschema
import time:       108 |        108 |             jsonschema_specifications._core
import time:       135 |        135 |             importlib.readers
import time:      2192 |       3093 |           jsonschema_specifications
import time:       576 |        576 |             fractions
import time:       183 |        759 |           jsonschema._keywords
import time:       123 |        123 |           jsonschema._legacy_keywords
import time:        95 |         95 |             jsonschema.protocols
import time:       126 |        221 |           jsonschema._typing
import time:      2244 |       6437 |         jsonschema.validators
import time:       114 |      22869 |       jsonschema
import time:       122 |        122 |       pystac.validation.local_validator
import time:       148 |      23138 |     pystac.validation.stac_validator
import time:       104 |      23399 |   pystac.validation
import time:        69 |         69 |     pystac.extensions
import time:       287 |        287 |     pystac.extensions.base
import time:       136 |        491 |   pystac.extensions.hooks
import time:       595 |        595 |     pystac.extensions.raster
import time:       458 |       1052 |   pystac.extensions.classification
import time:       546 |        546 |   pystac.extensions.datacube
import time:       288 |        288 |     pystac.extensions.projection
import time:       219 |        219 |     pystac.extensions.view
import time:       290 |        796 |   pystac.extensions.eo
import time:       267 |        267 |   pystac.extensions.file
import time:       177 |        177 |   pystac.extensions.grid
import time:       259 |        259 |   pystac.extensions.item_assets
import time:       420 |        420 |   pystac.extensions.label
import time:       325 |        325 |   pystac.extensions.mgrs
import time:       834 |        834 |   pystac.extensions.mlm
import time:       484 |        484 |   pystac.extensions.pointcloud
import time:       484 |        484 |   pystac.extensions.sar
import time:       284 |        284 |   pystac.extensions.sat
import time:       305 |        305 |   pystac.extensions.scientific
import time:       279 |        279 |   pystac.extensions.storage
import time:       256 |        256 |   pystac.extensions.table
import time:       255 |        255 |   pystac.extensions.timestamps
import time:       802 |        802 |   pystac.extensions.version
import time:       220 |        220 |   pystac.extensions.xarray_assets
import time:       423 |      83644 | pystac

and a reasonable after:

import time: self [us] | cumulative | imported package
import time:        88 |         88 |   _io
import time:        33 |         33 |   marshal
import time:       213 |        213 |   posix
import time:       396 |        729 | _frozen_importlib_external
import time:        60 |         60 |   time
import time:        98 |        157 | zipimport
import time:        69 |         69 |     _codecs
import time:       212 |        280 |   codecs
import time:       382 |        382 |   encodings.aliases
import time:       318 |        980 | encodings
import time:       119 |        119 | encodings.utf_8
import time:        45 |         45 | _signal
import time:        19 |         19 |     _abc
import time:       114 |        132 |   abc
import time:       128 |        260 | io
import time:        27 |         27 |       _stat
import time:        88 |        115 |     stat
import time:       521 |        521 |     _collections_abc
import time:        81 |         81 |       genericpath
import time:       119 |        200 |     posixpath
import time:       377 |       1211 |   os
import time:       137 |        137 |   _sitebuiltins
import time:       128 |        128 |     __future__
import time:       125 |        125 |         warnings
import time:        80 |        205 |       importlib
import time:        96 |        300 |     importlib.machinery
import time:        62 |         62 |       importlib._abc
import time:        63 |         63 |           itertools
import time:        59 |         59 |           keyword
import time:       471 |        471 |             _operator
import time:       147 |        617 |           operator
import time:       122 |        122 |           reprlib
import time:        33 |         33 |           _collections
import time:       402 |       1294 |         collections
import time:       204 |        204 |           types
import time:        36 |         36 |           _functools
import time:       324 |        563 |         functools
import time:       253 |       2109 |       contextlib
import time:       113 |       2283 |     importlib.util
import time:       352 |        352 |           enum
import time:        44 |         44 |             _sre
import time:       142 |        142 |               sre_constants
import time:       223 |        364 |             sre_parse
import time:       175 |        583 |           sre_compile
import time:        36 |         36 |           _locale
import time:       118 |        118 |           copyreg
import time:       301 |       1387 |         re
import time:       135 |       1522 |       fnmatch
import time:        30 |         30 |         _winapi
import time:        23 |         23 |         nt
import time:        20 |         20 |         nt
import time:        19 |         19 |         nt
import time:        19 |         19 |         nt
import time:       123 |        231 |       ntpath
import time:        31 |         31 |       errno
import time:        55 |         55 |         urllib
import time:       726 |        726 |         ipaddress
import time:       586 |       1366 |       urllib.parse
import time:       396 |       3544 |     pathlib
import time:       210 |       6463 |   __editable___pystac_1_14_1_finder
import time:        96 |         96 |   _virtualenv
import time:       125 |        125 |   _distutils_hack
import time:        51 |         51 |   sitecustomize
import time:       817 |       8897 | site
import time:       122 |        122 |     collections.abc
import time:      1165 |       1287 |   typing
import time:       205 |        205 |   pystac.errors
import time:        69 |         69 |   pystac.version
import time:       141 |        141 |         math
import time:       173 |        173 |         _datetime
import time:       553 |        866 |       datetime
import time:        73 |         73 |           dateutil._version
import time:        98 |        170 |         dateutil
import time:        25 |         25 |             _string
import time:       418 |        443 |           string
import time:       392 |        392 |             locale
import time:       299 |        690 |           calendar
import time:       171 |        171 |               _struct
import time:       111 |        282 |             struct
import time:       804 |       1085 |           six
import time:       211 |        211 |               numbers
import time:       345 |        556 |             _decimal
import time:        99 |        654 |           decimal
import time:        73 |         73 |           dateutil._common
import time:        90 |         90 |               _bisect
import time:       133 |        223 |             bisect
import time:       160 |        160 |               _weakrefset
import time:       199 |        359 |             weakref
import time:        20 |         20 |             six.moves
import time:       116 |        116 |             dateutil.tz._common
import time:        87 |         87 |             dateutil.tz._factories
import time:        13 |         13 |               six.moves.winreg
import time:        84 |         97 |             dateutil.tz.win
import time:       391 |       1291 |           dateutil.tz.tz
import time:       594 |       4827 |         dateutil.parser._parser
import time:       167 |        167 |         dateutil.parser.isoparser
import time:       101 |       5264 |       dateutil.parser
import time:       264 |       6392 |     pystac.utils
import time:       177 |       6569 |   pystac.media_type
import time:       150 |        150 |   pystac.rel_type
import time:       115 |        115 |           _json
import time:       219 |        333 |         json.scanner
import time:       237 |        570 |       json.decoder
import time:       309 |        309 |       json.encoder
import time:       120 |        998 |     json
import time:       209 |        209 |             token
import time:       504 |        713 |           tokenize
import time:        74 |        786 |         linecache
import time:       156 |        941 |       traceback
import time:       309 |        309 |       threading
import time:        27 |         27 |       atexit
import time:      1074 |       2350 |     logging
import time:       229 |        229 |             zlib
import time:       107 |        107 |               _compression
import time:       132 |        132 |               _bz2
import time:       136 |        374 |             bz2
import time:       151 |        151 |               _lzma
import time:       133 |        283 |             lzma
import time:       380 |       1264 |           shutil
import time:        83 |         83 |             _random
import time:       117 |        117 |             _sha512
import time:       271 |        470 |           random
import time:       216 |       1949 |         tempfile
import time:        92 |       2040 |       urllib.response
import time:       115 |       2155 |     urllib.error
import time:       146 |        146 |         binascii
import time:       201 |        347 |       base64
import time:        93 |         93 |       email
import time:      1446 |       1446 |         _hashlib
import time:       104 |        104 |         _blake2
import time:       132 |       1681 |       hashlib
import time:       455 |        455 |         http
import time:       216 |        216 |             email.errors
import time:       122 |        122 |                 email.quoprimime
import time:        98 |         98 |                 email.base64mime
import time:        71 |         71 |                     quopri
import time:        64 |        135 |                   email.encoders
import time:       148 |        282 |                 email.charset
import time:       406 |        906 |               email.header
import time:       184 |        184 |                   _socket
import time:        98 |         98 |                     select
import time:       654 |        751 |                   selectors
import time:       161 |        161 |                   array
import time:       916 |       2012 |                 socket
import time:       128 |        128 |                 email._parseaddr
import time:       303 |       2442 |               email.utils
import time:       148 |       3495 |             email._policybase
import time:       316 |       4027 |           email.feedparser
import time:       172 |       4198 |         email.parser
import time:        91 |         91 |           uu
import time:       140 |        140 |           email._encoded_words
import time:        63 |         63 |           email.iterators
import time:       302 |        595 |         email.message
import time:      1040 |       1040 |           _ssl
import time:      1566 |       2605 |         ssl
import time:       590 |       8440 |       http.client
import time:       940 |      11500 |     urllib.request
import time:        63 |         63 |                 org
import time:        15 |         77 |               org.python
import time:         8 |         85 |             org.python.core
import time:       132 |        216 |           copy
import time:       125 |        340 |         pystac.cache
import time:       226 |        226 |         pystac.serialization.identify
import time:       133 |        699 |       pystac.serialization.common_properties
import time:       147 |        147 |       pystac.serialization.migrate
import time:       201 |       1046 |     pystac.serialization
import time:       461 |        461 |               signal
import time:       148 |        148 |               fcntl
import time:        71 |         71 |               msvcrt
import time:       131 |        131 |               _posixsubprocess
import time:       340 |       1149 |             subprocess
import time:      1642 |       2791 |           platform
import time:       192 |        192 |           _uuid
import time:       284 |       3265 |         uuid
import time:       494 |        494 |               _ast
import time:       638 |       1131 |             ast
import time:       119 |        119 |                 _opcode
import time:       134 |        252 |               opcode
import time:       260 |        511 |             dis
import time:      1333 |       2975 |           inspect
import time:       350 |       3324 |         dataclasses
import time:       251 |       6839 |       orjson.orjson
import time:       108 |       6947 |     orjson
import time:       462 |        462 |       urllib3.exceptions
import time:       214 |        214 |               urllib3.util.timeout
import time:       202 |        415 |             urllib3.util.connection
import time:        56 |         56 |               urllib3.util.util
import time:        40 |         40 |               brotlicffi
import time:        32 |         32 |               brotli
import time:        29 |         29 |               compression
import time:        29 |         29 |               zstandard
import time:       301 |        485 |             urllib3.util.request
import time:        73 |         73 |             urllib3.util.response
import time:       217 |        217 |             urllib3.util.retry
import time:       109 |        109 |               hmac
import time:      4356 |       4356 |               urllib3.util.url
import time:       162 |        162 |               urllib3.util.ssltransport
import time:       176 |       4801 |             urllib3.util.ssl_
import time:        71 |         71 |             urllib3.util.wait
import time:        91 |       6150 |           urllib3.util
import time:        11 |       6161 |         urllib3.util.connection
import time:       344 |       6505 |       urllib3._base_connection
import time:       357 |        357 |       urllib3._collections
import time:       112 |        112 |       urllib3._version
import time:        98 |         98 |             _heapq
import time:        92 |        189 |           heapq
import time:        94 |         94 |           _queue
import time:       207 |        490 |         queue
import time:        38 |         38 |                 _winapi
import time:        30 |         30 |                 winreg
import time:       144 |        211 |               mimetypes
import time:       119 |        329 |             urllib3.fields
import time:       108 |        436 |           urllib3.filepost
import time:        71 |         71 |             brotlicffi
import time:        39 |         39 |             brotli
import time:       118 |        118 |                     _csv
import time:       176 |        293 |                   csv
import time:       456 |        456 |                   zipfile
import time:       562 |        562 |                   textwrap
import time:        53 |         53 |                       importlib.metadata._functools
import time:        91 |        144 |                     importlib.metadata._text
import time:       197 |        340 |                   importlib.metadata._adapters
import time:       166 |        166 |                   importlib.metadata._meta
import time:       233 |        233 |                   importlib.metadata._collections
import time:        89 |         89 |                   importlib.metadata._itertools
import time:       289 |        289 |                   importlib.abc
import time:       789 |       3214 |                 importlib.metadata
import time:       178 |       3392 |               urllib3.http2
import time:       131 |        131 |               urllib3.http2.probe
import time:        89 |         89 |               urllib3.util.ssl_match_hostname
import time:       447 |       4058 |             urllib3.connection
import time:        52 |         52 |             compression
import time:        33 |         33 |             zstandard
import time:       292 |       4543 |           urllib3.response
import time:       133 |       5112 |         urllib3._request_methods
import time:        75 |         75 |         urllib3.util.proxy
import time:       238 |       5913 |       urllib3.connectionpool
import time:       572 |        572 |       urllib3.poolmanager
import time:       253 |      14170 |     urllib3
import time:       257 |      39419 |   pystac.stac_io
import time:       638 |        638 |       html.entities
import time:       321 |        958 |     html
import time:        72 |         72 |         pystac.html.jinja_env
import time:        87 |        159 |       pystac.html
import time:        11 |        169 |     pystac.html.jinja_env
import time:       170 |        170 |     pystac.link
import time:       268 |       1564 |   pystac.stac_object
import time:       210 |        210 |     pystac.layout
import time:       329 |        539 |   pystac.catalog
import time:        90 |         90 |       pystac.common_metadata
import time:       143 |        232 |     pystac.asset
import time:        98 |         98 |     pystac.item_assets
import time:       128 |        128 |     pystac.provider
import time:       104 |        104 |           importlib._adapters
import time:       119 |        223 |         importlib._common
import time:       148 |        370 |       importlib.resources
import time:       379 |        749 |     pystac.summaries
import time:       264 |       1468 |   pystac.collection
import time:       543 |        543 |   pystac.item
import time:       133 |        133 |   pystac.item_collection
import time:       124 |        124 |     pystac.extensions
import time:       270 |        270 |     pystac.extensions.base
import time:       190 |        583 |   pystac.extensions.hooks
import time:       518 |        518 |     pystac.extensions.raster
import time:       366 |        883 |   pystac.extensions.classification
import time:       536 |        536 |   pystac.extensions.datacube
import time:       255 |        255 |     pystac.extensions.projection
import time:       260 |        260 |     pystac.extensions.view
import time:       288 |        801 |   pystac.extensions.eo
import time:       309 |        309 |   pystac.extensions.file
import time:       230 |        230 |   pystac.extensions.grid
import time:       128 |        128 |   pystac.extensions.item_assets
import time:       386 |        386 |   pystac.extensions.label
import time:       319 |        319 |   pystac.extensions.mgrs
import time:       957 |        957 |   pystac.extensions.mlm
import time:       411 |        411 |   pystac.extensions.pointcloud
import time:       444 |        444 |   pystac.extensions.sar
import time:       263 |        263 |   pystac.extensions.sat
import time:       338 |        338 |   pystac.extensions.scientific
import time:       307 |        307 |   pystac.extensions.storage
import time:       322 |        322 |   pystac.extensions.table
import time:       183 |        183 |   pystac.extensions.timestamps
import time:       369 |        369 |   pystac.extensions.version
import time:       184 |        184 |   pystac.extensions.xarray_assets
import time:       350 |      60235 | pystac

PR Checklist:

  • Pre-commit hooks pass (run pre-commit run --all-files)
  • Tests pass (run pytest)
  • Documentation has been updated to reflect changes, if applicable
  • This PR maintains or improves overall codebase code coverage.
  • Changes are added to the CHANGELOG. See the docs for information about adding to the changelog.

@pjonsson pjonsson force-pushed the remove-unused-import branch from 64331b0 to 201e29b Compare October 5, 2025 11:58
pjonsson added a commit to pjonsson/pystac that referenced this pull request Oct 5, 2025
Python import times are noticeable during
interactive use of CLI applications, so
push the (near) single-use imports into
the functions where they are used so
the import cost is paid when calling
the functions instead of when starting
the CLI to print the help or do some
other unrelated action.

Timings on top of stac-utils#1583 inside
a Python:3.10-bookworm container.

Before this change:

$ uv run hyperfine --warmup 3 "python3 -c 'import pystac'"
Benchmark 1: python3 -c 'import pystac'
  Time (mean ± σ):      67.2 ms ±   1.6 ms    [User: 58.6 ms, System: 8.6 ms]
  Range (min … max):    62.5 ms …  69.9 ms    45 runs

After this change:

$ uv run hyperfine --warmup 3 "python3 -c 'import pystac'"
Benchmark 1: python3 -c 'import pystac'
  Time (mean ± σ):      59.9 ms ±   1.5 ms    [User: 52.0 ms, System: 7.8 ms]
  Range (min … max):    56.9 ms …  64.2 ms    48 runs
@pjonsson pjonsson mentioned this pull request Oct 5, 2025
5 tasks
@gadomski gadomski self-requested a review October 6, 2025 12:48
@codecov
Copy link

codecov bot commented Oct 6, 2025

Codecov Report

❌ Patch coverage is 28.57143% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.32%. Comparing base (cf50958) to head (f10397e).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
pystac/__init__.py 28.57% 4 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1583      +/-   ##
==========================================
- Coverage   92.38%   92.32%   -0.06%     
==========================================
  Files          55       55              
  Lines        8375     8381       +6     
  Branches      965      966       +1     
==========================================
+ Hits         7737     7738       +1     
- Misses        453      457       +4     
- Partials      185      186       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Member

@gadomski gadomski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is a breaking change, we should put it behind a __getattr__ with a warning, e.g. (this is untested, so might be a bit broken):

def __getattr__(name: str) -> Any:
    if name == "validation":
        import warnings
        import pystac.validation
        
        warnings.warn("pystac.validation will not be automatically imported to the package in pystac v2.0. Instead, import it directly: `import pystac.validation`")
        return pystac.validation
    else:
        raise AttributeError(f"module {__name__} has no attribute {name}")

That way, we don't break any usage that looks like:

import pystac

pystac.validation.validate(...)

This takes 23 000us to import on
a Ryzen 9950X3D, and the import
does not seem to be used after
PR stac-utils#591 was merged.
@pjonsson pjonsson force-pushed the remove-unused-import branch from 201e29b to e56d019 Compare October 7, 2025 06:20
@pjonsson
Copy link
Contributor Author

pjonsson commented Oct 7, 2025

As this is a breaking change, we should put it behind a __getattr__ with a warning, e.g. (this is untested, so might be a bit broken):

Your code worked!

I added a DeprecationWarning/stacklevel, and some quotes to the AttributeError message to align with the default message.

@pjonsson pjonsson requested a review from gadomski October 7, 2025 06:23
Copy link
Member

@gadomski gadomski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't figure out how to add a pytest test for this, since pystac.validation ends up in the global attribute dictionary thanks to fixtures, but this one-liner works as expected:

$ python -c "import pystac; item = pystac.read_file('tests/data-files/item/sample-item.json'); pystac.validation.validate(item)"
<string>:1: DeprecationWarning: pystac.validation will not be automatically imported to the package in pystac v2.0. Instead, import it directly: `import pystac.validation`

@gadomski gadomski enabled auto-merge October 10, 2025 13:20
@gadomski gadomski added this pull request to the merge queue Oct 10, 2025
Merged via the queue into stac-utils:main with commit 065a631 Oct 10, 2025
19 checks passed
@pjonsson pjonsson deleted the remove-unused-import branch October 10, 2025 14:53
kmodali pushed a commit to kmodali/pystac that referenced this pull request Oct 16, 2025
This takes 23 000us to import on
a Ryzen 9950X3D, and the import
does not seem to be used after
PR stac-utils#591 was merged.

Co-authored-by: Pete Gadomski <[email protected]>
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.

2 participants